The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=a652357fb59f03bee85d61814002f9c60ea52340
commit a652357fb59f03bee85d61814002f9c60ea52340 Author: Sarah Walker <[email protected]> AuthorDate: 2026-01-13 14:23:03 +0000 Commit: Andrew Turner <[email protected]> CommitDate: 2026-01-13 15:28:04 +0000 rtld-elf: 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: kib, andrew Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D54559 --- libexec/rtld-elf/aarch64/reloc.c | 15 +++++++++++++-- libexec/rtld-elf/aarch64/rtld_machdep.h | 10 +++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/libexec/rtld-elf/aarch64/reloc.c b/libexec/rtld-elf/aarch64/reloc.c index 62d664f8fb80..85f7c1b4022a 100644 --- a/libexec/rtld-elf/aarch64/reloc.c +++ b/libexec/rtld-elf/aarch64/reloc.c @@ -444,10 +444,21 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target, return (target); } +__ifunc_arg_t ifunc_arg = { + ._size = sizeof(__ifunc_arg_t) +}; + void -ifunc_init(Elf_Auxinfo *aux_info[__min_size(AT_COUNT)] __unused) +ifunc_init(Elf_Auxinfo *aux_info[__min_size(AT_COUNT)]) { - + ifunc_arg._hwcap = aux_info[AT_HWCAP] != NULL ? + (aux_info[AT_HWCAP]->a_un.a_val | _IFUNC_ARG_HWCAP) : 0; + ifunc_arg._hwcap2 = aux_info[AT_HWCAP2] != NULL ? + aux_info[AT_HWCAP2]->a_un.a_val : 0; + ifunc_arg._hwcap3 = aux_info[AT_HWCAP3] != NULL ? + aux_info[AT_HWCAP3]->a_un.a_val : 0; + ifunc_arg._hwcap4 = aux_info[AT_HWCAP4] != NULL ? + aux_info[AT_HWCAP4]->a_un.a_val : 0; } /* diff --git a/libexec/rtld-elf/aarch64/rtld_machdep.h b/libexec/rtld-elf/aarch64/rtld_machdep.h index d689ae354c49..4b5ad523ee87 100644 --- a/libexec/rtld-elf/aarch64/rtld_machdep.h +++ b/libexec/rtld-elf/aarch64/rtld_machdep.h @@ -33,6 +33,7 @@ #include <sys/types.h> #include <machine/atomic.h> +#include <machine/ifunc.h> #include <machine/tls.h> struct Struct_Obj_Entry; @@ -67,6 +68,8 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target, #define call_init_pointer(obj, target) \ (((InitArrFunc)(target))(main_argc, main_argv, environ)) +extern struct __ifunc_arg_t ifunc_arg; + /* * Pass zeros into the ifunc resolver so we can change them later. The first * 8 arguments on arm64 are passed in registers so make them known values @@ -74,9 +77,10 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target, * no arguments are passed in, and if this changes later will be able to * compare the argument with 0 to see if it is set. */ -#define call_ifunc_resolver(ptr) \ - (((Elf_Addr (*)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, \ - uint64_t, uint64_t, uint64_t))ptr)(0, 0, 0, 0, 0, 0, 0, 0)) +#define call_ifunc_resolver(ptr) \ + (((Elf_Addr (*)(uint64_t, const struct __ifunc_arg_t *, uint64_t, \ + uint64_t, uint64_t, uint64_t, uint64_t, uint64_t))ptr)( \ + ifunc_arg._hwcap, &ifunc_arg, 0, 0, 0, 0, 0, 0)) #define round(size, align) \ (((size) + (align) - 1) & ~((align) - 1))
