1//===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_MC_MCOBJECTSTREAMER_H
10#define LLVM_MC_MCOBJECTSTREAMER_H
11
12#include "llvm/ADT/SetVector.h"
13#include "llvm/ADT/SmallVector.h"
14#include "llvm/MC/MCFixup.h"
15#include "llvm/MC/MCFragment.h"
16#include "llvm/MC/MCSection.h"
17#include "llvm/MC/MCStreamer.h"
18
19namespace llvm {
20class MCContext;
21class MCInst;
22class MCObjectWriter;
23class MCSymbol;
24struct MCDwarfFrameInfo;
25class MCAssembler;
26class MCCodeEmitter;
27class MCSubtargetInfo;
28class MCExpr;
29class MCAsmBackend;
30class raw_ostream;
31class raw_pwrite_stream;
32
33/// Streaming object file generation interface.
34///
35/// This class provides an implementation of the MCStreamer interface which is
36/// suitable for use with the assembler backend. Specific object file formats
37/// are expected to subclass this interface to implement directives specific
38/// to that file format or custom semantics expected by the object writer
39/// implementation.
40class MCObjectStreamer : public MCStreamer {
41 std::unique_ptr<MCAssembler> Assembler;
42 bool EmitEHFrame;
43 bool EmitDebugFrame;
44 struct PendingMCFixup {
45 const MCSymbol *Sym;
46 MCFixup Fixup;
47 MCDataFragment *DF;
48 PendingMCFixup(const MCSymbol *McSym, MCDataFragment *F, MCFixup McFixup)
49 : Sym(McSym), Fixup(McFixup), DF(F) {}
50 };
51 SmallVector<PendingMCFixup, 2> PendingFixups;
52
53 struct PendingAssignment {
54 MCSymbol *Symbol;
55 const MCExpr *Value;
56 };
57
58 /// A list of conditional assignments we may need to emit if the target
59 /// symbol is later emitted.
60 DenseMap<const MCSymbol *, SmallVector<PendingAssignment, 1>>
61 pendingAssignments;
62
63 virtual void emitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
64 void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
65 void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
66 MCSymbol *emitCFILabel() override;
67 void emitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI);
68 void resolvePendingFixups();
69
70protected:
71 MCObjectStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
72 std::unique_ptr<MCObjectWriter> OW,
73 std::unique_ptr<MCCodeEmitter> Emitter);
74 ~MCObjectStreamer();
75
76public:
77 /// state management
78 void reset() override;
79
80 /// Object streamers require the integrated assembler.
81 bool isIntegratedAssemblerRequired() const override { return true; }
82
83 void emitFrames(MCAsmBackend *MAB);
84 void emitCFISections(bool EH, bool Debug) override;
85
86 void insert(MCFragment *F) {
87 auto *Sec = CurFrag->getParent();
88 F->setParent(Sec);
89 F->setLayoutOrder(CurFrag->getLayoutOrder() + 1);
90 CurFrag->Next = F;
91 CurFrag = F;
92 Sec->curFragList()->Tail = F;
93 }
94
95 /// Get a data fragment to write into, creating a new one if the current
96 /// fragment is not a data fragment.
97 /// Optionally a \p STI can be passed in so that a new fragment is created
98 /// if the Subtarget differs from the current fragment.
99 MCDataFragment *getOrCreateDataFragment(const MCSubtargetInfo* STI = nullptr);
100
101protected:
102 bool changeSectionImpl(MCSection *Section, uint32_t Subsection);
103
104public:
105 void visitUsedSymbol(const MCSymbol &Sym) override;
106
107 MCAssembler &getAssembler() { return *Assembler; }
108 MCAssembler *getAssemblerPtr() override;
109 /// \name MCStreamer Interface
110 /// @{
111
112 void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
113 virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F,
114 uint64_t Offset);
115 void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
116 void emitConditionalAssignment(MCSymbol *Symbol,
117 const MCExpr *Value) override;
118 void emitValueImpl(const MCExpr *Value, unsigned Size,
119 SMLoc Loc = SMLoc()) override;
120 void emitULEB128Value(const MCExpr *Value) override;
121 void emitSLEB128Value(const MCExpr *Value) override;
122 void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
123 void changeSection(MCSection *Section, uint32_t Subsection = 0) override;
124 void switchSectionNoPrint(MCSection *Section) override;
125 void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
126
127 /// Emit an instruction to a special fragment, because this instruction
128 /// can change its size during relaxation.
129 virtual void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
130
131 void emitBundleAlignMode(Align Alignment) override;
132 void emitBundleLock(bool AlignToEnd) override;
133 void emitBundleUnlock() override;
134 void emitBytes(StringRef Data) override;
135 void emitValueToAlignment(Align Alignment, int64_t Value = 0,
136 unsigned ValueSize = 1,
137 unsigned MaxBytesToEmit = 0) override;
138 void emitCodeAlignment(Align ByteAlignment, const MCSubtargetInfo *STI,
139 unsigned MaxBytesToEmit = 0) override;
140 void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
141 SMLoc Loc) override;
142 void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
143 unsigned Flags, unsigned Isa,
144 unsigned Discriminator,
145 StringRef FileName) override;
146 void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
147 const MCSymbol *Label,
148 unsigned PointerSize) override;
149 void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override;
150 void emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
151 const MCSymbol *Label, SMLoc Loc);
152 void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
153 unsigned Column, bool PrologueEnd, bool IsStmt,
154 StringRef FileName, SMLoc Loc) override;
155 void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin,
156 const MCSymbol *End) override;
157 void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
158 unsigned SourceFileId,
159 unsigned SourceLineNum,
160 const MCSymbol *FnStartSym,
161 const MCSymbol *FnEndSym) override;
162 void emitCVDefRangeDirective(
163 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
164 StringRef FixedSizePortion) override;
165 void emitCVStringTableDirective() override;
166 void emitCVFileChecksumsDirective() override;
167 void emitCVFileChecksumOffsetDirective(unsigned FileNo) override;
168 void emitDTPRel32Value(const MCExpr *Value) override;
169 void emitDTPRel64Value(const MCExpr *Value) override;
170 void emitTPRel32Value(const MCExpr *Value) override;
171 void emitTPRel64Value(const MCExpr *Value) override;
172 void emitGPRel32Value(const MCExpr *Value) override;
173 void emitGPRel64Value(const MCExpr *Value) override;
174 std::optional<std::pair<bool, std::string>>
175 emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr,
176 SMLoc Loc, const MCSubtargetInfo &STI) override;
177 using MCStreamer::emitFill;
178 void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
179 SMLoc Loc = SMLoc()) override;
180 void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
181 SMLoc Loc = SMLoc()) override;
182 void emitNops(int64_t NumBytes, int64_t ControlledNopLength, SMLoc Loc,
183 const MCSubtargetInfo &STI) override;
184 void emitFileDirective(StringRef Filename) override;
185 void emitFileDirective(StringRef Filename, StringRef CompilerVersion,
186 StringRef TimeStamp, StringRef Description) override;
187
188 void emitAddrsig() override;
189 void emitAddrsigSym(const MCSymbol *Sym) override;
190
191 void finishImpl() override;
192
193 /// Emit the absolute difference between two symbols if possible.
194 ///
195 /// Emit the absolute difference between \c Hi and \c Lo, as long as we can
196 /// compute it. Currently, that requires that both symbols are in the same
197 /// data fragment and that the target has not specified that diff expressions
198 /// require relocations to be emitted. Otherwise, do nothing and return
199 /// \c false.
200 ///
201 /// \pre Offset of \c Hi is greater than the offset \c Lo.
202 void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
203 unsigned Size) override;
204
205 void emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
206 const MCSymbol *Lo) override;
207
208 bool mayHaveInstructions(MCSection &Sec) const override;
209
210 /// Emits pending conditional assignments that depend on \p Symbol
211 /// being emitted.
212 void emitPendingAssignments(MCSymbol *Symbol);
213};
214
215} // end namespace llvm
216
217#endif
218