Fix last fix: ET_DYN addresses are taken as relative to MOD->low_addr.
authorRoland McGrath <roland@redhat.com>
Thu, 18 Dec 2008 23:08:09 +0000 (15:08 -0800)
committerRoland McGrath <roland@redhat.com>
Thu, 18 Dec 2008 23:08:09 +0000 (15:08 -0800)
libdwfl/ChangeLog
libdwfl/derelocate.c

index 9d86f52..274b97d 100644 (file)
@@ -1,3 +1,8 @@
+2008-12-18  Roland McGrath  <roland@redhat.com>
+
+       * derelocate.c (dwfl_module_relocate_address): Fix last fix: ET_DYN
+       addresses are taken as relative to MOD->low_addr.
+
 2008-12-15  Roland McGrath  <roland@redhat.com>
 
        * derelocate.c (dwfl_module_relocate_address): Apply main.bias, not
index 7f390c7..f2a6467 100644 (file)
@@ -238,6 +238,7 @@ dwfl_module_relocations (Dwfl_Module *mod)
       return 1;
 
     case ET_EXEC:
+      assert (mod->main.bias == 0);
       assert (mod->debug.bias == 0);
       break;
     }
@@ -353,16 +354,26 @@ find_section (Dwfl_Module *mod, Dwarf_Addr *addr)
 int
 dwfl_module_relocate_address (Dwfl_Module *mod, Dwarf_Addr *addr)
 {
-  if (check_module (mod))
+  if (unlikely (check_module (mod)))
     return -1;
 
-  if (mod->e_type != ET_REL)
+  switch (mod->e_type)
     {
-      *addr -= mod->main.bias;
-      return 0;
+    case ET_REL:
+      return find_section (mod, addr);
+
+    case ET_DYN:
+      /* All relative to first and only relocation base: module start.  */
+      *addr -= mod->low_addr;
+      break;
+
+    default:
+      /* Already absolute, dwfl_module_relocations returned zero.  We
+        shouldn't really have been called, but it's a harmless no-op.  */
+      break;
     }
 
-  return find_section (mod, addr);
+  return 0;
 }
 INTDEF (dwfl_module_relocate_address)