This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: dwfl_module_relocate_address() versus base address
> 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.
Note that for ET_REL that call also incurs a big cost you don't otherwise
need (applying relocs to the section data).
> Although I am still confused how this ever worked before.
The buggy code only affects ET_DYN(-like) with separate debuginfo, not
ET_REL. It probably wasn't noticed before because usually vmlinux is not
separate debuginfo, it's a whole unstripped copy, and .ko are ET_REL.
> Also for the kernel we still do things slightly differently (making
> things relative to _stext) .
The kernel is treated as ET_DYN by libdwfl (hence the -like). Though the
file says ET_EXEC, it really behaves like ET_DYN on CONFIG_RELOCATABLE=y
kernels. This is just FYI, I guess.
> 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 :{
Since this code does getelf anyway (which, incidentally, imposes all the
costs of dwfl_module_address_section on every section), you can just do a
different workaround. You can even skip the bad overhead, because you
don't need to do any workaround for ET_REL files anyway:
if (ki == 0 && secname != NULL && secname[0] == '\0')
{
check for bug
}
So, you can do getelf + getdwarf, to get mainbias and dwbias, respectively.
If mainbias == dwbias, you are already correct. To check for the bug,
you'd see if the original sym_addr and the sym_addr adjusted by
dwfl_module_relocate_address mainbias or by dwbias. But, if you just want
to work right rather than test for the bug, you can just do:
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);
if (ki == 0 && secname != NULL && secname[0] == '\0')
{
Dwarf_Addr bias;
dwfl_assert ("dwfl_getelf", dwfl_module_getelf (m, &bias) != NULL);
sym_addr = save_addr - bias;
}
Thanks,
Roland