X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMCELFStreamer.cpp;h=47d14868600187cd4898cf0432ffc484d78258fa;hb=ed0266d8ee16537e7cec9d9409ddf07a8e3efbc5;hp=d07ef9e698ec1f4cf44ee7a97d247be89015e66a;hpb=0a70f9b3b9b4a8cb92f187ea0563c1a2ac784e6e;p=oota-llvm.git diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index d07ef9e698e..47d14868600 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) { @@ -65,10 +70,6 @@ void MCELFStreamer::EmitLabel(MCSymbol *Symbol) { MCELF::SetType(SD, ELF::STT_TLS); } -void MCELFStreamer::EmitDebugLabel(MCSymbol *Symbol) { - EmitLabel(Symbol); -} - void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { // Let the target do whatever target specific stuff it needs to do. getAssembler().getBackend().handleAssemblerFlag(Flag); @@ -91,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(Section)->getGroup(); + + MCAssembler &Asm = getAssembler(); + auto *SectionELF = static_cast(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) { @@ -112,12 +122,11 @@ void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { // If neither T1 < T2 nor T2 < T1 according to this ordering, use T2 (the user // provided type). static unsigned CombineSymbolTypes(unsigned T1, unsigned T2) { - unsigned TypeOrdering[] = {ELF::STT_NOTYPE, ELF::STT_OBJECT, ELF::STT_FUNC, - ELF::STT_GNU_IFUNC, ELF::STT_TLS}; - for (unsigned i = 0; i != array_lengthof(TypeOrdering); ++i) { - if (T1 == TypeOrdering[i]) + for (unsigned Type : {ELF::STT_NOTYPE, ELF::STT_OBJECT, ELF::STT_FUNC, + ELF::STT_GNU_IFUNC, ELF::STT_TLS}) { + if (T1 == Type) return T2; - if (T2 == TypeOrdering[i]) + if (T2 == Type) return T1; } @@ -161,10 +170,16 @@ bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, return false; case MCSA_NoDeadStrip: - case MCSA_ELF_TypeGnuUniqueObject: // Ignore for now. break; + case MCSA_ELF_TypeGnuUniqueObject: + MCELF::SetType(SD, CombineSymbolTypes(MCELF::GetType(SD), ELF::STT_OBJECT)); + MCELF::SetBinding(SD, ELF::STB_GNU_UNIQUE); + SD.setExternal(true); + BindingExplicitlySet.insert(Symbol); + break; + case MCSA_Global: MCELF::SetBinding(SD, ELF::STB_GLOBAL); SD.setExternal(true); @@ -243,11 +258,8 @@ void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, MCELF::SetType(SD, ELF::STT_OBJECT); if (MCELF::GetBinding(SD) == ELF_STB_Local) { - const MCSection *Section = getAssembler().getContext().getELFSection(".bss", - ELF::SHT_NOBITS, - ELF::SHF_WRITE | - ELF::SHF_ALLOC, - SectionKind::getBSS()); + const MCSection *Section = getAssembler().getContext().getELFSection( + ".bss", ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); AssignSection(Symbol, Section); @@ -275,11 +287,12 @@ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, EmitCommonSymbol(Symbol, Size, ByteAlignment); } -void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { +void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) { if (getCurrentSectionData()->isBundleLocked()) report_fatal_error("Emitting values inside a locked bundle is forbidden"); fixSymbolsInTLSFixups(Value); - MCObjectStreamer::EmitValueImpl(Value, Size); + MCObjectStreamer::EmitValueImpl(Value, Size, Loc); } void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, @@ -301,8 +314,7 @@ void MCELFStreamer::EmitFileDirective(StringRef Filename) { void MCELFStreamer::EmitIdent(StringRef IdentString) { const MCSection *Comment = getAssembler().getContext().getELFSection( - ".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, - SectionKind::getReadOnly(), 1, ""); + ".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); PushSection(); SwitchSection(Comment); if (!SeenIdent) { @@ -451,11 +463,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 @@ -477,10 +491,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) { @@ -490,12 +505,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() { @@ -537,7 +552,7 @@ void MCELFStreamer::Flush() { } void MCELFStreamer::FinishImpl() { - EmitFrames(NULL, true); + EmitFrames(nullptr); Flush(); @@ -546,12 +561,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; } @@ -559,10 +572,6 @@ void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { llvm_unreachable("Generic ELF doesn't support this directive"); } -MCSymbolData &MCELFStreamer::getOrCreateSymbolData(MCSymbol *Symbol) { - return getAssembler().getOrCreateSymbolData(*Symbol); -} - void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { llvm_unreachable("ELF doesn't support this directive"); }