diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h index dc6de568c022..e5f5289ea984 100644 --- a/lld/COFF/Chunks.h +++ b/lld/COFF/Chunks.h @@ -183,6 +183,10 @@ public: // and this chunk is considrered as dead. SectionChunk *Ptr; + // The CRC of the contents as described in the COFF spec 4.5.5. + // Auxiliary Format 5: Section Definitions. Used for ICF. + uint32_t Checksum = 0; + private: ArrayRef getContents() const; diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp index 4ec8f68fcf7a..1c23722d9bc7 100644 --- a/lld/COFF/ICF.cpp +++ b/lld/COFF/ICF.cpp @@ -44,7 +44,7 @@ uint64_t SectionChunk::getHash() const { NumRelocs, uint32_t(Header->SizeOfRawData), std::distance(Relocs.end(), Relocs.begin()), - hash_combine_range(A.data(), A.data() + A.size())); + Checksum); } // Returns true if this and a given chunk are identical COMDAT sections. @@ -58,6 +58,8 @@ bool SectionChunk::equals(const SectionChunk *X) const { return false; if (NumRelocs != X->NumRelocs) return false; + if (Checksum != X->Checksum) + return false; // Compare data if (getContents() != X->getContents()) diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index a8a35a5cfde3..a8537ec39650 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -225,13 +225,14 @@ Defined *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP, if (!SC) return nullptr; - // Handle associative sections + // Handle section definitions if (IsFirst && AuxP) { auto *Aux = reinterpret_cast(AuxP); if (Aux->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) if (auto *ParentSC = cast_or_null( SparseChunks[Aux->getNumber(Sym.isBigObj())])) ParentSC->addAssociative(SC); + SC->Checksum = Aux->CheckSum; } auto *B = new (Alloc) DefinedRegular(this, Sym, SC);