This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Re: [PATCH 2/3] libdwfl: Add minisymtab support.
- From: Mark Wielaard <mjw at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Wed, 23 Jan 2013 19:59:30 +0100
- Subject: Re: [PATCH 2/3] libdwfl: Add minisymtab support.
On Wed, 2013-01-23 at 19:04 +0100, Jan Kratochvil wrote:
> But I find it messy a bit, You adjust AUX_SYMENTS for that initial zero
> symbol but you do not adjust AUX_FIRST_GLOBAL for that initial zero symbol.
>
> Therefore AUX_SYMENTS and AUX_FIRST_GLOBAL numbering is off-by-one.
>
> I would prefer to not modify the member variable AUX_SYMENTS and only adjust
> it if needed / when read, as you already do with AUX_FIRST_GLOBAL.
You are right, that is nicer. And aux_syments is really only used in one
place. Updated patch that only adjusts at use attached.
> TBH FYI / no request here: I no not find this first_global + syments too clear
> now when combining multiple symbol tables, which is why I have refactored it in:
> [patch 1/3] ppc64 .opd: Refactor syments/first_global
> https://lists.fedorahosted.org/pipermail/elfutils-devel/2012-December/002839.html
I'll take a look. I should be somewhat familiar with the code now.
BTW. Please do ping patches you feel are urgent.
Thanks,
Mark
>From 697bdca1d7d70ebdcae90759dd885258400e1951 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mjw@redhat.com>
Date: Wed, 23 Jan 2013 17:39:19 +0100
Subject: [PATCH] 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>
---
libdwfl/ChangeLog | 13 +++++++++++++
libdwfl/dwfl_module_addrsym.c | 16 +++++++++++-----
libdwfl/dwfl_module_getdwarf.c | 22 ++++++++++++++++------
libdwfl/dwfl_module_getsym.c | 11 ++++++-----
tests/ChangeLog | 7 +++++++
tests/Makefile.am | 2 +-
tests/run-dwflsyms.sh | 13 +++++++++++++
tests/run-readelf-s.sh | 40 ++++++++++++++++++++++++++++++++++++++++
tests/testfilebasmin.bz2 | Bin 0 -> 1082 bytes
9 files changed, 107 insertions(+), 17 deletions(-)
create mode 100755 tests/testfilebasmin.bz2
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 828db08..cf5b42e 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -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,
diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c
index d2059ea..732b698 100644
--- a/libdwfl/dwfl_module_addrsym.c
+++ b/libdwfl/dwfl_module_addrsym.c
@@ -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. */
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index ffbe589..d35c266 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -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;
diff --git a/libdwfl/dwfl_module_getsym.c b/libdwfl/dwfl_module_getsym.c
index 3e4d9f6..07127b7 100644
--- a/libdwfl/dwfl_module_getsym.c
+++ b/libdwfl/dwfl_module_getsym.c
@@ -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;
diff --git a/tests/ChangeLog b/tests/ChangeLog
index feb9f69..bc721c7 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -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.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b46c4c2..f32ea24 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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 \
diff --git a/tests/run-dwflsyms.sh b/tests/run-dwflsyms.sh
index 570881a..56a7580 100755
--- a/tests/run-dwflsyms.sh
+++ b/tests/run-dwflsyms.sh
@@ -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
diff --git a/tests/run-readelf-s.sh b/tests/run-readelf-s.sh
index f14b305..bad31cf 100755
--- a/tests/run-readelf-s.sh
+++ b/tests/run-readelf-s.sh
@@ -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
diff --git a/tests/testfilebasmin.bz2 b/tests/testfilebasmin.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..3843972037ca84dc9599f5dc25ad05e0f2278f43
GIT binary patch
literal 1082
zcmV-A1jYM8T4*^jL0KkKS=jQ&IRF9VfB*mg-@X5@_22*Je}4D>|M%bjf9>DZXV?7x
z?YGnI|Np=OyaGAKD2ftjJw_CI4H-iLqfHtO6KOIHsLdKpF&?3fObq~!NuwjuHlS!|
z(@X*~X!SPL8$x;`LkW`&OaV07pQ>zXg-FzGO&Sdv27mzafB*mh0ib9A00000&;S4i
zjQ{`u0000Q211oG8z{uk14pO;000Jn05kwJ0004?000000MGyifCE4P007fb36#Xz
z6wn$pdY-0+Kn6etng9lYp!El+G7UXLKmY-wKmY&%>Hq)+fB+2xMN`W|n6h(h0~K>X
zNiGMW@`8zhT$zR$Q^rgd*$`Z9m`lJJN=B=@R>H_>9>04+P)<)iw#_)u2`;4s1XYxQ
z9}uz#GXx+X1|SKtrWQgv?lFfA-#;|A8=J{3XaGtQh!I5)Bl3a?6Xg&~nIr&_0YN-M
z2ayzjC$F}srzs+e!yXn@>tVwlyr78b$dn2c5^Fk{+Y`YQg%HUSX{A@nB68N^(p5O{
zATe4f8YA~bIz=l1QLZImYyc?26z@xQYCg<>;Xs7H%T~Z`Yys-)sW&t6S0bDA(8051
zAxTc5gaV@;>$5PfN%(W-xY*dt^eR<LNT3s<a4cUOpaMV{r-G!z+w|!8vB0a<YoE#v
z&Uv1FRUYal>|-?hMa&2c&|6INhjMZdSYzW_oGylL|KPlLLCtlmn3I}kT{@N8z&DxV
z8}UGx_G!iDpv9&XK%>W>Mxc+9_~Qgw*R(uQwnt7D416J#3P`L`2oU1Pis9c|I#>hK
z?s4BbkO1?8vo0@ius^RN{Lz2t6qp0av4o-S&4C1!`*&7ss|9DSfooz`AWAX=$)x}c
zNO3X5&J6`os40YoapOF1d?dPonFJ<`x(98R<hU-1HwP9pQ**~)mjMwrh;|VP0rrN4
z_c)H0bO8hAT@1lMaO((*%x^K=sZ_}Qui0`11PiQ+tq&O`3DM+5`mHd^m>>l$%zmIu
zC9nb**KCAjP1duZ%tu-%MIbn=+FJ6WAWAu8(WoAOF?p$sNV6IOOrX*VPKt@Z1=qg`
z18ayPYle(p>bL{IAOK3^IIQ8p0Iy<f`3pq3IWVO`UoxaxsBhdRKWEuNjKGg;MR}P1
z)t}2s)@Y0F3diYb=2LF+i(mAvk?o`M_-?lnU_oK_okv-fLdqp>T}^JKzl&0Hp$Ivc
zJ_ND;r6QxOAtV73?e@Y*`|S~cAX0NxkFy5Y%a1-xXj@&`28P3iVXv&wM5QSP+Knp~
z4BO5CwD9VRY^<XR*i1_BfvcF%7Xx&Vt0xT)L}u2D8-}~{b+c&uXnC{OZLTe6U@eBA
zYEL<a%!<`o*m3T4mMEc<wv$}=;g|qmm<?c1f<znwV27xmq3`&+k}1N3hR2pU$R!8e
AVgLXD
literal 0
HcmV?d00001
--
1.7.1