From b364d9538073716a256b37a790ff7bf3ddbb4f1b Mon Sep 17 00:00:00 2001 From: Dmitriy Ivanov <dimitry@google.com> Date: Tue, 16 Sep 2014 14:31:06 -0700 Subject: [PATCH] Remove has_DT_SYMBOLIC flag From the elf-spec: "Symbolically bound shared objects are identified by the .dynamic entry DT_SYMBOLIC. This tag is informational only; the runtime linker processes symbol lookups from these objects in the same manner as any other object." Bug: 18186310 (cherry picked from commit 8f61d991831f0ea515fa50a5c38dbbcfbab0dd28) Change-Id: I37024799ac8d1837993c8ae78780a448bedd6539 --- linker/dlfcn.cpp | 1 - linker/linker.cpp | 131 ++++++++++++++-------------------------------- linker/linker.h | 2 +- 3 files changed, 40 insertions(+), 94 deletions(-) diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp index 59f673ad5..c02bfb89a 100644 --- a/linker/dlfcn.cpp +++ b/linker/dlfcn.cpp @@ -244,7 +244,6 @@ soinfo* get_libdl_info() { __libdl_info.nchain = sizeof(g_libdl_chains)/sizeof(unsigned); __libdl_info.bucket = g_libdl_buckets; __libdl_info.chain = g_libdl_chains; - __libdl_info.has_DT_SYMBOLIC = true; __libdl_info.ref_count = 1; } diff --git a/linker/linker.cpp b/linker/linker.cpp index bd05498b0..246475b4e 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -487,117 +487,65 @@ static ElfW(Sym)* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi) { ElfW(Sym)* s = nullptr; if (somain != nullptr) { - /* - * Local scope is executable scope. Just start looking into it right away - * for the shortcut. - */ + DEBUG("%s: looking up %s in executable %s", + si->name, name, somain->name); - if (si == somain) { - s = soinfo_elf_lookup(si, elf_hash, name); - if (s != nullptr) { - *lsi = si; - goto done; - } + // 1. Look for it in the main executable + s = soinfo_elf_lookup(somain, elf_hash, name); + if (s != nullptr) { + *lsi = somain; + } - /* Next, look for it in the preloads list */ + // 2. Look for it in the ld_preloads + if (s == nullptr) { 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 */ - - /* - * If this object was built with symbolic relocations disabled, the - * first place to look to resolve external references is the main - * executable. - */ - - if (!si->has_DT_SYMBOLIC) { - DEBUG("%s: looking up %s in executable %s", - si->name, name, somain->name); - s = soinfo_elf_lookup(somain, elf_hash, name); if (s != nullptr) { - *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; - } + *lsi = g_ld_preloads[i]; + break; } } + } - /* Look for symbols in the local scope (the object who is - * searching). This happens with C++ templates on x86 for some - * reason. - * - * Notes on weak symbols: - * The ELF specs are ambiguous about treatment of weak definitions in - * dynamic linking. Some systems return the first definition found - * and some the first non-weak definition. This is system dependent. - * Here we return the first definition found for simplicity. */ + /* Look for symbols in the local scope (the object who is + * searching). This happens with C++ templates on x86 for some + * reason. + * + * Notes on weak symbols: + * The ELF specs are ambiguous about treatment of weak definitions in + * dynamic linking. Some systems return the first definition found + * and some the first non-weak definition. This is system dependent. + * Here we return the first definition found for simplicity. */ + if (s == nullptr) { s = soinfo_elf_lookup(si, elf_hash, name); if (s != nullptr) { *lsi = si; - goto done; - } - - /* - * If this object was built with -Bsymbolic and symbol is not found - * in the local scope, try to find the symbol in the main executable. - */ - - if (si->has_DT_SYMBOLIC) { - DEBUG("%s: looking up %s in executable %s after local scope", - si->name, name, somain->name); - s = soinfo_elf_lookup(somain, elf_hash, name); - if (s != nullptr) { - *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; - } - } } } } - si->get_children().visit([&](soinfo* child) { - DEBUG("%s: looking up %s in %s", si->name, name, child->name); - s = soinfo_elf_lookup(child, elf_hash, name); - if (s != nullptr) { - *lsi = child; - return false; - } - return true; - }); + if (s == nullptr) { + si->get_children().visit([&](soinfo* child) { + DEBUG("%s: looking up %s in %s", si->name, name, child->name); + s = soinfo_elf_lookup(child, elf_hash, name); + if (s != nullptr) { + *lsi = child; + return false; + } + return true; + }); + } -done: if (s != nullptr) { TRACE_TYPE(LOOKUP, "si %s sym %s s->st_value = %p, " "found in %s, base = %p, load bias = %p", si->name, name, reinterpret_cast<void*>(s->st_value), (*lsi)->name, reinterpret_cast<void*>((*lsi)->base), reinterpret_cast<void*>((*lsi)->load_bias)); - return s; } - return nullptr; + return s; } // Each size has it's own allocator. @@ -2042,7 +1990,7 @@ bool soinfo::PrelinkImage() { break; #endif case DT_SYMBOLIC: - has_DT_SYMBOLIC = true; + // ignored break; case DT_NEEDED: ++needed_count; @@ -2056,9 +2004,6 @@ bool soinfo::PrelinkImage() { has_text_relocations = true; #endif } - if (d->d_un.d_val & DF_SYMBOLIC) { - has_DT_SYMBOLIC = true; - } break; #if defined(__mips__) case DT_STRSZ: @@ -2092,8 +2037,10 @@ bool soinfo::PrelinkImage() { #endif default: - DEBUG("Unused DT entry: type %p arg %p", - reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val)); + if (!relocating_linker) { + DL_WARN("%s: unused DT entry: type %p arg %p", name, + reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val)); + } break; } } diff --git a/linker/linker.h b/linker/linker.h index ef2fbcd6c..e39585006 100644 --- a/linker/linker.h +++ b/linker/linker.h @@ -197,7 +197,7 @@ struct soinfo { #if !defined(__LP64__) bool has_text_relocations; #endif - bool has_DT_SYMBOLIC; + bool unused4; // DO NOT USE, maintained for compatibility soinfo(const char* name, const struct stat* file_stat, off64_t file_offset, int rtld_flags);