diff options
author | Elliott Hughes <enh@google.com> | 2012-11-02 11:25:48 -0700 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2012-11-02 11:25:49 -0700 |
commit | ed537239a94ebd11a8c262a319d81fd1f0d3f73f (patch) | |
tree | d8ea63e3b8968216a4ab87f7f97872005b0fa707 /linker | |
parent | dc77a22850e31eb369ec9776c13c967566bf61d0 (diff) | |
parent | c77c434149959e135ba21d1dd8a78a408fef2489 (diff) | |
download | android_bionic-ed537239a94ebd11a8c262a319d81fd1f0d3f73f.tar.gz android_bionic-ed537239a94ebd11a8c262a319d81fd1f0d3f73f.tar.bz2 android_bionic-ed537239a94ebd11a8c262a319d81fd1f0d3f73f.zip |
Merge "Adjust symbol lookup for DT_SYMBOLIC case"
Diffstat (limited to 'linker')
-rwxr-xr-x[-rw-r--r--] | linker/linker.cpp | 76 |
1 files changed, 53 insertions, 23 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp index 40f29a237..e064ccf6d 100644..100755 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -458,38 +458,68 @@ soinfo_do_lookup(soinfo *si, const char *name, soinfo **lsi, Elf32_Sym *s = NULL; int i; - if (si != NULL) { + if (si != NULL && somain != NULL) { /* - * If this object was built with symbolic relocations disabled, the - * first place to look to resolve external references is the main - * executable. + * Local scope is executable scope. Just start looking into it right away + * for the shortcut. */ - if (!si->has_DT_SYMBOLIC) { - DEBUG("%5d %s: looking up %s in executable %s\n", - pid, si->name, name, somain->name); - s = soinfo_elf_lookup(somain, elf_hash, name); + if (si == somain) { + s = soinfo_elf_lookup(si, elf_hash, name); if (s != NULL) { - *lsi = somain; + *lsi = si; goto done; } - } + } else { + /* Order of symbol lookup is controlled by DT_SYMBOLIC flag */ - /* Look for symbols in the local scope (the object who is - * searching). This happens with C++ templates on i386 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 this object was built with symbolic relocations disabled, the + * first place to look to resolve external references is the main + * executable. + */ - s = soinfo_elf_lookup(si, elf_hash, name); - if (s != NULL) { - *lsi = si; - goto done; + if (!si->has_DT_SYMBOLIC) { + DEBUG("%5d %s: looking up %s in executable %s\n", + pid, si->name, name, somain->name); + s = soinfo_elf_lookup(somain, elf_hash, name); + if (s != NULL) { + *lsi = somain; + goto done; + } + } + + /* Look for symbols in the local scope (the object who is + * searching). This happens with C++ templates on i386 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. */ + + s = soinfo_elf_lookup(si, elf_hash, name); + if (s != NULL) { + *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("%5d %s: looking up %s in executable %s after local scope\n", + pid, si->name, name, somain->name); + s = soinfo_elf_lookup(somain, elf_hash, name); + if (s != NULL) { + *lsi = somain; + goto done; + } + } } } |