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