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