1 //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
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
7 //===----------------------------------------------------------------------===//
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"
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());
37 MCObjectStreamer::~MCObjectStreamer() {}
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.
42 MCAssembler *MCObjectStreamer::getAssemblerPtr() {
43 if (getUseAssemblerInfoForParsing())
44 return Assembler.get();
48 void MCObjectStreamer::addPendingLabel(MCSymbol* S) {
49 MCSection *CurSection = getCurrentSectionOnly();
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();
58 // Add this label to the current Section / Subsection.
59 CurSection->addPendingLabel(S, CurSubsectionIdx);
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);
68 // There is no Section / Subsection for this label yet.
69 PendingLabels.push_back(S);
72 void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
73 MCSection *CurSection = getCurrentSectionOnly();
75 assert(PendingLabels.empty());
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();
85 // Associate a fragment with this label, either the supplied fragment
86 // or an empty data fragment.
88 CurSection->flushPendingLabels(F, FOffset, CurSubsectionIdx);
90 CurSection->flushPendingLabels(nullptr, 0, CurSubsectionIdx);
93 void MCObjectStreamer::flushPendingLabels() {
94 // Register labels that have not yet been assigned to a Section.
95 if (!PendingLabels.empty()) {
96 MCSection *CurSection = getCurrentSectionOnly();
98 for (MCSymbol* Sym : PendingLabels)
99 CurSection->addPendingLabel(Sym, CurSubsectionIdx);
100 PendingLabels.clear();
103 // Assign an empty data fragment to all remaining pending labels.
104 for (MCSection* Section : PendingLabelSections)
105 Section->flushPendingLabels();
108 // When fixup's offset is a forward declared label, e.g.:
110 // .reloc 1f, R_MIPS_JALR, foo
113 // postpone adding it to Fixups vector until the label is defined and its offset
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");
122 flushPendingLabels(PendingFixup.DF, PendingFixup.DF->getContents().size());
123 PendingFixup.Fixup.setOffset(PendingFixup.Sym->getOffset());
124 PendingFixup.DF->getFixups().push_back(PendingFixup.Fixup);
126 PendingFixups.clear();
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>
132 absoluteSymbolDiff(MCAssembler &Asm, const MCSymbol *Hi, const MCSymbol *Lo) {
134 if (Asm.getBackendPtr()->requiresDiffExpressionRelocations())
137 if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
138 Hi->isVariable() || Lo->isVariable())
141 return Hi->getOffset() - Lo->getOffset();
144 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
147 if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
148 EmitIntValue(*Diff, Size);
151 MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
154 void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
155 const MCSymbol *Lo) {
156 if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
157 EmitULEB128IntValue(*Diff);
160 MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
163 void MCObjectStreamer::reset() {
166 CurInsertionPoint = MCSection::iterator();
168 EmitDebugFrame = false;
169 PendingLabels.clear();
170 PendingLabelSections.clear();
174 void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
175 if (!getNumFrameInfos())
179 MCDwarfFrameEmitter::Emit(*this, MAB, true);
182 MCDwarfFrameEmitter::Emit(*this, MAB, false);
185 MCFragment *MCObjectStreamer::getCurrentFragment() const {
186 assert(getCurrentSectionOnly() && "No current section!");
188 if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
189 return &*std::prev(CurInsertionPoint);
194 static bool CanReuseDataFragment(const MCDataFragment &F,
195 const MCAssembler &Assembler,
196 const MCSubtargetInfo *STI) {
197 if (!F.hasInstructions())
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
205 return !STI || F.getSubtargetInfo() == 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();
218 void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
219 Assembler->registerSymbol(Sym);
222 void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
223 MCStreamer::EmitCFISections(EH, Debug);
225 EmitDebugFrame = Debug;
228 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
230 MCStreamer::EmitValueImpl(Value, Size, Loc);
231 MCDataFragment *DF = getOrCreateDataFragment();
232 flushPendingLabels(DF, DF->getContents().size());
234 MCDwarfLineEntry::Make(this, getCurrentSectionOnly());
236 // Avoid fixups when possible.
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.");
244 EmitIntValue(AbsValue, Size);
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);
253 MCSymbol *MCObjectStreamer::EmitCFILabel() {
254 MCSymbol *Label = getContext().createTempSymbol("cfi", true);
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);
265 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
266 Frame.End = getContext().createTempSymbol();
267 EmitLabel(Frame.End);
270 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
271 MCStreamer::EmitLabel(Symbol, Loc);
273 getAssembler().registerSymbol(*Symbol);
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
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());
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);
292 // Emit a label at a previously emitted fragment/offset position. This must be
293 // within the currently-active section.
294 void MCObjectStreamer::EmitLabelAtPos(MCSymbol *Symbol, SMLoc Loc,
295 MCFragment *F, uint64_t Offset) {
296 assert(F->getParent() == getCurrentSectionOnly());
298 MCStreamer::EmitLabel(Symbol, Loc);
299 getAssembler().registerSymbol(*Symbol);
300 auto *DF = dyn_cast_or_null<MCDataFragment>(F);
301 Symbol->setOffset(Offset);
303 Symbol->setFragment(F);
305 assert(isa<MCDummyFragment>(F) &&
306 "F must either be an MCDataFragment or the pending MCDummyFragment");
308 addPendingLabel(Symbol);
312 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
314 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
315 EmitULEB128IntValue(IntValue);
318 insert(new MCLEBFragment(*Value, false));
321 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
323 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
324 EmitSLEB128IntValue(IntValue);
327 insert(new MCLEBFragment(*Value, true));
330 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
331 const MCSymbol *Symbol) {
332 report_fatal_error("This file format doesn't support weak aliases.");
335 void MCObjectStreamer::ChangeSection(MCSection *Section,
336 const MCExpr *Subsection) {
337 changeSectionImpl(Section, Subsection);
340 bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
341 const MCExpr *Subsection) {
342 assert(Section && "Cannot switch to a null section!");
343 getContext().clearDwarfLocSeen();
345 bool Created = getAssembler().registerSection(*Section);
347 int64_t IntSubsection = 0;
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);
355 Section->getSubsectionInsertionPoint(CurSubsectionIdx);
359 void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
360 getAssembler().registerSymbol(*Symbol);
361 MCStreamer::EmitAssignment(Symbol, Value);
364 bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
365 return Sec.hasInstructions();
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);
375 void MCObjectStreamer::EmitInstructionImpl(const MCInst &Inst,
376 const MCSubtargetInfo &STI) {
377 MCStreamer::EmitInstruction(Inst, STI);
379 MCSection *Sec = getCurrentSectionOnly();
380 Sec->setHasInstructions(true);
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());
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);
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
398 if (Assembler.getRelaxAll() ||
399 (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
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);
408 // Otherwise emit to a separate fragment.
409 EmitInstToFragment(Inst, 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");
417 // Always create a new, separate fragment here, because its size can change
418 // during relaxation.
419 MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
422 SmallString<128> Code;
423 raw_svector_ostream VecOS(Code);
424 getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
426 IF->getContents().append(Code.begin(), Code.end());
430 static const char *const BundlingNotImplementedMsg =
431 "Aligned bundling is not implemented for this object format";
434 void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
435 llvm_unreachable(BundlingNotImplementedMsg);
438 void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
439 llvm_unreachable(BundlingNotImplementedMsg);
442 void MCObjectStreamer::EmitBundleUnlock() {
443 llvm_unreachable(BundlingNotImplementedMsg);
446 void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
447 unsigned Column, unsigned Flags,
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());
455 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
456 Isa, Discriminator, FileName);
459 static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
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);
470 static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
471 MCDwarfLineTableParams Params,
472 int64_t LineDelta, const MCSymbol *Label,
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);
480 // emit the sequence for the LineDelta (from 1) and a zero address delta.
481 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
484 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
485 const MCSymbol *LastLabel,
486 const MCSymbol *Label,
487 unsigned PointerSize) {
489 emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
493 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
495 if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
496 MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
500 insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
503 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
504 const MCSymbol *Label) {
505 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
507 if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
508 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
511 insert(new MCDwarfCallFrameFragment(*AddrDelta));
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))
522 // Emit a label at the current position and record it in the CodeViewContext.
523 MCSymbol *LineSym = getContext().createTempSymbol();
525 getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId,
526 FileNo, Line, Column, PrologueEnd,
530 void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
531 const MCSymbol *Begin,
532 const MCSymbol *End) {
533 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
535 this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End);
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,
544 this->MCStreamer::EmitCVInlineLinetableDirective(
545 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
548 void MCObjectStreamer::EmitCVDefRangeDirective(
549 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
550 StringRef FixedSizePortion) {
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);
559 void MCObjectStreamer::EmitCVStringTableDirective() {
560 getContext().getCVContext().emitStringTable(*this);
562 void MCObjectStreamer::EmitCVFileChecksumsDirective() {
563 getContext().getCVContext().emitFileChecksums(*this);
566 void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
567 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
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());
577 void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
580 unsigned MaxBytesToEmit) {
581 if (MaxBytesToEmit == 0)
582 MaxBytesToEmit = ByteAlignment;
583 insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
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));
591 void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
592 unsigned MaxBytesToEmit) {
593 EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
594 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
597 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
600 insert(new MCOrgFragment(*Offset, Value, Loc));
603 // Associate DTPRel32 fixup with data and resize data area
604 void MCObjectStreamer::EmitDTPRel32Value(const MCExpr *Value) {
605 MCDataFragment *DF = getOrCreateDataFragment();
606 flushPendingLabels(DF, DF->getContents().size());
608 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
609 Value, FK_DTPRel_4));
610 DF->getContents().resize(DF->getContents().size() + 4, 0);
613 // Associate DTPRel64 fixup with data and resize data area
614 void MCObjectStreamer::EmitDTPRel64Value(const MCExpr *Value) {
615 MCDataFragment *DF = getOrCreateDataFragment();
616 flushPendingLabels(DF, DF->getContents().size());
618 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
619 Value, FK_DTPRel_8));
620 DF->getContents().resize(DF->getContents().size() + 8, 0);
623 // Associate TPRel32 fixup with data and resize data area
624 void MCObjectStreamer::EmitTPRel32Value(const MCExpr *Value) {
625 MCDataFragment *DF = getOrCreateDataFragment();
626 flushPendingLabels(DF, DF->getContents().size());
628 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
630 DF->getContents().resize(DF->getContents().size() + 4, 0);
633 // Associate TPRel64 fixup with data and resize data area
634 void MCObjectStreamer::EmitTPRel64Value(const MCExpr *Value) {
635 MCDataFragment *DF = getOrCreateDataFragment();
636 flushPendingLabels(DF, DF->getContents().size());
638 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
640 DF->getContents().resize(DF->getContents().size() + 8, 0);
643 // Associate GPRel32 fixup with data and resize data area
644 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
645 MCDataFragment *DF = getOrCreateDataFragment();
646 flushPendingLabels(DF, DF->getContents().size());
648 DF->getFixups().push_back(
649 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
650 DF->getContents().resize(DF->getContents().size() + 4, 0);
653 // Associate GPRel64 fixup with data and resize data area
654 void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
655 MCDataFragment *DF = getOrCreateDataFragment();
656 flushPendingLabels(DF, DF->getContents().size());
658 DF->getFixups().push_back(
659 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
660 DF->getContents().resize(DF->getContents().size() + 8, 0);
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())
670 MCFixupKind Kind = *MaybeKind;
674 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
676 MCDataFragment *DF = getOrCreateDataFragment(&STI);
677 flushPendingLabels(DF, DF->getContents().size());
680 if (Offset.evaluateAsAbsolute(OffsetValue)) {
682 llvm_unreachable(".reloc offset is negative");
683 DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc));
687 if (Offset.getKind() != llvm::MCExpr::SymbolRef)
688 llvm_unreachable(".reloc offset is not absolute nor a label");
690 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(Offset);
691 if (SRE.getSymbol().isDefined()) {
692 DF->getFixups().push_back(MCFixup::create(SRE.getSymbol().getOffset(),
697 PendingFixups.emplace_back(&SRE.getSymbol(), DF,
698 MCFixup::create(-1, Expr, Kind, Loc));
702 void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
704 MCDataFragment *DF = getOrCreateDataFragment();
705 flushPendingLabels(DF, DF->getContents().size());
707 assert(getCurrentSectionOnly() && "need a section");
708 insert(new MCFillFragment(FillValue, 1, NumBytes, 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");
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);
733 // Otherwise emit as fragment.
734 MCDataFragment *DF = getOrCreateDataFragment();
735 flushPendingLabels(DF, DF->getContents().size());
737 assert(getCurrentSectionOnly() && "need a section");
738 insert(new MCFillFragment(Expr, Size, NumValues, Loc));
741 void MCObjectStreamer::EmitFileDirective(StringRef Filename) {
742 getAssembler().addFileName(Filename);
745 void MCObjectStreamer::EmitAddrsig() {
746 getAssembler().getWriter().emitAddrsigSection();
749 void MCObjectStreamer::EmitAddrsigSym(const MCSymbol *Sym) {
750 getAssembler().registerSymbol(*Sym);
751 getAssembler().getWriter().addAddrsigSymbol(Sym);
754 void MCObjectStreamer::FinishImpl() {
755 getContext().RemapDebugPaths();
757 // If we are generating dwarf for assembly source files dump out the sections.
758 if (getContext().getGenDwarfForAssembly())
759 MCGenDwarfInfo::Emit(this);
761 // Dump out the dwarf file & directory tables and line tables.
762 MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
764 // Update any remaining pending labels with empty data fragments.
765 flushPendingLabels();
767 resolvePendingFixups();
768 getAssembler().Finish();