https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97713
Bug ID: 97713 Summary: [gsplit-dwarf] label generated for .debug_abbrev.dwo offset, corresponding relocation ignored by objcopy --extract-dwo Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: vries at gcc dot gnu.org Target Milestone: --- I. Consider a simple hello.c, compiled with debug info: ... $ gcc-11 -g ~/hello.c -dA -save-temps ... In a-hello.s, in the CU header we have a label .Ldebug_abbrev0: ... .section .debug_info,"",@progbits .Ldebug_info0: .long 0x87 # Length of Compilation Unit Info .value 0x4 # DWARF version number .long .Ldebug_abbrev0 # Offset Into Abbrev. Section .... referring here: ... .section .debug_abbrev,"",@progbits .Ldebug_abbrev0: .uleb128 0x1 # (abbrev code) .uleb128 0x11 # (TAG: DW_TAG_compile_unit) ... In a-hello.o, we find a zero at the abbrev offset: ... Contents of the .debug_info section: Compilation Unit @ offset 0x0: Length: 0x87 (32-bit) Version: 4 Abbrev Offset: 0x0 Pointer Size: 8 ... but there's a related relocation in place: ... Relocation section '.rela.debug_info' at offset 0x4c8 contains 16 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000000006 00070000000a R_X86_64_32 0000000000000000 .debug_abbrev + 0 ... and in the a.out, we end up with: ... Compilation Unit @ offset 0xc7: Length: 0x87 (32-bit) Version: 4 Abbrev Offset: 0x64 ... II. Now cp a-hello.s to hello.s and modify like this: ... $ diff -u a-hello.s hello.s --- a-hello.s 2020-11-04 13:04:03.325633204 +0100 +++ hello.s 2020-11-04 13:04:17.001509687 +0100 @@ -102,6 +102,7 @@ # DW_AT_GNU_all_tail_call_sites .byte 0 # end of children of DIE 0xb .section .debug_abbrev,"",@progbits + .uleb128 0x0 # (abbrev code) .Ldebug_abbrev0: .uleb128 0x1 # (abbrev code) .uleb128 0x11 # (TAG: DW_TAG_compile_unit) ... and recompile: ... $ gcc-11 -g hello.s -save-temps ... We can see that we've indeed moved the label by 1 byte: ... $ llvm-dwarfdump -debug-abbrev a-hello.o a-hello.o: file format ELF64-x86-64 .debug_abbrev contents: Abbrev table for offset: 0x00000000 Abbrev table for offset: 0x00000001 [1] DW_TAG_compile_unit DW_CHILDREN_yes ... and likewise, the relocation: ... Relocation section '.rela.debug_info' at offset 0x4c8 contains 16 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000000006 00070000000a R_X86_64_32 0000000000000000 .debug_abbrev + 1 ... and likewise, in the a.out: ... Compilation Unit @ offset 0xc7: Length: 0x87 (32-bit) Version: 4 Abbrev Offset: 0x65 ... III. Now, let's try the same with in .debug_abbrev.dwo. We compile with -gsplit-dwarf: ... $ gcc-11 ~/hello.c -g -gsplit-dwarf -dA -save-temps ... and copy to hello.s and modify: ... $ diff -u a-hello.s hello.s --- a-hello.s 2020-11-04 13:12:57.188966796 +0100 +++ hello.s 2020-11-04 13:14:48.632059272 +0100 @@ -156,6 +156,7 @@ .byte 0 .byte 0 # end of skeleton .debug_abbrev .section .debug_abbrev.dwo,"e",@progbits + .uleb128 0x0 # (abbrev code) .Ldebug_abbrev0: .uleb128 0x1 # (abbrev code) .uleb128 0x11 # (TAG: DW_TAG_compile_unit) ... We can see that we indeed added the entry to .debug_abbrev.dwo: ... $ llvm-dwarfdump -debug-abbrev a-hello.dwo a-hello.dwo: file format ELF64-x86-64 .debug_abbrev.dwo contents: Abbrev table for offset: 0x00000000 Abbrev table for offset: 0x00000001 [1] DW_TAG_compile_unit DW_CHILDREN_yes ... The abbrev offset is 0: ... Contents of the .debug_info.dwo section: Compilation Unit @ offset 0x0: Length: 0x50 (32-bit) Version: 4 Abbrev Offset: 0x0 ... but there's no related relocation so the CU is interpreted using the empty abbrev table at offset 0, and we run into: ... <0><b>: Abbrev Number: 1 readelf: Warning: DIE at offset 0xb refers to abbreviation number 1 which does not exist ... The split into .o/.dwo is done like this: ... /usr/lib64/gcc/x86_64-suse-linux/11/../../../../x86_64-suse-linux/bin/as --gdwarf2 -v --64 -o a-hello.o hello.s objcopy --extract-dwo a-hello.o a-hello.dwo objcopy --strip-dwo a-hello.o ... so we can recreate the original a-hello.o, and find the relocation: ... Relocation section '.rela.debug_info.dwo' at offset 0x710 contains 1 entry: Offset Info Type Sym. Value Sym. Name + Addend 000000000006 000a0000000a R_X86_64_32 0000000000000000 .debug_abbrev.dwo + 1 ... So, objcopy --extract-dwo (silently) drops the relocation rather than implement it. Now, should objcopy implement the relocation? Note that llvm emits a '0' as abbrev offset instead of a label.