From c2048944ff8d9f2993264b45dfabf18d9036e379 Mon Sep 17 00:00:00 2001 From: Dmitriy Ivanov Date: Fri, 29 Aug 2014 10:15:25 -0700 Subject: [PATCH] Look into ld_preloads before current library Change lookup order during relocation so that ld_preloads always precede caller (unless caller is main executable). Asan needs this change in order to intercept libc->libc calls. Bug: 15432753 (cherry picked from commit 05e190c093ad5b04691ed87100a711ef91f380b0) Change-Id: I5bfb58e18015b1ec5b77842dbb37fb122fa1fd1a --- linker/linker.cpp | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/linker/linker.cpp b/linker/linker.cpp index 63c41c079..919f8c04a 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -525,6 +525,15 @@ static ElfW(Sym)* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi, s *lsi = si; goto done; } + + /* Next, look for it in the preloads list */ + for (int i = 0; g_ld_preloads[i] != NULL; i++) { + s = soinfo_elf_lookup(g_ld_preloads[i], elf_hash, name); + if (s != NULL) { + *lsi = g_ld_preloads[i]; + goto done; + } + } } else { /* Order of symbol lookup is controlled by DT_SYMBOLIC flag */ @@ -542,6 +551,15 @@ static ElfW(Sym)* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi, s *lsi = somain; goto done; } + + /* Next, look for it in the preloads list */ + for (int i = 0; g_ld_preloads[i] != NULL; i++) { + s = soinfo_elf_lookup(g_ld_preloads[i], elf_hash, name); + if (s != NULL) { + *lsi = g_ld_preloads[i]; + goto done; + } + } } /* Look for symbols in the local scope (the object who is @@ -573,16 +591,16 @@ static ElfW(Sym)* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi, s *lsi = somain; goto done; } - } - } - } - /* Next, look for it in the preloads list */ - for (int i = 0; g_ld_preloads[i] != nullptr; i++) { - s = soinfo_elf_lookup(g_ld_preloads[i], elf_hash, name); - if (s != nullptr) { - *lsi = g_ld_preloads[i]; - goto done; + /* Next, look for it in the preloads list */ + for (int i = 0; g_ld_preloads[i] != NULL; i++) { + s = soinfo_elf_lookup(g_ld_preloads[i], elf_hash, name); + if (s != NULL) { + *lsi = g_ld_preloads[i]; + goto done; + } + } + } } }