Index: lld/ELF/InputSection.cpp =================================================================== --- lld/ELF/InputSection.cpp +++ lld/ELF/InputSection.cpp @@ -829,8 +829,16 @@ if (Sym.isTls() && !Out::TlsPhdr) Target->relocateOne(BufLoc, Type, 0); - else + else if (Sym.getOutputSection()) Target->relocateOne(BufLoc, Type, SignExtend64(Sym.getVA(Addend))); + else + // If the relocation points to a deleted section (--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 [