commit 7d9b821db6bc494417a57321b419c6b9481a2128 Author: Roland McGrath Date: Thu Dec 18 15:08:09 2008 -0800 Fix last fix: ET_DYN addresses are taken as relative to MOD->low_addr. * derelocate.c (dwfl_module_relocate_address): Fix last fix: ET_DYN addresses are taken as relative to MOD->low_addr. --- diff --git a/libdwfl/derelocate.c b/libdwfl/derelocate.c index 7f390c7..f2a6467 100644 --- a/libdwfl/derelocate.c +++ b/libdwfl/derelocate.c @@ -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)