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