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