[lld] r315097 - Refine our --wrap implementation.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 6 13:09:34 PDT 2017
Author: rafael
Date: Fri Oct 6 13:09:34 2017
New Revision: 315097
URL: http://llvm.org/viewvc/llvm-project?rev=315097&view=rev
Log:
Refine our --wrap implementation.
Before this patch we would copy foo into real_foo and wrap_foo into
foo. The net result is that __wrap_foo shows up twice in the symbol
table.
With this patch we:
* save a copy of __real_foo before copying foo.
* drop one of the __wrap_foo from the symbol table.
* if __real_foo was not undefined, add a *new* symbol with that content to
the symbol table.
The net result is that
Anything using foo now uses __wrap_foo
Anything using __real_foo now uses foo.
Anything using __wrap_foo still does.
And the symbol table has foo, __wrap_foo and __real_foo (if defined).
Which I think is the desired behavior.
Added:
lld/trunk/test/ELF/Inputs/wrap-no-real.s
lld/trunk/test/ELF/wrap-no-real.s
Modified:
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/ELF/SymbolTable.h
lld/trunk/test/ELF/lto/wrap-2.ll
lld/trunk/test/ELF/wrap.s
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=315097&r1=315096&r2=315097&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Fri Oct 6 13:09:34 2017
@@ -164,6 +164,8 @@ template <class ELFT> void SymbolTable::
defsym(Real, Sym);
defsym(Sym, Wrap);
+
+ WrapSymbols.push_back({Wrap, Real});
}
// Creates alias for symbol. Used to implement --defsym=ALIAS=SYM.
@@ -183,11 +185,43 @@ void SymbolTable::addSymbolAlias(StringR
// LTO (if LTO is running) not to include these symbols in IPO. Now that the
// symbols are finalized, we can perform the replacement.
void SymbolTable::applySymbolRenames() {
+ // This function rotates 3 symbols:
+ //
+ // __real_foo becomes foo
+ // foo becomes __wrap_foo
+ // __wrap_foo becomes __real_foo
+ //
+ // The last part is special in that we don't want to change what references to
+ // __wrap_foo point to, we just want have __real_foo in the symbol table.
+
+ // First make a copy of __real_foo
+ std::vector<Symbol> Origs;
+ for (const auto &P : WrapSymbols)
+ Origs.push_back(*P.second);
+
+ // Replace __real_foo with foo and foo with __wrap_foo
for (SymbolRenaming &S : Defsyms) {
S.Dst->body()->copyFrom(S.Src->body());
S.Dst->File = S.Src->File;
S.Dst->Binding = S.Binding;
}
+
+ // Hide one of the copies of __wrap_foo, create a new symbol and copy
+ // __real_foo into it.
+ for (unsigned I = 0, N = WrapSymbols.size(); I < N; ++I) {
+ // We now have two copies of __wrap_foo. Drop one.
+ Symbol *Wrap = WrapSymbols[I].first;
+ Wrap->IsUsedInRegularObj = false;
+
+ Symbol *Real = &Origs[I];
+ // If __real_foo was undefined, we don't want it in the symbol table.
+ if (Real->body()->isUndefined())
+ continue;
+
+ auto *NewSym = make<Symbol>();
+ memcpy(NewSym, Real, sizeof(Symbol));
+ SymVector.push_back(NewSym);
+ }
}
static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=315097&r1=315096&r2=315097&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Fri Oct 6 13:09:34 2017
@@ -144,6 +144,9 @@ private:
// For -defsym or -wrap.
std::vector<SymbolRenaming> Defsyms;
+ // For -wrap.
+ std::vector<std::pair<Symbol *, Symbol *>> WrapSymbols;
+
// For LTO.
std::unique_ptr<BitcodeCompiler> LTO;
};
Added: lld/trunk/test/ELF/Inputs/wrap-no-real.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/wrap-no-real.s?rev=315097&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/wrap-no-real.s (added)
+++ lld/trunk/test/ELF/Inputs/wrap-no-real.s Fri Oct 6 13:09:34 2017
@@ -0,0 +1,3 @@
+.globl foo, __wrap_foo
+foo = 0x11000
+__wrap_foo = 0x11010
Modified: lld/trunk/test/ELF/lto/wrap-2.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/wrap-2.ll?rev=315097&r1=315096&r2=315097&view=diff
==============================================================================
--- lld/trunk/test/ELF/lto/wrap-2.ll (original)
+++ lld/trunk/test/ELF/lto/wrap-2.ll Fri Oct 6 13:09:34 2017
@@ -28,11 +28,11 @@
; THIN-NEXT: jmp{{.*}}<bar>
; Check that bar and __wrap_bar retain their original binding.
-; BIND: Name: bar
+; BIND: Name: __wrap_bar
; BIND-NEXT: Value:
; BIND-NEXT: Size:
; BIND-NEXT: Binding: Local
-; BIND: Name: __wrap_bar
+; BIND: Name: bar
; BIND-NEXT: Value:
; BIND-NEXT: Size:
; BIND-NEXT: Binding: Local
Added: lld/trunk/test/ELF/wrap-no-real.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/wrap-no-real.s?rev=315097&view=auto
==============================================================================
--- lld/trunk/test/ELF/wrap-no-real.s (added)
+++ lld/trunk/test/ELF/wrap-no-real.s Fri Oct 6 13:09:34 2017
@@ -0,0 +1,26 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/wrap-no-real.s -o %t2.o
+
+// RUN: ld.lld -o %t %t1.o %t2.o -wrap foo
+// RUN: llvm-objdump -d -print-imm-hex %t | FileCheck %s
+
+// CHECK: _start:
+// CHECK-NEXT: movl $0x11010, %edx
+// CHECK-NEXT: movl $0x11010, %edx
+// CHECK-NEXT: movl $0x11000, %edx
+
+// RUN: llvm-readobj -t -s %t | FileCheck -check-prefix=SYM %s
+// SYM-NOT: Name: __real_foo
+// SYM: Name: foo
+// SYM-NEXT: Value: 0x11000
+// SYM-NOT: Name: __real_foo
+// SYM: Name: __wrap_foo
+// SYM-NEXT: Value: 0x11010
+// SYM-NOT: Name: __real_foo
+
+.global _start
+_start:
+ movl $foo, %edx
+ movl $__wrap_foo, %edx
+ movl $__real_foo, %edx
Modified: lld/trunk/test/ELF/wrap.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/wrap.s?rev=315097&r1=315096&r2=315097&view=diff
==============================================================================
--- lld/trunk/test/ELF/wrap.s (original)
+++ lld/trunk/test/ELF/wrap.s Fri Oct 6 13:09:34 2017
@@ -12,17 +12,13 @@
// CHECK-NEXT: movl $0x11010, %edx
// CHECK-NEXT: movl $0x11000, %edx
-// This shows an oddity of our implementation. The symbol foo gets
-// mapped to __wrap_foo, but stays in the symbol table. This results
-// in it showing up twice in the output.
-
// RUN: llvm-readobj -t -s %t3 | FileCheck -check-prefix=SYM %s
// SYM: Name: foo
// SYM-NEXT: Value: 0x11000
// SYM: Name: __wrap_foo
// SYM-NEXT: Value: 0x11010
-// SYM: Name: __wrap_foo
-// SYM-NEXT: Value: 0x11010
+// SYM: Name: __real_foo
+// SYM-NEXT: Value: 0x11020
.global _start
_start:
More information about the llvm-commits
mailing list