Download raw body.
arm64 LSE support in userland: introduce elf_aux_info?
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 <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.
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?
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 <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 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 <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;
+}
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 <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_ */
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 <bsd.regress.mk>
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 <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;
+}
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 <uvm/uvm.h>
#include <machine/fdt.h>
+#include <machine/elf.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_clock.h>
@@ -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 <uvm/uvm.h>
#include <machine/cpufunc.h>
+#include <machine/elf.h>
#include <machine/fdt.h>
#include <machine/sbi.h>
@@ -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 <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_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
arm64 LSE support in userland: introduce elf_aux_info?