xref: /llvm-project/llvm/include/llvm/MC/MCObjectStreamer.h (revision 28646d0cc12a01b0de2e4eb982cb91590bc2f84a)
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 
19 namespace llvm {
20 class MCContext;
21 class MCInst;
22 class MCObjectWriter;
23 class MCSymbol;
24 struct MCDwarfFrameInfo;
25 class MCAssembler;
26 class MCCodeEmitter;
27 class MCSubtargetInfo;
28 class MCExpr;
29 class MCAsmBackend;
30 class raw_ostream;
31 class 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.
40 class 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 
70 protected:
71   MCObjectStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
72                    std::unique_ptr<MCObjectWriter> OW,
73                    std::unique_ptr<MCCodeEmitter> Emitter);
74   ~MCObjectStreamer();
75 
76 public:
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 
101 protected:
102   bool changeSectionImpl(MCSection *Section, uint32_t Subsection);
103 
104 public:
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,
150                              MCSymbol *EndLabel = nullptr) override;
151   void emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
152                                  const MCSymbol *Label, SMLoc Loc);
153   void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
154                           unsigned Column, bool PrologueEnd, bool IsStmt,
155                           StringRef FileName, SMLoc Loc) override;
156   void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin,
157                                 const MCSymbol *End) override;
158   void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
159                                       unsigned SourceFileId,
160                                       unsigned SourceLineNum,
161                                       const MCSymbol *FnStartSym,
162                                       const MCSymbol *FnEndSym) override;
163   void emitCVDefRangeDirective(
164       ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
165       StringRef FixedSizePortion) override;
166   void emitCVStringTableDirective() override;
167   void emitCVFileChecksumsDirective() override;
168   void emitCVFileChecksumOffsetDirective(unsigned FileNo) override;
169   void emitDTPRel32Value(const MCExpr *Value) override;
170   void emitDTPRel64Value(const MCExpr *Value) override;
171   void emitTPRel32Value(const MCExpr *Value) override;
172   void emitTPRel64Value(const MCExpr *Value) override;
173   void emitGPRel32Value(const MCExpr *Value) override;
174   void emitGPRel64Value(const MCExpr *Value) override;
175   std::optional<std::pair<bool, std::string>>
176   emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr,
177                      SMLoc Loc, const MCSubtargetInfo &STI) override;
178   using MCStreamer::emitFill;
179   void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
180                 SMLoc Loc = SMLoc()) override;
181   void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
182                 SMLoc Loc = SMLoc()) override;
183   void emitNops(int64_t NumBytes, int64_t ControlledNopLength, SMLoc Loc,
184                 const MCSubtargetInfo &STI) override;
185   void emitFileDirective(StringRef Filename) override;
186   void emitFileDirective(StringRef Filename, StringRef CompilerVersion,
187                          StringRef TimeStamp, StringRef Description) override;
188 
189   void emitAddrsig() override;
190   void emitAddrsigSym(const MCSymbol *Sym) override;
191 
192   void finishImpl() override;
193 
194   /// Emit the absolute difference between two symbols if possible.
195   ///
196   /// Emit the absolute difference between \c Hi and \c Lo, as long as we can
197   /// compute it.  Currently, that requires that both symbols are in the same
198   /// data fragment and that the target has not specified that diff expressions
199   /// require relocations to be emitted. Otherwise, do nothing and return
200   /// \c false.
201   ///
202   /// \pre Offset of \c Hi is greater than the offset \c Lo.
203   void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
204                               unsigned Size) override;
205 
206   void emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
207                                        const MCSymbol *Lo) override;
208 
209   bool mayHaveInstructions(MCSection &Sec) const override;
210 
211   /// Emits pending conditional assignments that depend on \p Symbol
212   /// being emitted.
213   void emitPendingAssignments(MCSymbol *Symbol);
214 };
215 
216 } // end namespace llvm
217 
218 #endif
219