]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
readelf: Add .gdb_index version 7 support.
authorMark Wielaard <mjw@redhat.com>
Fri, 29 Jun 2012 21:38:09 +0000 (23:38 +0200)
committerMark Wielaard <mjw@redhat.com>
Tue, 10 Jul 2012 12:40:35 +0000 (14:40 +0200)
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 <mjw@redhat.com>
src/ChangeLog
src/readelf.c
tests/ChangeLog
tests/Makefile.am
tests/run-readelf-gdb_index.sh [new file with mode: 0755]
tests/testfilegdbindex5.bz2 [new file with mode: 0755]
tests/testfilegdbindex7.bz2 [new file with mode: 0755]

index 2928ab1f94ffb2e484ff994aaf3c0d5e6ccd79d1..a474bb92020e342e5bdac88be7eb6aa8eaf88fae 100644 (file)
@@ -1,3 +1,9 @@
+2012-07-10  Mark Wielaard  <mjw@redhat.com>
+
+       * 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  <mjw@redhat.com>
 
        * readelf.c (dwarf_attr_string): Add DW_AT_GNU_macros.
index eb1d469d015685c5a35e8002ce5156e619a210d7..62b2100b4b074419557bef1ccb614c951889df75 100644 (file)
@@ -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");
        }
index 9b649173e99aebdce323af30dae770b6c6905379..9cc13c5a998b710154faf74e84d244d07f4470a9 100644 (file)
@@ -1,3 +1,12 @@
+2012-06-27  Mark Wielaard  <mjw@redhat.com>
+
+       * 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  <mjw@redhat.com>
 
        * run-macro-test.sh: New test.
index 39e58ae8679bfb08fa9d60b9e264dcd6eb6bb2f6..4d7fa22b503fe0935603f8058fcba3894f0ae9ca 100644 (file)
@@ -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 (executable)
index 0000000..31c94c1
--- /dev/null
@@ -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 (executable)
index 0000000..45ee945
Binary files /dev/null and b/tests/testfilegdbindex5.bz2 differ
diff --git a/tests/testfilegdbindex7.bz2 b/tests/testfilegdbindex7.bz2
new file mode 100755 (executable)
index 0000000..2a7c6c2
Binary files /dev/null and b/tests/testfilegdbindex7.bz2 differ