Rewrite addSymbolWrap and applySymbolWrap. NFCI.
authorRui Ueyama <ruiu@google.com>
Sat, 4 Nov 2017 23:09:43 +0000 (23:09 +0000)
committerRui Ueyama <ruiu@google.com>
Sat, 4 Nov 2017 23:09:43 +0000 (23:09 +0000)
r317396 changed the way how we handle the -defsym option. The option is
now handled using the infrastructure for the linker script.

We used to handle both -defsym and -wrap using the same set of functions
in the symbol table. Now, we don't need to do that.

This patch rewrites the functions so that they become more straightforward.
The new functions directly handle -wrap rather than abstract it.

llvm-svn: 317426

lld/ELF/Driver.cpp
lld/ELF/SymbolTable.cpp
lld/ELF/SymbolTable.h

index 62f52d9..30b9947 100644 (file)
@@ -1092,8 +1092,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
   if (errorCount())
     return;
 
-  // Apply symbol renames for -wrap and -defsym
-  Symtab->applySymbolRenames();
+  // Apply symbol renames for -wrap.
+  Symtab->applySymbolWrap();
 
   // Now that we have a complete list of input files.
   // Beyond this point, no new files are added.
index 8a4b148..047af33 100644 (file)
@@ -155,54 +155,51 @@ template <class ELFT> void SymbolTable::addSymbolWrap(StringRef Name) {
     return;
   Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name));
   Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name));
+  WrappedSymbols.push_back({Sym, Real, Wrap, Sym->Binding, Real->Binding});
 
-  defsym(Real, Sym);
-  defsym(Sym, Wrap);
+  // We want to tell LTO not to inline symbols to be overwritten
+  // because LTO doesn't know the final symbol contents after renaming.
+  Real->CanInline = false;
+  Sym->CanInline = false;
 
-  WrapSymbols.push_back({Wrap, Real});
+  // Tell LTO not to eliminate these symbols.
+  Sym->IsUsedInRegularObj = true;
+  Wrap->IsUsedInRegularObj = true;
 }
 
 // Apply symbol renames created by -wrap. The renames are created
 // before LTO in addSymbolWrap() to have a chance to inform 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() {
+void SymbolTable::applySymbolWrap() {
   // This function rotates 3 symbols:
   //
-  // __real_foo becomes foo
-  // foo        becomes __wrap_foo
-  // __wrap_foo becomes __real_foo
+  // __real_sym becomes sym
+  // sym        becomes __wrap_sym
+  // __wrap_sym becomes __real_sym
   //
   // 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<SymbolUnion> Origs;
-  for (const auto &P : WrapSymbols)
-    Origs.emplace_back(*(SymbolUnion *)P.second);
-
-  // Replace __real_foo with foo and foo with __wrap_foo
-  for (SymbolRenaming &S : Defsyms) {
-    S.Dst->copyFrom(S.Src);
-    S.Dst->File = S.Src->File;
-    S.Dst->Binding = S.Binding;
-  }
+  // __wrap_sym point to, we just want have __real_sym in the symbol table.
+
+  for (WrappedSymbol &W : WrappedSymbols) {
+    // First, make a copy of __real_sym.
+    Symbol *Real = nullptr;
+    if (W.Real->isInCurrentOutput()) {
+      Real = (Symbol *)make<SymbolUnion>();
+      memcpy(Real, W.Real, sizeof(SymbolUnion));
+    }
 
-  // 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;
+    // Replace __real_sym with sym and sym with __wrap_sym.
+    W.Real->copyFrom(W.Sym);
+    W.Real->Binding = W.RealBinding;
+    W.Sym->copyFrom(W.Wrap);
+    W.Sym->Binding = W.SymBinding;
 
-    auto *Real = (Symbol *)&Origs[I];
-    // If __real_foo was undefined, we don't want it in the symbol table.
-    if (!Real->isInCurrentOutput())
-      continue;
-
-    auto *NewSym = (Symbol *)make<SymbolUnion>();
-    memcpy(NewSym, Real, sizeof(SymbolUnion));
-    SymVector.push_back(NewSym);
+    if (Real) {
+      // We now have two copies of __wrap_sym. Drop one.
+      W.Wrap->IsUsedInRegularObj = false;
+      SymVector.push_back(Real);
+    }
   }
 }
 
@@ -529,17 +526,6 @@ Symbol *SymbolTable::find(StringRef Name) {
   return SymVector[V.Idx];
 }
 
-void SymbolTable::defsym(Symbol *Dst, Symbol *Src) {
-  // We want to tell LTO not to inline Dst symbol because LTO doesn't
-  // know the final symbol contents after renaming.
-  Dst->CanInline = false;
-
-  // Tell LTO not to eliminate this symbol.
-  Src->IsUsedInRegularObj = true;
-
-  Defsyms.push_back({Dst, Src, Dst->Binding});
-}
-
 template <class ELFT>
 Symbol *SymbolTable::addLazyArchive(StringRef Name, ArchiveFile *F,
                                     const object::Archive::Symbol Sym) {
index 45ae59e..789f023 100644 (file)
@@ -36,7 +36,7 @@ public:
   template <class ELFT> void addFile(InputFile *File);
   template <class ELFT> void addCombinedLTOObject();
   template <class ELFT> void addSymbolWrap(StringRef Name);
-  void applySymbolRenames();
+  void applySymbolWrap();
 
   ArrayRef<Symbol *> getSymbols() const { return SymVector; }
 
@@ -129,17 +129,16 @@ private:
   // directive in version scripts.
   llvm::Optional<llvm::StringMap<std::vector<Symbol *>>> DemangledSyms;
 
-  struct SymbolRenaming {
-    Symbol *Dst;
-    Symbol *Src;
-    uint8_t Binding;
+  struct WrappedSymbol {
+    Symbol *Sym;
+    Symbol *Real;
+    Symbol *Wrap;
+    uint8_t SymBinding;
+    uint8_t RealBinding;
   };
 
-  // For -defsym or -wrap.
-  std::vector<SymbolRenaming> Defsyms;
-
   // For -wrap.
-  std::vector<std::pair<Symbol *, Symbol *>> WrapSymbols;
+  std::vector<WrappedSymbol> WrappedSymbols;
 
   // For LTO.
   std::unique_ptr<BitcodeCompiler> LTO;