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