From 750b1f2f5c84acaf0776de5239dc81e2e95c1dec Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 17 Dec 2008 17:22:23 +0100 Subject: dump_unwindsyms: Adjust against correct p_vaddr. --- ChangeLog | 4 ++++ translate.cxx | 28 ++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5fd9c0ad..f993fd08 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-12-17 Mark Wielaard + + * translate.cxx (dump_unwindsyms): Adjust against correct p_vaddr. + 2008-12-16 Mark Wielaard * translate.cxx (dump_unwindsyms): Simplify diff --git a/translate.cxx b/translate.cxx index c1ced9ec..1640d87e 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4523,24 +4523,36 @@ dump_unwindsyms (Dwfl_Module *m, if (n > 0) // only try to relocate if there exist relocation bases { - Dwarf_Addr save_addr = sym_addr; + Dwarf_Addr bias, save_addr = sym_addr; + GElf_Ehdr *ehdr, ehdr_mem; + GElf_Phdr *phdr = NULL, phdr_mem; + Elf *elf = dwfl_module_getelf (m, &bias); + int idx; 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. + // up to 0.137 would substract the wrong bias. + if (ki == 0 && secname != NULL && secname[0] == '\0') + sym_addr = save_addr - bias; + // We just want the address relative to the start of the // segment as loaded into memory. - if (ki == 0 && secname != NULL && secname[0] == '\0') + ehdr = gelf_getehdr(elf, &ehdr_mem); + for (idx = 0; idx < ehdr->e_phnum; idx++) { - Dwarf_Addr start; - dwfl_module_info (m, NULL, &start, - NULL, NULL, NULL, NULL, NULL); - sym_addr = save_addr - start; + phdr = gelf_getphdr (elf, idx, &phdr_mem); + if (phdr != NULL + && phdr->p_type == PT_LOAD + && phdr->p_flags & PF_X + && sym_addr >= phdr->p_vaddr + && sym_addr < phdr->p_vaddr + phdr->p_memsz) + break; } + if (phdr != NULL && idx < ehdr->e_phnum) + sym_addr -= phdr->p_vaddr; } if (n == 1 && modname == "kernel") -- cgit