When multiple incompatible COMDAT sections are present, gold selects one, but doesn't discard .debug_* and .eh_frame bits which refer to the other ones.
This then shows up as glitches in debugging the resulting executable under GDB. Test: --- cut --- test.h --- #include <stdio.h> inline int foo() { return 3; } extern char buf[4]; inline void HelloWorld() { // just some code to mess with stack layout printf("memcmp(): %d\n", __builtin_memcmp(buf, "abc", sizeof(buf))); printf("Hello %d\n", foo()); } --- cut --- test.h --- --- cut --- test1.cc --- #include "test.h" void Trampoline(void (*fn)() = HelloWorld); char buf[4] = "abc"; int main() { HelloWorld(); Trampoline(); return 0; } --- cut --- test1.cc --- --- cut --- test2.cc --- #include "test.h" void Trampoline(void (*fn)() = HelloWorld) { fn(); } void NotCalled() { Trampoline(); } --- cut --- test2.cc --- ./ld --version GNU gold (GNU Binutils 2.19.51.20090714) 1.9 ... g++ -g -c test1.cc && g++ -g -c test2.cc -O2 && g++ -g test1.o test2.o -B. -o test-gold First the unwind info: nm test-gold | grep HelloWorld 00000000004002fe W _Z10HelloWorldv readelf -wf test-gold # contains inconsistent unwind descriptors: # from test1.o, corresponds to code actually used 000000a8 00000024 0000004c FDE cie=00000060 pc=004002fe..0040033f DW_CFA_advance_loc4: 1 to 004002ff DW_CFA_def_cfa_offset: 16 DW_CFA_offset: r6 at cfa-16 DW_CFA_advance_loc4: 3 to 00400302 DW_CFA_def_cfa_reg: r6 DW_CFA_nop # from test2.o, corresponds to discarded code 000000d8 0000001c 00000090 FDE cie=00000090 pc=004002fe..00400343 DW_CFA_advance_loc4: 5 to 00400303 DW_CFA_def_cfa_offset: 16 DW_CFA_nop This shows up as a glitch in GDB: (gdb) b *&HelloWorld Breakpoint 1 at 0x4002fe: file test.h, line 10. (gdb) r Breakpoint 1, HelloWorld () at test.h:10 10 printf("memcmp(): %d\n", __builtin_memcmp(buf, "abc", sizeof(buf))); (gdb) bt #0 HelloWorld () at test.h:10 #1 0x00000000004002e1 in main () at test1.cc:7 (gdb) si HelloWorld () at test.h:8 8 inline void HelloWorld() { (gdb) bt #0 HelloWorld () at test.h:8 #1 0x00007fffffffdaa0 in ?? () #2 0x00000000004002e1 in main () at test1.cc:7 (gdb) si 0x0000000000400302 8 inline void HelloWorld() { (gdb) bt #0 0x0000000000400302 in HelloWorld () at test.h:8 #1 0x00007fffffffdaa0 in ?? () #2 0x00000000004002e1 in main () at test1.cc:7 (gdb) si 0x0000000000400307 in HelloWorld () at test.h:10 10 printf("memcmp(): %d\n", __builtin_memcmp(buf, "abc", sizeof(buf))); (gdb) bt #0 0x0000000000400307 in HelloWorld () at test.h:10 #1 0x00000000004002e1 in main () at test1.cc:7 Second, debug info differences: readelf -w <1><223>: Abbrev Number: 7 (DW_TAG_subprogram) <224> DW_AT_external : 1 <225> DW_AT_name : HelloWorld <230> DW_AT_decl_file : 1 <231> DW_AT_decl_line : 8 <232> DW_AT_MIPS_linkage_name: _Z10HelloWorldv <242> DW_AT_low_pc : 0x4002fe <24a> DW_AT_high_pc : 0x40033f <252> DW_AT_frame_base : 0x4c (location list) ... <1><36a>: Abbrev Number: 13 (DW_TAG_subprogram) <36b> DW_AT_external : 1 <36c> DW_AT_name : (indirect string, offset: 0x28): HelloWorld <370> DW_AT_decl_file : 2 <371> DW_AT_decl_line : 8 <372> DW_AT_MIPS_linkage_name: (indirect string, offset: 0xd5): _Z10HelloWorldv <376> DW_AT_low_pc : 0x4002fe <37e> DW_AT_high_pc : 0x400343 <386> DW_AT_frame_base : 0x107 (location list) Is HelloWorld spanning [0x4002fe,0x40033f] or [0x4002fe,0x400343] range? Finally, GNU ld doesn't show the same problem: it zeros out debug* and eh_frame entries corresponding to discarded sections: 000000d8 0000001c 00000090 FDE cie=00000090 pc=00000000..00000045 DW_CFA_advance_loc4: 5 to 00000005 DW_CFA_def_cfa_offset: 16 DW_CFA_nop And the debug info like this: <1><35d>: Abbrev Number: 12 (DW_TAG_subprogram) <35e> DW_AT_external : 1 <35f> DW_AT_name : foo <363> DW_AT_decl_file : 2 <364> DW_AT_decl_line : 3 <365> DW_AT_type : <2dd> <369> DW_AT_inline : 3 (declared as inline and inlined) <1><36a>: Abbrev Number: 13 (DW_TAG_subprogram) <36b> DW_AT_external : 1 <36c> DW_AT_name : (indirect string, offset: 0xb1): HelloWorld <370> DW_AT_decl_file : 2 <371> DW_AT_decl_line : 8 <372> DW_AT_MIPS_linkage_name: (indirect string, offset: 0x11d): _Z10HelloWorldv <376> DW_AT_low_pc : 0 <37e> DW_AT_high_pc : 0 <386> DW_AT_frame_base : 0x107 (location list) -- Summary: Gold produces incorrect debug and unwind info when incompatible COMDAT sections are present Product: binutils Version: 2.20 (HEAD) Status: NEW Severity: normal Priority: P2 Component: gold AssignedTo: ppluzhnikov at google dot com ReportedBy: ppluzhnikov at google dot com CC: bug-binutils at gnu dot org GCC build triplet: x86_64-unknown-linux-gnu GCC host triplet: x86_64-unknown-linux-gnu GCC target triplet: x86_64-unknown-linux-gnu http://sourceware.org/bugzilla/show_bug.cgi?id=10400 ------- You are receiving this mail because: ------- You are on the CC list for the bug, or are watching someone who is. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils