From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: multipart/mixed; boundary="===============6333091861774694400==" MIME-Version: 1.0 From: Mark Wielaard To: elfutils-devel@lists.fedorahosted.org Subject: Re: [PATCH] libdwfl: find_dynsym don't assume dynamic linker has adjusted DYNAMIC entries. Date: Fri, 14 Nov 2014 12:30:10 +0100 Message-ID: <1415964610.5000.5.camel@bordewijk.wildebeest.org> In-Reply-To: 1415635725-9414-1-git-send-email-mjw@redhat.com --===============6333091861774694400== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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_getdwar= f.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_bia= s. */ > + void translate_offs (GElf_Addr adjust) > + { > GElf_Off offs[i_max] =3D { 0, }; > - find_offsets (mod->main.elf, mod->main_bias, phnum, i_max, addr= s, > - offs); > + find_offsets (mod->main.elf, adjust, phnum, i_max, addrs, off= s); > = > /* Figure out the size of the symbol table. */ > if (offs[i_hash] !=3D 0) > @@ -824,9 +826,18 @@ find_dynsym (Dwfl_Module *mod) > mod->symfile =3D &mod->main; > mod->symerr =3D 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 =3D=3D 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. --===============6333091861774694400==--