// hash used for generating the table. Version 6 contains symbols
// for inlined functions, older versions didn't. Version 7 adds
// symbol kinds. Version 8 just indicates that it correctly includes
- // TUs for symbols.
- if (vers < 4 || vers > 8)
+ // TUs for symbols. Version 9 adds shortcut table for information
+ // regarding the main function.
+ if (vers < 4 || vers > 9)
{
printf (_(" unknown version, cannot parse section\n"));
return;
if (unlikely (readp + 4 > dataend))
goto invalid_data;
+ uint32_t shortcut_off = 0;
+ if (vers >= 9)
+ {
+ shortcut_off = read_4ubyte_unaligned (dbg, readp);
+ printf (_(" shortcut offset: %#" PRIx32 "\n"), shortcut_off);
+
+ readp += 4;
+ if (unlikely (readp + 4 > dataend))
+ goto invalid_data;
+ }
+
uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
printf (_(" constant offset: %#" PRIx32 "\n"), const_off);
if (const_off >= data->d_size)
goto invalid_data;
+ const unsigned char *shortcut_start = NULL;
+ if (vers >= 9)
+ {
+ if (shortcut_off >= data->d_size)
+ goto invalid_data;
+
+ shortcut_start = data->d_buf + shortcut_off;
+ nextp = shortcut_start;
+ }
+ else
+ nextp = const_start;
+
readp = data->d_buf + sym_off;
- nextp = const_start;
size_t sym_nr = (nextp - readp) / 8;
printf (_("\n Symbol table at offset %#" PRIx32
}
n++;
}
+
+ if (vers < 9)
+ return;
+
+ if (unlikely (shortcut_start == NULL))
+ goto invalid_data;
+
+ readp = shortcut_start;
+ nextp = const_start;
+ size_t shortcut_nr = (nextp - readp) / 4;
+
+ if (unlikely (shortcut_nr != 2))
+ goto invalid_data;
+
+ printf (_("\nShortcut table at offset %#" PRIx32 " contains %zu slots:\n"),
+ shortcut_off, shortcut_nr);
+
+ uint32_t lang = read_4ubyte_unaligned (dbg, readp);
+ readp += 4;
+
+ /* Include the hex number of LANG in the output if the language
+ is unknown. */
+ const char *lang_str = dwarf_lang_string (lang);
+ lang_str = string_or_unknown (lang_str, lang, DW_LANG_lo_user,
+ DW_LANG_hi_user, true);
+
+ printf (_("Language of main: %s\n"), lang_str);
+ printf (_("Name of main: "));
+
+ if (lang != 0)
+ {
+ uint32_t name = read_4ubyte_unaligned (dbg, readp);
+ readp += 4;
+ const unsigned char *sym = const_start + name;
+
+ if (unlikely ((size_t) (dataend - const_start) < name
+ || memchr (sym, '\0', dataend - sym) == NULL))
+ goto invalid_data;
+
+ printf ("%s\n", sym);
+ }
+ else
+ printf ("<unknown>\n");
}
/* Returns true and sets split DWARF CU id if there is a split compile
# (gdb) save gdb-index .
# objcopy --add-section .gdb_index=testfilegdbindex7.gdb-index --set-section-flags .gdb_index=readonly testfilegdbindex7 testfilegdbindex7
-testfiles testfilegdbindex5 testfilegdbindex7
+testfiles testfilegdbindex5 testfilegdbindex7 testfilegdbindex9 testfilegdbindex9-no-maininfo
testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=gdb_index testfilegdbindex5 <<\EOF
[ 754] symbol: int, CUs: 0 (type:S)
EOF
+# testfilegdbindex9-no-maininfo is built the same way as testfilegdbindex7.
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=gdb_index testfilegdbindex9-no-maininfo <<\EOF
+
+GDB section [33] '.gdb_index' at offset 0x38e1 contains 8415 bytes :
+ Version: 9
+ CU offset: 0x1c
+ TU offset: 0x3c
+ address offset: 0x54
+ symbol offset: 0x7c
+ shortcut offset: 0x207c
+ constant offset: 0x2084
+
+ CU list at offset 0x1c contains 2 entries:
+ [ 0] start: 0x00004c, length: 220
+ [ 1] start: 0x000128, length: 214
+
+ TU list at offset 0x3c contains 1 entries:
+ [ 0] CU offset: 0, type offset: 30, signature: 0x87e03f92cc37cdf0
+
+ Address list at offset 0x54 contains 2 entries:
+ [ 0] 0x0000000000401106 <main>..0x000000000040113b <main+0x35>, CU index: 1
+ [ 1] 0x000000000040113c <hello>..0x0000000000401173 <say+0x1c>, CU index: 2
+
+ Symbol table at offset 0x54 contains 1024 slots:
+ [ 123] symbol: global, CUs: 1 (var:G), 0T (var:G)
+ [ 489] symbol: main, CUs: 1 (func:G)
+ [ 518] symbol: char, CUs: 0 (type:S)
+ [ 661] symbol: foo, CUs: 0 (type:S)
+ [ 741] symbol: hello, CUs: 1 (var:S), 0T (func:S)
+ [ 746] symbol: say, CUs: 0T (func:G)
+ [ 754] symbol: int, CUs: 1 (type:S)
+
+Shortcut table at offset 0x207c contains 2 slots:
+Language of main: ??? (0)
+Name of main: <unknown>
+EOF
+
+# testfilegdbindex9.f90
+#
+# program repro
+# type small_stride
+# character*40 long_string
+# integer small_pad
+# end type small_stride
+# type(small_stride), dimension (20), target :: unpleasant
+# character*40, pointer, dimension(:):: c40pt
+# integer i
+# do i = 0,19
+# unpleasant(i+1)%small_pad = i+1
+# unpleasant(i+1)%long_string = char (ichar('0') + i)
+# end do
+# c40pt => unpleasant%long_string
+# print *, c40pt
+#end program repro
+
+# gfortran -g -o testfilegdbindex9 testfilegdbindex9.f90
+# gdb-add-index testfilegdbindex9
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=gdb_index testfilegdbindex9 <<\EOF
+
+GDB section [35] '.gdb_index' at offset 0x37d9 contains 8395 bytes :
+ Version: 9
+ CU offset: 0x1c
+ TU offset: 0x2c
+ address offset: 0x2c
+ symbol offset: 0x40
+ shortcut offset: 0x2040
+ constant offset: 0x2048
+
+ CU list at offset 0x1c contains 1 entries:
+ [ 0] start: 00000000, length: 307
+
+ TU list at offset 0x2c contains 0 entries:
+
+ Address list at offset 0x2c contains 1 entries:
+ [ 0] 0x0000000000401166 <MAIN__>..0x00000000004013f0 <main+0x3a>, CU index: 0
+
+ Symbol table at offset 0x2c contains 1024 slots:
+ [ 61] symbol: small_stride, CUs: 0 (type:S)
+ [ 71] symbol: integer(kind=8), CUs: 0 (type:S)
+ [ 161] symbol: character(kind=1), CUs: 0 (type:S)
+ [ 397] symbol: unpleasant, CUs: 0 (var:S)
+ [ 489] symbol: main, CUs: 0 (func:G)
+ [ 827] symbol: integer(kind=4), CUs: 0 (type:S)
+ [ 858] symbol: c40pt, CUs: 0 (var:S)
+ [ 965] symbol: repro, CUs: 0 (func:S)
+ [1016] symbol: i, CUs: 0 (var:S)
+
+Shortcut table at offset 0x2040 contains 2 slots:
+Language of main: Fortran08
+Name of main: repro
+EOF
+
exit 0