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