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