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/MC/MCAsmBackend.h"
11 #include "llvm/MC/MCAsmInfo.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/MCObjectFileInfo.h"
19 #include "llvm/MC/MCObjectWriter.h"
20 #include "llvm/MC/MCSection.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/MC/MCValue.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/SourceMgr.h"
25 using namespace llvm;
26
MCObjectStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> TAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter)27 MCObjectStreamer::MCObjectStreamer(MCContext &Context,
28 std::unique_ptr<MCAsmBackend> TAB,
29 std::unique_ptr<MCObjectWriter> OW,
30 std::unique_ptr<MCCodeEmitter> Emitter)
31 : MCStreamer(Context),
32 Assembler(std::make_unique<MCAssembler>(
33 Context, std::move(TAB), std::move(Emitter), std::move(OW))),
34 EmitEHFrame(true), EmitDebugFrame(false) {
35 if (Assembler->getBackendPtr())
36 setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
37 }
38
39 MCObjectStreamer::~MCObjectStreamer() = default;
40
41 // AssemblerPtr is used for evaluation of expressions and causes
42 // difference between asm and object outputs. Return nullptr to in
43 // inline asm mode to limit divergence to assembly inputs.
getAssemblerPtr()44 MCAssembler *MCObjectStreamer::getAssemblerPtr() {
45 if (getUseAssemblerInfoForParsing())
46 return Assembler.get();
47 return nullptr;
48 }
49
addPendingLabel(MCSymbol * S)50 void MCObjectStreamer::addPendingLabel(MCSymbol* S) {
51 MCSection *CurSection = getCurrentSectionOnly();
52 if (CurSection) {
53 // Register labels that have not yet been assigned to a Section.
54 if (!PendingLabels.empty()) {
55 for (MCSymbol* Sym : PendingLabels)
56 CurSection->addPendingLabel(Sym);
57 PendingLabels.clear();
58 }
59
60 // Add this label to the current Section / Subsection.
61 CurSection->addPendingLabel(S, CurSubsectionIdx);
62
63 // Add this Section to the list of PendingLabelSections.
64 PendingLabelSections.insert(CurSection);
65 } else
66 // There is no Section / Subsection for this label yet.
67 PendingLabels.push_back(S);
68 }
69
flushPendingLabels(MCFragment * F,uint64_t FOffset)70 void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
71 MCSection *CurSection = getCurrentSectionOnly();
72 if (!CurSection) {
73 assert(PendingLabels.empty());
74 return;
75 }
76 // Register labels that have not yet been assigned to a Section.
77 if (!PendingLabels.empty()) {
78 for (MCSymbol* Sym : PendingLabels)
79 CurSection->addPendingLabel(Sym, CurSubsectionIdx);
80 PendingLabels.clear();
81 }
82
83 // Associate a fragment with this label, either the supplied fragment
84 // or an empty data fragment.
85 if (F)
86 CurSection->flushPendingLabels(F, FOffset, CurSubsectionIdx);
87 else
88 CurSection->flushPendingLabels(nullptr, 0, CurSubsectionIdx);
89 }
90
flushPendingLabels()91 void MCObjectStreamer::flushPendingLabels() {
92 // Register labels that have not yet been assigned to a Section.
93 if (!PendingLabels.empty()) {
94 MCSection *CurSection = getCurrentSectionOnly();
95 assert(CurSection);
96 for (MCSymbol* Sym : PendingLabels)
97 CurSection->addPendingLabel(Sym, CurSubsectionIdx);
98 PendingLabels.clear();
99 }
100
101 // Assign an empty data fragment to all remaining pending labels.
102 for (MCSection* Section : PendingLabelSections)
103 Section->flushPendingLabels();
104 }
105
106 // When fixup's offset is a forward declared label, e.g.:
107 //
108 // .reloc 1f, R_MIPS_JALR, foo
109 // 1: nop
110 //
111 // postpone adding it to Fixups vector until the label is defined and its offset
112 // is known.
resolvePendingFixups()113 void MCObjectStreamer::resolvePendingFixups() {
114 for (PendingMCFixup &PendingFixup : PendingFixups) {
115 if (!PendingFixup.Sym || PendingFixup.Sym->isUndefined ()) {
116 getContext().reportError(PendingFixup.Fixup.getLoc(),
117 "unresolved relocation offset");
118 continue;
119 }
120 flushPendingLabels(PendingFixup.DF, PendingFixup.DF->getContents().size());
121 PendingFixup.Fixup.setOffset(PendingFixup.Sym->getOffset() +
122 PendingFixup.Fixup.getOffset());
123
124 // If the location symbol to relocate is in MCEncodedFragmentWithFixups,
125 // put the Fixup into location symbol's fragment. Otherwise
126 // put into PendingFixup.DF
127 MCFragment *SymFragment = PendingFixup.Sym->getFragment();
128 switch (SymFragment->getKind()) {
129 case MCFragment::FT_Relaxable:
130 case MCFragment::FT_Dwarf:
131 case MCFragment::FT_PseudoProbe:
132 cast<MCEncodedFragmentWithFixups<8, 1>>(SymFragment)
133 ->getFixups()
134 .push_back(PendingFixup.Fixup);
135 break;
136 case MCFragment::FT_Data:
137 case MCFragment::FT_CVDefRange:
138 cast<MCEncodedFragmentWithFixups<32, 4>>(SymFragment)
139 ->getFixups()
140 .push_back(PendingFixup.Fixup);
141 break;
142 default:
143 PendingFixup.DF->getFixups().push_back(PendingFixup.Fixup);
144 break;
145 }
146 }
147 PendingFixups.clear();
148 }
149
150 // As a compile-time optimization, avoid allocating and evaluating an MCExpr
151 // tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
absoluteSymbolDiff(const MCSymbol * Hi,const MCSymbol * Lo)152 static Optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
153 const MCSymbol *Lo) {
154 assert(Hi && Lo);
155 if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
156 Hi->isVariable() || Lo->isVariable())
157 return None;
158
159 return Hi->getOffset() - Lo->getOffset();
160 }
161
emitAbsoluteSymbolDiff(const MCSymbol * Hi,const MCSymbol * Lo,unsigned Size)162 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
163 const MCSymbol *Lo,
164 unsigned Size) {
165 if (!getAssembler().getContext().getTargetTriple().isRISCV())
166 if (Optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
167 return emitIntValue(*Diff, Size);
168 MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
169 }
170
emitAbsoluteSymbolDiffAsULEB128(const MCSymbol * Hi,const MCSymbol * Lo)171 void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
172 const MCSymbol *Lo) {
173 if (!getAssembler().getContext().getTargetTriple().isRISCV())
174 if (Optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
175 return emitULEB128IntValue(*Diff);
176 MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
177 }
178
reset()179 void MCObjectStreamer::reset() {
180 if (Assembler)
181 Assembler->reset();
182 CurInsertionPoint = MCSection::iterator();
183 EmitEHFrame = true;
184 EmitDebugFrame = false;
185 PendingLabels.clear();
186 PendingLabelSections.clear();
187 MCStreamer::reset();
188 }
189
emitFrames(MCAsmBackend * MAB)190 void MCObjectStreamer::emitFrames(MCAsmBackend *MAB) {
191 if (!getNumFrameInfos())
192 return;
193
194 if (EmitEHFrame)
195 MCDwarfFrameEmitter::Emit(*this, MAB, true);
196
197 if (EmitDebugFrame)
198 MCDwarfFrameEmitter::Emit(*this, MAB, false);
199 }
200
getCurrentFragment() const201 MCFragment *MCObjectStreamer::getCurrentFragment() const {
202 assert(getCurrentSectionOnly() && "No current section!");
203
204 if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
205 return &*std::prev(CurInsertionPoint);
206
207 return nullptr;
208 }
209
canReuseDataFragment(const MCDataFragment & F,const MCAssembler & Assembler,const MCSubtargetInfo * STI)210 static bool canReuseDataFragment(const MCDataFragment &F,
211 const MCAssembler &Assembler,
212 const MCSubtargetInfo *STI) {
213 if (!F.hasInstructions())
214 return true;
215 // When bundling is enabled, we don't want to add data to a fragment that
216 // already has instructions (see MCELFStreamer::emitInstToData for details)
217 if (Assembler.isBundlingEnabled())
218 return Assembler.getRelaxAll();
219 // If the subtarget is changed mid fragment we start a new fragment to record
220 // the new STI.
221 return !STI || F.getSubtargetInfo() == STI;
222 }
223
224 MCDataFragment *
getOrCreateDataFragment(const MCSubtargetInfo * STI)225 MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
226 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
227 if (!F || !canReuseDataFragment(*F, *Assembler, STI)) {
228 F = new MCDataFragment();
229 insert(F);
230 }
231 return F;
232 }
233
visitUsedSymbol(const MCSymbol & Sym)234 void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
235 Assembler->registerSymbol(Sym);
236 }
237
emitCFISections(bool EH,bool Debug)238 void MCObjectStreamer::emitCFISections(bool EH, bool Debug) {
239 MCStreamer::emitCFISections(EH, Debug);
240 EmitEHFrame = EH;
241 EmitDebugFrame = Debug;
242 }
243
emitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)244 void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
245 SMLoc Loc) {
246 MCStreamer::emitValueImpl(Value, Size, Loc);
247 MCDataFragment *DF = getOrCreateDataFragment();
248 flushPendingLabels(DF, DF->getContents().size());
249
250 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
251
252 // Avoid fixups when possible.
253 int64_t AbsValue;
254 if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {
255 if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
256 getContext().reportError(
257 Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");
258 return;
259 }
260 emitIntValue(AbsValue, Size);
261 return;
262 }
263 DF->getFixups().push_back(
264 MCFixup::create(DF->getContents().size(), Value,
265 MCFixup::getKindForSize(Size, false), Loc));
266 DF->getContents().resize(DF->getContents().size() + Size, 0);
267 }
268
emitCFILabel()269 MCSymbol *MCObjectStreamer::emitCFILabel() {
270 MCSymbol *Label = getContext().createTempSymbol("cfi");
271 emitLabel(Label);
272 return Label;
273 }
274
emitCFIStartProcImpl(MCDwarfFrameInfo & Frame)275 void MCObjectStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
276 // We need to create a local symbol to avoid relocations.
277 Frame.Begin = getContext().createTempSymbol();
278 emitLabel(Frame.Begin);
279 }
280
emitCFIEndProcImpl(MCDwarfFrameInfo & Frame)281 void MCObjectStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
282 Frame.End = getContext().createTempSymbol();
283 emitLabel(Frame.End);
284 }
285
emitLabel(MCSymbol * Symbol,SMLoc Loc)286 void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
287 MCStreamer::emitLabel(Symbol, Loc);
288
289 getAssembler().registerSymbol(*Symbol);
290
291 // If there is a current fragment, mark the symbol as pointing into it.
292 // Otherwise queue the label and set its fragment pointer when we emit the
293 // next fragment.
294 auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
295 if (F && !(getAssembler().isBundlingEnabled() &&
296 getAssembler().getRelaxAll())) {
297 Symbol->setFragment(F);
298 Symbol->setOffset(F->getContents().size());
299 } else {
300 // Assign all pending labels to offset 0 within the dummy "pending"
301 // fragment. (They will all be reassigned to a real fragment in
302 // flushPendingLabels())
303 Symbol->setOffset(0);
304 addPendingLabel(Symbol);
305 }
306
307 emitPendingAssignments(Symbol);
308 }
309
emitPendingAssignments(MCSymbol * Symbol)310 void MCObjectStreamer::emitPendingAssignments(MCSymbol *Symbol) {
311 auto Assignments = pendingAssignments.find(Symbol);
312 if (Assignments != pendingAssignments.end()) {
313 for (const PendingAssignment &A : Assignments->second)
314 emitAssignment(A.Symbol, A.Value);
315
316 pendingAssignments.erase(Assignments);
317 }
318 }
319
320 // Emit a label at a previously emitted fragment/offset position. This must be
321 // within the currently-active section.
emitLabelAtPos(MCSymbol * Symbol,SMLoc Loc,MCFragment * F,uint64_t Offset)322 void MCObjectStreamer::emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc,
323 MCFragment *F, uint64_t Offset) {
324 assert(F->getParent() == getCurrentSectionOnly());
325
326 MCStreamer::emitLabel(Symbol, Loc);
327 getAssembler().registerSymbol(*Symbol);
328 auto *DF = dyn_cast_or_null<MCDataFragment>(F);
329 Symbol->setOffset(Offset);
330 if (DF) {
331 Symbol->setFragment(F);
332 } else {
333 assert(isa<MCDummyFragment>(F) &&
334 "F must either be an MCDataFragment or the pending MCDummyFragment");
335 assert(Offset == 0);
336 addPendingLabel(Symbol);
337 }
338 }
339
emitULEB128Value(const MCExpr * Value)340 void MCObjectStreamer::emitULEB128Value(const MCExpr *Value) {
341 int64_t IntValue;
342 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
343 emitULEB128IntValue(IntValue);
344 return;
345 }
346 insert(new MCLEBFragment(*Value, false));
347 }
348
emitSLEB128Value(const MCExpr * Value)349 void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) {
350 int64_t IntValue;
351 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
352 emitSLEB128IntValue(IntValue);
353 return;
354 }
355 insert(new MCLEBFragment(*Value, true));
356 }
357
emitWeakReference(MCSymbol * Alias,const MCSymbol * Symbol)358 void MCObjectStreamer::emitWeakReference(MCSymbol *Alias,
359 const MCSymbol *Symbol) {
360 report_fatal_error("This file format doesn't support weak aliases.");
361 }
362
changeSection(MCSection * Section,const MCExpr * Subsection)363 void MCObjectStreamer::changeSection(MCSection *Section,
364 const MCExpr *Subsection) {
365 changeSectionImpl(Section, Subsection);
366 }
367
changeSectionImpl(MCSection * Section,const MCExpr * Subsection)368 bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
369 const MCExpr *Subsection) {
370 assert(Section && "Cannot switch to a null section!");
371 getContext().clearDwarfLocSeen();
372
373 bool Created = getAssembler().registerSection(*Section);
374
375 int64_t IntSubsection = 0;
376 if (Subsection &&
377 !Subsection->evaluateAsAbsolute(IntSubsection, getAssemblerPtr()))
378 report_fatal_error("Cannot evaluate subsection number");
379 if (IntSubsection < 0 || IntSubsection > 8192)
380 report_fatal_error("Subsection number out of range");
381 CurSubsectionIdx = unsigned(IntSubsection);
382 CurInsertionPoint =
383 Section->getSubsectionInsertionPoint(CurSubsectionIdx);
384 return Created;
385 }
386
emitAssignment(MCSymbol * Symbol,const MCExpr * Value)387 void MCObjectStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
388 getAssembler().registerSymbol(*Symbol);
389 MCStreamer::emitAssignment(Symbol, Value);
390 emitPendingAssignments(Symbol);
391 }
392
emitConditionalAssignment(MCSymbol * Symbol,const MCExpr * Value)393 void MCObjectStreamer::emitConditionalAssignment(MCSymbol *Symbol,
394 const MCExpr *Value) {
395 const MCSymbol *Target = &cast<MCSymbolRefExpr>(*Value).getSymbol();
396
397 // If the symbol already exists, emit the assignment. Otherwise, emit it
398 // later only if the symbol is also emitted.
399 if (Target->isRegistered())
400 emitAssignment(Symbol, Value);
401 else
402 pendingAssignments[Target].push_back({Symbol, Value});
403 }
404
mayHaveInstructions(MCSection & Sec) const405 bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
406 return Sec.hasInstructions();
407 }
408
emitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)409 void MCObjectStreamer::emitInstruction(const MCInst &Inst,
410 const MCSubtargetInfo &STI) {
411 const MCSection &Sec = *getCurrentSectionOnly();
412 if (Sec.isVirtualSection()) {
413 getContext().reportError(Inst.getLoc(), Twine(Sec.getVirtualSectionKind()) +
414 " section '" + Sec.getName() +
415 "' cannot have instructions");
416 return;
417 }
418 getAssembler().getBackend().emitInstructionBegin(*this, Inst, STI);
419 emitInstructionImpl(Inst, STI);
420 getAssembler().getBackend().emitInstructionEnd(*this, Inst);
421 }
422
emitInstructionImpl(const MCInst & Inst,const MCSubtargetInfo & STI)423 void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst,
424 const MCSubtargetInfo &STI) {
425 MCStreamer::emitInstruction(Inst, STI);
426
427 MCSection *Sec = getCurrentSectionOnly();
428 Sec->setHasInstructions(true);
429
430 // Now that a machine instruction has been assembled into this section, make
431 // a line entry for any .loc directive that has been seen.
432 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
433
434 // If this instruction doesn't need relaxation, just emit it as data.
435 MCAssembler &Assembler = getAssembler();
436 MCAsmBackend &Backend = Assembler.getBackend();
437 if (!(Backend.mayNeedRelaxation(Inst, STI) ||
438 Backend.allowEnhancedRelaxation())) {
439 emitInstToData(Inst, STI);
440 return;
441 }
442
443 // Otherwise, relax and emit it as data if either:
444 // - The RelaxAll flag was passed
445 // - Bundling is enabled and this instruction is inside a bundle-locked
446 // group. We want to emit all such instructions into the same data
447 // fragment.
448 if (Assembler.getRelaxAll() ||
449 (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
450 MCInst Relaxed = Inst;
451 while (Backend.mayNeedRelaxation(Relaxed, STI))
452 Backend.relaxInstruction(Relaxed, STI);
453 emitInstToData(Relaxed, STI);
454 return;
455 }
456
457 // Otherwise emit to a separate fragment.
458 emitInstToFragment(Inst, STI);
459 }
460
emitInstToFragment(const MCInst & Inst,const MCSubtargetInfo & STI)461 void MCObjectStreamer::emitInstToFragment(const MCInst &Inst,
462 const MCSubtargetInfo &STI) {
463 if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
464 llvm_unreachable("All instructions should have already been relaxed");
465
466 // Always create a new, separate fragment here, because its size can change
467 // during relaxation.
468 MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
469 insert(IF);
470
471 SmallString<128> Code;
472 raw_svector_ostream VecOS(Code);
473 getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
474 STI);
475 IF->getContents().append(Code.begin(), Code.end());
476 }
477
478 #ifndef NDEBUG
479 static const char *const BundlingNotImplementedMsg =
480 "Aligned bundling is not implemented for this object format";
481 #endif
482
emitBundleAlignMode(unsigned AlignPow2)483 void MCObjectStreamer::emitBundleAlignMode(unsigned AlignPow2) {
484 llvm_unreachable(BundlingNotImplementedMsg);
485 }
486
emitBundleLock(bool AlignToEnd)487 void MCObjectStreamer::emitBundleLock(bool AlignToEnd) {
488 llvm_unreachable(BundlingNotImplementedMsg);
489 }
490
emitBundleUnlock()491 void MCObjectStreamer::emitBundleUnlock() {
492 llvm_unreachable(BundlingNotImplementedMsg);
493 }
494
emitDwarfLocDirective(unsigned FileNo,unsigned Line,unsigned Column,unsigned Flags,unsigned Isa,unsigned Discriminator,StringRef FileName)495 void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
496 unsigned Column, unsigned Flags,
497 unsigned Isa,
498 unsigned Discriminator,
499 StringRef FileName) {
500 // In case we see two .loc directives in a row, make sure the
501 // first one gets a line entry.
502 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
503
504 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
505 Discriminator, FileName);
506 }
507
buildSymbolDiff(MCObjectStreamer & OS,const MCSymbol * A,const MCSymbol * B)508 static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
509 const MCSymbol *B) {
510 MCContext &Context = OS.getContext();
511 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
512 const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
513 const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
514 const MCExpr *AddrDelta =
515 MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
516 return AddrDelta;
517 }
518
emitDwarfSetLineAddr(MCObjectStreamer & OS,MCDwarfLineTableParams Params,int64_t LineDelta,const MCSymbol * Label,int PointerSize)519 static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
520 MCDwarfLineTableParams Params,
521 int64_t LineDelta, const MCSymbol *Label,
522 int PointerSize) {
523 // emit the sequence to set the address
524 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1);
525 OS.emitULEB128IntValue(PointerSize + 1);
526 OS.emitIntValue(dwarf::DW_LNE_set_address, 1);
527 OS.emitSymbolValue(Label, PointerSize);
528
529 // emit the sequence for the LineDelta (from 1) and a zero address delta.
530 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
531 }
532
emitDwarfAdvanceLineAddr(int64_t LineDelta,const MCSymbol * LastLabel,const MCSymbol * Label,unsigned PointerSize)533 void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
534 const MCSymbol *LastLabel,
535 const MCSymbol *Label,
536 unsigned PointerSize) {
537 if (!LastLabel) {
538 emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
539 Label, PointerSize);
540 return;
541 }
542 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
543 int64_t Res;
544 if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
545 MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
546 Res);
547 return;
548 }
549 insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
550 }
551
emitDwarfLineEndEntry(MCSection * Section,MCSymbol * LastLabel)552 void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
553 MCSymbol *LastLabel) {
554 // Emit a DW_LNE_end_sequence for the end of the section.
555 // Use the section end label to compute the address delta and use INT64_MAX
556 // as the line delta which is the signal that this is actually a
557 // DW_LNE_end_sequence.
558 MCSymbol *SectionEnd = endSection(Section);
559
560 // Switch back the dwarf line section, in case endSection had to switch the
561 // section.
562 MCContext &Ctx = getContext();
563 switchSection(Ctx.getObjectFileInfo()->getDwarfLineSection());
564
565 const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
566 emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
567 AsmInfo->getCodePointerSize());
568 }
569
emitDwarfAdvanceFrameAddr(const MCSymbol * LastLabel,const MCSymbol * Label)570 void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
571 const MCSymbol *Label) {
572 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
573 int64_t Res;
574 if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
575 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
576 return;
577 }
578 insert(new MCDwarfCallFrameFragment(*AddrDelta));
579 }
580
emitCVLocDirective(unsigned FunctionId,unsigned FileNo,unsigned Line,unsigned Column,bool PrologueEnd,bool IsStmt,StringRef FileName,SMLoc Loc)581 void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
582 unsigned Line, unsigned Column,
583 bool PrologueEnd, bool IsStmt,
584 StringRef FileName, SMLoc Loc) {
585 // Validate the directive.
586 if (!checkCVLocSection(FunctionId, FileNo, Loc))
587 return;
588
589 // Emit a label at the current position and record it in the CodeViewContext.
590 MCSymbol *LineSym = getContext().createTempSymbol();
591 emitLabel(LineSym);
592 getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId,
593 FileNo, Line, Column, PrologueEnd,
594 IsStmt);
595 }
596
emitCVLinetableDirective(unsigned FunctionId,const MCSymbol * Begin,const MCSymbol * End)597 void MCObjectStreamer::emitCVLinetableDirective(unsigned FunctionId,
598 const MCSymbol *Begin,
599 const MCSymbol *End) {
600 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
601 End);
602 this->MCStreamer::emitCVLinetableDirective(FunctionId, Begin, End);
603 }
604
emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,unsigned SourceFileId,unsigned SourceLineNum,const MCSymbol * FnStartSym,const MCSymbol * FnEndSym)605 void MCObjectStreamer::emitCVInlineLinetableDirective(
606 unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
607 const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {
608 getContext().getCVContext().emitInlineLineTableForFunction(
609 *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
610 FnEndSym);
611 this->MCStreamer::emitCVInlineLinetableDirective(
612 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
613 }
614
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,StringRef FixedSizePortion)615 void MCObjectStreamer::emitCVDefRangeDirective(
616 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
617 StringRef FixedSizePortion) {
618 MCFragment *Frag =
619 getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
620 // Attach labels that were pending before we created the defrange fragment to
621 // the beginning of the new fragment.
622 flushPendingLabels(Frag, 0);
623 this->MCStreamer::emitCVDefRangeDirective(Ranges, FixedSizePortion);
624 }
625
emitCVStringTableDirective()626 void MCObjectStreamer::emitCVStringTableDirective() {
627 getContext().getCVContext().emitStringTable(*this);
628 }
emitCVFileChecksumsDirective()629 void MCObjectStreamer::emitCVFileChecksumsDirective() {
630 getContext().getCVContext().emitFileChecksums(*this);
631 }
632
emitCVFileChecksumOffsetDirective(unsigned FileNo)633 void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
634 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
635 }
636
emitBytes(StringRef Data)637 void MCObjectStreamer::emitBytes(StringRef Data) {
638 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
639 MCDataFragment *DF = getOrCreateDataFragment();
640 flushPendingLabels(DF, DF->getContents().size());
641 DF->getContents().append(Data.begin(), Data.end());
642 }
643
emitValueToAlignment(unsigned ByteAlignment,int64_t Value,unsigned ValueSize,unsigned MaxBytesToEmit)644 void MCObjectStreamer::emitValueToAlignment(unsigned ByteAlignment,
645 int64_t Value,
646 unsigned ValueSize,
647 unsigned MaxBytesToEmit) {
648 if (MaxBytesToEmit == 0)
649 MaxBytesToEmit = ByteAlignment;
650 insert(new MCAlignFragment(Align(ByteAlignment), Value, ValueSize,
651 MaxBytesToEmit));
652
653 // Update the maximum alignment on the current section if necessary.
654 MCSection *CurSec = getCurrentSectionOnly();
655 if (ByteAlignment > CurSec->getAlignment())
656 CurSec->setAlignment(Align(ByteAlignment));
657 }
658
emitCodeAlignment(unsigned ByteAlignment,const MCSubtargetInfo * STI,unsigned MaxBytesToEmit)659 void MCObjectStreamer::emitCodeAlignment(unsigned ByteAlignment,
660 const MCSubtargetInfo *STI,
661 unsigned MaxBytesToEmit) {
662 emitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
663 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true, STI);
664 }
665
emitValueToOffset(const MCExpr * Offset,unsigned char Value,SMLoc Loc)666 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
667 unsigned char Value,
668 SMLoc Loc) {
669 insert(new MCOrgFragment(*Offset, Value, Loc));
670 }
671
672 // Associate DTPRel32 fixup with data and resize data area
emitDTPRel32Value(const MCExpr * Value)673 void MCObjectStreamer::emitDTPRel32Value(const MCExpr *Value) {
674 MCDataFragment *DF = getOrCreateDataFragment();
675 flushPendingLabels(DF, DF->getContents().size());
676
677 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
678 Value, FK_DTPRel_4));
679 DF->getContents().resize(DF->getContents().size() + 4, 0);
680 }
681
682 // Associate DTPRel64 fixup with data and resize data area
emitDTPRel64Value(const MCExpr * Value)683 void MCObjectStreamer::emitDTPRel64Value(const MCExpr *Value) {
684 MCDataFragment *DF = getOrCreateDataFragment();
685 flushPendingLabels(DF, DF->getContents().size());
686
687 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
688 Value, FK_DTPRel_8));
689 DF->getContents().resize(DF->getContents().size() + 8, 0);
690 }
691
692 // Associate TPRel32 fixup with data and resize data area
emitTPRel32Value(const MCExpr * Value)693 void MCObjectStreamer::emitTPRel32Value(const MCExpr *Value) {
694 MCDataFragment *DF = getOrCreateDataFragment();
695 flushPendingLabels(DF, DF->getContents().size());
696
697 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
698 Value, FK_TPRel_4));
699 DF->getContents().resize(DF->getContents().size() + 4, 0);
700 }
701
702 // Associate TPRel64 fixup with data and resize data area
emitTPRel64Value(const MCExpr * Value)703 void MCObjectStreamer::emitTPRel64Value(const MCExpr *Value) {
704 MCDataFragment *DF = getOrCreateDataFragment();
705 flushPendingLabels(DF, DF->getContents().size());
706
707 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
708 Value, FK_TPRel_8));
709 DF->getContents().resize(DF->getContents().size() + 8, 0);
710 }
711
712 // Associate GPRel32 fixup with data and resize data area
emitGPRel32Value(const MCExpr * Value)713 void MCObjectStreamer::emitGPRel32Value(const MCExpr *Value) {
714 MCDataFragment *DF = getOrCreateDataFragment();
715 flushPendingLabels(DF, DF->getContents().size());
716
717 DF->getFixups().push_back(
718 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
719 DF->getContents().resize(DF->getContents().size() + 4, 0);
720 }
721
722 // Associate GPRel64 fixup with data and resize data area
emitGPRel64Value(const MCExpr * Value)723 void MCObjectStreamer::emitGPRel64Value(const MCExpr *Value) {
724 MCDataFragment *DF = getOrCreateDataFragment();
725 flushPendingLabels(DF, DF->getContents().size());
726
727 DF->getFixups().push_back(
728 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
729 DF->getContents().resize(DF->getContents().size() + 8, 0);
730 }
731
732 static Optional<std::pair<bool, std::string>>
getOffsetAndDataFragment(const MCSymbol & Symbol,uint32_t & RelocOffset,MCDataFragment * & DF)733 getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset,
734 MCDataFragment *&DF) {
735 if (Symbol.isVariable()) {
736 const MCExpr *SymbolExpr = Symbol.getVariableValue();
737 MCValue OffsetVal;
738 if(!SymbolExpr->evaluateAsRelocatable(OffsetVal, nullptr, nullptr))
739 return std::make_pair(false,
740 std::string("symbol in .reloc offset is not "
741 "relocatable"));
742 if (OffsetVal.isAbsolute()) {
743 RelocOffset = OffsetVal.getConstant();
744 MCFragment *Fragment = Symbol.getFragment();
745 // FIXME Support symbols with no DF. For example:
746 // .reloc .data, ENUM_VALUE, <some expr>
747 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
748 return std::make_pair(false,
749 std::string("symbol in offset has no data "
750 "fragment"));
751 DF = cast<MCDataFragment>(Fragment);
752 return None;
753 }
754
755 if (OffsetVal.getSymB())
756 return std::make_pair(false,
757 std::string(".reloc symbol offset is not "
758 "representable"));
759
760 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
761 if (!SRE.getSymbol().isDefined())
762 return std::make_pair(false,
763 std::string("symbol used in the .reloc offset is "
764 "not defined"));
765
766 if (SRE.getSymbol().isVariable())
767 return std::make_pair(false,
768 std::string("symbol used in the .reloc offset is "
769 "variable"));
770
771 MCFragment *Fragment = SRE.getSymbol().getFragment();
772 // FIXME Support symbols with no DF. For example:
773 // .reloc .data, ENUM_VALUE, <some expr>
774 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
775 return std::make_pair(false,
776 std::string("symbol in offset has no data "
777 "fragment"));
778 RelocOffset = SRE.getSymbol().getOffset() + OffsetVal.getConstant();
779 DF = cast<MCDataFragment>(Fragment);
780 } else {
781 RelocOffset = Symbol.getOffset();
782 MCFragment *Fragment = Symbol.getFragment();
783 // FIXME Support symbols with no DF. For example:
784 // .reloc .data, ENUM_VALUE, <some expr>
785 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
786 return std::make_pair(false,
787 std::string("symbol in offset has no data "
788 "fragment"));
789 DF = cast<MCDataFragment>(Fragment);
790 }
791 return None;
792 }
793
794 Optional<std::pair<bool, std::string>>
emitRelocDirective(const MCExpr & Offset,StringRef Name,const MCExpr * Expr,SMLoc Loc,const MCSubtargetInfo & STI)795 MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
796 const MCExpr *Expr, SMLoc Loc,
797 const MCSubtargetInfo &STI) {
798 Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name);
799 if (!MaybeKind)
800 return std::make_pair(true, std::string("unknown relocation name"));
801
802 MCFixupKind Kind = *MaybeKind;
803
804 if (Expr == nullptr)
805 Expr =
806 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
807
808 MCDataFragment *DF = getOrCreateDataFragment(&STI);
809 flushPendingLabels(DF, DF->getContents().size());
810
811 MCValue OffsetVal;
812 if (!Offset.evaluateAsRelocatable(OffsetVal, nullptr, nullptr))
813 return std::make_pair(false,
814 std::string(".reloc offset is not relocatable"));
815 if (OffsetVal.isAbsolute()) {
816 if (OffsetVal.getConstant() < 0)
817 return std::make_pair(false, std::string(".reloc offset is negative"));
818 DF->getFixups().push_back(
819 MCFixup::create(OffsetVal.getConstant(), Expr, Kind, Loc));
820 return None;
821 }
822 if (OffsetVal.getSymB())
823 return std::make_pair(false,
824 std::string(".reloc offset is not representable"));
825
826 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
827 const MCSymbol &Symbol = SRE.getSymbol();
828 if (Symbol.isDefined()) {
829 uint32_t SymbolOffset = 0;
830 Optional<std::pair<bool, std::string>> Error;
831 Error = getOffsetAndDataFragment(Symbol, SymbolOffset, DF);
832
833 if (Error != None)
834 return Error;
835
836 DF->getFixups().push_back(
837 MCFixup::create(SymbolOffset + OffsetVal.getConstant(),
838 Expr, Kind, Loc));
839 return None;
840 }
841
842 PendingFixups.emplace_back(
843 &SRE.getSymbol(), DF,
844 MCFixup::create(OffsetVal.getConstant(), Expr, Kind, Loc));
845 return None;
846 }
847
emitFill(const MCExpr & NumBytes,uint64_t FillValue,SMLoc Loc)848 void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
849 SMLoc Loc) {
850 MCDataFragment *DF = getOrCreateDataFragment();
851 flushPendingLabels(DF, DF->getContents().size());
852
853 assert(getCurrentSectionOnly() && "need a section");
854 insert(new MCFillFragment(FillValue, 1, NumBytes, Loc));
855 }
856
emitFill(const MCExpr & NumValues,int64_t Size,int64_t Expr,SMLoc Loc)857 void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
858 int64_t Expr, SMLoc Loc) {
859 int64_t IntNumValues;
860 // Do additional checking now if we can resolve the value.
861 if (NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) {
862 if (IntNumValues < 0) {
863 getContext().getSourceManager()->PrintMessage(
864 Loc, SourceMgr::DK_Warning,
865 "'.fill' directive with negative repeat count has no effect");
866 return;
867 }
868 // Emit now if we can for better errors.
869 int64_t NonZeroSize = Size > 4 ? 4 : Size;
870 Expr &= ~0ULL >> (64 - NonZeroSize * 8);
871 for (uint64_t i = 0, e = IntNumValues; i != e; ++i) {
872 emitIntValue(Expr, NonZeroSize);
873 if (NonZeroSize < Size)
874 emitIntValue(0, Size - NonZeroSize);
875 }
876 return;
877 }
878
879 // Otherwise emit as fragment.
880 MCDataFragment *DF = getOrCreateDataFragment();
881 flushPendingLabels(DF, DF->getContents().size());
882
883 assert(getCurrentSectionOnly() && "need a section");
884 insert(new MCFillFragment(Expr, Size, NumValues, Loc));
885 }
886
emitNops(int64_t NumBytes,int64_t ControlledNopLength,SMLoc Loc,const MCSubtargetInfo & STI)887 void MCObjectStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLength,
888 SMLoc Loc, const MCSubtargetInfo &STI) {
889 // Emit an NOP fragment.
890 MCDataFragment *DF = getOrCreateDataFragment();
891 flushPendingLabels(DF, DF->getContents().size());
892
893 assert(getCurrentSectionOnly() && "need a section");
894
895 insert(new MCNopsFragment(NumBytes, ControlledNopLength, Loc, STI));
896 }
897
emitFileDirective(StringRef Filename)898 void MCObjectStreamer::emitFileDirective(StringRef Filename) {
899 getAssembler().addFileName(Filename);
900 }
901
emitFileDirective(StringRef Filename,StringRef CompilerVerion,StringRef TimeStamp,StringRef Description)902 void MCObjectStreamer::emitFileDirective(StringRef Filename,
903 StringRef CompilerVerion,
904 StringRef TimeStamp,
905 StringRef Description) {
906 getAssembler().addFileName(Filename);
907 // TODO: add additional info to integrated assembler.
908 }
909
emitAddrsig()910 void MCObjectStreamer::emitAddrsig() {
911 getAssembler().getWriter().emitAddrsigSection();
912 }
913
emitAddrsigSym(const MCSymbol * Sym)914 void MCObjectStreamer::emitAddrsigSym(const MCSymbol *Sym) {
915 getAssembler().registerSymbol(*Sym);
916 getAssembler().getWriter().addAddrsigSymbol(Sym);
917 }
918
finishImpl()919 void MCObjectStreamer::finishImpl() {
920 getContext().RemapDebugPaths();
921
922 // If we are generating dwarf for assembly source files dump out the sections.
923 if (getContext().getGenDwarfForAssembly())
924 MCGenDwarfInfo::Emit(this);
925
926 // Dump out the dwarf file & directory tables and line tables.
927 MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
928
929 // Emit pseudo probes for the current module.
930 MCPseudoProbeTable::emit(this);
931
932 // Update any remaining pending labels with empty data fragments.
933 flushPendingLabels();
934
935 resolvePendingFixups();
936 getAssembler().Finish();
937 }
938