aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCObjectStreamer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC/MCObjectStreamer.cpp')
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp108
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,