Author: hans Date: Tue Aug 7 00:46:29 2018 New Revision: 339108 URL: http://llvm.org/viewvc/llvm-project?rev=339108&view=rev Log: Merging r339058: ------------------------------------------------------------------------ r339058 | mstorsjo | 2018-08-06 23:26:09 +0200 (Mon, 06 Aug 2018) | 16 lines
[COFF] Treat .xdata/.pdata$<sym> as implicitly associative to <sym> for MinGW MinGW configurations don't use associative comdats, as GNU ld doesn't support that. Instead they produce normal comdats named .text$sym, .xdata$sym and .pdata$sym. GNU ld doesn't discard any comdats starting with .xdata or .pdata, even if --gc-sections is used (while it does discard other unreferenced comdats), regardless of what symbol name is used after the $ separator. For LLD, treat any such comdat as implicitly associative to the base symbol. This requires maintaining a map from symbol name to section number, but that is only maintained when the MinGW flag has been enabled. Differential Revision: https://reviews.llvm.org/D49700 ------------------------------------------------------------------------ Added: lld/branches/release_70/test/COFF/Inputs/associative-comdat-mingw-2.s - copied unchanged from r339058, lld/trunk/test/COFF/Inputs/associative-comdat-mingw-2.s lld/branches/release_70/test/COFF/associative-comdat-mingw.s - copied unchanged from r339058, lld/trunk/test/COFF/associative-comdat-mingw.s Modified: lld/branches/release_70/ (props changed) lld/branches/release_70/COFF/InputFiles.cpp lld/branches/release_70/COFF/InputFiles.h Propchange: lld/branches/release_70/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Tue Aug 7 00:46:29 2018 @@ -1 +1 @@ -/lld/trunk:338679,338684,338697,338699 +/lld/trunk:338679,338684,338697,338699,339058 Modified: lld/branches/release_70/COFF/InputFiles.cpp URL: http://llvm.org/viewvc/llvm-project/lld/branches/release_70/COFF/InputFiles.cpp?rev=339108&r1=339107&r2=339108&view=diff ============================================================================== --- lld/branches/release_70/COFF/InputFiles.cpp (original) +++ lld/branches/release_70/COFF/InputFiles.cpp Tue Aug 7 00:46:29 2018 @@ -205,7 +205,13 @@ SectionChunk *ObjFile::readSection(uint3 void ObjFile::readAssociativeDefinition( COFFSymbolRef Sym, const coff_aux_section_definition *Def) { - SectionChunk *Parent = SparseChunks[Def->getNumber(Sym.isBigObj())]; + readAssociativeDefinition(Sym, Def, Def->getNumber(Sym.isBigObj())); +} + +void ObjFile::readAssociativeDefinition(COFFSymbolRef Sym, + const coff_aux_section_definition *Def, + uint32_t ParentSection) { + SectionChunk *Parent = SparseChunks[ParentSection]; // If the parent is pending, it probably means that its section definition // appears after us in the symbol table. Leave the associated section as @@ -225,6 +231,35 @@ void ObjFile::readAssociativeDefinition( } } +void ObjFile::recordPrevailingSymbolForMingw( + COFFSymbolRef Sym, DenseMap<StringRef, uint32_t> &PrevailingSectionMap) { + // For comdat symbols in executable sections, where this is the copy + // of the section chunk we actually include instead of discarding it, + // add the symbol to a map to allow using it for implicitly + // associating .[px]data$<func> sections to it. + int32_t SectionNumber = Sym.getSectionNumber(); + SectionChunk *SC = SparseChunks[SectionNumber]; + if (SC && SC->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) { + StringRef Name; + COFFObj->getSymbolName(Sym, Name); + PrevailingSectionMap[Name] = SectionNumber; + } +} + +void ObjFile::maybeAssociateSEHForMingw( + COFFSymbolRef Sym, const coff_aux_section_definition *Def, + const DenseMap<StringRef, uint32_t> &PrevailingSectionMap) { + StringRef Name; + COFFObj->getSymbolName(Sym, Name); + if (Name.consume_front(".pdata$") || Name.consume_front(".xdata$")) { + // For MinGW, treat .[px]data$<func> as implicitly associative to + // the symbol <func>. + auto ParentSym = PrevailingSectionMap.find(Name); + if (ParentSym != PrevailingSectionMap.end()) + readAssociativeDefinition(Sym, Def, ParentSym->second); + } +} + Symbol *ObjFile::createRegular(COFFSymbolRef Sym) { SectionChunk *SC = SparseChunks[Sym.getSectionNumber()]; if (Sym.isExternal()) { @@ -248,19 +283,24 @@ void ObjFile::initializeSymbols() { std::vector<uint32_t> PendingIndexes; PendingIndexes.reserve(NumSymbols); + DenseMap<StringRef, uint32_t> PrevailingSectionMap; std::vector<const coff_aux_section_definition *> ComdatDefs( COFFObj->getNumberOfSections() + 1); for (uint32_t I = 0; I < NumSymbols; ++I) { COFFSymbolRef COFFSym = check(COFFObj->getSymbol(I)); + bool PrevailingComdat; if (COFFSym.isUndefined()) { Symbols[I] = createUndefined(COFFSym); } else if (COFFSym.isWeakExternal()) { Symbols[I] = createUndefined(COFFSym); uint32_t TagIndex = COFFSym.getAux<coff_aux_weak_external>()->TagIndex; WeakAliases.emplace_back(Symbols[I], TagIndex); - } else if (Optional<Symbol *> OptSym = createDefined(COFFSym, ComdatDefs)) { + } else if (Optional<Symbol *> OptSym = + createDefined(COFFSym, ComdatDefs, PrevailingComdat)) { Symbols[I] = *OptSym; + if (Config->MinGW && PrevailingComdat) + recordPrevailingSymbolForMingw(COFFSym, PrevailingSectionMap); } else { // createDefined() returns None if a symbol belongs to a section that // was pending at the point when the symbol was read. This can happen in @@ -278,9 +318,12 @@ void ObjFile::initializeSymbols() { for (uint32_t I : PendingIndexes) { COFFSymbolRef Sym = check(COFFObj->getSymbol(I)); - if (auto *Def = Sym.getSectionDefinition()) + if (auto *Def = Sym.getSectionDefinition()) { if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) readAssociativeDefinition(Sym, Def); + else if (Config->MinGW) + maybeAssociateSEHForMingw(Sym, Def, PrevailingSectionMap); + } if (SparseChunks[Sym.getSectionNumber()] == PendingComdat) { StringRef Name; COFFObj->getSymbolName(Sym, Name); @@ -306,7 +349,9 @@ Symbol *ObjFile::createUndefined(COFFSym Optional<Symbol *> ObjFile::createDefined( COFFSymbolRef Sym, - std::vector<const coff_aux_section_definition *> &ComdatDefs) { + std::vector<const coff_aux_section_definition *> &ComdatDefs, + bool &Prevailing) { + Prevailing = false; auto GetName = [&]() { StringRef S; COFFObj->getSymbolName(Sym, S); @@ -352,7 +397,6 @@ Optional<Symbol *> ObjFile::createDefine if (const coff_aux_section_definition *Def = ComdatDefs[SectionNumber]) { ComdatDefs[SectionNumber] = nullptr; Symbol *Leader; - bool Prevailing; if (Sym.isExternal()) { std::tie(Leader, Prevailing) = Symtab->addComdat(this, GetName(), Sym.getGeneric()); Modified: lld/branches/release_70/COFF/InputFiles.h URL: http://llvm.org/viewvc/llvm-project/lld/branches/release_70/COFF/InputFiles.h?rev=339108&r1=339107&r2=339108&view=diff ============================================================================== --- lld/branches/release_70/COFF/InputFiles.h (original) +++ lld/branches/release_70/COFF/InputFiles.h Tue Aug 7 00:46:29 2018 @@ -13,6 +13,7 @@ #include "Config.h" #include "lld/Common/LLVM.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/LTO/LTO.h" #include "llvm/Object/Archive.h" @@ -157,10 +158,24 @@ private: COFFSymbolRef COFFSym, const llvm::object::coff_aux_section_definition *Def); + void readAssociativeDefinition( + COFFSymbolRef COFFSym, + const llvm::object::coff_aux_section_definition *Def, + uint32_t ParentSection); + + void recordPrevailingSymbolForMingw( + COFFSymbolRef COFFSym, + llvm::DenseMap<StringRef, uint32_t> &PrevailingSectionMap); + + void maybeAssociateSEHForMingw( + COFFSymbolRef Sym, const llvm::object::coff_aux_section_definition *Def, + const llvm::DenseMap<StringRef, uint32_t> &PrevailingSectionMap); + llvm::Optional<Symbol *> createDefined(COFFSymbolRef Sym, std::vector<const llvm::object::coff_aux_section_definition *> - &ComdatDefs); + &ComdatDefs, + bool &PrevailingComdat); Symbol *createRegular(COFFSymbolRef Sym); Symbol *createUndefined(COFFSymbolRef Sym); _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits