[lld] r257075 - ELF: Implement --wrap.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 7 09:20:08 PST 2016


Author: ruiu
Date: Thu Jan  7 11:20:07 2016
New Revision: 257075

URL: http://llvm.org/viewvc/llvm-project?rev=257075&view=rev
Log:
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

Added:
    lld/trunk/test/ELF/Inputs/wrap.s
    lld/trunk/test/ELF/wrap.s
Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Options.td
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/Symbols.h

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=257075&r1=257074&r2=257075&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Thu Jan  7 11:20:07 2016
@@ -310,6 +310,9 @@ template <class ELFT> void LinkerDriver:
   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";
 

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=257075&r1=257074&r2=257075&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Thu Jan  7 11:20:07 2016
@@ -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<["-"]
 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.

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=257075&r1=257074&r2=257075&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Thu Jan  7 11:20:07 2016
@@ -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>::addIgnore
   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>

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=257075&r1=257074&r2=257075&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Thu Jan  7 11:20:07 2016
@@ -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:

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=257075&r1=257074&r2=257075&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Thu Jan  7 11:20:07 2016
@@ -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

Added: lld/trunk/test/ELF/Inputs/wrap.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/wrap.s?rev=257075&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/wrap.s (added)
+++ lld/trunk/test/ELF/Inputs/wrap.s Thu Jan  7 11:20:07 2016
@@ -0,0 +1,4 @@
+.globl foo, __wrap_foo, __real_foo
+foo = 0x11000
+__wrap_foo = 0x11010
+__real_foo = 0x11020

Added: lld/trunk/test/ELF/wrap.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/wrap.s?rev=257075&view=auto
==============================================================================
--- lld/trunk/test/ELF/wrap.s (added)
+++ lld/trunk/test/ELF/wrap.s Thu Jan  7 11:20:07 2016
@@ -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




More information about the llvm-commits mailing list