Merge "Adjust symbol lookup for DT_SYMBOLIC case"
diff --git a/linker/linker.cpp b/linker/linker.cpp
old mode 100644
new mode 100755
index 40f29a2..e064ccf
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -458,38 +458,68 @@
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;
+ }
+ }
}
}