1 //===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_MC_MCOBJECTSTREAMER_H
10 #define LLVM_MC_MCOBJECTSTREAMER_H
12 #include "llvm/ADT/SmallVector.h"
13 #include "llvm/MC/MCAssembler.h"
14 #include "llvm/MC/MCSection.h"
15 #include "llvm/MC/MCStreamer.h"
20 class MCSubtargetInfo
;
26 class raw_pwrite_stream
;
28 /// Streaming object file generation interface.
30 /// This class provides an implementation of the MCStreamer interface which is
31 /// suitable for use with the assembler backend. Specific object file formats
32 /// are expected to subclass this interface to implement directives specific
33 /// to that file format or custom semantics expected by the object writer
35 class MCObjectStreamer
: public MCStreamer
{
36 std::unique_ptr
<MCAssembler
> Assembler
;
37 MCSection::iterator CurInsertionPoint
;
40 SmallVector
<MCSymbol
*, 2> PendingLabels
;
41 struct PendingMCFixup
{
45 PendingMCFixup(const MCSymbol
*McSym
, MCDataFragment
*F
, MCFixup McFixup
)
46 : Sym(McSym
), Fixup(McFixup
), DF(F
) {}
48 SmallVector
<PendingMCFixup
, 2> PendingFixups
;
50 virtual void EmitInstToData(const MCInst
&Inst
, const MCSubtargetInfo
&) = 0;
51 void EmitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) override
;
52 void EmitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) override
;
53 MCSymbol
*EmitCFILabel() override
;
54 void EmitInstructionImpl(const MCInst
&Inst
, const MCSubtargetInfo
&STI
);
55 void resolvePendingFixups();
58 MCObjectStreamer(MCContext
&Context
, std::unique_ptr
<MCAsmBackend
> TAB
,
59 std::unique_ptr
<MCObjectWriter
> OW
,
60 std::unique_ptr
<MCCodeEmitter
> Emitter
);
65 void reset() override
;
67 /// Object streamers require the integrated assembler.
68 bool isIntegratedAssemblerRequired() const override
{ return true; }
70 void EmitFrames(MCAsmBackend
*MAB
);
71 void EmitCFISections(bool EH
, bool Debug
) override
;
73 MCFragment
*getCurrentFragment() const;
75 void insert(MCFragment
*F
) {
76 flushPendingLabels(F
);
77 MCSection
*CurSection
= getCurrentSectionOnly();
78 CurSection
->getFragmentList().insert(CurInsertionPoint
, F
);
79 F
->setParent(CurSection
);
82 /// Get a data fragment to write into, creating a new one if the current
83 /// fragment is not a data fragment.
84 /// Optionally a \p STI can be passed in so that a new fragment is created
85 /// if the Subtarget differs from the current fragment.
86 MCDataFragment
*getOrCreateDataFragment(const MCSubtargetInfo
* STI
= nullptr);
87 MCPaddingFragment
*getOrCreatePaddingFragment();
90 bool changeSectionImpl(MCSection
*Section
, const MCExpr
*Subsection
);
92 /// If any labels have been emitted but not assigned fragments, ensure that
93 /// they get assigned, either to F if possible or to a new data fragment.
94 /// Optionally, it is also possible to provide an offset \p FOffset, which
95 /// will be used as a symbol offset within the fragment.
96 void flushPendingLabels(MCFragment
*F
, uint64_t FOffset
= 0);
99 void visitUsedSymbol(const MCSymbol
&Sym
) override
;
101 /// Create a dummy fragment to assign any pending labels.
102 void flushPendingLabels() { flushPendingLabels(nullptr); }
104 MCAssembler
&getAssembler() { return *Assembler
; }
105 MCAssembler
*getAssemblerPtr() override
;
106 /// \name MCStreamer Interface
109 void EmitLabel(MCSymbol
*Symbol
, SMLoc Loc
= SMLoc()) override
;
110 virtual void EmitLabel(MCSymbol
*Symbol
, SMLoc Loc
, MCFragment
*F
);
111 void EmitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) override
;
112 void EmitValueImpl(const MCExpr
*Value
, unsigned Size
,
113 SMLoc Loc
= SMLoc()) override
;
114 void EmitULEB128Value(const MCExpr
*Value
) override
;
115 void EmitSLEB128Value(const MCExpr
*Value
) override
;
116 void EmitWeakReference(MCSymbol
*Alias
, const MCSymbol
*Symbol
) override
;
117 void ChangeSection(MCSection
*Section
, const MCExpr
*Subsection
) override
;
118 void EmitInstruction(const MCInst
&Inst
, const MCSubtargetInfo
&STI
) override
;
120 /// Emit an instruction to a special fragment, because this instruction
121 /// can change its size during relaxation.
122 virtual void EmitInstToFragment(const MCInst
&Inst
, const MCSubtargetInfo
&);
124 void EmitBundleAlignMode(unsigned AlignPow2
) override
;
125 void EmitBundleLock(bool AlignToEnd
) override
;
126 void EmitBundleUnlock() override
;
127 void EmitBytes(StringRef Data
) override
;
128 void EmitValueToAlignment(unsigned ByteAlignment
, int64_t Value
= 0,
129 unsigned ValueSize
= 1,
130 unsigned MaxBytesToEmit
= 0) override
;
131 void EmitCodeAlignment(unsigned ByteAlignment
,
132 unsigned MaxBytesToEmit
= 0) override
;
133 void emitValueToOffset(const MCExpr
*Offset
, unsigned char Value
,
136 EmitCodePaddingBasicBlockStart(const MCCodePaddingContext
&Context
) override
;
138 EmitCodePaddingBasicBlockEnd(const MCCodePaddingContext
&Context
) override
;
139 void EmitDwarfLocDirective(unsigned FileNo
, unsigned Line
,
140 unsigned Column
, unsigned Flags
,
141 unsigned Isa
, unsigned Discriminator
,
142 StringRef FileName
) override
;
143 void EmitDwarfAdvanceLineAddr(int64_t LineDelta
, const MCSymbol
*LastLabel
,
144 const MCSymbol
*Label
,
145 unsigned PointerSize
);
146 void EmitDwarfAdvanceFrameAddr(const MCSymbol
*LastLabel
,
147 const MCSymbol
*Label
);
148 void EmitCVLocDirective(unsigned FunctionId
, unsigned FileNo
, unsigned Line
,
149 unsigned Column
, bool PrologueEnd
, bool IsStmt
,
150 StringRef FileName
, SMLoc Loc
) override
;
151 void EmitCVLinetableDirective(unsigned FunctionId
, const MCSymbol
*Begin
,
152 const MCSymbol
*End
) override
;
153 void EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId
,
154 unsigned SourceFileId
,
155 unsigned SourceLineNum
,
156 const MCSymbol
*FnStartSym
,
157 const MCSymbol
*FnEndSym
) override
;
158 void EmitCVDefRangeDirective(
159 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
160 StringRef FixedSizePortion
) override
;
161 void EmitCVStringTableDirective() override
;
162 void EmitCVFileChecksumsDirective() override
;
163 void EmitCVFileChecksumOffsetDirective(unsigned FileNo
) override
;
164 void EmitDTPRel32Value(const MCExpr
*Value
) override
;
165 void EmitDTPRel64Value(const MCExpr
*Value
) override
;
166 void EmitTPRel32Value(const MCExpr
*Value
) override
;
167 void EmitTPRel64Value(const MCExpr
*Value
) override
;
168 void EmitGPRel32Value(const MCExpr
*Value
) override
;
169 void EmitGPRel64Value(const MCExpr
*Value
) override
;
170 bool EmitRelocDirective(const MCExpr
&Offset
, StringRef Name
,
171 const MCExpr
*Expr
, SMLoc Loc
,
172 const MCSubtargetInfo
&STI
) override
;
173 using MCStreamer::emitFill
;
174 void emitFill(const MCExpr
&NumBytes
, uint64_t FillValue
,
175 SMLoc Loc
= SMLoc()) override
;
176 void emitFill(const MCExpr
&NumValues
, int64_t Size
, int64_t Expr
,
177 SMLoc Loc
= SMLoc()) override
;
178 void EmitFileDirective(StringRef Filename
) override
;
180 void EmitAddrsig() override
;
181 void EmitAddrsigSym(const MCSymbol
*Sym
) override
;
183 void FinishImpl() override
;
185 /// Emit the absolute difference between two symbols if possible.
187 /// Emit the absolute difference between \c Hi and \c Lo, as long as we can
188 /// compute it. Currently, that requires that both symbols are in the same
189 /// data fragment and that the target has not specified that diff expressions
190 /// require relocations to be emitted. Otherwise, do nothing and return
193 /// \pre Offset of \c Hi is greater than the offset \c Lo.
194 void emitAbsoluteSymbolDiff(const MCSymbol
*Hi
, const MCSymbol
*Lo
,
195 unsigned Size
) override
;
197 void emitAbsoluteSymbolDiffAsULEB128(const MCSymbol
*Hi
,
198 const MCSymbol
*Lo
) override
;
200 bool mayHaveInstructions(MCSection
&Sec
) const override
;
203 } // end namespace llvm