1 //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/MC/MCObjectStreamer.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/MC/MCAsmBackend.h"
12 #include "llvm/MC/MCAssembler.h"
13 #include "llvm/MC/MCCodeEmitter.h"
14 #include "llvm/MC/MCCodeView.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCDwarf.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCObjectWriter.h"
19 #include "llvm/MC/MCSection.h"
20 #include "llvm/MC/MCSymbol.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/SourceMgr.h"
23 using namespace llvm;
24
MCObjectStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> TAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter)25 MCObjectStreamer::MCObjectStreamer(MCContext &Context,
26 std::unique_ptr<MCAsmBackend> TAB,
27 std::unique_ptr<MCObjectWriter> OW,
28 std::unique_ptr<MCCodeEmitter> Emitter)
29 : MCStreamer(Context),
30 Assembler(std::make_unique<MCAssembler>(
31 Context, std::move(TAB), std::move(Emitter), std::move(OW))),
32 EmitEHFrame(true), EmitDebugFrame(false) {
33 if (Assembler->getBackendPtr())
34 setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
35 }
36
~MCObjectStreamer()37 MCObjectStreamer::~MCObjectStreamer() {}
38
39 // AssemblerPtr is used for evaluation of expressions and causes
40 // difference between asm and object outputs. Return nullptr to in
41 // inline asm mode to limit divergence to assembly inputs.
getAssemblerPtr()42 MCAssembler *MCObjectStreamer::getAssemblerPtr() {
43 if (getUseAssemblerInfoForParsing())
44 return Assembler.get();
45 return nullptr;
46 }
47
addPendingLabel(MCSymbol * S)48 void MCObjectStreamer::addPendingLabel(MCSymbol* S) {
49 MCSection *CurSection = getCurrentSectionOnly();
50 if (CurSection) {
51 // Register labels that have not yet been assigned to a Section.
52 if (!PendingLabels.empty()) {
53 for (MCSymbol* Sym : PendingLabels)
54 CurSection->addPendingLabel(Sym);
55 PendingLabels.clear();
56 }
57
58 // Add this label to the current Section / Subsection.
59 CurSection->addPendingLabel(S, CurSubsectionIdx);
60
61 // Add this Section to the list of PendingLabelSections.
62 auto SecIt = std::find(PendingLabelSections.begin(),
63 PendingLabelSections.end(), CurSection);
64 if (SecIt == PendingLabelSections.end())
65 PendingLabelSections.push_back(CurSection);
66 }
67 else
68 // There is no Section / Subsection for this label yet.
69 PendingLabels.push_back(S);
70 }
71
flushPendingLabels(MCFragment * F,uint64_t FOffset)72 void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
73 MCSection *CurSection = getCurrentSectionOnly();
74 if (!CurSection) {
75 assert(PendingLabels.empty());
76 return;
77 }
78 // Register labels that have not yet been assigned to a Section.
79 if (!PendingLabels.empty()) {
80 for (MCSymbol* Sym : PendingLabels)
81 CurSection->addPendingLabel(Sym, CurSubsectionIdx);
82 PendingLabels.clear();
83 }
84
85 // Associate a fragment with this label, either the supplied fragment
86 // or an empty data fragment.
87 if (F)
88 CurSection->flushPendingLabels(F, FOffset, CurSubsectionIdx);
89 else
90 CurSection->flushPendingLabels(nullptr, 0, CurSubsectionIdx);
91 }
92
flushPendingLabels()93 void MCObjectStreamer::flushPendingLabels() {
94 // Register labels that have not yet been assigned to a Section.
95 if (!PendingLabels.empty()) {
96 MCSection *CurSection = getCurrentSectionOnly();
97 assert(CurSection);
98 for (MCSymbol* Sym : PendingLabels)
99 CurSection->addPendingLabel(Sym, CurSubsectionIdx);
100 PendingLabels.clear();
101 }
102
103 // Assign an empty data fragment to all remaining pending labels.
104 for (MCSection* Section : PendingLabelSections)
105 Section->flushPendingLabels();
106 }
107
108 // When fixup's offset is a forward declared label, e.g.:
109 //
110 // .reloc 1f, R_MIPS_JALR, foo
111 // 1: nop
112 //
113 // postpone adding it to Fixups vector until the label is defined and its offset
114 // is known.
resolvePendingFixups()115 void MCObjectStreamer::resolvePendingFixups() {
116 for (PendingMCFixup &PendingFixup : PendingFixups) {
117 if (!PendingFixup.Sym || PendingFixup.Sym->isUndefined ()) {
118 getContext().reportError(PendingFixup.Fixup.getLoc(),
119 "unresolved relocation offset");
120 continue;
121 }
122 flushPendingLabels(PendingFixup.DF, PendingFixup.DF->getContents().size());
123 PendingFixup.Fixup.setOffset(PendingFixup.Sym->getOffset());
124 PendingFixup.DF->getFixups().push_back(PendingFixup.Fixup);
125 }
126 PendingFixups.clear();
127 }
128
129 // As a compile-time optimization, avoid allocating and evaluating an MCExpr
130 // tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
131 static Optional<uint64_t>
absoluteSymbolDiff(MCAssembler & Asm,const MCSymbol * Hi,const MCSymbol * Lo)132 absoluteSymbolDiff(MCAssembler &Asm, const MCSymbol *Hi, const MCSymbol *Lo) {
133 assert(Hi && Lo);
134 if (Asm.getBackendPtr()->requiresDiffExpressionRelocations())
135 return None;
136
137 if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
138 Hi->isVariable() || Lo->isVariable())
139 return None;
140
141 return Hi->getOffset() - Lo->getOffset();
142 }
143
emitAbsoluteSymbolDiff(const MCSymbol * Hi,const MCSymbol * Lo,unsigned Size)144 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
145 const MCSymbol *Lo,
146 unsigned Size) {
147 if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
148 EmitIntValue(*Diff, Size);
149 return;
150 }
151 MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
152 }
153
emitAbsoluteSymbolDiffAsULEB128(const MCSymbol * Hi,const MCSymbol * Lo)154 void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
155 const MCSymbol *Lo) {
156 if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
157 EmitULEB128IntValue(*Diff);
158 return;
159 }
160 MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
161 }
162
reset()163 void MCObjectStreamer::reset() {
164 if (Assembler)
165 Assembler->reset();
166 CurInsertionPoint = MCSection::iterator();
167 EmitEHFrame = true;
168 EmitDebugFrame = false;
169 PendingLabels.clear();
170 PendingLabelSections.clear();
171 MCStreamer::reset();
172 }
173
EmitFrames(MCAsmBackend * MAB)174 void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
175 if (!getNumFrameInfos())
176 return;
177
178 if (EmitEHFrame)
179 MCDwarfFrameEmitter::Emit(*this, MAB, true);
180
181 if (EmitDebugFrame)
182 MCDwarfFrameEmitter::Emit(*this, MAB, false);
183 }
184
getCurrentFragment() const185 MCFragment *MCObjectStreamer::getCurrentFragment() const {
186 assert(getCurrentSectionOnly() && "No current section!");
187
188 if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
189 return &*std::prev(CurInsertionPoint);
190
191 return nullptr;
192 }
193
CanReuseDataFragment(const MCDataFragment & F,const MCAssembler & Assembler,const MCSubtargetInfo * STI)194 static bool CanReuseDataFragment(const MCDataFragment &F,
195 const MCAssembler &Assembler,
196 const MCSubtargetInfo *STI) {
197 if (!F.hasInstructions())
198 return true;
199 // When bundling is enabled, we don't want to add data to a fragment that
200 // already has instructions (see MCELFStreamer::EmitInstToData for details)
201 if (Assembler.isBundlingEnabled())
202 return Assembler.getRelaxAll();
203 // If the subtarget is changed mid fragment we start a new fragment to record
204 // the new STI.
205 return !STI || F.getSubtargetInfo() == STI;
206 }
207
208 MCDataFragment *
getOrCreateDataFragment(const MCSubtargetInfo * STI)209 MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
210 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
211 if (!F || !CanReuseDataFragment(*F, *Assembler, STI)) {
212 F = new MCDataFragment();
213 insert(F);
214 }
215 return F;
216 }
217
visitUsedSymbol(const MCSymbol & Sym)218 void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
219 Assembler->registerSymbol(Sym);
220 }
221
EmitCFISections(bool EH,bool Debug)222 void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
223 MCStreamer::EmitCFISections(EH, Debug);
224 EmitEHFrame = EH;
225 EmitDebugFrame = Debug;
226 }
227
EmitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)228 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
229 SMLoc Loc) {
230 MCStreamer::EmitValueImpl(Value, Size, Loc);
231 MCDataFragment *DF = getOrCreateDataFragment();
232 flushPendingLabels(DF, DF->getContents().size());
233
234 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
235
236 // Avoid fixups when possible.
237 int64_t AbsValue;
238 if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {
239 if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
240 getContext().reportError(
241 Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");
242 return;
243 }
244 EmitIntValue(AbsValue, Size);
245 return;
246 }
247 DF->getFixups().push_back(
248 MCFixup::create(DF->getContents().size(), Value,
249 MCFixup::getKindForSize(Size, false), Loc));
250 DF->getContents().resize(DF->getContents().size() + Size, 0);
251 }
252
EmitCFILabel()253 MCSymbol *MCObjectStreamer::EmitCFILabel() {
254 MCSymbol *Label = getContext().createTempSymbol("cfi", true);
255 EmitLabel(Label);
256 return Label;
257 }
258
EmitCFIStartProcImpl(MCDwarfFrameInfo & Frame)259 void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
260 // We need to create a local symbol to avoid relocations.
261 Frame.Begin = getContext().createTempSymbol();
262 EmitLabel(Frame.Begin);
263 }
264
EmitCFIEndProcImpl(MCDwarfFrameInfo & Frame)265 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
266 Frame.End = getContext().createTempSymbol();
267 EmitLabel(Frame.End);
268 }
269
EmitLabel(MCSymbol * Symbol,SMLoc Loc)270 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
271 MCStreamer::EmitLabel(Symbol, Loc);
272
273 getAssembler().registerSymbol(*Symbol);
274
275 // If there is a current fragment, mark the symbol as pointing into it.
276 // Otherwise queue the label and set its fragment pointer when we emit the
277 // next fragment.
278 auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
279 if (F && !(getAssembler().isBundlingEnabled() &&
280 getAssembler().getRelaxAll())) {
281 Symbol->setFragment(F);
282 Symbol->setOffset(F->getContents().size());
283 } else {
284 // Assign all pending labels to offset 0 within the dummy "pending"
285 // fragment. (They will all be reassigned to a real fragment in
286 // flushPendingLabels())
287 Symbol->setOffset(0);
288 addPendingLabel(Symbol);
289 }
290 }
291
292 // Emit a label at a previously emitted fragment/offset position. This must be
293 // within the currently-active section.
EmitLabelAtPos(MCSymbol * Symbol,SMLoc Loc,MCFragment * F,uint64_t Offset)294 void MCObjectStreamer::EmitLabelAtPos(MCSymbol *Symbol, SMLoc Loc,
295 MCFragment *F, uint64_t Offset) {
296 assert(F->getParent() == getCurrentSectionOnly());
297
298 MCStreamer::EmitLabel(Symbol, Loc);
299 getAssembler().registerSymbol(*Symbol);
300 auto *DF = dyn_cast_or_null<MCDataFragment>(F);
301 Symbol->setOffset(Offset);
302 if (DF) {
303 Symbol->setFragment(F);
304 } else {
305 assert(isa<MCDummyFragment>(F) &&
306 "F must either be an MCDataFragment or the pending MCDummyFragment");
307 assert(Offset == 0);
308 addPendingLabel(Symbol);
309 }
310 }
311
EmitULEB128Value(const MCExpr * Value)312 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
313 int64_t IntValue;
314 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
315 EmitULEB128IntValue(IntValue);
316 return;
317 }
318 insert(new MCLEBFragment(*Value, false));
319 }
320
EmitSLEB128Value(const MCExpr * Value)321 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
322 int64_t IntValue;
323 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
324 EmitSLEB128IntValue(IntValue);
325 return;
326 }
327 insert(new MCLEBFragment(*Value, true));
328 }
329
EmitWeakReference(MCSymbol * Alias,const MCSymbol * Symbol)330 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
331 const MCSymbol *Symbol) {
332 report_fatal_error("This file format doesn't support weak aliases.");
333 }
334
ChangeSection(MCSection * Section,const MCExpr * Subsection)335 void MCObjectStreamer::ChangeSection(MCSection *Section,
336 const MCExpr *Subsection) {
337 changeSectionImpl(Section, Subsection);
338 }
339
changeSectionImpl(MCSection * Section,const MCExpr * Subsection)340 bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
341 const MCExpr *Subsection) {
342 assert(Section && "Cannot switch to a null section!");
343 getContext().clearDwarfLocSeen();
344
345 bool Created = getAssembler().registerSection(*Section);
346
347 int64_t IntSubsection = 0;
348 if (Subsection &&
349 !Subsection->evaluateAsAbsolute(IntSubsection, getAssemblerPtr()))
350 report_fatal_error("Cannot evaluate subsection number");
351 if (IntSubsection < 0 || IntSubsection > 8192)
352 report_fatal_error("Subsection number out of range");
353 CurSubsectionIdx = unsigned(IntSubsection);
354 CurInsertionPoint =
355 Section->getSubsectionInsertionPoint(CurSubsectionIdx);
356 return Created;
357 }
358
EmitAssignment(MCSymbol * Symbol,const MCExpr * Value)359 void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
360 getAssembler().registerSymbol(*Symbol);
361 MCStreamer::EmitAssignment(Symbol, Value);
362 }
363
mayHaveInstructions(MCSection & Sec) const364 bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
365 return Sec.hasInstructions();
366 }
367
EmitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)368 void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
369 const MCSubtargetInfo &STI) {
370 getAssembler().getBackend().alignBranchesBegin(*this, Inst);
371 EmitInstructionImpl(Inst, STI);
372 getAssembler().getBackend().alignBranchesEnd(*this, Inst);
373 }
374
EmitInstructionImpl(const MCInst & Inst,const MCSubtargetInfo & STI)375 void MCObjectStreamer::EmitInstructionImpl(const MCInst &Inst,
376 const MCSubtargetInfo &STI) {
377 MCStreamer::EmitInstruction(Inst, STI);
378
379 MCSection *Sec = getCurrentSectionOnly();
380 Sec->setHasInstructions(true);
381
382 // Now that a machine instruction has been assembled into this section, make
383 // a line entry for any .loc directive that has been seen.
384 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
385
386 // If this instruction doesn't need relaxation, just emit it as data.
387 MCAssembler &Assembler = getAssembler();
388 if (!Assembler.getBackend().mayNeedRelaxation(Inst, STI)) {
389 EmitInstToData(Inst, STI);
390 return;
391 }
392
393 // Otherwise, relax and emit it as data if either:
394 // - The RelaxAll flag was passed
395 // - Bundling is enabled and this instruction is inside a bundle-locked
396 // group. We want to emit all such instructions into the same data
397 // fragment.
398 if (Assembler.getRelaxAll() ||
399 (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
400 MCInst Relaxed;
401 getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
402 while (getAssembler().getBackend().mayNeedRelaxation(Relaxed, STI))
403 getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
404 EmitInstToData(Relaxed, STI);
405 return;
406 }
407
408 // Otherwise emit to a separate fragment.
409 EmitInstToFragment(Inst, STI);
410 }
411
EmitInstToFragment(const MCInst & Inst,const MCSubtargetInfo & STI)412 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
413 const MCSubtargetInfo &STI) {
414 if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
415 llvm_unreachable("All instructions should have already been relaxed");
416
417 // Always create a new, separate fragment here, because its size can change
418 // during relaxation.
419 MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
420 insert(IF);
421
422 SmallString<128> Code;
423 raw_svector_ostream VecOS(Code);
424 getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
425 STI);
426 IF->getContents().append(Code.begin(), Code.end());
427 }
428
429 #ifndef NDEBUG
430 static const char *const BundlingNotImplementedMsg =
431 "Aligned bundling is not implemented for this object format";
432 #endif
433
EmitBundleAlignMode(unsigned AlignPow2)434 void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
435 llvm_unreachable(BundlingNotImplementedMsg);
436 }
437
EmitBundleLock(bool AlignToEnd)438 void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
439 llvm_unreachable(BundlingNotImplementedMsg);
440 }
441
EmitBundleUnlock()442 void MCObjectStreamer::EmitBundleUnlock() {
443 llvm_unreachable(BundlingNotImplementedMsg);
444 }
445
EmitDwarfLocDirective(unsigned FileNo,unsigned Line,unsigned Column,unsigned Flags,unsigned Isa,unsigned Discriminator,StringRef FileName)446 void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
447 unsigned Column, unsigned Flags,
448 unsigned Isa,
449 unsigned Discriminator,
450 StringRef FileName) {
451 // In case we see two .loc directives in a row, make sure the
452 // first one gets a line entry.
453 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
454
455 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
456 Isa, Discriminator, FileName);
457 }
458
buildSymbolDiff(MCObjectStreamer & OS,const MCSymbol * A,const MCSymbol * B)459 static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
460 const MCSymbol *B) {
461 MCContext &Context = OS.getContext();
462 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
463 const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
464 const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
465 const MCExpr *AddrDelta =
466 MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
467 return AddrDelta;
468 }
469
emitDwarfSetLineAddr(MCObjectStreamer & OS,MCDwarfLineTableParams Params,int64_t LineDelta,const MCSymbol * Label,int PointerSize)470 static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
471 MCDwarfLineTableParams Params,
472 int64_t LineDelta, const MCSymbol *Label,
473 int PointerSize) {
474 // emit the sequence to set the address
475 OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1);
476 OS.EmitULEB128IntValue(PointerSize + 1);
477 OS.EmitIntValue(dwarf::DW_LNE_set_address, 1);
478 OS.EmitSymbolValue(Label, PointerSize);
479
480 // emit the sequence for the LineDelta (from 1) and a zero address delta.
481 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
482 }
483
EmitDwarfAdvanceLineAddr(int64_t LineDelta,const MCSymbol * LastLabel,const MCSymbol * Label,unsigned PointerSize)484 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
485 const MCSymbol *LastLabel,
486 const MCSymbol *Label,
487 unsigned PointerSize) {
488 if (!LastLabel) {
489 emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
490 Label, PointerSize);
491 return;
492 }
493 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
494 int64_t Res;
495 if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
496 MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
497 Res);
498 return;
499 }
500 insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
501 }
502
EmitDwarfAdvanceFrameAddr(const MCSymbol * LastLabel,const MCSymbol * Label)503 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
504 const MCSymbol *Label) {
505 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
506 int64_t Res;
507 if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
508 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
509 return;
510 }
511 insert(new MCDwarfCallFrameFragment(*AddrDelta));
512 }
513
EmitCVLocDirective(unsigned FunctionId,unsigned FileNo,unsigned Line,unsigned Column,bool PrologueEnd,bool IsStmt,StringRef FileName,SMLoc Loc)514 void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
515 unsigned Line, unsigned Column,
516 bool PrologueEnd, bool IsStmt,
517 StringRef FileName, SMLoc Loc) {
518 // Validate the directive.
519 if (!checkCVLocSection(FunctionId, FileNo, Loc))
520 return;
521
522 // Emit a label at the current position and record it in the CodeViewContext.
523 MCSymbol *LineSym = getContext().createTempSymbol();
524 EmitLabel(LineSym);
525 getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId,
526 FileNo, Line, Column, PrologueEnd,
527 IsStmt);
528 }
529
EmitCVLinetableDirective(unsigned FunctionId,const MCSymbol * Begin,const MCSymbol * End)530 void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
531 const MCSymbol *Begin,
532 const MCSymbol *End) {
533 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
534 End);
535 this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End);
536 }
537
EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,unsigned SourceFileId,unsigned SourceLineNum,const MCSymbol * FnStartSym,const MCSymbol * FnEndSym)538 void MCObjectStreamer::EmitCVInlineLinetableDirective(
539 unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
540 const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {
541 getContext().getCVContext().emitInlineLineTableForFunction(
542 *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
543 FnEndSym);
544 this->MCStreamer::EmitCVInlineLinetableDirective(
545 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
546 }
547
EmitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,StringRef FixedSizePortion)548 void MCObjectStreamer::EmitCVDefRangeDirective(
549 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
550 StringRef FixedSizePortion) {
551 MCFragment *Frag =
552 getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
553 // Attach labels that were pending before we created the defrange fragment to
554 // the beginning of the new fragment.
555 flushPendingLabels(Frag, 0);
556 this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
557 }
558
EmitCVStringTableDirective()559 void MCObjectStreamer::EmitCVStringTableDirective() {
560 getContext().getCVContext().emitStringTable(*this);
561 }
EmitCVFileChecksumsDirective()562 void MCObjectStreamer::EmitCVFileChecksumsDirective() {
563 getContext().getCVContext().emitFileChecksums(*this);
564 }
565
EmitCVFileChecksumOffsetDirective(unsigned FileNo)566 void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
567 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
568 }
569
EmitBytes(StringRef Data)570 void MCObjectStreamer::EmitBytes(StringRef Data) {
571 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
572 MCDataFragment *DF = getOrCreateDataFragment();
573 flushPendingLabels(DF, DF->getContents().size());
574 DF->getContents().append(Data.begin(), Data.end());
575 }
576
EmitValueToAlignment(unsigned ByteAlignment,int64_t Value,unsigned ValueSize,unsigned MaxBytesToEmit)577 void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
578 int64_t Value,
579 unsigned ValueSize,
580 unsigned MaxBytesToEmit) {
581 if (MaxBytesToEmit == 0)
582 MaxBytesToEmit = ByteAlignment;
583 insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
584
585 // Update the maximum alignment on the current section if necessary.
586 MCSection *CurSec = getCurrentSectionOnly();
587 if (ByteAlignment > CurSec->getAlignment())
588 CurSec->setAlignment(Align(ByteAlignment));
589 }
590
EmitCodeAlignment(unsigned ByteAlignment,unsigned MaxBytesToEmit)591 void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
592 unsigned MaxBytesToEmit) {
593 EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
594 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
595 }
596
emitValueToOffset(const MCExpr * Offset,unsigned char Value,SMLoc Loc)597 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
598 unsigned char Value,
599 SMLoc Loc) {
600 insert(new MCOrgFragment(*Offset, Value, Loc));
601 }
602
603 // Associate DTPRel32 fixup with data and resize data area
EmitDTPRel32Value(const MCExpr * Value)604 void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) {
605 MCDataFragment *DF = getOrCreateDataFragment();
606 flushPendingLabels(DF, DF->getContents().size());
607
608 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
609 Value, FK_DTPRel_4));
610 DF->getContents().resize(DF->getContents().size() + 4, 0);
611 }
612
613 // Associate DTPRel64 fixup with data and resize data area
EmitDTPRel64Value(const MCExpr * Value)614 void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) {
615 MCDataFragment *DF = getOrCreateDataFragment();
616 flushPendingLabels(DF, DF->getContents().size());
617
618 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
619 Value, FK_DTPRel_8));
620 DF->getContents().resize(DF->getContents().size() + 8, 0);
621 }
622
623 // Associate TPRel32 fixup with data and resize data area
EmitTPRel32Value(const MCExpr * Value)624 void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) {
625 MCDataFragment *DF = getOrCreateDataFragment();
626 flushPendingLabels(DF, DF->getContents().size());
627
628 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
629 Value, FK_TPRel_4));
630 DF->getContents().resize(DF->getContents().size() + 4, 0);
631 }
632
633 // Associate TPRel64 fixup with data and resize data area
EmitTPRel64Value(const MCExpr * Value)634 void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) {
635 MCDataFragment *DF = getOrCreateDataFragment();
636 flushPendingLabels(DF, DF->getContents().size());
637
638 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
639 Value, FK_TPRel_8));
640 DF->getContents().resize(DF->getContents().size() + 8, 0);
641 }
642
643 // Associate GPRel32 fixup with data and resize data area
EmitGPRel32Value(const MCExpr * Value)644 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
645 MCDataFragment *DF = getOrCreateDataFragment();
646 flushPendingLabels(DF, DF->getContents().size());
647
648 DF->getFixups().push_back(
649 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
650 DF->getContents().resize(DF->getContents().size() + 4, 0);
651 }
652
653 // Associate GPRel64 fixup with data and resize data area
EmitGPRel64Value(const MCExpr * Value)654 void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
655 MCDataFragment *DF = getOrCreateDataFragment();
656 flushPendingLabels(DF, DF->getContents().size());
657
658 DF->getFixups().push_back(
659 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
660 DF->getContents().resize(DF->getContents().size() + 8, 0);
661 }
662
EmitRelocDirective(const MCExpr & Offset,StringRef Name,const MCExpr * Expr,SMLoc Loc,const MCSubtargetInfo & STI)663 bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
664 const MCExpr *Expr, SMLoc Loc,
665 const MCSubtargetInfo &STI) {
666 Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name);
667 if (!MaybeKind.hasValue())
668 return true;
669
670 MCFixupKind Kind = *MaybeKind;
671
672 if (Expr == nullptr)
673 Expr =
674 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
675
676 MCDataFragment *DF = getOrCreateDataFragment(&STI);
677 flushPendingLabels(DF, DF->getContents().size());
678
679 int64_t OffsetValue;
680 if (Offset.evaluateAsAbsolute(OffsetValue)) {
681 if (OffsetValue < 0)
682 llvm_unreachable(".reloc offset is negative");
683 DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc));
684 return false;
685 }
686
687 if (Offset.getKind() != llvm::MCExpr::SymbolRef)
688 llvm_unreachable(".reloc offset is not absolute nor a label");
689
690 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(Offset);
691 if (SRE.getSymbol().isDefined()) {
692 DF->getFixups().push_back(MCFixup::create(SRE.getSymbol().getOffset(),
693 Expr, Kind, Loc));
694 return false;
695 }
696
697 PendingFixups.emplace_back(&SRE.getSymbol(), DF,
698 MCFixup::create(-1, Expr, Kind, Loc));
699 return false;
700 }
701
emitFill(const MCExpr & NumBytes,uint64_t FillValue,SMLoc Loc)702 void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
703 SMLoc Loc) {
704 MCDataFragment *DF = getOrCreateDataFragment();
705 flushPendingLabels(DF, DF->getContents().size());
706
707 assert(getCurrentSectionOnly() && "need a section");
708 insert(new MCFillFragment(FillValue, 1, NumBytes, Loc));
709 }
710
emitFill(const MCExpr & NumValues,int64_t Size,int64_t Expr,SMLoc Loc)711 void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
712 int64_t Expr, SMLoc Loc) {
713 int64_t IntNumValues;
714 // Do additional checking now if we can resolve the value.
715 if (NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) {
716 if (IntNumValues < 0) {
717 getContext().getSourceManager()->PrintMessage(
718 Loc, SourceMgr::DK_Warning,
719 "'.fill' directive with negative repeat count has no effect");
720 return;
721 }
722 // Emit now if we can for better errors.
723 int64_t NonZeroSize = Size > 4 ? 4 : Size;
724 Expr &= ~0ULL >> (64 - NonZeroSize * 8);
725 for (uint64_t i = 0, e = IntNumValues; i != e; ++i) {
726 EmitIntValue(Expr, NonZeroSize);
727 if (NonZeroSize < Size)
728 EmitIntValue(0, Size - NonZeroSize);
729 }
730 return;
731 }
732
733 // Otherwise emit as fragment.
734 MCDataFragment *DF = getOrCreateDataFragment();
735 flushPendingLabels(DF, DF->getContents().size());
736
737 assert(getCurrentSectionOnly() && "need a section");
738 insert(new MCFillFragment(Expr, Size, NumValues, Loc));
739 }
740
EmitFileDirective(StringRef Filename)741 void MCObjectStreamer::EmitFileDirective(StringRef Filename) {
742 getAssembler().addFileName(Filename);
743 }
744
EmitAddrsig()745 void MCObjectStreamer::EmitAddrsig() {
746 getAssembler().getWriter().emitAddrsigSection();
747 }
748
EmitAddrsigSym(const MCSymbol * Sym)749 void MCObjectStreamer::EmitAddrsigSym(const MCSymbol *Sym) {
750 getAssembler().registerSymbol(*Sym);
751 getAssembler().getWriter().addAddrsigSymbol(Sym);
752 }
753
FinishImpl()754 void MCObjectStreamer::FinishImpl() {
755 getContext().RemapDebugPaths();
756
757 // If we are generating dwarf for assembly source files dump out the sections.
758 if (getContext().getGenDwarfForAssembly())
759 MCGenDwarfInfo::Emit(this);
760
761 // Dump out the dwarf file & directory tables and line tables.
762 MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
763
764 // Update any remaining pending labels with empty data fragments.
765 flushPendingLabels();
766
767 resolvePendingFixups();
768 getAssembler().Finish();
769 }
770