Return has_DT_SYMBOLIC flag.

This reverts commit 8f61d991831f0ea515fa50a5c38dbbcfbab0dd28

 Despite the fact that static linker does all the work while linking
 -Bsymbolic executables, according to the SCO doc following DT_SYMBOLIC
 and DF_SYMBOLIC flags is still a requirement for the dynamic linker
 as well.

 (see http://www.sco.com/developers/gabi/2012-12-31/ch5.dynamic.html)

Bug: 18186310

(cherry picked from commit 96bc37f2e1093416a432135265fd7a4db6c3df17)

Change-Id: Ie217be4f3305d877066e4cfe91975ae1c7768330
This commit is contained in:
Dmitriy Ivanov 2014-09-29 12:10:36 -07:00
parent 748fbe5c41
commit f90e21004e
2 changed files with 47 additions and 23 deletions

View File

@ -486,14 +486,34 @@ static ElfW(Sym)* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi) {
unsigned elf_hash = elfhash(name);
ElfW(Sym)* s = nullptr;
if (somain != nullptr) {
DEBUG("%s: looking up %s in executable %s",
si->name, name, somain->name);
// 1. Look for it in the main executable
s = soinfo_elf_lookup(somain, elf_hash, name);
/* "This element's presence in a shared object library alters the dynamic linker's
* symbol resolution algorithm for references within the library. Instead of starting
* a symbol search with the executable file, the dynamic linker starts from the shared
* object itself. If the shared object fails to supply the referenced symbol, the
* dynamic linker then searches the executable file and other shared objects as usual."
*
* http://www.sco.com/developers/gabi/2012-12-31/ch5.dynamic.html
*
* Note that this is unlikely since static linker avoids generating
* relocations for -Bsymbolic linked dynamic executables.
*/
if (si->has_DT_SYMBOLIC) {
DEBUG("%s: looking up %s in local scope (DT_SYMBOLIC)", si->name, name);
s = soinfo_elf_lookup(si, elf_hash, name);
if (s != nullptr) {
*lsi = somain;
*lsi = si;
}
}
if (s == nullptr && somain != nullptr) {
// 1. Look for it in the main executable unless we already did.
if (si != somain || !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;
}
}
// 2. Look for it in the ld_preloads
@ -506,22 +526,23 @@ static ElfW(Sym)* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi) {
}
}
}
}
/* 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;
}
if (s == nullptr && !si->has_DT_SYMBOLIC) {
DEBUG("%s: looking up %s in local scope", si->name, name);
s = soinfo_elf_lookup(si, elf_hash, name);
if (s != nullptr) {
*lsi = si;
}
}
@ -2023,7 +2044,7 @@ bool soinfo::PrelinkImage() {
break;
#endif
case DT_SYMBOLIC:
// ignored
has_DT_SYMBOLIC = true;
break;
case DT_NEEDED:
++needed_count;
@ -2037,6 +2058,9 @@ 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:

View File

@ -197,7 +197,7 @@ struct soinfo {
#if !defined(__LP64__)
bool has_text_relocations;
#endif
bool unused4; // DO NOT USE, maintained for compatibility
bool has_DT_SYMBOLIC;
soinfo(const char* name, const struct stat* file_stat, off64_t file_offset, int rtld_flags);