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