diff options
author | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2019-04-23 15:59:34 +0100 |
---|---|---|
committer | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2019-07-04 11:13:32 +0100 |
commit | 2b8a3c86e7606cf1b0a997dad8af2d45ae8989c3 (patch) | |
tree | c4e4865f35dec331c65e487baaa4589ece50d097 /sysdeps/aarch64/dl-irel.h | |
parent | 41d6f74e6cb6a92ab428c11ee1e408b2a16aa1b0 (diff) | |
download | glibc-2b8a3c86e7606cf1b0a997dad8af2d45ae8989c3.tar.gz glibc-2b8a3c86e7606cf1b0a997dad8af2d45ae8989c3.tar.xz glibc-2b8a3c86e7606cf1b0a997dad8af2d45ae8989c3.zip |
aarch64: new ifunc resolver ABI
Passing a second argument to the ifunc resolver allows accessing AT_HWCAP2 values from the resolver. AArch64 will start using AT_HWCAP2 on linux because for ilp32 to remain compatible with lp64 ABI no more than 32bit hwcap flags can be in AT_HWCAP which is already used up. Currently the relocation ordering logic does not guarantee that ifunc resolvers can call libc apis or access libc objects, so only the resolver arguments and runtime environment dependent instructions can be used to do the dispatch (this affects ifunc resolvers outside of the libc). Since ifunc resolver is target specific and only supposed to be called by the dynamic linker, the call ABI can be changed in a backward compatible way: Old call ABI passed hwcap as uint64_t, new abi sets the _IFUNC_ARG_HWCAP flag in the hwcap and passes a second argument that's a pointer to an extendible struct. A resolver has to check the _IFUNC_ARG_HWCAP flag before accessing the second argument. The new sys/ifunc.h installed header has the definitions for the new ABI, everything is in the implementation reserved namespace. An alternative approach is to try to support extern calls from ifunc resolvers such as getauxval, but that seems non-trivial https://sourceware.org/ml/libc-alpha/2017-01/msg00468.html * sysdeps/aarch64/Makefile: Install sys/ifunc.h and add tests. * sysdeps/aarch64/dl-irel.h (elf_ifunc_invoke): Update to new ABI. * sysdeps/aarch64/sys/ifunc.h: New file. * sysdeps/aarch64/tst-ifunc-arg-1.c: New file. * sysdeps/aarch64/tst-ifunc-arg-2.c: New file.
Diffstat (limited to 'sysdeps/aarch64/dl-irel.h')
-rw-r--r-- | sysdeps/aarch64/dl-irel.h | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/sysdeps/aarch64/dl-irel.h b/sysdeps/aarch64/dl-irel.h index 4f669e70d7..8db6ef57dd 100644 --- a/sysdeps/aarch64/dl-irel.h +++ b/sysdeps/aarch64/dl-irel.h @@ -24,6 +24,7 @@ #include <unistd.h> #include <ldsodefs.h> #include <sysdep.h> +#include <sys/ifunc.h> #define ELF_MACHINE_IRELA 1 @@ -31,7 +32,13 @@ static inline ElfW(Addr) __attribute ((always_inline)) elf_ifunc_invoke (ElfW(Addr) addr) { - return ((ElfW(Addr) (*) (uint64_t)) (addr)) (GLRO(dl_hwcap)); + __ifunc_arg_t arg; + + arg._size = sizeof (arg); + arg._hwcap = GLRO(dl_hwcap); + arg._hwcap2 = GLRO(dl_hwcap2); + return ((ElfW(Addr) (*) (uint64_t, const __ifunc_arg_t *)) (addr)) + (GLRO(dl_hwcap) | _IFUNC_ARG_HWCAP, &arg); } static inline void |