From 616cd991947a3aabc083384b1e7d86b88c3ab710 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 31 Oct 2017 16:10:24 +0000 Subject: [PATCH] [COFF] Merge Symbol and SymbolBody. llvm-svn: 317007 --- lld/COFF/Config.h | 5 +- lld/COFF/Driver.cpp | 14 +++--- lld/COFF/InputFiles.cpp | 20 ++++---- lld/COFF/InputFiles.h | 1 - lld/COFF/LTO.cpp | 9 ++-- lld/COFF/PDB.cpp | 4 +- lld/COFF/SymbolTable.cpp | 127 +++++++++++++++++++++-------------------------- lld/COFF/SymbolTable.h | 31 ++++++------ lld/COFF/Symbols.h | 69 ++++++++++--------------- lld/COFF/Writer.cpp | 16 +++--- 10 files changed, 131 insertions(+), 165 deletions(-) diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 0c8a9b9..4b935c0 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -27,7 +27,6 @@ using llvm::StringRef; class DefinedAbsolute; class DefinedRelative; class StringChunk; -struct Symbol; class SymbolBody; // Short aliases. @@ -111,8 +110,8 @@ struct Configuration { bool SaveTemps = false; // Used for SafeSEH. - Symbol *SEHTable = nullptr; - Symbol *SEHCount = nullptr; + SymbolBody *SEHTable = nullptr; + SymbolBody *SEHCount = nullptr; // Used for /opt:lldlto=N unsigned LTOOptLevel = 2; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index c3cb1d9..6d44498 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -378,7 +378,7 @@ StringRef LinkerDriver::findDefaultEntry() { }; for (auto E : Entries) { StringRef Entry = Symtab->findMangle(mangle(E[0])); - if (!Entry.empty() && !isa(Symtab->find(Entry)->body())) + if (!Entry.empty() && !isa(Symtab->find(Entry))) return mangle(E[1]); } return ""; @@ -1181,10 +1181,10 @@ void LinkerDriver::link(ArrayRef ArgsArr) { for (auto Pair : Config->AlternateNames) { StringRef From = Pair.first; StringRef To = Pair.second; - Symbol *Sym = Symtab->find(From); + SymbolBody *Sym = Symtab->find(From); if (!Sym) continue; - if (auto *U = dyn_cast(Sym->body())) + if (auto *U = dyn_cast(Sym)) if (!U->WeakAlias) U->WeakAlias = Symtab->addUndefined(To); } @@ -1237,8 +1237,8 @@ void LinkerDriver::link(ArrayRef ArgsArr) { Args.hasArg(OPT_export_all_symbols))) { AutoExporter Exporter; - Symtab->forEachSymbol([=](Symbol *S) { - auto *Def = dyn_cast(S->body()); + Symtab->forEachSymbol([=](SymbolBody *S) { + auto *Def = dyn_cast(S); if (!Exporter.shouldExport(Def)) return; Export E; @@ -1265,13 +1265,13 @@ void LinkerDriver::link(ArrayRef ArgsArr) { StringRef Name = Pair.first; uint32_t Alignment = Pair.second; - Symbol *Sym = Symtab->find(Name); + SymbolBody *Sym = Symtab->find(Name); if (!Sym) { warn("/aligncomm symbol " + Name + " not found"); continue; } - auto *DC = dyn_cast(Sym->body()); + auto *DC = dyn_cast(Sym); if (!DC) { warn("/aligncomm symbol " + Name + " of wrong kind"); continue; diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index 534194d..fbf8fbe 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -54,7 +54,7 @@ static void checkAndSetWeakAlias(SymbolTable *Symtab, InputFile *F, SymbolBody *Source, SymbolBody *Target) { if (auto *U = dyn_cast(Source)) { if (U->WeakAlias && U->WeakAlias != Target) - Symtab->reportDuplicate(Source->symbol(), F); + Symtab->reportDuplicate(Source, F); U->WeakAlias = Target; } } @@ -215,7 +215,7 @@ void ObjFile::initializeSymbols() { SymbolBody *ObjFile::createUndefined(COFFSymbolRef Sym) { StringRef Name; COFFObj->getSymbolName(Sym, Name); - return Symtab->addUndefined(Name, this, Sym.isWeakExternal())->body(); + return Symtab->addUndefined(Name, this, Sym.isWeakExternal()); } SymbolBody *ObjFile::createDefined(COFFSymbolRef Sym, const void *AuxP, @@ -225,9 +225,9 @@ SymbolBody *ObjFile::createDefined(COFFSymbolRef Sym, const void *AuxP, auto *C = make(Sym); Chunks.push_back(C); COFFObj->getSymbolName(Sym, Name); - Symbol *S = + SymbolBody *S = Symtab->addCommon(this, Name, Sym.getValue(), Sym.getGeneric(), C); - return S->body(); + return S; } if (Sym.isAbsolute()) { COFFObj->getSymbolName(Sym, Name); @@ -241,7 +241,7 @@ SymbolBody *ObjFile::createDefined(COFFSymbolRef Sym, const void *AuxP, return nullptr; } if (Sym.isExternal()) - return Symtab->addAbsolute(Name, Sym)->body(); + return Symtab->addAbsolute(Name, Sym); else return make(Name, Sym); } @@ -280,9 +280,9 @@ SymbolBody *ObjFile::createDefined(COFFSymbolRef Sym, const void *AuxP, DefinedRegular *B; if (Sym.isExternal()) { COFFObj->getSymbolName(Sym, Name); - Symbol *S = + SymbolBody *S = Symtab->addRegular(this, Name, SC->isCOMDAT(), Sym.getGeneric(), SC); - B = cast(S->body()); + B = cast(S); } else B = make(this, /*Name*/ "", SC->isCOMDAT(), /*IsExternal*/ false, Sym.getGeneric(), SC); @@ -368,7 +368,7 @@ void BitcodeFile::parse() { MB.getBuffer(), Saver.save(ParentName + MB.getBufferIdentifier())))); for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) { StringRef SymName = Saver.save(ObjSym.getName()); - Symbol *Sym; + SymbolBody *Sym; if (ObjSym.isUndefined()) { Sym = Symtab->addUndefined(SymName, this, false); } else if (ObjSym.isCommon()) { @@ -378,12 +378,12 @@ void BitcodeFile::parse() { Sym = Symtab->addUndefined(SymName, this, true); std::string Fallback = ObjSym.getCOFFWeakExternalFallback(); SymbolBody *Alias = Symtab->addUndefined(Saver.save(Fallback)); - checkAndSetWeakAlias(Symtab, this, Sym->body(), Alias); + checkAndSetWeakAlias(Symtab, this, Sym, Alias); } else { bool IsCOMDAT = ObjSym.getComdatIndex() != -1; Sym = Symtab->addRegular(this, SymName, IsCOMDAT); } - SymbolBodies.push_back(Sym->body()); + SymbolBodies.push_back(Sym); } Directives = Obj->getCOFFLinkerOpts(); } diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h index aa1a0e1..0a38a08 100644 --- a/lld/COFF/InputFiles.h +++ b/lld/COFF/InputFiles.h @@ -47,7 +47,6 @@ class DefinedImportData; class DefinedImportThunk; class Lazy; class SectionChunk; -struct Symbol; class SymbolBody; class Undefined; diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp index b84599b..d600426 100644 --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -88,9 +88,7 @@ BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {} BitcodeCompiler::~BitcodeCompiler() = default; -static void undefine(Symbol *S) { - replaceBody(S, S->body()->getName()); -} +static void undefine(SymbolBody *S) { replaceBody(S, S->getName()); } void BitcodeCompiler::add(BitcodeFile &F) { lto::InputFile &Obj = *F.Obj; @@ -100,8 +98,7 @@ void BitcodeCompiler::add(BitcodeFile &F) { // Provide a resolution to the LTO API for each symbol. for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) { - SymbolBody *B = SymBodies[SymNum]; - Symbol *Sym = B->symbol(); + SymbolBody *Sym = SymBodies[SymNum]; lto::SymbolResolution &R = Resols[SymNum]; ++SymNum; @@ -110,7 +107,7 @@ void BitcodeCompiler::add(BitcodeFile &F) { // flags an undefined in IR with a definition in ASM as prevailing. // Once IRObjectFile is fixed to report only one symbol this hack can // be removed. - R.Prevailing = !ObjSym.isUndefined() && B->getFile() == &F; + R.Prevailing = !ObjSym.isUndefined() && Sym->getFile() == &F; R.VisibleToRegularObj = Sym->IsUsedInRegularObj; if (R.Prevailing) undefine(Sym); diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index 7998709..a31a2bb 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -727,9 +727,9 @@ void PDBLinker::addObjectsToPDB() { // Compute the public and global symbols. auto &GsiBuilder = Builder.getGsiBuilder(); std::vector Publics; - Symtab->forEachSymbol([&Publics](Symbol *S) { + Symtab->forEachSymbol([&Publics](SymbolBody *S) { // Only emit defined, live symbols that have a chunk. - auto *Def = dyn_cast(S->body()); + auto *Def = dyn_cast(S); if (Def && Def->isLive() && Def->getChunk()) Publics.push_back(createPublic(Def)); }); diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 04dd654..ba39184 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -33,17 +33,17 @@ enum SymbolPreference { /// Checks if an existing symbol S should be kept or replaced by a new symbol. /// Returns SP_EXISTING when S should be kept, SP_NEW when the new symbol /// should be kept, and SP_CONFLICT if no valid resolution exists. -static SymbolPreference compareDefined(Symbol *S, bool WasInserted, +static SymbolPreference compareDefined(SymbolBody *S, bool WasInserted, bool NewIsCOMDAT) { // If the symbol wasn't previously known, the new symbol wins by default. - if (WasInserted || !isa(S->body())) + if (WasInserted || !isa(S)) return SP_NEW; // If the existing symbol is a DefinedRegular, both it and the new symbol // must be comdats. In that case, we have no reason to prefer one symbol // over the other, and we keep the existing one. If one of the symbols // is not a comdat, we report a conflict. - if (auto *R = dyn_cast(S->body())) { + if (auto *R = dyn_cast(S)) { if (NewIsCOMDAT && R->isCOMDAT()) return SP_EXISTING; else @@ -95,8 +95,8 @@ void SymbolTable::reportRemainingUndefines() { SmallPtrSet Undefs; for (auto &I : Symtab) { - Symbol *Sym = I.second; - auto *Undef = dyn_cast(Sym->body()); + SymbolBody *Sym = I.second; + auto *Undef = dyn_cast(Sym); if (!Undef) continue; if (!Sym->IsUsedInRegularObj) @@ -106,32 +106,18 @@ void SymbolTable::reportRemainingUndefines() { // A weak alias may have been resolved, so check for that. if (Defined *D = Undef->getWeakAlias()) { - // We resolve weak aliases by replacing the alias's SymbolBody with the - // target's SymbolBody. This causes all SymbolBody pointers referring to - // the old symbol to instead refer to the new symbol. However, we can't - // just blindly copy sizeof(Symbol::Body) bytes from D to Sym->Body - // because D may be an internal symbol, and internal symbols are stored as - // "unparented" SymbolBodies. For that reason we need to check which type - // of symbol we are dealing with and copy the correct number of bytes. - if (isa(D)) - memcpy(Sym->Body.buffer, D, sizeof(DefinedRegular)); - else if (isa(D)) - memcpy(Sym->Body.buffer, D, sizeof(DefinedAbsolute)); - else - // No other internal symbols are possible. - Sym->Body = D->symbol()->Body; + memcpy(Sym, D, sizeof(SymbolUnion)); continue; } // If we can resolve a symbol by removing __imp_ prefix, do that. // This odd rule is for compatibility with MSVC linker. if (Name.startswith("__imp_")) { - Symbol *Imp = find(Name.substr(strlen("__imp_"))); - if (Imp && isa(Imp->body())) { - auto *D = cast(Imp->body()); + SymbolBody *Imp = find(Name.substr(strlen("__imp_"))); + if (Imp && isa(Imp)) { + auto *D = cast(Imp); replaceBody(Sym, Name, D); - LocalImportChunks.push_back( - cast(Sym->body())->getChunk()); + LocalImportChunks.push_back(cast(Sym)->getChunk()); continue; } } @@ -140,7 +126,7 @@ void SymbolTable::reportRemainingUndefines() { // They are replaced with dummy defined symbols. if (Config->Force) replaceBody(Sym, Name, 0); - Undefs.insert(Sym->body()); + Undefs.insert(Sym); } if (Undefs.empty()) @@ -156,28 +142,28 @@ void SymbolTable::reportRemainingUndefines() { errorOrWarn(toString(File) + ": undefined symbol: " + Sym->getName()); } -std::pair SymbolTable::insert(StringRef Name) { - Symbol *&Sym = Symtab[CachedHashStringRef(Name)]; +std::pair SymbolTable::insert(StringRef Name) { + SymbolBody *&Sym = Symtab[CachedHashStringRef(Name)]; if (Sym) return {Sym, false}; - Sym = make(); + Sym = (SymbolBody *)make(); Sym->IsUsedInRegularObj = false; Sym->PendingArchiveLoad = false; return {Sym, true}; } -Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F, - bool IsWeakAlias) { - Symbol *S; +SymbolBody *SymbolTable::addUndefined(StringRef Name, InputFile *F, + bool IsWeakAlias) { + SymbolBody *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name); if (!F || !isa(F)) S->IsUsedInRegularObj = true; - if (WasInserted || (isa(S->body()) && IsWeakAlias)) { + if (WasInserted || (isa(S) && IsWeakAlias)) { replaceBody(S, Name); return S; } - if (auto *L = dyn_cast(S->body())) { + if (auto *L = dyn_cast(S)) { if (!S->PendingArchiveLoad) { S->PendingArchiveLoad = true; L->File->addMember(&L->Sym); @@ -188,66 +174,66 @@ Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F, void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) { StringRef Name = Sym.getName(); - Symbol *S; + SymbolBody *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name); if (WasInserted) { replaceBody(S, F, Sym); return; } - auto *U = dyn_cast(S->body()); + auto *U = dyn_cast(S); if (!U || U->WeakAlias || S->PendingArchiveLoad) return; S->PendingArchiveLoad = true; F->addMember(&Sym); } -void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) { - error("duplicate symbol: " + toString(*Existing->body()) + " in " + - toString(Existing->body()->getFile()) + " and in " + +void SymbolTable::reportDuplicate(SymbolBody *Existing, InputFile *NewFile) { + error("duplicate symbol: " + toString(*Existing) + " in " + + toString(Existing->getFile()) + " and in " + (NewFile ? toString(NewFile) : "(internal)")); } -Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) { - Symbol *S; +SymbolBody *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) { + SymbolBody *S; bool WasInserted; std::tie(S, WasInserted) = insert(N); S->IsUsedInRegularObj = true; - if (WasInserted || isa(S->body()) || isa(S->body())) + if (WasInserted || isa(S) || isa(S)) replaceBody(S, N, Sym); - else if (!isa(S->body())) + else if (!isa(S)) reportDuplicate(S, nullptr); return S; } -Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) { - Symbol *S; +SymbolBody *SymbolTable::addAbsolute(StringRef N, uint64_t VA) { + SymbolBody *S; bool WasInserted; std::tie(S, WasInserted) = insert(N); S->IsUsedInRegularObj = true; - if (WasInserted || isa(S->body()) || isa(S->body())) + if (WasInserted || isa(S) || isa(S)) replaceBody(S, N, VA); - else if (!isa(S->body())) + else if (!isa(S)) reportDuplicate(S, nullptr); return S; } -Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) { - Symbol *S; +SymbolBody *SymbolTable::addSynthetic(StringRef N, Chunk *C) { + SymbolBody *S; bool WasInserted; std::tie(S, WasInserted) = insert(N); S->IsUsedInRegularObj = true; - if (WasInserted || isa(S->body()) || isa(S->body())) + if (WasInserted || isa(S) || isa(S)) replaceBody(S, N, C); - else if (!isa(S->body())) + else if (!isa(S)) reportDuplicate(S, nullptr); return S; } -Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT, - const coff_symbol_generic *Sym, - SectionChunk *C) { - Symbol *S; +SymbolBody *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT, + const coff_symbol_generic *Sym, + SectionChunk *C) { + SymbolBody *S; bool WasInserted; std::tie(S, WasInserted) = insert(N); if (!isa(F)) @@ -267,29 +253,30 @@ Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT, return S; } -Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size, - const coff_symbol_generic *Sym, CommonChunk *C) { - Symbol *S; +SymbolBody *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size, + const coff_symbol_generic *Sym, + CommonChunk *C) { + SymbolBody *S; bool WasInserted; std::tie(S, WasInserted) = insert(N); if (!isa(F)) S->IsUsedInRegularObj = true; - if (WasInserted || !isa(S->body())) + if (WasInserted || !isa(S)) replaceBody(S, F, N, Size, Sym, C); - else if (auto *DC = dyn_cast(S->body())) + else if (auto *DC = dyn_cast(S)) if (Size > DC->getSize()) replaceBody(S, F, N, Size, Sym, C); return S; } DefinedImportData *SymbolTable::addImportData(StringRef N, ImportFile *F) { - Symbol *S; + SymbolBody *S; bool WasInserted; std::tie(S, WasInserted) = insert(N); S->IsUsedInRegularObj = true; - if (WasInserted || isa(S->body()) || isa(S->body())) { + if (WasInserted || isa(S) || isa(S)) { replaceBody(S, N, F); - return cast(S->body()); + return cast(S); } reportDuplicate(S, F); @@ -299,13 +286,13 @@ DefinedImportData *SymbolTable::addImportData(StringRef N, ImportFile *F) { DefinedImportThunk *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID, uint16_t Machine) { - Symbol *S; + SymbolBody *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name); S->IsUsedInRegularObj = true; - if (WasInserted || isa(S->body()) || isa(S->body())) { + if (WasInserted || isa(S) || isa(S)) { replaceBody(S, Name, ID, Machine); - return cast(S->body()); + return cast(S); } reportDuplicate(S, ID->File); @@ -321,14 +308,14 @@ std::vector SymbolTable::getChunks() { return Res; } -Symbol *SymbolTable::find(StringRef Name) { +SymbolBody *SymbolTable::find(StringRef Name) { auto It = Symtab.find(CachedHashStringRef(Name)); if (It == Symtab.end()) return nullptr; return It->second; } -Symbol *SymbolTable::findUnderscore(StringRef Name) { +SymbolBody *SymbolTable::findUnderscore(StringRef Name) { if (Config->Machine == I386) return find(("_" + Name).str()); return find(Name); @@ -344,8 +331,8 @@ StringRef SymbolTable::findByPrefix(StringRef Prefix) { } StringRef SymbolTable::findMangle(StringRef Name) { - if (Symbol *Sym = find(Name)) - if (!isa(Sym->body())) + if (SymbolBody *Sym = find(Name)) + if (!isa(Sym)) return Name; if (Config->Machine != I386) return findByPrefix(("?" + Name + "@@Y").str()); @@ -379,7 +366,7 @@ void SymbolTable::mangleMaybe(SymbolBody *B) { } SymbolBody *SymbolTable::addUndefined(StringRef Name) { - return addUndefined(Name, nullptr, false)->body(); + return addUndefined(Name, nullptr, false); } std::vector SymbolTable::compileBitcodeFiles() { diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index c825826..57b1089 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -32,7 +32,6 @@ class DefinedRelative; class Lazy; class SectionChunk; class SymbolBody; -struct Symbol; // SymbolTable is a bucket of all known symbols, including defined, // undefined, or lazy symbols (the last one is symbols in archive @@ -59,8 +58,8 @@ public: std::vector getChunks(); // Returns a symbol for a given name. Returns a nullptr if not found. - Symbol *find(StringRef Name); - Symbol *findUnderscore(StringRef Name); + SymbolBody *find(StringRef Name); + SymbolBody *findUnderscore(StringRef Name); // Occasionally we have to resolve an undefined symbol to its // mangled symbol. This function tries to find a mangled name @@ -78,23 +77,23 @@ public: // Creates an Undefined symbol for a given name. SymbolBody *addUndefined(StringRef Name); - Symbol *addSynthetic(StringRef N, Chunk *C); - Symbol *addAbsolute(StringRef N, uint64_t VA); + SymbolBody *addSynthetic(StringRef N, Chunk *C); + SymbolBody *addAbsolute(StringRef N, uint64_t VA); - Symbol *addUndefined(StringRef Name, InputFile *F, bool IsWeakAlias); + SymbolBody *addUndefined(StringRef Name, InputFile *F, bool IsWeakAlias); void addLazy(ArchiveFile *F, const Archive::Symbol Sym); - Symbol *addAbsolute(StringRef N, COFFSymbolRef S); - Symbol *addRegular(InputFile *F, StringRef N, bool IsCOMDAT, - const llvm::object::coff_symbol_generic *S = nullptr, - SectionChunk *C = nullptr); - Symbol *addCommon(InputFile *F, StringRef N, uint64_t Size, - const llvm::object::coff_symbol_generic *S = nullptr, - CommonChunk *C = nullptr); + SymbolBody *addAbsolute(StringRef N, COFFSymbolRef S); + SymbolBody *addRegular(InputFile *F, StringRef N, bool IsCOMDAT, + const llvm::object::coff_symbol_generic *S = nullptr, + SectionChunk *C = nullptr); + SymbolBody *addCommon(InputFile *F, StringRef N, uint64_t Size, + const llvm::object::coff_symbol_generic *S = nullptr, + CommonChunk *C = nullptr); DefinedImportData *addImportData(StringRef N, ImportFile *F); DefinedImportThunk *addImportThunk(StringRef Name, DefinedImportData *S, uint16_t Machine); - void reportDuplicate(Symbol *Existing, InputFile *NewFile); + void reportDuplicate(SymbolBody *Existing, InputFile *NewFile); // A list of chunks which to be added to .rdata. std::vector LocalImportChunks; @@ -106,10 +105,10 @@ public: } private: - std::pair insert(StringRef Name); + std::pair insert(StringRef Name); StringRef findByPrefix(StringRef Prefix); - llvm::DenseMap Symtab; + llvm::DenseMap Symtab; std::unique_ptr LTO; }; diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h index 4042b4e..944a2df 100644 --- a/lld/COFF/Symbols.h +++ b/lld/COFF/Symbols.h @@ -32,7 +32,6 @@ using llvm::object::coff_symbol_generic; class ArchiveFile; class InputFile; class ObjFile; -struct Symbol; class SymbolTable; // The base class for real symbol classes. @@ -74,11 +73,6 @@ public: // after calling markLive. bool isLive() const; - Symbol *symbol(); - const Symbol *symbol() const { - return const_cast(this)->symbol(); - } - protected: friend SymbolTable; explicit SymbolBody(Kind K, StringRef N = "") @@ -96,6 +90,14 @@ public: // symbols from being written to the symbol table more than once. unsigned WrittenToSymtab : 1; + // True if this symbol was referenced by a regular (non-bitcode) object. + unsigned IsUsedInRegularObj : 1; + + // True if we've seen both a lazy and an undefined symbol with this symbol + // name, which means that we have enqueued an archive member load and should + // not load any more archive members to resolve the same symbol. + unsigned PendingArchiveLoad : 1; + protected: StringRef Name; }; @@ -397,47 +399,30 @@ inline Chunk *Defined::getChunk() { llvm_unreachable("unknown symbol kind"); } -// A real symbol object, SymbolBody, is usually stored within a Symbol. There's -// always one Symbol for each symbol name. The resolver updates the SymbolBody -// stored in the Body field of this object as it resolves symbols. Symbol also -// holds computed properties of symbol names. -struct Symbol { - // True if this symbol was referenced by a regular (non-bitcode) object. - unsigned IsUsedInRegularObj : 1; - - // True if we've seen both a lazy and an undefined symbol with this symbol - // name, which means that we have enqueued an archive member load and should - // not load any more archive members to resolve the same symbol. - unsigned PendingArchiveLoad : 1; - - // This field is used to store the Symbol's SymbolBody. This instantiation of - // AlignedCharArrayUnion gives us a struct with a char array field that is - // large and aligned enough to store any derived class of SymbolBody. - llvm::AlignedCharArrayUnion< - DefinedRegular, DefinedCommon, DefinedAbsolute, DefinedSynthetic, Lazy, - Undefined, DefinedImportData, DefinedImportThunk, DefinedLocalImport> - Body; - - SymbolBody *body() { - return reinterpret_cast(Body.buffer); - } - const SymbolBody *body() const { return const_cast(this)->body(); } +// A buffer class that is large enough to hold any SymbolBody-derived +// object. We allocate memory using this class and instantiate a symbol +// using the placement new. +union SymbolUnion { + alignas(DefinedCOFF) char A[sizeof(DefinedCOFF)]; + alignas(DefinedRegular) char B[sizeof(DefinedRegular)]; + alignas(DefinedCommon) char C[sizeof(DefinedCommon)]; + alignas(DefinedAbsolute) char D[sizeof(DefinedAbsolute)]; + alignas(DefinedSynthetic) char E[sizeof(DefinedSynthetic)]; + alignas(Lazy) char F[sizeof(Lazy)]; + alignas(Undefined) char G[sizeof(Undefined)]; + alignas(DefinedImportData) char H[sizeof(DefinedImportData)]; + alignas(DefinedImportThunk) char I[sizeof(DefinedImportThunk)]; + alignas(DefinedLocalImport) char J[sizeof(DefinedLocalImport)]; }; template -void replaceBody(Symbol *S, ArgT &&... Arg) { - static_assert(sizeof(T) <= sizeof(S->Body), "Body too small"); - static_assert(alignof(T) <= alignof(decltype(S->Body)), - "Body not aligned enough"); +void replaceBody(SymbolBody *S, ArgT &&... Arg) { + static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small"); + static_assert(alignof(T) <= alignof(SymbolUnion), + "SymbolUnion not aligned enough"); assert(static_cast(static_cast(nullptr)) == nullptr && "Not a SymbolBody"); - new (S->Body.buffer) T(std::forward(Arg)...); -} - -inline Symbol *SymbolBody::symbol() { - assert(isExternal()); - return reinterpret_cast(reinterpret_cast(this) - - offsetof(Symbol, Body)); + new (S) T(std::forward(Arg)...); } } // namespace coff diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 0ab2263..a4b73da 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -731,8 +731,8 @@ template void Writer::writeHeader() { Dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = Sec->getRVA(); Dir[BASE_RELOCATION_TABLE].Size = Sec->getVirtualSize(); } - if (Symbol *Sym = Symtab->findUnderscore("_tls_used")) { - if (Defined *B = dyn_cast(Sym->body())) { + if (SymbolBody *Sym = Symtab->findUnderscore("_tls_used")) { + if (Defined *B = dyn_cast(Sym)) { Dir[TLS_TABLE].RelativeVirtualAddress = B->getRVA(); Dir[TLS_TABLE].Size = Config->is64() ? sizeof(object::coff_tls_directory64) @@ -743,8 +743,8 @@ template void Writer::writeHeader() { Dir[DEBUG_DIRECTORY].RelativeVirtualAddress = DebugDirectory->getRVA(); Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize(); } - if (Symbol *Sym = Symtab->findUnderscore("_load_config_used")) { - if (auto *B = dyn_cast(Sym->body())) { + if (SymbolBody *Sym = Symtab->findUnderscore("_load_config_used")) { + if (auto *B = dyn_cast(Sym)) { SectionChunk *SC = B->getChunk(); assert(B->getRVA() >= SC->getRVA()); uint64_t OffsetInChunk = B->getRVA() - SC->getRVA(); @@ -804,10 +804,10 @@ void Writer::fixSafeSEHSymbols() { // Replace the absolute table symbol with a synthetic symbol pointing to the // SEHTable chunk so that we can emit base relocations for it and resolve // section relative relocations. - Symbol *T = Symtab->find("___safe_se_handler_table"); - Symbol *C = Symtab->find("___safe_se_handler_count"); - replaceBody(T, T->body()->getName(), SEHTable); - cast(C->body())->setVA(SEHTable->getSize() / 4); + SymbolBody *T = Symtab->find("___safe_se_handler_table"); + SymbolBody *C = Symtab->find("___safe_se_handler_count"); + replaceBody(T, T->getName(), SEHTable); + cast(C)->setVA(SEHTable->getSize() / 4); } // Handles /section options to allow users to overwrite -- 2.7.4