forked from OSchip/llvm-project
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 llvm-svn: 336609
This commit is contained in:
parent
ec34220f5c
commit
3e730b8ae6
|
@ -1010,7 +1010,7 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
|
|||
}
|
||||
|
||||
// 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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -1579,6 +1579,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
|||
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())
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue