blob: a00000bc11b60cae8567ee49da9dd7a4967aac1e [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_MC_MCOBJECTSTREAMER_H
10#define LLVM_MC_MCOBJECTSTREAMER_H
11
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020012#include "llvm/ADT/SetVector.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010013#include "llvm/ADT/SmallVector.h"
14#include "llvm/MC/MCAssembler.h"
15#include "llvm/MC/MCSection.h"
16#include "llvm/MC/MCStreamer.h"
17
18namespace llvm {
19class MCAssembler;
20class MCCodeEmitter;
21class MCSubtargetInfo;
22class MCExpr;
23class MCFragment;
24class MCDataFragment;
25class MCAsmBackend;
26class raw_ostream;
27class raw_pwrite_stream;
28
Andrew Scullcdfcccc2018-10-05 20:58:37 +010029/// Streaming object file generation interface.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010030///
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.
36class MCObjectStreamer : public MCStreamer {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010037 std::unique_ptr<MCAssembler> Assembler;
38 MCSection::iterator CurInsertionPoint;
39 bool EmitEHFrame;
40 bool EmitDebugFrame;
41 SmallVector<MCSymbol *, 2> PendingLabels;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020042 SmallSetVector<MCSection *, 4> PendingLabelSections;
43 unsigned CurSubsectionIdx;
Andrew Walbran16937d02019-10-22 13:54:20 +010044 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;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010052
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020053 virtual void emitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
54 void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
55 void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
56 MCSymbol *emitCFILabel() override;
57 void emitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI);
Andrew Walbran16937d02019-10-22 13:54:20 +010058 void resolvePendingFixups();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010059
60protected:
61 MCObjectStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
Andrew Scullcdfcccc2018-10-05 20:58:37 +010062 std::unique_ptr<MCObjectWriter> OW,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010063 std::unique_ptr<MCCodeEmitter> Emitter);
64 ~MCObjectStreamer();
65
66public:
67 /// state management
68 void reset() override;
69
70 /// Object streamers require the integrated assembler.
71 bool isIntegratedAssemblerRequired() const override { return true; }
72
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020073 void emitFrames(MCAsmBackend *MAB);
74 void emitCFISections(bool EH, bool Debug) override;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010075
76 MCFragment *getCurrentFragment() const;
77
78 void insert(MCFragment *F) {
79 flushPendingLabels(F);
80 MCSection *CurSection = getCurrentSectionOnly();
81 CurSection->getFragmentList().insert(CurInsertionPoint, F);
82 F->setParent(CurSection);
83 }
84
85 /// Get a data fragment to write into, creating a new one if the current
86 /// fragment is not a data fragment.
Andrew Scullcdfcccc2018-10-05 20:58:37 +010087 /// Optionally a \p STI can be passed in so that a new fragment is created
88 /// if the Subtarget differs from the current fragment.
89 MCDataFragment *getOrCreateDataFragment(const MCSubtargetInfo* STI = nullptr);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010090
91protected:
92 bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection);
93
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020094 /// Assign a label to the current Section and Subsection even though a
95 /// fragment is not yet present. Use flushPendingLabels(F) to associate
96 /// a fragment with this label.
97 void addPendingLabel(MCSymbol* label);
98
99 /// If any labels have been emitted but not assigned fragments in the current
100 /// Section and Subsection, ensure that they get assigned, either to fragment
101 /// F if possible or to a new data fragment. Optionally, one can provide an
102 /// offset \p FOffset as a symbol offset within the fragment.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100103 void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0);
104
105public:
106 void visitUsedSymbol(const MCSymbol &Sym) override;
107
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200108 /// Create a data fragment for any pending labels across all Sections
109 /// and Subsections.
110 void flushPendingLabels();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100111
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100112 MCAssembler &getAssembler() { return *Assembler; }
113 MCAssembler *getAssemblerPtr() override;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100114 /// \name MCStreamer Interface
115 /// @{
116
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200117 void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
118 virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F,
119 uint64_t Offset);
120 void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
121 void emitValueImpl(const MCExpr *Value, unsigned Size,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100122 SMLoc Loc = SMLoc()) override;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200123 void emitULEB128Value(const MCExpr *Value) override;
124 void emitSLEB128Value(const MCExpr *Value) override;
125 void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
126 void changeSection(MCSection *Section, const MCExpr *Subsection) override;
127 void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100128
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100129 /// Emit an instruction to a special fragment, because this instruction
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100130 /// can change its size during relaxation.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200131 virtual void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100132
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200133 void emitBundleAlignMode(unsigned AlignPow2) override;
134 void emitBundleLock(bool AlignToEnd) override;
135 void emitBundleUnlock() override;
136 void emitBytes(StringRef Data) override;
137 void emitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100138 unsigned ValueSize = 1,
139 unsigned MaxBytesToEmit = 0) override;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200140 void emitCodeAlignment(unsigned ByteAlignment,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100141 unsigned MaxBytesToEmit = 0) override;
142 void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
143 SMLoc Loc) override;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200144 void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
145 unsigned Flags, unsigned Isa,
146 unsigned Discriminator,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100147 StringRef FileName) override;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200148 void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
149 const MCSymbol *Label, unsigned PointerSize);
150 void emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100151 const MCSymbol *Label);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200152 void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100153 unsigned Column, bool PrologueEnd, bool IsStmt,
154 StringRef FileName, SMLoc Loc) override;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200155 void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100156 const MCSymbol *End) override;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200157 void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100158 unsigned SourceFileId,
159 unsigned SourceLineNum,
160 const MCSymbol *FnStartSym,
161 const MCSymbol *FnEndSym) override;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200162 void emitCVDefRangeDirective(
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100163 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
164 StringRef FixedSizePortion) override;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200165 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 Optional<std::pair<bool, std::string>>
175 emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr,
176 SMLoc Loc, const MCSubtargetInfo &STI) override;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100177 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;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200182 void emitNops(int64_t NumBytes, int64_t ControlledNopLength,
183 SMLoc Loc) override;
184 void emitFileDirective(StringRef Filename) override;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100185
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200186 void emitAddrsig() override;
187 void emitAddrsigSym(const MCSymbol *Sym) override;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100188
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200189 void finishImpl() override;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100190
191 /// Emit the absolute difference between two symbols if possible.
192 ///
193 /// Emit the absolute difference between \c Hi and \c Lo, as long as we can
194 /// compute it. Currently, that requires that both symbols are in the same
Andrew Scull0372a572018-11-16 15:47:06 +0000195 /// data fragment and that the target has not specified that diff expressions
196 /// require relocations to be emitted. Otherwise, do nothing and return
197 /// \c false.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100198 ///
199 /// \pre Offset of \c Hi is greater than the offset \c Lo.
200 void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
201 unsigned Size) override;
202
203 void emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
204 const MCSymbol *Lo) override;
205
206 bool mayHaveInstructions(MCSection &Sec) const override;
207};
208
209} // end namespace llvm
210
211#endif