| commit b3165a70ae83b46dc145f335dfa9690ece361e92 |
| Author: Fangrui Song <i@maskray.me> |
| Date: Thu Feb 4 09:17:47 2021 -0800 |
| |
| [ELF] Allow R_386_GOTOFF from .debug_info |
| |
| 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 |
| |
| diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp |
| index f40bb258b9af..6f16fc7abc48 100644 |
| --- a/lld/ELF/InputSection.cpp |
| +++ b/lld/ELF/InputSection.cpp |
| @@ -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) + "'"; |
| diff --git a/lld/test/ELF/non-abs-reloc.s b/lld/test/ELF/non-abs-reloc.s |
| index 72a65424ed1f..82f913efe4d8 100644 |
| --- a/lld/test/ELF/non-abs-reloc.s |
| +++ b/lld/test/ELF/non-abs-reloc.s |
| @@ -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 |