summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2012-06-29 23:38:09 +0200
committerMark Wielaard <[email protected]>2012-07-10 14:40:35 +0200
commit84a1e0b7396b29752f27486ec166b782a56852cb (patch)
treea441c83400219045121848a67b6da062a18dbe2b
parentef5688e1c4916c669f12dee708d07cec416b4e77 (diff)
readelf: Add .gdb_index version 7 support.
Add version 7 support. Keep track of cu_nr. Print kind and static/global flag for each symbol. When a symbol is in the TU list add 'T'. Add testfilegdbindex test files. Signed-off-by: Mark Wielaard <[email protected]>
-rw-r--r--src/ChangeLog6
-rw-r--r--src/readelf.c64
-rw-r--r--tests/ChangeLog9
-rw-r--r--tests/Makefile.am6
-rwxr-xr-xtests/run-readelf-gdb_index.sh130
-rwxr-xr-xtests/testfilegdbindex5.bz2bin0 -> 3481 bytes
-rwxr-xr-xtests/testfilegdbindex7.bz2bin0 -> 3497 bytes
7 files changed, 197 insertions, 18 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 2928ab1f..a474bb92 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2012-07-10 Mark Wielaard <[email protected]>
+
+ * readelf.c (print_gdb_index_section): Add version 7 support.
+ Keep track of cu_nr. Print kind and static/global flag for each
+ symbol. When a symbol is in the TU list add 'T'.
+
2012-06-26 Mark Wielaard <[email protected]>
* readelf.c (dwarf_attr_string): Add DW_AT_GNU_macros.
diff --git a/src/readelf.c b/src/readelf.c
index eb1d469d..62b2100b 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -7123,7 +7123,7 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
// The only difference between version 4 and version 5 is the
// hash used for generating the table. Version 6 contains symbols
// for inlined functions, older versions didn't.
- if (vers < 4 || vers > 6)
+ if (vers < 4 || vers > 7)
{
printf (gettext (" unknown version, cannot parse section\n"));
return;
@@ -7167,14 +7167,14 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
readp = data->d_buf + cu_off;
const unsigned char *nextp = data->d_buf + tu_off;
- size_t nr = (nextp - readp) / 16;
+ size_t cu_nr = (nextp - readp) / 16;
printf (gettext ("\n CU list at offset %#" PRIx32
" contains %zu entries:\n"),
- cu_off, nr);
+ cu_off, cu_nr);
size_t n = 0;
- while (readp + 16 <= dataend && n < nr)
+ while (readp + 16 <= dataend && n < cu_nr)
{
uint64_t off = read_8ubyte_unaligned (dbg, readp);
readp += 8;
@@ -7189,14 +7189,14 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
readp = data->d_buf + tu_off;
nextp = data->d_buf + addr_off;
- nr = (nextp - readp) / 24;
+ size_t tu_nr = (nextp - readp) / 24;
printf (gettext ("\n TU list at offset %#" PRIx32
" contains %zu entries:\n"),
- tu_off, nr);
+ tu_off, tu_nr);
n = 0;
- while (readp + 24 <= dataend && n < nr)
+ while (readp + 24 <= dataend && n < tu_nr)
{
uint64_t off = read_8ubyte_unaligned (dbg, readp);
readp += 8;
@@ -7215,14 +7215,14 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
readp = data->d_buf + addr_off;
nextp = data->d_buf + sym_off;
- nr = (nextp - readp) / 20;
+ size_t addr_nr = (nextp - readp) / 20;
printf (gettext ("\n Address list at offset %#" PRIx32
" contains %zu entries:\n"),
- addr_off, nr);
+ addr_off, addr_nr);
n = 0;
- while (readp + 20 <= dataend && n < nr)
+ while (readp + 20 <= dataend && n < addr_nr)
{
uint64_t low = read_8ubyte_unaligned (dbg, readp);
readp += 8;
@@ -7242,14 +7242,14 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
readp = data->d_buf + sym_off;
nextp = data->d_buf + const_off;
- nr = (nextp - readp) / 8;
+ size_t sym_nr = (nextp - readp) / 8;
printf (gettext ("\n Symbol table at offset %#" PRIx32
" contains %zu slots:\n"),
- addr_off, nr);
+ addr_off, sym_nr);
n = 0;
- while (readp + 8 <= dataend && n < nr)
+ while (readp + 8 <= dataend && n < sym_nr)
{
uint32_t name = read_4ubyte_unaligned (dbg, readp);
readp += 4;
@@ -7272,10 +7272,42 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
while (cus--)
{
- uint32_t cu;
+ uint32_t cu_kind, cu, kind;
+ bool is_static;
readcus += 4;
- cu = read_4ubyte_unaligned (dbg, readcus);
- printf ("%" PRId32 "%s", cu, ((cus > 0) ? ", " : ""));
+ cu_kind = read_4ubyte_unaligned (dbg, readcus);
+ cu = cu_kind & ((1 << 24) - 1);
+ kind = (cu_kind >> 28) & 7;
+ is_static = cu_kind & (1 << 31);
+ if (cu > cu_nr - 1)
+ printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
+ else
+ printf ("%" PRId32, cu);
+ if (kind != 0)
+ {
+ printf (" (");
+ switch (kind)
+ {
+ case 1:
+ printf ("type");
+ break;
+ case 2:
+ printf ("var");
+ break;
+ case 3:
+ printf ("func");
+ break;
+ case 4:
+ printf ("other");
+ break;
+ default:
+ printf ("unknown-0x%" PRIx32, kind);
+ break;
+ }
+ printf (":%c)", (is_static ? 'S' : 'G'));
+ }
+ if (cus > 0)
+ printf (", ");
}
printf ("\n");
}
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 9b649173..9cc13c5a 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,12 @@
+2012-06-27 Mark Wielaard <[email protected]>
+
+ * run-readelf-gdb-index.sh: New test.
+ * testfilegdbindex5.bz2: New testfile.
+ * testfilegdbindex7.bz2: Likewise.
+ * Makefile.am (TESTS): Add run-readelf-gdb-index.sh.
+ (EXTRA_DIST): run-readelf-gdb_index.sh, testfilegdbindex5.bz2 and
+ testfilegdbindex7.bz2.
+
2012-06-26 Mark Wielaard <[email protected]>
* run-macro-test.sh: New test.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 39e58ae8..4d7fa22b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -79,8 +79,8 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
run-early-offscn.sh run-dwarf-getmacros.sh \
run-test-flag-nobits.sh run-prelink-addr-test.sh \
run-dwarf-getstring.sh run-rerequest_tag.sh run-typeiter.sh \
- run-readelf-d.sh run-unstrip-n.sh run-low_high_pc.sh \
- run-macro-test.sh
+ run-readelf-d.sh run-readelf-gdb_index.sh run-unstrip-n.sh \
+ run-low_high_pc.sh run-macro-test.sh
if !STANDALONE
noinst_PROGRAMS += msg_tst md5-sha1-test
@@ -157,6 +157,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
testfile56.bz2 testfile57.bz2 testfile58.bz2 \
run-typeiter.sh testfile59.bz2 \
run-readelf-d.sh testlib_dynseg.so.bz2 \
+ run-readelf-gdb_index.sh testfilegdbindex5.bz2 \
+ testfilegdbindex7.bz2 \
run-unstrip-n.sh testcore-rtlib.bz2 \
run-low_high_pc.sh testfile_low_high_pc.bz2 \
run-macro-test.sh testfile-macinfo.bz2 testfile-macros.bz2
diff --git a/tests/run-readelf-gdb_index.sh b/tests/run-readelf-gdb_index.sh
new file mode 100755
index 00000000..31c94c14
--- /dev/null
+++ b/tests/run-readelf-gdb_index.sh
@@ -0,0 +1,130 @@
+#! /bin/sh
+# Copyright (C) 2012 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# common.h
+# struct foo
+# {
+# const char *bar;
+# };
+#
+# extern char *global;
+# int say (struct foo *prefix);
+
+# hello.c
+# #include "common.h"
+#
+# static char *hello = "Hello";
+#
+# int
+# main (int argc, char **argv)
+# {
+# struct foo baz;
+# global = hello;
+# baz.bar = global;
+# return say(&baz);
+# }
+
+# world.c
+# #include "common.h"
+#
+# char *global;
+#
+# static int hello (const char *bar)
+# {
+# return bar == global;
+# }
+#
+# int
+# say (struct foo *prefix)
+# {
+# return hello (prefix->bar);
+# }
+
+# gcc -g -fdebug-types-section -c hello.c
+# gcc -g -fdebug-types-section -c world.c
+# gcc -g -fdebug-types-section -o testfilegdbindex7 hello.o world.o
+# gdb testfilegdbindex7
+# (gdb) save gdb-index .
+# objcopy --add-section .gdb_index=testfilegdbindex7.gdb-index --set-section-flags .gdb_index=readonly testfilegdbindex7 testfilegdbindex7
+
+testfiles testfilegdbindex5 testfilegdbindex7
+
+testrun_compare ../src/readelf --debug-dump=gdb_index testfilegdbindex5 <<\EOF
+
+GDB section [33] '.gdb_index' at offset 0xe76 contains 8383 bytes :
+ Version: 5
+ CU offset: 0x18
+ TU offset: 0x38
+ address offset: 0x50
+ symbol offset: 0x78
+ constant offset: 0x2078
+
+ CU list at offset 0x18 contains 2 entries:
+ [ 0] start: 00000000, length: 184
+ [ 1] start: 0x0000b8, length: 204
+
+ TU list at offset 0x38 contains 1 entries:
+ [ 0] CU offset: 0, type offset: 29, signature: 0x87e03f92cc37cdf0
+
+ Address list at offset 0x50 contains 2 entries:
+ [ 0] 0x000000000040049c <main>..0x00000000004004d1 <main+0x35>, CU index: 0
+ [ 1] 0x00000000004004d4 <hello>..0x000000000040050b <say+0x1c>, CU index: 1
+
+ Symbol table at offset 0x50 contains 1024 slots:
+ [ 123] symbol: global, CUs: 1
+ [ 489] symbol: main, CUs: 0
+ [ 518] symbol: char, CUs: 0
+ [ 661] symbol: foo, CUs: 0T
+ [ 741] symbol: hello, CUs: 0, 1
+ [ 746] symbol: say, CUs: 1
+ [ 754] symbol: int, CUs: 0
+EOF
+
+testrun_compare ../src/readelf --debug-dump=gdb_index testfilegdbindex7 <<\EOF
+
+GDB section [33] '.gdb_index' at offset 0xe76 contains 8399 bytes :
+ Version: 7
+ CU offset: 0x18
+ TU offset: 0x38
+ address offset: 0x50
+ symbol offset: 0x78
+ constant offset: 0x2078
+
+ CU list at offset 0x18 contains 2 entries:
+ [ 0] start: 00000000, length: 184
+ [ 1] start: 0x0000b8, length: 204
+
+ TU list at offset 0x38 contains 1 entries:
+ [ 0] CU offset: 0, type offset: 29, signature: 0x87e03f92cc37cdf0
+
+ Address list at offset 0x50 contains 2 entries:
+ [ 0] 0x000000000040049c <main>..0x00000000004004d1 <main+0x35>, CU index: 0
+ [ 1] 0x00000000004004d4 <hello>..0x000000000040050b <say+0x1c>, CU index: 1
+
+ Symbol table at offset 0x50 contains 1024 slots:
+ [ 123] symbol: global, CUs: 1 (var:G)
+ [ 489] symbol: main, CUs: 0 (func:G)
+ [ 518] symbol: char, CUs: 0 (type:S)
+ [ 661] symbol: foo, CUs: 0T (type:S)
+ [ 741] symbol: hello, CUs: 0 (var:S), 1 (func:S)
+ [ 746] symbol: say, CUs: 1 (func:G)
+ [ 754] symbol: int, CUs: 0 (type:S)
+EOF
+
+exit 0
diff --git a/tests/testfilegdbindex5.bz2 b/tests/testfilegdbindex5.bz2
new file mode 100755
index 00000000..45ee945a
--- /dev/null
+++ b/tests/testfilegdbindex5.bz2
Binary files differ
diff --git a/tests/testfilegdbindex7.bz2 b/tests/testfilegdbindex7.bz2
new file mode 100755
index 00000000..2a7c6c2c
--- /dev/null
+++ b/tests/testfilegdbindex7.bz2
Binary files differ