summaryrefslogtreecommitdiff
path: root/linker/linker.cpp
diff options
context:
space:
mode:
authorPeter Collingbourne <pcc@google.com>2019-08-07 19:06:00 -0700
committerPeter Collingbourne <pcc@google.com>2019-08-15 09:21:34 -0700
commit191ecdc49ba18fc07d62d419fd51cc7dee4190f8 (patch)
treebfd1dc23f8fed1ddeee6b62a81623b32159b6799 /linker/linker.cpp
parent639ad55176c78bfd70c3786a92a05dd3d2299953 (diff)
Fix a few bionic test failures caused by hwasan global instrumentation.
The call to the load hook needs to be moved before the call to link_image() because the latter calls ifunc resolvers which might access global variables. This fixes a bunch of ifunc tests. The dlfcn.segment_gap test is currently failing. One problem is that the name of the .bss.end_of_gap section changes as a result of global instrumentation. Add some wildcards in so that we match both names. The other problem seems to be the same as b/139089152. It turns out that we need to untag pointers in a few more places. Since we have quite a few of these now it seems worth creating a function for it. Test: bionic-unit-tests Change-Id: I44e2b0904faacdda7cc0c5e844ffc09de01dea2d
Diffstat (limited to 'linker/linker.cpp')
-rw-r--r--linker/linker.cpp10
1 files changed, 6 insertions, 4 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 0361a8ab3..e41194d1a 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -951,7 +951,9 @@ static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns,
}
soinfo* find_containing_library(const void* p) {
- ElfW(Addr) address = reinterpret_cast<ElfW(Addr)>(p);
+ // Addresses within a library may be tagged if they point to globals. Untag
+ // them so that the bounds check succeeds.
+ ElfW(Addr) address = reinterpret_cast<ElfW(Addr)>(untag_address(p));
for (soinfo* si = solist_get_head(); si != nullptr; si = si->next) {
if (address < si->base || address - si->base >= si->size) {
continue;
@@ -1901,13 +1903,13 @@ bool find_libraries(android_namespace_t* ns,
// flag is set.
link_extinfo = extinfo;
}
+ if (__libc_shared_globals()->load_hook) {
+ __libc_shared_globals()->load_hook(si->load_bias, si->phdr, si->phnum);
+ }
if (!si->link_image(global_group, local_group, link_extinfo, &relro_fd_offset) ||
!get_cfi_shadow()->AfterLoad(si, solist_get_head())) {
return false;
}
- if (__libc_shared_globals()->load_hook) {
- __libc_shared_globals()->load_hook(si->load_bias, si->phdr, si->phnum);
- }
}
return true;