Index: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -1010,7 +1010,7 @@ } // 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(InX::Iplt, InX::IgotPlt, InX::RelaIplt, Target->IRelativeRel, Sym); Index: lld/trunk/ELF/SymbolTable.h =================================================================== --- lld/trunk/ELF/SymbolTable.h +++ lld/trunk/ELF/SymbolTable.h @@ -39,6 +39,7 @@ template void addCombinedLTOObject(); template void addSymbolWrap(StringRef Name); void applySymbolWrap(); + void applySymbolWrapReloc(); ArrayRef getSymbols() const { return SymVector; } Index: lld/trunk/ELF/SymbolTable.cpp =================================================================== --- lld/trunk/ELF/SymbolTable.cpp +++ lld/trunk/ELF/SymbolTable.cpp @@ -212,6 +212,17 @@ } } +// 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; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -1579,6 +1579,9 @@ if (!Config->Relocatable) forEachRelSec(scanRelocations); + // 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()) Index: lld/trunk/test/ELF/wrap-plt.s =================================================================== --- lld/trunk/test/ELF/wrap-plt.s +++ lld/trunk/test/ELF/wrap-plt.s @@ -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@plt + jmp __wrap_foo@plt + jmp _start@plt