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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210367 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2014-06-06 19:26:12 +00:00
parent 5448320a20
commit 013321a0f9
17 changed files with 138 additions and 184 deletions

View File

@ -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
=========================

View File

@ -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

View File

@ -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,

View File

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

View File

@ -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;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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,";

View File

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

View File

@ -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"

View File

@ -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

View File

@ -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: }

View File

@ -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

View File

@ -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

View File

@ -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: ]