From: Mark Kettenis Subject: Re: arm64 LSE support in userland: introduce elf_aux_info? To: Jeremie Courreges-Anglas Cc: deraadt@openbsd.org, tech@openbsd.org, brad@comstyle.com Date: Sun, 14 Jul 2024 10:31:15 +0200 > Date: Fri, 12 Jul 2024 18:23:25 +0200 > From: Jeremie Courreges-Anglas > > On Fri, Jul 12, 2024 at 01:18:41PM +0200, Mark Kettenis wrote: > > > Date: Wed, 10 Jul 2024 18:41:57 +0200 > > > From: Jeremie Courreges-Anglas > > > > > > 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 > > > > > > > > > > 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 > > > > > > > > > > > > > > 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 > > > > > 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 > > > 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. > > Rationale was: it's harmless and it gives the regress test something > to test on architectures with no hwcap support. > > > * 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 looked and decided to just drop them for now. There may be > candidates but I'd rather have them discussed later if at all. > > > * 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? > > That was my concern, indeed. Looking at the FreeBSD code, they're > also not supporting all the defines they provide, they even document > this in BUGS (which I trimmed and renamed to CAVEATS). Code using > that function should check for ENOENT to know whether a feature is not > supported. > > However, doing a quick audit using https://codesearch.debian.net/ it > seems only very few of them are used; actually I could find only one, > used in FreeBSD-specific code. So I trimmed the list, but keeping the > same AT_* values (they are supposed to match our AUX_* values). > I guess we could re-add some in case we find actual consumers. > > > * There are some tab vs. spaces inconsistencies, especially in the > > multiple-include protection stuff. > > They were present in the original files, I just didn't bother to fix > them. Done in the updated diff. > > > A few more comments below... > > Also adressed, thanks, see new diff. Christian and Stuart confirmed > they liked the idea. > > ok? I think this looks good. We can tweak the arm64 hwcap bits once this has landed in the tree. ok kettenis@ unless some show-stopper in your ports build shows up > diff --git a/lib/libc/Symbols.list b/lib/libc/Symbols.list > index eb4d78cc947..48c4965a6d9 100644 > --- a/lib/libc/Symbols.list > +++ b/lib/libc/Symbols.list > @@ -608,6 +608,7 @@ daemon > devname > dirfd > dirname > +elf_aux_info > endfsent > endgrent > endnetgrent > diff --git a/lib/libc/dlfcn/init.c b/lib/libc/dlfcn/init.c > index 9fc63c97f98..0cf4347631c 100644 > --- a/lib/libc/dlfcn/init.c > +++ b/lib/libc/dlfcn/init.c > @@ -49,6 +49,8 @@ char ***_csu_finish(char **_argv, char **_envp, void (*_cleanup)(void)); > /* 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, char **envp, dl_cb_cb *cb) > ; > 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; > diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc > index cf36ead40e9..1f1c25a9af5 100644 > --- a/lib/libc/gen/Makefile.inc > +++ b/lib/libc/gen/Makefile.inc > @@ -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 authenticate.c \ > > 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 \ > diff --git a/lib/libc/gen/elf_aux_info.3 b/lib/libc/gen/elf_aux_info.3 > new file mode 100644 > index 00000000000..c2a63c87e74 > --- /dev/null > +++ b/lib/libc/gen/elf_aux_info.3 > @@ -0,0 +1,74 @@ > +.\" $OpenBSD$ > +.\" > +.\" Origin: FreeBSD auxv.3 > +.\" > +.\" Copyright (c) 2019 Ian Lepore > +.\" > +.\" 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 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 can be requested (corresponding buffer sizes are > +specified in parenthesis): > +.Bl -tag -width AT_HWCAP2 > +.It AT_HWCAP > +CPU / hardware feature flags > +.Dv (sizeof(unsigned long)) . > +.It AT_HWCAP2 > +CPU / hardware feature flags > +.Dv (sizeof(unsigned long)) . > +.It AT_PAGESZ > +Page size in bytes > +.Dv (sizeof(int)) . > +.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 . > diff --git a/lib/libc/gen/elf_aux_info.c b/lib/libc/gen/elf_aux_info.c > new file mode 100644 > index 00000000000..eef979a89e7 > --- /dev/null > +++ b/lib/libc/gen/elf_aux_info.c > @@ -0,0 +1,70 @@ > +/* $OpenBSD$ */ > + > +/* > + * Copyright (c) 2024 Jeremie Courreges-Anglas > + * > + * 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 > +#include > + > +#include > + > +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; > +} > diff --git a/lib/libc/hidden/sys/auxv.h b/lib/libc/hidden/sys/auxv.h > new file mode 100644 > index 00000000000..8d25aaaa826 > --- /dev/null > +++ b/lib/libc/hidden/sys/auxv.h > @@ -0,0 +1,26 @@ > +/* $OpenBSD$ */ > + > +/* > + * Copyright (c) 2024 Jeremie Courreges-Anglas > + * > + * 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 > + > +PROTO_DEPRECATED(elf_aux_info); > + > +#endif /* !_LIBC_SYS_AUXV_H_ */ > diff --git a/regress/lib/libc/Makefile b/regress/lib/libc/Makefile > index 8b5e4d45034..f27137d3f64 100644 > --- a/regress/lib/libc/Makefile > +++ b/regress/lib/libc/Makefile > @@ -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 > diff --git a/regress/lib/libc/elf_aux_info/Makefile b/regress/lib/libc/elf_aux_info/Makefile > new file mode 100644 > index 00000000000..2885fb18512 > --- /dev/null > +++ b/regress/lib/libc/elf_aux_info/Makefile > @@ -0,0 +1,3 @@ > +PROG=elf_aux_info > + > +.include > diff --git a/regress/lib/libc/elf_aux_info/elf_aux_info.c b/regress/lib/libc/elf_aux_info/elf_aux_info.c > new file mode 100644 > index 00000000000..481085d6d97 > --- /dev/null > +++ b/regress/lib/libc/elf_aux_info/elf_aux_info.c > @@ -0,0 +1,54 @@ > +#include > + > +#include > +#include > + > +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; > +} > diff --git a/sys/arch/alpha/include/elf.h b/sys/arch/alpha/include/elf.h > new file mode 100644 > index 00000000000..5864bc487f4 > --- /dev/null > +++ b/sys/arch/alpha/include/elf.h > @@ -0,0 +1,7 @@ > +/* $OpenBSD$ */ > + > +/* > + * This file is in the public domain. > + */ > + > +/* Nothing for now */ > diff --git a/sys/arch/amd64/include/elf.h b/sys/arch/amd64/include/elf.h > new file mode 100644 > index 00000000000..5864bc487f4 > --- /dev/null > +++ b/sys/arch/amd64/include/elf.h > @@ -0,0 +1,7 @@ > +/* $OpenBSD$ */ > + > +/* > + * This file is in the public domain. > + */ > + > +/* Nothing for now */ > diff --git a/sys/arch/arm/include/elf.h b/sys/arch/arm/include/elf.h > new file mode 100644 > index 00000000000..a17ba1ae396 > --- /dev/null > +++ b/sys/arch/arm/include/elf.h > @@ -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_ > + > +/* > + * 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_ */ > diff --git a/sys/arch/arm64/arm64/cpu.c b/sys/arch/arm64/arm64/cpu.c > index ae17940fbc8..01db0046cb4 100644 > --- a/sys/arch/arm64/arm64/cpu.c > +++ b/sys/arch/arm64/arm64/cpu.c > @@ -32,6 +32,7 @@ > #include > > #include > +#include > > #include > #include > @@ -716,6 +717,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) { > diff --git a/sys/arch/arm64/include/elf.h b/sys/arch/arm64/include/elf.h > new file mode 100644 > index 00000000000..53be0b910c2 > --- /dev/null > +++ b/sys/arch/arm64/include/elf.h > @@ -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_ */ > diff --git a/sys/arch/hppa/include/elf.h b/sys/arch/hppa/include/elf.h > new file mode 100644 > index 00000000000..5864bc487f4 > --- /dev/null > +++ b/sys/arch/hppa/include/elf.h > @@ -0,0 +1,7 @@ > +/* $OpenBSD$ */ > + > +/* > + * This file is in the public domain. > + */ > + > +/* Nothing for now */ > diff --git a/sys/arch/i386/include/elf.h b/sys/arch/i386/include/elf.h > new file mode 100644 > index 00000000000..5864bc487f4 > --- /dev/null > +++ b/sys/arch/i386/include/elf.h > @@ -0,0 +1,7 @@ > +/* $OpenBSD$ */ > + > +/* > + * This file is in the public domain. > + */ > + > +/* Nothing for now */ > diff --git a/sys/arch/m88k/include/elf.h b/sys/arch/m88k/include/elf.h > new file mode 100644 > index 00000000000..5864bc487f4 > --- /dev/null > +++ b/sys/arch/m88k/include/elf.h > @@ -0,0 +1,7 @@ > +/* $OpenBSD$ */ > + > +/* > + * This file is in the public domain. > + */ > + > +/* Nothing for now */ > diff --git a/sys/arch/mips64/include/elf.h b/sys/arch/mips64/include/elf.h > new file mode 100644 > index 00000000000..5864bc487f4 > --- /dev/null > +++ b/sys/arch/mips64/include/elf.h > @@ -0,0 +1,7 @@ > +/* $OpenBSD$ */ > + > +/* > + * This file is in the public domain. > + */ > + > +/* Nothing for now */ > diff --git a/sys/arch/powerpc/include/elf.h b/sys/arch/powerpc/include/elf.h > new file mode 100644 > index 00000000000..821ba5ae3cb > --- /dev/null > +++ b/sys/arch/powerpc/include/elf.h > @@ -0,0 +1,14 @@ > +/* $OpenBSD$ */ > + > +/* > + * This file is in the public domain. > + */ > + > +#ifndef _MACHINE_ELF_H_ > +#define _MACHINE_ELF_H_ > + > +/* > + * TODO FreeBSD puts PPC_FEATURE* in cpu.h > + */ > + > +#endif /* !_MACHINE_ELF_H_ */ > diff --git a/sys/arch/powerpc64/include/elf.h b/sys/arch/powerpc64/include/elf.h > new file mode 100644 > index 00000000000..821ba5ae3cb > --- /dev/null > +++ b/sys/arch/powerpc64/include/elf.h > @@ -0,0 +1,14 @@ > +/* $OpenBSD$ */ > + > +/* > + * This file is in the public domain. > + */ > + > +#ifndef _MACHINE_ELF_H_ > +#define _MACHINE_ELF_H_ > + > +/* > + * TODO FreeBSD puts PPC_FEATURE* in cpu.h > + */ > + > +#endif /* !_MACHINE_ELF_H_ */ > diff --git a/sys/arch/riscv64/include/elf.h b/sys/arch/riscv64/include/elf.h > new file mode 100644 > index 00000000000..de902743da5 > --- /dev/null > +++ b/sys/arch/riscv64/include/elf.h > @@ -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_ */ > diff --git a/sys/arch/riscv64/riscv64/cpu.c b/sys/arch/riscv64/riscv64/cpu.c > index 0d40b236569..4e6c08adacf 100644 > --- a/sys/arch/riscv64/riscv64/cpu.c > +++ b/sys/arch/riscv64/riscv64/cpu.c > @@ -28,6 +28,7 @@ > #include > > #include > +#include > #include > #include > > @@ -236,6 +237,8 @@ cpu_attach(struct device *parent, struct device *dev, void *aux) > #endif > cpu_identify(ci); > > + hwcap |= HWCAP_ISA_G | HWCAP_ISA_C; > + > if (OF_getproplen(ci->ci_node, "clocks") > 0) { > cpu_node = ci->ci_node; > cpu_cpuspeed = cpu_clockspeed; > diff --git a/sys/arch/sh/include/elf.h b/sys/arch/sh/include/elf.h > new file mode 100644 > index 00000000000..5864bc487f4 > --- /dev/null > +++ b/sys/arch/sh/include/elf.h > @@ -0,0 +1,7 @@ > +/* $OpenBSD$ */ > + > +/* > + * This file is in the public domain. > + */ > + > +/* Nothing for now */ > diff --git a/sys/arch/sparc64/include/elf.h b/sys/arch/sparc64/include/elf.h > new file mode 100644 > index 00000000000..5864bc487f4 > --- /dev/null > +++ b/sys/arch/sparc64/include/elf.h > @@ -0,0 +1,7 @@ > +/* $OpenBSD$ */ > + > +/* > + * This file is in the public domain. > + */ > + > +/* Nothing for now */ > diff --git a/sys/sys/auxv.h b/sys/sys/auxv.h > new file mode 100644 > index 00000000000..26de550fdc6 > --- /dev/null > +++ b/sys/sys/auxv.h > @@ -0,0 +1,50 @@ > +/* $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 > +#include > + > +/* Values for a_type. */ > +#define AT_NULL 0 /* Terminates the vector. */ > +#define AT_IGNORE 1 /* Ignored entry. */ > +#define AT_PAGESZ 6 /* Page size in bytes. */ > +#define AT_HWCAP 25 /* CPU feature flags. */ > +#define AT_HWCAP2 26 /* CPU feature flags 2. */ > + > +#define AT_COUNT 27 /* Count of defined aux entry types. */ > + > +__BEGIN_DECLS > +int elf_aux_info(int aux, void *buf, int buflen); > +__END_DECLS > + > +#endif /* !_SYS_AUXV_H_ */ > diff --git a/sys/sys/exec_elf.h b/sys/sys/exec_elf.h > index 7825dff418b..1b45c3ebb70 100644 > --- a/sys/sys/exec_elf.h > +++ b/sys/sys/exec_elf.h > @@ -727,6 +727,8 @@ enum AuxID { > AUX_base = 7, /* base addr for ld.so or static PIE */ > AUX_flags = 8, /* processor flags */ > 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; > > > -- > jca >