[PATCH] D88625: [MC] Redirect fixup symbol to the aliasee (if exists)

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 30 17:24:59 PDT 2020


MaskRay created this revision.
MaskRay added reviewers: echristo, jyknight.
Herald added subscribers: llvm-commits, hiraditya, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.
MaskRay requested review of this revision.

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4acf8c78e659833be8be047ba2f8561386a11d4b
(1994) introduced this behavior:
if a fixup symbol is equated to an expression with an undefined symbol, convert
the fixup to be against the target symbol. glibc relies on this behavior.

  asm("memcpy = __GI_memcpy"); // from sysdeps/generic/symbol-hacks.h
  
  ...
    // call memcpy at PLT
    // The relocation references __GI_memcpy in GNU as, but memcpy in MC (without the patch)
    memcpy (...);

This patch adds the similar behavior to MC. glibc also redirects
`memcpy_plus_1 = __GI_memcpy+1`, but this patch does not implement it.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88625

Files:
  llvm/lib/MC/MCAssembler.cpp
  llvm/test/MC/ELF/relocation-alias.s


Index: llvm/test/MC/ELF/relocation-alias.s
===================================================================
--- /dev/null
+++ llvm/test/MC/ELF/relocation-alias.s
@@ -0,0 +1,38 @@
+# RUN: llvm-mc -filetype=obj -triple x86_64 %s -o %t
+# RUN: llvm-objdump -dr %t | FileCheck %s
+# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYM
+
+## If a fixup symbol is equated to an undefined symbol, convert the fixup
+## to be against the target symbol.
+# CHECK:      callq {{.*}}
+# CHECK-NEXT:   R_X86_64_PLT32  __GI_memcpy-0x4
+# CHECK:      movabsq $0, %rax
+# CHECK-NEXT:   R_X86_64_64  __GI_memcpy+0x2
+memcpy = __GI_memcpy
+call memcpy at PLT
+movabsq $memcpy+2, %rax
+
+## NOTE: GNU as redirects memcpy_plus_1.
+# CHECK:      callq {{.*}}
+# CHECK-NEXT:   R_X86_64_PLT32  memcpy_plus_1
+memcpy_plus_1 = __GI_memcpy+1
+call memcpy_plus_1 at PLT
+
+# CHECK:      movabsq $0, %rbx
+# CHECK-NEXT:   R_X86_64_64  data_alias
+.globl data_alias
+.set data_alias, data
+movabsq $data_alias, %rbx
+
+.data
+.byte 0
+.globl data
+data:
+
+## Redirected symbols do not have a symbol table entry.
+# SYM:      NOTYPE LOCAL  DEFAULT UND
+# SYM-NEXT: NOTYPE GLOBAL DEFAULT UND __GI_memcpy
+# SYM-NEXT: NOTYPE GLOBAL DEFAULT   4 data
+# SYM-NEXT: NOTYPE GLOBAL DEFAULT   4 data_alias
+# SYM-NEXT: NOTYPE GLOBAL DEFAULT UND memcpy_plus_1
+# SYM-NOT:  {{.}}
Index: llvm/lib/MC/MCAssembler.cpp
===================================================================
--- llvm/lib/MC/MCAssembler.cpp
+++ llvm/lib/MC/MCAssembler.cpp
@@ -216,6 +216,21 @@
       return true;
     }
   }
+  if (const MCSymbolRefExpr *RefA = Target.getSymA()) {
+    // If SymA is equated to an expression with an undefined symbol, GNU as
+    // converts the fixup to be against the target symbol. We only support a
+    // simple form `alias = aliasee` (MCSymbolRefExpr).
+    auto &SymA = RefA->getSymbol();
+    if (SymA.isVariable()) {
+      if (auto *SRE = dyn_cast<MCSymbolRefExpr>(SymA.getVariableValue()))
+        if (SRE->getSymbol().isUndefined() &&
+            SRE->getKind() != MCSymbolRefExpr::VK_WEAKREF) {
+          Target = MCValue::get(
+              MCSymbolRefExpr::create(&SRE->getSymbol(), RefA->getKind(), Ctx),
+              Target.getSymB(), Target.getConstant(), Target.getRefKind());
+        }
+    }
+  }
 
   assert(getBackendPtr() && "Expected assembler backend");
   bool IsTarget = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags &


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D88625.295440.patch
Type: text/x-patch
Size: 2439 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201001/37bc950d/attachment.bin>


More information about the llvm-commits mailing list