[llvm-branch-commits] [lld] r339108 - Merging r339058:

Hans Wennborg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Aug 7 00:46:30 PDT 2018


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);
 




More information about the llvm-branch-commits mailing list