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