This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: dwfl_module_relocate_address() versus base address


Hi,

On Mon, 2008-12-15 at 13:06 +0100, Mark Wielaard wrote:
> Also for the kernel we still do things slightly differently (making
> things relative to _stext) . I checked in the following patch to my
> pr6866 branch and will be testing more with it.

This is not completely true. I was confused since we also rely on the
secname produced by dwfl_module_relocation_info() (being empty for
ET_DYN). So that is now also replicated by hand in the new patch. It is
getting slightly messy now :{

Cheers,

Mark
diff --git a/translate.cxx b/translate.cxx
index 27f6a04..bb976d5 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -4523,9 +4523,26 @@ dump_unwindsyms (Dwfl_Module *m,
 
               if (n > 0) // only try to relocate if there exist relocation bases
                 {
-                  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);
+		  // 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);
                 }
 
               if (n == 1 && modname == "kernel")

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]