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