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 Roland,

On Fri, 2008-12-12 at 12:06 -0800, Roland McGrath wrote:
> I think dwfl_module_relocate_address might be applying the wrong bias.  It
> subtracts the dwbias, but it should subtract the main file bias.  The
> address you pass it is an absolute address in that Dwfl's address space,
> and what it should yield is the address relative to the first p_vaddr in
> the DSO (i.e. 0 if not prelinked).

Aha! Doh. Yes, things make a lot more sense now. Since older/current
versions of dwfl_module_relocate_address() will have this bug I am using
dwfl_module_address_section() now, which does seem to do the right
thing. Then to get the relative address of the symbol when the code is
mapped in all we need is the section offset. This seems to work fine in
all cases. Although I am still confused how this ever worked before.
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.

Thanks,

Mark
diff --git a/translate.cxx b/translate.cxx
index 27f6a04..c60d2da 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -4521,11 +4521,24 @@ dump_unwindsyms (Dwfl_Module *m,
               Dwarf_Addr sym_addr = sym.st_value;
               const char *secname = NULL;
 
-              if (n > 0) // only try to relocate if there exist relocation bases
+              // only try to relocate if there exist relocation bases
+              // and not for the kernel, we readjust against _stext,
+              // through extra_offset above.
+              if (n > 0 && modname != "kernel")
                 {
-                  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;
+		  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;
+		  secname = "";
                 }
 
               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]