From dc0b0b0df311007b1ac2dcfb9bec7df938e8561f Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Sat, 4 Nov 2017 23:09:43 +0000 Subject: [PATCH] Rewrite addSymbolWrap and applySymbolWrap. NFCI. 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 | 4 +-- lld/ELF/SymbolTable.cpp | 76 ++++++++++++++++++++----------------------------- lld/ELF/SymbolTable.h | 17 ++++++----- 3 files changed, 41 insertions(+), 56 deletions(-) diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 62f52d9..30b9947 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1092,8 +1092,8 @@ template 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. diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 8a4b148..047af33 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -155,54 +155,51 @@ template void SymbolTable::addSymbolWrap(StringRef Name) { return; Symbol *Real = addUndefined(Saver.save("__real_" + Name)); Symbol *Wrap = addUndefined(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 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(); + 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(); - 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 Symbol *SymbolTable::addLazyArchive(StringRef Name, ArchiveFile *F, const object::Archive::Symbol Sym) { diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index 45ae59e..789f023 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -36,7 +36,7 @@ public: template void addFile(InputFile *File); template void addCombinedLTOObject(); template void addSymbolWrap(StringRef Name); - void applySymbolRenames(); + void applySymbolWrap(); ArrayRef getSymbols() const { return SymVector; } @@ -129,17 +129,16 @@ private: // directive in version scripts. llvm::Optional>> 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 Defsyms; - // For -wrap. - std::vector> WrapSymbols; + std::vector WrappedSymbols; // For LTO. std::unique_ptr LTO; -- 2.7.4