diff options
Diffstat (limited to 'lib/MC/MCELFStreamer.cpp')
-rw-r--r-- | lib/MC/MCELFStreamer.cpp | 57 |
1 files changed, 36 insertions, 21 deletions
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 7c70540..bdc4a84 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" @@ -38,19 +39,23 @@ using namespace llvm; MCELFStreamer::~MCELFStreamer() { } -void MCELFStreamer::InitSections() { +void MCELFStreamer::InitSections(bool NoExecStack) { // This emulates the same behavior of GNU as. This makes it easier // to compare the output as the major sections are in the same order. - SwitchSection(getContext().getObjectFileInfo()->getTextSection()); + MCContext &Ctx = getContext(); + SwitchSection(Ctx.getObjectFileInfo()->getTextSection()); EmitCodeAlignment(4); - SwitchSection(getContext().getObjectFileInfo()->getDataSection()); + SwitchSection(Ctx.getObjectFileInfo()->getDataSection()); EmitCodeAlignment(4); - SwitchSection(getContext().getObjectFileInfo()->getBSSSection()); + SwitchSection(Ctx.getObjectFileInfo()->getBSSSection()); EmitCodeAlignment(4); - SwitchSection(getContext().getObjectFileInfo()->getTextSection()); + SwitchSection(Ctx.getObjectFileInfo()->getTextSection()); + + if (NoExecStack) + SwitchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx)); } void MCELFStreamer::EmitLabel(MCSymbol *Symbol) { @@ -87,10 +92,19 @@ void MCELFStreamer::ChangeSection(const MCSection *Section, MCSectionData *CurSection = getCurrentSectionData(); if (CurSection && CurSection->isBundleLocked()) report_fatal_error("Unterminated .bundle_lock when changing a section"); - const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup(); + + MCAssembler &Asm = getAssembler(); + auto *SectionELF = static_cast<const MCSectionELF *>(Section); + const MCSymbol *Grp = SectionELF->getGroup(); if (Grp) - getAssembler().getOrCreateSymbolData(*Grp); + Asm.getOrCreateSymbolData(*Grp); + this->MCObjectStreamer::ChangeSection(Section, Subsection); + MCSymbol *SectionSymbol = getContext().getOrCreateSectionSymbol(*SectionELF); + if (SectionSymbol->isUndefined()) { + EmitLabel(SectionSymbol); + MCELF::SetType(Asm.getSymbolData(*SectionSymbol), ELF::STT_SECTION); + } } void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { @@ -448,11 +462,13 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst, } else { DF = new MCDataFragment(); insert(DF); - if (SD->getBundleLockState() == MCSectionData::BundleLockedAlignToEnd) { - // If this is a new fragment created for a bundle-locked group, and the - // group was marked as "align_to_end", set a flag in the fragment. - DF->setAlignToBundleEnd(true); - } + } + if (SD->getBundleLockState() == MCSectionData::BundleLockedAlignToEnd) { + // If this fragment is for a group marked "align_to_end", set a flag + // in the fragment. This can happen after the fragment has already been + // created if there are nested bundle_align groups and an inner one + // is the one marked align_to_end. + DF->setAlignToBundleEnd(true); } // We're now emitting an instruction in a bundle group, so this flag has @@ -474,10 +490,11 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst, void MCELFStreamer::EmitBundleAlignMode(unsigned AlignPow2) { assert(AlignPow2 <= 30 && "Invalid bundle alignment"); MCAssembler &Assembler = getAssembler(); - if (Assembler.getBundleAlignSize() == 0 && AlignPow2 > 0) - Assembler.setBundleAlignSize(1 << AlignPow2); + if (AlignPow2 > 0 && (Assembler.getBundleAlignSize() == 0 || + Assembler.getBundleAlignSize() == 1U << AlignPow2)) + Assembler.setBundleAlignSize(1U << AlignPow2); else - report_fatal_error(".bundle_align_mode should be only set once per file"); + report_fatal_error(".bundle_align_mode cannot be changed once set"); } void MCELFStreamer::EmitBundleLock(bool AlignToEnd) { @@ -487,12 +504,12 @@ void MCELFStreamer::EmitBundleLock(bool AlignToEnd) { // if (!getAssembler().isBundlingEnabled()) report_fatal_error(".bundle_lock forbidden when bundling is disabled"); - else if (SD->isBundleLocked()) - report_fatal_error("Nesting of .bundle_lock is forbidden"); + + if (!SD->isBundleLocked()) + SD->setBundleGroupBeforeFirstInst(true); SD->setBundleLockState(AlignToEnd ? MCSectionData::BundleLockedAlignToEnd : MCSectionData::BundleLocked); - SD->setBundleGroupBeforeFirstInst(true); } void MCELFStreamer::EmitBundleUnlock() { @@ -543,12 +560,10 @@ void MCELFStreamer::FinishImpl() { MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *CE, - bool RelaxAll, bool NoExecStack) { + bool RelaxAll) { MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE); if (RelaxAll) S->getAssembler().setRelaxAll(true); - if (NoExecStack) - S->getAssembler().setNoExecStack(true); return S; } |