diff options
Diffstat (limited to 'llvm/lib/MC/MCObjectStreamer.cpp')
-rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 108 |
1 files changed, 47 insertions, 61 deletions
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index d5b8f22..d7f4be1 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -33,6 +33,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 +47,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 +126,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()); @@ -180,7 +189,7 @@ void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { // 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(); + MCFragment *F = getCurrentFragment(); Symbol->setFragment(F); Symbol->setOffset(F->getContents().size()); @@ -214,10 +223,9 @@ void MCObjectStreamer::emitULEB128Value(const MCExpr *Value) { emitULEB128IntValue(IntValue); return; } - auto *F = getOrCreateDataFragment(); - F->Kind = MCFragment::FT_LEB; - F->setLEBSigned(false); - F->setLEBValue(Value); + auto *F = getCurrentFragment(); + F->makeLEB(false, Value); + newFragment(); } void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) { @@ -226,10 +234,9 @@ void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) { emitSLEB128IntValue(IntValue); return; } - auto *F = getOrCreateDataFragment(); - F->Kind = MCFragment::FT_LEB; - F->setLEBSigned(true); - F->setLEBValue(Value); + auto *F = getCurrentFragment(); + F->makeLEB(true, Value); + newFragment(); } void MCObjectStreamer::emitWeakReference(MCSymbol *Alias, @@ -238,11 +245,6 @@ 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(); @@ -261,7 +263,7 @@ bool MCObjectStreamer::changeSectionImpl(MCSection *Section, Section->CurFragList = &Subsections[I].second; CurFrag = Section->CurFragList->Tail; - return getAssembler().registerSection(*Section); + getAssembler().registerSection(*Section); } void MCObjectStreamer::switchSectionNoPrint(MCSection *Section) { @@ -293,18 +295,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(); @@ -338,7 +328,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(); @@ -370,7 +360,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); @@ -381,6 +371,7 @@ void MCObjectStreamer::emitInstToFragment(const MCInst &Inst, F->setVarContents(Data); F->setVarFixups(Fixups); F->setInst(Inst); + newFragment(); } void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line, @@ -442,10 +433,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, @@ -473,9 +465,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, @@ -534,7 +527,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())); } @@ -543,28 +536,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, |