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/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"
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());
39 MCObjectStreamer::~MCObjectStreamer() = default;
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.
44 MCAssembler
*MCObjectStreamer::getAssemblerPtr() {
45 if (getUseAssemblerInfoForParsing())
46 return Assembler
.get();
50 void MCObjectStreamer::addPendingLabel(MCSymbol
* S
) {
51 MCSection
*CurSection
= getCurrentSectionOnly();
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();
60 // Add this label to the current Section / Subsection.
61 CurSection
->addPendingLabel(S
, CurSubsectionIdx
);
63 // Add this Section to the list of PendingLabelSections.
64 PendingLabelSections
.insert(CurSection
);
66 // There is no Section / Subsection for this label yet.
67 PendingLabels
.push_back(S
);
70 void MCObjectStreamer::flushPendingLabels(MCFragment
*F
, uint64_t FOffset
) {
72 MCSection
*CurSection
= getCurrentSectionOnly();
74 assert(PendingLabels
.empty());
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();
84 // Associate the labels with F.
85 CurSection
->flushPendingLabels(F
, FOffset
, CurSubsectionIdx
);
88 void MCObjectStreamer::flushPendingLabels() {
89 // Register labels that have not yet been assigned to a Section.
90 if (!PendingLabels
.empty()) {
91 MCSection
*CurSection
= getCurrentSectionOnly();
93 for (MCSymbol
* Sym
: PendingLabels
)
94 CurSection
->addPendingLabel(Sym
, CurSubsectionIdx
);
95 PendingLabels
.clear();
98 // Assign an empty data fragment to all remaining pending labels.
99 for (MCSection
* Section
: PendingLabelSections
)
100 Section
->flushPendingLabels();
103 // When fixup's offset is a forward declared label, e.g.:
105 // .reloc 1f, R_MIPS_JALR, foo
108 // postpone adding it to Fixups vector until the label is defined and its offset
110 void MCObjectStreamer::resolvePendingFixups() {
111 for (PendingMCFixup
&PendingFixup
: PendingFixups
) {
112 if (!PendingFixup
.Sym
|| PendingFixup
.Sym
->isUndefined ()) {
113 getContext().reportError(PendingFixup
.Fixup
.getLoc(),
114 "unresolved relocation offset");
117 flushPendingLabels(PendingFixup
.DF
, PendingFixup
.DF
->getContents().size());
118 PendingFixup
.Fixup
.setOffset(PendingFixup
.Sym
->getOffset() +
119 PendingFixup
.Fixup
.getOffset());
121 // If the location symbol to relocate is in MCEncodedFragmentWithFixups,
122 // put the Fixup into location symbol's fragment. Otherwise
123 // put into PendingFixup.DF
124 MCFragment
*SymFragment
= PendingFixup
.Sym
->getFragment();
125 switch (SymFragment
->getKind()) {
126 case MCFragment::FT_Relaxable
:
127 case MCFragment::FT_Dwarf
:
128 case MCFragment::FT_PseudoProbe
:
129 cast
<MCEncodedFragmentWithFixups
<8, 1>>(SymFragment
)
131 .push_back(PendingFixup
.Fixup
);
133 case MCFragment::FT_Data
:
134 case MCFragment::FT_CVDefRange
:
135 cast
<MCEncodedFragmentWithFixups
<32, 4>>(SymFragment
)
137 .push_back(PendingFixup
.Fixup
);
140 PendingFixup
.DF
->getFixups().push_back(PendingFixup
.Fixup
);
144 PendingFixups
.clear();
147 // As a compile-time optimization, avoid allocating and evaluating an MCExpr
148 // tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
149 static std::optional
<uint64_t> absoluteSymbolDiff(const MCSymbol
*Hi
,
150 const MCSymbol
*Lo
) {
152 if (!Hi
->getFragment() || Hi
->getFragment() != Lo
->getFragment() ||
153 Hi
->isVariable() || Lo
->isVariable())
156 return Hi
->getOffset() - Lo
->getOffset();
159 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol
*Hi
,
162 if (!getAssembler().getContext().getTargetTriple().isRISCV())
163 if (std::optional
<uint64_t> Diff
= absoluteSymbolDiff(Hi
, Lo
))
164 return emitIntValue(*Diff
, Size
);
165 MCStreamer::emitAbsoluteSymbolDiff(Hi
, Lo
, Size
);
168 void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol
*Hi
,
169 const MCSymbol
*Lo
) {
170 if (!getAssembler().getContext().getTargetTriple().isRISCV())
171 if (std::optional
<uint64_t> Diff
= absoluteSymbolDiff(Hi
, Lo
)) {
172 emitULEB128IntValue(*Diff
);
175 MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi
, Lo
);
178 void MCObjectStreamer::reset() {
181 CurInsertionPoint
= MCSection::iterator();
183 EmitDebugFrame
= false;
184 PendingLabels
.clear();
185 PendingLabelSections
.clear();
189 void MCObjectStreamer::emitFrames(MCAsmBackend
*MAB
) {
190 if (!getNumFrameInfos())
194 MCDwarfFrameEmitter::Emit(*this, MAB
, true);
197 MCDwarfFrameEmitter::Emit(*this, MAB
, false);
200 MCFragment
*MCObjectStreamer::getCurrentFragment() const {
201 assert(getCurrentSectionOnly() && "No current section!");
203 if (CurInsertionPoint
!= getCurrentSectionOnly()->getFragmentList().begin())
204 return &*std::prev(CurInsertionPoint
);
209 static bool canReuseDataFragment(const MCDataFragment
&F
,
210 const MCAssembler
&Assembler
,
211 const MCSubtargetInfo
*STI
) {
212 if (!F
.hasInstructions())
214 // Do not add data after a linker-relaxable instruction. The difference
215 // between a new label and a label at or before the linker-relaxable
216 // instruction cannot be resolved at assemble-time.
217 if (F
.isLinkerRelaxable())
219 // When bundling is enabled, we don't want to add data to a fragment that
220 // already has instructions (see MCELFStreamer::emitInstToData for details)
221 if (Assembler
.isBundlingEnabled())
222 return Assembler
.getRelaxAll();
223 // If the subtarget is changed mid fragment we start a new fragment to record
225 return !STI
|| F
.getSubtargetInfo() == STI
;
229 MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo
*STI
) {
230 MCDataFragment
*F
= dyn_cast_or_null
<MCDataFragment
>(getCurrentFragment());
231 if (!F
|| !canReuseDataFragment(*F
, *Assembler
, STI
)) {
232 F
= new MCDataFragment();
238 void MCObjectStreamer::visitUsedSymbol(const MCSymbol
&Sym
) {
239 Assembler
->registerSymbol(Sym
);
242 void MCObjectStreamer::emitCFISections(bool EH
, bool Debug
) {
243 MCStreamer::emitCFISections(EH
, Debug
);
245 EmitDebugFrame
= Debug
;
248 void MCObjectStreamer::emitValueImpl(const MCExpr
*Value
, unsigned Size
,
250 MCStreamer::emitValueImpl(Value
, Size
, Loc
);
251 MCDataFragment
*DF
= getOrCreateDataFragment();
252 flushPendingLabels(DF
, DF
->getContents().size());
254 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
256 // Avoid fixups when possible.
258 if (Value
->evaluateAsAbsolute(AbsValue
, getAssemblerPtr())) {
259 if (!isUIntN(8 * Size
, AbsValue
) && !isIntN(8 * Size
, AbsValue
)) {
260 getContext().reportError(
261 Loc
, "value evaluated as " + Twine(AbsValue
) + " is out of range.");
264 emitIntValue(AbsValue
, Size
);
267 DF
->getFixups().push_back(
268 MCFixup::create(DF
->getContents().size(), Value
,
269 MCFixup::getKindForSize(Size
, false), Loc
));
270 DF
->getContents().resize(DF
->getContents().size() + Size
, 0);
273 MCSymbol
*MCObjectStreamer::emitCFILabel() {
274 MCSymbol
*Label
= getContext().createTempSymbol("cfi");
279 void MCObjectStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) {
280 // We need to create a local symbol to avoid relocations.
281 Frame
.Begin
= getContext().createTempSymbol();
282 emitLabel(Frame
.Begin
);
285 void MCObjectStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) {
286 Frame
.End
= getContext().createTempSymbol();
287 emitLabel(Frame
.End
);
290 void MCObjectStreamer::emitLabel(MCSymbol
*Symbol
, SMLoc Loc
) {
291 MCStreamer::emitLabel(Symbol
, Loc
);
293 getAssembler().registerSymbol(*Symbol
);
295 // If there is a current fragment, mark the symbol as pointing into it.
296 // Otherwise queue the label and set its fragment pointer when we emit the
298 auto *F
= dyn_cast_or_null
<MCDataFragment
>(getCurrentFragment());
299 if (F
&& !(getAssembler().isBundlingEnabled() &&
300 getAssembler().getRelaxAll())) {
301 Symbol
->setFragment(F
);
302 Symbol
->setOffset(F
->getContents().size());
304 // Assign all pending labels to offset 0 within the dummy "pending"
305 // fragment. (They will all be reassigned to a real fragment in
306 // flushPendingLabels())
307 Symbol
->setOffset(0);
308 addPendingLabel(Symbol
);
311 emitPendingAssignments(Symbol
);
314 void MCObjectStreamer::emitPendingAssignments(MCSymbol
*Symbol
) {
315 auto Assignments
= pendingAssignments
.find(Symbol
);
316 if (Assignments
!= pendingAssignments
.end()) {
317 for (const PendingAssignment
&A
: Assignments
->second
)
318 emitAssignment(A
.Symbol
, A
.Value
);
320 pendingAssignments
.erase(Assignments
);
324 // Emit a label at a previously emitted fragment/offset position. This must be
325 // within the currently-active section.
326 void MCObjectStreamer::emitLabelAtPos(MCSymbol
*Symbol
, SMLoc Loc
,
327 MCFragment
*F
, uint64_t Offset
) {
328 assert(F
->getParent() == getCurrentSectionOnly());
330 MCStreamer::emitLabel(Symbol
, Loc
);
331 getAssembler().registerSymbol(*Symbol
);
332 auto *DF
= dyn_cast_or_null
<MCDataFragment
>(F
);
333 Symbol
->setOffset(Offset
);
335 Symbol
->setFragment(F
);
337 assert(isa
<MCDummyFragment
>(F
) &&
338 "F must either be an MCDataFragment or the pending MCDummyFragment");
340 addPendingLabel(Symbol
);
344 void MCObjectStreamer::emitULEB128Value(const MCExpr
*Value
) {
346 if (Value
->evaluateAsAbsolute(IntValue
, getAssemblerPtr())) {
347 emitULEB128IntValue(IntValue
);
350 insert(new MCLEBFragment(*Value
, false));
353 void MCObjectStreamer::emitSLEB128Value(const MCExpr
*Value
) {
355 if (Value
->evaluateAsAbsolute(IntValue
, getAssemblerPtr())) {
356 emitSLEB128IntValue(IntValue
);
359 insert(new MCLEBFragment(*Value
, true));
362 void MCObjectStreamer::emitWeakReference(MCSymbol
*Alias
,
363 const MCSymbol
*Symbol
) {
364 report_fatal_error("This file format doesn't support weak aliases.");
367 void MCObjectStreamer::changeSection(MCSection
*Section
,
368 const MCExpr
*Subsection
) {
369 changeSectionImpl(Section
, Subsection
);
372 bool MCObjectStreamer::changeSectionImpl(MCSection
*Section
,
373 const MCExpr
*Subsection
) {
374 assert(Section
&& "Cannot switch to a null section!");
375 getContext().clearDwarfLocSeen();
377 bool Created
= getAssembler().registerSection(*Section
);
379 int64_t IntSubsection
= 0;
381 !Subsection
->evaluateAsAbsolute(IntSubsection
, getAssemblerPtr())) {
382 getContext().reportError(Subsection
->getLoc(),
383 "cannot evaluate subsection number");
385 if (!isUInt
<31>(IntSubsection
)) {
386 getContext().reportError(Subsection
->getLoc(),
387 "subsection number " + Twine(IntSubsection
) +
388 " is not within [0,2147483647]");
391 CurSubsectionIdx
= unsigned(IntSubsection
);
393 Section
->getSubsectionInsertionPoint(CurSubsectionIdx
);
397 void MCObjectStreamer::emitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {
398 getAssembler().registerSymbol(*Symbol
);
399 MCStreamer::emitAssignment(Symbol
, Value
);
400 emitPendingAssignments(Symbol
);
403 void MCObjectStreamer::emitConditionalAssignment(MCSymbol
*Symbol
,
404 const MCExpr
*Value
) {
405 const MCSymbol
*Target
= &cast
<MCSymbolRefExpr
>(*Value
).getSymbol();
407 // If the symbol already exists, emit the assignment. Otherwise, emit it
408 // later only if the symbol is also emitted.
409 if (Target
->isRegistered())
410 emitAssignment(Symbol
, Value
);
412 pendingAssignments
[Target
].push_back({Symbol
, Value
});
415 bool MCObjectStreamer::mayHaveInstructions(MCSection
&Sec
) const {
416 return Sec
.hasInstructions();
419 void MCObjectStreamer::emitInstruction(const MCInst
&Inst
,
420 const MCSubtargetInfo
&STI
) {
421 const MCSection
&Sec
= *getCurrentSectionOnly();
422 if (Sec
.isVirtualSection()) {
423 getContext().reportError(Inst
.getLoc(), Twine(Sec
.getVirtualSectionKind()) +
424 " section '" + Sec
.getName() +
425 "' cannot have instructions");
428 getAssembler().getBackend().emitInstructionBegin(*this, Inst
, STI
);
429 emitInstructionImpl(Inst
, STI
);
430 getAssembler().getBackend().emitInstructionEnd(*this, Inst
);
433 void MCObjectStreamer::emitInstructionImpl(const MCInst
&Inst
,
434 const MCSubtargetInfo
&STI
) {
435 MCStreamer::emitInstruction(Inst
, STI
);
437 MCSection
*Sec
= getCurrentSectionOnly();
438 Sec
->setHasInstructions(true);
440 // Now that a machine instruction has been assembled into this section, make
441 // a line entry for any .loc directive that has been seen.
442 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
444 // If this instruction doesn't need relaxation, just emit it as data.
445 MCAssembler
&Assembler
= getAssembler();
446 MCAsmBackend
&Backend
= Assembler
.getBackend();
447 if (!(Backend
.mayNeedRelaxation(Inst
, STI
) ||
448 Backend
.allowEnhancedRelaxation())) {
449 emitInstToData(Inst
, STI
);
453 // Otherwise, relax and emit it as data if either:
454 // - The RelaxAll flag was passed
455 // - Bundling is enabled and this instruction is inside a bundle-locked
456 // group. We want to emit all such instructions into the same data
458 if (Assembler
.getRelaxAll() ||
459 (Assembler
.isBundlingEnabled() && Sec
->isBundleLocked())) {
460 MCInst Relaxed
= Inst
;
461 while (Backend
.mayNeedRelaxation(Relaxed
, STI
))
462 Backend
.relaxInstruction(Relaxed
, STI
);
463 emitInstToData(Relaxed
, STI
);
467 // Otherwise emit to a separate fragment.
468 emitInstToFragment(Inst
, STI
);
471 void MCObjectStreamer::emitInstToFragment(const MCInst
&Inst
,
472 const MCSubtargetInfo
&STI
) {
473 if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
474 llvm_unreachable("All instructions should have already been relaxed");
476 // Always create a new, separate fragment here, because its size can change
477 // during relaxation.
478 MCRelaxableFragment
*IF
= new MCRelaxableFragment(Inst
, STI
);
481 SmallString
<128> Code
;
482 getAssembler().getEmitter().encodeInstruction(Inst
, Code
, IF
->getFixups(),
484 IF
->getContents().append(Code
.begin(), Code
.end());
488 static const char *const BundlingNotImplementedMsg
=
489 "Aligned bundling is not implemented for this object format";
492 void MCObjectStreamer::emitBundleAlignMode(Align Alignment
) {
493 llvm_unreachable(BundlingNotImplementedMsg
);
496 void MCObjectStreamer::emitBundleLock(bool AlignToEnd
) {
497 llvm_unreachable(BundlingNotImplementedMsg
);
500 void MCObjectStreamer::emitBundleUnlock() {
501 llvm_unreachable(BundlingNotImplementedMsg
);
504 void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo
, unsigned Line
,
505 unsigned Column
, unsigned Flags
,
507 unsigned Discriminator
,
508 StringRef FileName
) {
509 // In case we see two .loc directives in a row, make sure the
510 // first one gets a line entry.
511 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
513 this->MCStreamer::emitDwarfLocDirective(FileNo
, Line
, Column
, Flags
, Isa
,
514 Discriminator
, FileName
);
517 static const MCExpr
*buildSymbolDiff(MCObjectStreamer
&OS
, const MCSymbol
*A
,
518 const MCSymbol
*B
, SMLoc Loc
) {
519 MCContext
&Context
= OS
.getContext();
520 MCSymbolRefExpr::VariantKind Variant
= MCSymbolRefExpr::VK_None
;
521 const MCExpr
*ARef
= MCSymbolRefExpr::create(A
, Variant
, Context
);
522 const MCExpr
*BRef
= MCSymbolRefExpr::create(B
, Variant
, Context
);
523 const MCExpr
*AddrDelta
=
524 MCBinaryExpr::create(MCBinaryExpr::Sub
, ARef
, BRef
, Context
, Loc
);
528 static void emitDwarfSetLineAddr(MCObjectStreamer
&OS
,
529 MCDwarfLineTableParams Params
,
530 int64_t LineDelta
, const MCSymbol
*Label
,
532 // emit the sequence to set the address
533 OS
.emitIntValue(dwarf::DW_LNS_extended_op
, 1);
534 OS
.emitULEB128IntValue(PointerSize
+ 1);
535 OS
.emitIntValue(dwarf::DW_LNE_set_address
, 1);
536 OS
.emitSymbolValue(Label
, PointerSize
);
538 // emit the sequence for the LineDelta (from 1) and a zero address delta.
539 MCDwarfLineAddr::Emit(&OS
, Params
, LineDelta
, 0);
542 void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta
,
543 const MCSymbol
*LastLabel
,
544 const MCSymbol
*Label
,
545 unsigned PointerSize
) {
547 emitDwarfSetLineAddr(*this, Assembler
->getDWARFLinetableParams(), LineDelta
,
551 const MCExpr
*AddrDelta
= buildSymbolDiff(*this, Label
, LastLabel
, SMLoc());
552 insert(new MCDwarfLineAddrFragment(LineDelta
, *AddrDelta
));
555 void MCObjectStreamer::emitDwarfLineEndEntry(MCSection
*Section
,
556 MCSymbol
*LastLabel
) {
557 // Emit a DW_LNE_end_sequence for the end of the section.
558 // Use the section end label to compute the address delta and use INT64_MAX
559 // as the line delta which is the signal that this is actually a
560 // DW_LNE_end_sequence.
561 MCSymbol
*SectionEnd
= endSection(Section
);
563 // Switch back the dwarf line section, in case endSection had to switch the
565 MCContext
&Ctx
= getContext();
566 switchSection(Ctx
.getObjectFileInfo()->getDwarfLineSection());
568 const MCAsmInfo
*AsmInfo
= Ctx
.getAsmInfo();
569 emitDwarfAdvanceLineAddr(INT64_MAX
, LastLabel
, SectionEnd
,
570 AsmInfo
->getCodePointerSize());
573 void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol
*LastLabel
,
574 const MCSymbol
*Label
,
576 const MCExpr
*AddrDelta
= buildSymbolDiff(*this, Label
, LastLabel
, Loc
);
577 insert(new MCDwarfCallFrameFragment(*AddrDelta
, nullptr));
580 void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId
, unsigned FileNo
,
581 unsigned Line
, unsigned Column
,
582 bool PrologueEnd
, bool IsStmt
,
583 StringRef FileName
, SMLoc Loc
) {
584 // Validate the directive.
585 if (!checkCVLocSection(FunctionId
, FileNo
, Loc
))
588 // Emit a label at the current position and record it in the CodeViewContext.
589 MCSymbol
*LineSym
= getContext().createTempSymbol();
591 getContext().getCVContext().recordCVLoc(getContext(), LineSym
, FunctionId
,
592 FileNo
, Line
, Column
, PrologueEnd
,
596 void MCObjectStreamer::emitCVLinetableDirective(unsigned FunctionId
,
597 const MCSymbol
*Begin
,
598 const MCSymbol
*End
) {
599 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId
, Begin
,
601 this->MCStreamer::emitCVLinetableDirective(FunctionId
, Begin
, End
);
604 void MCObjectStreamer::emitCVInlineLinetableDirective(
605 unsigned PrimaryFunctionId
, unsigned SourceFileId
, unsigned SourceLineNum
,
606 const MCSymbol
*FnStartSym
, const MCSymbol
*FnEndSym
) {
607 getContext().getCVContext().emitInlineLineTableForFunction(
608 *this, PrimaryFunctionId
, SourceFileId
, SourceLineNum
, FnStartSym
,
610 this->MCStreamer::emitCVInlineLinetableDirective(
611 PrimaryFunctionId
, SourceFileId
, SourceLineNum
, FnStartSym
, FnEndSym
);
614 void MCObjectStreamer::emitCVDefRangeDirective(
615 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
616 StringRef FixedSizePortion
) {
618 getContext().getCVContext().emitDefRange(*this, Ranges
, FixedSizePortion
);
619 // Attach labels that were pending before we created the defrange fragment to
620 // the beginning of the new fragment.
621 flushPendingLabels(Frag
, 0);
622 this->MCStreamer::emitCVDefRangeDirective(Ranges
, FixedSizePortion
);
625 void MCObjectStreamer::emitCVStringTableDirective() {
626 getContext().getCVContext().emitStringTable(*this);
628 void MCObjectStreamer::emitCVFileChecksumsDirective() {
629 getContext().getCVContext().emitFileChecksums(*this);
632 void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo
) {
633 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo
);
636 void MCObjectStreamer::emitBytes(StringRef Data
) {
637 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
638 MCDataFragment
*DF
= getOrCreateDataFragment();
639 flushPendingLabels(DF
, DF
->getContents().size());
640 DF
->getContents().append(Data
.begin(), Data
.end());
643 void MCObjectStreamer::emitValueToAlignment(Align Alignment
, int64_t Value
,
645 unsigned MaxBytesToEmit
) {
646 if (MaxBytesToEmit
== 0)
647 MaxBytesToEmit
= Alignment
.value();
648 insert(new MCAlignFragment(Alignment
, Value
, ValueSize
, MaxBytesToEmit
));
650 // Update the maximum alignment on the current section if necessary.
651 MCSection
*CurSec
= getCurrentSectionOnly();
652 CurSec
->ensureMinAlignment(Alignment
);
655 void MCObjectStreamer::emitCodeAlignment(Align Alignment
,
656 const MCSubtargetInfo
*STI
,
657 unsigned MaxBytesToEmit
) {
658 emitValueToAlignment(Alignment
, 0, 1, MaxBytesToEmit
);
659 cast
<MCAlignFragment
>(getCurrentFragment())->setEmitNops(true, STI
);
662 void MCObjectStreamer::emitValueToOffset(const MCExpr
*Offset
,
665 insert(new MCOrgFragment(*Offset
, Value
, Loc
));
668 // Associate DTPRel32 fixup with data and resize data area
669 void MCObjectStreamer::emitDTPRel32Value(const MCExpr
*Value
) {
670 MCDataFragment
*DF
= getOrCreateDataFragment();
671 flushPendingLabels(DF
, DF
->getContents().size());
673 DF
->getFixups().push_back(MCFixup::create(DF
->getContents().size(),
674 Value
, FK_DTPRel_4
));
675 DF
->getContents().resize(DF
->getContents().size() + 4, 0);
678 // Associate DTPRel64 fixup with data and resize data area
679 void MCObjectStreamer::emitDTPRel64Value(const MCExpr
*Value
) {
680 MCDataFragment
*DF
= getOrCreateDataFragment();
681 flushPendingLabels(DF
, DF
->getContents().size());
683 DF
->getFixups().push_back(MCFixup::create(DF
->getContents().size(),
684 Value
, FK_DTPRel_8
));
685 DF
->getContents().resize(DF
->getContents().size() + 8, 0);
688 // Associate TPRel32 fixup with data and resize data area
689 void MCObjectStreamer::emitTPRel32Value(const MCExpr
*Value
) {
690 MCDataFragment
*DF
= getOrCreateDataFragment();
691 flushPendingLabels(DF
, DF
->getContents().size());
693 DF
->getFixups().push_back(MCFixup::create(DF
->getContents().size(),
695 DF
->getContents().resize(DF
->getContents().size() + 4, 0);
698 // Associate TPRel64 fixup with data and resize data area
699 void MCObjectStreamer::emitTPRel64Value(const MCExpr
*Value
) {
700 MCDataFragment
*DF
= getOrCreateDataFragment();
701 flushPendingLabels(DF
, DF
->getContents().size());
703 DF
->getFixups().push_back(MCFixup::create(DF
->getContents().size(),
705 DF
->getContents().resize(DF
->getContents().size() + 8, 0);
708 // Associate GPRel32 fixup with data and resize data area
709 void MCObjectStreamer::emitGPRel32Value(const MCExpr
*Value
) {
710 MCDataFragment
*DF
= getOrCreateDataFragment();
711 flushPendingLabels(DF
, DF
->getContents().size());
713 DF
->getFixups().push_back(
714 MCFixup::create(DF
->getContents().size(), Value
, FK_GPRel_4
));
715 DF
->getContents().resize(DF
->getContents().size() + 4, 0);
718 // Associate GPRel64 fixup with data and resize data area
719 void MCObjectStreamer::emitGPRel64Value(const MCExpr
*Value
) {
720 MCDataFragment
*DF
= getOrCreateDataFragment();
721 flushPendingLabels(DF
, DF
->getContents().size());
723 DF
->getFixups().push_back(
724 MCFixup::create(DF
->getContents().size(), Value
, FK_GPRel_4
));
725 DF
->getContents().resize(DF
->getContents().size() + 8, 0);
728 static std::optional
<std::pair
<bool, std::string
>>
729 getOffsetAndDataFragment(const MCSymbol
&Symbol
, uint32_t &RelocOffset
,
730 MCDataFragment
*&DF
) {
731 if (Symbol
.isVariable()) {
732 const MCExpr
*SymbolExpr
= Symbol
.getVariableValue();
734 if(!SymbolExpr
->evaluateAsRelocatable(OffsetVal
, nullptr, nullptr))
735 return std::make_pair(false,
736 std::string("symbol in .reloc offset is not "
738 if (OffsetVal
.isAbsolute()) {
739 RelocOffset
= OffsetVal
.getConstant();
740 MCFragment
*Fragment
= Symbol
.getFragment();
741 // FIXME Support symbols with no DF. For example:
742 // .reloc .data, ENUM_VALUE, <some expr>
743 if (!Fragment
|| Fragment
->getKind() != MCFragment::FT_Data
)
744 return std::make_pair(false,
745 std::string("symbol in offset has no data "
747 DF
= cast
<MCDataFragment
>(Fragment
);
751 if (OffsetVal
.getSymB())
752 return std::make_pair(false,
753 std::string(".reloc symbol offset is not "
756 const MCSymbolRefExpr
&SRE
= cast
<MCSymbolRefExpr
>(*OffsetVal
.getSymA());
757 if (!SRE
.getSymbol().isDefined())
758 return std::make_pair(false,
759 std::string("symbol used in the .reloc offset is "
762 if (SRE
.getSymbol().isVariable())
763 return std::make_pair(false,
764 std::string("symbol used in the .reloc offset is "
767 MCFragment
*Fragment
= SRE
.getSymbol().getFragment();
768 // FIXME Support symbols with no DF. For example:
769 // .reloc .data, ENUM_VALUE, <some expr>
770 if (!Fragment
|| Fragment
->getKind() != MCFragment::FT_Data
)
771 return std::make_pair(false,
772 std::string("symbol in offset has no data "
774 RelocOffset
= SRE
.getSymbol().getOffset() + OffsetVal
.getConstant();
775 DF
= cast
<MCDataFragment
>(Fragment
);
777 RelocOffset
= Symbol
.getOffset();
778 MCFragment
*Fragment
= Symbol
.getFragment();
779 // FIXME Support symbols with no DF. For example:
780 // .reloc .data, ENUM_VALUE, <some expr>
781 if (!Fragment
|| Fragment
->getKind() != MCFragment::FT_Data
)
782 return std::make_pair(false,
783 std::string("symbol in offset has no data "
785 DF
= cast
<MCDataFragment
>(Fragment
);
790 std::optional
<std::pair
<bool, std::string
>>
791 MCObjectStreamer::emitRelocDirective(const MCExpr
&Offset
, StringRef Name
,
792 const MCExpr
*Expr
, SMLoc Loc
,
793 const MCSubtargetInfo
&STI
) {
794 std::optional
<MCFixupKind
> MaybeKind
=
795 Assembler
->getBackend().getFixupKind(Name
);
797 return std::make_pair(true, std::string("unknown relocation name"));
799 MCFixupKind Kind
= *MaybeKind
;
803 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
805 MCDataFragment
*DF
= getOrCreateDataFragment(&STI
);
806 flushPendingLabels(DF
, DF
->getContents().size());
809 if (!Offset
.evaluateAsRelocatable(OffsetVal
, nullptr, nullptr))
810 return std::make_pair(false,
811 std::string(".reloc offset is not relocatable"));
812 if (OffsetVal
.isAbsolute()) {
813 if (OffsetVal
.getConstant() < 0)
814 return std::make_pair(false, std::string(".reloc offset is negative"));
815 DF
->getFixups().push_back(
816 MCFixup::create(OffsetVal
.getConstant(), Expr
, Kind
, Loc
));
819 if (OffsetVal
.getSymB())
820 return std::make_pair(false,
821 std::string(".reloc offset is not representable"));
823 const MCSymbolRefExpr
&SRE
= cast
<MCSymbolRefExpr
>(*OffsetVal
.getSymA());
824 const MCSymbol
&Symbol
= SRE
.getSymbol();
825 if (Symbol
.isDefined()) {
826 uint32_t SymbolOffset
= 0;
827 std::optional
<std::pair
<bool, std::string
>> Error
=
828 getOffsetAndDataFragment(Symbol
, SymbolOffset
, DF
);
830 if (Error
!= std::nullopt
)
833 DF
->getFixups().push_back(
834 MCFixup::create(SymbolOffset
+ OffsetVal
.getConstant(),
839 PendingFixups
.emplace_back(
840 &SRE
.getSymbol(), DF
,
841 MCFixup::create(OffsetVal
.getConstant(), Expr
, Kind
, Loc
));
845 void MCObjectStreamer::emitFill(const MCExpr
&NumBytes
, uint64_t FillValue
,
847 MCDataFragment
*DF
= getOrCreateDataFragment();
848 flushPendingLabels(DF
, DF
->getContents().size());
850 assert(getCurrentSectionOnly() && "need a section");
851 insert(new MCFillFragment(FillValue
, 1, NumBytes
, Loc
));
854 void MCObjectStreamer::emitFill(const MCExpr
&NumValues
, int64_t Size
,
855 int64_t Expr
, SMLoc Loc
) {
856 int64_t IntNumValues
;
857 // Do additional checking now if we can resolve the value.
858 if (NumValues
.evaluateAsAbsolute(IntNumValues
, getAssemblerPtr())) {
859 if (IntNumValues
< 0) {
860 getContext().getSourceManager()->PrintMessage(
861 Loc
, SourceMgr::DK_Warning
,
862 "'.fill' directive with negative repeat count has no effect");
865 // Emit now if we can for better errors.
866 int64_t NonZeroSize
= Size
> 4 ? 4 : Size
;
867 Expr
&= ~0ULL >> (64 - NonZeroSize
* 8);
868 for (uint64_t i
= 0, e
= IntNumValues
; i
!= e
; ++i
) {
869 emitIntValue(Expr
, NonZeroSize
);
870 if (NonZeroSize
< Size
)
871 emitIntValue(0, Size
- NonZeroSize
);
876 // Otherwise emit as fragment.
877 MCDataFragment
*DF
= getOrCreateDataFragment();
878 flushPendingLabels(DF
, DF
->getContents().size());
880 assert(getCurrentSectionOnly() && "need a section");
881 insert(new MCFillFragment(Expr
, Size
, NumValues
, Loc
));
884 void MCObjectStreamer::emitNops(int64_t NumBytes
, int64_t ControlledNopLength
,
885 SMLoc Loc
, const MCSubtargetInfo
&STI
) {
886 // Emit an NOP fragment.
887 MCDataFragment
*DF
= getOrCreateDataFragment();
888 flushPendingLabels(DF
, DF
->getContents().size());
890 assert(getCurrentSectionOnly() && "need a section");
892 insert(new MCNopsFragment(NumBytes
, ControlledNopLength
, Loc
, STI
));
895 void MCObjectStreamer::emitFileDirective(StringRef Filename
) {
896 getAssembler().addFileName(Filename
);
899 void MCObjectStreamer::emitFileDirective(StringRef Filename
,
900 StringRef CompilerVerion
,
902 StringRef Description
) {
903 getAssembler().addFileName(Filename
);
904 // TODO: add additional info to integrated assembler.
907 void MCObjectStreamer::emitAddrsig() {
908 getAssembler().getWriter().emitAddrsigSection();
911 void MCObjectStreamer::emitAddrsigSym(const MCSymbol
*Sym
) {
912 getAssembler().getWriter().addAddrsigSymbol(Sym
);
915 void MCObjectStreamer::finishImpl() {
916 getContext().RemapDebugPaths();
918 // If we are generating dwarf for assembly source files dump out the sections.
919 if (getContext().getGenDwarfForAssembly())
920 MCGenDwarfInfo::Emit(this);
922 // Dump out the dwarf file & directory tables and line tables.
923 MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
925 // Emit pseudo probes for the current module.
926 MCPseudoProbeTable::emit(this);
928 // Update any remaining pending labels with empty data fragments.
929 flushPendingLabels();
931 resolvePendingFixups();
932 getAssembler().Finish();