diff options
| author | Fangrui Song <maskray@google.com> | 2020-01-03 21:44:57 -0800 |
|---|---|---|
| committer | Fangrui Song <maskray@google.com> | 2020-01-12 13:46:24 -0800 |
| commit | 2bfee35cb860859b436de0b780fbd00d68e198a4 (patch) | |
| tree | fe4c42d800afca08c64c7f17c9e12d6146e6bf4f | |
| parent | 241f330d6bab52ab4e3a01cbb9a3edd417d07c59 (diff) | |
| download | bcm5719-llvm-2bfee35cb860859b436de0b780fbd00d68e198a4.tar.gz bcm5719-llvm-2bfee35cb860859b436de0b780fbd00d68e198a4.zip | |
[MC][ELF] Emit a relocation if target is defined in the same section and is non-local
For a target symbol defined in the same section, currently we don't emit
a relocation if VariantKind is VK_None (with few exceptions like RISC-V
relaxation), while GNU as emits one. This causes program behavior
differences with and without -ffunction-sections, and can break intended
symbol interposition in a -shared link.
```
.globl foo
foo:
call foo # no relocation. On other targets, may be written as b foo, etc
call bar # a relocation if bar is in another section (e.g. -ffunction-sections)
call foo@plt # a relocation
```
Unify these cases by always emitting a relocation. If we ever want to
optimize `call foo` in -shared links, we should emit a STB_LOCAL alias
and call via the alias.
ARM/thumb2-beq-fixup.s: we now emit a relocation to global_thumb_fn as GNU as does.
X86/Inputs/align-branch-64-2.s: we now emit R_X86_64_PLT32 to foo as GNU does.
ELF/relax.s: rewrite the test as target-in-same-section.s .
We omitted relocations to `global` and now emit R_X86_64_PLT32.
Note, GNU as does not emit a relocation for `jmp global` (maybe its own
bug). Our new behavior is compatible except `jmp global`.
Reviewed By: peter.smith
Differential Revision: https://reviews.llvm.org/D72197
| -rw-r--r-- | lld/test/ELF/global-offset-table-position-aarch64.s | 2 | ||||
| -rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 22 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/thumb1-branch-reloc.s | 12 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/thumb2-beq-fixup.s | 1 | ||||
| -rw-r--r-- | llvm/test/MC/ELF/relax.s | 33 | ||||
| -rw-r--r-- | llvm/test/MC/ELF/target-in-same-section.s | 39 | ||||
| -rw-r--r-- | llvm/test/MC/X86/align-branch-64-2a.s | 2 | ||||
| -rw-r--r-- | llvm/test/MC/X86/align-branch-64-2b.s | 2 | ||||
| -rw-r--r-- | llvm/test/MC/X86/align-branch-64-2c.s | 2 |
9 files changed, 56 insertions, 59 deletions
diff --git a/lld/test/ELF/global-offset-table-position-aarch64.s b/lld/test/ELF/global-offset-table-position-aarch64.s index cfe3003babe..1a3e8062546 100644 --- a/lld/test/ELF/global-offset-table-position-aarch64.s +++ b/lld/test/ELF/global-offset-table-position-aarch64.s @@ -20,7 +20,7 @@ _start: .long _GLOBAL_OFFSET_TABLE_ - . // CHECK: Name: _GLOBAL_OFFSET_TABLE_ (11) -// CHECK-NEXT: Value: 0x30360 +// CHECK-NEXT: Value: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local (0x0) // CHECK-NEXT: Type: None (0x0) diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index f8e93889344..b421d0b2bf6 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -569,26 +569,6 @@ void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex, IsReserved); } -// True if the assembler knows nothing about the final value of the symbol. -// This doesn't cover the comdat issues, since in those cases the assembler -// can at least know that all symbols in the section will move together. -static bool isWeak(const MCSymbolELF &Sym) { - if (Sym.getType() == ELF::STT_GNU_IFUNC) - return true; - - switch (Sym.getBinding()) { - default: - llvm_unreachable("Unknown binding"); - case ELF::STB_LOCAL: - return false; - case ELF::STB_GLOBAL: - return false; - case ELF::STB_WEAK: - case ELF::STB_GNU_UNIQUE: - return true; - } -} - bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol, bool Used, bool Renamed) { if (Symbol.isVariable()) { @@ -1534,7 +1514,7 @@ bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl( const auto &SymA = cast<MCSymbolELF>(SA); if (IsPCRel) { assert(!InSet); - if (isWeak(SymA)) + if (SymA.getBinding() != ELF::STB_LOCAL) return false; } return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB, diff --git a/llvm/test/MC/ARM/thumb1-branch-reloc.s b/llvm/test/MC/ARM/thumb1-branch-reloc.s index c599389d1c2..22384bec027 100644 --- a/llvm/test/MC/ARM/thumb1-branch-reloc.s +++ b/llvm/test/MC/ARM/thumb1-branch-reloc.s @@ -18,4 +18,14 @@ @CHECK: Section {{.*}} .rel.text.cond { @CHECK: 0x0 R_ARM_THM_JUMP8 @CHECK: } -
\ No newline at end of file + + .section .text.insection +.globl global +local: +global: + b local + b global + +@CHECK: Section {{.*}} .rel.text.insection { +@CHECK-NEXT: 0x2 R_ARM_THM_JUMP11 global 0x0 +@CHECK-NEXT: } diff --git a/llvm/test/MC/ARM/thumb2-beq-fixup.s b/llvm/test/MC/ARM/thumb2-beq-fixup.s index e6d43e8fed9..36728081162 100644 --- a/llvm/test/MC/ARM/thumb2-beq-fixup.s +++ b/llvm/test/MC/ARM/thumb2-beq-fixup.s @@ -36,4 +36,5 @@ global_thumb_fn: @ CHECK: Section (3) .rel.text @ CHECK-NEXT: 0x0 R_ARM_THM_JUMP19 internal_arm_fn 0x0 @ CHECK-NEXT: 0x4 R_ARM_THM_JUMP19 global_arm_fn 0x0 +@ CHECK-NEXT: 0x8 R_ARM_THM_JUMP19 global_thumb_fn 0x0 @ CHECK-NEXT: } diff --git a/llvm/test/MC/ELF/relax.s b/llvm/test/MC/ELF/relax.s deleted file mode 100644 index 27de52963ba..00000000000 --- a/llvm/test/MC/ELF/relax.s +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -S --sd --symbols | FileCheck %s - -// Test that we do not relax these. - -bar: -.globl foo -foo: - .set zed,foo - - jmp bar - jmp foo - jmp zed - -// CHECK: Section { -// CHECK: Name: .text -// CHECK-NEXT: Type: SHT_PROGBITS -// CHECK-NEXT: Flags [ -// CHECK-NEXT: SHF_ALLOC -// CHECK-NEXT: SHF_EXECINSTR -// CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x40 -// CHECK-NEXT: Size: 6 -// CHECK-NEXT: Link: 0 -// CHECK-NEXT: Info: 0 -// CHECK-NEXT: AddressAlignment: 4 -// CHECK-NEXT: EntrySize: 0 -// CHECK-NEXT: SectionData ( -// CHECK-NEXT: 0000: EBFEEBFC EBFA -// CHECK-NEXT: ) -// CHECK-NEXT: } -// CHECK: Symbol { -// CHECK: Name: foo diff --git a/llvm/test/MC/ELF/target-in-same-section.s b/llvm/test/MC/ELF/target-in-same-section.s new file mode 100644 index 00000000000..dbdacaffdb7 --- /dev/null +++ b/llvm/test/MC/ELF/target-in-same-section.s @@ -0,0 +1,39 @@ +## For a target defined in the same section, create a relocation if the +## symbol is not local, otherwise resolve the fixup statically. +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t +# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s + +# RELOC: .rela.text { +# RELOC-NEXT: 0x5 R_X86_64_PLT32 global 0xFFFFFFFFFFFFFFFC +# RELOC-NEXT: 0xA R_X86_64_PLT32 weak 0xFFFFFFFFFFFFFFFC +# RELOC-NEXT: 0x19 R_X86_64_PLT32 global 0xFFFFFFFFFFFFFFFC +# RELOC-NEXT: 0x1E R_X86_64_PLT32 weak 0xFFFFFFFFFFFFFFFC +# RELOC-NEXT: } + +# CHECK: 0: jmp +# CHECK-NEXT: 2: jmp +# CHECK-NEXT: 4: jmp +# CHECK-NEXT: 9: jmp +# CHECK-NEXT: e: callq +# CHECK-NEXT: 13: callq +# CHECK-NEXT: 18: callq +# CHECK-NEXT: 1d: callq +# CHECK-NEXT: 22: retq + +.globl global +.weak weak +global: +weak: +local: +.set var,global + jmp var + jmp local + jmp global + jmp weak + + call var + call local + call global + call weak + ret diff --git a/llvm/test/MC/X86/align-branch-64-2a.s b/llvm/test/MC/X86/align-branch-64-2a.s index 61e9e1f899b..0652840cbc2 100644 --- a/llvm/test/MC/X86/align-branch-64-2a.s +++ b/llvm/test/MC/X86/align-branch-64-2a.s @@ -12,6 +12,6 @@ # CHECK-NEXT: 3e: ff d0 callq *%rax # CHECK-COUNT-3: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1 # CHECK-NEXT: 58: 55 pushq %rbp -# CHECK-NEXT: 59: e8 a2 ff ff ff callq {{.*}} +# CHECK-NEXT: 59: e8 00 00 00 00 callq {{.*}} # CHECK-COUNT-4: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1 # CHECK: 7e: ff 14 25 00 00 00 00 callq *0 diff --git a/llvm/test/MC/X86/align-branch-64-2b.s b/llvm/test/MC/X86/align-branch-64-2b.s index 1cb49f7d109..91494fa36ba 100644 --- a/llvm/test/MC/X86/align-branch-64-2b.s +++ b/llvm/test/MC/X86/align-branch-64-2b.s @@ -11,7 +11,7 @@ # CHECK-NEXT: 3c: ff d0 callq *%rax # CHECK-COUNT-3: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1 # CHECK: 56: 55 pushq %rbp -# CHECK-NEXT: 57: e8 a4 ff ff ff callq {{.*}} +# CHECK-NEXT: 57: e8 00 00 00 00 callq {{.*}} # CHECK-COUNT-4: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1 # CHECK-COUNT-4: : 90 nop # CHECK: 80: ff 14 25 00 00 00 00 callq *0 diff --git a/llvm/test/MC/X86/align-branch-64-2c.s b/llvm/test/MC/X86/align-branch-64-2c.s index bb750aa24a0..6754feb85f2 100644 --- a/llvm/test/MC/X86/align-branch-64-2c.s +++ b/llvm/test/MC/X86/align-branch-64-2c.s @@ -14,6 +14,6 @@ # CHECK-COUNT-3: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1 # CHECK: 5a: 55 pushq %rbp # CHECK-COUNT-5: : 90 nop -# CHECK: 60: e8 9b ff ff ff callq {{.*}} +# CHECK: 60: e8 00 00 00 00 callq {{.*}} # CHECK-COUNT-4: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1 # CHECK: 85: ff 14 25 00 00 00 00 callq *0 |

