[ELF] Allow R_386_GOTOFF from .debug_info
authorFangrui Song <i@maskray.me>
Thu, 4 Feb 2021 17:17:47 +0000 (09:17 -0800)
committerFangrui Song <i@maskray.me>
Thu, 4 Feb 2021 17:17:47 +0000 (09:17 -0800)
In GCC emitted .debug_info sections, R_386_GOTOFF may be used to
relocate DW_AT_GNU_call_site_value values
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98946).

R_386_GOTOFF (`S + A - GOT`) is one of the `isStaticLinkTimeConstant` relocation
type which is not PC-relative, so it can be used from non-SHF_ALLOC sections. We
current allow new relocation types as needs come. The diagnostic has caught some
bugs in the past.

Differential Revision: https://reviews.llvm.org/D95994

lld/ELF/InputSection.cpp
lld/test/ELF/non-abs-reloc.s

index f40bb25..6f16fc7 100644 (file)
@@ -901,7 +901,10 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
       continue;
     }
 
-    if (expr != R_ABS && expr != R_DTPREL && expr != R_RISCV_ADD) {
+    // R_ABS/R_DTPREL and some other relocations can be used from non-SHF_ALLOC
+    // sections.
+    if (expr != R_ABS && expr != R_DTPREL && expr != R_GOTPLTREL &&
+        expr != R_RISCV_ADD) {
       std::string msg = getLocation<ELFT>(offset) +
                         ": has non-ABS relocation " + toString(type) +
                         " against symbol '" + toString(sym) + "'";
index 72a6542..82f913e 100644 (file)
@@ -1,17 +1,17 @@
 // REQUIRES: x86
 // RUN: split-file %s %t
-// RUN: llvm-mc -filetype=obj -triple=x86_64 %t/asm -o %t.o
-// RUN: ld.lld -T %t/lds %t.o -o %t.exe 2>&1 | FileCheck %s
-// CHECK:      warning: {{.*}}.o:(.nonalloc1+0x1): has non-ABS relocation R_X86_64_PC32 against symbol '_start'
-// CHECK-NEXT: warning: {{.*}}.o:(.nonalloc1+0x6): has non-ABS relocation R_X86_64_PC32 against symbol '_start'
+// RUN: llvm-mc -filetype=obj -triple=i386 %t/asm -o %t.o
+// RUN: ld.lld -T %t/lds %t.o -o %t.exe 2>&1 | FileCheck %s --implicit-check-not=warning: --implicit-check-not=error:
+// CHECK:      warning: {{.*}}.o:(.nonalloc1+0x1): has non-ABS relocation R_386_PC32 against symbol '_start'
+// CHECK-NEXT: warning: {{.*}}.o:(.nonalloc1+0x6): has non-ABS relocation R_386_PC32 against symbol '_start'
 
 // RUN: llvm-objdump -D --no-show-raw-insn %t.exe | FileCheck --check-prefix=DISASM %s
 // DISASM:      Disassembly of section .nonalloc:
 // DISASM-EMPTY:
 // DISASM-NEXT: <.nonalloc>:
 // DISASM-NEXT:   0: nop
-// DISASM-NEXT:   1: callq 0x0
-// DISASM-NEXT:   6: callq 0x0
+// DISASM-NEXT:   1: calll 0x0
+// DISASM-NEXT:   6: calll 0x0
 
 //--- lds
 SECTIONS {
@@ -20,6 +20,7 @@ SECTIONS {
 //--- asm
 .globl _start
 _start:
+.L0:
   nop
 
 .section .nonalloc0
@@ -30,3 +31,8 @@ _start:
   .long _start - . - 4
   .byte 0xe8
   .long _start - . - 4
+
+// GCC may relocate DW_AT_GNU_call_site_value with R_386_GOTOFF.
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98946
+.section .debug_info
+  .long .L0@gotoff