1 //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
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 #include "llvm/MC/MCObjectStreamer.h"
10 #include "llvm/MC/MCAsmBackend.h"
11 #include "llvm/MC/MCAsmInfo.h"
12 #include "llvm/MC/MCAssembler.h"
13 #include "llvm/MC/MCCodeEmitter.h"
14 #include "llvm/MC/MCCodeView.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCDwarf.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCObjectFileInfo.h"
19 #include "llvm/MC/MCObjectWriter.h"
20 #include "llvm/MC/MCSection.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/MC/MCValue.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/SourceMgr.h"
25 using namespace llvm;
26
MCObjectStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> TAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter)27 MCObjectStreamer::MCObjectStreamer(MCContext &Context,
28 std::unique_ptr<MCAsmBackend> TAB,
29 std::unique_ptr<MCObjectWriter> OW,
30 std::unique_ptr<MCCodeEmitter> Emitter)
31 : MCStreamer(Context),
32 Assembler(std::make_unique<MCAssembler>(
33 Context, std::move(TAB), std::move(Emitter), std::move(OW))),
34 EmitEHFrame(true), EmitDebugFrame(false) {
35 if (Assembler->getBackendPtr())
36 setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
37 }
38
39 MCObjectStreamer::~MCObjectStreamer() = default;
40
41 // AssemblerPtr is used for evaluation of expressions and causes
42 // difference between asm and object outputs. Return nullptr to in
43 // inline asm mode to limit divergence to assembly inputs.
getAssemblerPtr()44 MCAssembler *MCObjectStreamer::getAssemblerPtr() {
45 if (getUseAssemblerInfoForParsing())
46 return Assembler.get();
47 return nullptr;
48 }
49
addPendingLabel(MCSymbol * S)50 void MCObjectStreamer::addPendingLabel(MCSymbol* S) {
51 MCSection *CurSection = getCurrentSectionOnly();
52 if (CurSection) {
53 // Register labels that have not yet been assigned to a Section.
54 if (!PendingLabels.empty()) {
55 for (MCSymbol* Sym : PendingLabels)
56 CurSection->addPendingLabel(Sym);
57 PendingLabels.clear();
58 }
59
60 // Add this label to the current Section / Subsection.
61 CurSection->addPendingLabel(S, CurSubsectionIdx);
62
63 // Add this Section to the list of PendingLabelSections.
64 PendingLabelSections.insert(CurSection);
65 } else
66 // There is no Section / Subsection for this label yet.
67 PendingLabels.push_back(S);
68 }
69
flushPendingLabels(MCFragment * F,uint64_t FOffset)70 void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
71 MCSection *CurSection = getCurrentSectionOnly();
72 if (!CurSection) {
73 assert(PendingLabels.empty());
74 return;
75 }
76 // Register labels that have not yet been assigned to a Section.
77 if (!PendingLabels.empty()) {
78 for (MCSymbol* Sym : PendingLabels)
79 CurSection->addPendingLabel(Sym, CurSubsectionIdx);
80 PendingLabels.clear();
81 }
82
83 // Associate a fragment with this label, either the supplied fragment
84 // or an empty data fragment.
85 if (F)
86 CurSection->flushPendingLabels(F, FOffset, CurSubsectionIdx);
87 else
88 CurSection->flushPendingLabels(nullptr, 0, CurSubsectionIdx);
89 }
90
flushPendingLabels()91 void MCObjectStreamer::flushPendingLabels() {
92 // Register labels that have not yet been assigned to a Section.
93 if (!PendingLabels.empty()) {
94 MCSection *CurSection = getCurrentSectionOnly();
95 assert(CurSection);
96 for (MCSymbol* Sym : PendingLabels)
97 CurSection->addPendingLabel(Sym, CurSubsectionIdx);
98 PendingLabels.clear();
99 }
100
101 // Assign an empty data fragment to all remaining pending labels.
102 for (MCSection* Section : PendingLabelSections)
103 Section->flushPendingLabels();
104 }
105
106 // When fixup's offset is a forward declared label, e.g.:
107 //
108 // .reloc 1f, R_MIPS_JALR, foo
109 // 1: nop
110 //
111 // postpone adding it to Fixups vector until the label is defined and its offset
112 // is known.
resolvePendingFixups()113 void MCObjectStreamer::resolvePendingFixups() {
114 for (PendingMCFixup &PendingFixup : PendingFixups) {
115 if (!PendingFixup.Sym || PendingFixup.Sym->isUndefined ()) {
116 getContext().reportError(PendingFixup.Fixup.getLoc(),
117 "unresolved relocation offset");
118 continue;
119 }
120 flushPendingLabels(PendingFixup.DF, PendingFixup.DF->getContents().size());
121 PendingFixup.Fixup.setOffset(PendingFixup.Sym->getOffset() +
122 PendingFixup.Fixup.getOffset());
123
124 // If the location symbol to relocate is in MCEncodedFragmentWithFixups,
125 // put the Fixup into location symbol's fragment. Otherwise
126 // put into PendingFixup.DF
127 MCFragment *SymFragment = PendingFixup.Sym->getFragment();
128 switch (SymFragment->getKind()) {
129 case MCFragment::FT_Relaxable:
130 case MCFragment::FT_Dwarf:
131 case MCFragment::FT_PseudoProbe:
132 cast<MCEncodedFragmentWithFixups<8, 1>>(SymFragment)
133 ->getFixups()
134 .push_back(PendingFixup.Fixup);
135 break;
136 case MCFragment::FT_Data:
137 case MCFragment::FT_CVDefRange:
138 cast<MCEncodedFragmentWithFixups<32, 4>>(SymFragment)
139 ->getFixups()
140 .push_back(PendingFixup.Fixup);
141 break;
142 default:
143 PendingFixup.DF->getFixups().push_back(PendingFixup.Fixup);
144 break;
145 }
146 }
147 PendingFixups.clear();
148 }
149
150 // As a compile-time optimization, avoid allocating and evaluating an MCExpr
151 // tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
absoluteSymbolDiff(const MCSymbol * Hi,const MCSymbol * Lo)152 static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
153 const MCSymbol *Lo) {
154 assert(Hi && Lo);
155 if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
156 Hi->isVariable() || Lo->isVariable())
157 return std::nullopt;
158
159 return Hi->getOffset() - Lo->getOffset();
160 }
161
emitAbsoluteSymbolDiff(const MCSymbol * Hi,const MCSymbol * Lo,unsigned Size)162 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
163 const MCSymbol *Lo,
164 unsigned Size) {
165 if (!getAssembler().getContext().getTargetTriple().isRISCV())
166 if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
167 return emitIntValue(*Diff, Size);
168 MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
169 }
170
emitAbsoluteSymbolDiffAsULEB128(const MCSymbol * Hi,const MCSymbol * Lo)171 void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
172 const MCSymbol *Lo) {
173 if (!getAssembler().getContext().getTargetTriple().isRISCV())
174 if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
175 emitULEB128IntValue(*Diff);
176 return;
177 }
178 MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
179 }
180
reset()181 void MCObjectStreamer::reset() {
182 if (Assembler)
183 Assembler->reset();
184 CurInsertionPoint = MCSection::iterator();
185 EmitEHFrame = true;
186 EmitDebugFrame = false;
187 PendingLabels.clear();
188 PendingLabelSections.clear();
189 MCStreamer::reset();
190 }
191
emitFrames(MCAsmBackend * MAB)192 void MCObjectStreamer::emitFrames(MCAsmBackend *MAB) {
193 if (!getNumFrameInfos())
194 return;
195
196 if (EmitEHFrame)
197 MCDwarfFrameEmitter::Emit(*this, MAB, true);
198
199 if (EmitDebugFrame)
200 MCDwarfFrameEmitter::Emit(*this, MAB, false);
201 }
202
getCurrentFragment() const203 MCFragment *MCObjectStreamer::getCurrentFragment() const {
204 assert(getCurrentSectionOnly() && "No current section!");
205
206 if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
207 return &*std::prev(CurInsertionPoint);
208
209 return nullptr;
210 }
211
canReuseDataFragment(const MCDataFragment & F,const MCAssembler & Assembler,const MCSubtargetInfo * STI)212 static bool canReuseDataFragment(const MCDataFragment &F,
213 const MCAssembler &Assembler,
214 const MCSubtargetInfo *STI) {
215 if (!F.hasInstructions())
216 return true;
217 // When bundling is enabled, we don't want to add data to a fragment that
218 // already has instructions (see MCELFStreamer::emitInstToData for details)
219 if (Assembler.isBundlingEnabled())
220 return Assembler.getRelaxAll();
221 // If the subtarget is changed mid fragment we start a new fragment to record
222 // the new STI.
223 return !STI || F.getSubtargetInfo() == STI;
224 }
225
226 MCDataFragment *
getOrCreateDataFragment(const MCSubtargetInfo * STI)227 MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
228 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
229 if (!F || !canReuseDataFragment(*F, *Assembler, STI)) {
230 F = new MCDataFragment();
231 insert(F);
232 }
233 return F;
234 }
235
visitUsedSymbol(const MCSymbol & Sym)236 void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
237 Assembler->registerSymbol(Sym);
238 }
239
emitCFISections(bool EH,bool Debug)240 void MCObjectStreamer::emitCFISections(bool EH, bool Debug) {
241 MCStreamer::emitCFISections(EH, Debug);
242 EmitEHFrame = EH;
243 EmitDebugFrame = Debug;
244 }
245
emitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)246 void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
247 SMLoc Loc) {
248 MCStreamer::emitValueImpl(Value, Size, Loc);
249 MCDataFragment *DF = getOrCreateDataFragment();
250 flushPendingLabels(DF, DF->getContents().size());
251
252 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
253
254 // Avoid fixups when possible.
255 int64_t AbsValue;
256 if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {
257 if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
258 getContext().reportError(
259 Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");
260 return;
261 }
262 emitIntValue(AbsValue, Size);
263 return;
264 }
265 DF->getFixups().push_back(
266 MCFixup::create(DF->getContents().size(), Value,
267 MCFixup::getKindForSize(Size, false), Loc));
268 DF->getContents().resize(DF->getContents().size() + Size, 0);
269 }
270
emitCFILabel()271 MCSymbol *MCObjectStreamer::emitCFILabel() {
272 MCSymbol *Label = getContext().createTempSymbol("cfi");
273 emitLabel(Label);
274 return Label;
275 }
276
emitCFIStartProcImpl(MCDwarfFrameInfo & Frame)277 void MCObjectStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
278 // We need to create a local symbol to avoid relocations.
279 Frame.Begin = getContext().createTempSymbol();
280 emitLabel(Frame.Begin);
281 }
282
emitCFIEndProcImpl(MCDwarfFrameInfo & Frame)283 void MCObjectStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
284 Frame.End = getContext().createTempSymbol();
285 emitLabel(Frame.End);
286 }
287
emitLabel(MCSymbol * Symbol,SMLoc Loc)288 void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
289 MCStreamer::emitLabel(Symbol, Loc);
290
291 getAssembler().registerSymbol(*Symbol);
292
293 // If there is a current fragment, mark the symbol as pointing into it.
294 // Otherwise queue the label and set its fragment pointer when we emit the
295 // next fragment.
296 auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
297 if (F && !(getAssembler().isBundlingEnabled() &&
298 getAssembler().getRelaxAll())) {
299 Symbol->setFragment(F);
300 Symbol->setOffset(F->getContents().size());
301 } else {
302 // Assign all pending labels to offset 0 within the dummy "pending"
303 // fragment. (They will all be reassigned to a real fragment in
304 // flushPendingLabels())
305 Symbol->setOffset(0);
306 addPendingLabel(Symbol);
307 }
308
309 emitPendingAssignments(Symbol);
310 }
311
emitPendingAssignments(MCSymbol * Symbol)312 void MCObjectStreamer::emitPendingAssignments(MCSymbol *Symbol) {
313 auto Assignments = pendingAssignments.find(Symbol);
314 if (Assignments != pendingAssignments.end()) {
315 for (const PendingAssignment &A : Assignments->second)
316 emitAssignment(A.Symbol, A.Value);
317
318 pendingAssignments.erase(Assignments);
319 }
320 }
321
322 // Emit a label at a previously emitted fragment/offset position. This must be
323 // within the currently-active section.
emitLabelAtPos(MCSymbol * Symbol,SMLoc Loc,MCFragment * F,uint64_t Offset)324 void MCObjectStreamer::emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc,
325 MCFragment *F, uint64_t Offset) {
326 assert(F->getParent() == getCurrentSectionOnly());
327
328 MCStreamer::emitLabel(Symbol, Loc);
329 getAssembler().registerSymbol(*Symbol);
330 auto *DF = dyn_cast_or_null<MCDataFragment>(F);
331 Symbol->setOffset(Offset);
332 if (DF) {
333 Symbol->setFragment(F);
334 } else {
335 assert(isa<MCDummyFragment>(F) &&
336 "F must either be an MCDataFragment or the pending MCDummyFragment");
337 assert(Offset == 0);
338 addPendingLabel(Symbol);
339 }
340 }
341
emitULEB128Value(const MCExpr * Value)342 void MCObjectStreamer::emitULEB128Value(const MCExpr *Value) {
343 int64_t IntValue;
344 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
345 emitULEB128IntValue(IntValue);
346 return;
347 }
348 insert(new MCLEBFragment(*Value, false));
349 }
350
emitSLEB128Value(const MCExpr * Value)351 void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) {
352 int64_t IntValue;
353 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
354 emitSLEB128IntValue(IntValue);
355 return;
356 }
357 insert(new MCLEBFragment(*Value, true));
358 }
359
emitWeakReference(MCSymbol * Alias,const MCSymbol * Symbol)360 void MCObjectStreamer::emitWeakReference(MCSymbol *Alias,
361 const MCSymbol *Symbol) {
362 report_fatal_error("This file format doesn't support weak aliases.");
363 }
364
changeSection(MCSection * Section,const MCExpr * Subsection)365 void MCObjectStreamer::changeSection(MCSection *Section,
366 const MCExpr *Subsection) {
367 changeSectionImpl(Section, Subsection);
368 }
369
changeSectionImpl(MCSection * Section,const MCExpr * Subsection)370 bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
371 const MCExpr *Subsection) {
372 assert(Section && "Cannot switch to a null section!");
373 getContext().clearDwarfLocSeen();
374
375 bool Created = getAssembler().registerSection(*Section);
376
377 int64_t IntSubsection = 0;
378 if (Subsection &&
379 !Subsection->evaluateAsAbsolute(IntSubsection, getAssemblerPtr()))
380 report_fatal_error("Cannot evaluate subsection number");
381 if (IntSubsection < 0 || IntSubsection > 8192)
382 report_fatal_error("Subsection number out of range");
383 CurSubsectionIdx = unsigned(IntSubsection);
384 CurInsertionPoint =
385 Section->getSubsectionInsertionPoint(CurSubsectionIdx);
386 return Created;
387 }
388
emitAssignment(MCSymbol * Symbol,const MCExpr * Value)389 void MCObjectStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
390 getAssembler().registerSymbol(*Symbol);
391 MCStreamer::emitAssignment(Symbol, Value);
392 emitPendingAssignments(Symbol);
393 }
394
emitConditionalAssignment(MCSymbol * Symbol,const MCExpr * Value)395 void MCObjectStreamer::emitConditionalAssignment(MCSymbol *Symbol,
396 const MCExpr *Value) {
397 const MCSymbol *Target = &cast<MCSymbolRefExpr>(*Value).getSymbol();
398
399 // If the symbol already exists, emit the assignment. Otherwise, emit it
400 // later only if the symbol is also emitted.
401 if (Target->isRegistered())
402 emitAssignment(Symbol, Value);
403 else
404 pendingAssignments[Target].push_back({Symbol, Value});
405 }
406
mayHaveInstructions(MCSection & Sec) const407 bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
408 return Sec.hasInstructions();
409 }
410
emitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)411 void MCObjectStreamer::emitInstruction(const MCInst &Inst,
412 const MCSubtargetInfo &STI) {
413 const MCSection &Sec = *getCurrentSectionOnly();
414 if (Sec.isVirtualSection()) {
415 getContext().reportError(Inst.getLoc(), Twine(Sec.getVirtualSectionKind()) +
416 " section '" + Sec.getName() +
417 "' cannot have instructions");
418 return;
419 }
420 getAssembler().getBackend().emitInstructionBegin(*this, Inst, STI);
421 emitInstructionImpl(Inst, STI);
422 getAssembler().getBackend().emitInstructionEnd(*this, Inst);
423 }
424
emitInstructionImpl(const MCInst & Inst,const MCSubtargetInfo & STI)425 void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst,
426 const MCSubtargetInfo &STI) {
427 MCStreamer::emitInstruction(Inst, STI);
428
429 MCSection *Sec = getCurrentSectionOnly();
430 Sec->setHasInstructions(true);
431
432 // Now that a machine instruction has been assembled into this section, make
433 // a line entry for any .loc directive that has been seen.
434 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
435
436 // If this instruction doesn't need relaxation, just emit it as data.
437 MCAssembler &Assembler = getAssembler();
438 MCAsmBackend &Backend = Assembler.getBackend();
439 if (!(Backend.mayNeedRelaxation(Inst, STI) ||
440 Backend.allowEnhancedRelaxation())) {
441 emitInstToData(Inst, STI);
442 return;
443 }
444
445 // Otherwise, relax and emit it as data if either:
446 // - The RelaxAll flag was passed
447 // - Bundling is enabled and this instruction is inside a bundle-locked
448 // group. We want to emit all such instructions into the same data
449 // fragment.
450 if (Assembler.getRelaxAll() ||
451 (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
452 MCInst Relaxed = Inst;
453 while (Backend.mayNeedRelaxation(Relaxed, STI))
454 Backend.relaxInstruction(Relaxed, STI);
455 emitInstToData(Relaxed, STI);
456 return;
457 }
458
459 // Otherwise emit to a separate fragment.
460 emitInstToFragment(Inst, STI);
461 }
462
emitInstToFragment(const MCInst & Inst,const MCSubtargetInfo & STI)463 void MCObjectStreamer::emitInstToFragment(const MCInst &Inst,
464 const MCSubtargetInfo &STI) {
465 if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
466 llvm_unreachable("All instructions should have already been relaxed");
467
468 // Always create a new, separate fragment here, because its size can change
469 // during relaxation.
470 MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
471 insert(IF);
472
473 SmallString<128> Code;
474 raw_svector_ostream VecOS(Code);
475 getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
476 STI);
477 IF->getContents().append(Code.begin(), Code.end());
478 }
479
480 #ifndef NDEBUG
481 static const char *const BundlingNotImplementedMsg =
482 "Aligned bundling is not implemented for this object format";
483 #endif
484
emitBundleAlignMode(Align Alignment)485 void MCObjectStreamer::emitBundleAlignMode(Align Alignment) {
486 llvm_unreachable(BundlingNotImplementedMsg);
487 }
488
emitBundleLock(bool AlignToEnd)489 void MCObjectStreamer::emitBundleLock(bool AlignToEnd) {
490 llvm_unreachable(BundlingNotImplementedMsg);
491 }
492
emitBundleUnlock()493 void MCObjectStreamer::emitBundleUnlock() {
494 llvm_unreachable(BundlingNotImplementedMsg);
495 }
496
emitDwarfLocDirective(unsigned FileNo,unsigned Line,unsigned Column,unsigned Flags,unsigned Isa,unsigned Discriminator,StringRef FileName)497 void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
498 unsigned Column, unsigned Flags,
499 unsigned Isa,
500 unsigned Discriminator,
501 StringRef FileName) {
502 // In case we see two .loc directives in a row, make sure the
503 // first one gets a line entry.
504 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
505
506 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
507 Discriminator, FileName);
508 }
509
buildSymbolDiff(MCObjectStreamer & OS,const MCSymbol * A,const MCSymbol * B)510 static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
511 const MCSymbol *B) {
512 MCContext &Context = OS.getContext();
513 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
514 const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
515 const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
516 const MCExpr *AddrDelta =
517 MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
518 return AddrDelta;
519 }
520
emitDwarfSetLineAddr(MCObjectStreamer & OS,MCDwarfLineTableParams Params,int64_t LineDelta,const MCSymbol * Label,int PointerSize)521 static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
522 MCDwarfLineTableParams Params,
523 int64_t LineDelta, const MCSymbol *Label,
524 int PointerSize) {
525 // emit the sequence to set the address
526 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1);
527 OS.emitULEB128IntValue(PointerSize + 1);
528 OS.emitIntValue(dwarf::DW_LNE_set_address, 1);
529 OS.emitSymbolValue(Label, PointerSize);
530
531 // emit the sequence for the LineDelta (from 1) and a zero address delta.
532 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
533 }
534
emitDwarfAdvanceLineAddr(int64_t LineDelta,const MCSymbol * LastLabel,const MCSymbol * Label,unsigned PointerSize)535 void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
536 const MCSymbol *LastLabel,
537 const MCSymbol *Label,
538 unsigned PointerSize) {
539 if (!LastLabel) {
540 emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
541 Label, PointerSize);
542 return;
543 }
544 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
545 int64_t Res;
546 if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
547 MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
548 Res);
549 return;
550 }
551 insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
552 }
553
emitDwarfLineEndEntry(MCSection * Section,MCSymbol * LastLabel)554 void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
555 MCSymbol *LastLabel) {
556 // Emit a DW_LNE_end_sequence for the end of the section.
557 // Use the section end label to compute the address delta and use INT64_MAX
558 // as the line delta which is the signal that this is actually a
559 // DW_LNE_end_sequence.
560 MCSymbol *SectionEnd = endSection(Section);
561
562 // Switch back the dwarf line section, in case endSection had to switch the
563 // section.
564 MCContext &Ctx = getContext();
565 switchSection(Ctx.getObjectFileInfo()->getDwarfLineSection());
566
567 const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
568 emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
569 AsmInfo->getCodePointerSize());
570 }
571
emitDwarfAdvanceFrameAddr(const MCSymbol * LastLabel,const MCSymbol * Label)572 void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
573 const MCSymbol *Label) {
574 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
575 int64_t Res;
576 if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
577 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
578 return;
579 }
580 insert(new MCDwarfCallFrameFragment(*AddrDelta));
581 }
582
emitCVLocDirective(unsigned FunctionId,unsigned FileNo,unsigned Line,unsigned Column,bool PrologueEnd,bool IsStmt,StringRef FileName,SMLoc Loc)583 void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
584 unsigned Line, unsigned Column,
585 bool PrologueEnd, bool IsStmt,
586 StringRef FileName, SMLoc Loc) {
587 // Validate the directive.
588 if (!checkCVLocSection(FunctionId, FileNo, Loc))
589 return;
590
591 // Emit a label at the current position and record it in the CodeViewContext.
592 MCSymbol *LineSym = getContext().createTempSymbol();
593 emitLabel(LineSym);
594 getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId,
595 FileNo, Line, Column, PrologueEnd,
596 IsStmt);
597 }
598
emitCVLinetableDirective(unsigned FunctionId,const MCSymbol * Begin,const MCSymbol * End)599 void MCObjectStreamer::emitCVLinetableDirective(unsigned FunctionId,
600 const MCSymbol *Begin,
601 const MCSymbol *End) {
602 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
603 End);
604 this->MCStreamer::emitCVLinetableDirective(FunctionId, Begin, End);
605 }
606
emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,unsigned SourceFileId,unsigned SourceLineNum,const MCSymbol * FnStartSym,const MCSymbol * FnEndSym)607 void MCObjectStreamer::emitCVInlineLinetableDirective(
608 unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
609 const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {
610 getContext().getCVContext().emitInlineLineTableForFunction(
611 *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
612 FnEndSym);
613 this->MCStreamer::emitCVInlineLinetableDirective(
614 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
615 }
616
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,StringRef FixedSizePortion)617 void MCObjectStreamer::emitCVDefRangeDirective(
618 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
619 StringRef FixedSizePortion) {
620 MCFragment *Frag =
621 getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
622 // Attach labels that were pending before we created the defrange fragment to
623 // the beginning of the new fragment.
624 flushPendingLabels(Frag, 0);
625 this->MCStreamer::emitCVDefRangeDirective(Ranges, FixedSizePortion);
626 }
627
emitCVStringTableDirective()628 void MCObjectStreamer::emitCVStringTableDirective() {
629 getContext().getCVContext().emitStringTable(*this);
630 }
emitCVFileChecksumsDirective()631 void MCObjectStreamer::emitCVFileChecksumsDirective() {
632 getContext().getCVContext().emitFileChecksums(*this);
633 }
634
emitCVFileChecksumOffsetDirective(unsigned FileNo)635 void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
636 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
637 }
638
emitBytes(StringRef Data)639 void MCObjectStreamer::emitBytes(StringRef Data) {
640 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
641 MCDataFragment *DF = getOrCreateDataFragment();
642 flushPendingLabels(DF, DF->getContents().size());
643 DF->getContents().append(Data.begin(), Data.end());
644 }
645
emitValueToAlignment(Align Alignment,int64_t Value,unsigned ValueSize,unsigned MaxBytesToEmit)646 void MCObjectStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
647 unsigned ValueSize,
648 unsigned MaxBytesToEmit) {
649 if (MaxBytesToEmit == 0)
650 MaxBytesToEmit = Alignment.value();
651 insert(new MCAlignFragment(Alignment, Value, ValueSize, MaxBytesToEmit));
652
653 // Update the maximum alignment on the current section if necessary.
654 MCSection *CurSec = getCurrentSectionOnly();
655 CurSec->ensureMinAlignment(Alignment);
656 }
657
emitCodeAlignment(Align Alignment,const MCSubtargetInfo * STI,unsigned MaxBytesToEmit)658 void MCObjectStreamer::emitCodeAlignment(Align Alignment,
659 const MCSubtargetInfo *STI,
660 unsigned MaxBytesToEmit) {
661 emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit);
662 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true, STI);
663 }
664
emitValueToOffset(const MCExpr * Offset,unsigned char Value,SMLoc Loc)665 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
666 unsigned char Value,
667 SMLoc Loc) {
668 insert(new MCOrgFragment(*Offset, Value, Loc));
669 }
670
671 // Associate DTPRel32 fixup with data and resize data area
emitDTPRel32Value(const MCExpr * Value)672 void MCObjectStreamer::emitDTPRel32Value(const MCExpr *Value) {
673 MCDataFragment *DF = getOrCreateDataFragment();
674 flushPendingLabels(DF, DF->getContents().size());
675
676 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
677 Value, FK_DTPRel_4));
678 DF->getContents().resize(DF->getContents().size() + 4, 0);
679 }
680
681 // Associate DTPRel64 fixup with data and resize data area
emitDTPRel64Value(const MCExpr * Value)682 void MCObjectStreamer::emitDTPRel64Value(const MCExpr *Value) {
683 MCDataFragment *DF = getOrCreateDataFragment();
684 flushPendingLabels(DF, DF->getContents().size());
685
686 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
687 Value, FK_DTPRel_8));
688 DF->getContents().resize(DF->getContents().size() + 8, 0);
689 }
690
691 // Associate TPRel32 fixup with data and resize data area
emitTPRel32Value(const MCExpr * Value)692 void MCObjectStreamer::emitTPRel32Value(const MCExpr *Value) {
693 MCDataFragment *DF = getOrCreateDataFragment();
694 flushPendingLabels(DF, DF->getContents().size());
695
696 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
697 Value, FK_TPRel_4));
698 DF->getContents().resize(DF->getContents().size() + 4, 0);
699 }
700
701 // Associate TPRel64 fixup with data and resize data area
emitTPRel64Value(const MCExpr * Value)702 void MCObjectStreamer::emitTPRel64Value(const MCExpr *Value) {
703 MCDataFragment *DF = getOrCreateDataFragment();
704 flushPendingLabels(DF, DF->getContents().size());
705
706 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
707 Value, FK_TPRel_8));
708 DF->getContents().resize(DF->getContents().size() + 8, 0);
709 }
710
711 // Associate GPRel32 fixup with data and resize data area
emitGPRel32Value(const MCExpr * Value)712 void MCObjectStreamer::emitGPRel32Value(const MCExpr *Value) {
713 MCDataFragment *DF = getOrCreateDataFragment();
714 flushPendingLabels(DF, DF->getContents().size());
715
716 DF->getFixups().push_back(
717 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
718 DF->getContents().resize(DF->getContents().size() + 4, 0);
719 }
720
721 // Associate GPRel64 fixup with data and resize data area
emitGPRel64Value(const MCExpr * Value)722 void MCObjectStreamer::emitGPRel64Value(const MCExpr *Value) {
723 MCDataFragment *DF = getOrCreateDataFragment();
724 flushPendingLabels(DF, DF->getContents().size());
725
726 DF->getFixups().push_back(
727 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
728 DF->getContents().resize(DF->getContents().size() + 8, 0);
729 }
730
731 static std::optional<std::pair<bool, std::string>>
getOffsetAndDataFragment(const MCSymbol & Symbol,uint32_t & RelocOffset,MCDataFragment * & DF)732 getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset,
733 MCDataFragment *&DF) {
734 if (Symbol.isVariable()) {
735 const MCExpr *SymbolExpr = Symbol.getVariableValue();
736 MCValue OffsetVal;
737 if(!SymbolExpr->evaluateAsRelocatable(OffsetVal, nullptr, nullptr))
738 return std::make_pair(false,
739 std::string("symbol in .reloc offset is not "
740 "relocatable"));
741 if (OffsetVal.isAbsolute()) {
742 RelocOffset = OffsetVal.getConstant();
743 MCFragment *Fragment = Symbol.getFragment();
744 // FIXME Support symbols with no DF. For example:
745 // .reloc .data, ENUM_VALUE, <some expr>
746 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
747 return std::make_pair(false,
748 std::string("symbol in offset has no data "
749 "fragment"));
750 DF = cast<MCDataFragment>(Fragment);
751 return std::nullopt;
752 }
753
754 if (OffsetVal.getSymB())
755 return std::make_pair(false,
756 std::string(".reloc symbol offset is not "
757 "representable"));
758
759 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
760 if (!SRE.getSymbol().isDefined())
761 return std::make_pair(false,
762 std::string("symbol used in the .reloc offset is "
763 "not defined"));
764
765 if (SRE.getSymbol().isVariable())
766 return std::make_pair(false,
767 std::string("symbol used in the .reloc offset is "
768 "variable"));
769
770 MCFragment *Fragment = SRE.getSymbol().getFragment();
771 // FIXME Support symbols with no DF. For example:
772 // .reloc .data, ENUM_VALUE, <some expr>
773 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
774 return std::make_pair(false,
775 std::string("symbol in offset has no data "
776 "fragment"));
777 RelocOffset = SRE.getSymbol().getOffset() + OffsetVal.getConstant();
778 DF = cast<MCDataFragment>(Fragment);
779 } else {
780 RelocOffset = Symbol.getOffset();
781 MCFragment *Fragment = Symbol.getFragment();
782 // FIXME Support symbols with no DF. For example:
783 // .reloc .data, ENUM_VALUE, <some expr>
784 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
785 return std::make_pair(false,
786 std::string("symbol in offset has no data "
787 "fragment"));
788 DF = cast<MCDataFragment>(Fragment);
789 }
790 return std::nullopt;
791 }
792
793 std::optional<std::pair<bool, std::string>>
emitRelocDirective(const MCExpr & Offset,StringRef Name,const MCExpr * Expr,SMLoc Loc,const MCSubtargetInfo & STI)794 MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
795 const MCExpr *Expr, SMLoc Loc,
796 const MCSubtargetInfo &STI) {
797 std::optional<MCFixupKind> MaybeKind =
798 Assembler->getBackend().getFixupKind(Name);
799 if (!MaybeKind)
800 return std::make_pair(true, std::string("unknown relocation name"));
801
802 MCFixupKind Kind = *MaybeKind;
803
804 if (Expr == nullptr)
805 Expr =
806 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
807
808 MCDataFragment *DF = getOrCreateDataFragment(&STI);
809 flushPendingLabels(DF, DF->getContents().size());
810
811 MCValue OffsetVal;
812 if (!Offset.evaluateAsRelocatable(OffsetVal, nullptr, nullptr))
813 return std::make_pair(false,
814 std::string(".reloc offset is not relocatable"));
815 if (OffsetVal.isAbsolute()) {
816 if (OffsetVal.getConstant() < 0)
817 return std::make_pair(false, std::string(".reloc offset is negative"));
818 DF->getFixups().push_back(
819 MCFixup::create(OffsetVal.getConstant(), Expr, Kind, Loc));
820 return std::nullopt;
821 }
822 if (OffsetVal.getSymB())
823 return std::make_pair(false,
824 std::string(".reloc offset is not representable"));
825
826 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
827 const MCSymbol &Symbol = SRE.getSymbol();
828 if (Symbol.isDefined()) {
829 uint32_t SymbolOffset = 0;
830 std::optional<std::pair<bool, std::string>> Error =
831 getOffsetAndDataFragment(Symbol, SymbolOffset, DF);
832
833 if (Error != std::nullopt)
834 return Error;
835
836 DF->getFixups().push_back(
837 MCFixup::create(SymbolOffset + OffsetVal.getConstant(),
838 Expr, Kind, Loc));
839 return std::nullopt;
840 }
841
842 PendingFixups.emplace_back(
843 &SRE.getSymbol(), DF,
844 MCFixup::create(OffsetVal.getConstant(), Expr, Kind, Loc));
845 return std::nullopt;
846 }
847
emitFill(const MCExpr & NumBytes,uint64_t FillValue,SMLoc Loc)848 void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
849 SMLoc Loc) {
850 MCDataFragment *DF = getOrCreateDataFragment();
851 flushPendingLabels(DF, DF->getContents().size());
852
853 assert(getCurrentSectionOnly() && "need a section");
854 insert(new MCFillFragment(FillValue, 1, NumBytes, Loc));
855 }
856
emitFill(const MCExpr & NumValues,int64_t Size,int64_t Expr,SMLoc Loc)857 void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
858 int64_t Expr, SMLoc Loc) {
859 int64_t IntNumValues;
860 // Do additional checking now if we can resolve the value.
861 if (NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) {
862 if (IntNumValues < 0) {
863 getContext().getSourceManager()->PrintMessage(
864 Loc, SourceMgr::DK_Warning,
865 "'.fill' directive with negative repeat count has no effect");
866 return;
867 }
868 // Emit now if we can for better errors.
869 int64_t NonZeroSize = Size > 4 ? 4 : Size;
870 Expr &= ~0ULL >> (64 - NonZeroSize * 8);
871 for (uint64_t i = 0, e = IntNumValues; i != e; ++i) {
872 emitIntValue(Expr, NonZeroSize);
873 if (NonZeroSize < Size)
874 emitIntValue(0, Size - NonZeroSize);
875 }
876 return;
877 }
878
879 // Otherwise emit as fragment.
880 MCDataFragment *DF = getOrCreateDataFragment();
881 flushPendingLabels(DF, DF->getContents().size());
882
883 assert(getCurrentSectionOnly() && "need a section");
884 insert(new MCFillFragment(Expr, Size, NumValues, Loc));
885 }
886
emitNops(int64_t NumBytes,int64_t ControlledNopLength,SMLoc Loc,const MCSubtargetInfo & STI)887 void MCObjectStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLength,
888 SMLoc Loc, const MCSubtargetInfo &STI) {
889 // Emit an NOP fragment.
890 MCDataFragment *DF = getOrCreateDataFragment();
891 flushPendingLabels(DF, DF->getContents().size());
892
893 assert(getCurrentSectionOnly() && "need a section");
894
895 insert(new MCNopsFragment(NumBytes, ControlledNopLength, Loc, STI));
896 }
897
emitFileDirective(StringRef Filename)898 void MCObjectStreamer::emitFileDirective(StringRef Filename) {
899 getAssembler().addFileName(Filename);
900 }
901
emitFileDirective(StringRef Filename,StringRef CompilerVerion,StringRef TimeStamp,StringRef Description)902 void MCObjectStreamer::emitFileDirective(StringRef Filename,
903 StringRef CompilerVerion,
904 StringRef TimeStamp,
905 StringRef Description) {
906 getAssembler().addFileName(Filename);
907 // TODO: add additional info to integrated assembler.
908 }
909
emitAddrsig()910 void MCObjectStreamer::emitAddrsig() {
911 getAssembler().getWriter().emitAddrsigSection();
912 }
913
emitAddrsigSym(const MCSymbol * Sym)914 void MCObjectStreamer::emitAddrsigSym(const MCSymbol *Sym) {
915 getAssembler().getWriter().addAddrsigSymbol(Sym);
916 }
917
finishImpl()918 void MCObjectStreamer::finishImpl() {
919 getContext().RemapDebugPaths();
920
921 // If we are generating dwarf for assembly source files dump out the sections.
922 if (getContext().getGenDwarfForAssembly())
923 MCGenDwarfInfo::Emit(this);
924
925 // Dump out the dwarf file & directory tables and line tables.
926 MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
927
928 // Emit pseudo probes for the current module.
929 MCPseudoProbeTable::emit(this);
930
931 // Update any remaining pending labels with empty data fragments.
932 flushPendingLabels();
933
934 resolvePendingFixups();
935 getAssembler().Finish();
936 }
937