18dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- C++ -*-===// 28dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// 38dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// The LLVM Compiler Infrastructure 48dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// 58dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// This file is distributed under the University of Illinois Open Source 68dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// License. See LICENSE.TXT for details. 78dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// 88dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//===----------------------------------------------------------------------===// 98dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 108dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#ifndef LLVM_MC_MCOBJECTSTREAMER_H 118dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#define LLVM_MC_MCOBJECTSTREAMER_H 128dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 1337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/ADT/SmallVector.h" 14df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne#include "llvm/MC/MCAssembler.h" 156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/MC/MCSection.h" 168dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#include "llvm/MC/MCStreamer.h" 178dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 188dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarnamespace llvm { 198dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarclass MCAssembler; 208dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarclass MCCodeEmitter; 2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass MCSubtargetInfo; 228067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencerclass MCExpr; 238067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencerclass MCFragment; 248067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencerclass MCDataFragment; 2578c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Chengclass MCAsmBackend; 268dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarclass raw_ostream; 270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarclass raw_pwrite_stream; 288dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 298dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// \brief Streaming object file generation interface. 308dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// 318dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// This class provides an implementation of the MCStreamer interface which is 328dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// suitable for use with the assembler backend. Specific object file formats 338dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// are expected to subclass this interface to implement directives specific 348dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// to that file format or custom semantics expected by the object writer 358dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// implementation. 368dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarclass MCObjectStreamer : public MCStreamer { 378dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar MCAssembler *Assembler; 386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSection::iterator CurInsertionPoint; 39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool EmitEHFrame; 40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool EmitDebugFrame; 416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVector<MCSymbol *, 2> PendingLabels; 428dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0; 4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; 4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; 46f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 478dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarprotected: 480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS, 494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCCodeEmitter *Emitter); 500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar ~MCObjectStreamer() override; 518dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 525399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigaspublic: 535399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigas /// state management 5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void reset() override; 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Object streamers require the integrated assembler. 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isIntegratedAssemblerRequired() const override { return true; } 585399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigas 59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void EmitFrames(MCAsmBackend *MAB); 60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void EmitCFISections(bool EH, bool Debug) override; 61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 628067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer MCFragment *getCurrentFragment() const; 638067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 6437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void insert(MCFragment *F) { 6537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines flushPendingLabels(F); 666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSection *CurSection = getCurrentSectionOnly(); 676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar CurSection->getFragmentList().insert(CurInsertionPoint, F); 686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar F->setParent(CurSection); 69df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne } 70df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne 718067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer /// Get a data fragment to write into, creating a new one if the current 728067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer /// fragment is not a data fragment. 7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MCDataFragment *getOrCreateDataFragment(); 748067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 75de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarprotected: 766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection); 774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar /// If any labels have been emitted but not assigned fragments, ensure that 790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar /// they get assigned, either to F if possible or to a new data fragment. 800c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar /// Optionally, it is also possible to provide an offset \p FOffset, which 810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar /// will be used as a symbol offset within the fragment. 820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0); 830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 848dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarpublic: 85c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines void visitUsedSymbol(const MCSymbol &Sym) override; 86c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 878dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar MCAssembler &getAssembler() { return *Assembler; } 8883b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar 896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// \name MCStreamer Interface 9083b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar /// @{ 9183b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitLabel(MCSymbol *Symbol) override; 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; 94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void EmitValueImpl(const MCExpr *Value, unsigned Size, 95f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SMLoc Loc = SMLoc()) override; 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitULEB128Value(const MCExpr *Value) override; 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitSLEB128Value(const MCExpr *Value) override; 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; 996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void ChangeSection(MCSection *Section, const MCExpr *Subsection) override; 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo& STI) override; 1014766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky 1024766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky /// \brief Emit an instruction to a special fragment, because this instruction 1034766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky /// can change its size during relaxation. 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines virtual void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &); 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitBundleAlignMode(unsigned AlignPow2) override; 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitBundleLock(bool AlignToEnd) override; 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitBundleUnlock() override; 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitBytes(StringRef Data) override; 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ValueSize = 1, 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned MaxBytesToEmit = 0) override; 11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitCodeAlignment(unsigned ByteAlignment, 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned MaxBytesToEmit = 0) override; 115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void emitValueToOffset(const MCExpr *Offset, unsigned char Value) override; 11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Column, unsigned Flags, 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Isa, unsigned Discriminator, 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef FileName) override; 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, 12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSymbol *Label, 122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned PointerSize); 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCSymbol *Label); 125de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, 126de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned Column, bool PrologueEnd, bool IsStmt, 127de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StringRef FileName) override; 128de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void EmitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin, 129de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const MCSymbol *End) override; 130de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void EmitCVInlineLinetableDirective( 131de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, 132de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar const MCSymbol *FnStartSym, const MCSymbol *FnEndSym, 133de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ArrayRef<unsigned> SecondaryFunctionIds) override; 134de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void EmitCVDefRangeDirective( 135de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, 136de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar StringRef FixedSizePortion) override; 137de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void EmitCVStringTableDirective() override; 138de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void EmitCVFileChecksumsDirective() override; 13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitGPRel32Value(const MCExpr *Value) override; 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitGPRel64Value(const MCExpr *Value) override; 141f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool EmitRelocDirective(const MCExpr &Offset, StringRef Name, 142f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCExpr *Expr, SMLoc Loc) override; 143de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar using MCStreamer::emitFill; 144de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void emitFill(uint64_t NumBytes, uint8_t FillValue) override; 145de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void emitFill(const MCExpr &NumBytes, uint64_t FillValue, 146de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SMLoc Loc = SMLoc()) override; 147de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr, 148de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SMLoc Loc = SMLoc()) override; 149de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void FinishImpl() override; 151c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines 1526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// Emit the absolute difference between two symbols if possible. 1536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// 1546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// Emit the absolute difference between \c Hi and \c Lo, as long as we can 1556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// compute it. Currently, that requires that both symbols are in the same 1566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// data fragment. Otherwise, do nothing and return \c false. 1576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// 1586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// \pre Offset of \c Hi is greater than the offset \c Lo. 1596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, 1606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Size) override; 1616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool mayHaveInstructions(MCSection &Sec) const override; 1638dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar}; 1648dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 1658dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar} // end namespace llvm 1668dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 1678dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#endif 168