]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/MC/MCObjectStreamer.cpp
Merge ^/head r318560 through r318657.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / MC / MCObjectStreamer.cpp
1 //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/MC/MCObjectStreamer.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/MC/MCAsmBackend.h"
13 #include "llvm/MC/MCAsmInfo.h"
14 #include "llvm/MC/MCAssembler.h"
15 #include "llvm/MC/MCCodeEmitter.h"
16 #include "llvm/MC/MCCodeView.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCDwarf.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCObjectWriter.h"
21 #include "llvm/MC/MCSection.h"
22 #include "llvm/MC/MCSymbol.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/SourceMgr.h"
25 #include "llvm/Support/TargetRegistry.h"
26 using namespace llvm;
27
28 MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
29                                    raw_pwrite_stream &OS,
30                                    MCCodeEmitter *Emitter_)
31     : MCStreamer(Context),
32       Assembler(new MCAssembler(Context, TAB, *Emitter_,
33                                 *TAB.createObjectWriter(OS))),
34       EmitEHFrame(true), EmitDebugFrame(false) {}
35
36 MCObjectStreamer::~MCObjectStreamer() {
37   delete &Assembler->getBackend();
38   delete &Assembler->getEmitter();
39   delete &Assembler->getWriter();
40   delete Assembler;
41 }
42
43 void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
44   if (PendingLabels.empty())
45     return;
46   if (!F) {
47     F = new MCDataFragment();
48     MCSection *CurSection = getCurrentSectionOnly();
49     CurSection->getFragmentList().insert(CurInsertionPoint, F);
50     F->setParent(CurSection);
51   }
52   for (MCSymbol *Sym : PendingLabels) {
53     Sym->setFragment(F);
54     Sym->setOffset(FOffset);
55   }
56   PendingLabels.clear();
57 }
58
59 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
60                                               const MCSymbol *Lo,
61                                               unsigned Size) {
62   // If not assigned to the same (valid) fragment, fallback.
63   if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
64       Hi->isVariable() || Lo->isVariable()) {
65     MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
66     return;
67   }
68
69   EmitIntValue(Hi->getOffset() - Lo->getOffset(), Size);
70 }
71
72 void MCObjectStreamer::reset() {
73   if (Assembler)
74     Assembler->reset();
75   CurInsertionPoint = MCSection::iterator();
76   EmitEHFrame = true;
77   EmitDebugFrame = false;
78   PendingLabels.clear();
79   MCStreamer::reset();
80 }
81
82 void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
83   if (!getNumFrameInfos())
84     return;
85
86   if (EmitEHFrame)
87     MCDwarfFrameEmitter::Emit(*this, MAB, true);
88
89   if (EmitDebugFrame)
90     MCDwarfFrameEmitter::Emit(*this, MAB, false);
91 }
92
93 MCFragment *MCObjectStreamer::getCurrentFragment() const {
94   assert(getCurrentSectionOnly() && "No current section!");
95
96   if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
97     return &*std::prev(CurInsertionPoint);
98
99   return nullptr;
100 }
101
102 MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() {
103   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
104   // When bundling is enabled, we don't want to add data to a fragment that
105   // already has instructions (see MCELFStreamer::EmitInstToData for details)
106   if (!F || (Assembler->isBundlingEnabled() && !Assembler->getRelaxAll() &&
107              F->hasInstructions())) {
108     F = new MCDataFragment();
109     insert(F);
110   }
111   return F;
112 }
113
114 void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
115   Assembler->registerSymbol(Sym);
116 }
117
118 void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
119   MCStreamer::EmitCFISections(EH, Debug);
120   EmitEHFrame = EH;
121   EmitDebugFrame = Debug;
122 }
123
124 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
125                                      SMLoc Loc) {
126   MCStreamer::EmitValueImpl(Value, Size, Loc);
127   MCDataFragment *DF = getOrCreateDataFragment();
128   flushPendingLabels(DF, DF->getContents().size());
129
130   MCCVLineEntry::Make(this);
131   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
132
133   // Avoid fixups when possible.
134   int64_t AbsValue;
135   if (Value->evaluateAsAbsolute(AbsValue, getAssembler())) {
136     if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
137       getContext().reportError(
138           Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");
139       return;
140     }
141     EmitIntValue(AbsValue, Size);
142     return;
143   }
144   DF->getFixups().push_back(
145       MCFixup::create(DF->getContents().size(), Value,
146                       MCFixup::getKindForSize(Size, false), Loc));
147   DF->getContents().resize(DF->getContents().size() + Size, 0);
148 }
149
150 void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
151   // We need to create a local symbol to avoid relocations.
152   Frame.Begin = getContext().createTempSymbol();
153   EmitLabel(Frame.Begin);
154 }
155
156 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
157   Frame.End = getContext().createTempSymbol();
158   EmitLabel(Frame.End);
159 }
160
161 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
162   MCStreamer::EmitLabel(Symbol, Loc);
163
164   getAssembler().registerSymbol(*Symbol);
165
166   // If there is a current fragment, mark the symbol as pointing into it.
167   // Otherwise queue the label and set its fragment pointer when we emit the
168   // next fragment.
169   auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
170   if (F && !(getAssembler().isBundlingEnabled() &&
171              getAssembler().getRelaxAll())) {
172     Symbol->setFragment(F);
173     Symbol->setOffset(F->getContents().size());
174   } else {
175     PendingLabels.push_back(Symbol);
176   }
177 }
178
179 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) {
180   MCStreamer::EmitLabel(Symbol, Loc);
181   getAssembler().registerSymbol(*Symbol);
182   auto *DF = dyn_cast_or_null<MCDataFragment>(F);
183   if (DF)
184     Symbol->setFragment(F);
185   else
186     PendingLabels.push_back(Symbol);
187 }
188
189 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
190   int64_t IntValue;
191   if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {
192     EmitULEB128IntValue(IntValue);
193     return;
194   }
195   insert(new MCLEBFragment(*Value, false));
196 }
197
198 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
199   int64_t IntValue;
200   if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {
201     EmitSLEB128IntValue(IntValue);
202     return;
203   }
204   insert(new MCLEBFragment(*Value, true));
205 }
206
207 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
208                                          const MCSymbol *Symbol) {
209   report_fatal_error("This file format doesn't support weak aliases.");
210 }
211
212 void MCObjectStreamer::ChangeSection(MCSection *Section,
213                                      const MCExpr *Subsection) {
214   changeSectionImpl(Section, Subsection);
215 }
216
217 bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
218                                          const MCExpr *Subsection) {
219   assert(Section && "Cannot switch to a null section!");
220   flushPendingLabels(nullptr);
221   getContext().clearDwarfLocSeen();
222
223   bool Created = getAssembler().registerSection(*Section);
224
225   int64_t IntSubsection = 0;
226   if (Subsection &&
227       !Subsection->evaluateAsAbsolute(IntSubsection, getAssembler()))
228     report_fatal_error("Cannot evaluate subsection number");
229   if (IntSubsection < 0 || IntSubsection > 8192)
230     report_fatal_error("Subsection number out of range");
231   CurInsertionPoint =
232       Section->getSubsectionInsertionPoint(unsigned(IntSubsection));
233   return Created;
234 }
235
236 void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
237   getAssembler().registerSymbol(*Symbol);
238   MCStreamer::EmitAssignment(Symbol, Value);
239 }
240
241 bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
242   return Sec.hasInstructions();
243 }
244
245 void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
246                                        const MCSubtargetInfo &STI, bool) {
247   MCStreamer::EmitInstruction(Inst, STI);
248
249   MCSection *Sec = getCurrentSectionOnly();
250   Sec->setHasInstructions(true);
251
252   // Now that a machine instruction has been assembled into this section, make
253   // a line entry for any .loc directive that has been seen.
254   MCCVLineEntry::Make(this);
255   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
256
257   // If this instruction doesn't need relaxation, just emit it as data.
258   MCAssembler &Assembler = getAssembler();
259   if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
260     EmitInstToData(Inst, STI);
261     return;
262   }
263
264   // Otherwise, relax and emit it as data if either:
265   // - The RelaxAll flag was passed
266   // - Bundling is enabled and this instruction is inside a bundle-locked
267   //   group. We want to emit all such instructions into the same data
268   //   fragment.
269   if (Assembler.getRelaxAll() ||
270       (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
271     MCInst Relaxed;
272     getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
273     while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
274       getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
275     EmitInstToData(Relaxed, STI);
276     return;
277   }
278
279   // Otherwise emit to a separate fragment.
280   EmitInstToFragment(Inst, STI);
281 }
282
283 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
284                                           const MCSubtargetInfo &STI) {
285   if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
286     llvm_unreachable("All instructions should have already been relaxed");
287
288   // Always create a new, separate fragment here, because its size can change
289   // during relaxation.
290   MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
291   insert(IF);
292
293   SmallString<128> Code;
294   raw_svector_ostream VecOS(Code);
295   getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
296                                                 STI);
297   IF->getContents().append(Code.begin(), Code.end());
298 }
299
300 #ifndef NDEBUG
301 static const char *const BundlingNotImplementedMsg =
302   "Aligned bundling is not implemented for this object format";
303 #endif
304
305 void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
306   llvm_unreachable(BundlingNotImplementedMsg);
307 }
308
309 void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
310   llvm_unreachable(BundlingNotImplementedMsg);
311 }
312
313 void MCObjectStreamer::EmitBundleUnlock() {
314   llvm_unreachable(BundlingNotImplementedMsg);
315 }
316
317 void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
318                                              unsigned Column, unsigned Flags,
319                                              unsigned Isa,
320                                              unsigned Discriminator,
321                                              StringRef FileName) {
322   // In case we see two .loc directives in a row, make sure the
323   // first one gets a line entry.
324   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
325
326   this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
327                                           Isa, Discriminator, FileName);
328 }
329
330 static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
331                                      const MCSymbol *B) {
332   MCContext &Context = OS.getContext();
333   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
334   const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
335   const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
336   const MCExpr *AddrDelta =
337       MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
338   return AddrDelta;
339 }
340
341 static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
342                                  MCDwarfLineTableParams Params,
343                                  int64_t LineDelta, const MCSymbol *Label,
344                                  int PointerSize) {
345   // emit the sequence to set the address
346   OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1);
347   OS.EmitULEB128IntValue(PointerSize + 1);
348   OS.EmitIntValue(dwarf::DW_LNE_set_address, 1);
349   OS.EmitSymbolValue(Label, PointerSize);
350
351   // emit the sequence for the LineDelta (from 1) and a zero address delta.
352   MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
353 }
354
355 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
356                                                 const MCSymbol *LastLabel,
357                                                 const MCSymbol *Label,
358                                                 unsigned PointerSize) {
359   if (!LastLabel) {
360     emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
361                          Label, PointerSize);
362     return;
363   }
364   const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
365   int64_t Res;
366   if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) {
367     MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
368                           Res);
369     return;
370   }
371   insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
372 }
373
374 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
375                                                  const MCSymbol *Label) {
376   const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
377   int64_t Res;
378   if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) {
379     MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
380     return;
381   }
382   insert(new MCDwarfCallFrameFragment(*AddrDelta));
383 }
384
385 void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
386                                           unsigned Line, unsigned Column,
387                                           bool PrologueEnd, bool IsStmt,
388                                           StringRef FileName, SMLoc Loc) {
389   // In case we see two .cv_loc directives in a row, make sure the
390   // first one gets a line entry.
391   MCCVLineEntry::Make(this);
392
393   this->MCStreamer::EmitCVLocDirective(FunctionId, FileNo, Line, Column,
394                                        PrologueEnd, IsStmt, FileName, Loc);
395 }
396
397 void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
398                                                 const MCSymbol *Begin,
399                                                 const MCSymbol *End) {
400   getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
401                                                        End);
402   this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End);
403 }
404
405 void MCObjectStreamer::EmitCVInlineLinetableDirective(
406     unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
407     const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {
408   getContext().getCVContext().emitInlineLineTableForFunction(
409       *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
410       FnEndSym);
411   this->MCStreamer::EmitCVInlineLinetableDirective(
412       PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
413 }
414
415 void MCObjectStreamer::EmitCVDefRangeDirective(
416     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
417     StringRef FixedSizePortion) {
418   getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
419   this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
420 }
421
422 void MCObjectStreamer::EmitCVStringTableDirective() {
423   getContext().getCVContext().emitStringTable(*this);
424 }
425 void MCObjectStreamer::EmitCVFileChecksumsDirective() {
426   getContext().getCVContext().emitFileChecksums(*this);
427 }
428
429
430 void MCObjectStreamer::EmitBytes(StringRef Data) {
431   MCCVLineEntry::Make(this);
432   MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
433   MCDataFragment *DF = getOrCreateDataFragment();
434   flushPendingLabels(DF, DF->getContents().size());
435   DF->getContents().append(Data.begin(), Data.end());
436 }
437
438 void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
439                                             int64_t Value,
440                                             unsigned ValueSize,
441                                             unsigned MaxBytesToEmit) {
442   if (MaxBytesToEmit == 0)
443     MaxBytesToEmit = ByteAlignment;
444   insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
445
446   // Update the maximum alignment on the current section if necessary.
447   MCSection *CurSec = getCurrentSectionOnly();
448   if (ByteAlignment > CurSec->getAlignment())
449     CurSec->setAlignment(ByteAlignment);
450 }
451
452 void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
453                                          unsigned MaxBytesToEmit) {
454   EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
455   cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
456 }
457
458 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
459                                          unsigned char Value,
460                                          SMLoc Loc) {
461   insert(new MCOrgFragment(*Offset, Value, Loc));
462 }
463
464 // Associate DTPRel32 fixup with data and resize data area
465 void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) {
466   MCDataFragment *DF = getOrCreateDataFragment();
467   flushPendingLabels(DF, DF->getContents().size());
468
469   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
470                                             Value, FK_DTPRel_4));
471   DF->getContents().resize(DF->getContents().size() + 4, 0);
472 }
473
474 // Associate DTPRel64 fixup with data and resize data area
475 void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) {
476   MCDataFragment *DF = getOrCreateDataFragment();
477   flushPendingLabels(DF, DF->getContents().size());
478
479   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
480                                             Value, FK_DTPRel_8));
481   DF->getContents().resize(DF->getContents().size() + 8, 0);
482 }
483
484 // Associate TPRel32 fixup with data and resize data area
485 void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) {
486   MCDataFragment *DF = getOrCreateDataFragment();
487   flushPendingLabels(DF, DF->getContents().size());
488
489   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
490                                             Value, FK_TPRel_4));
491   DF->getContents().resize(DF->getContents().size() + 4, 0);
492 }
493
494 // Associate TPRel64 fixup with data and resize data area
495 void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) {
496   MCDataFragment *DF = getOrCreateDataFragment();
497   flushPendingLabels(DF, DF->getContents().size());
498
499   DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
500                                             Value, FK_TPRel_8));
501   DF->getContents().resize(DF->getContents().size() + 8, 0);
502 }
503
504 // Associate GPRel32 fixup with data and resize data area
505 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
506   MCDataFragment *DF = getOrCreateDataFragment();
507   flushPendingLabels(DF, DF->getContents().size());
508
509   DF->getFixups().push_back(
510       MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
511   DF->getContents().resize(DF->getContents().size() + 4, 0);
512 }
513
514 // Associate GPRel64 fixup with data and resize data area
515 void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
516   MCDataFragment *DF = getOrCreateDataFragment();
517   flushPendingLabels(DF, DF->getContents().size());
518
519   DF->getFixups().push_back(
520       MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
521   DF->getContents().resize(DF->getContents().size() + 8, 0);
522 }
523
524 bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
525                                           const MCExpr *Expr, SMLoc Loc) {
526   int64_t OffsetValue;
527   if (!Offset.evaluateAsAbsolute(OffsetValue))
528     llvm_unreachable("Offset is not absolute");
529
530   if (OffsetValue < 0)
531     llvm_unreachable("Offset is negative");
532
533   MCDataFragment *DF = getOrCreateDataFragment();
534   flushPendingLabels(DF, DF->getContents().size());
535
536   Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name);
537   if (!MaybeKind.hasValue())
538     return true;
539
540   MCFixupKind Kind = *MaybeKind;
541
542   if (Expr == nullptr)
543     Expr =
544         MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
545   DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc));
546   return false;
547 }
548
549 void MCObjectStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
550   assert(getCurrentSectionOnly() && "need a section");
551   insert(new MCFillFragment(FillValue, NumBytes));
552 }
553
554 void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
555                                 SMLoc Loc) {
556   MCDataFragment *DF = getOrCreateDataFragment();
557   flushPendingLabels(DF, DF->getContents().size());
558
559   int64_t IntNumBytes;
560   if (!NumBytes.evaluateAsAbsolute(IntNumBytes, getAssembler())) {
561     getContext().reportError(Loc, "expected absolute expression");
562     return;
563   }
564
565   if (IntNumBytes <= 0) {
566     getContext().reportError(Loc, "invalid number of bytes");
567     return;
568   }
569
570   emitFill(IntNumBytes, FillValue);
571 }
572
573 void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
574                                 int64_t Expr, SMLoc Loc) {
575   int64_t IntNumValues;
576   if (!NumValues.evaluateAsAbsolute(IntNumValues, getAssembler())) {
577     getContext().reportError(Loc, "expected absolute expression");
578     return;
579   }
580
581   if (IntNumValues < 0) {
582     getContext().getSourceManager()->PrintMessage(
583         Loc, SourceMgr::DK_Warning,
584         "'.fill' directive with negative repeat count has no effect");
585     return;
586   }
587
588   MCStreamer::emitFill(IntNumValues, Size, Expr);
589 }
590
591 void MCObjectStreamer::EmitFileDirective(StringRef Filename) {
592   getAssembler().addFileName(Filename);
593 }
594
595 void MCObjectStreamer::FinishImpl() {
596   // If we are generating dwarf for assembly source files dump out the sections.
597   if (getContext().getGenDwarfForAssembly())
598     MCGenDwarfInfo::Emit(this);
599
600   // Dump out the dwarf file & directory tables and line tables.
601   MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
602
603   flushPendingLabels(nullptr);
604   getAssembler().Finish();
605 }