diff options
Diffstat (limited to 'clang-r353983/include/llvm/MC/MCObjectStreamer.h')
| -rw-r--r-- | clang-r353983/include/llvm/MC/MCObjectStreamer.h | 205 |
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 |
