mirror of
https://github.com/openharmony/third_party_elfutils.git
synced 2026-07-19 19:43:34 -04:00
libdwfl: Support auxiliary symbol table only for getsym and addrsym.
Static binaries can have only an auxiliary symbol table and no dynsym or symtab table. Signed-off-by: Mark Wielaard <mjw@redhat.com>
This commit is contained in:
@@ -1,3 +1,16 @@
|
||||
2013-01-23 Mark Wielaard <mjw@redhat.com>
|
||||
|
||||
* dwfl_module_getdwarf.c (find_aux_sym): Don't substract one
|
||||
from aux_syments by default.
|
||||
(find_symtab): Also succeed when only aux_symdata is found.
|
||||
When no symtab is found always try to load auxiliary table.
|
||||
(dwfl_module_getsymtab): Substract one from result when both
|
||||
tables have symbols.
|
||||
* dwfl_module_getsym.c (dwfl_module_getsym): Only skip auxiliary
|
||||
zero entry when both tables have symbols.
|
||||
* dwfl_module_addrsym.c (dwfl_module_addrsym): Only substract
|
||||
one from first_global when both tables have symbols.
|
||||
|
||||
2013-01-16 Mark Wielaard <mjw@redhat.com>
|
||||
|
||||
* libdwflP.h (struct Dwfl_Module): Add aux_sym, aux_symdata,
|
||||
|
||||
@@ -175,11 +175,17 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
|
||||
|
||||
/* First go through global symbols. mod->first_global and
|
||||
mod->aux_first_global are setup by dwfl_module_getsymtab to the
|
||||
index of the first global symbol in the module's symbol table. Both
|
||||
are zero when unknown. All symbols with local binding come first in
|
||||
the symbol table, then all globals. */
|
||||
int first_global = mod->first_global + mod->aux_first_global - 1;
|
||||
search_table (first_global < 0 ? 1 : first_global, syments);
|
||||
index of the first global symbol in those symbol tables. Both
|
||||
are non-zero when the table exist, except when there is only a
|
||||
dynsym table loaded through phdrs, then first_global is zero and
|
||||
there will be no auxiliary table. All symbols with local binding
|
||||
come first in the symbol table, then all globals. The zeroth,
|
||||
null entry, in the auxiliary table is skipped if there is a main
|
||||
table. */
|
||||
int first_global = mod->first_global + mod->aux_first_global;
|
||||
if (mod->syments > 0 && mod->aux_syments > 0)
|
||||
first_global--;
|
||||
search_table (first_global == 0 ? 1 : first_global, syments);
|
||||
|
||||
/* If we found nothing searching the global symbols, then try the locals.
|
||||
Unless we have a global sizeless symbol that matches exactly. */
|
||||
|
||||
@@ -909,7 +909,7 @@ find_aux_sym (Dwfl_Module *mod __attribute__ ((unused)),
|
||||
minisymtab = true;
|
||||
*aux_symscn = scn;
|
||||
*aux_strshndx = shdr->sh_link;
|
||||
mod->aux_syments = shdr->sh_size / shdr->sh_entsize - 1;
|
||||
mod->aux_syments = shdr->sh_size / shdr->sh_entsize;
|
||||
mod->aux_first_global = shdr->sh_info;
|
||||
if (*aux_xndxscn != NULL)
|
||||
return;
|
||||
@@ -949,7 +949,7 @@ find_aux_sym (Dwfl_Module *mod __attribute__ ((unused)),
|
||||
static void
|
||||
find_symtab (Dwfl_Module *mod)
|
||||
{
|
||||
if (mod->symdata != NULL /* Already done. */
|
||||
if (mod->symdata != NULL || mod->aux_symdata != NULL /* Already done. */
|
||||
|| mod->symerr != DWFL_E_NOERROR) /* Cached previous failure. */
|
||||
return;
|
||||
|
||||
@@ -1001,16 +1001,23 @@ find_symtab (Dwfl_Module *mod)
|
||||
break;
|
||||
|
||||
case DWFL_E_NO_SYMTAB:
|
||||
/* There might be an auxiliary table. */
|
||||
find_aux_sym (mod, &aux_symscn, &aux_xndxscn, &aux_strshndx);
|
||||
|
||||
if (symscn != NULL)
|
||||
{
|
||||
/* We still have the dynamic symbol table. */
|
||||
mod->symerr = DWFL_E_NOERROR;
|
||||
|
||||
/* The dynsym table might be extended by an auxiliary table. */
|
||||
find_aux_sym (mod, &aux_symscn, &aux_xndxscn, &aux_strshndx);
|
||||
break;
|
||||
}
|
||||
|
||||
if (aux_symscn != NULL)
|
||||
{
|
||||
/* We still have the auxiliary symbol table. */
|
||||
mod->symerr = DWFL_E_NOERROR;
|
||||
goto aux_cache;
|
||||
}
|
||||
|
||||
/* Last ditch, look for dynamic symbols without section headers. */
|
||||
find_dynsym (mod);
|
||||
return;
|
||||
@@ -1049,6 +1056,7 @@ find_symtab (Dwfl_Module *mod)
|
||||
/* Cache any auxiliary symbol info, when it fails, just ignore aux_sym. */
|
||||
if (aux_symscn != NULL)
|
||||
{
|
||||
aux_cache:
|
||||
/* This does some sanity checks on the string table section. */
|
||||
if (elf_strptr (mod->aux_sym.elf, aux_strshndx, 0) == NULL)
|
||||
{
|
||||
@@ -1233,7 +1241,9 @@ dwfl_module_getsymtab (Dwfl_Module *mod)
|
||||
|
||||
find_symtab (mod);
|
||||
if (mod->symerr == DWFL_E_NOERROR)
|
||||
return mod->syments + mod->aux_syments;
|
||||
/* We will skip the auxiliary zero entry if there is another one. */
|
||||
return (mod->syments + mod->aux_syments
|
||||
- (mod->syments > 0 && mod->aux_syments > 0 ? 1 : 0));
|
||||
|
||||
__libdwfl_seterrno (mod->symerr);
|
||||
return -1;
|
||||
|
||||
@@ -48,6 +48,7 @@ dwfl_module_getsym (Dwfl_Module *mod, int ndx,
|
||||
And skip the auxiliary table zero undefined entry. */
|
||||
GElf_Word shndx;
|
||||
int tndx = ndx;
|
||||
int skip_aux_zero = (mod->syments > 0 && mod->aux_syments > 0) ? 1 : 0;
|
||||
struct dwfl_file *file;
|
||||
Elf_Data *symdata;
|
||||
Elf_Data *symxndxdata;
|
||||
@@ -62,19 +63,19 @@ dwfl_module_getsym (Dwfl_Module *mod, int ndx,
|
||||
symxndxdata = mod->symxndxdata;
|
||||
symstrdata = mod->symstrdata;
|
||||
}
|
||||
else if (ndx < mod->first_global + mod->aux_first_global - 1)
|
||||
else if (ndx < mod->first_global + mod->aux_first_global - skip_aux_zero)
|
||||
{
|
||||
/* aux symbol table (locals). */
|
||||
tndx = ndx - mod->first_global + 1;
|
||||
tndx = ndx - mod->first_global + skip_aux_zero;
|
||||
file = &mod->aux_sym;
|
||||
symdata = mod->aux_symdata;
|
||||
symxndxdata = mod->aux_symxndxdata;
|
||||
symstrdata = mod->aux_symstrdata;
|
||||
}
|
||||
else if ((size_t) ndx < mod->syments + mod->aux_first_global - 1)
|
||||
else if ((size_t) ndx < mod->syments + mod->aux_first_global - skip_aux_zero)
|
||||
{
|
||||
/* main symbol table (globals). */
|
||||
tndx = ndx - mod->aux_first_global + 1;
|
||||
tndx = ndx - mod->aux_first_global + skip_aux_zero;
|
||||
file = mod->symfile;
|
||||
symdata = mod->symdata;
|
||||
symxndxdata = mod->symxndxdata;
|
||||
@@ -83,7 +84,7 @@ dwfl_module_getsym (Dwfl_Module *mod, int ndx,
|
||||
else
|
||||
{
|
||||
/* aux symbol table (globals). */
|
||||
tndx = ndx - mod->syments + 1;
|
||||
tndx = ndx - mod->syments + skip_aux_zero;
|
||||
file = &mod->aux_sym;
|
||||
symdata = mod->aux_symdata;
|
||||
symxndxdata = mod->aux_symxndxdata;
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
2013-01-23 Mark Wielaard <mjw@redhat.com>
|
||||
|
||||
* testfilebasmin.bz2: New testfile.
|
||||
* Makefile.am (EXTRA_DIST): Add testfilebasmin.bz2.
|
||||
* run-readelf-s.sh: Test testfilebasmin.
|
||||
* run-dwflsyms.sh: Likewise.
|
||||
|
||||
2013-01-16 Mark Wielaard <mjw@redhat.com>
|
||||
|
||||
* Makefile.am (check_PROGRAMS): Add dwflsyms.
|
||||
|
||||
+1
-1
@@ -175,7 +175,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
|
||||
testfilegdbindex7.bz2 \
|
||||
run-readelf-s.sh testfilebazdbg.bz2 testfilebazdyn.bz2 \
|
||||
testfilebazmin.bz2 testfilebazdbg.debug.bz2 testfilebazmdb.bz2 \
|
||||
testfilebaztab.bz2 \
|
||||
testfilebaztab.bz2 testfilebasmin.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 \
|
||||
|
||||
@@ -25,6 +25,7 @@ testfiles testfilebazdbg testfilebazdbg.debug
|
||||
testfiles testfilebazdyn
|
||||
testfiles testfilebazmdb
|
||||
testfiles testfilebazmin
|
||||
testfiles testfilebasmin
|
||||
|
||||
tempfiles testfile.dynsym.in testfile.symtab.in testfile.minsym.in dwflsyms.out
|
||||
|
||||
@@ -190,4 +191,16 @@ cat testfile.symtab.in \
|
||||
cat testfile.minsym.in \
|
||||
| testrun_compare ./dwflsyms -e testfilebazmin
|
||||
|
||||
testrun_compare ./dwflsyms -e testfilebasmin <<\EOF
|
||||
0: NOTYPE LOCAL (0) 0
|
||||
1: FUNC LOCAL foo (18) 0x400168
|
||||
2: SECTION LOCAL (0) 0x400120
|
||||
3: SECTION LOCAL (0) 0x400144
|
||||
4: SECTION LOCAL (0) 0x4001c0
|
||||
5: SECTION LOCAL (0) 0x600258
|
||||
6: FUNC GLOBAL _start (21) 0x4001a8
|
||||
7: FUNC GLOBAL main (33) 0x400144
|
||||
8: FUNC GLOBAL bar (44) 0x40017a
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -74,12 +74,33 @@
|
||||
#
|
||||
# - testfilebazmin (dynsym + gnu_debugdata)
|
||||
# objcopy --remove-section=.gnu_debuglink baz testfilebazmin
|
||||
#
|
||||
#
|
||||
# Special auxiliary only, can happen with static binaries.
|
||||
# - start.c
|
||||
#
|
||||
# extern int main (int argc, char ** argv);
|
||||
# void _start (void) { for (;;) main (1, 0); }
|
||||
#
|
||||
# gcc -g -c start.c
|
||||
# gcc -static -nostdlib -o bas foo.o bar.o start.o
|
||||
#
|
||||
# eu-strip --remove-comment -f bas.debug bas
|
||||
# nm bas.debug --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t") print $1 }' | sort > funcsyms
|
||||
# objcopy -S --remove-section .gdb_index --remove-section .comment --keep-symbols=funcsyms bas.debug mini_debuginfo
|
||||
# rm -f mini_debuginfo.xz
|
||||
# xz mini_debuginfo
|
||||
# objcopy --add-section .gnu_debugdata=mini_debuginfo.xz bas
|
||||
# rm bas.debug
|
||||
# mv bas testfilebasmin
|
||||
|
||||
|
||||
testfiles testfilebaztab
|
||||
testfiles testfilebazdbg testfilebazdbg.debug
|
||||
testfiles testfilebazdyn
|
||||
testfiles testfilebazmdb
|
||||
testfiles testfilebazmin
|
||||
testfiles testfilebasmin
|
||||
|
||||
tempfiles testfile.dynsym.in testfile.symtab.in testfile.minsym.in
|
||||
|
||||
@@ -253,4 +274,23 @@ cat testfile.dynsym.in \
|
||||
cat testfile.minsym.in \
|
||||
| testrun_compare ../src/readelf --elf-section -s testfilebazmin
|
||||
|
||||
testrun_compare ../src/readelf -s testfilebasmin <<EOF
|
||||
EOF
|
||||
|
||||
testrun_compare ../src/readelf --elf-section -s testfilebasmin <<\EOF
|
||||
|
||||
Symbol table [ 6] '.symtab' contains 9 entries:
|
||||
6 local symbols String table: [ 7] '.strtab'
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UNDEF
|
||||
1: 0000000000400168 18 FUNC LOCAL DEFAULT 2 foo
|
||||
2: 0000000000400120 0 SECTION LOCAL DEFAULT 1
|
||||
3: 0000000000400144 0 SECTION LOCAL DEFAULT 2
|
||||
4: 00000000004001c0 0 SECTION LOCAL DEFAULT 3
|
||||
5: 0000000000600258 0 SECTION LOCAL DEFAULT 4
|
||||
6: 00000000004001a8 21 FUNC GLOBAL DEFAULT 2 _start
|
||||
7: 0000000000400144 33 FUNC GLOBAL DEFAULT 2 main
|
||||
8: 000000000040017a 44 FUNC GLOBAL DEFAULT 2 bar
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
|
||||
Executable
BIN
Binary file not shown.
Reference in New Issue
Block a user