From 0766ae08e58cb6358ed1ce407439bd3614380b2e Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 6 Jun 2014 19:26:12 +0000 Subject: [PATCH] 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. llvm-svn: 210367 --- llvm/docs/Extensions.rst | 35 ++++++++------ .../llvm/CodeGen/TargetLoweringObjectFileImpl.h | 12 ++--- llvm/include/llvm/MC/MCContext.h | 4 +- llvm/include/llvm/MC/MCSectionCOFF.h | 18 ++------ .../include/llvm/Target/TargetLoweringObjectFile.h | 6 +-- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 6 +-- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 18 ++++---- llvm/lib/MC/MCContext.cpp | 13 +++--- llvm/lib/MC/MCParser/COFFAsmParser.cpp | 52 ++++++--------------- llvm/lib/MC/MCSectionCOFF.cpp | 9 +--- llvm/lib/MC/WinCOFFObjectWriter.cpp | 30 +++++++++--- llvm/test/MC/COFF/global_ctors_dtors.ll | 4 +- llvm/test/MC/COFF/linkonce-invalid.s | 14 +----- llvm/test/MC/COFF/linkonce.s | 29 ------------ llvm/test/MC/COFF/section-comdat-conflict.s | 13 ++++++ llvm/test/MC/COFF/section-comdat-conflict2.s | 6 +++ llvm/test/MC/COFF/section-comdat.s | 53 ++++++++++++---------- 17 files changed, 138 insertions(+), 184 deletions(-) create mode 100644 llvm/test/MC/COFF/section-comdat-conflict.s create mode 100644 llvm/test/MC/COFF/section-comdat-conflict2.s diff --git a/llvm/docs/Extensions.rst b/llvm/docs/Extensions.rst index a49485c..cd489c0 100644 --- a/llvm/docs/Extensions.rst +++ b/llvm/docs/Extensions.rst @@ -76,7 +76,7 @@ the target. It corresponds to the COFF relocation types 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 ========================= diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 9f1cbaa..230d1ed 100644 --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -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 diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h index 7557e76..2f9b32b 100644 --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -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, diff --git a/llvm/include/llvm/MC/MCSectionCOFF.h b/llvm/include/llvm/MC/MCSectionCOFF.h index a428f9e..d205e2a 100644 --- a/llvm/include/llvm/MC/MCSectionCOFF.h +++ b/llvm/include/llvm/MC/MCSectionCOFF.h @@ -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; diff --git a/llvm/include/llvm/Target/TargetLoweringObjectFile.h b/llvm/include/llvm/Target/TargetLoweringObjectFile.h index 374a163..419eced 100644 --- a/llvm/include/llvm/Target/TargetLoweringObjectFile.h +++ b/llvm/include/llvm/Target/TargetLoweringObjectFile.h @@ -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; } diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index cb7cacb..9d822d3c 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1397,7 +1397,6 @@ void AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) { 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(const Constant *List, bool isCtor) { 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); diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index d349425..02abc28 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -336,7 +336,7 @@ getSectionForConstant(SectionKind Kind) const { } 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 *TargetLoweringObjectFileELF::getStaticCtorSection( } 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 *getAssociativeCOFFSection(MCContext &Ctx, // Make an associative section with the same name and kind as the normal // section. const MCSectionCOFF *SecCOFF = cast(Sec); - const MCSectionCOFF *KeySecCOFF = cast(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); } diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index c163268..130bb99 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -277,10 +277,11 @@ const MCSectionELF *MCContext::CreateELFGroupSection() { 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 Section, unsigned Characteristics, 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; diff --git a/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/llvm/lib/MC/MCParser/COFFAsmParser.cpp index decf01c..8e8447f 100644 --- a/llvm/lib/MC/MCParser/COFFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/COFFAsmParser.cpp @@ -37,7 +37,7 @@ class COFFAsmParser : public MCAsmParserExtension { 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 MCAsmParserExtension { 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(StringRef Section, 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::ParseDirectiveSection(StringRef, SMLoc) { } 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::ParseDirectiveSection(StringRef, SMLoc) { 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(StringRef, SMLoc) { 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(TypeId) @@ -481,48 +477,28 @@ bool COFFAsmParser::parseCOMDATTypeAndAssoc(COFF::COMDATType &Type, 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( - 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( 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"); diff --git a/llvm/lib/MC/MCSectionCOFF.cpp b/llvm/lib/MC/MCSectionCOFF.cpp index 335b8cd..fc2bd36 100644 --- a/llvm/lib/MC/MCSectionCOFF.cpp +++ b/llvm/lib/MC/MCSectionCOFF.cpp @@ -30,14 +30,9 @@ bool MCSectionCOFF::ShouldOmitSectionDirective(StringRef Name, 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(const MCAsmInfo &MAI, 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,"; diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp index 961cbc6..6f9c73b 100644 --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -347,6 +347,14 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { 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(MCSymbolData const &SymbolData, 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(MCAssembler &Asm, const MCSectionCOFF &MCSec = static_cast(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) diff --git a/llvm/test/MC/COFF/global_ctors_dtors.ll b/llvm/test/MC/COFF/global_ctors_dtors.ll index 735c493..ca17f24 100644 --- a/llvm/test/MC/COFF/global_ctors_dtors.ll +++ b/llvm/test/MC/COFF/global_ctors_dtors.ll @@ -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" diff --git a/llvm/test/MC/COFF/linkonce-invalid.s b/llvm/test/MC/COFF/linkonce-invalid.s index 90ce4a7..cc3a27c 100644 --- a/llvm/test/MC/COFF/linkonce-invalid.s +++ b/llvm/test/MC/COFF/linkonce-invalid.s @@ -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 diff --git a/llvm/test/MC/COFF/linkonce.s b/llvm/test/MC/COFF/linkonce.s index e7b7f47..b6e81ad 100644 --- a/llvm/test/MC/COFF/linkonce.s +++ b/llvm/test/MC/COFF/linkonce.s @@ -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: } diff --git a/llvm/test/MC/COFF/section-comdat-conflict.s b/llvm/test/MC/COFF/section-comdat-conflict.s new file mode 100644 index 0000000..7ed452a --- /dev/null +++ b/llvm/test/MC/COFF/section-comdat-conflict.s @@ -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 diff --git a/llvm/test/MC/COFF/section-comdat-conflict2.s b/llvm/test/MC/COFF/section-comdat-conflict2.s new file mode 100644 index 0000000..e2dfc2d --- /dev/null +++ b/llvm/test/MC/COFF/section-comdat-conflict2.s @@ -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 diff --git a/llvm/test/MC/COFF/section-comdat.s b/llvm/test/MC/COFF/section-comdat.s index dd5be87..a0ea7d0 100644 --- a/llvm/test/MC/COFF/section-comdat.s +++ b/llvm/test/MC/COFF/section-comdat.s @@ -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: ] -- 2.7.4