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
This commit is contained in:
committed by
Andrew Turner
parent
449339bdba
commit
a652357fb5
@@ -444,10 +444,21 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
||||
return (target);
|
||||
}
|
||||
|
||||
void
|
||||
ifunc_init(Elf_Auxinfo *aux_info[__min_size(AT_COUNT)] __unused)
|
||||
{
|
||||
__ifunc_arg_t ifunc_arg = {
|
||||
._size = sizeof(__ifunc_arg_t)
|
||||
};
|
||||
|
||||
void
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user