[lld] r336609 - Fix direct calls to __wrap_sym when it is relocated.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 9 15:03:06 PDT 2018


Author: ruiu
Date: Mon Jul  9 15:03:05 2018
New Revision: 336609

URL: http://llvm.org/viewvc/llvm-project?rev=336609&view=rev
Log:
Fix direct calls to __wrap_sym when it is relocated.

Patch by Matthew Koontz!

Before, direct calls to __wrap_sym would not map to valid PLT entries,
so they would crash at runtime. This change maps such calls to the same
PLT entry as calls to sym that are then wrapped.

Differential Revision: https://reviews.llvm.org/D48502

Added:
    lld/trunk/test/ELF/wrap-plt.s
Modified:
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=336609&r1=336608&r2=336609&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Mon Jul  9 15:03:05 2018
@@ -1010,7 +1010,7 @@ static void scanReloc(InputSectionBase &
   }
 
   // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
-  if (needsPlt(Expr) && !Sym.isInPlt()) {
+  if (needsPlt(Expr) && !Sym.isInPlt() && Sym.IsUsedInRegularObj) {
     if (Sym.isGnuIFunc() && !Sym.IsPreemptible)
       addPltEntry<ELFT>(InX::Iplt, InX::IgotPlt, InX::RelaIplt,
                         Target->IRelativeRel, Sym);

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=336609&r1=336608&r2=336609&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Mon Jul  9 15:03:05 2018
@@ -212,6 +212,17 @@ void SymbolTable::applySymbolWrap() {
   }
 }
 
+// Apply changes caused by relocations to wrapped symbols
+// This is needed for direct calls to __wrap_sym
+void SymbolTable::applySymbolWrapReloc() {
+  for (WrappedSymbol &W : WrappedSymbols) {
+    memcpy(W.Wrap, W.Sym, sizeof(SymbolUnion));
+
+    // Keep this so that this copy of the symbol remains dropped
+    W.Wrap->IsUsedInRegularObj = false;
+  }
+}
+
 static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
   if (VA == STV_DEFAULT)
     return VB;

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=336609&r1=336608&r2=336609&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Mon Jul  9 15:03:05 2018
@@ -39,6 +39,7 @@ public:
   template <class ELFT> void addCombinedLTOObject();
   template <class ELFT> void addSymbolWrap(StringRef Name);
   void applySymbolWrap();
+  void applySymbolWrapReloc();
 
   ArrayRef<Symbol *> getSymbols() const { return SymVector; }
 

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=336609&r1=336608&r2=336609&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Jul  9 15:03:05 2018
@@ -1579,6 +1579,9 @@ template <class ELFT> void Writer<ELFT>:
   if (!Config->Relocatable)
     forEachRelSec(scanRelocations<ELFT>);
 
+  // Apply changes caused by relocations to wrapped symbols
+  Symtab->applySymbolWrapReloc();
+
   if (InX::Plt && !InX::Plt->empty())
     InX::Plt->addSymbols();
   if (InX::Iplt && !InX::Iplt->empty())

Added: lld/trunk/test/ELF/wrap-plt.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/wrap-plt.s?rev=336609&view=auto
==============================================================================
--- lld/trunk/test/ELF/wrap-plt.s (added)
+++ lld/trunk/test/ELF/wrap-plt.s Mon Jul  9 15:03:05 2018
@@ -0,0 +1,45 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+
+// RUN: ld.lld -o %t2 %t -wrap foo -shared
+// RUN: llvm-readobj -s -r %t2 | FileCheck %s
+// RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s
+
+// CHECK:      Name: .plt
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x1020
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 48
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 16
+
+// CHECK:      Relocations [
+// CHECK-NEXT:   Section ({{.*}}) .rela.plt {
+// CHECK-NEXT:     0x2018 R_X86_64_JUMP_SLOT __wrap_foo 0x0
+// CHECK-NEXT:     0x2020 R_X86_64_JUMP_SLOT _start 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+
+// DISASM:      _start:
+// DISASM-NEXT: jmp	41
+// DISASM-NEXT: jmp	36
+// DISASM-NEXT: jmp	47
+
+.global foo
+foo:
+  nop
+
+.global __wrap_foo
+__wrap_foo:
+  nop
+
+.global _start
+_start:
+  jmp foo at plt
+  jmp __wrap_foo at plt
+  jmp _start at plt




More information about the llvm-commits mailing list