#ifndef LLVM_MC_MCOBJECTSTREAMER_H
#define LLVM_MC_MCOBJECTSTREAMER_H
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCFragment.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
namespace llvm {
class MCContext;
class MCInst;
class MCObjectWriter;
class MCSymbol;
struct MCDwarfFrameInfo;
class MCAssembler;
class MCCodeEmitter;
class MCSubtargetInfo;
class MCExpr;
class MCFragment;
class MCDataFragment;
class MCAsmBackend;
class raw_ostream;
class raw_pwrite_stream;
class MCObjectStreamer : public MCStreamer {
std::unique_ptr<MCAssembler> Assembler;
MCSection::iterator CurInsertionPoint;
bool EmitEHFrame;
bool EmitDebugFrame;
SmallVector<MCSymbol *, 2> PendingLabels;
SmallSetVector<MCSection *, 4> PendingLabelSections;
unsigned CurSubsectionIdx;
struct PendingMCFixup {
const MCSymbol *Sym;
MCFixup Fixup;
MCDataFragment *DF;
PendingMCFixup(const MCSymbol *McSym, MCDataFragment *F, MCFixup McFixup)
: Sym(McSym), Fixup(McFixup), DF(F) {}
};
SmallVector<PendingMCFixup, 2> PendingFixups;
struct PendingAssignment {
MCSymbol *Symbol;
const MCExpr *Value;
};
DenseMap<const MCSymbol *, SmallVector<PendingAssignment, 1>>
pendingAssignments;
virtual void emitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
MCSymbol *emitCFILabel() override;
void emitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI);
void resolvePendingFixups();
protected:
MCObjectStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
std::unique_ptr<MCObjectWriter> OW,
std::unique_ptr<MCCodeEmitter> Emitter);
~MCObjectStreamer();
public:
void reset() override;
bool isIntegratedAssemblerRequired() const override { return true; }
void emitFrames(MCAsmBackend *MAB);
void emitCFISections(bool EH, bool Debug) override;
MCFragment *getCurrentFragment() const;
void insert(MCFragment *F) {
flushPendingLabels(F);
MCSection *CurSection = getCurrentSectionOnly();
CurSection->getFragmentList().insert(CurInsertionPoint, F);
F->setParent(CurSection);
}
MCDataFragment *getOrCreateDataFragment(const MCSubtargetInfo* STI = nullptr);
protected:
bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection);
void addPendingLabel(MCSymbol* label);
void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0);
public:
void visitUsedSymbol(const MCSymbol &Sym) override;
void flushPendingLabels();
MCAssembler &getAssembler() { return *Assembler; }
MCAssembler *getAssemblerPtr() override;
void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F,
uint64_t Offset);
void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
void emitConditionalAssignment(MCSymbol *Symbol,
const MCExpr *Value) override;
void emitValueImpl(const MCExpr *Value, unsigned Size,
SMLoc Loc = SMLoc()) override;
void emitULEB128Value(const MCExpr *Value) override;
void emitSLEB128Value(const MCExpr *Value) override;
void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
void changeSection(MCSection *Section, const MCExpr *Subsection) override;
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
virtual void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
void emitBundleAlignMode(unsigned AlignPow2) override;
void emitBundleLock(bool AlignToEnd) override;
void emitBundleUnlock() override;
void emitBytes(StringRef Data) override;
void emitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0) override;
void emitCodeAlignment(unsigned ByteAlignment, const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit = 0) override;
void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
SMLoc Loc) override;
void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
unsigned Flags, unsigned Isa,
unsigned Discriminator,
StringRef FileName) override;
void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
const MCSymbol *Label,
unsigned PointerSize) override;
void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override;
void emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
const MCSymbol *Label);
void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
unsigned Column, bool PrologueEnd, bool IsStmt,
StringRef FileName, SMLoc Loc) override;
void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin,
const MCSymbol *End) override;
void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
unsigned SourceFileId,
unsigned SourceLineNum,
const MCSymbol *FnStartSym,
const MCSymbol *FnEndSym) override;
void emitCVDefRangeDirective(
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
StringRef FixedSizePortion) override;
void emitCVStringTableDirective() override;
void emitCVFileChecksumsDirective() override;
void emitCVFileChecksumOffsetDirective(unsigned FileNo) override;
void emitDTPRel32Value(const MCExpr *Value) override;
void emitDTPRel64Value(const MCExpr *Value) override;
void emitTPRel32Value(const MCExpr *Value) override;
void emitTPRel64Value(const MCExpr *Value) override;
void emitGPRel32Value(const MCExpr *Value) override;
void emitGPRel64Value(const MCExpr *Value) override;
Optional<std::pair<bool, std::string>>
emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr,
SMLoc Loc, const MCSubtargetInfo &STI) override;
using MCStreamer::emitFill;
void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
SMLoc Loc = SMLoc()) override;
void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
SMLoc Loc = SMLoc()) override;
void emitNops(int64_t NumBytes, int64_t ControlledNopLength, SMLoc Loc,
const MCSubtargetInfo &STI) override;
void emitFileDirective(StringRef Filename) override;
void emitFileDirective(StringRef Filename, StringRef CompilerVerion,
StringRef TimeStamp, StringRef Description) override;
void emitAddrsig() override;
void emitAddrsigSym(const MCSymbol *Sym) override;
void finishImpl() override;
void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Size) override;
void emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
const MCSymbol *Lo) override;
bool mayHaveInstructions(MCSection &Sec) const override;
void emitPendingAssignments(MCSymbol *Symbol);
};
}
#endif