Index: lld/ELF/InputSection.h =================================================================== --- lld/ELF/InputSection.h +++ lld/ELF/InputSection.h @@ -73,6 +73,9 @@ unsigned Bss : 1; + // True if this is a debuginfo section. + unsigned Debug : 1; + // Set for sections that should not be folded by ICF. unsigned KeepUnique : 1; @@ -100,7 +103,7 @@ uint64_t Entsize, uint64_t Alignment, uint32_t Type, uint32_t Info, uint32_t Link) : Name(Name), Repl(this), SectionKind(SectionKind), Live(false), - Assigned(false), Bss(false), KeepUnique(false), Alignment(Alignment), + Assigned(false), Bss(false), Debug(false), KeepUnique(false), Alignment(Alignment), Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Info(Info) {} }; Index: lld/ELF/InputSection.cpp =================================================================== --- lld/ELF/InputSection.cpp +++ lld/ELF/InputSection.cpp @@ -71,6 +71,7 @@ NumRelocations = 0; AreRelocsRela = false; + Debug = Name.startswith(".debug") || Name.startswith(".zdebug"); // The ELF spec states that a value of 0 means the section has // no alignment constraits. @@ -830,8 +831,16 @@ if (Sym.isTls() && !Out::TlsPhdr) Target->relocateOne(BufLoc, Type, 0); - else + else if (Sym.getOutputSection() || !Debug) Target->relocateOne(BufLoc, Type, SignExtend64(Sym.getVA(Addend))); + else + // If the relocation points to a deleted section, e.g. due to + // --gc-sections, then it is neccessary to make the start offset + // be outside the module address range to not overlap with the module's + // ranges. We use UINT64_MAX-1 as maximal value of an address because + // UINT64_MAX has special usage in .debug_ranges. + // https://bugs.llvm.org/show_bug.cgi?id=41124 + Target->relocateOne(BufLoc, Type, 0xfffffffffffffffeULL); } } Index: lld/test/ELF/gc-sections-alloc.s =================================================================== --- lld/test/ELF/gc-sections-alloc.s +++ lld/test/ELF/gc-sections-alloc.s @@ -20,7 +20,7 @@ # CHECK-NEXT: AddressAlignment: # CHECK-NEXT: EntrySize: # CHECK-NEXT: SectionData ( -# CHECK-NEXT: 0000: 00000000 00000000 | +# CHECK-NEXT: 0000: FEFFFFFF FFFFFFFF | # CHECK-NEXT: ) Index: lld/test/ELF/gc-sections-debuginfo.s =================================================================== --- /dev/null +++ lld/test/ELF/gc-sections-debuginfo.s @@ -0,0 +1,41 @@ +# REQUIRES: x86 + +# RUN: echo '.section .text,"a"; .byte 0; .section .debug_foo,"",@progbits; .quad .text' \ +# RUN: | llvm-mc --filetype=obj --arch=x86-64 - -o %t +# RUN: ld.lld %t -o %t2 --gc-sections +# RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s --check-prefixes=CHECK,CHECK64 + +# RUN: echo '.section .text,"a"; .byte 0; .section .debug_foo,"",@progbits; .long .text' \ +# RUN: | llvm-mc --filetype=obj --arch=x86 - -o %t +# RUN: ld.lld %t -o %t2 --gc-sections +# RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s --check-prefixes=CHECK,CHECK32 + + +# When --gc-sections is used, the linker deletes unused text sections, +# but their debug data is left in the binary. That debug data could have relocations +# pointing to deleted sections. Address ranges of such debug data could overlap +# with other address ranges for correct debug data. To prevent addresses clashing +# it is neccessary to resolve such relocations to an address which is out of the +# module address space. That test checks that relocations from the .debug_foo +# section pointing to a deleted .text section would be resolved +# to 0xfffffffffffffffe. + +# CHECK-NOT: Name: .text + +# CHECK: Name: .debug_foo +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: ] +# CHECK-NEXT: Address: +# CHECK-NEXT: Offset: +# CHECK64-NEXT: Size: 8 +# CHECK32-NEXT: Size: 4 +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: SectionData ( +# CHECK64-NEXT: 0000: FEFFFFFF FFFFFFFF +# CHECK32-NEXT: 0000: FEFFFFFF +# CHECK-NEXT: ) + Index: lld/test/ELF/merge-gc-piece2.s =================================================================== --- lld/test/ELF/merge-gc-piece2.s +++ lld/test/ELF/merge-gc-piece2.s @@ -15,7 +15,7 @@ # CHECK-NEXT: AddressAlignment: # CHECK-NEXT: EntrySize: # CHECK-NEXT: SectionData ( -# CHECK-NEXT: 0000: 01000000 00000000 02000000 00000000 +# CHECK-NEXT: 0000: FEFFFFFF FFFFFFFF FEFFFFFF FFFFFFFF # CHECK-NEXT: ) .section .foo,"aM",@progbits,8 Index: lld/test/ELF/relocation-copy-flags.s =================================================================== --- lld/test/ELF/relocation-copy-flags.s +++ lld/test/ELF/relocation-copy-flags.s @@ -62,7 +62,7 @@ // CHECK-NEXT: AddressAlignment: 1 // CHECK-NEXT: EntrySize: 0 // CHECK-NEXT: SectionData ( -// CHECK-NEXT: 0000: 00000000 +// CHECK-NEXT: 0000: FEFFFFFF FFFFFFFF // CHECK-NEXT: ) // CHECK: Relocations [