summaryrefslogtreecommitdiff
path: root/clang-r353983/include/llvm/MC/MCObjectStreamer.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983/include/llvm/MC/MCObjectStreamer.h')
-rw-r--r--clang-r353983/include/llvm/MC/MCObjectStreamer.h205
1 files changed, 205 insertions, 0 deletions
diff --git a/clang-r353983/include/llvm/MC/MCObjectStreamer.h b/clang-r353983/include/llvm/MC/MCObjectStreamer.h
new file mode 100644
index 00000000..8affca49
--- /dev/null
+++ b/clang-r353983/include/llvm/MC/MCObjectStreamer.h
@@ -0,0 +1,205 @@
+//===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCOBJECTSTREAMER_H
+#define LLVM_MC_MCOBJECTSTREAMER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCStreamer.h"
+
+namespace llvm {
+class MCAssembler;
+class MCCodeEmitter;
+class MCSubtargetInfo;
+class MCExpr;
+class MCFragment;
+class MCDataFragment;
+class MCAsmBackend;
+class raw_ostream;
+class raw_pwrite_stream;
+
+/// Streaming object file generation interface.
+///
+/// This class provides an implementation of the MCStreamer interface which is
+/// suitable for use with the assembler backend. Specific object file formats
+/// are expected to subclass this interface to implement directives specific
+/// to that file format or custom semantics expected by the object writer
+/// implementation.
+class MCObjectStreamer : public MCStreamer {
+ std::unique_ptr<MCAssembler> Assembler;
+ MCSection::iterator CurInsertionPoint;
+ bool EmitEHFrame;
+ bool EmitDebugFrame;
+ SmallVector<MCSymbol *, 2> PendingLabels;
+ 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;
+
+ 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:
+ /// state management
+ void reset() override;
+
+ /// Object streamers require the integrated assembler.
+ 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);
+ }
+
+ /// Get a data fragment to write into, creating a new one if the current
+ /// fragment is not a data fragment.
+ /// Optionally a \p STI can be passed in so that a new fragment is created
+ /// if the Subtarget differs from the current fragment.
+ MCDataFragment *getOrCreateDataFragment(const MCSubtargetInfo* STI = nullptr);
+ MCPaddingFragment *getOrCreatePaddingFragment();
+
+protected:
+ bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection);
+
+ /// If any labels have been emitted but not assigned fragments, ensure that
+ /// they get assigned, either to F if possible or to a new data fragment.
+ /// Optionally, it is also possible to provide an offset \p FOffset, which
+ /// will be used as a symbol offset within the fragment.
+ void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0);
+
+public:
+ void visitUsedSymbol(const MCSymbol &Sym) override;
+
+ /// Create a dummy fragment to assign any pending labels.
+ void flushPendingLabels() { flushPendingLabels(nullptr); }
+
+ MCAssembler &getAssembler() { return *Assembler; }
+ MCAssembler *getAssemblerPtr() override;
+ /// \name MCStreamer Interface
+ /// @{
+
+ void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+ virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F);
+ void EmitAssignment(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;
+
+ /// Emit an instruction to a special fragment, because this instruction
+ /// can change its size during relaxation.
+ 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,
+ unsigned MaxBytesToEmit = 0) override;
+ void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
+ SMLoc Loc) override;
+ void
+ EmitCodePaddingBasicBlockStart(const MCCodePaddingContext &Context) override;
+ void
+ EmitCodePaddingBasicBlockEnd(const MCCodePaddingContext &Context) 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);
+ 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;
+ bool 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 EmitFileDirective(StringRef Filename) override;
+
+ void EmitAddrsig() override;
+ void EmitAddrsigSym(const MCSymbol *Sym) override;
+
+ void FinishImpl() override;
+
+ /// Emit the absolute difference between two symbols if possible.
+ ///
+ /// Emit the absolute difference between \c Hi and \c Lo, as long as we can
+ /// compute it. Currently, that requires that both symbols are in the same
+ /// data fragment and that the target has not specified that diff expressions
+ /// require relocations to be emitted. Otherwise, do nothing and return
+ /// \c false.
+ ///
+ /// \pre Offset of \c Hi is greater than the offset \c Lo.
+ 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;
+};
+
+} // end namespace llvm
+
+#endif