summaryrefslogtreecommitdiff
path: root/linker/linker.cpp
diff options
context:
space:
mode:
authorPeter Collingbourne <pcc@google.com>2019-10-28 10:57:26 -0700
committerPeter Collingbourne <pcc@google.com>2019-10-28 20:20:29 -0700
commite949195f6489653ee3771535951ed06973246c3e (patch)
tree204c6f7112e6524c0380cf683f2954753471fd26 /linker/linker.cpp
parent9615e0ddacafcc728ff432fce61eaa0a1049880e (diff)
Adopt GNU calling convention for ifunc resolvers.
In order for an ifunc resolver to detect the presence of certain CPU features, access to getauxval(AT_HWCAP) or getauxval(AT_HWCAP2) may be required. In order for getauxval() to work, it needs to access the pointer to the auxiliary vector stored by the linker in the libc shared globals data structure. Accessing the shared globals requires libc to call the __libc_shared_globals() function exported by the linker. However, in order to call this function, libc must be fully relocated, which is not guaranteed to be the case at the point when ifunc resolvers are called. glibc solves this problem by passing the values of getauxval(AT_HWCAP) (and getauxval(AT_HWCAP2) on aarch64) as arguments to the ifunc resolver. Since this seems to be not only the most straightforward way to solve the problem but also improves our compatibility with glibc, we adopt their calling convention. This change is ABI compatible with old resolvers because the arguments are passed in registers, so the old resolvers will simply ignore the new arguments. Bug: 135772972 Change-Id: Ie65bd6e7067f0c878df3d348c815fda61dc12de2
Diffstat (limited to 'linker/linker.cpp')
-rw-r--r--linker/linker.cpp7
1 files changed, 3 insertions, 4 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 3c30e73b3..f4fccac1e 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -68,6 +68,7 @@
#include "linker_tls.h"
#include "linker_utils.h"
+#include "private/bionic_call_ifunc_resolver.h"
#include "private/bionic_globals.h"
#include "android-base/macros.h"
#include "android-base/strings.h"
@@ -2689,11 +2690,9 @@ bool link_namespaces_all_libs(android_namespace_t* namespace_from,
ElfW(Addr) call_ifunc_resolver(ElfW(Addr) resolver_addr) {
if (g_is_ldd) return 0;
- typedef ElfW(Addr) (*ifunc_resolver_t)(void);
- ifunc_resolver_t ifunc_resolver = reinterpret_cast<ifunc_resolver_t>(resolver_addr);
- ElfW(Addr) ifunc_addr = ifunc_resolver();
+ ElfW(Addr) ifunc_addr = __bionic_call_ifunc_resolver(resolver_addr);
TRACE_TYPE(RELO, "Called ifunc_resolver@%p. The result is %p",
- ifunc_resolver, reinterpret_cast<void*>(ifunc_addr));
+ reinterpret_cast<void *>(resolver_addr), reinterpret_cast<void*>(ifunc_addr));
return ifunc_addr;
}