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