summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSarah Walker <sarah.walker2@arm.com>2026-01-13 14:24:00 +0000
committerAndrew Turner <andrew@FreeBSD.org>2026-01-13 15:28:04 +0000
commit5eec3531204bd93426642a9c45b0c292a01447e4 (patch)
tree78ebafee16675151d80bf0f4f72feb8d6122f603 /lib
parenta652357fb59f03bee85d61814002f9c60ea52340 (diff)
libc/csu: Pass HWCAP flags to ifunc resolver functions
Function arguments are based on Section 9.4.1 "GNU C Library IFUNC interface" from "System V ABI for the Arm 64-bit Architecture (AArch64)", 2025Q1. (https://github.com/ARM-software/abi-aa/releases/download/2025Q1/sysvabi64.pdf) Reviewed by: andrew Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D54599
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/csu/aarch64/reloc.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/lib/libc/csu/aarch64/reloc.c b/lib/libc/csu/aarch64/reloc.c
index 4ba7920bcb07..77e8a38176ce 100644
--- a/lib/libc/csu/aarch64/reloc.c
+++ b/lib/libc/csu/aarch64/reloc.c
@@ -25,17 +25,42 @@
*/
#include <sys/cdefs.h>
+#include <machine/ifunc.h>
+
+static __ifunc_arg_t ifunc_arg;
static void
-ifunc_init(const Elf_Auxinfo *aux __unused)
+ifunc_init(const Elf_Auxinfo *aux)
{
+ ifunc_arg._size = sizeof(ifunc_arg);
+ ifunc_arg._hwcap = 0;
+ ifunc_arg._hwcap2 = 0;
+ ifunc_arg._hwcap3 = 0;
+ ifunc_arg._hwcap4 = 0;
+
+ for (; aux->a_type != AT_NULL; aux++) {
+ switch (aux->a_type) {
+ case AT_HWCAP:
+ ifunc_arg._hwcap = aux->a_un.a_val | _IFUNC_ARG_HWCAP;
+ break;
+ case AT_HWCAP2:
+ ifunc_arg._hwcap2 = aux->a_un.a_val;
+ break;
+ case AT_HWCAP3:
+ ifunc_arg._hwcap3 = aux->a_un.a_val;
+ break;
+ case AT_HWCAP4:
+ ifunc_arg._hwcap4 = aux->a_un.a_val;
+ break;
+ }
+ }
}
static void
crt1_handle_rela(const Elf_Rela *r)
{
typedef Elf_Addr (*ifunc_resolver_t)(
- uint64_t, uint64_t, uint64_t, uint64_t,
+ uint64_t, const __ifunc_arg_t *, uint64_t, uint64_t,
uint64_t, uint64_t, uint64_t, uint64_t);
Elf_Addr *ptr, *where, target;
@@ -43,7 +68,7 @@ crt1_handle_rela(const Elf_Rela *r)
case R_AARCH64_IRELATIVE:
ptr = (Elf_Addr *)r->r_addend;
where = (Elf_Addr *)r->r_offset;
- target = ((ifunc_resolver_t)ptr)(0, 0, 0, 0, 0, 0, 0, 0);
+ target = ((ifunc_resolver_t)ptr)(ifunc_arg._hwcap, &ifunc_arg, 0, 0, 0, 0, 0, 0);
*where = target;
break;
}