The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=5eec3531204bd93426642a9c45b0c292a01447e4
commit 5eec3531204bd93426642a9c45b0c292a01447e4 Author: Sarah Walker <[email protected]> AuthorDate: 2026-01-13 14:24:00 +0000 Commit: Andrew Turner <[email protected]> CommitDate: 2026-01-13 15:28:04 +0000 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 --- lib/libc/csu/aarch64/reloc.c | 31 ++++++++++++++++++++++++++++--- 1 file 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; }
