forked from OSchip/llvm-project
ELF: Implement --wrap.
In this patch, all symbols are resolved normally and then wrap options are applied. Renaming is implemented by mutating `Body` pointers of Symbols. (As a result, Symtab.find(SymbolName)->getName() may return a string that's different from SymbolName, but that is by design. I designed the symbol and the symbol table to allow this kind of operations.) http://reviews.llvm.org/D15896 llvm-svn: 257075
This commit is contained in:
parent
82fc962c20
commit
deb154001d
|
@ -310,6 +310,9 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
|||
for (StringRef S : Config->Undefined)
|
||||
Symtab.addUndefinedOpt(S);
|
||||
|
||||
for (auto *Arg : Args.filtered(OPT_wrap))
|
||||
Symtab.wrap(Arg->getValue());
|
||||
|
||||
if (Config->OutputFile.empty())
|
||||
Config->OutputFile = "a.out";
|
||||
|
||||
|
|
|
@ -109,6 +109,9 @@ def verbose : Flag<["--"], "verbose">;
|
|||
def whole_archive : Flag<["--", "-"], "whole-archive">,
|
||||
HelpText<"Force load of all members in a static library">;
|
||||
|
||||
def wrap : Separate<["--", "-"], "wrap">, MetaVarName<"<symbol>">,
|
||||
HelpText<"Use wrapper functions for symbol">;
|
||||
|
||||
def z : JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">,
|
||||
HelpText<"Linker option extensions">;
|
||||
|
||||
|
@ -136,6 +139,7 @@ def alias_soname_soname : Separate<["-"], "soname">, Alias<soname>;
|
|||
def alias_script_T : Separate<["-"], "T">, Alias<script>;
|
||||
def alias_strip_all: Flag<["-"], "s">, Alias<strip_all>;
|
||||
def alias_undefined_u : Separate<["-"], "u">, Alias<undefined>;
|
||||
def alias_wrap_wrap : Joined<["--", "-"], "wrap=">, Alias<wrap>;
|
||||
|
||||
// Our symbol resolution algorithm handles symbols in archive files differently
|
||||
// than traditional linkers, so we don't need --start-group and --end-group.
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "Config.h"
|
||||
#include "Error.h"
|
||||
#include "Symbols.h"
|
||||
#include "llvm/Support/StringSaver.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::object;
|
||||
|
@ -124,6 +125,19 @@ SymbolBody *SymbolTable<ELFT>::addIgnored(StringRef Name) {
|
|||
return Sym;
|
||||
}
|
||||
|
||||
// Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.
|
||||
// Used to implement --wrap.
|
||||
template <class ELFT> void SymbolTable<ELFT>::wrap(StringRef Name) {
|
||||
if (Symtab.count(Name) == 0)
|
||||
return;
|
||||
StringSaver Saver(Alloc);
|
||||
Symbol *Sym = addUndefined(Name)->getSymbol();
|
||||
Symbol *Real = addUndefined(Saver.save("__real_" + Name))->getSymbol();
|
||||
Symbol *Wrap = addUndefined(Saver.save("__wrap_" + Name))->getSymbol();
|
||||
Real->Body = Sym->Body;
|
||||
Sym->Body = Wrap->Body;
|
||||
}
|
||||
|
||||
// Returns a file from which symbol B was created.
|
||||
// If B does not belong to any file, returns a nullptr.
|
||||
template <class ELFT>
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
SymbolBody *addIgnored(StringRef Name);
|
||||
void scanShlibUndefined();
|
||||
SymbolBody *find(StringRef Name);
|
||||
void wrap(StringRef Name);
|
||||
ELFFileBase<ELFT> *findFile(SymbolBody *B);
|
||||
|
||||
private:
|
||||
|
|
|
@ -105,6 +105,7 @@ public:
|
|||
// you can access P->Backref->Body to get the resolver's result.
|
||||
void setBackref(Symbol *P) { Backref = P; }
|
||||
SymbolBody *repl() { return Backref ? Backref->Body : this; }
|
||||
Symbol *getSymbol() { return Backref; }
|
||||
|
||||
// Decides which symbol should "win" in the symbol table, this or
|
||||
// the Other. Returns 1 if this wins, -1 if the Other wins, or 0 if
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
.globl foo, __wrap_foo, __real_foo
|
||||
foo = 0x11000
|
||||
__wrap_foo = 0x11010
|
||||
__real_foo = 0x11020
|
|
@ -0,0 +1,19 @@
|
|||
// REQUIRES: x86
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/wrap.s -o %t2
|
||||
|
||||
// RUN: ld.lld -o %t3 %t %t2 -wrap foo -wrap nosuchsym
|
||||
// RUN: llvm-objdump -d -print-imm-hex %t3 | FileCheck %s
|
||||
// RUN: ld.lld -o %t3 %t %t2 --wrap foo -wrap=nosuchsym
|
||||
// RUN: llvm-objdump -d -print-imm-hex %t3 | FileCheck %s
|
||||
|
||||
// CHECK: _start:
|
||||
// CHECK-NEXT: movl $0x11010, %edx
|
||||
// CHECK-NEXT: movl $0x11010, %edx
|
||||
// CHECK-NEXT: movl $0x11000, %edx
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
movl $foo, %edx
|
||||
movl $__wrap_foo, %edx
|
||||
movl $__real_foo, %edx
|
Loading…
Reference in New Issue