[llvm] 2bfee35 - [MC][ELF] Emit a relocation if target is defined in the same section and is non-local

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 12 13:46:31 PST 2020


Author: Fangrui Song
Date: 2020-01-12T13:46:24-08:00
New Revision: 2bfee35cb860859b436de0b780fbd00d68e198a4

URL: https://github.com/llvm/llvm-project/commit/2bfee35cb860859b436de0b780fbd00d68e198a4
DIFF: https://github.com/llvm/llvm-project/commit/2bfee35cb860859b436de0b780fbd00d68e198a4.diff

LOG: [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 at 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

Added: 
    llvm/test/MC/ELF/target-in-same-section.s

Modified: 
    lld/test/ELF/global-offset-table-position-aarch64.s
    llvm/lib/MC/ELFObjectWriter.cpp
    llvm/test/MC/ARM/thumb1-branch-reloc.s
    llvm/test/MC/ARM/thumb2-beq-fixup.s
    llvm/test/MC/X86/align-branch-64-2a.s
    llvm/test/MC/X86/align-branch-64-2b.s
    llvm/test/MC/X86/align-branch-64-2c.s

Removed: 
    llvm/test/MC/ELF/relax.s


################################################################################
diff  --git a/lld/test/ELF/global-offset-table-position-aarch64.s b/lld/test/ELF/global-offset-table-position-aarch64.s
index cfe3003babe3..1a3e8062546f 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 f8e938893444..b421d0b2bf68 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 c599389d1c2d..22384bec0274 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
+
+ at CHECK:      Section {{.*}} .rel.text.insection {
+ at CHECK-NEXT:   0x2 R_ARM_THM_JUMP11 global 0x0
+ at CHECK-NEXT: }

diff  --git a/llvm/test/MC/ARM/thumb2-beq-fixup.s b/llvm/test/MC/ARM/thumb2-beq-fixup.s
index e6d43e8fed96..36728081162f 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 27de52963bad..000000000000
--- 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 000000000000..dbdacaffdb7f
--- /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 61e9e1f899b9..0652840cbc29 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 1cb49f7d1090..91494fa36ba3 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 bb750aa24a07..6754feb85f2f 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


        


More information about the llvm-commits mailing list