(dl_main): Grok --list flag.
[kopensolaris-gnu/glibc.git] / elf / dl-reloc.c
index 94ffb71..7e4f499 100644 (file)
@@ -60,30 +60,40 @@ _dl_relocate_object (struct link_map *l, int lazy)
       = ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
 
 
-    Elf32_Addr resolve (const Elf32_Sym **ref)
+    Elf32_Addr resolve (const Elf32_Sym **ref, Elf32_Addr r_offset)
       {
        return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope,
-                                 l->l_name);
+                                 l->l_name, (*ref)->st_value == r_offset);
       }
 
     real_next = l->l_next;
     if (l->l_info[DT_SYMBOLIC])
       {
-       l->l_prev->l_next = real_next;
+       if (l->l_prev)
+         l->l_prev->l_next = real_next;
        l->l_next = _dl_loaded;
        scope = l;
       }
     else
       scope = _dl_loaded;
 
+    if (l->l_type == lt_interpreter)
+      /* We cannot be lazy when relocating the dynamic linker itself.  It
+        was previously relocated eagerly (allowing us to be running now),
+        and needs always to be fully relocated so it can run without the
+        aid of run-time fixups (because it's the one to do them), so we
+        must always re-relocate its PLT eagerly.  */
+      lazy = 0;
+
     ELF_DYNAMIC_RELOCATE (l, lazy, resolve);
 
     /* Restore list frobnication done above for DT_SYMBOLIC.  */
     l->l_next = real_next;
-    l->l_prev->l_next = l;
+    if (l->l_prev)
+      l->l_prev->l_next = l;
   }
 
-  if (l->l_info[DT_JMPREL] && lazy)
+  if (l->l_info[DT_JMPREL] && lazy)
     /* Set up the PLT so its unrelocated entries will
        jump to _dl_runtime_resolve, which will relocate them.  */
     elf_machine_runtime_setup (l);