Index | Thread | Search

From:
Mark Kettenis <mark.kettenis@xs4all.nl>
Subject:
Re: arm64 LSE support in userland: introduce elf_aux_info?
To:
Jeremie Courreges-Anglas <jca@wxcvbn.org>
Cc:
deraadt@openbsd.org, tech@openbsd.org, brad@comstyle.com
Date:
Fri, 12 Jul 2024 13:18:41 +0200

Download raw body.

Thread
> Date: Wed, 10 Jul 2024 18:41:57 +0200
> From: Jeremie Courreges-Anglas <jca@wxcvbn.org>
> 
> On Mon, Jul 08, 2024 at 09:17:23AM +0200, Mark Kettenis wrote:
> > > Date: Sun, 7 Jul 2024 17:44:39 +0200
> > > From: Jeremie Courreges-Anglas <jca@wxcvbn.org>
> > > 
> > > On Sun, Jul 07, 2024 at 03:00:55PM +0200, Mark Kettenis wrote:
> > > > > Date: Sat, 6 Jul 2024 14:47:28 +0200
> > > > > From: Jeremie Courreges-Anglas <jca@wxcvbn.org>
> > > > > 
> > > > > On Thu, Jul 04, 2024 at 08:14:15AM -0600, Theo de Raadt wrote:
> > > > > > In glibc, getauxval(3) is a monster API that keeps growing additional
> > > > > > heads and tentacles.  Exporting a tiny version of it to userland is
> > > > > > worrying.
> > > > > 
> > > > > Agreed about getauxval.
> > > > 
> > > > Not sure what you folks mean with that.  Is the problem that there are
> > > > too many AT_xxx constants for which we would not want to add support?
> > > > That I do agree with.
> > > 
> > > Yep.
> > > 
> > > > So do yout think that adding just the few AT_xxx constants that we
> > > > care about would cause too many problems in ports?
> > > 
> > > (One common pattern visible in ports is to #define some AT_xxx
> > > constants (with a hardcoded value copied from Linux headers) if
> > > they're not already #defined.)
> > > 
> > > I fear that detection of the getauxval() symbol may trigger the use of
> > > Linux-specific code paths, possibly with no useful/usable fallback in
> > > case of an error.  Also, some ports may start to include <linux/*.h>
> > > headers along with their use of getauxval().  It would be a shame to
> > > implement getauxval() and yet need non-trivial patches in ports.
> > > 
> > > > > > When the real problem here is a tiny little check to use done only
> > > > > > internal to only our libc, and therefore why not use an OpenBSD private
> > > > > > interface.
> > > > > 
> > > > > Indeed we could use a private API for this specific need.  But the
> > > > > problem is not just about our libc, ports also want a way to query
> > > > > hardware capabilities.  We usually have to patch them to use a
> > > > > sysctl(2) or just drop the code that detects such capabilities.
> > > > > I feel like implementing elf_aux_info(3) should be considered.  Has
> > > > > someone already tried that?  If people don't object, that could be a
> > > > > todo entry for c2k24.
> > > > 
> > > > So elf_aux_info(3) is just getauxval(3) with a somewhat different API.
> > > > It is a bit better in the sense that it unambiguously tells you if an
> > > > AT_xxx value isn't supported.
> > > > 
> > > > Are you less worried about us not implementing all the AT_xxx defines
> > > > that FreeBSD has?
> > > 
> > > Yes.  Dumb comparison:
> > > 
> > >   https://www.man7.org/linux/man-pages/man3/getauxval.3.html 34 defines
> > >   https://man.freebsd.org/cgi/man.cgi?elf_aux_info(3) 11 defines
> > > 
> > > Compare that to the 8 AUX_xxx values handled in our kern/exec_elf.c...
> > 
> > And perhaps more importantly, FreeBSD doesn't have bad ones like
> > AT_SECURE.
> > 
> > > BTW, we currently always export 0 for AUX_flags.  The comment in
> > > exec_elf.h says "processor flags".  Have you considered reusing this
> > > for a quick compiler-rt hack?
> > 
> > AUX_flags would be AT_FLAGS, which is related to e_flags in the ELF
> > header.  Solaris used this to mark binaries that (unconditionally) use
> > certain instruction set extensions.  I suppose we could use it on
> > arm64 but AT_HWCAP and AT_HWCAP2 on Linux and FreeBSD provide more
> > flags than we could fit in AT_FLAGS.
> 
> Ack, forget my question.  I introduced new AUX_hwcap* requests, that
> map to the AT_HWCAP* defines.
> 
> > If we go this route we do want the features to align with what Linux
> > and FreeBSD use.  I don't think we want to burden porters with
> > figuring out what OpenBSD feature bit maps onto what Linux uses.
> 
> For the diff below I just used the bits from FreeBSD.  Hopefully they
> should be the same as Linux, but I haven't checked yet.
> 
> > > > I suspect that there is a much smaller number of ports that support
> > > > elf_aux_info(3).
> > > 
> > > Well, maybe it's a good thing? ;)
> > > 
> > > More seriously, I've started an amd64 bulk build on a system with a
> > > dumb elf_aux_info() that always returns ENOENT.  I should have numbers
> > > in 2 days for ports that may automatically pick it up.
> 
> That bulk build completed with no fallout, but I doubt that
> elf_aux_info() is used much on amd64.
> 
> > > There would also be a bunch of other ports where we'd have to add an
> > > ugly "|| defined(__OpenBSD__)" chunk to the FreeBSD code path, but at
> > > least that's something that could be upstreamed.
> > >
> > > Feedback from other porters would be welcome.
> 
> The diff below introduces elf_aux_info(3).  Manpage and
> <machine/elf.h> bits taken from FreeBSD.  I have only tested this
> (successfully) on amd64.  I have no arm64 machine at hand, and the
> riscv64 ports machines are currently busy with a bulk build.
> 
> Mark, as discussed, I'm only setting the Atomics/LSE bit on arm64.
> If I didn't mess something up, the regress test should show it.
> 
> The main TODO entries:
> - arm
> - remaining arm64 bits (cpu_sysctl/hwcap refactoring?)
> - powerpc
> 
> Thoughts?  ok?

A few thoughts here.

* Reading the auxv stuff during libc init and storing it in local
  variables is a good thing as it avoids issues from messing around
  with envp and such.

* I have no objection to also supporting AT_PAGESZ.

* We should probably properly prune the man page instead of commenting
  out AT_xxx entries (unless we intend to support them at a later stage).

* I think we should prune the list of AT_xxx defines.  Maybe we should
  only provide the ones that we actually implement?  Or at least we
  should prune some of the non-standard ones that FreeBSD added.  Or
  are you afraid this may break ports code?

* There are some tab vs. spaces inconsistencies, especially in the
  multiple-include protection stuff.

A few more comments below...

> Index: lib/libc/Symbols.list
> ===================================================================
> RCS file: /cvs/src/lib/libc/Symbols.list,v
> diff -u -p -r1.87 Symbols.list
> --- lib/libc/Symbols.list	18 May 2024 05:20:22 -0000	1.87
> +++ lib/libc/Symbols.list	10 Jul 2024 16:17:09 -0000
> @@ -608,6 +608,7 @@ daemon
>  devname
>  dirfd
>  dirname
> +elf_aux_info
>  endfsent
>  endgrent
>  endnetgrent
> Index: lib/libc/dlfcn/init.c
> ===================================================================
> RCS file: /cvs/src/lib/libc/dlfcn/init.c,v
> diff -u -p -r1.22 init.c
> --- lib/libc/dlfcn/init.c	21 Jan 2024 17:18:13 -0000	1.22
> +++ lib/libc/dlfcn/init.c	10 Jul 2024 16:17:09 -0000
> @@ -49,6 +49,8 @@ char	***_csu_finish(char **_argv, char *
>  /* provide definitions for these */
>  int	_pagesize = 0;
>  struct timekeep	*_timekeep;
> +unsigned long	_hwcap, _hwcap2;
> +int	_hwcap_avail, _hwcap2_avail;
>  
>  /*
>   * In dynamically linked binaries environ and __progname are overridden by
> @@ -96,6 +98,14 @@ _libc_preinit(int argc, char **argv, cha
>  		;
>  	for (aux = (void *)envp; aux->au_id != AUX_null; aux++) {
>  		switch (aux->au_id) {
> +		case AUX_hwcap:
> +			_hwcap = aux->au_v;
> +			_hwcap_avail = 1;
> +			break;
> +		case AUX_hwcap2:
> +			_hwcap2 = aux->au_v;
> +			_hwcap2_avail = 1;
> +			break;
>  		case AUX_pagesz:
>  			_pagesize = aux->au_v;
>  			break;
> Index: lib/libc/gen/Makefile.inc
> ===================================================================
> RCS file: /cvs/src/lib/libc/gen/Makefile.inc,v
> diff -u -p -r1.82 Makefile.inc
> --- lib/libc/gen/Makefile.inc	2 Sep 2019 21:18:40 -0000	1.82
> +++ lib/libc/gen/Makefile.inc	10 Jul 2024 16:17:09 -0000
> @@ -6,8 +6,8 @@
>  SRCS+=  alarm.c assert.c auth_subr.c authenticate.c \
>          basename.c clock.c clock_getcpuclockid.c \
>          closedir.c confstr.c ctermid.c ctype_.c \
> -        daemon.c devname.c dirfd.c dirname.c disklabel.c err.c \
> -        errc.c errx.c errlist.c errno.c exec.c \
> +        daemon.c devname.c dirfd.c dirname.c disklabel.c elf_aux_info.c \
> +        err.c errc.c errx.c errlist.c errno.c exec.c \
>          fdatasync.c fnmatch.c fpclassify.c frexp.c \
>          fstab.c ftok.c fts.c ftw.c getbsize.c getcap.c getcwd.c \
>          getdomainname.c getgrent.c getgrouplist.c gethostname.c \
> @@ -36,7 +36,7 @@ SRCS+=  alarm.c assert.c auth_subr.c aut
>  
>  MAN+=	__tfork_thread.3 alarm.3 auth_subr.3 authenticate.3 basename.3 clock.3 \
>  	clock_getcpuclockid.3 confstr.3 \
> -	ctermid.3 daemon.3 devname.3 opendir.3 dirname.3 err.3 \
> +	ctermid.3 daemon.3 devname.3 opendir.3 dirname.3 elf_aux_info.3 err.3 \
>  	execv.3 fabs.3 fnmatch.3 fpclassify.3 fpgetmask.3 frexp.3 ftok.3 fts_open.3 \
>  	ftw.3 getbsize.3 cgetent.3 getcwd.3 getdomainname.3 getdiskbyname.3 \
>  	getfsent.3 getgrent.3 getgrouplist.3 gethostname.3 getloadavg.3 \
> Index: lib/libc/gen/elf_aux_info.3
> ===================================================================
> RCS file: lib/libc/gen/elf_aux_info.3
> diff -N lib/libc/gen/elf_aux_info.3
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ lib/libc/gen/elf_aux_info.3	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,111 @@
> +.\"	$OpenBSD$
> +.\"
> +.\" Origin: FreeBSD auxv.3
> +.\"
> +.\" Copyright (c) 2019 Ian Lepore <ian@freebsd.org>
> +.\"
> +.\" Redistribution and use in source and binary forms, with or without
> +.\" modification, are permitted provided that the following conditions
> +.\" are met:
> +.\"
> +.\" 1. Redistributions of source code must retain the above copyright
> +.\"    notice, this list of conditions and the following disclaimer.
> +.\" 2. Redistributions in binary form must reproduce the above copyright
> +.\"    notice, this list of conditions and the following disclaimer in the
> +.\"    documentation and/or other materials provided with the distribution.
> +.\"
> +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
> +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +.\"
> +.Dd $Mdocdate$
> +.Dt ELF_AUX_INFO 3
> +.Os
> +.Sh NAME
> +.Nm elf_aux_info
> +.Nd extract data from the elf auxiliary vector of the current process
> +.\" .Sh LIBRARY
> +.\" .Lb libc
> +.Sh SYNOPSIS
> +.In sys/auxv.h
> +.Ft int
> +.Fn elf_aux_info "int aux" "void *buf" "int buflen"
> +.Sh DESCRIPTION
> +The
> +.Fn elf_aux_info
> +function retrieves the auxiliary info vector requested in
> +.Va aux .
> +The information is stored into the provided buffer if it will fit.
> +The following values, defined in
> +.In sys/elf_common.h
> +can be requested (corresponding buffer sizes are specified in parenthesis):
> +.Bl -tag -width AT_OSRELDATE
> +.\" .It AT_CANARY
> +.\" The canary value for SSP (arbitrary sized buffer, as many bytes are
> +.\" returned as it fits into it, rest is zeroed).
> +.\" .It AT_EXECPATH
> +.\" The path of executed program
> +.\" .Dv (MAXPATHLEN).
> +.\" This may not be present if the process was initialized by
> +.\" .Xr fexecve 2
> +.\" and the namecache no longer contains the file's name.
> +.It AT_HWCAP
> +CPU / hardware feature flags
> +.Dv (sizeof(unsigned long)) .
> +.It AT_HWCAP2
> +CPU / hardware feature flags
> +.Dv (sizeof(unsigned long)) .
> +.\" .It AT_NCPUS
> +.\" Number of CPUs
> +.\" .Dv (sizeof(int)).
> +.\" .It AT_OSRELDATE
> +.\" The
> +.\" .Dv OSRELDATE
> +.\" of the kernel or jail the program is running on
> +.\" .Dv (sizeof(int)).
> +.\" .It AT_PAGESIZES
> +.\" Vector of page sizes (arbitrary sized buffer, as many elements of the
> +.\" .Dv pagesizes
> +.\" array are returned as it fits).
> +.It AT_PAGESZ
> +Page size in bytes
> +.Dv (sizeof(int)) .
> +.\" .It AT_TIMEKEEP
> +.\" Pointer to VDSO timehands (for library internal use,
> +.\" .Dv sizeof(void *)).
> +.\" .It AT_USRSTACKBASE
> +.\" Top of the user stack for main thread.
> +.\" .It AT_USRSTACKLIM
> +.\" Limit for grow of the user stack for main thread.
> +.El
> +.Sh RETURN VALUES
> +Returns zero on success, or an error number on failure.
> +.Sh ERRORS
> +.Bl -tag -width Er
> +.It Bq Er EINVAL
> +An unknown item was requested.
> +.It Bq Er EINVAL
> +The provided buffer was not the right size for the requested item.
> +.It Bq Er ENOENT
> +The requested item is not available.
> +.El
> +.Sh HISTORY
> +The
> +.Fn elf_aux_info
> +function appeared in
> +.Fx 12.0
> +and was first available in
> +.Ox 7.6 .
> +.\" .Sh BUGS
> +.Sh CAVEATS
> +Only a small subset of available auxiliary info vector items are
> +accessible with this function.
> +.\" Some items require a "right-sized" buffer while others just require a
> +.\" "big enough" buffer.
> Index: lib/libc/gen/elf_aux_info.c
> ===================================================================
> RCS file: lib/libc/gen/elf_aux_info.c
> diff -N lib/libc/gen/elf_aux_info.c
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ lib/libc/gen/elf_aux_info.c	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,70 @@
> +/*	$OpenBSD$	*/
> +
> +/*
> + * Copyright (c) 2024 Jeremie Courreges-Anglas <jca@wxcvbn.org>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include <sys/types.h>
> +#include <sys/auxv.h>
> +
> +#include <errno.h>
> +
> +extern int _pagesize;
> +extern unsigned long _hwcap, _hwcap2;
> +extern int _hwcap_avail, _hwcap2_avail;
> +
> +int
> +elf_aux_info(int request, void *buf, int buflen)
> +{
> +	int ret = 0;
> +
> +	if (buflen < 0)
> +		return EINVAL;
> +
> +	switch (request) {
> +	case AT_HWCAP:
> +		if (buflen != sizeof(unsigned long))
> +			ret = EINVAL;
> +		else if (!_hwcap_avail)
> +			ret = ENOENT;
> +		else
> +			*(unsigned long *)buf = _hwcap;
> +		break;
> +	case AT_HWCAP2:
> +		if (buflen != sizeof(unsigned long))
> +			ret = EINVAL;
> +		else if (!_hwcap2_avail)
> +			ret = ENOENT;
> +		else
> +			*(unsigned long *)buf = _hwcap2;
> +		break;
> +	case AT_PAGESZ:
> +		if (buflen != sizeof(int))
> +			ret = EINVAL;
> +		else if (!_pagesize)
> +			ret = ENOENT;
> +		else
> +			*(int *)buf = _pagesize;
> +		break;
> +	default:
> +		if (request < 0 || request >= AT_COUNT)
> +			ret = EINVAL;
> +		else
> +			ret = ENOENT;
> +		break;
> +	}
> +
> +	return ret;
> +}
> Index: lib/libc/hidden/sys/auxv.h
> ===================================================================
> RCS file: lib/libc/hidden/sys/auxv.h
> diff -N lib/libc/hidden/sys/auxv.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ lib/libc/hidden/sys/auxv.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,26 @@
> +/*	$OpenBSD$	*/
> +
> +/*
> + * Copyright (c) 2024 Jeremie Courreges-Anglas <jca@wxcvbn.org>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#ifndef _LIBC_SYS_AUXV_H_
> +#define _LIBC_SYS_AUXV_H_
> +
> +#include_next <sys/auxv.h>
> +
> +PROTO_DEPRECATED(elf_aux_info);
> +
> +#endif /* !_LIBC_SYS_AUXV_H_ */
> Index: regress/lib/libc/Makefile
> ===================================================================
> RCS file: /cvs/src/regress/lib/libc/Makefile,v
> diff -u -p -r1.58 Makefile
> --- regress/lib/libc/Makefile	31 Aug 2021 09:58:17 -0000	1.58
> +++ regress/lib/libc/Makefile	10 Jul 2024 16:17:09 -0000
> @@ -5,6 +5,7 @@ SUBDIR+= alloca arc4random-fork atexit
>  SUBDIR+= basename
>  SUBDIR+= cephes cxa-atexit
>  SUBDIR+= db dirname
> +#SUBDIR+= elf_aux_info
>  SUBDIR+= env explicit_bzero
>  SUBDIR+= ffs fmemopen fnmatch fpclassify fread
>  SUBDIR+= gcvt getaddrinfo getcap getopt getopt_long glob
> Index: sys/arch/alpha/include/elf.h
> ===================================================================
> RCS file: sys/arch/alpha/include/elf.h
> diff -N sys/arch/alpha/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/alpha/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,7 @@
> +/*	$OpenBSD$	*/
> +
> +/*
> + * This file is in the public domain.
> + */
> +
> +/* Nothing for now */
> Index: sys/arch/amd64/include/elf.h
> ===================================================================
> RCS file: sys/arch/amd64/include/elf.h
> diff -N sys/arch/amd64/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/amd64/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,7 @@
> +/*	$OpenBSD$	*/
> +
> +/*
> + * This file is in the public domain.
> + */
> +
> +/* Nothing for now */
> Index: sys/arch/arm/include/elf.h
> ===================================================================
> RCS file: sys/arch/arm/include/elf.h
> diff -N sys/arch/arm/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/arm/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,77 @@
> +/*	$OpenBSD$	*/
> +
> +/*-
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2001 David E. O'Brien
> + * Copyright (c) 1996-1997 John D. Polstra.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + */
> +
> +#ifndef _MACHINE_ELF_H_
> +#define	_MACHINE_ELF_H_ 1
> +
> +/*
> + * ELF definitions for the ARM architecture.
> + */
> +
> +#ifdef _KERNEL
> +# define __HAVE_CPU_HWCAP
> +# define __HAVE_CPU_HWCAP2
> +extern unsigned long	hwcap, hwcap2;
> +#endif /* _KERNEL */
> +
> +/* Flags passed in AT_HWCAP. */
> +#define	HWCAP_SWP		0x00000001	/* Unsupported, never set.    */
> +#define	HWCAP_HALF		0x00000002	/* Always set.                */
> +#define	HWCAP_THUMB		0x00000004
> +#define	HWCAP_26BIT		0x00000008	/* Unsupported, never set.    */
> +#define	HWCAP_FAST_MULT		0x00000010	/* Always set.                */
> +#define	HWCAP_FPA		0x00000020	/* Unsupported, never set.    */
> +#define	HWCAP_VFP		0x00000040
> +#define	HWCAP_EDSP		0x00000080	/* Always set for ARMv6+.     */
> +#define	HWCAP_JAVA		0x00000100	/* Unsupported, never set.    */
> +#define	HWCAP_IWMMXT		0x00000200	/* Unsupported, never set.    */
> +#define	HWCAP_CRUNCH		0x00000400	/* Unsupported, never set.    */
> +#define	HWCAP_THUMBEE		0x00000800
> +#define	HWCAP_NEON		0x00001000
> +#define	HWCAP_VFPv3		0x00002000
> +#define	HWCAP_VFPv3D16		0x00004000
> +#define	HWCAP_TLS		0x00008000	/* Always set for ARMv6+.     */
> +#define	HWCAP_VFPv4		0x00010000
> +#define	HWCAP_IDIVA		0x00020000
> +#define	HWCAP_IDIVT		0x00040000
> +#define	HWCAP_VFPD32		0x00080000
> +#define	HWCAP_IDIV		(HWCAP_IDIVA | HWCAP_IDIVT)
> +#define	HWCAP_LPAE		0x00100000
> +#define	HWCAP_EVTSTRM		0x00200000	/* Not implemented yet.       */
> +
> +/* Flags passed in AT_HWCAP2. */
> +#define	HWCAP2_AES		0x00000001
> +#define	HWCAP2_PMULL		0x00000002
> +#define	HWCAP2_SHA1		0x00000004
> +#define	HWCAP2_SHA2		0x00000008
> +#define	HWCAP2_CRC32		0x00000010
> +
> +#endif /* !_MACHINE_ELF_H_ */
> Index: sys/arch/arm64/arm64/cpu.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/arm64/arm64/cpu.c,v
> diff -u -p -r1.124 cpu.c
> --- sys/arch/arm64/arm64/cpu.c	10 Jul 2024 11:01:24 -0000	1.124
> +++ sys/arch/arm64/arm64/cpu.c	10 Jul 2024 16:17:09 -0000
> @@ -32,6 +32,7 @@
>  #include <uvm/uvm.h>
>  
>  #include <machine/fdt.h>
> +#include <machine/elf.h>
>  
>  #include <dev/ofw/openfirm.h>
>  #include <dev/ofw/ofw_clock.h>
> @@ -717,6 +718,10 @@ cpu_identify(struct cpu_info *ci)
>  		printf("%sAtomic", sep);
>  		sep = ",";
>  		arm64_has_lse = 1;
> +		/*
> +		 * XXX should be populated and sanitized like cpu_sysctl() does
> +		 */
> +		hwcap |= HWCAP_ATOMICS;
>  	}
>  
>  	if (ID_AA64ISAR0_CRC32(id) >= ID_AA64ISAR0_CRC32_BASE) {
> Index: sys/arch/arm64/include/elf.h
> ===================================================================
> RCS file: sys/arch/arm64/include/elf.h
> diff -N sys/arch/arm64/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/arm64/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,121 @@
> +/*-
> + * Copyright (c) 1996-1997 John D. Polstra.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + */
> +
> +#ifndef	_MACHINE_ELF_H_
> +#define	_MACHINE_ELF_H_
> +
> +/*
> + * ELF definitions for the AArch64 architecture.
> + */
> +
> +#ifdef _KERNEL
> +# define __HAVE_CPU_HWCAP
> +# define __HAVE_CPU_HWCAP2
> +extern unsigned long	hwcap, hwcap2;
> +#endif /* _KERNEL */
> +
> +/* HWCAP */
> +#define	HWCAP_FP		0x00000001
> +#define	HWCAP_ASIMD		0x00000002
> +#define	HWCAP_EVTSTRM		0x00000004
> +#define	HWCAP_AES		0x00000008
> +#define	HWCAP_PMULL		0x00000010
> +#define	HWCAP_SHA1		0x00000020
> +#define	HWCAP_SHA2		0x00000040
> +#define	HWCAP_CRC32		0x00000080
> +#define	HWCAP_ATOMICS		0x00000100
> +#define	HWCAP_FPHP		0x00000200
> +#define	HWCAP_ASIMDHP		0x00000400
> +#define	HWCAP_CPUID		0x00000800
> +#define	HWCAP_ASIMDRDM		0x00001000
> +#define	HWCAP_JSCVT		0x00002000
> +#define	HWCAP_FCMA		0x00004000
> +#define	HWCAP_LRCPC		0x00008000
> +#define	HWCAP_DCPOP		0x00010000
> +#define	HWCAP_SHA3		0x00020000
> +#define	HWCAP_SM3		0x00040000
> +#define	HWCAP_SM4		0x00080000
> +#define	HWCAP_ASIMDDP		0x00100000
> +#define	HWCAP_SHA512		0x00200000
> +#define	HWCAP_SVE		0x00400000
> +#define	HWCAP_ASIMDFHM		0x00800000
> +#define	HWCAP_DIT		0x01000000
> +#define	HWCAP_USCAT		0x02000000
> +#define	HWCAP_ILRCPC		0x04000000
> +#define	HWCAP_FLAGM		0x08000000
> +#define	HWCAP_SSBS		0x10000000
> +#define	HWCAP_SB		0x20000000
> +#define	HWCAP_PACA		0x40000000
> +#define	HWCAP_PACG		0x80000000
> +
> +/* HWCAP2 */
> +#define	HWCAP2_DCPODP		0x0000000000000001ul
> +#define	HWCAP2_SVE2		0x0000000000000002ul
> +#define	HWCAP2_SVEAES		0x0000000000000004ul
> +#define	HWCAP2_SVEPMULL		0x0000000000000008ul
> +#define	HWCAP2_SVEBITPERM	0x0000000000000010ul
> +#define	HWCAP2_SVESHA3		0x0000000000000020ul
> +#define	HWCAP2_SVESM4		0x0000000000000040ul
> +#define	HWCAP2_FLAGM2		0x0000000000000080ul
> +#define	HWCAP2_FRINT		0x0000000000000100ul
> +#define	HWCAP2_SVEI8MM		0x0000000000000200ul
> +#define	HWCAP2_SVEF32MM		0x0000000000000400ul
> +#define	HWCAP2_SVEF64MM		0x0000000000000800ul
> +#define	HWCAP2_SVEBF16		0x0000000000001000ul
> +#define	HWCAP2_I8MM		0x0000000000002000ul
> +#define	HWCAP2_BF16		0x0000000000004000ul
> +#define	HWCAP2_DGH		0x0000000000008000ul
> +#define	HWCAP2_RNG		0x0000000000010000ul
> +#define	HWCAP2_BTI		0x0000000000020000ul
> +#define	HWCAP2_MTE		0x0000000000040000ul
> +#define	HWCAP2_ECV		0x0000000000080000ul
> +#define	HWCAP2_AFP		0x0000000000100000ul
> +#define	HWCAP2_RPRES		0x0000000000200000ul
> +#define	HWCAP2_MTE3		0x0000000000400000ul
> +#define	HWCAP2_SME		0x0000000000800000ul
> +#define	HWCAP2_SME_I16I64	0x0000000001000000ul
> +#define	HWCAP2_SME_F64F64	0x0000000002000000ul
> +#define	HWCAP2_SME_I8I32	0x0000000004000000ul
> +#define	HWCAP2_SME_F16F32	0x0000000008000000ul
> +#define	HWCAP2_SME_B16F32	0x0000000010000000ul
> +#define	HWCAP2_SME_F32F32	0x0000000020000000ul
> +#define	HWCAP2_SME_FA64		0x0000000040000000ul
> +#define	HWCAP2_WFXT		0x0000000080000000ul
> +#define	HWCAP2_EBF16		0x0000000100000000ul
> +#define	HWCAP2_SVE_EBF16	0x0000000200000000ul
> +#define	HWCAP2_CSSC		0x0000000400000000ul
> +#define	HWCAP2_RPRFM		0x0000000800000000ul
> +#define	HWCAP2_SVE2P1		0x0000001000000000ul
> +#define	HWCAP2_SME2		0x0000002000000000ul
> +#define	HWCAP2_SME2P1		0x0000004000000000ul
> +#define	HWCAP2_SME_I16I32	0x0000008000000000ul
> +#define	HWCAP2_SME_BI32I32	0x0000010000000000ul
> +#define	HWCAP2_SME_B16B16	0x0000020000000000ul
> +#define	HWCAP2_SME_F16F16	0x0000040000000000ul
> +#define	HWCAP2_MOPS		0x0000080000000000ul
> +#define	HWCAP2_HBC		0x0000100000000000ul
> +
> +#endif /* !_MACHINE_ELF_H_ */
> Index: sys/arch/hppa/include/elf.h
> ===================================================================
> RCS file: sys/arch/hppa/include/elf.h
> diff -N sys/arch/hppa/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/hppa/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,7 @@
> +/*	$OpenBSD$	*/
> +
> +/*
> + * This file is in the public domain.
> + */
> +
> +/* Nothing for now */
> Index: sys/arch/i386/include/elf.h
> ===================================================================
> RCS file: sys/arch/i386/include/elf.h
> diff -N sys/arch/i386/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/i386/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,7 @@
> +/*	$OpenBSD$	*/
> +
> +/*
> + * This file is in the public domain.
> + */
> +
> +/* Nothing for now */
> Index: sys/arch/m88k/include/elf.h
> ===================================================================
> RCS file: sys/arch/m88k/include/elf.h
> diff -N sys/arch/m88k/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/m88k/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,7 @@
> +/*	$OpenBSD$	*/
> +
> +/*
> + * This file is in the public domain.
> + */
> +
> +/* Nothing for now */
> Index: sys/arch/mips64/include/elf.h
> ===================================================================
> RCS file: sys/arch/mips64/include/elf.h
> diff -N sys/arch/mips64/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/mips64/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,7 @@
> +/*	$OpenBSD$	*/
> +
> +/*
> + * This file is in the public domain.
> + */
> +
> +/* Nothing for now */
> Index: sys/arch/powerpc/include/elf.h
> ===================================================================
> RCS file: sys/arch/powerpc/include/elf.h
> diff -N sys/arch/powerpc/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/powerpc/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,14 @@
> +/*	$OpenBSD$	*/
> +
> +/*
> + * This file is in the public domain.
> + */
> +
> +#ifndef _MACHINE_ELF_H_
> +#define	_MACHINE_ELF_H_ 1
> +
> +/*
> + * TODO FreeBSD puts PPC_FEATURE* in cpu.h
> + */
> +
> +#endif /* !_MACHINE_ELF_H_ */
> Index: sys/arch/powerpc64/include/elf.h
> ===================================================================
> RCS file: sys/arch/powerpc64/include/elf.h
> diff -N sys/arch/powerpc64/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/powerpc64/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,14 @@
> +/*	$OpenBSD$	*/
> +
> +/*
> + * This file is in the public domain.
> + */
> +
> +#ifndef _MACHINE_ELF_H_
> +#define	_MACHINE_ELF_H_ 1
> +
> +/*
> + * TODO FreeBSD puts PPC_FEATURE* in cpu.h
> + */
> +
> +#endif /* !_MACHINE_ELF_H_ */
> Index: sys/arch/riscv64/include/elf.h
> ===================================================================
> RCS file: sys/arch/riscv64/include/elf.h
> diff -N sys/arch/riscv64/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/riscv64/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,52 @@
> +/*	$OpenBSD$	*/
> +
> +/*-
> + * Copyright (c) 1996-1997 John D. Polstra.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + */
> +
> +#ifndef	_MACHINE_ELF_H_
> +#define	_MACHINE_ELF_H_
> +
> +/*
> + * ELF definitions for the RISC-V architecture.
> + */
> +
> +#ifdef _KERNEL
> +# define __HAVE_CPU_HWCAP
> +extern unsigned long	hwcap;
> +#endif /* _KERNEL */
> +
> +/* Flags passed in AT_HWCAP */
> +#define	HWCAP_ISA_BIT(c)	(1 << ((c) - 'a'))
> +#define	HWCAP_ISA_I		HWCAP_ISA_BIT('i')
> +#define	HWCAP_ISA_M		HWCAP_ISA_BIT('m')
> +#define	HWCAP_ISA_A		HWCAP_ISA_BIT('a')
> +#define	HWCAP_ISA_F		HWCAP_ISA_BIT('f')
> +#define	HWCAP_ISA_D		HWCAP_ISA_BIT('d')
> +#define	HWCAP_ISA_C		HWCAP_ISA_BIT('c')
> +#define	HWCAP_ISA_G		\
> +    (HWCAP_ISA_I | HWCAP_ISA_M | HWCAP_ISA_A | HWCAP_ISA_F | HWCAP_ISA_D)
> +
> +#endif /* !_MACHINE_ELF_H_ */
> Index: sys/arch/riscv64/riscv64/cpu.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/riscv64/riscv64/cpu.c,v
> diff -u -p -r1.19 cpu.c
> --- sys/arch/riscv64/riscv64/cpu.c	11 Jun 2024 15:44:55 -0000	1.19
> +++ sys/arch/riscv64/riscv64/cpu.c	10 Jul 2024 16:17:09 -0000
> @@ -28,6 +28,7 @@
>  #include <uvm/uvm.h>
>  
>  #include <machine/cpufunc.h>
> +#include <machine/elf.h>
>  #include <machine/fdt.h>
>  #include <machine/sbi.h>
>  
> @@ -235,6 +236,8 @@ cpu_attach(struct device *parent, struct
>  	} else {
>  #endif
>  		cpu_identify(ci);
> +
> +		hwcap |= HWCAP_ISA_G;

Hah, not advertising 'C' are we ;).

>  		if (OF_getproplen(ci->ci_node, "clocks") > 0) {
>  			cpu_node = ci->ci_node;
> Index: sys/arch/sh/include/elf.h
> ===================================================================
> RCS file: sys/arch/sh/include/elf.h
> diff -N sys/arch/sh/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/sh/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,7 @@
> +/*	$OpenBSD$	*/
> +
> +/*
> + * This file is in the public domain.
> + */
> +
> +/* Nothing for now */
> Index: sys/arch/sparc64/include/elf.h
> ===================================================================
> RCS file: sys/arch/sparc64/include/elf.h
> diff -N sys/arch/sparc64/include/elf.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/arch/sparc64/include/elf.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,7 @@
> +/*	$OpenBSD$	*/
> +
> +/*
> + * This file is in the public domain.
> + */
> +
> +/* Nothing for now */
> Index: sys/kern/exec_elf.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/exec_elf.c,v
> diff -u -p -r1.186 exec_elf.c
> --- sys/kern/exec_elf.c	2 Apr 2024 08:39:16 -0000	1.186
> +++ sys/kern/exec_elf.c	10 Jul 2024 16:17:09 -0000
> @@ -89,6 +89,7 @@
>  
>  #include <machine/reg.h>
>  #include <machine/exec.h>
> +#include <machine/elf.h>
>  
>  int	elf_load_file(struct proc *, char *, struct exec_package *,
>  	    struct elf_args *);
> @@ -994,6 +995,18 @@ exec_elf_fixup(struct proc *p, struct ex
>  		a->au_id = AUX_entry;
>  		a->au_v = ap->arg_entry;
>  		a++;
> +
> +#ifdef __HAVE_CPU_HWCAP
> +		a->au_id = AUX_hwcap;
> +		a->au_v = hwcap;
> +		a++;
> +#endif /* __HAVE_CPU_HWCAP */
> +
> +#ifdef __HAVE_CPU_HWCAP2
> +		a->au_id = AUX_hwcap2;
> +		a->au_v = hwcap2;
> +		a++;
> +#endif /* __HAVE_CPU_HWCAP2 */
>  
>  		a->au_id = AUX_openbsd_timekeep;
>  		a->au_v = p->p_p->ps_timekeep;
> Index: sys/sys/auxv.h
> ===================================================================
> RCS file: sys/sys/auxv.h
> diff -N sys/sys/auxv.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ sys/sys/auxv.h	10 Jul 2024 16:17:09 -0000
> @@ -0,0 +1,82 @@
> +/*	$OpenBSD$	*/
> +
> +/*-
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2017 Michal Meloun
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + */
> +
> +#ifndef	_SYS_AUXV_H_
> +#define	_SYS_AUXV_H_
> +
> +#include <sys/types.h>
> +#include <machine/elf.h>
> +
> +/* Values for a_type. */
> +#define	AT_NULL		0	/* Terminates the vector. */
> +#define	AT_IGNORE	1	/* Ignored entry. */
> +#define	AT_EXECFD	2	/* File descriptor of program to load. */
> +#define	AT_PHDR		3	/* Program header of program already loaded. */
> +#define	AT_PHENT	4	/* Size of each program header entry. */
> +#define	AT_PHNUM	5	/* Number of program header entries. */
> +#define	AT_PAGESZ	6	/* Page size in bytes. */
> +#define	AT_BASE		7	/* Interpreter's base address. */
> +#define	AT_FLAGS	8	/* Flags. */
> +#define	AT_ENTRY	9	/* Where interpreter should transfer control. */
> +#define	AT_NOTELF	10	/* Program is not ELF ?? */
> +#define	AT_UID		11	/* Real uid. */
> +#define	AT_EUID		12	/* Effective uid. */
> +#define	AT_GID		13	/* Real gid. */
> +#define	AT_EGID		14	/* Effective gid. */
> +#define	AT_EXECPATH	15	/* Path to the executable. */
> +#define	AT_CANARY	16	/* Canary for SSP. */
> +#define	AT_CANARYLEN	17	/* Length of the canary. */
> +#define	AT_OSRELDATE	18	/* OSRELDATE. */
> +#define	AT_NCPUS	19	/* Number of CPUs. */
> +#define	AT_PAGESIZES	20	/* Pagesizes. */
> +#define	AT_PAGESIZESLEN	21	/* Number of pagesizes. */
> +#define	AT_TIMEKEEP	22	/* Pointer to timehands. */
> +#define	AT_STACKPROT	23	/* Initial stack protection. */
> +#define	AT_EHDRFLAGS	24	/* e_flags field from elf hdr */
> +#define	AT_HWCAP	25	/* CPU feature flags. */
> +#define	AT_HWCAP2	26	/* CPU feature flags 2. */
> +#define	AT_BSDFLAGS	27	/* ELF BSD Flags. */
> +#define	AT_ARGC		28	/* Argument count */
> +#define	AT_ARGV		29	/* Argument vector */
> +#define	AT_ENVC		30	/* Environment count */
> +#define	AT_ENVV		31	/* Environment vector */
> +#define	AT_PS_STRINGS	32	/* struct ps_strings */
> +#define	AT_FXRNG	33	/* Pointer to root RNG seed version. */
> +#define	AT_KPRELOAD	34	/* Base of vdso, preloaded by rtld */
> +#define	AT_USRSTACKBASE	35	/* Top of user stack */
> +#define	AT_USRSTACKLIM	36	/* Grow limit of user stack */
> +
> +#define	AT_COUNT	37	/* Count of defined aux entry types. */
> +
> +__BEGIN_DECLS
> +int elf_aux_info(int aux, void *buf, int buflen);
> +__END_DECLS
> +
> +#endif /* !_SYS_AUXV_H_ */
> Index: sys/sys/exec_elf.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/exec_elf.h,v
> diff -u -p -r1.104 exec_elf.h
> --- sys/sys/exec_elf.h	22 Jun 2024 12:26:17 -0000	1.104
> +++ sys/sys/exec_elf.h	10 Jul 2024 16:17:09 -0000
> @@ -725,8 +725,10 @@ enum AuxID {
>  	AUX_phnum = 5,			/* # phdr entries */
>  	AUX_pagesz = 6,			/* PAGESIZE */
>  	AUX_base = 7,			/* base addr for ld.so or static PIE */
> -	AUX_flags = 8,			/* processor flags */
> +	AUX_flags = 8,			/* SUN processor flags */

I'd leave the comment as-is; while I do think only Sun actually used
this one, it isn't a Sun-specific one (those start at 2000), and other
OSes may have used this entry as well.

>  	AUX_entry = 9,			/* a.out entry */
> +	AUX_hwcap = 25,			/* processor flags */
> +	AUX_hwcap2 = 26,		/* processor flags (continued) */
>  	AUX_sun_uid = 2000,		/* euid */
>  	AUX_sun_ruid = 2001,		/* ruid */
>  	AUX_sun_gid = 2002,		/* egid */
> @@ -820,7 +822,7 @@ extern Elf_Dyn		_DYNAMIC[];
>  /*
>   * How many entries are in the AuxInfo array we pass to the process?
>   */
> -#define	ELF_AUX_ENTRIES	9
> +#define	ELF_AUX_ENTRIES	11
>  #define	ELF_AUX_WORDS	(sizeof(AuxInfo) * ELF_AUX_ENTRIES / sizeof(char *))
>  
>  struct exec_package;
> ? regress/lib/libc/elf_aux_info/obj
> Index: regress/lib/libc/elf_aux_info/Makefile
> ===================================================================
> RCS file: regress/lib/libc/elf_aux_info/Makefile
> diff -N regress/lib/libc/elf_aux_info/Makefile
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ regress/lib/libc/elf_aux_info/Makefile	10 Jul 2024 16:22:51 -0000
> @@ -0,0 +1,3 @@
> +PROG=elf_aux_info
> +
> +.include <bsd.regress.mk>
> Index: regress/lib/libc/elf_aux_info/elf_aux_info.c
> ===================================================================
> RCS file: regress/lib/libc/elf_aux_info/elf_aux_info.c
> diff -N regress/lib/libc/elf_aux_info/elf_aux_info.c
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ regress/lib/libc/elf_aux_info/elf_aux_info.c	10 Jul 2024 16:22:51 -0000
> @@ -0,0 +1,54 @@
> +#include <sys/auxv.h>
> +
> +#include <errno.h>
> +#include <stdio.h>
> +
> +int
> +main(void)
> +{
> +	int ret = 0;
> +	int a;
> +	unsigned long b;
> +
> +
> +	/* Should always succeed */
> +	if (elf_aux_info(AT_PAGESZ, &a, sizeof(a)))
> +		ret |= 1;
> +	else
> +		fprintf(stderr, "AT_PAGESZ %d\n", a);
> +
> +	/* Wrong size */
> +	if (elf_aux_info(AT_PAGESZ, &b, sizeof(b)) != EINVAL)
> +		ret |= 2;
> +
> +	/* Invalid request */
> +	if (elf_aux_info(-1, &a, sizeof(a)) != EINVAL)
> +		ret |= 4;
> +
> +	/* Should either succeed or fail with ENOENT if not supported */
> +	switch (elf_aux_info(AT_HWCAP, &b, sizeof(b))) {
> +	case 0:
> +		fprintf(stderr, "AT_HWCAP %lx\n", b);
> +		break;
> +	case ENOENT:
> +		break;
> +	default:
> +		ret |= 8;
> +	}
> +
> +	/* Should either succeed or fail with ENOENT if not supported */
> +	switch (elf_aux_info(AT_HWCAP2, &b, sizeof(b))) {
> +	case 0:
> +		fprintf(stderr, "AT_HWCAP2 %lx\n", b);
> +		break;
> +	case ENOENT:
> +		break;
> +	default:
> +		ret |= 16;
> +	}
> +
> +	if (ret)
> +		fprintf(stderr, "FAILED (status %x)\n", ret);
> +		
> +	return ret;
> +}
> 
> -- 
> jca
>