mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
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:
parent
5448320a20
commit
013321a0f9
@ -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
|
||||
=========================
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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,";
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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: }
|
||||
|
13
test/MC/COFF/section-comdat-conflict.s
Normal file
13
test/MC/COFF/section-comdat-conflict.s
Normal 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
|
6
test/MC/COFF/section-comdat-conflict2.s
Normal file
6
test/MC/COFF/section-comdat-conflict2.s
Normal 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
|
@ -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: ]
|
||||
|
Loading…
Reference in New Issue
Block a user