mirror of
https://github.com/openharmony/third_party_elfutils.git
synced 2026-07-19 19:43:34 -04:00
libdwfl: Fix and test aux_sym address_sync with relocated ELF
The aux_sym address_sync already worked with a full prelink, which has .gnu.prelink_undo, but it failed on plain relocations with prelink -r. Now it uses the difference in ehdr.e_entry as a first offset guess, and the tests confirm this seems to work fine. Signed-off-by: Josh Stone <jistone@redhat.com>
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
2013-11-18 Josh Stone <jistone@redhat.com>
|
||||
|
||||
* dwfl_module_getdwarf.c (find_aux_address_sync): New function.
|
||||
(find_aux_sym): Use it.
|
||||
|
||||
2013-11-14 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
Code cleanup: Remove const in prototype
|
||||
|
||||
@@ -816,6 +816,33 @@ find_dynsym (Dwfl_Module *mod)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if USE_LZMA
|
||||
/* Try to find the offset between the main file and .gnu_debugdata. */
|
||||
static bool
|
||||
find_aux_address_sync (Dwfl_Module *mod)
|
||||
{
|
||||
/* Don't trust the phdrs in the minisymtab elf file to be setup correctly.
|
||||
The address_sync is equal to the main file it is embedded in at first. */
|
||||
mod->aux_sym.address_sync = mod->main.address_sync;
|
||||
|
||||
/* Adjust address_sync for the difference in entry addresses, attempting to
|
||||
account for ELF relocation changes after aux was split. */
|
||||
GElf_Ehdr ehdr_main, ehdr_aux;
|
||||
if (unlikely (gelf_getehdr (mod->main.elf, &ehdr_main) == NULL)
|
||||
|| unlikely (gelf_getehdr (mod->aux_sym.elf, &ehdr_aux) == NULL))
|
||||
return false;
|
||||
mod->aux_sym.address_sync += ehdr_aux.e_entry - ehdr_main.e_entry;
|
||||
|
||||
/* The shdrs are setup OK to make find_prelink_address_sync () do the right
|
||||
thing, which is possibly more reliable, but it needs .gnu.prelink_undo. */
|
||||
if (mod->aux_sym.address_sync != 0)
|
||||
return find_prelink_address_sync (mod, &mod->aux_sym) == DWFL_E_NOERROR;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Try to find the auxiliary symbol table embedded in the main elf file
|
||||
section .gnu_debugdata. Only matters if the symbol information comes
|
||||
from the main file dynsym. No harm done if not found. */
|
||||
@@ -879,21 +906,11 @@ find_aux_sym (Dwfl_Module *mod __attribute__ ((unused)),
|
||||
mod->aux_sym.elf->flags |= ELF_F_MALLOCED;
|
||||
if (open_elf (mod, &mod->aux_sym) != DWFL_E_NOERROR)
|
||||
return;
|
||||
/* Don't trust the phdrs in the minisymtab elf file to be
|
||||
setup correctly. The address_sync is equal to the main
|
||||
file it is embedded in at first. The shdrs are setup
|
||||
OK to make find_prelink_address_sync () do the right
|
||||
thing if necessary though. */
|
||||
mod->aux_sym.address_sync = mod->main.address_sync;
|
||||
if (mod->aux_sym.address_sync != 0)
|
||||
if (! find_aux_address_sync (mod))
|
||||
{
|
||||
error = find_prelink_address_sync (mod, &mod->aux_sym);
|
||||
if (error != DWFL_E_NOERROR)
|
||||
{
|
||||
elf_end (mod->aux_sym.elf);
|
||||
mod->aux_sym.elf = NULL;
|
||||
return;
|
||||
}
|
||||
elf_end (mod->aux_sym.elf);
|
||||
mod->aux_sym.elf = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* So far, so good. Get minisymtab table data and cache it. */
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
2013-11-18 Josh Stone <jistone@redhat.com>
|
||||
|
||||
* testfilebazdbg_plr.bz2: New testfile.
|
||||
* testfilebazmin_plr.bz2: Likewise.
|
||||
* Makefile.am (EXTRA_DIST): Add the above files.
|
||||
* run-dwflsyms.sh: Add prelink -r tests.
|
||||
|
||||
2013-11-15 Mark Wielaard <mjw@redhat.com>
|
||||
|
||||
* testfilebazmdb.bz2: Regenerated.
|
||||
|
||||
@@ -190,6 +190,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
|
||||
testfilebazmin.bz2 testfilebazdbg.debug.bz2 testfilebazmdb.bz2 \
|
||||
testfilebaztab.bz2 testfilebasmin.bz2 \
|
||||
testfilebazdbg_pl.bz2 testfilebazmin_pl.bz2 \
|
||||
testfilebazdbg_plr.bz2 testfilebazmin_plr.bz2 \
|
||||
run-dwflsyms.sh \
|
||||
run-unstrip-n.sh testcore-rtlib.bz2 testcore-rtlib-ppc.bz2 \
|
||||
run-low_high_pc.sh testfile_low_high_pc.bz2 \
|
||||
|
||||
@@ -19,14 +19,18 @@
|
||||
|
||||
# Tests dwfl_module_{addrsym,getsym,relocate_address}
|
||||
# See run-readelf-s.sh for how to generate test binaries.
|
||||
# In addition, *_pl files were created from their base file
|
||||
# with prelink -N, and *_plr with prelink -r 0x4200000000.
|
||||
|
||||
testfiles testfilebaztab
|
||||
testfiles testfilebazdbg testfilebazdbg.debug
|
||||
testfiles testfilebazdbg_pl
|
||||
testfiles testfilebazdbg_plr
|
||||
testfiles testfilebazdyn
|
||||
testfiles testfilebazmdb
|
||||
testfiles testfilebazmin
|
||||
testfiles testfilebazmin_pl
|
||||
testfiles testfilebazmin_plr
|
||||
testfiles testfilebasmin
|
||||
|
||||
tempfiles testfile.dynsym.in testfile.symtab.in testfile.minsym.in dwflsyms.out
|
||||
@@ -328,6 +332,9 @@ cat testfile.symtab.in \
|
||||
cat testfile.symtab_pl.in \
|
||||
| testrun_compare ${abs_builddir}/dwflsyms -e testfilebazdbg_pl
|
||||
|
||||
sed s/0x3000/0x4200/g testfile.symtab_pl.in \
|
||||
| testrun_compare ${abs_builddir}/dwflsyms -e testfilebazdbg_plr
|
||||
|
||||
cat testfile.dynsym.in \
|
||||
| testrun_compare ${abs_builddir}/dwflsyms -e testfilebazdyn
|
||||
|
||||
@@ -340,6 +347,9 @@ cat testfile.minsym.in \
|
||||
cat testfile.minsym_pl.in \
|
||||
| testrun_compare ${abs_builddir}/dwflsyms -e testfilebazmin_pl
|
||||
|
||||
sed s/0x3000/0x4200/g testfile.minsym_pl.in \
|
||||
| testrun_compare ${abs_builddir}/dwflsyms -e testfilebazmin_plr
|
||||
|
||||
testrun_compare ${abs_builddir}/dwflsyms -e testfilebasmin <<\EOF
|
||||
0: NOTYPE LOCAL (0) 0
|
||||
1: FUNC LOCAL foo (18) 0x400168, rel: 0x400168
|
||||
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Reference in New Issue
Block a user