diff options
Diffstat (limited to 'llvm/lib/MC/MCObjectStreamer.cpp')
-rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 125 |
1 files changed, 61 insertions, 64 deletions
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index f61dda6..f046552 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -19,7 +19,6 @@ #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SourceMgr.h" using namespace llvm; @@ -33,6 +32,7 @@ MCObjectStreamer::MCObjectStreamer(MCContext &Context, Context, std::move(TAB), std::move(Emitter), std::move(OW))), EmitEHFrame(true), EmitDebugFrame(false) { assert(Assembler->getBackendPtr() && Assembler->getEmitterPtr()); + IsObj = true; setAllowAutoPadding(Assembler->getBackend().allowAutoPadding()); if (Context.getTargetOptions() && Context.getTargetOptions()->MCRelaxAll) Assembler->setRelaxAll(true); @@ -46,6 +46,25 @@ MCAssembler *MCObjectStreamer::getAssemblerPtr() { return nullptr; } +void MCObjectStreamer::newFragment() { + addFragment(getContext().allocFragment<MCFragment>()); +} + +void MCObjectStreamer::insert(MCFragment *F) { + assert(F->getKind() != MCFragment::FT_Data && + "F should have a variable-size tail"); + addFragment(F); + newFragment(); +} + +void MCObjectStreamer::appendContents(size_t Num, char Elt) { + CurFrag->appendContents(Num, Elt); +} + +void MCObjectStreamer::addFixup(const MCExpr *Value, MCFixupKind Kind) { + CurFrag->addFixup(MCFixup::create(CurFrag->getFixedSize(), Value, Kind)); +} + // As a compile-time optimization, avoid allocating and evaluating an MCExpr // tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment's fixed // part. @@ -106,32 +125,21 @@ void MCObjectStreamer::emitFrames(MCAsmBackend *MAB) { MCDwarfFrameEmitter::Emit(*this, MAB, false); } -MCFragment *MCObjectStreamer::getOrCreateDataFragment() { - // TODO: Start a new fragment whenever finalizing the variable-size tail of a - // previous one, so that all getOrCreateDataFragment calls can be replaced - // with getCurrentFragment - auto *F = getCurrentFragment(); - if (F->getKind() != MCFragment::FT_Data) { - F = getContext().allocFragment<MCFragment>(); - insert(F); - } - return F; -} - void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) { Assembler->registerSymbol(Sym); } -void MCObjectStreamer::emitCFISections(bool EH, bool Debug) { - MCStreamer::emitCFISections(EH, Debug); +void MCObjectStreamer::emitCFISections(bool EH, bool Debug, bool SFrame) { + MCStreamer::emitCFISections(EH, Debug, SFrame); EmitEHFrame = EH; EmitDebugFrame = Debug; + EmitSFrame = SFrame; } void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) { MCStreamer::emitValueImpl(Value, Size, Loc); - MCFragment *DF = getOrCreateDataFragment(); + MCFragment *DF = getCurrentFragment(); MCDwarfLineEntry::make(this, getCurrentSectionOnly()); @@ -177,10 +185,10 @@ void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { getAssembler().registerSymbol(*Symbol); - // If there is a current fragment, mark the symbol as pointing into it. - // Otherwise queue the label and set its fragment pointer when we emit the - // next fragment. - MCFragment *F = getOrCreateDataFragment(); + // Set the fragment and offset. This function might be called by + // changeSection, when the section stack top hasn't been changed to the new + // section. + MCFragment *F = CurFrag; Symbol->setFragment(F); Symbol->setOffset(F->getContents().size()); @@ -214,7 +222,7 @@ void MCObjectStreamer::emitULEB128Value(const MCExpr *Value) { emitULEB128IntValue(IntValue); return; } - auto *F = getOrCreateDataFragment(); + auto *F = getCurrentFragment(); F->makeLEB(false, Value); newFragment(); } @@ -225,7 +233,7 @@ void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) { emitSLEB128IntValue(IntValue); return; } - auto *F = getOrCreateDataFragment(); + auto *F = getCurrentFragment(); F->makeLEB(true, Value); newFragment(); } @@ -236,14 +244,18 @@ void MCObjectStreamer::emitWeakReference(MCSymbol *Alias, } void MCObjectStreamer::changeSection(MCSection *Section, uint32_t Subsection) { - changeSectionImpl(Section, Subsection); -} - -bool MCObjectStreamer::changeSectionImpl(MCSection *Section, - uint32_t Subsection) { assert(Section && "Cannot switch to a null section!"); getContext().clearDwarfLocSeen(); + // Register the section and create an initial fragment for subsection 0 + // if `Subsection` is non-zero. + bool NewSec = getAssembler().registerSection(*Section); + MCFragment *F0 = nullptr; + if (NewSec && Subsection) { + changeSection(Section, 0); + F0 = CurFrag; + } + auto &Subsections = Section->Subsections; size_t I = 0, E = Subsections.size(); while (I != E && Subsections[I].first < Subsection) @@ -259,12 +271,13 @@ bool MCObjectStreamer::changeSectionImpl(MCSection *Section, Section->CurFragList = &Subsections[I].second; CurFrag = Section->CurFragList->Tail; - return getAssembler().registerSection(*Section); -} - -void MCObjectStreamer::switchSectionNoPrint(MCSection *Section) { - MCStreamer::switchSectionNoPrint(Section); - changeSection(Section, 0); + // Define the section symbol at subsection 0's initial fragment if required. + if (!NewSec) + return; + if (auto *Sym = Section->getBeginSymbol()) { + Sym->setFragment(Subsection ? F0 : CurFrag); + getAssembler().registerSymbol(*Sym); + } } void MCObjectStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) { @@ -291,18 +304,6 @@ bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { void MCObjectStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { - const MCSection &Sec = *getCurrentSectionOnly(); - if (Sec.isVirtualSection()) { - getContext().reportError(Inst.getLoc(), Twine(Sec.getVirtualSectionKind()) + - " section '" + Sec.getName() + - "' cannot have instructions"); - return; - } - emitInstructionImpl(Inst, STI); -} - -void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst, - const MCSubtargetInfo &STI) { MCStreamer::emitInstruction(Inst, STI); MCSection *Sec = getCurrentSectionOnly(); @@ -336,7 +337,7 @@ void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst, void MCObjectStreamer::emitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) { - MCFragment *F = getOrCreateDataFragment(); + MCFragment *F = getCurrentFragment(); // Append the instruction to the data fragment. size_t FixupStartIndex = F->getFixups().size(); @@ -368,7 +369,7 @@ void MCObjectStreamer::emitInstToData(const MCInst &Inst, void MCObjectStreamer::emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &STI) { - auto *F = getOrCreateDataFragment(); + auto *F = getCurrentFragment(); SmallVector<char, 16> Data; SmallVector<MCFixup, 1> Fixups; getAssembler().getEmitter().encodeInstruction(Inst, Data, Fixups, STI); @@ -379,6 +380,7 @@ void MCObjectStreamer::emitInstToFragment(const MCInst &Inst, F->setVarContents(Data); F->setVarFixups(Fixups); F->setInst(Inst); + newFragment(); } void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line, @@ -440,10 +442,11 @@ void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta, return; } - auto *F = getOrCreateDataFragment(); + auto *F = getCurrentFragment(); F->Kind = MCFragment::FT_Dwarf; F->setDwarfAddrDelta(buildSymbolDiff(*this, Label, LastLabel, SMLoc())); F->setDwarfLineDelta(LineDelta); + newFragment(); } void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section, @@ -471,9 +474,10 @@ void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section, void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label, SMLoc Loc) { - auto *F = getOrCreateDataFragment(); + auto *F = getCurrentFragment(); F->Kind = MCFragment::FT_DwarfFrame; F->setDwarfAddrDelta(buildSymbolDiff(*this, Label, LastLabel, Loc)); + newFragment(); } void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo, @@ -532,7 +536,7 @@ void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) { void MCObjectStreamer::emitBytes(StringRef Data) { MCDwarfLineEntry::make(this, getCurrentSectionOnly()); - MCFragment *DF = getOrCreateDataFragment(); + MCFragment *DF = getCurrentFragment(); DF->appendContents(ArrayRef(Data.data(), Data.size())); } @@ -541,28 +545,21 @@ void MCObjectStreamer::emitValueToAlignment(Align Alignment, int64_t Fill, unsigned MaxBytesToEmit) { if (MaxBytesToEmit == 0) MaxBytesToEmit = Alignment.value(); - insert(getContext().allocFragment<MCAlignFragment>(Alignment, Fill, FillLen, - MaxBytesToEmit)); + MCFragment *F = getCurrentFragment(); + F->makeAlign(Alignment, Fill, FillLen, MaxBytesToEmit); + newFragment(); // Update the maximum alignment on the current section if necessary. - MCSection *CurSec = getCurrentSectionOnly(); - CurSec->ensureMinAlignment(Alignment); + F->getParent()->ensureMinAlignment(Alignment); } void MCObjectStreamer::emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit) { + auto *F = getCurrentFragment(); emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit); - auto *F = cast<MCAlignFragment>(getCurrentFragment()); - F->setEmitNops(true, STI); - // With RISC-V style linker relaxation, mark the section as linker-relaxable - // if the alignment is larger than the minimum NOP size. - unsigned Size; - if (getAssembler().getBackend().shouldInsertExtraNopBytesForCodeAlign(*F, - Size)) { - getCurrentSectionOnly()->setLinkerRelaxable(); - newFragment(); - } + F->u.align.EmitNops = true; + F->STI = STI; } void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset, |