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
) {
71 MCSection
*CurSection
= getCurrentSectionOnly();
73 assert(PendingLabels
.empty());
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();
83 // Associate a fragment with this label, either the supplied fragment
84 // or an empty data fragment.
86 CurSection
->flushPendingLabels(F
, FOffset
, CurSubsectionIdx
);
88 CurSection
->flushPendingLabels(nullptr, 0, CurSubsectionIdx
);
91 void MCObjectStreamer::flushPendingLabels() {
92 // Register labels that have not yet been assigned to a Section.
93 if (!PendingLabels
.empty()) {
94 MCSection
*CurSection
= getCurrentSectionOnly();
96 for (MCSymbol
* Sym
: PendingLabels
)
97 CurSection
->addPendingLabel(Sym
, CurSubsectionIdx
);
98 PendingLabels
.clear();
101 // Assign an empty data fragment to all remaining pending labels.
102 for (MCSection
* Section
: PendingLabelSections
)
103 Section
->flushPendingLabels();
106 // When fixup's offset is a forward declared label, e.g.:
108 // .reloc 1f, R_MIPS_JALR, foo
111 // postpone adding it to Fixups vector until the label is defined and its offset
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");
120 flushPendingLabels(PendingFixup
.DF
, PendingFixup
.DF
->getContents().size());
121 PendingFixup
.Fixup
.setOffset(PendingFixup
.Sym
->getOffset() +
122 PendingFixup
.Fixup
.getOffset());
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
)
134 .push_back(PendingFixup
.Fixup
);
136 case MCFragment::FT_Data
:
137 case MCFragment::FT_CVDefRange
:
138 cast
<MCEncodedFragmentWithFixups
<32, 4>>(SymFragment
)
140 .push_back(PendingFixup
.Fixup
);
143 PendingFixup
.DF
->getFixups().push_back(PendingFixup
.Fixup
);
147 PendingFixups
.clear();
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.
152 static std::optional
<uint64_t> absoluteSymbolDiff(const MCSymbol
*Hi
,
153 const MCSymbol
*Lo
) {
155 if (!Hi
->getFragment() || Hi
->getFragment() != Lo
->getFragment() ||
156 Hi
->isVariable() || Lo
->isVariable())
159 return Hi
->getOffset() - Lo
->getOffset();
162 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol
*Hi
,
165 if (!getAssembler().getContext().getTargetTriple().isRISCV())
166 if (std::optional
<uint64_t> Diff
= absoluteSymbolDiff(Hi
, Lo
))
167 return emitIntValue(*Diff
, Size
);
168 MCStreamer::emitAbsoluteSymbolDiff(Hi
, Lo
, Size
);
171 void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol
*Hi
,
172 const MCSymbol
*Lo
) {
173 if (!getAssembler().getContext().getTargetTriple().isRISCV())
174 if (std::optional
<uint64_t> Diff
= absoluteSymbolDiff(Hi
, Lo
)) {
175 emitULEB128IntValue(*Diff
);
178 MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi
, Lo
);
181 void MCObjectStreamer::reset() {
184 CurInsertionPoint
= MCSection::iterator();
186 EmitDebugFrame
= false;
187 PendingLabels
.clear();
188 PendingLabelSections
.clear();
192 void MCObjectStreamer::emitFrames(MCAsmBackend
*MAB
) {
193 if (!getNumFrameInfos())
197 MCDwarfFrameEmitter::Emit(*this, MAB
, true);
200 MCDwarfFrameEmitter::Emit(*this, MAB
, false);
203 MCFragment
*MCObjectStreamer::getCurrentFragment() const {
204 assert(getCurrentSectionOnly() && "No current section!");
206 if (CurInsertionPoint
!= getCurrentSectionOnly()->getFragmentList().begin())
207 return &*std::prev(CurInsertionPoint
);
212 static bool canReuseDataFragment(const MCDataFragment
&F
,
213 const MCAssembler
&Assembler
,
214 const MCSubtargetInfo
*STI
) {
215 if (!F
.hasInstructions())
217 // When bundling is enabled, we don't want to add data to a fragment that
218 // already has instructions (see MCELFStreamer::emitInstToData for details)
219 if (Assembler
.isBundlingEnabled())
220 return Assembler
.getRelaxAll();
221 // If the subtarget is changed mid fragment we start a new fragment to record
223 return !STI
|| F
.getSubtargetInfo() == STI
;
227 MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo
*STI
) {
228 MCDataFragment
*F
= dyn_cast_or_null
<MCDataFragment
>(getCurrentFragment());
229 if (!F
|| !canReuseDataFragment(*F
, *Assembler
, STI
)) {
230 F
= new MCDataFragment();
236 void MCObjectStreamer::visitUsedSymbol(const MCSymbol
&Sym
) {
237 Assembler
->registerSymbol(Sym
);
240 void MCObjectStreamer::emitCFISections(bool EH
, bool Debug
) {
241 MCStreamer::emitCFISections(EH
, Debug
);
243 EmitDebugFrame
= Debug
;
246 void MCObjectStreamer::emitValueImpl(const MCExpr
*Value
, unsigned Size
,
248 MCStreamer::emitValueImpl(Value
, Size
, Loc
);
249 MCDataFragment
*DF
= getOrCreateDataFragment();
250 flushPendingLabels(DF
, DF
->getContents().size());
252 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
254 // Avoid fixups when possible.
256 if (Value
->evaluateAsAbsolute(AbsValue
, getAssemblerPtr())) {
257 if (!isUIntN(8 * Size
, AbsValue
) && !isIntN(8 * Size
, AbsValue
)) {
258 getContext().reportError(
259 Loc
, "value evaluated as " + Twine(AbsValue
) + " is out of range.");
262 emitIntValue(AbsValue
, Size
);
265 DF
->getFixups().push_back(
266 MCFixup::create(DF
->getContents().size(), Value
,
267 MCFixup::getKindForSize(Size
, false), Loc
));
268 DF
->getContents().resize(DF
->getContents().size() + Size
, 0);
271 MCSymbol
*MCObjectStreamer::emitCFILabel() {
272 MCSymbol
*Label
= getContext().createTempSymbol("cfi");
277 void MCObjectStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) {
278 // We need to create a local symbol to avoid relocations.
279 Frame
.Begin
= getContext().createTempSymbol();
280 emitLabel(Frame
.Begin
);
283 void MCObjectStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) {
284 Frame
.End
= getContext().createTempSymbol();
285 emitLabel(Frame
.End
);
288 void MCObjectStreamer::emitLabel(MCSymbol
*Symbol
, SMLoc Loc
) {
289 MCStreamer::emitLabel(Symbol
, Loc
);
291 getAssembler().registerSymbol(*Symbol
);
293 // If there is a current fragment, mark the symbol as pointing into it.
294 // Otherwise queue the label and set its fragment pointer when we emit the
296 auto *F
= dyn_cast_or_null
<MCDataFragment
>(getCurrentFragment());
297 if (F
&& !(getAssembler().isBundlingEnabled() &&
298 getAssembler().getRelaxAll())) {
299 Symbol
->setFragment(F
);
300 Symbol
->setOffset(F
->getContents().size());
302 // Assign all pending labels to offset 0 within the dummy "pending"
303 // fragment. (They will all be reassigned to a real fragment in
304 // flushPendingLabels())
305 Symbol
->setOffset(0);
306 addPendingLabel(Symbol
);
309 emitPendingAssignments(Symbol
);
312 void MCObjectStreamer::emitPendingAssignments(MCSymbol
*Symbol
) {
313 auto Assignments
= pendingAssignments
.find(Symbol
);
314 if (Assignments
!= pendingAssignments
.end()) {
315 for (const PendingAssignment
&A
: Assignments
->second
)
316 emitAssignment(A
.Symbol
, A
.Value
);
318 pendingAssignments
.erase(Assignments
);
322 // Emit a label at a previously emitted fragment/offset position. This must be
323 // within the currently-active section.
324 void MCObjectStreamer::emitLabelAtPos(MCSymbol
*Symbol
, SMLoc Loc
,
325 MCFragment
*F
, uint64_t Offset
) {
326 assert(F
->getParent() == getCurrentSectionOnly());
328 MCStreamer::emitLabel(Symbol
, Loc
);
329 getAssembler().registerSymbol(*Symbol
);
330 auto *DF
= dyn_cast_or_null
<MCDataFragment
>(F
);
331 Symbol
->setOffset(Offset
);
333 Symbol
->setFragment(F
);
335 assert(isa
<MCDummyFragment
>(F
) &&
336 "F must either be an MCDataFragment or the pending MCDummyFragment");
338 addPendingLabel(Symbol
);
342 void MCObjectStreamer::emitULEB128Value(const MCExpr
*Value
) {
344 if (Value
->evaluateAsAbsolute(IntValue
, getAssemblerPtr())) {
345 emitULEB128IntValue(IntValue
);
348 insert(new MCLEBFragment(*Value
, false));
351 void MCObjectStreamer::emitSLEB128Value(const MCExpr
*Value
) {
353 if (Value
->evaluateAsAbsolute(IntValue
, getAssemblerPtr())) {
354 emitSLEB128IntValue(IntValue
);
357 insert(new MCLEBFragment(*Value
, true));
360 void MCObjectStreamer::emitWeakReference(MCSymbol
*Alias
,
361 const MCSymbol
*Symbol
) {
362 report_fatal_error("This file format doesn't support weak aliases.");
365 void MCObjectStreamer::changeSection(MCSection
*Section
,
366 const MCExpr
*Subsection
) {
367 changeSectionImpl(Section
, Subsection
);
370 bool MCObjectStreamer::changeSectionImpl(MCSection
*Section
,
371 const MCExpr
*Subsection
) {
372 assert(Section
&& "Cannot switch to a null section!");
373 getContext().clearDwarfLocSeen();
375 bool Created
= getAssembler().registerSection(*Section
);
377 int64_t IntSubsection
= 0;
379 !Subsection
->evaluateAsAbsolute(IntSubsection
, getAssemblerPtr()))
380 report_fatal_error("Cannot evaluate subsection number");
381 if (IntSubsection
< 0 || IntSubsection
> 8192)
382 report_fatal_error("Subsection number out of range");
383 CurSubsectionIdx
= unsigned(IntSubsection
);
385 Section
->getSubsectionInsertionPoint(CurSubsectionIdx
);
389 void MCObjectStreamer::emitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {
390 getAssembler().registerSymbol(*Symbol
);
391 MCStreamer::emitAssignment(Symbol
, Value
);
392 emitPendingAssignments(Symbol
);
395 void MCObjectStreamer::emitConditionalAssignment(MCSymbol
*Symbol
,
396 const MCExpr
*Value
) {
397 const MCSymbol
*Target
= &cast
<MCSymbolRefExpr
>(*Value
).getSymbol();
399 // If the symbol already exists, emit the assignment. Otherwise, emit it
400 // later only if the symbol is also emitted.
401 if (Target
->isRegistered())
402 emitAssignment(Symbol
, Value
);
404 pendingAssignments
[Target
].push_back({Symbol
, Value
});
407 bool MCObjectStreamer::mayHaveInstructions(MCSection
&Sec
) const {
408 return Sec
.hasInstructions();
411 void MCObjectStreamer::emitInstruction(const MCInst
&Inst
,
412 const MCSubtargetInfo
&STI
) {
413 const MCSection
&Sec
= *getCurrentSectionOnly();
414 if (Sec
.isVirtualSection()) {
415 getContext().reportError(Inst
.getLoc(), Twine(Sec
.getVirtualSectionKind()) +
416 " section '" + Sec
.getName() +
417 "' cannot have instructions");
420 getAssembler().getBackend().emitInstructionBegin(*this, Inst
, STI
);
421 emitInstructionImpl(Inst
, STI
);
422 getAssembler().getBackend().emitInstructionEnd(*this, Inst
);
425 void MCObjectStreamer::emitInstructionImpl(const MCInst
&Inst
,
426 const MCSubtargetInfo
&STI
) {
427 MCStreamer::emitInstruction(Inst
, STI
);
429 MCSection
*Sec
= getCurrentSectionOnly();
430 Sec
->setHasInstructions(true);
432 // Now that a machine instruction has been assembled into this section, make
433 // a line entry for any .loc directive that has been seen.
434 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
436 // If this instruction doesn't need relaxation, just emit it as data.
437 MCAssembler
&Assembler
= getAssembler();
438 MCAsmBackend
&Backend
= Assembler
.getBackend();
439 if (!(Backend
.mayNeedRelaxation(Inst
, STI
) ||
440 Backend
.allowEnhancedRelaxation())) {
441 emitInstToData(Inst
, STI
);
445 // Otherwise, relax and emit it as data if either:
446 // - The RelaxAll flag was passed
447 // - Bundling is enabled and this instruction is inside a bundle-locked
448 // group. We want to emit all such instructions into the same data
450 if (Assembler
.getRelaxAll() ||
451 (Assembler
.isBundlingEnabled() && Sec
->isBundleLocked())) {
452 MCInst Relaxed
= Inst
;
453 while (Backend
.mayNeedRelaxation(Relaxed
, STI
))
454 Backend
.relaxInstruction(Relaxed
, STI
);
455 emitInstToData(Relaxed
, STI
);
459 // Otherwise emit to a separate fragment.
460 emitInstToFragment(Inst
, STI
);
463 void MCObjectStreamer::emitInstToFragment(const MCInst
&Inst
,
464 const MCSubtargetInfo
&STI
) {
465 if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
466 llvm_unreachable("All instructions should have already been relaxed");
468 // Always create a new, separate fragment here, because its size can change
469 // during relaxation.
470 MCRelaxableFragment
*IF
= new MCRelaxableFragment(Inst
, STI
);
473 SmallString
<128> Code
;
474 getAssembler().getEmitter().encodeInstruction(Inst
, Code
, IF
->getFixups(),
476 IF
->getContents().append(Code
.begin(), Code
.end());
480 static const char *const BundlingNotImplementedMsg
=
481 "Aligned bundling is not implemented for this object format";
484 void MCObjectStreamer::emitBundleAlignMode(Align Alignment
) {
485 llvm_unreachable(BundlingNotImplementedMsg
);
488 void MCObjectStreamer::emitBundleLock(bool AlignToEnd
) {
489 llvm_unreachable(BundlingNotImplementedMsg
);
492 void MCObjectStreamer::emitBundleUnlock() {
493 llvm_unreachable(BundlingNotImplementedMsg
);
496 void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo
, unsigned Line
,
497 unsigned Column
, unsigned Flags
,
499 unsigned Discriminator
,
500 StringRef FileName
) {
501 // In case we see two .loc directives in a row, make sure the
502 // first one gets a line entry.
503 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
505 this->MCStreamer::emitDwarfLocDirective(FileNo
, Line
, Column
, Flags
, Isa
,
506 Discriminator
, FileName
);
509 static const MCExpr
*buildSymbolDiff(MCObjectStreamer
&OS
, const MCSymbol
*A
,
511 MCContext
&Context
= OS
.getContext();
512 MCSymbolRefExpr::VariantKind Variant
= MCSymbolRefExpr::VK_None
;
513 const MCExpr
*ARef
= MCSymbolRefExpr::create(A
, Variant
, Context
);
514 const MCExpr
*BRef
= MCSymbolRefExpr::create(B
, Variant
, Context
);
515 const MCExpr
*AddrDelta
=
516 MCBinaryExpr::create(MCBinaryExpr::Sub
, ARef
, BRef
, Context
);
520 static void emitDwarfSetLineAddr(MCObjectStreamer
&OS
,
521 MCDwarfLineTableParams Params
,
522 int64_t LineDelta
, const MCSymbol
*Label
,
524 // emit the sequence to set the address
525 OS
.emitIntValue(dwarf::DW_LNS_extended_op
, 1);
526 OS
.emitULEB128IntValue(PointerSize
+ 1);
527 OS
.emitIntValue(dwarf::DW_LNE_set_address
, 1);
528 OS
.emitSymbolValue(Label
, PointerSize
);
530 // emit the sequence for the LineDelta (from 1) and a zero address delta.
531 MCDwarfLineAddr::Emit(&OS
, Params
, LineDelta
, 0);
534 void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta
,
535 const MCSymbol
*LastLabel
,
536 const MCSymbol
*Label
,
537 unsigned PointerSize
) {
539 emitDwarfSetLineAddr(*this, Assembler
->getDWARFLinetableParams(), LineDelta
,
543 const MCExpr
*AddrDelta
= buildSymbolDiff(*this, Label
, LastLabel
);
544 insert(new MCDwarfLineAddrFragment(LineDelta
, *AddrDelta
));
547 void MCObjectStreamer::emitDwarfLineEndEntry(MCSection
*Section
,
548 MCSymbol
*LastLabel
) {
549 // Emit a DW_LNE_end_sequence for the end of the section.
550 // Use the section end label to compute the address delta and use INT64_MAX
551 // as the line delta which is the signal that this is actually a
552 // DW_LNE_end_sequence.
553 MCSymbol
*SectionEnd
= endSection(Section
);
555 // Switch back the dwarf line section, in case endSection had to switch the
557 MCContext
&Ctx
= getContext();
558 switchSection(Ctx
.getObjectFileInfo()->getDwarfLineSection());
560 const MCAsmInfo
*AsmInfo
= Ctx
.getAsmInfo();
561 emitDwarfAdvanceLineAddr(INT64_MAX
, LastLabel
, SectionEnd
,
562 AsmInfo
->getCodePointerSize());
565 void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol
*LastLabel
,
566 const MCSymbol
*Label
) {
567 const MCExpr
*AddrDelta
= buildSymbolDiff(*this, Label
, LastLabel
);
568 insert(new MCDwarfCallFrameFragment(*AddrDelta
));
571 void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId
, unsigned FileNo
,
572 unsigned Line
, unsigned Column
,
573 bool PrologueEnd
, bool IsStmt
,
574 StringRef FileName
, SMLoc Loc
) {
575 // Validate the directive.
576 if (!checkCVLocSection(FunctionId
, FileNo
, Loc
))
579 // Emit a label at the current position and record it in the CodeViewContext.
580 MCSymbol
*LineSym
= getContext().createTempSymbol();
582 getContext().getCVContext().recordCVLoc(getContext(), LineSym
, FunctionId
,
583 FileNo
, Line
, Column
, PrologueEnd
,
587 void MCObjectStreamer::emitCVLinetableDirective(unsigned FunctionId
,
588 const MCSymbol
*Begin
,
589 const MCSymbol
*End
) {
590 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId
, Begin
,
592 this->MCStreamer::emitCVLinetableDirective(FunctionId
, Begin
, End
);
595 void MCObjectStreamer::emitCVInlineLinetableDirective(
596 unsigned PrimaryFunctionId
, unsigned SourceFileId
, unsigned SourceLineNum
,
597 const MCSymbol
*FnStartSym
, const MCSymbol
*FnEndSym
) {
598 getContext().getCVContext().emitInlineLineTableForFunction(
599 *this, PrimaryFunctionId
, SourceFileId
, SourceLineNum
, FnStartSym
,
601 this->MCStreamer::emitCVInlineLinetableDirective(
602 PrimaryFunctionId
, SourceFileId
, SourceLineNum
, FnStartSym
, FnEndSym
);
605 void MCObjectStreamer::emitCVDefRangeDirective(
606 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
607 StringRef FixedSizePortion
) {
609 getContext().getCVContext().emitDefRange(*this, Ranges
, FixedSizePortion
);
610 // Attach labels that were pending before we created the defrange fragment to
611 // the beginning of the new fragment.
612 flushPendingLabels(Frag
, 0);
613 this->MCStreamer::emitCVDefRangeDirective(Ranges
, FixedSizePortion
);
616 void MCObjectStreamer::emitCVStringTableDirective() {
617 getContext().getCVContext().emitStringTable(*this);
619 void MCObjectStreamer::emitCVFileChecksumsDirective() {
620 getContext().getCVContext().emitFileChecksums(*this);
623 void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo
) {
624 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo
);
627 void MCObjectStreamer::emitBytes(StringRef Data
) {
628 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
629 MCDataFragment
*DF
= getOrCreateDataFragment();
630 flushPendingLabels(DF
, DF
->getContents().size());
631 DF
->getContents().append(Data
.begin(), Data
.end());
634 void MCObjectStreamer::emitValueToAlignment(Align Alignment
, int64_t Value
,
636 unsigned MaxBytesToEmit
) {
637 if (MaxBytesToEmit
== 0)
638 MaxBytesToEmit
= Alignment
.value();
639 insert(new MCAlignFragment(Alignment
, Value
, ValueSize
, MaxBytesToEmit
));
641 // Update the maximum alignment on the current section if necessary.
642 MCSection
*CurSec
= getCurrentSectionOnly();
643 CurSec
->ensureMinAlignment(Alignment
);
646 void MCObjectStreamer::emitCodeAlignment(Align Alignment
,
647 const MCSubtargetInfo
*STI
,
648 unsigned MaxBytesToEmit
) {
649 emitValueToAlignment(Alignment
, 0, 1, MaxBytesToEmit
);
650 cast
<MCAlignFragment
>(getCurrentFragment())->setEmitNops(true, STI
);
653 void MCObjectStreamer::emitValueToOffset(const MCExpr
*Offset
,
656 insert(new MCOrgFragment(*Offset
, Value
, Loc
));
659 // Associate DTPRel32 fixup with data and resize data area
660 void MCObjectStreamer::emitDTPRel32Value(const MCExpr
*Value
) {
661 MCDataFragment
*DF
= getOrCreateDataFragment();
662 flushPendingLabels(DF
, DF
->getContents().size());
664 DF
->getFixups().push_back(MCFixup::create(DF
->getContents().size(),
665 Value
, FK_DTPRel_4
));
666 DF
->getContents().resize(DF
->getContents().size() + 4, 0);
669 // Associate DTPRel64 fixup with data and resize data area
670 void MCObjectStreamer::emitDTPRel64Value(const MCExpr
*Value
) {
671 MCDataFragment
*DF
= getOrCreateDataFragment();
672 flushPendingLabels(DF
, DF
->getContents().size());
674 DF
->getFixups().push_back(MCFixup::create(DF
->getContents().size(),
675 Value
, FK_DTPRel_8
));
676 DF
->getContents().resize(DF
->getContents().size() + 8, 0);
679 // Associate TPRel32 fixup with data and resize data area
680 void MCObjectStreamer::emitTPRel32Value(const MCExpr
*Value
) {
681 MCDataFragment
*DF
= getOrCreateDataFragment();
682 flushPendingLabels(DF
, DF
->getContents().size());
684 DF
->getFixups().push_back(MCFixup::create(DF
->getContents().size(),
686 DF
->getContents().resize(DF
->getContents().size() + 4, 0);
689 // Associate TPRel64 fixup with data and resize data area
690 void MCObjectStreamer::emitTPRel64Value(const MCExpr
*Value
) {
691 MCDataFragment
*DF
= getOrCreateDataFragment();
692 flushPendingLabels(DF
, DF
->getContents().size());
694 DF
->getFixups().push_back(MCFixup::create(DF
->getContents().size(),
696 DF
->getContents().resize(DF
->getContents().size() + 8, 0);
699 // Associate GPRel32 fixup with data and resize data area
700 void MCObjectStreamer::emitGPRel32Value(const MCExpr
*Value
) {
701 MCDataFragment
*DF
= getOrCreateDataFragment();
702 flushPendingLabels(DF
, DF
->getContents().size());
704 DF
->getFixups().push_back(
705 MCFixup::create(DF
->getContents().size(), Value
, FK_GPRel_4
));
706 DF
->getContents().resize(DF
->getContents().size() + 4, 0);
709 // Associate GPRel64 fixup with data and resize data area
710 void MCObjectStreamer::emitGPRel64Value(const MCExpr
*Value
) {
711 MCDataFragment
*DF
= getOrCreateDataFragment();
712 flushPendingLabels(DF
, DF
->getContents().size());
714 DF
->getFixups().push_back(
715 MCFixup::create(DF
->getContents().size(), Value
, FK_GPRel_4
));
716 DF
->getContents().resize(DF
->getContents().size() + 8, 0);
719 static std::optional
<std::pair
<bool, std::string
>>
720 getOffsetAndDataFragment(const MCSymbol
&Symbol
, uint32_t &RelocOffset
,
721 MCDataFragment
*&DF
) {
722 if (Symbol
.isVariable()) {
723 const MCExpr
*SymbolExpr
= Symbol
.getVariableValue();
725 if(!SymbolExpr
->evaluateAsRelocatable(OffsetVal
, nullptr, nullptr))
726 return std::make_pair(false,
727 std::string("symbol in .reloc offset is not "
729 if (OffsetVal
.isAbsolute()) {
730 RelocOffset
= OffsetVal
.getConstant();
731 MCFragment
*Fragment
= Symbol
.getFragment();
732 // FIXME Support symbols with no DF. For example:
733 // .reloc .data, ENUM_VALUE, <some expr>
734 if (!Fragment
|| Fragment
->getKind() != MCFragment::FT_Data
)
735 return std::make_pair(false,
736 std::string("symbol in offset has no data "
738 DF
= cast
<MCDataFragment
>(Fragment
);
742 if (OffsetVal
.getSymB())
743 return std::make_pair(false,
744 std::string(".reloc symbol offset is not "
747 const MCSymbolRefExpr
&SRE
= cast
<MCSymbolRefExpr
>(*OffsetVal
.getSymA());
748 if (!SRE
.getSymbol().isDefined())
749 return std::make_pair(false,
750 std::string("symbol used in the .reloc offset is "
753 if (SRE
.getSymbol().isVariable())
754 return std::make_pair(false,
755 std::string("symbol used in the .reloc offset is "
758 MCFragment
*Fragment
= SRE
.getSymbol().getFragment();
759 // FIXME Support symbols with no DF. For example:
760 // .reloc .data, ENUM_VALUE, <some expr>
761 if (!Fragment
|| Fragment
->getKind() != MCFragment::FT_Data
)
762 return std::make_pair(false,
763 std::string("symbol in offset has no data "
765 RelocOffset
= SRE
.getSymbol().getOffset() + OffsetVal
.getConstant();
766 DF
= cast
<MCDataFragment
>(Fragment
);
768 RelocOffset
= Symbol
.getOffset();
769 MCFragment
*Fragment
= Symbol
.getFragment();
770 // FIXME Support symbols with no DF. For example:
771 // .reloc .data, ENUM_VALUE, <some expr>
772 if (!Fragment
|| Fragment
->getKind() != MCFragment::FT_Data
)
773 return std::make_pair(false,
774 std::string("symbol in offset has no data "
776 DF
= cast
<MCDataFragment
>(Fragment
);
781 std::optional
<std::pair
<bool, std::string
>>
782 MCObjectStreamer::emitRelocDirective(const MCExpr
&Offset
, StringRef Name
,
783 const MCExpr
*Expr
, SMLoc Loc
,
784 const MCSubtargetInfo
&STI
) {
785 std::optional
<MCFixupKind
> MaybeKind
=
786 Assembler
->getBackend().getFixupKind(Name
);
788 return std::make_pair(true, std::string("unknown relocation name"));
790 MCFixupKind Kind
= *MaybeKind
;
794 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
796 MCDataFragment
*DF
= getOrCreateDataFragment(&STI
);
797 flushPendingLabels(DF
, DF
->getContents().size());
800 if (!Offset
.evaluateAsRelocatable(OffsetVal
, nullptr, nullptr))
801 return std::make_pair(false,
802 std::string(".reloc offset is not relocatable"));
803 if (OffsetVal
.isAbsolute()) {
804 if (OffsetVal
.getConstant() < 0)
805 return std::make_pair(false, std::string(".reloc offset is negative"));
806 DF
->getFixups().push_back(
807 MCFixup::create(OffsetVal
.getConstant(), Expr
, Kind
, Loc
));
810 if (OffsetVal
.getSymB())
811 return std::make_pair(false,
812 std::string(".reloc offset is not representable"));
814 const MCSymbolRefExpr
&SRE
= cast
<MCSymbolRefExpr
>(*OffsetVal
.getSymA());
815 const MCSymbol
&Symbol
= SRE
.getSymbol();
816 if (Symbol
.isDefined()) {
817 uint32_t SymbolOffset
= 0;
818 std::optional
<std::pair
<bool, std::string
>> Error
=
819 getOffsetAndDataFragment(Symbol
, SymbolOffset
, DF
);
821 if (Error
!= std::nullopt
)
824 DF
->getFixups().push_back(
825 MCFixup::create(SymbolOffset
+ OffsetVal
.getConstant(),
830 PendingFixups
.emplace_back(
831 &SRE
.getSymbol(), DF
,
832 MCFixup::create(OffsetVal
.getConstant(), Expr
, Kind
, Loc
));
836 void MCObjectStreamer::emitFill(const MCExpr
&NumBytes
, uint64_t FillValue
,
838 MCDataFragment
*DF
= getOrCreateDataFragment();
839 flushPendingLabels(DF
, DF
->getContents().size());
841 assert(getCurrentSectionOnly() && "need a section");
842 insert(new MCFillFragment(FillValue
, 1, NumBytes
, Loc
));
845 void MCObjectStreamer::emitFill(const MCExpr
&NumValues
, int64_t Size
,
846 int64_t Expr
, SMLoc Loc
) {
847 int64_t IntNumValues
;
848 // Do additional checking now if we can resolve the value.
849 if (NumValues
.evaluateAsAbsolute(IntNumValues
, getAssemblerPtr())) {
850 if (IntNumValues
< 0) {
851 getContext().getSourceManager()->PrintMessage(
852 Loc
, SourceMgr::DK_Warning
,
853 "'.fill' directive with negative repeat count has no effect");
856 // Emit now if we can for better errors.
857 int64_t NonZeroSize
= Size
> 4 ? 4 : Size
;
858 Expr
&= ~0ULL >> (64 - NonZeroSize
* 8);
859 for (uint64_t i
= 0, e
= IntNumValues
; i
!= e
; ++i
) {
860 emitIntValue(Expr
, NonZeroSize
);
861 if (NonZeroSize
< Size
)
862 emitIntValue(0, Size
- NonZeroSize
);
867 // Otherwise emit as fragment.
868 MCDataFragment
*DF
= getOrCreateDataFragment();
869 flushPendingLabels(DF
, DF
->getContents().size());
871 assert(getCurrentSectionOnly() && "need a section");
872 insert(new MCFillFragment(Expr
, Size
, NumValues
, Loc
));
875 void MCObjectStreamer::emitNops(int64_t NumBytes
, int64_t ControlledNopLength
,
876 SMLoc Loc
, const MCSubtargetInfo
&STI
) {
877 // Emit an NOP fragment.
878 MCDataFragment
*DF
= getOrCreateDataFragment();
879 flushPendingLabels(DF
, DF
->getContents().size());
881 assert(getCurrentSectionOnly() && "need a section");
883 insert(new MCNopsFragment(NumBytes
, ControlledNopLength
, Loc
, STI
));
886 void MCObjectStreamer::emitFileDirective(StringRef Filename
) {
887 getAssembler().addFileName(Filename
);
890 void MCObjectStreamer::emitFileDirective(StringRef Filename
,
891 StringRef CompilerVerion
,
893 StringRef Description
) {
894 getAssembler().addFileName(Filename
);
895 // TODO: add additional info to integrated assembler.
898 void MCObjectStreamer::emitAddrsig() {
899 getAssembler().getWriter().emitAddrsigSection();
902 void MCObjectStreamer::emitAddrsigSym(const MCSymbol
*Sym
) {
903 getAssembler().getWriter().addAddrsigSymbol(Sym
);
906 void MCObjectStreamer::finishImpl() {
907 getContext().RemapDebugPaths();
909 // If we are generating dwarf for assembly source files dump out the sections.
910 if (getContext().getGenDwarfForAssembly())
911 MCGenDwarfInfo::Emit(this);
913 // Dump out the dwarf file & directory tables and line tables.
914 MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
916 // Emit pseudo probes for the current module.
917 MCPseudoProbeTable::emit(this);
919 // Update any remaining pending labels with empty data fragments.
920 flushPendingLabels();
922 resolvePendingFixups();
923 getAssembler().Finish();