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 relocation points to the deleted section (-Wl,--gc-sections), + // then it is neccessary to make start offset to be out of + // module address range to not to overlap with module's ranges. + // UINT64_MAX-1 used as maximal value of an address. UINT64_MAX has + // special usage in .debug_ranges so we use UINT64_MAX minus one. + // 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,40 @@ +# REQUIRES: x86 + +# RUN: echo '.section .text,"a"; .byte 0; .section .debug_info,"",@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-prefix=CHECK -check-prefix=CHECK64 + +# RUN: echo '.section .text,"a"; .byte 0; .section .debug_info,"",@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-prefix=CHECK -check-prefix=CHECK32 + + +# When -Wl,--gc-sections used - linker deletes unused text sections. +# But their debug info left in the binary. That debug_info could have relocations +# pointing to deleted sections. Address ranges of such debug_info could overlapp +# with other address ranges for correct debug_info. To prevent address'es clashing +# it is neccessary to resolve such relocations to an address which is out of module +# address space. That test checks that relocation from .debug_info section pointing +# to deleted section .text would be resolved into 0xfffffffffffffffe. + +# CHECK-NOT: Name: .text + +# CHECK: Name: .debug_info +# 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 [