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