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