1 //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/MC/MCObjectStreamer.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/MC/MCAsmBackend.h"
13 #include "llvm/MC/MCAsmInfo.h"
14 #include "llvm/MC/MCAssembler.h"
15 #include "llvm/MC/MCCodeEmitter.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCDwarf.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCObjectWriter.h"
20 #include "llvm/MC/MCSection.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/Support/ErrorHandling.h"
25 MCObjectStreamer::MCObjectStreamer(MCContext
&Context
, MCAsmBackend
&TAB
,
26 raw_ostream
&OS
, MCCodeEmitter
*Emitter_
)
27 : MCStreamer(Context
),
28 Assembler(new MCAssembler(Context
, TAB
, *Emitter_
,
29 *TAB
.createObjectWriter(OS
), OS
)),
30 CurSectionData(nullptr), EmitEHFrame(true), EmitDebugFrame(false) {}
32 MCObjectStreamer::MCObjectStreamer(MCContext
&Context
, MCAsmBackend
&TAB
,
33 raw_ostream
&OS
, MCCodeEmitter
*Emitter_
,
34 MCAssembler
*_Assembler
)
35 : MCStreamer(Context
), Assembler(_Assembler
), CurSectionData(nullptr),
36 EmitEHFrame(true), EmitDebugFrame(false) {}
38 MCObjectStreamer::~MCObjectStreamer() {
39 delete &Assembler
->getBackend();
40 delete &Assembler
->getEmitter();
41 delete &Assembler
->getWriter();
45 void MCObjectStreamer::flushPendingLabels(MCFragment
*F
) {
46 if (PendingLabels
.size()) {
48 F
= new MCDataFragment();
49 CurSectionData
->getFragmentList().insert(CurInsertionPoint
, F
);
50 F
->setParent(CurSectionData
);
52 for (MCSymbolData
*SD
: PendingLabels
) {
56 PendingLabels
.clear();
60 void MCObjectStreamer::reset() {
63 CurSectionData
= nullptr;
64 CurInsertionPoint
= MCSectionData::iterator();
66 EmitDebugFrame
= false;
67 PendingLabels
.clear();
71 void MCObjectStreamer::EmitFrames(MCAsmBackend
*MAB
) {
72 if (!getNumFrameInfos())
76 MCDwarfFrameEmitter::Emit(*this, MAB
, true);
79 MCDwarfFrameEmitter::Emit(*this, MAB
, false);
82 MCFragment
*MCObjectStreamer::getCurrentFragment() const {
83 assert(getCurrentSectionData() && "No current section!");
85 if (CurInsertionPoint
!= getCurrentSectionData()->getFragmentList().begin())
86 return std::prev(CurInsertionPoint
);
91 MCDataFragment
*MCObjectStreamer::getOrCreateDataFragment() {
92 MCDataFragment
*F
= dyn_cast_or_null
<MCDataFragment
>(getCurrentFragment());
93 // When bundling is enabled, we don't want to add data to a fragment that
94 // already has instructions (see MCELFStreamer::EmitInstToData for details)
95 if (!F
|| (Assembler
->isBundlingEnabled() && F
->hasInstructions())) {
96 F
= new MCDataFragment();
102 void MCObjectStreamer::visitUsedSymbol(const MCSymbol
&Sym
) {
103 Assembler
->getOrCreateSymbolData(Sym
);
106 void MCObjectStreamer::EmitCFISections(bool EH
, bool Debug
) {
107 MCStreamer::EmitCFISections(EH
, Debug
);
109 EmitDebugFrame
= Debug
;
112 void MCObjectStreamer::EmitValueImpl(const MCExpr
*Value
, unsigned Size
,
114 MCStreamer::EmitValueImpl(Value
, Size
, Loc
);
115 MCDataFragment
*DF
= getOrCreateDataFragment();
117 MCLineEntry::Make(this, getCurrentSection().first
);
119 // Avoid fixups when possible.
121 if (Value
->EvaluateAsAbsolute(AbsValue
, getAssembler())) {
122 EmitIntValue(AbsValue
, Size
);
125 DF
->getFixups().push_back(
126 MCFixup::Create(DF
->getContents().size(), Value
,
127 MCFixup::getKindForSize(Size
, false), Loc
));
128 DF
->getContents().resize(DF
->getContents().size() + Size
, 0);
131 void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) {
132 // We need to create a local symbol to avoid relocations.
133 Frame
.Begin
= getContext().CreateTempSymbol();
134 EmitLabel(Frame
.Begin
);
137 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) {
138 Frame
.End
= getContext().CreateTempSymbol();
139 EmitLabel(Frame
.End
);
142 void MCObjectStreamer::EmitLabel(MCSymbol
*Symbol
) {
143 MCStreamer::EmitLabel(Symbol
);
145 MCSymbolData
&SD
= getAssembler().getOrCreateSymbolData(*Symbol
);
146 assert(!SD
.getFragment() && "Unexpected fragment on symbol data!");
148 // If there is a current fragment, mark the symbol as pointing into it.
149 // Otherwise queue the label and set its fragment pointer when we emit the
151 if (auto *F
= dyn_cast_or_null
<MCDataFragment
>(getCurrentFragment())) {
153 SD
.setOffset(F
->getContents().size());
155 PendingLabels
.push_back(&SD
);
159 void MCObjectStreamer::EmitULEB128Value(const MCExpr
*Value
) {
161 if (Value
->EvaluateAsAbsolute(IntValue
, getAssembler())) {
162 EmitULEB128IntValue(IntValue
);
165 insert(new MCLEBFragment(*Value
, false));
168 void MCObjectStreamer::EmitSLEB128Value(const MCExpr
*Value
) {
170 if (Value
->EvaluateAsAbsolute(IntValue
, getAssembler())) {
171 EmitSLEB128IntValue(IntValue
);
174 insert(new MCLEBFragment(*Value
, true));
177 void MCObjectStreamer::EmitWeakReference(MCSymbol
*Alias
,
178 const MCSymbol
*Symbol
) {
179 report_fatal_error("This file format doesn't support weak aliases.");
182 void MCObjectStreamer::ChangeSection(const MCSection
*Section
,
183 const MCExpr
*Subsection
) {
184 assert(Section
&& "Cannot switch to a null section!");
185 flushPendingLabels(nullptr);
187 CurSectionData
= &getAssembler().getOrCreateSectionData(*Section
);
189 int64_t IntSubsection
= 0;
191 !Subsection
->EvaluateAsAbsolute(IntSubsection
, getAssembler()))
192 report_fatal_error("Cannot evaluate subsection number");
193 if (IntSubsection
< 0 || IntSubsection
> 8192)
194 report_fatal_error("Subsection number out of range");
196 CurSectionData
->getSubsectionInsertionPoint(unsigned(IntSubsection
));
199 void MCObjectStreamer::EmitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {
200 getAssembler().getOrCreateSymbolData(*Symbol
);
201 MCStreamer::EmitAssignment(Symbol
, Value
);
204 void MCObjectStreamer::EmitInstruction(const MCInst
&Inst
,
205 const MCSubtargetInfo
&STI
) {
206 MCStreamer::EmitInstruction(Inst
, STI
);
208 MCSectionData
*SD
= getCurrentSectionData();
209 SD
->setHasInstructions(true);
211 // Now that a machine instruction has been assembled into this section, make
212 // a line entry for any .loc directive that has been seen.
213 MCLineEntry::Make(this, getCurrentSection().first
);
215 // If this instruction doesn't need relaxation, just emit it as data.
216 MCAssembler
&Assembler
= getAssembler();
217 if (!Assembler
.getBackend().mayNeedRelaxation(Inst
)) {
218 EmitInstToData(Inst
, STI
);
222 // Otherwise, relax and emit it as data if either:
223 // - The RelaxAll flag was passed
224 // - Bundling is enabled and this instruction is inside a bundle-locked
225 // group. We want to emit all such instructions into the same data
227 if (Assembler
.getRelaxAll() ||
228 (Assembler
.isBundlingEnabled() && SD
->isBundleLocked())) {
230 getAssembler().getBackend().relaxInstruction(Inst
, Relaxed
);
231 while (getAssembler().getBackend().mayNeedRelaxation(Relaxed
))
232 getAssembler().getBackend().relaxInstruction(Relaxed
, Relaxed
);
233 EmitInstToData(Relaxed
, STI
);
237 // Otherwise emit to a separate fragment.
238 EmitInstToFragment(Inst
, STI
);
241 void MCObjectStreamer::EmitInstToFragment(const MCInst
&Inst
,
242 const MCSubtargetInfo
&STI
) {
243 // Always create a new, separate fragment here, because its size can change
244 // during relaxation.
245 MCRelaxableFragment
*IF
= new MCRelaxableFragment(Inst
, STI
);
248 SmallString
<128> Code
;
249 raw_svector_ostream
VecOS(Code
);
250 getAssembler().getEmitter().EncodeInstruction(Inst
, VecOS
, IF
->getFixups(),
253 IF
->getContents().append(Code
.begin(), Code
.end());
257 static const char *const BundlingNotImplementedMsg
=
258 "Aligned bundling is not implemented for this object format";
261 void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2
) {
262 llvm_unreachable(BundlingNotImplementedMsg
);
265 void MCObjectStreamer::EmitBundleLock(bool AlignToEnd
) {
266 llvm_unreachable(BundlingNotImplementedMsg
);
269 void MCObjectStreamer::EmitBundleUnlock() {
270 llvm_unreachable(BundlingNotImplementedMsg
);
273 void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo
, unsigned Line
,
274 unsigned Column
, unsigned Flags
,
276 unsigned Discriminator
,
277 StringRef FileName
) {
278 // In case we see two .loc directives in a row, make sure the
279 // first one gets a line entry.
280 MCLineEntry::Make(this, getCurrentSection().first
);
282 this->MCStreamer::EmitDwarfLocDirective(FileNo
, Line
, Column
, Flags
,
283 Isa
, Discriminator
, FileName
);
286 static const MCExpr
*buildSymbolDiff(MCObjectStreamer
&OS
, const MCSymbol
*A
,
288 MCContext
&Context
= OS
.getContext();
289 MCSymbolRefExpr::VariantKind Variant
= MCSymbolRefExpr::VK_None
;
290 const MCExpr
*ARef
= MCSymbolRefExpr::Create(A
, Variant
, Context
);
291 const MCExpr
*BRef
= MCSymbolRefExpr::Create(B
, Variant
, Context
);
292 const MCExpr
*AddrDelta
=
293 MCBinaryExpr::Create(MCBinaryExpr::Sub
, ARef
, BRef
, Context
);
297 static void emitDwarfSetLineAddr(MCObjectStreamer
&OS
, int64_t LineDelta
,
298 const MCSymbol
*Label
, int PointerSize
) {
299 // emit the sequence to set the address
300 OS
.EmitIntValue(dwarf::DW_LNS_extended_op
, 1);
301 OS
.EmitULEB128IntValue(PointerSize
+ 1);
302 OS
.EmitIntValue(dwarf::DW_LNE_set_address
, 1);
303 OS
.EmitSymbolValue(Label
, PointerSize
);
305 // emit the sequence for the LineDelta (from 1) and a zero address delta.
306 MCDwarfLineAddr::Emit(&OS
, LineDelta
, 0);
309 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta
,
310 const MCSymbol
*LastLabel
,
311 const MCSymbol
*Label
,
312 unsigned PointerSize
) {
314 emitDwarfSetLineAddr(*this, LineDelta
, Label
, PointerSize
);
317 const MCExpr
*AddrDelta
= buildSymbolDiff(*this, Label
, LastLabel
);
319 if (AddrDelta
->EvaluateAsAbsolute(Res
, getAssembler())) {
320 MCDwarfLineAddr::Emit(this, LineDelta
, Res
);
323 insert(new MCDwarfLineAddrFragment(LineDelta
, *AddrDelta
));
326 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol
*LastLabel
,
327 const MCSymbol
*Label
) {
328 const MCExpr
*AddrDelta
= buildSymbolDiff(*this, Label
, LastLabel
);
330 if (AddrDelta
->EvaluateAsAbsolute(Res
, getAssembler())) {
331 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res
);
334 insert(new MCDwarfCallFrameFragment(*AddrDelta
));
337 void MCObjectStreamer::EmitBytes(StringRef Data
) {
338 MCLineEntry::Make(this, getCurrentSection().first
);
339 getOrCreateDataFragment()->getContents().append(Data
.begin(), Data
.end());
342 void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment
,
345 unsigned MaxBytesToEmit
) {
346 if (MaxBytesToEmit
== 0)
347 MaxBytesToEmit
= ByteAlignment
;
348 insert(new MCAlignFragment(ByteAlignment
, Value
, ValueSize
, MaxBytesToEmit
));
350 // Update the maximum alignment on the current section if necessary.
351 if (ByteAlignment
> getCurrentSectionData()->getAlignment())
352 getCurrentSectionData()->setAlignment(ByteAlignment
);
355 void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment
,
356 unsigned MaxBytesToEmit
) {
357 EmitValueToAlignment(ByteAlignment
, 0, 1, MaxBytesToEmit
);
358 cast
<MCAlignFragment
>(getCurrentFragment())->setEmitNops(true);
361 bool MCObjectStreamer::EmitValueToOffset(const MCExpr
*Offset
,
362 unsigned char Value
) {
364 if (Offset
->EvaluateAsAbsolute(Res
, getAssembler())) {
365 insert(new MCOrgFragment(*Offset
, Value
));
369 MCSymbol
*CurrentPos
= getContext().CreateTempSymbol();
370 EmitLabel(CurrentPos
);
371 MCSymbolRefExpr::VariantKind Variant
= MCSymbolRefExpr::VK_None
;
373 MCSymbolRefExpr::Create(CurrentPos
, Variant
, getContext());
374 const MCExpr
*Delta
=
375 MCBinaryExpr::Create(MCBinaryExpr::Sub
, Offset
, Ref
, getContext());
377 if (!Delta
->EvaluateAsAbsolute(Res
, getAssembler()))
379 EmitFill(Res
, Value
);
383 // Associate GPRel32 fixup with data and resize data area
384 void MCObjectStreamer::EmitGPRel32Value(const MCExpr
*Value
) {
385 MCDataFragment
*DF
= getOrCreateDataFragment();
387 DF
->getFixups().push_back(MCFixup::Create(DF
->getContents().size(),
389 DF
->getContents().resize(DF
->getContents().size() + 4, 0);
392 // Associate GPRel32 fixup with data and resize data area
393 void MCObjectStreamer::EmitGPRel64Value(const MCExpr
*Value
) {
394 MCDataFragment
*DF
= getOrCreateDataFragment();
396 DF
->getFixups().push_back(MCFixup::Create(DF
->getContents().size(),
398 DF
->getContents().resize(DF
->getContents().size() + 8, 0);
401 void MCObjectStreamer::EmitFill(uint64_t NumBytes
, uint8_t FillValue
) {
402 // FIXME: A MCFillFragment would be more memory efficient but MCExpr has
403 // problems evaluating expressions across multiple fragments.
404 getOrCreateDataFragment()->getContents().append(NumBytes
, FillValue
);
407 void MCObjectStreamer::EmitZeros(uint64_t NumBytes
) {
408 const MCSection
*Sec
= getCurrentSection().first
;
409 assert(Sec
&& "need a section");
410 unsigned ItemSize
= Sec
->isVirtualSection() ? 0 : 1;
411 insert(new MCFillFragment(0, ItemSize
, NumBytes
));
414 void MCObjectStreamer::FinishImpl() {
415 // If we are generating dwarf for assembly source files dump out the sections.
416 if (getContext().getGenDwarfForAssembly())
417 MCGenDwarfInfo::Emit(this);
419 // Dump out the dwarf file & directory tables and line tables.
420 MCDwarfLineTable::Emit(this);
422 flushPendingLabels(nullptr);
423 getAssembler().Finish();