diff options
| -rw-r--r-- | lld/COFF/Chunks.cpp | 24 | ||||
| -rw-r--r-- | lld/COFF/Chunks.h | 19 | ||||
| -rw-r--r-- | lld/COFF/InputFiles.cpp | 6 | ||||
| -rw-r--r-- | lld/COFF/Symbols.cpp | 28 | ||||
| -rw-r--r-- | lld/COFF/Symbols.h | 39 | ||||
| -rw-r--r-- | lld/COFF/Writer.cpp | 9 |
6 files changed, 39 insertions, 86 deletions
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp index 1369bdf465b..c5cf80ec775 100644 --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -28,7 +28,7 @@ namespace lld { namespace coff { SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H) - : Chunk(SectionKind), File(F), Ptr(this), Header(H), + : Chunk(SectionKind), Ptr(this), File(F), Header(H), Relocs(File->getCOFFObj()->getRelocations(Header)), NumRelocs(std::distance(Relocs.begin(), Relocs.end())) { // Initialize SectionName. @@ -86,11 +86,8 @@ void SectionChunk::mark() { // Mark all symbols listed in the relocation table for this section. for (const coff_relocation &Rel : Relocs) { SymbolBody *B = File->getSymbolBody(Rel.SymbolTableIndex); - if (auto *D = dyn_cast<DefinedRegular>(B)) { + if (auto *D = dyn_cast<DefinedRegular>(B)) D->markLive(); - } else if (auto *D = dyn_cast<DefinedCOMDAT>(B)) { - D->markLive(); - } } // Mark associative sections if any. @@ -184,10 +181,10 @@ bool SectionChunk::equals(const SectionChunk *X) const { return false; SymbolBody *B1 = File->getSymbolBody(R1.SymbolTableIndex); SymbolBody *B2 = X->File->getSymbolBody(R2.SymbolTableIndex); - if (auto *C1 = dyn_cast<DefinedCOMDAT>(B1)) - if (auto *C2 = dyn_cast<DefinedCOMDAT>(B2)) - if (C1->getChunk() == C2->getChunk()) - return true; + auto *D1 = dyn_cast<DefinedRegular>(B1); + auto *D2 = dyn_cast<DefinedRegular>(B2); + if (D1 && D2 && D1->getChunk() == D2->getChunk()) + return true; return B1 == B2; }; return std::equal(Relocs.begin(), Relocs.end(), X->Relocs.begin(), Eq); @@ -199,15 +196,8 @@ ArrayRef<uint8_t> SectionChunk::getContents() const { return A; } -// Returns a pointer to this chunk or its replacement. -SectionChunk *SectionChunk::repl() { - while (Ptr != Ptr->Ptr) - Ptr = Ptr->Ptr; - return Ptr; -} - void SectionChunk::replaceWith(SectionChunk *Other) { - Ptr = Other; + Ptr = Other->Ptr; Live = false; } diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h index 58be91b96a1..d44c0255083 100644 --- a/lld/COFF/Chunks.h +++ b/lld/COFF/Chunks.h @@ -28,7 +28,7 @@ using llvm::object::coff_section; using llvm::sys::fs::file_magic; class Defined; -class DefinedCOMDAT; +class DefinedRegular; class DefinedImportData; class ObjectFile; class OutputSection; @@ -125,7 +125,7 @@ public: void addAssociative(SectionChunk *Child); StringRef getDebugName() override; - void setSymbol(DefinedCOMDAT *S) { if (!Sym) Sym = S; } + void setSymbol(DefinedRegular *S) { if (!Sym) Sym = S; } // Used by the garbage collector. bool isRoot() { return Root; } @@ -133,23 +133,22 @@ public: void markLive() { if (!Live) mark(); } // Used for ICF (Identical COMDAT Folding) - SectionChunk *repl(); void replaceWith(SectionChunk *Other); uint64_t getHash() const; bool equals(const SectionChunk *Other) const; -private: - ArrayRef<uint8_t> getContents() const; - - // A file this chunk was created from. - ObjectFile *File; - // A pointer pointing to a replacement for this chunk. // Initially it points to "this" object. If this chunk is merged // with other chunk by ICF, it points to another chunk, // and this chunk is considrered as dead. SectionChunk *Ptr; +private: + ArrayRef<uint8_t> getContents() const; + + // A file this chunk was created from. + ObjectFile *File; + const coff_section *Header; StringRef SectionName; std::vector<Chunk *> AssocChildren; @@ -163,7 +162,7 @@ private: // Chunks are basically unnamed chunks of bytes. // Symbols are associated for debugging and logging purposs only. - DefinedCOMDAT *Sym = nullptr; + DefinedRegular *Sym = nullptr; }; // A chunk for common symbols. Common chunks don't have actual data. diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index 9a15827eaf7..d11c265104a 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -215,10 +215,8 @@ SymbolBody *ObjectFile::createSymbolBody(COFFSymbolRef Sym, const void *AuxP, } Chunk *C = SparseChunks[Sym.getSectionNumber()]; if (auto *SC = cast_or_null<SectionChunk>(C)) { - if (!SC->isCOMDAT()) - return new (Alloc) DefinedRegular(COFFObj.get(), Sym, SC); - auto *B = new (Alloc) DefinedCOMDAT(COFFObj.get(), Sym, SC); - if (Sym.getValue() == 0 && !AuxP) + auto *B = new (Alloc) DefinedRegular(COFFObj.get(), Sym, SC); + if (SC->isCOMDAT() && Sym.getValue() == 0 && !AuxP) SC->setSymbol(B); return B; } diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp index 02cf7322084..cbdc418b010 100644 --- a/lld/COFF/Symbols.cpp +++ b/lld/COFF/Symbols.cpp @@ -26,16 +26,11 @@ namespace coff { int DefinedRegular::compare(SymbolBody *Other) { if (Other->kind() < kind()) return -Other->compare(this); - if (isa<DefinedRegular>(Other)) - return 0; - return 1; -} - -int DefinedCOMDAT::compare(SymbolBody *Other) { - if (Other->kind() < kind()) - return -Other->compare(this); - if (isa<DefinedRegular>(Other)) + if (auto *D = dyn_cast<DefinedRegular>(Other)) { + if (isCOMDAT() && D->isCOMDAT()) + return 1; return 0; + } return 1; } @@ -67,9 +62,12 @@ int DefinedBitcode::compare(SymbolBody *Other) { // replicate the rest of the symbol resolution logic here; symbol // resolution will be done accurately after lowering bitcode symbols // to regular symbols in addCombinedLTOObject(). - if (isa<DefinedRegular>(Other) && Replaceable) - return -1; - if (isa<DefinedCommon>(Other) || isa<DefinedCOMDAT>(Other)) + if (auto *D = dyn_cast<DefinedRegular>(Other)) { + if (Replaceable || D->isCOMDAT()) + return -1; + return 0; + } + if (isa<DefinedCommon>(Other)) return -1; return 0; } @@ -117,12 +115,6 @@ StringRef DefinedRegular::getName() { return Name; } -StringRef DefinedCOMDAT::getName() { - if (Name.empty()) - COFFFile->getSymbolName(Sym, Name); - return Name; -} - StringRef DefinedCommon::getName() { if (Name.empty()) COFFFile->getSymbolName(Sym, Name); diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h index 7cbff414cbb..a93e3fbedb2 100644 --- a/lld/COFF/Symbols.h +++ b/lld/COFF/Symbols.h @@ -51,7 +51,6 @@ public: DefinedImportThunkKind, DefinedLocalImportKind, DefinedCommonKind, - DefinedCOMDATKind, DefinedRegularKind, DefinedLast, LazyKind, @@ -115,51 +114,31 @@ public: class DefinedRegular : public Defined { public: DefinedRegular(COFFObjectFile *F, COFFSymbolRef S, SectionChunk *C) - : Defined(DefinedRegularKind), COFFFile(F), Sym(S), Data(C) {} + : Defined(DefinedRegularKind), COFFFile(F), Sym(S), Data(&C->Ptr), + IsCOMDAT(C->isCOMDAT()) {} static bool classof(const SymbolBody *S) { return S->kind() == DefinedRegularKind; } - StringRef getName() override; - uint64_t getRVA() override { return Data->getRVA() + Sym.getValue(); } - bool isExternal() override { return Sym.isExternal(); } - uint64_t getFileOff() override { return Data->getFileOff() + Sym.getValue(); } - int compare(SymbolBody *Other) override; - void markLive() { Data->markLive(); } - -private: - StringRef Name; - COFFObjectFile *COFFFile; - COFFSymbolRef Sym; - SectionChunk *Data; -}; - -class DefinedCOMDAT : public Defined { -public: - DefinedCOMDAT(COFFObjectFile *F, COFFSymbolRef S, SectionChunk *C) - : Defined(DefinedCOMDATKind), COFFFile(F), Sym(S), Data(C) {} - - static bool classof(const SymbolBody *S) { - return S->kind() == DefinedCOMDATKind; - } - uint64_t getFileOff() override { - return Data->repl()->getFileOff() + Sym.getValue(); + return (*Data)->getFileOff() + Sym.getValue(); } StringRef getName() override; - uint64_t getRVA() override { return Data->repl()->getRVA() + Sym.getValue(); } + uint64_t getRVA() override { return (*Data)->getRVA() + Sym.getValue(); } bool isExternal() override { return Sym.isExternal(); } int compare(SymbolBody *Other) override; - void markLive() { Data->repl()->markLive(); } - Chunk *getChunk() { return Data->repl(); } + bool isCOMDAT() { return IsCOMDAT; } + void markLive() { (*Data)->markLive(); } + Chunk *getChunk() { return *Data; } private: StringRef Name; COFFObjectFile *COFFFile; COFFSymbolRef Sym; - SectionChunk *Data; + SectionChunk **Data; + bool IsCOMDAT; }; class DefinedCommon : public Defined { diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 5901fe64c3e..fb8005b2560 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -111,14 +111,9 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) { void Writer::markLive() { if (!Config->DoGC) return; - for (StringRef Name : Config->GCRoots) { - SymbolBody *B = Symtab->find(Name); - if (auto *D = dyn_cast<DefinedRegular>(B)) { + for (StringRef Name : Config->GCRoots) + if (auto *D = dyn_cast<DefinedRegular>(Symtab->find(Name))) D->markLive(); - } else if (auto *D = dyn_cast<DefinedCOMDAT>(B)) { - D->markLive(); - } - } for (Chunk *C : Symtab->getChunks()) if (auto *SC = dyn_cast<SectionChunk>(C)) if (SC->isRoot()) |

