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