diff options
| author | Sarah Walker <sarah.walker2@arm.com> | 2026-01-13 14:24:00 +0000 |
|---|---|---|
| committer | Andrew Turner <andrew@FreeBSD.org> | 2026-01-13 15:28:04 +0000 |
| commit | 5eec3531204bd93426642a9c45b0c292a01447e4 (patch) | |
| tree | 78ebafee16675151d80bf0f4f72feb8d6122f603 /lib | |
| parent | a652357fb59f03bee85d61814002f9c60ea52340 (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.c | 31 |
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; } |
