10b57cec5SDimitry Andric //===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLVM_MC_MCOBJECTSTREAMER_H 100b57cec5SDimitry Andric #define LLVM_MC_MCOBJECTSTREAMER_H 110b57cec5SDimitry Andric 125ffd83dbSDimitry Andric #include "llvm/ADT/SetVector.h" 130b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 1481ad6265SDimitry Andric #include "llvm/MC/MCFixup.h" 1581ad6265SDimitry Andric #include "llvm/MC/MCFragment.h" 160b57cec5SDimitry Andric #include "llvm/MC/MCSection.h" 170b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric namespace llvm { 2081ad6265SDimitry Andric class MCContext; 2181ad6265SDimitry Andric class MCInst; 2281ad6265SDimitry Andric class MCObjectWriter; 2381ad6265SDimitry Andric class MCSymbol; 2481ad6265SDimitry Andric struct MCDwarfFrameInfo; 250b57cec5SDimitry Andric class MCAssembler; 260b57cec5SDimitry Andric class MCCodeEmitter; 270b57cec5SDimitry Andric class MCSubtargetInfo; 280b57cec5SDimitry Andric class MCExpr; 290b57cec5SDimitry Andric class MCFragment; 300b57cec5SDimitry Andric class MCDataFragment; 310b57cec5SDimitry Andric class MCAsmBackend; 320b57cec5SDimitry Andric class raw_ostream; 330b57cec5SDimitry Andric class raw_pwrite_stream; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric /// Streaming object file generation interface. 360b57cec5SDimitry Andric /// 370b57cec5SDimitry Andric /// This class provides an implementation of the MCStreamer interface which is 380b57cec5SDimitry Andric /// suitable for use with the assembler backend. Specific object file formats 390b57cec5SDimitry Andric /// are expected to subclass this interface to implement directives specific 400b57cec5SDimitry Andric /// to that file format or custom semantics expected by the object writer 410b57cec5SDimitry Andric /// implementation. 420b57cec5SDimitry Andric class MCObjectStreamer : public MCStreamer { 430b57cec5SDimitry Andric std::unique_ptr<MCAssembler> Assembler; 440b57cec5SDimitry Andric MCSection::iterator CurInsertionPoint; 450b57cec5SDimitry Andric bool EmitEHFrame; 460b57cec5SDimitry Andric bool EmitDebugFrame; 470b57cec5SDimitry Andric SmallVector<MCSymbol *, 2> PendingLabels; 485ffd83dbSDimitry Andric SmallSetVector<MCSection *, 4> PendingLabelSections; 4906c3fb27SDimitry Andric unsigned CurSubsectionIdx = 0; 500b57cec5SDimitry Andric struct PendingMCFixup { 510b57cec5SDimitry Andric const MCSymbol *Sym; 520b57cec5SDimitry Andric MCFixup Fixup; 530b57cec5SDimitry Andric MCDataFragment *DF; PendingMCFixupPendingMCFixup540b57cec5SDimitry Andric PendingMCFixup(const MCSymbol *McSym, MCDataFragment *F, MCFixup McFixup) 550b57cec5SDimitry Andric : Sym(McSym), Fixup(McFixup), DF(F) {} 560b57cec5SDimitry Andric }; 570b57cec5SDimitry Andric SmallVector<PendingMCFixup, 2> PendingFixups; 580b57cec5SDimitry Andric 590eae32dcSDimitry Andric struct PendingAssignment { 600eae32dcSDimitry Andric MCSymbol *Symbol; 610eae32dcSDimitry Andric const MCExpr *Value; 620eae32dcSDimitry Andric }; 630eae32dcSDimitry Andric 640eae32dcSDimitry Andric /// A list of conditional assignments we may need to emit if the target 650eae32dcSDimitry Andric /// symbol is later emitted. 660eae32dcSDimitry Andric DenseMap<const MCSymbol *, SmallVector<PendingAssignment, 1>> 670eae32dcSDimitry Andric pendingAssignments; 680eae32dcSDimitry Andric 695ffd83dbSDimitry Andric virtual void emitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0; 705ffd83dbSDimitry Andric void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; 715ffd83dbSDimitry Andric void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; 725ffd83dbSDimitry Andric MCSymbol *emitCFILabel() override; 735ffd83dbSDimitry Andric void emitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI); 740b57cec5SDimitry Andric void resolvePendingFixups(); 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric protected: 770b57cec5SDimitry Andric MCObjectStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB, 780b57cec5SDimitry Andric std::unique_ptr<MCObjectWriter> OW, 790b57cec5SDimitry Andric std::unique_ptr<MCCodeEmitter> Emitter); 800b57cec5SDimitry Andric ~MCObjectStreamer(); 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric public: 830b57cec5SDimitry Andric /// state management 840b57cec5SDimitry Andric void reset() override; 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric /// Object streamers require the integrated assembler. isIntegratedAssemblerRequired()870b57cec5SDimitry Andric bool isIntegratedAssemblerRequired() const override { return true; } 880b57cec5SDimitry Andric 895ffd83dbSDimitry Andric void emitFrames(MCAsmBackend *MAB); 905ffd83dbSDimitry Andric void emitCFISections(bool EH, bool Debug) override; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric MCFragment *getCurrentFragment() const; 930b57cec5SDimitry Andric insert(MCFragment * F)940b57cec5SDimitry Andric void insert(MCFragment *F) { 950b57cec5SDimitry Andric flushPendingLabels(F); 960b57cec5SDimitry Andric MCSection *CurSection = getCurrentSectionOnly(); 970b57cec5SDimitry Andric CurSection->getFragmentList().insert(CurInsertionPoint, F); 980b57cec5SDimitry Andric F->setParent(CurSection); 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric /// Get a data fragment to write into, creating a new one if the current 1020b57cec5SDimitry Andric /// fragment is not a data fragment. 1030b57cec5SDimitry Andric /// Optionally a \p STI can be passed in so that a new fragment is created 1040b57cec5SDimitry Andric /// if the Subtarget differs from the current fragment. 1050b57cec5SDimitry Andric MCDataFragment *getOrCreateDataFragment(const MCSubtargetInfo* STI = nullptr); 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric protected: 1080b57cec5SDimitry Andric bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection); 1090b57cec5SDimitry Andric 110480093f4SDimitry Andric /// Assign a label to the current Section and Subsection even though a 111480093f4SDimitry Andric /// fragment is not yet present. Use flushPendingLabels(F) to associate 112480093f4SDimitry Andric /// a fragment with this label. 113480093f4SDimitry Andric void addPendingLabel(MCSymbol* label); 114480093f4SDimitry Andric 115480093f4SDimitry Andric /// If any labels have been emitted but not assigned fragments in the current 11606c3fb27SDimitry Andric /// Section and Subsection, ensure that they get assigned to fragment F. 11706c3fb27SDimitry Andric /// Optionally, one can provide an offset \p FOffset as a symbol offset within 11806c3fb27SDimitry Andric /// the fragment. 1190b57cec5SDimitry Andric void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0); 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric public: 1220b57cec5SDimitry Andric void visitUsedSymbol(const MCSymbol &Sym) override; 1230b57cec5SDimitry Andric 124480093f4SDimitry Andric /// Create a data fragment for any pending labels across all Sections 125480093f4SDimitry Andric /// and Subsections. 126480093f4SDimitry Andric void flushPendingLabels(); 1270b57cec5SDimitry Andric getAssembler()1280b57cec5SDimitry Andric MCAssembler &getAssembler() { return *Assembler; } 1290b57cec5SDimitry Andric MCAssembler *getAssemblerPtr() override; 1300b57cec5SDimitry Andric /// \name MCStreamer Interface 1310b57cec5SDimitry Andric /// @{ 1320b57cec5SDimitry Andric 1335ffd83dbSDimitry Andric void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; 1345ffd83dbSDimitry Andric virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F, 135480093f4SDimitry Andric uint64_t Offset); 1365ffd83dbSDimitry Andric void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; 1370eae32dcSDimitry Andric void emitConditionalAssignment(MCSymbol *Symbol, 1380eae32dcSDimitry Andric const MCExpr *Value) override; 1395ffd83dbSDimitry Andric void emitValueImpl(const MCExpr *Value, unsigned Size, 1400b57cec5SDimitry Andric SMLoc Loc = SMLoc()) override; 1415ffd83dbSDimitry Andric void emitULEB128Value(const MCExpr *Value) override; 1425ffd83dbSDimitry Andric void emitSLEB128Value(const MCExpr *Value) override; 1435ffd83dbSDimitry Andric void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; 1445ffd83dbSDimitry Andric void changeSection(MCSection *Section, const MCExpr *Subsection) override; 1455ffd83dbSDimitry Andric void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric /// Emit an instruction to a special fragment, because this instruction 1480b57cec5SDimitry Andric /// can change its size during relaxation. 1495ffd83dbSDimitry Andric virtual void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &); 1500b57cec5SDimitry Andric 151bdd1243dSDimitry Andric void emitBundleAlignMode(Align Alignment) override; 1525ffd83dbSDimitry Andric void emitBundleLock(bool AlignToEnd) override; 1535ffd83dbSDimitry Andric void emitBundleUnlock() override; 1545ffd83dbSDimitry Andric void emitBytes(StringRef Data) override; 155bdd1243dSDimitry Andric void emitValueToAlignment(Align Alignment, int64_t Value = 0, 1560b57cec5SDimitry Andric unsigned ValueSize = 1, 1570b57cec5SDimitry Andric unsigned MaxBytesToEmit = 0) override; 158bdd1243dSDimitry Andric void emitCodeAlignment(Align ByteAlignment, const MCSubtargetInfo *STI, 1590b57cec5SDimitry Andric unsigned MaxBytesToEmit = 0) override; 1600b57cec5SDimitry Andric void emitValueToOffset(const MCExpr *Offset, unsigned char Value, 1610b57cec5SDimitry Andric SMLoc Loc) override; 1625ffd83dbSDimitry Andric void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, 1635ffd83dbSDimitry Andric unsigned Flags, unsigned Isa, 1645ffd83dbSDimitry Andric unsigned Discriminator, 1650b57cec5SDimitry Andric StringRef FileName) override; 1665ffd83dbSDimitry Andric void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, 167fe6060f1SDimitry Andric const MCSymbol *Label, 168fe6060f1SDimitry Andric unsigned PointerSize) override; 169fe6060f1SDimitry Andric void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override; 1705ffd83dbSDimitry Andric void emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 17106c3fb27SDimitry Andric const MCSymbol *Label, SMLoc Loc); 1725ffd83dbSDimitry Andric void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, 1730b57cec5SDimitry Andric unsigned Column, bool PrologueEnd, bool IsStmt, 1740b57cec5SDimitry Andric StringRef FileName, SMLoc Loc) override; 1755ffd83dbSDimitry Andric void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin, 1760b57cec5SDimitry Andric const MCSymbol *End) override; 1775ffd83dbSDimitry Andric void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId, 1780b57cec5SDimitry Andric unsigned SourceFileId, 1790b57cec5SDimitry Andric unsigned SourceLineNum, 1800b57cec5SDimitry Andric const MCSymbol *FnStartSym, 1810b57cec5SDimitry Andric const MCSymbol *FnEndSym) override; 1825ffd83dbSDimitry Andric void emitCVDefRangeDirective( 1830b57cec5SDimitry Andric ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, 1840b57cec5SDimitry Andric StringRef FixedSizePortion) override; 1855ffd83dbSDimitry Andric void emitCVStringTableDirective() override; 1865ffd83dbSDimitry Andric void emitCVFileChecksumsDirective() override; 1875ffd83dbSDimitry Andric void emitCVFileChecksumOffsetDirective(unsigned FileNo) override; 1885ffd83dbSDimitry Andric void emitDTPRel32Value(const MCExpr *Value) override; 1895ffd83dbSDimitry Andric void emitDTPRel64Value(const MCExpr *Value) override; 1905ffd83dbSDimitry Andric void emitTPRel32Value(const MCExpr *Value) override; 1915ffd83dbSDimitry Andric void emitTPRel64Value(const MCExpr *Value) override; 1925ffd83dbSDimitry Andric void emitGPRel32Value(const MCExpr *Value) override; 1935ffd83dbSDimitry Andric void emitGPRel64Value(const MCExpr *Value) override; 194bdd1243dSDimitry Andric std::optional<std::pair<bool, std::string>> 1955ffd83dbSDimitry Andric emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, 1965ffd83dbSDimitry Andric SMLoc Loc, const MCSubtargetInfo &STI) override; 1970b57cec5SDimitry Andric using MCStreamer::emitFill; 1980b57cec5SDimitry Andric void emitFill(const MCExpr &NumBytes, uint64_t FillValue, 1990b57cec5SDimitry Andric SMLoc Loc = SMLoc()) override; 2000b57cec5SDimitry Andric void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr, 2010b57cec5SDimitry Andric SMLoc Loc = SMLoc()) override; 202349cc55cSDimitry Andric void emitNops(int64_t NumBytes, int64_t ControlledNopLength, SMLoc Loc, 203349cc55cSDimitry Andric const MCSubtargetInfo &STI) override; 2045ffd83dbSDimitry Andric void emitFileDirective(StringRef Filename) override; 205fe6060f1SDimitry Andric void emitFileDirective(StringRef Filename, StringRef CompilerVerion, 206fe6060f1SDimitry Andric StringRef TimeStamp, StringRef Description) override; 2070b57cec5SDimitry Andric 2085ffd83dbSDimitry Andric void emitAddrsig() override; 2095ffd83dbSDimitry Andric void emitAddrsigSym(const MCSymbol *Sym) override; 2100b57cec5SDimitry Andric 2115ffd83dbSDimitry Andric void finishImpl() override; 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric /// Emit the absolute difference between two symbols if possible. 2140b57cec5SDimitry Andric /// 2150b57cec5SDimitry Andric /// Emit the absolute difference between \c Hi and \c Lo, as long as we can 2160b57cec5SDimitry Andric /// compute it. Currently, that requires that both symbols are in the same 2170b57cec5SDimitry Andric /// data fragment and that the target has not specified that diff expressions 2180b57cec5SDimitry Andric /// require relocations to be emitted. Otherwise, do nothing and return 2190b57cec5SDimitry Andric /// \c false. 2200b57cec5SDimitry Andric /// 2210b57cec5SDimitry Andric /// \pre Offset of \c Hi is greater than the offset \c Lo. 2220b57cec5SDimitry Andric void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, 2230b57cec5SDimitry Andric unsigned Size) override; 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric void emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi, 2260b57cec5SDimitry Andric const MCSymbol *Lo) override; 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric bool mayHaveInstructions(MCSection &Sec) const override; 2290eae32dcSDimitry Andric 2300eae32dcSDimitry Andric /// Emits pending conditional assignments that depend on \p Symbol 2310eae32dcSDimitry Andric /// being emitted. 2320eae32dcSDimitry Andric void emitPendingAssignments(MCSymbol *Symbol); 2330b57cec5SDimitry Andric }; 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric } // end namespace llvm 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric #endif 238