OSDN Git Service

Look into ld_preloads before current library
authorDmitriy Ivanov <dimitry@google.com>
Fri, 29 Aug 2014 17:15:25 +0000 (10:15 -0700)
committerDmitriy Ivanov <dimitry@google.com>
Fri, 29 Aug 2014 18:46:06 +0000 (11:46 -0700)
 Change lookup order during relocation so that
 ld_preloads always precede caller (unless caller
 is main executable).

 Asan needs this change in order to intercept libc->libc
 calls.

Bug: 15432753
Change-Id: If69aa16efe59aa35bb30e96feb83d08f1efbec86

linker/linker.cpp

index 2d8e07e..cf65705 100644 (file)
@@ -495,6 +495,15 @@ static ElfW(Sym)* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi, s
                 *lsi = si;
                 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;
+                }
+            }
         } else {
             /* Order of symbol lookup is controlled by DT_SYMBOLIC flag */
 
@@ -512,6 +521,15 @@ static ElfW(Sym)* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi, s
                     *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;
+                    }
+                }
             }
 
             /* Look for symbols in the local scope (the object who is
@@ -543,16 +561,16 @@ static ElfW(Sym)* soinfo_do_lookup(soinfo* si, const char* name, soinfo** lsi, s
                     *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;
+                /* 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;
+                    }
+                }
+            }
         }
     }