On Mon, 2014-11-10 at 17:08 +0100, Mark Wielaard wrote:
We had a regression on i686 where we failed to find the vdso symbol
table
and so couldn't resolve any addresses pointing into the vdso to function
names. This was because at least on i686 we have to rely on the phdrs and
the DYNAMIC segment to locate the symbol table.
The fix look large, but ignoring whitespace it is actually pretty small:
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index e705f57..adb94b4 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -718,10 +718,12 @@ find_dynsym (Dwfl_Module *mod)
break;
}
- /* Translate pointers into file offsets. */
+ /* Translate pointers into file offsets. ADJUST is either zero
+ in case the dynamic segment wasn't adjusted or mod->main_bias. */
+ void translate_offs (GElf_Addr adjust)
+ {
GElf_Off offs[i_max] = { 0, };
- find_offsets (mod->main.elf, mod->main_bias, phnum, i_max, addrs,
- offs);
+ find_offsets (mod->main.elf, adjust, phnum, i_max, addrs, offs);
/* Figure out the size of the symbol table. */
if (offs[i_hash] != 0)
@@ -824,9 +826,18 @@ find_dynsym (Dwfl_Module *mod)
mod->symfile = &mod->main;
mod->symerr = DWFL_E_NOERROR;
}
- return;
}
}
+
+ /* First try unadjusted, like ELF files from disk, vdso.
+ Then try for already adjusted dynamic section, like ELF
+ from remote memory. */
+ translate_offs (0);
+ if (mod->symfile == NULL)
+ translate_offs (mod->main_bias);
+
+ return;
+ }
}
}
<--->
commit 037505 "Fix resolving ELF symbols for live PIDs with deleted files"
changed find_dynsym to assume the PT_DYNAMIC entries had been adjusted by
the dynamic linker. That is often a correct assumption when the ELF image
comes from remote memory. But we cannot rely on that. In the case of the
vdso image the DYNAMIC segment has not been adjusted for example.
There is no good way to determine whether the DYNAMIC segment has or
hasn't been adjusted already to the load address by the dynamic linker.
So we just try twice. Once without and if the fails again with assuming
adjustments being applied.
Includes a new vdsosyms testcase that fails on i686 before and succeeds
after the fix.
After some more testing I pushed this to master now.