rui314/mold

Symbol table is empty in `.gdb_index` created by mold

marxin opened this issue · 4 comments

I've just noticed the Symbol table of a .gdb_index is either empty or somehow corrupted for a trivial example:

❯ mold --version
mold 2.32.1 (compatible with GNU ld)
❯ gcc --version
gcc (SUSE Linux) 13.3.0
❯ echo 'int main() { return 0; }' | gcc -x c - -g -fuse-ld=mold -gpubnames -Wl,--gdb-index
❯ readelf --debug-dump=gdb_index a.out
Contents of the .gdb_index section:

Version 7

CU table:
[  0] 0 - 0x38
[  1] 0x39 - 0x1a7
[  2] 0x1a8 - 0x1e8
[  3] 0x1e9 - 0x2a1
[  4] 0x2a2 - 0x2c4
[  5] 0x2c5 - 0x318
[  6] 0x319 - 0x33b

TU table:

Address table:
00000000002014d0 00000000002014f6 0
0000000000201500 0000000000201515 3
00000000002014b0 00000000002014c6 4
00000000002014a0 00000000002014a8 4
00000000002015c6 00000000002015d1 5
00000000002014c6 00000000002014cb 6
00000000002014a8 00000000002014ad 6

Symbol table:
❯ eu-readelf --debug-dump=gdb_index a.out

GDB section [40] '.gdb_index' at offset 0x3020 contains 284 bytes :
 Version:         7
 CU offset:       0x18
 TU offset:       0x88
 address offset:  0x88
 symbol offset:   0x114
 constant offset: 0x11c

 CU list at offset 0x18 contains 7 entries:
 [   0] start: 00000000, length:    57
 [   1] start: 0x000039, length:   367
 [   2] start: 0x0001a8, length:    65
 [   3] start: 0x0001e9, length:   185
 [   4] start: 0x0002a2, length:    35
 [   5] start: 0x0002c5, length:    84
 [   6] start: 0x000319, length:    35

 TU list at offset 0x88 contains 0 entries:

 Address list at offset 0x88 contains 7 entries:
 [   0] 0x00000000002014d0 <_start>..0x00000000002014f5 <_start+0x25>, CU index:     0
 [   1] 0x0000000000201500..0x0000000000201514 <_dl_relocate_static_pie+0x6>, CU index:     3
 [   2] 0x00000000002014b0 <_init>..0x00000000002014c5 <_init+0x15>, CU index:     4
 [   3] 0x00000000002014a0 <_fini>..0x00000000002014a7 <_fini+0x7>, CU index:     4
 [   4] 0x00000000002015c6 <main>..0x00000000002015d0 <main+0xa>, CU index:     5
 [   5] 0x00000000002014c6 <_init+0x16>..0x00000000002014ca <_init+0x1a>, CU index:     6
 [   6] 0x00000000002014a8 <_fini+0x8>..0x00000000002014ac <_fini+0xc>, CU index:     6
eu-readelf: invalid data

If I emit the index by GDB I get:

❯ readelf --debug-dump=gdb_index a.out
Contents of the .gdb_index section:

Version 8

CU table:
[  0] 0 - 0x38
[  1] 0x39 - 0x1a7
[  2] 0x1a8 - 0x1e8
[  3] 0x1e9 - 0x2a1
[  4] 0x2a2 - 0x2c4
[  5] 0x2c5 - 0x318
[  6] 0x319 - 0x33b

TU table:

Address table:
00000000002014a0 00000000002014a8 4
00000000002014a8 00000000002014ad 6
00000000002014b0 00000000002014c6 4
00000000002014c6 00000000002014cb 6
00000000002014d0 00000000002014f6 0
0000000000201500 0000000000201515 3
00000000002015c6 00000000002015d1 5

Symbol table:
[ 18] unsigned long: 1 [static, type]
[ 68] unsigned char: 1 [static, type]
[ 93] unsigned short: 1 [static, type]
[ 94] _IO_stdin_used: 2 [global, variable]
[136] __int128: 1 [static, type]
[201] unsigned long long: 1 [static, type]
[334] __abi_tag: 1 [static, variable]
[386] __uint32_t: 1 [static, type]
[452] long double: 1 [static, type]
[468] long: 1 [static, type]
[476] _Bool: 1 [static, type]
[489] main: 5 [global, function]
[511] float: 1 [static, type]
[512] _dl_relocate_static_pie: 3 [global, function]
[518] char: 1 [static, type]
[542] int32_t: 1 [static, type]
[547] short: 1 [static, type]
[623] long long: 1 [static, type]
[689] signed char: 1 [static, type]
[732] unsigned int: 1 [static, type]
[754] int: 1 [static, type]
[842] uint32_t: 1 [static, type]
[851] _start: 0 [global, function]
[902] __int32_t: 1 [static, type]
[977] double: 1 [static, type]
[986] Elf64_Nhdr: 1 [static, type]
[1000] Elf64_Word: 1 [static, type]

I've got a couple of follow-up questions:

  • Why did you choose to implement the Version 7 in mold? Apparently, the Version 8 is > 10 years old and one might expect pretty all used gdb versions can use it. Or am I wrong?
  • Is the -gpubnames option needed for Mold to properly emit the GDB index?

Thanks!

Got it! One needs to use -ggnu-pubnames option instead of -gpubnames. Can you please document the behavior in --help for --gdb-index option?

It seems the section format changes in between -gpubnames and -ggnu-pubnames:

Contents of the .debug_pubnames section:

  Length:                              23
  Version:                             2
  Offset into .debug_info section:     0
  Size of area in .debug_info section: 84

    Offset	Name
    2e    	main
...
Contents of the .debug_gnu_pubnames section:

  Length:                              24
  Version:                             2
  Offset into .debug_info section:     0
  Size of area in .debug_info section: 84

    Offset  Kind          Name
    2e      g,function    main

Just for completeness, there's man page of the GCC compiler for the 2 options as mentioned earlier:

       -gpubnames
           Generate DWARF ".debug_pubnames" and ".debug_pubtypes" sections.

       -ggnu-pubnames
           Generate ".debug_pubnames" and ".debug_pubtypes" sections in a format suitable for conversion into a GDB index.  This option is only useful with a linker that can produce GDB index version 7.

If I use the correct option, mold emits the expected output:

[  1] main: 5 [global, function]
[  2] int: 5 [static, type]

Oh, it's mentioned in the manual page, my bad. Sorry for the noise.

So I'm going to utilize readelf --debug=gdb_index at least in #1296.

I wrongly thought the -gpubnames and -ggnu-pubnames options emit the same ELF sections, but that's incorrect. The former emits .debug_pubnames, while the latter one .debug_gnu_pubnames sections.