Skip to content

Commit 2bfee35

Browse files
committed
[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
1 parent 241f330 commit 2bfee35

File tree

9 files changed

+56
-59
lines changed

9 files changed

+56
-59
lines changed

lld/test/ELF/global-offset-table-position-aarch64.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ _start:
2020
.long _GLOBAL_OFFSET_TABLE_ - .
2121

2222
// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (11)
23-
// CHECK-NEXT: Value: 0x30360
23+
// CHECK-NEXT: Value:
2424
// CHECK-NEXT: Size: 0
2525
// CHECK-NEXT: Binding: Local (0x0)
2626
// CHECK-NEXT: Type: None (0x0)

llvm/lib/MC/ELFObjectWriter.cpp

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -569,26 +569,6 @@ void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
569569
IsReserved);
570570
}
571571

572-
// True if the assembler knows nothing about the final value of the symbol.
573-
// This doesn't cover the comdat issues, since in those cases the assembler
574-
// can at least know that all symbols in the section will move together.
575-
static bool isWeak(const MCSymbolELF &Sym) {
576-
if (Sym.getType() == ELF::STT_GNU_IFUNC)
577-
return true;
578-
579-
switch (Sym.getBinding()) {
580-
default:
581-
llvm_unreachable("Unknown binding");
582-
case ELF::STB_LOCAL:
583-
return false;
584-
case ELF::STB_GLOBAL:
585-
return false;
586-
case ELF::STB_WEAK:
587-
case ELF::STB_GNU_UNIQUE:
588-
return true;
589-
}
590-
}
591-
592572
bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
593573
bool Used, bool Renamed) {
594574
if (Symbol.isVariable()) {
@@ -1534,7 +1514,7 @@ bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
15341514
const auto &SymA = cast<MCSymbolELF>(SA);
15351515
if (IsPCRel) {
15361516
assert(!InSet);
1537-
if (isWeak(SymA))
1517+
if (SymA.getBinding() != ELF::STB_LOCAL)
15381518
return false;
15391519
}
15401520
return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,

llvm/test/MC/ARM/thumb1-branch-reloc.s

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,14 @@
1818
@CHECK: Section {{.*}} .rel.text.cond {
1919
@CHECK: 0x0 R_ARM_THM_JUMP8
2020
@CHECK: }
21-
21+
22+
.section .text.insection
23+
.globl global
24+
local:
25+
global:
26+
b local
27+
b global
28+
29+
@CHECK: Section {{.*}} .rel.text.insection {
30+
@CHECK-NEXT: 0x2 R_ARM_THM_JUMP11 global 0x0
31+
@CHECK-NEXT: }

llvm/test/MC/ARM/thumb2-beq-fixup.s

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@ global_thumb_fn:
3636
@ CHECK: Section (3) .rel.text
3737
@ CHECK-NEXT: 0x0 R_ARM_THM_JUMP19 internal_arm_fn 0x0
3838
@ CHECK-NEXT: 0x4 R_ARM_THM_JUMP19 global_arm_fn 0x0
39+
@ CHECK-NEXT: 0x8 R_ARM_THM_JUMP19 global_thumb_fn 0x0
3940
@ CHECK-NEXT: }

llvm/test/MC/ELF/relax.s

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
## For a target defined in the same section, create a relocation if the
2+
## symbol is not local, otherwise resolve the fixup statically.
3+
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t
4+
# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
5+
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
6+
7+
# RELOC: .rela.text {
8+
# RELOC-NEXT: 0x5 R_X86_64_PLT32 global 0xFFFFFFFFFFFFFFFC
9+
# RELOC-NEXT: 0xA R_X86_64_PLT32 weak 0xFFFFFFFFFFFFFFFC
10+
# RELOC-NEXT: 0x19 R_X86_64_PLT32 global 0xFFFFFFFFFFFFFFFC
11+
# RELOC-NEXT: 0x1E R_X86_64_PLT32 weak 0xFFFFFFFFFFFFFFFC
12+
# RELOC-NEXT: }
13+
14+
# CHECK: 0: jmp
15+
# CHECK-NEXT: 2: jmp
16+
# CHECK-NEXT: 4: jmp
17+
# CHECK-NEXT: 9: jmp
18+
# CHECK-NEXT: e: callq
19+
# CHECK-NEXT: 13: callq
20+
# CHECK-NEXT: 18: callq
21+
# CHECK-NEXT: 1d: callq
22+
# CHECK-NEXT: 22: retq
23+
24+
.globl global
25+
.weak weak
26+
global:
27+
weak:
28+
local:
29+
.set var,global
30+
jmp var
31+
jmp local
32+
jmp global
33+
jmp weak
34+
35+
call var
36+
call local
37+
call global
38+
call weak
39+
ret

llvm/test/MC/X86/align-branch-64-2a.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212
# CHECK-NEXT: 3e: ff d0 callq *%rax
1313
# CHECK-COUNT-3: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1
1414
# CHECK-NEXT: 58: 55 pushq %rbp
15-
# CHECK-NEXT: 59: e8 a2 ff ff ff callq {{.*}}
15+
# CHECK-NEXT: 59: e8 00 00 00 00 callq {{.*}}
1616
# CHECK-COUNT-4: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1
1717
# CHECK: 7e: ff 14 25 00 00 00 00 callq *0

llvm/test/MC/X86/align-branch-64-2b.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# CHECK-NEXT: 3c: ff d0 callq *%rax
1212
# CHECK-COUNT-3: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1
1313
# CHECK: 56: 55 pushq %rbp
14-
# CHECK-NEXT: 57: e8 a4 ff ff ff callq {{.*}}
14+
# CHECK-NEXT: 57: e8 00 00 00 00 callq {{.*}}
1515
# CHECK-COUNT-4: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1
1616
# CHECK-COUNT-4: : 90 nop
1717
# CHECK: 80: ff 14 25 00 00 00 00 callq *0

llvm/test/MC/X86/align-branch-64-2c.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
# CHECK-COUNT-3: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1
1515
# CHECK: 5a: 55 pushq %rbp
1616
# CHECK-COUNT-5: : 90 nop
17-
# CHECK: 60: e8 9b ff ff ff callq {{.*}}
17+
# CHECK: 60: e8 00 00 00 00 callq {{.*}}
1818
# CHECK-COUNT-4: : 64 89 04 25 01 00 00 00 movl %eax, %fs:1
1919
# CHECK: 85: ff 14 25 00 00 00 00 callq *0

0 commit comments

Comments
 (0)