diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | translate.cxx | 38 |
2 files changed, 23 insertions, 20 deletions
@@ -1,3 +1,8 @@ +2008-12-16 Mark Wielaard <mjw@redhat.com> + + * translate.cxx (dump_unwindsyms): Simplify + dwfl_module_relocate_address workaround. + 2008-12-15 Mark Wielaard <mjw@redhat.com> * tapsets.cxx (utrace_derived_probe_group::emit_module_decls): diff --git a/translate.cxx b/translate.cxx index bb976d59..c1ced9ec 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4523,26 +4523,24 @@ dump_unwindsyms (Dwfl_Module *m, if (n > 0) // only try to relocate if there exist relocation bases { - // libdwfl up to 0.137 could miscalculate the relocated - // address for shared ET_DYN files (n > 0). Luckily - // dwfl_module_address_section does work correctly. - // Then we just need to add the section offset to get - // the (relative) address of the symbol when mapped in. - Dwarf_Addr bias; - Elf_Scn *sec; - GElf_Shdr *shdr, shdr_mem; - GElf_Ehdr *ehdr, ehdr_mem; - Elf *elf; - sec = dwfl_module_address_section (m, &sym_addr, &bias); - dwfl_assert ("dwfl_module_address_section", sec != NULL); - shdr = gelf_getshdr(sec, &shdr_mem); - sym_addr += shdr->sh_offset; - elf = dwfl_module_getelf (m, &bias); - ehdr = gelf_getehdr(elf, &ehdr_mem); - if (ehdr->e_type == ET_DYN) - secname = ""; - else - secname = elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name); + Dwarf_Addr save_addr = sym_addr; + int ki = dwfl_module_relocate_address (m, &sym_addr); + dwfl_assert ("dwfl_module_relocate_address", ki >= 0); + secname = dwfl_module_relocation_info (m, ki, NULL); + + // For ET_DYN files (secname == "") we do ignore the + // dwfl_module_relocate_address adjustment. libdwfl + // up to 0.137 would substract the wrong bias. And + // we are not actually interested in the bias adjustment. + // We just want the address relative to the start of the + // segment as loaded into memory. + if (ki == 0 && secname != NULL && secname[0] == '\0') + { + Dwarf_Addr start; + dwfl_module_info (m, NULL, &start, + NULL, NULL, NULL, NULL, NULL); + sym_addr = save_addr - start; + } } if (n == 1 && modname == "kernel") |