Index: lld/ELF/InputSection.cpp =================================================================== --- lld/ELF/InputSection.cpp +++ lld/ELF/InputSection.cpp @@ -651,17 +651,25 @@ RelExpr Expr = Target->getRelExpr(Type, Sym, BufLoc); if (Expr == R_NONE) continue; - if (Expr != R_ABS) { - // GCC 8.0 or earlier have a bug that it emits R_386_GOTPC relocations - // against _GLOBAL_OFFSET_TABLE for .debug_info. The bug seems to have - // been fixed in 2017: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630, - // but we need to keep this bug-compatible code for a while. - if (Config->EMachine == EM_386 && Type == R_386_GOTPC) - continue; - error(getLocation(Offset) + ": has non-ABS relocation " + - toString(Type) + " against symbol '" + toString(Sym) + "'"); - return; + if (Expr != R_ABS) { + // If the control reaches here, we found a PC-relative relocation in a + // non-ALLOC section. Since non-ALLOC section is not loaded into memory + // at runtime, the notion of PC-relative in such section doesn't make + // sense. So, this is a usage error. However, GNU linkers historically + // accept such relocations without any error and relocate them as if + // they were at address 0. For bug-compatibilty, we accepts them with + // warnings. + // + // GCC 8.0 or earlier emit such relocations due to a bug [1]. Steel Bank + // Common Lisp as of 2018 emits them too. + // + // [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630 + warn(getLocation(Offset) + ": has non-ABS relocation " + + toString(Type) + " against symbol '" + toString(Sym) + "'"); + Target->relocateOne(BufLoc, Type, + SignExtend64(Sym.getVA(Addend - Offset))); + continue; } if (Sym.isTls() && !Out::TlsPhdr) Index: lld/test/ELF/invalid/invalid-debug-relocations.test =================================================================== --- lld/test/ELF/invalid/invalid-debug-relocations.test +++ /dev/null @@ -1,40 +0,0 @@ -# REQUIRES: x86 -# RUN: yaml2obj %s -o %t.o -# RUN: not ld.lld -gdb-index %t.o -o %t.exe 2>&1 | FileCheck %s - -# CHECK: error: {{.*}}invalid-debug-relocations.test.tmp.o:(.debug_info+0x0): has non-ABS relocation Unknown (255) against symbol '_start' - -!ELF -FileHeader: - Class: ELFCLASS32 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_386 -Sections: - - Type: SHT_PROGBITS - Name: .text - Flags: [ ] - AddressAlign: 0x04 - Content: "0000" - - Type: SHT_PROGBITS - Name: .debug_info - Flags: [ ] - AddressAlign: 0x04 - Content: "0000" - - Type: SHT_REL - Name: .rel.debug_info - Link: .symtab - Info: .debug_info - Relocations: - - Offset: 0 - Symbol: _start - Type: 0xFF - - Offset: 4 - Symbol: _start - Type: 0xFF -Symbols: - Global: - - Name: _start - Type: STT_FUNC - Section: .text - Value: 0x0 Index: lld/test/ELF/non-abs-reloc.s =================================================================== --- lld/test/ELF/non-abs-reloc.s +++ lld/test/ELF/non-abs-reloc.s @@ -1,11 +1,18 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s -// CHECK: {{.*}}:(.dummy+0x0): has non-ABS relocation R_X86_64_GOTPCREL against symbol 'foo' +// RUN: ld.lld %t.o -o %t 2>&1 | FileCheck %s +// CHECK: (.nonalloc+0x1): has non-ABS relocation R_X86_64_PC32 against symbol '_start' +// CHECK: (.nonalloc+0x6): has non-ABS relocation R_X86_64_PC32 against symbol '_start' + +// RUN: llvm-objdump -D %t +// DISASM: <.nonalloc>: +// DISASM-NEXT: 0: e8 fb 0f 20 00 callq 201000 <_start> +// DISASM-NEXT: 5: e8 f6 0f 20 00 callq 201000 <_start> .globl _start _start: nop -.section .dummy - .long foo@gotpcrel +.section .nonalloc + call _start + call _start