[llvm] r210367 - Fix a few issues with comdat handling on COFF.

Rafael Espindola rafael.espindola at gmail.com
Fri Jun 6 12:26:12 PDT 2014


Author: rafael
Date: Fri Jun  6 14:26:12 2014
New Revision: 210367

URL: http://llvm.org/viewvc/llvm-project?rev=210367&view=rev
Log:
Fix a few issues with comdat handling on COFF.

* Section association cannot use just the section name as many
sections can have the same name. With this patch, the comdat symbol in
an assoc section is interpreted to mean a symbol in the associated
section and the mapping is discovered from it.

* Comdat symbols were not being set correctly. Instead we were getting
whatever was output first for that section.

A consequence is that associative sections now must use .section to
set the association. Using .linkonce would not work since it is not
possible to change a sections comdat symbol (it is used to decide if
we should create a new section or reuse an existing one).

This includes r210298, which was reverted because it was asserting
on an associated section having the same comdat as the associated
section.

Added:
    llvm/trunk/test/MC/COFF/section-comdat-conflict.s
    llvm/trunk/test/MC/COFF/section-comdat-conflict2.s
Modified:
    llvm/trunk/docs/Extensions.rst
    llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
    llvm/trunk/include/llvm/MC/MCContext.h
    llvm/trunk/include/llvm/MC/MCSectionCOFF.h
    llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/trunk/lib/MC/MCContext.cpp
    llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp
    llvm/trunk/lib/MC/MCSectionCOFF.cpp
    llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
    llvm/trunk/test/MC/COFF/global_ctors_dtors.ll
    llvm/trunk/test/MC/COFF/linkonce-invalid.s
    llvm/trunk/test/MC/COFF/linkonce.s
    llvm/trunk/test/MC/COFF/section-comdat.s

Modified: llvm/trunk/docs/Extensions.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Extensions.rst?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/docs/Extensions.rst (original)
+++ llvm/trunk/docs/Extensions.rst Fri Jun  6 14:26:12 2014
@@ -76,7 +76,7 @@ the target.  It corresponds to the COFF
 
 Syntax:
 
-   ``.linkonce [ comdat type [ section identifier ] ]``
+   ``.linkonce [ comdat type ]``
 
 Supported COMDAT types:
 
@@ -95,16 +95,6 @@ Supported COMDAT types:
    Duplicates are discarded, but the linker issues an error if any duplicates
    do not have exactly the same content.
 
-``associative``
-   Links the section if a certain other COMDAT section is linked. This other
-   section is indicated by its section identifier following the comdat type.
-   The following restrictions apply to the associated section:
-
-   1. It must be the name of a section already defined.
-   2. It must differ from the current section.
-   3. It must be a COMDAT section.
-   4. It cannot be another associative COMDAT section.
-
 ``largest``
    Links the largest section from among the duplicates.
 
@@ -118,10 +108,6 @@ Supported COMDAT types:
   .linkonce
     ...
 
-  .section .xdata$foo
-  .linkonce associative .text$foo
-    ...
-
 ``.section`` Directive
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -160,6 +146,25 @@ different COMDATs:
   Symbol2:
   .long 1
 
+In addition to the types allowed with ``.linkonce``, ``.section`` also accepts
+``associative``. The meaning is that the section is linked  if a certain other
+COMDAT section is linked. This other section is indicated by the comdat symbol
+in this directive. It can be any symbol defined in the associated section, but
+is usually the associated section's comdat.
+
+   The following restrictions apply to the associated section:
+
+   1. It must be a COMDAT section.
+   2. It cannot be another associative COMDAT section.
+
+In the following example the symobl ``sym`` is the comdat symbol of ``.foo``
+and ``.bar`` is associated to ``.foo``.
+
+.. code-block:: gas
+
+	.section	.foo,"bw",discard, "sym"
+	.section	.bar,"rd",associative, "sym"
+
 Target Specific Behaviour
 =========================
 

Modified: llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h (original)
+++ llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h Fri Jun  6 14:26:12 2014
@@ -68,11 +68,9 @@ public:
 
   void InitializeELF(bool UseInitArray_);
   const MCSection *getStaticCtorSection(unsigned Priority,
-                                        const MCSymbol *KeySym,
-                                        const MCSection *KeySec) const override;
+                                        const MCSymbol *KeySym) const override;
   const MCSection *getStaticDtorSection(unsigned Priority,
-                                        const MCSymbol *KeySym,
-                                        const MCSection *KeySec) const override;
+                                        const MCSymbol *KeySym) const override;
 };
 
 
@@ -144,11 +142,9 @@ public:
                        Mangler &Mang, const TargetMachine &TM) const override;
 
   const MCSection *getStaticCtorSection(unsigned Priority,
-                                        const MCSymbol *KeySym,
-                                        const MCSection *KeySec) const override;
+                                        const MCSymbol *KeySym) const override;
   const MCSection *getStaticDtorSection(unsigned Priority,
-                                        const MCSymbol *KeySym,
-                                        const MCSection *KeySec) const override;
+                                        const MCSymbol *KeySym) const override;
 };
 
 } // end namespace llvm

Modified: llvm/trunk/include/llvm/MC/MCContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCContext.h (original)
+++ llvm/trunk/include/llvm/MC/MCContext.h Fri Jun  6 14:26:12 2014
@@ -273,9 +273,7 @@ namespace llvm {
     const MCSectionCOFF *getCOFFSection(StringRef Section,
                                         unsigned Characteristics,
                                         SectionKind Kind,
-                                        StringRef COMDATSymName,
-                                        int Selection,
-                                        const MCSectionCOFF *Assoc = nullptr);
+                                        StringRef COMDATSymName, int Selection);
 
     const MCSectionCOFF *getCOFFSection(StringRef Section,
                                         unsigned Characteristics,

Modified: llvm/trunk/include/llvm/MC/MCSectionCOFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSectionCOFF.h?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSectionCOFF.h (original)
+++ llvm/trunk/include/llvm/MC/MCSectionCOFF.h Fri Jun  6 14:26:12 2014
@@ -42,24 +42,15 @@ class MCSymbol;
     /// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
     mutable int Selection;
 
-    /// Assoc - This is name of the associated section, if it is a COMDAT
-    /// section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0 with an
-    /// associative Selection (IMAGE_COMDAT_SELECT_ASSOCIATIVE).
-    mutable const MCSectionCOFF *Assoc;
-
   private:
     friend class MCContext;
     MCSectionCOFF(StringRef Section, unsigned Characteristics,
-                  const MCSymbol *COMDATSymbol, int Selection,
-                  const MCSectionCOFF *Assoc, SectionKind K)
+                  const MCSymbol *COMDATSymbol, int Selection, SectionKind K)
         : MCSection(SV_COFF, K), SectionName(Section),
           Characteristics(Characteristics), COMDATSymbol(COMDATSymbol),
-          Selection(Selection), Assoc(Assoc) {
+          Selection(Selection) {
       assert ((Characteristics & 0x00F00000) == 0 &&
         "alignment must not be set upon section creation");
-      assert ((Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) ==
-              (Assoc != nullptr) &&
-        "associative COMDAT section must have an associated section");
     }
     ~MCSectionCOFF();
 
@@ -76,11 +67,10 @@ class MCSymbol;
       return SectionName.str() + "_end";
     }
     unsigned getCharacteristics() const { return Characteristics; }
+    const MCSymbol *getCOMDATSymbol() const { return COMDATSymbol; }
     int getSelection() const { return Selection; }
-    const MCSectionCOFF *getAssocSection() const { return Assoc; }
 
-    void setSelection(int Selection,
-                      const MCSectionCOFF *Assoc = nullptr) const;
+    void setSelection(int Selection) const;
 
     void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
                               const MCExpr *Subsection) const override;

Modified: llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLoweringObjectFile.h Fri Jun  6 14:26:12 2014
@@ -131,14 +131,12 @@ public:
                     MCStreamer &Streamer) const;
 
   virtual const MCSection *getStaticCtorSection(unsigned Priority,
-                                                const MCSymbol *KeySym,
-                                                const MCSection *KeySec) const {
+                                                const MCSymbol *KeySym) const {
     return StaticCtorSection;
   }
 
   virtual const MCSection *getStaticDtorSection(unsigned Priority,
-                                                const MCSymbol *KeySym,
-                                                const MCSection *KeySec) const {
+                                                const MCSymbol *KeySym) const {
     return StaticDtorSection;
   }
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Fri Jun  6 14:26:12 2014
@@ -1397,7 +1397,6 @@ void AsmPrinter::EmitXXStructorList(cons
   for (Structor &S : Structors) {
     const TargetLoweringObjectFile &Obj = getObjFileLowering();
     const MCSymbol *KeySym = nullptr;
-    const MCSection *KeySec = nullptr;
     if (GlobalValue *GV = S.ComdatKey) {
       if (GV->hasAvailableExternallyLinkage())
         // If the associated variable is available_externally, some other TU
@@ -1405,11 +1404,10 @@ void AsmPrinter::EmitXXStructorList(cons
         continue;
 
       KeySym = getSymbol(GV);
-      KeySec = getObjFileLowering().SectionForGlobal(GV, *Mang, TM);
     }
     const MCSection *OutputSection =
-        (isCtor ? Obj.getStaticCtorSection(S.Priority, KeySym, KeySec)
-                : Obj.getStaticDtorSection(S.Priority, KeySym, KeySec));
+        (isCtor ? Obj.getStaticCtorSection(S.Priority, KeySym)
+                : Obj.getStaticDtorSection(S.Priority, KeySym));
     OutStreamer.SwitchSection(OutputSection);
     if (OutStreamer.getCurrentSection() != OutStreamer.getPreviousSection())
       EmitAlignment(Align);

Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Fri Jun  6 14:26:12 2014
@@ -336,7 +336,7 @@ getSectionForConstant(SectionKind Kind)
 }
 
 const MCSection *TargetLoweringObjectFileELF::getStaticCtorSection(
-    unsigned Priority, const MCSymbol *KeySym, const MCSection *KeySec) const {
+    unsigned Priority, const MCSymbol *KeySym) const {
   // The default scheme is .ctor / .dtor, so we have to invert the priority
   // numbering.
   if (Priority == 65535)
@@ -356,7 +356,7 @@ const MCSection *TargetLoweringObjectFil
 }
 
 const MCSection *TargetLoweringObjectFileELF::getStaticDtorSection(
-    unsigned Priority, const MCSymbol *KeySym, const MCSection *KeySec) const {
+    unsigned Priority, const MCSymbol *KeySym) const {
   // The default scheme is .ctor / .dtor, so we have to invert the priority
   // numbering.
   if (Priority == 65535)
@@ -864,8 +864,7 @@ emitModuleFlags(MCStreamer &Streamer,
 
 static const MCSection *getAssociativeCOFFSection(MCContext &Ctx,
                                                   const MCSection *Sec,
-                                                  const MCSymbol *KeySym,
-                                                  const MCSection *KeySec) {
+                                                  const MCSymbol *KeySym) {
   // Return the normal section if we don't have to be associative.
   if (!KeySym)
     return Sec;
@@ -873,20 +872,19 @@ static const MCSection *getAssociativeCO
   // Make an associative section with the same name and kind as the normal
   // section.
   const MCSectionCOFF *SecCOFF = cast<MCSectionCOFF>(Sec);
-  const MCSectionCOFF *KeySecCOFF = cast<MCSectionCOFF>(KeySec);
   unsigned Characteristics =
       SecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT;
   return Ctx.getCOFFSection(SecCOFF->getSectionName(), Characteristics,
                             SecCOFF->getKind(), KeySym->getName(),
-                            COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, KeySecCOFF);
+                            COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
 }
 
 const MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection(
-    unsigned Priority, const MCSymbol *KeySym, const MCSection *KeySec) const {
-  return getAssociativeCOFFSection(getContext(), StaticCtorSection, KeySym, KeySec);
+    unsigned Priority, const MCSymbol *KeySym) const {
+  return getAssociativeCOFFSection(getContext(), StaticCtorSection, KeySym);
 }
 
 const MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
-    unsigned Priority, const MCSymbol *KeySym, const MCSection *KeySec) const {
-  return getAssociativeCOFFSection(getContext(), StaticDtorSection, KeySym, KeySec);
+    unsigned Priority, const MCSymbol *KeySym) const {
+  return getAssociativeCOFFSection(getContext(), StaticDtorSection, KeySym);
 }

Modified: llvm/trunk/lib/MC/MCContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCContext.cpp (original)
+++ llvm/trunk/lib/MC/MCContext.cpp Fri Jun  6 14:26:12 2014
@@ -277,10 +277,11 @@ const MCSectionELF *MCContext::CreateELF
   return Result;
 }
 
-const MCSectionCOFF *
-MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
-                          SectionKind Kind, StringRef COMDATSymName,
-                          int Selection, const MCSectionCOFF *Assoc) {
+const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
+                                               unsigned Characteristics,
+                                               SectionKind Kind,
+                                               StringRef COMDATSymName,
+                                               int Selection) {
   // Do the lookup, if we have a hit, return it.
 
   SectionGroupPair P(Section, COMDATSymName);
@@ -294,8 +295,8 @@ MCContext::getCOFFSection(StringRef Sect
     COMDATSymbol = GetOrCreateSymbol(COMDATSymName);
 
   StringRef CachedName = Iter->first.first;
-  MCSectionCOFF *Result = new (*this) MCSectionCOFF(
-      CachedName, Characteristics, COMDATSymbol, Selection, Assoc, Kind);
+  MCSectionCOFF *Result = new (*this)
+      MCSectionCOFF(CachedName, Characteristics, COMDATSymbol, Selection, Kind);
 
   Iter->second = Result;
   return Result;

Modified: llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp Fri Jun  6 14:26:12 2014
@@ -37,7 +37,7 @@ class COFFAsmParser : public MCAsmParser
 
   bool ParseSectionSwitch(StringRef Section, unsigned Characteristics,
                           SectionKind Kind, StringRef COMDATSymName,
-                          COFF::COMDATType Type, const MCSectionCOFF *Assoc);
+                          COFF::COMDATType Type);
 
   bool ParseSectionName(StringRef &SectionName);
   bool ParseSectionFlags(StringRef FlagsString, unsigned* Flags);
@@ -117,8 +117,7 @@ class COFFAsmParser : public MCAsmParser
   bool ParseDirectiveEndef(StringRef, SMLoc);
   bool ParseDirectiveSecRel32(StringRef, SMLoc);
   bool ParseDirectiveSecIdx(StringRef, SMLoc);
-  bool parseCOMDATTypeAndAssoc(COFF::COMDATType &Type,
-                               const MCSectionCOFF *&Assoc);
+  bool parseCOMDATType(COFF::COMDATType &Type);
   bool ParseDirectiveLinkOnce(StringRef, SMLoc);
 
   // Win64 EH directives.
@@ -293,21 +292,20 @@ bool COFFAsmParser::ParseSectionSwitch(S
                                        unsigned Characteristics,
                                        SectionKind Kind) {
   return ParseSectionSwitch(Section, Characteristics, Kind, "",
-                            COFF::IMAGE_COMDAT_SELECT_ANY, nullptr);
+                            COFF::IMAGE_COMDAT_SELECT_ANY);
 }
 
 bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
                                        unsigned Characteristics,
                                        SectionKind Kind,
                                        StringRef COMDATSymName,
-                                       COFF::COMDATType Type,
-                                       const MCSectionCOFF *Assoc) {
+                                       COFF::COMDATType Type) {
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in section switching directive");
   Lex();
 
   getStreamer().SwitchSection(getContext().getCOFFSection(
-      Section, Characteristics, Kind, COMDATSymName, Type, Assoc));
+      Section, Characteristics, Kind, COMDATSymName, Type));
 
   return false;
 }
@@ -359,14 +357,13 @@ bool COFFAsmParser::ParseDirectiveSectio
   }
 
   COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
-  const MCSectionCOFF *Assoc = nullptr;
   StringRef COMDATSymName;
   if (getLexer().is(AsmToken::Comma)) {
     Lex();
 
     Flags |= COFF::IMAGE_SCN_LNK_COMDAT;
 
-    if (parseCOMDATTypeAndAssoc(Type, Assoc))
+    if (parseCOMDATType(Type))
       return true;
 
     if (getLexer().isNot(AsmToken::Comma))
@@ -381,7 +378,7 @@ bool COFFAsmParser::ParseDirectiveSectio
     return TokError("unexpected token in directive");
 
   SectionKind Kind = computeSectionKind(Flags);
-  ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type, Assoc);
+  ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type);
   return false;
 }
 
@@ -461,9 +458,8 @@ bool COFFAsmParser::ParseDirectiveSecIdx
   return false;
 }
 
-/// ::= [ identifier [ identifier ] ]
-bool COFFAsmParser::parseCOMDATTypeAndAssoc(COFF::COMDATType &Type,
-                                            const MCSectionCOFF *&Assoc) {
+/// ::= [ identifier ]
+bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
   StringRef TypeId = getTok().getIdentifier();
 
   Type = StringSwitch<COFF::COMDATType>(TypeId)
@@ -481,48 +477,28 @@ bool COFFAsmParser::parseCOMDATTypeAndAs
 
   Lex();
 
-  if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
-    SMLoc Loc = getTok().getLoc();
-    StringRef AssocName;
-    if (ParseSectionName(AssocName))
-      return TokError("expected associated section name");
-
-    Assoc = static_cast<const MCSectionCOFF*>(
-                                        getContext().getCOFFSection(AssocName));
-    if (!Assoc)
-      return Error(Loc, "cannot associate unknown section '" + AssocName + "'");
-    if (!(Assoc->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT))
-      return Error(Loc, "associated section must be a COMDAT section");
-    if (Assoc->getSelection() == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
-      return Error(Loc, "associated section cannot be itself associative");
-  }
-
   return false;
 }
 
 /// ParseDirectiveLinkOnce
-///  ::= .linkonce [ identifier [ identifier ] ]
+///  ::= .linkonce [ identifier ]
 bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
   COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
-  const MCSectionCOFF *Assoc = nullptr;
   if (getLexer().is(AsmToken::Identifier))
-    if (parseCOMDATTypeAndAssoc(Type, Assoc))
+    if (parseCOMDATType(Type))
       return true;
 
   const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>(
                                        getStreamer().getCurrentSection().first);
 
-
-  if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
-    if (Assoc == Current)
-      return Error(Loc, "cannot associate a section with itself");
-  }
+  if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
+    return Error(Loc, "cannot make section associative with .linkonce");
 
   if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
     return Error(Loc, Twine("section '") + Current->getSectionName() +
                                                        "' is already linkonce");
 
-  Current->setSelection(Type, Assoc);
+  Current->setSelection(Type);
 
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in directive");

Modified: llvm/trunk/lib/MC/MCSectionCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSectionCOFF.cpp?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCSectionCOFF.cpp (original)
+++ llvm/trunk/lib/MC/MCSectionCOFF.cpp Fri Jun  6 14:26:12 2014
@@ -30,14 +30,9 @@ bool MCSectionCOFF::ShouldOmitSectionDir
   return false;
 }
 
-void MCSectionCOFF::setSelection(int Selection,
-                                 const MCSectionCOFF *Assoc) const {
+void MCSectionCOFF::setSelection(int Selection) const {
   assert(Selection != 0 && "invalid COMDAT selection type");
-  assert((Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) ==
-         (Assoc != nullptr) &&
-    "associative COMDAT section must have an associated section");
   this->Selection = Selection;
-  this->Assoc = Assoc;
   Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
 }
 
@@ -82,7 +77,7 @@ void MCSectionCOFF::PrintSwitchToSection
         OS << "same_contents,";
         break;
       case COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE:
-        OS << "associative " << Assoc->getSectionName() << ",";
+        OS << "associative,";
         break;
       case COFF::IMAGE_COMDAT_SELECT_LARGEST:
         OS << "largest,";

Modified: llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp Fri Jun  6 14:26:12 2014
@@ -347,6 +347,14 @@ void WinCOFFObjectWriter::DefineSection(
 
   COFFSection *coff_section = createSection(Sec.getSectionName());
   COFFSymbol  *coff_symbol = createSymbol(Sec.getSectionName());
+  if (Sec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+    if (const MCSymbol *S = Sec.getCOMDATSymbol()) {
+      COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
+      if (COMDATSymbol->Section)
+        report_fatal_error("two sections have the same comdat");
+      COMDATSymbol->Section = coff_section;
+    }
+  }
 
   coff_section->Symbol = coff_symbol;
   coff_symbol->Section = coff_section;
@@ -458,9 +466,15 @@ void WinCOFFObjectWriter::DefineSymbol(M
       coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
     } else {
       const MCSymbolData &BaseData = Assembler.getSymbolData(*Base);
-      if (BaseData.Fragment)
-        coff_symbol->Section =
+      if (BaseData.Fragment) {
+        COFFSection *Sec =
             SectionMap[&BaseData.Fragment->getParent()->getSection()];
+
+        if (coff_symbol->Section && coff_symbol->Section != Sec)
+          report_fatal_error("conflicting sections for symbol");
+
+        coff_symbol->Section = Sec;
+      }
     }
 
     coff_symbol->MCData = &ResSymData;
@@ -865,11 +879,15 @@ void WinCOFFObjectWriter::WriteObject(MC
     const MCSectionCOFF &MCSec =
       static_cast<const MCSectionCOFF &>(Section->MCData->getSection());
 
-    COFFSection *Assoc = SectionMap.lookup(MCSec.getAssocSection());
+    const MCSymbol *COMDAT = MCSec.getCOMDATSymbol();
+    assert(COMDAT);
+    COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(COMDAT);
+    assert(COMDATSymbol);
+    COFFSection *Assoc = COMDATSymbol->Section;
     if (!Assoc)
-      report_fatal_error(Twine("Missing associated COMDAT section ") +
-                         MCSec.getAssocSection()->getSectionName() +
-                         " for section " + MCSec.getSectionName());
+      report_fatal_error(
+          Twine("Missing associated COMDAT section for section ") +
+          MCSec.getSectionName());
 
     // Skip this section if the associated section is unused.
     if (Assoc->Number == -1)

Modified: llvm/trunk/test/MC/COFF/global_ctors_dtors.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/global_ctors_dtors.ll?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/test/MC/COFF/global_ctors_dtors.ll (original)
+++ llvm/trunk/test/MC/COFF/global_ctors_dtors.ll Fri Jun  6 14:26:12 2014
@@ -51,14 +51,14 @@ define i32 @main() nounwind {
 
 ; WIN32: .section .CRT$XCU,"rd"
 ; WIN32: a_global_ctor
-; WIN32: .section .CRT$XCU,"rd",associative .bss,{{_?}}b
+; WIN32: .section .CRT$XCU,"rd",associative,{{_?}}b
 ; WIN32: b_global_ctor
 ; WIN32-NOT: c_global_ctor
 ; WIN32: .section .CRT$XTX,"rd"
 ; WIN32: a_global_dtor
 ; MINGW32: .section .ctors,"wd"
 ; MINGW32: a_global_ctor
-; MINGW32: .section .ctors,"wd",associative .bss,{{_?}}b
+; MINGW32: .section .ctors,"wd",associative,{{_?}}b
 ; MINGW32: b_global_ctor
 ; MINGW32-NOT: c_global_ctor
 ; MINGW32: .section .dtors,"wd"

Modified: llvm/trunk/test/MC/COFF/linkonce-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/linkonce-invalid.s?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/test/MC/COFF/linkonce-invalid.s (original)
+++ llvm/trunk/test/MC/COFF/linkonce-invalid.s Fri Jun  6 14:26:12 2014
@@ -19,21 +19,9 @@
 // CHECK: error: unexpected token in directive
 .linkonce discard foo
 
-// CHECK: error: expected associated section name
+// CHECK: error: cannot make section associative with .linkonce
 .linkonce associative
 
-// CHECK: error: cannot associate unknown section 'unknown'
-.linkonce associative unknown
-
-// CHECK: error: cannot associate a section with itself
-.linkonce associative invalid
-
-// CHECK: error: associated section must be a COMDAT section
-.linkonce associative non_comdat
-
-// CHECK: error: associated section cannot be itself associative
-.linkonce associative assoc
-
 // CHECK: error: section 'multi' is already linkonce
 .section multi
 .linkonce discard

Modified: llvm/trunk/test/MC/COFF/linkonce.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/linkonce.s?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/test/MC/COFF/linkonce.s (original)
+++ llvm/trunk/test/MC/COFF/linkonce.s Fri Jun  6 14:26:12 2014
@@ -24,7 +24,6 @@
 .long 1
 
 .section s6
-.linkonce associative s1
 .long 1
 
 .section s7
@@ -39,11 +38,6 @@
 .linkonce discard
 .long 1
 
-// Check that valid '.section' names can be associated.
-.section multi
-.linkonce associative .foo$bar
-.long 1
-
 
 // CHECK: Sections [
 // CHECK:   Section {
@@ -79,7 +73,6 @@
 // CHECK:   Section {
 // CHECK:     Name: s6
 // CHECK:     Characteristics [
-// CHECK:       IMAGE_SCN_LNK_COMDAT
 // CHECK:     ]
 // CHECK:   }
 // CHECK:   Section {
@@ -94,12 +87,6 @@
 // CHECK:       IMAGE_SCN_LNK_COMDAT
 // CHECK:     ]
 // CHECK:   }
-// CHECK:   Section {
-// CHECK:     Name: multi
-// CHECK:     Characteristics [
-// CHECK:       IMAGE_SCN_LNK_COMDAT
-// CHECK:     ]
-// CHECK:   }
 // CHECK: ]
 // CHECK: Symbols [
 // CHECK:   Symbol {
@@ -144,12 +131,6 @@
 // CHECK:   }
 // CHECK:   Symbol {
 // CHECK:     Name: s6
-// CHECK:     Section: s6 (6)
-// CHECK:     AuxSectionDef {
-// CHECK:       Number: 1
-// CHECK:       Selection: Associative (0x5)
-// CHECK:       AssocSection: s1
-// CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
 // CHECK:     Name: s7
@@ -167,13 +148,3 @@
 // CHECK:       Selection: Newest (0x7)
 // CHECK:     }
 // CHECK:   }
-// CHECK:   Symbol {
-// CHECK:     Name: multi
-// CHECK:     Value: 0
-// CHECK:     Section: multi (10)
-// CHECK:     AuxSectionDef {
-// CHECK:       Number: 9
-// CHECK:       Selection: Associative (0x5)
-// CHECK:       AssocSection: .foo$bar
-// CHECK:     }
-// CHECK:   }

Added: llvm/trunk/test/MC/COFF/section-comdat-conflict.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/section-comdat-conflict.s?rev=210367&view=auto
==============================================================================
--- llvm/trunk/test/MC/COFF/section-comdat-conflict.s (added)
+++ llvm/trunk/test/MC/COFF/section-comdat-conflict.s Fri Jun  6 14:26:12 2014
@@ -0,0 +1,13 @@
+// RUN: not llvm-mc -triple i386-pc-win32 -filetype=obj < %s 2>&1 |  FileCheck %s
+
+// CHECK: conflicting sections for symbol
+
+        .section .xyz
+        .global bar
+bar:
+        .long 42
+
+        .section        .abcd,"xr",discard,bar
+        .global foo
+foo:
+        .long 42

Added: llvm/trunk/test/MC/COFF/section-comdat-conflict2.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/section-comdat-conflict2.s?rev=210367&view=auto
==============================================================================
--- llvm/trunk/test/MC/COFF/section-comdat-conflict2.s (added)
+++ llvm/trunk/test/MC/COFF/section-comdat-conflict2.s Fri Jun  6 14:26:12 2014
@@ -0,0 +1,6 @@
+// RUN: not llvm-mc -triple i386-pc-win32 -filetype=obj < %s 2>&1 |  FileCheck %s
+
+// CHECK: two sections have the same comdat
+
+        .section        .xyz,"xr",discard,bar
+        .section        .abcd,"xr",discard,bar

Modified: llvm/trunk/test/MC/COFF/section-comdat.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/section-comdat.s?rev=210367&r1=210366&r2=210367&view=diff
==============================================================================
--- llvm/trunk/test/MC/COFF/section-comdat.s (original)
+++ llvm/trunk/test/MC/COFF/section-comdat.s Fri Jun  6 14:26:12 2014
@@ -1,8 +1,7 @@
 // RUN: llvm-mc -triple i386-pc-win32 -filetype=obj %s | llvm-readobj -s -t | FileCheck %s
 // RUN: llvm-mc -triple x86_64-pc-win32 -filetype=obj %s | llvm-readobj -s -t | FileCheck %s
 
-.section assocSec
-.linkonce
+.section assocSec, "dr", discard, "assocSym"
 .long 1
 
 .section secName, "dr", discard, "Symbol1"
@@ -25,7 +24,7 @@ Symbol3:
 Symbol4:
 .long 1
 
-.section SecName, "dr", associative assocSec, "Symbol5"
+.section SecName, "dr", associative, "assocSym"
 .globl Symbol5
 Symbol5:
 .long 1
@@ -107,6 +106,10 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
+// CHECK:     Name: assocSym
+// CHECK:     Section: assocSec
+// CHECK:   }
+// CHECK:   Symbol {
 // CHECK:     Name: secName
 // CHECK:     Section: secName (2)
 // CHECK:     AuxSectionDef {
@@ -114,6 +117,10 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
+// CHECK:     Name: Symbol1
+// CHECK:     Section: secName (2)
+// CHECK:   }
+// CHECK:   Symbol {
 // CHECK:     Name: secName
 // CHECK:     Section: secName (3)
 // CHECK:     AuxSectionDef {
@@ -121,6 +128,10 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
+// CHECK:     Name: Symbol2
+// CHECK:     Section: secName (3)
+// CHECK:   }
+// CHECK:   Symbol {
 // CHECK:     Name: SecName
 // CHECK:     Section: SecName (4)
 // CHECK:     AuxSectionDef {
@@ -128,6 +139,10 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
+// CHECK:     Name: Symbol3
+// CHECK:     Section: SecName (4)
+// CHECK:   }
+// CHECK:   Symbol {
 // CHECK:     Name: SecName
 // CHECK:     Section: SecName (5)
 // CHECK:     AuxSymbolCount: 1
@@ -136,6 +151,10 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
+// CHECK:     Name: Symbol4
+// CHECK:     Section: SecName (5)
+// CHECK:   }
+// CHECK:   Symbol {
 // CHECK:     Name: SecName
 // CHECK:     Section: SecName (6)
 // CHECK:     AuxSectionDef {
@@ -151,6 +170,10 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
+// CHECK:     Name: Symbol6
+// CHECK:     Section: SecName (7)
+// CHECK:   }
+// CHECK:   Symbol {
 // CHECK:     Name: SecName
 // CHECK:     Section: SecName (8)
 // CHECK:     AuxSectionDef {
@@ -158,31 +181,11 @@ Symbol7:
 // CHECK:     }
 // CHECK:   }
 // CHECK:   Symbol {
-// CHECK:     Name: Symbol1
-// CHECK:     Section: secName (2)
-// CHECK:   }
-// CHECK:   Symbol {
-// CHECK:     Name: Symbol2
-// CHECK:     Section: secName (3)
-// CHECK:   }
-// CHECK:   Symbol {
-// CHECK:     Name: Symbol3
-// CHECK:     Section: SecName (4)
-// CHECK:   }
-// CHECK:   Symbol {
-// CHECK:     Name: Symbol4
-// CHECK:     Section: SecName (5)
+// CHECK:     Name: Symbol7
+// CHECK:     Section: SecName (8)
 // CHECK:   }
 // CHECK:   Symbol {
 // CHECK:     Name: Symbol5
 // CHECK:     Section: SecName (6)
 // CHECK:   }
-// CHECK:   Symbol {
-// CHECK:     Name: Symbol6
-// CHECK:     Section: SecName (7)
-// CHECK:   }
-// CHECK:   Symbol {
-// CHECK:     Name: Symbol7
-// CHECK:     Section: SecName (8)
-// CHECK:   }
 // CHECK: ]





More information about the llvm-commits mailing list