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
This commit is contained in:
Dmitriy Ivanov 2014-09-16 14:31:06 -07:00
parent c85e82dde5
commit b364d95380
3 changed files with 40 additions and 94 deletions

View File

@ -244,7 +244,6 @@ soinfo* get_libdl_info() {
__libdl_info.nchain = sizeof(g_libdl_chains)/sizeof(unsigned); __libdl_info.nchain = sizeof(g_libdl_chains)/sizeof(unsigned);
__libdl_info.bucket = g_libdl_buckets; __libdl_info.bucket = g_libdl_buckets;
__libdl_info.chain = g_libdl_chains; __libdl_info.chain = g_libdl_chains;
__libdl_info.has_DT_SYMBOLIC = true;
__libdl_info.ref_count = 1; __libdl_info.ref_count = 1;
} }

View File

@ -487,117 +487,65 @@ static ElfW(Sym)* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi) {
ElfW(Sym)* s = nullptr; ElfW(Sym)* s = nullptr;
if (somain != nullptr) { if (somain != nullptr) {
/* DEBUG("%s: looking up %s in executable %s",
* Local scope is executable scope. Just start looking into it right away si->name, name, somain->name);
* for the shortcut.
*/
if (si == somain) { // 1. Look for it in the main executable
s = soinfo_elf_lookup(si, elf_hash, name); s = soinfo_elf_lookup(somain, elf_hash, name);
if (s != nullptr) { if (s != nullptr) {
*lsi = si; *lsi = somain;
goto done; }
}
/* 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++) { for (int i = 0; g_ld_preloads[i] != NULL; i++) {
s = soinfo_elf_lookup(g_ld_preloads[i], elf_hash, name); 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) { if (s != nullptr) {
*lsi = somain; *lsi = g_ld_preloads[i];
goto done; break;
}
/* 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 /* Look for symbols in the local scope (the object who is
* searching). This happens with C++ templates on x86 for some * searching). This happens with C++ templates on x86 for some
* reason. * reason.
* *
* Notes on weak symbols: * Notes on weak symbols:
* The ELF specs are ambiguous about treatment of weak definitions in * The ELF specs are ambiguous about treatment of weak definitions in
* dynamic linking. Some systems return the first definition found * dynamic linking. Some systems return the first definition found
* and some the first non-weak definition. This is system dependent. * and some the first non-weak definition. This is system dependent.
* Here we return the first definition found for simplicity. */ * Here we return the first definition found for simplicity. */
if (s == nullptr) {
s = soinfo_elf_lookup(si, elf_hash, name); s = soinfo_elf_lookup(si, elf_hash, name);
if (s != nullptr) { if (s != nullptr) {
*lsi = si; *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) { if (s == nullptr) {
DEBUG("%s: looking up %s in %s", si->name, name, child->name); si->get_children().visit([&](soinfo* child) {
s = soinfo_elf_lookup(child, elf_hash, name); DEBUG("%s: looking up %s in %s", si->name, name, child->name);
if (s != nullptr) { s = soinfo_elf_lookup(child, elf_hash, name);
*lsi = child; if (s != nullptr) {
return false; *lsi = child;
} return false;
return true; }
}); return true;
});
}
done:
if (s != nullptr) { if (s != nullptr) {
TRACE_TYPE(LOOKUP, "si %s sym %s s->st_value = %p, " TRACE_TYPE(LOOKUP, "si %s sym %s s->st_value = %p, "
"found in %s, base = %p, load bias = %p", "found in %s, base = %p, load bias = %p",
si->name, name, reinterpret_cast<void*>(s->st_value), si->name, name, reinterpret_cast<void*>(s->st_value),
(*lsi)->name, reinterpret_cast<void*>((*lsi)->base), (*lsi)->name, reinterpret_cast<void*>((*lsi)->base),
reinterpret_cast<void*>((*lsi)->load_bias)); reinterpret_cast<void*>((*lsi)->load_bias));
return s;
} }
return nullptr; return s;
} }
// Each size has it's own allocator. // Each size has it's own allocator.
@ -2042,7 +1990,7 @@ bool soinfo::PrelinkImage() {
break; break;
#endif #endif
case DT_SYMBOLIC: case DT_SYMBOLIC:
has_DT_SYMBOLIC = true; // ignored
break; break;
case DT_NEEDED: case DT_NEEDED:
++needed_count; ++needed_count;
@ -2056,9 +2004,6 @@ bool soinfo::PrelinkImage() {
has_text_relocations = true; has_text_relocations = true;
#endif #endif
} }
if (d->d_un.d_val & DF_SYMBOLIC) {
has_DT_SYMBOLIC = true;
}
break; break;
#if defined(__mips__) #if defined(__mips__)
case DT_STRSZ: case DT_STRSZ:
@ -2092,8 +2037,10 @@ bool soinfo::PrelinkImage() {
#endif #endif
default: default:
DEBUG("Unused DT entry: type %p arg %p", if (!relocating_linker) {
reinterpret_cast<void*>(d->d_tag), reinterpret_cast<void*>(d->d_un.d_val)); 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; break;
} }
} }

View File

@ -197,7 +197,7 @@ struct soinfo {
#if !defined(__LP64__) #if !defined(__LP64__)
bool has_text_relocations; bool has_text_relocations;
#endif #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); soinfo(const char* name, const struct stat* file_stat, off64_t file_offset, int rtld_flags);