summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/Extensions.rst35
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h12
-rw-r--r--include/llvm/MC/MCContext.h4
-rw-r--r--include/llvm/MC/MCSectionCOFF.h18
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h6
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp6
-rw-r--r--lib/CodeGen/TargetLoweringObjectFileImpl.cpp18
-rw-r--r--lib/MC/MCContext.cpp13
-rw-r--r--lib/MC/MCParser/COFFAsmParser.cpp52
-rw-r--r--lib/MC/MCSectionCOFF.cpp9
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp30
-rw-r--r--test/MC/COFF/global_ctors_dtors.ll4
-rw-r--r--test/MC/COFF/linkonce-invalid.s14
-rw-r--r--test/MC/COFF/linkonce.s29
-rw-r--r--test/MC/COFF/section-comdat-conflict.s13
-rw-r--r--test/MC/COFF/section-comdat-conflict2.s6
-rw-r--r--test/MC/COFF/section-comdat.s53
17 files changed, 138 insertions, 184 deletions
diff --git a/docs/Extensions.rst b/docs/Extensions.rst
index a49485cc5e..cd489c0e54 100644
--- a/docs/Extensions.rst
+++ b/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/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 9f1cbaa7a5..230d1ed51a 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/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/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index 7557e7629b..2f9b32b984 100644
--- a/include/llvm/MC/MCContext.h
+++ b/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/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index a428f9efb2..d205e2aebf 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/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/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 374a163800..419eced0a0 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/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/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index cb7cacbb00..9d822d3cb1 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/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/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index d349425815..02abc282e6 100644
--- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/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<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);
}
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index c16326829d..130bb99f98 100644
--- a/lib/MC/MCContext.cpp
+++ b/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/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp
index decf01c46c..8e8447f7b8 100644
--- a/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/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<COFF::COMDATType>(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<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");
diff --git a/lib/MC/MCSectionCOFF.cpp b/lib/MC/MCSectionCOFF.cpp
index 335b8cd612..fc2bd365e1 100644
--- a/lib/MC/MCSectionCOFF.cpp
+++ b/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/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp
index 961cbc6a8f..6f9c73b9cc 100644
--- a/lib/MC/WinCOFFObjectWriter.cpp
+++ b/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<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)
diff --git a/test/MC/COFF/global_ctors_dtors.ll b/test/MC/COFF/global_ctors_dtors.ll
index 735c493683..ca17f24a68 100644
--- a/test/MC/COFF/global_ctors_dtors.ll
+++ b/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/test/MC/COFF/linkonce-invalid.s b/test/MC/COFF/linkonce-invalid.s
index 90ce4a7ad3..cc3a27c903 100644
--- a/test/MC/COFF/linkonce-invalid.s
+++ b/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/test/MC/COFF/linkonce.s b/test/MC/COFF/linkonce.s
index e7b7f475a3..b6e81ad4b6 100644
--- a/test/MC/COFF/linkonce.s
+++ b/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/test/MC/COFF/section-comdat-conflict.s b/test/MC/COFF/section-comdat-conflict.s
new file mode 100644
index 0000000000..7ed452a5cd
--- /dev/null
+++ b/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/test/MC/COFF/section-comdat-conflict2.s b/test/MC/COFF/section-comdat-conflict2.s
new file mode 100644
index 0000000000..e2dfc2d68b
--- /dev/null
+++ b/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/test/MC/COFF/section-comdat.s b/test/MC/COFF/section-comdat.s
index dd5be871b0..a0ea7d0928 100644
--- a/test/MC/COFF/section-comdat.s
+++ b/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: ]