1 //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
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/MCStreamer.h"
10 #include "llvm/ADT/Optional.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/BinaryFormat/COFF.h"
15 #include "llvm/MC/MCAsmBackend.h"
16 #include "llvm/MC/MCAsmInfo.h"
17 #include "llvm/MC/MCCodeView.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCDwarf.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstPrinter.h"
23 #include "llvm/MC/MCObjectFileInfo.h"
24 #include "llvm/MC/MCRegister.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCSection.h"
27 #include "llvm/MC/MCSectionCOFF.h"
28 #include "llvm/MC/MCSymbol.h"
29 #include "llvm/MC/MCWin64EH.h"
30 #include "llvm/MC/MCWinEH.h"
31 #include "llvm/Support/Casting.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/LEB128.h"
34 #include "llvm/Support/MathExtras.h"
35 #include "llvm/Support/raw_ostream.h"
43 MCTargetStreamer::MCTargetStreamer(MCStreamer
&S
) : Streamer(S
) {
44 S
.setTargetStreamer(this);
47 // Pin the vtables to this file.
48 MCTargetStreamer::~MCTargetStreamer() = default;
50 void MCTargetStreamer::emitLabel(MCSymbol
*Symbol
) {}
52 void MCTargetStreamer::finish() {}
54 void MCTargetStreamer::changeSection(const MCSection
*CurSection
,
56 const MCExpr
*Subsection
,
58 Section
->PrintSwitchToSection(
59 *Streamer
.getContext().getAsmInfo(),
60 Streamer
.getContext().getObjectFileInfo()->getTargetTriple(), OS
,
64 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive
) {
65 Streamer
.EmitRawText(Directive
);
68 void MCTargetStreamer::emitValue(const MCExpr
*Value
) {
70 raw_svector_ostream
OS(Str
);
72 Value
->print(OS
, Streamer
.getContext().getAsmInfo());
73 Streamer
.EmitRawText(OS
.str());
76 void MCTargetStreamer::emitRawBytes(StringRef Data
) {
77 const MCAsmInfo
*MAI
= Streamer
.getContext().getAsmInfo();
78 const char *Directive
= MAI
->getData8bitsDirective();
79 for (const unsigned char C
: Data
.bytes()) {
81 raw_svector_ostream
OS(Str
);
83 OS
<< Directive
<< (unsigned)C
;
84 Streamer
.EmitRawText(OS
.str());
88 void MCTargetStreamer::emitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {}
90 MCStreamer::MCStreamer(MCContext
&Ctx
)
91 : Context(Ctx
), CurrentWinFrameInfo(nullptr),
92 UseAssemblerInfoForParsing(false) {
93 SectionStack
.push_back(std::pair
<MCSectionSubPair
, MCSectionSubPair
>());
96 MCStreamer::~MCStreamer() {}
98 void MCStreamer::reset() {
99 DwarfFrameInfos
.clear();
100 CurrentWinFrameInfo
= nullptr;
101 WinFrameInfos
.clear();
102 SymbolOrdering
.clear();
103 SectionStack
.clear();
104 SectionStack
.push_back(std::pair
<MCSectionSubPair
, MCSectionSubPair
>());
107 raw_ostream
&MCStreamer::GetCommentOS() {
108 // By default, discard comments.
112 unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos
.size(); }
113 ArrayRef
<MCDwarfFrameInfo
> MCStreamer::getDwarfFrameInfos() const {
114 return DwarfFrameInfos
;
117 void MCStreamer::emitRawComment(const Twine
&T
, bool TabPrefix
) {}
119 void MCStreamer::addExplicitComment(const Twine
&T
) {}
120 void MCStreamer::emitExplicitComments() {}
122 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend
*MAB
) {
123 for (auto &FI
: DwarfFrameInfos
)
124 FI
.CompactUnwindEncoding
=
125 (MAB
? MAB
->generateCompactUnwindEncoding(FI
.Instructions
) : 0);
128 /// EmitIntValue - Special case of EmitValue that avoids the client having to
129 /// pass in a MCExpr for constant integers.
130 void MCStreamer::EmitIntValue(uint64_t Value
, unsigned Size
) {
131 assert(1 <= Size
&& Size
<= 8 && "Invalid size");
132 assert((isUIntN(8 * Size
, Value
) || isIntN(8 * Size
, Value
)) &&
135 const bool isLittleEndian
= Context
.getAsmInfo()->isLittleEndian();
136 for (unsigned i
= 0; i
!= Size
; ++i
) {
137 unsigned index
= isLittleEndian
? i
: (Size
- i
- 1);
138 buf
[i
] = uint8_t(Value
>> (index
* 8));
140 EmitBytes(StringRef(buf
, Size
));
143 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
144 /// client having to pass in a MCExpr for constant integers.
145 void MCStreamer::EmitULEB128IntValue(uint64_t Value
, unsigned PadTo
) {
146 SmallString
<128> Tmp
;
147 raw_svector_ostream
OSE(Tmp
);
148 encodeULEB128(Value
, OSE
, PadTo
);
149 EmitBytes(OSE
.str());
152 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
153 /// client having to pass in a MCExpr for constant integers.
154 void MCStreamer::EmitSLEB128IntValue(int64_t Value
) {
155 SmallString
<128> Tmp
;
156 raw_svector_ostream
OSE(Tmp
);
157 encodeSLEB128(Value
, OSE
);
158 EmitBytes(OSE
.str());
161 void MCStreamer::EmitValue(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
162 EmitValueImpl(Value
, Size
, Loc
);
165 void MCStreamer::EmitSymbolValue(const MCSymbol
*Sym
, unsigned Size
,
166 bool IsSectionRelative
) {
167 assert((!IsSectionRelative
|| Size
== 4) &&
168 "SectionRelative value requires 4-bytes");
170 if (!IsSectionRelative
)
171 EmitValueImpl(MCSymbolRefExpr::create(Sym
, getContext()), Size
);
173 EmitCOFFSecRel32(Sym
, /*Offset=*/0);
176 void MCStreamer::EmitDTPRel64Value(const MCExpr
*Value
) {
177 report_fatal_error("unsupported directive in streamer");
180 void MCStreamer::EmitDTPRel32Value(const MCExpr
*Value
) {
181 report_fatal_error("unsupported directive in streamer");
184 void MCStreamer::EmitTPRel64Value(const MCExpr
*Value
) {
185 report_fatal_error("unsupported directive in streamer");
188 void MCStreamer::EmitTPRel32Value(const MCExpr
*Value
) {
189 report_fatal_error("unsupported directive in streamer");
192 void MCStreamer::EmitGPRel64Value(const MCExpr
*Value
) {
193 report_fatal_error("unsupported directive in streamer");
196 void MCStreamer::EmitGPRel32Value(const MCExpr
*Value
) {
197 report_fatal_error("unsupported directive in streamer");
200 /// Emit NumBytes bytes worth of the value specified by FillValue.
201 /// This implements directives such as '.space'.
202 void MCStreamer::emitFill(uint64_t NumBytes
, uint8_t FillValue
) {
203 emitFill(*MCConstantExpr::create(NumBytes
, getContext()), FillValue
);
206 /// The implementation in this class just redirects to emitFill.
207 void MCStreamer::EmitZeros(uint64_t NumBytes
) {
208 emitFill(NumBytes
, 0);
212 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo
, StringRef Directory
,
214 Optional
<MD5::MD5Result
> Checksum
,
215 Optional
<StringRef
> Source
,
217 return getContext().getDwarfFile(Directory
, Filename
, FileNo
, Checksum
,
221 void MCStreamer::emitDwarfFile0Directive(StringRef Directory
,
223 Optional
<MD5::MD5Result
> Checksum
,
224 Optional
<StringRef
> Source
,
226 getContext().setMCLineTableRootFile(CUID
, Directory
, Filename
, Checksum
,
230 void MCStreamer::EmitCFIBKeyFrame() {
231 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
234 CurFrame
->IsBKeyFrame
= true;
237 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo
, unsigned Line
,
238 unsigned Column
, unsigned Flags
,
240 unsigned Discriminator
,
241 StringRef FileName
) {
242 getContext().setCurrentDwarfLoc(FileNo
, Line
, Column
, Flags
, Isa
,
246 MCSymbol
*MCStreamer::getDwarfLineTableSymbol(unsigned CUID
) {
247 MCDwarfLineTable
&Table
= getContext().getMCDwarfLineTable(CUID
);
248 if (!Table
.getLabel()) {
249 StringRef Prefix
= Context
.getAsmInfo()->getPrivateGlobalPrefix();
251 Context
.getOrCreateSymbol(Prefix
+ "line_table_start" + Twine(CUID
)));
253 return Table
.getLabel();
256 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
257 return !DwarfFrameInfos
.empty() && !DwarfFrameInfos
.back().End
;
260 MCDwarfFrameInfo
*MCStreamer::getCurrentDwarfFrameInfo() {
261 if (!hasUnfinishedDwarfFrameInfo()) {
262 getContext().reportError(SMLoc(), "this directive must appear between "
263 ".cfi_startproc and .cfi_endproc "
267 return &DwarfFrameInfos
.back();
270 bool MCStreamer::EmitCVFileDirective(unsigned FileNo
, StringRef Filename
,
271 ArrayRef
<uint8_t> Checksum
,
272 unsigned ChecksumKind
) {
273 return getContext().getCVContext().addFile(*this, FileNo
, Filename
, Checksum
,
277 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId
) {
278 return getContext().getCVContext().recordFunctionId(FunctionId
);
281 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId
,
282 unsigned IAFunc
, unsigned IAFile
,
283 unsigned IALine
, unsigned IACol
,
285 if (getContext().getCVContext().getCVFunctionInfo(IAFunc
) == nullptr) {
286 getContext().reportError(Loc
, "parent function id not introduced by "
287 ".cv_func_id or .cv_inline_site_id");
291 return getContext().getCVContext().recordInlinedCallSiteId(
292 FunctionId
, IAFunc
, IAFile
, IALine
, IACol
);
295 void MCStreamer::EmitCVLocDirective(unsigned FunctionId
, unsigned FileNo
,
296 unsigned Line
, unsigned Column
,
297 bool PrologueEnd
, bool IsStmt
,
298 StringRef FileName
, SMLoc Loc
) {}
300 bool MCStreamer::checkCVLocSection(unsigned FuncId
, unsigned FileNo
,
302 CodeViewContext
&CVC
= getContext().getCVContext();
303 MCCVFunctionInfo
*FI
= CVC
.getCVFunctionInfo(FuncId
);
305 getContext().reportError(
306 Loc
, "function id not introduced by .cv_func_id or .cv_inline_site_id");
311 if (FI
->Section
== nullptr)
312 FI
->Section
= getCurrentSectionOnly();
313 else if (FI
->Section
!= getCurrentSectionOnly()) {
314 getContext().reportError(
316 "all .cv_loc directives for a function must be in the same section");
322 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId
,
323 const MCSymbol
*Begin
,
324 const MCSymbol
*End
) {}
326 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId
,
327 unsigned SourceFileId
,
328 unsigned SourceLineNum
,
329 const MCSymbol
*FnStartSym
,
330 const MCSymbol
*FnEndSym
) {}
332 /// Only call this on endian-specific types like ulittle16_t and little32_t, or
333 /// structs composed of them.
334 template <typename T
>
335 static void copyBytesForDefRange(SmallString
<20> &BytePrefix
,
336 codeview::SymbolKind SymKind
,
337 const T
&DefRangeHeader
) {
338 BytePrefix
.resize(2 + sizeof(T
));
339 codeview::ulittle16_t SymKindLE
= codeview::ulittle16_t(SymKind
);
340 memcpy(&BytePrefix
[0], &SymKindLE
, 2);
341 memcpy(&BytePrefix
[2], &DefRangeHeader
, sizeof(T
));
344 void MCStreamer::EmitCVDefRangeDirective(
345 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
346 StringRef FixedSizePortion
) {}
348 void MCStreamer::EmitCVDefRangeDirective(
349 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
350 codeview::DefRangeRegisterRelSym::Header DRHdr
) {
351 SmallString
<20> BytePrefix
;
352 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_REGISTER_REL
, DRHdr
);
353 EmitCVDefRangeDirective(Ranges
, BytePrefix
);
356 void MCStreamer::EmitCVDefRangeDirective(
357 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
358 codeview::DefRangeSubfieldRegisterSym::Header DRHdr
) {
359 SmallString
<20> BytePrefix
;
360 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_SUBFIELD_REGISTER
,
362 EmitCVDefRangeDirective(Ranges
, BytePrefix
);
365 void MCStreamer::EmitCVDefRangeDirective(
366 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
367 codeview::DefRangeRegisterSym::Header DRHdr
) {
368 SmallString
<20> BytePrefix
;
369 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_REGISTER
, DRHdr
);
370 EmitCVDefRangeDirective(Ranges
, BytePrefix
);
373 void MCStreamer::EmitCVDefRangeDirective(
374 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
375 codeview::DefRangeFramePointerRelSym::Header DRHdr
) {
376 SmallString
<20> BytePrefix
;
377 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_FRAMEPOINTER_REL
,
379 EmitCVDefRangeDirective(Ranges
, BytePrefix
);
382 void MCStreamer::EmitEHSymAttributes(const MCSymbol
*Symbol
,
383 MCSymbol
*EHSymbol
) {
386 void MCStreamer::InitSections(bool NoExecStack
) {
387 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
390 void MCStreamer::AssignFragment(MCSymbol
*Symbol
, MCFragment
*Fragment
) {
392 Symbol
->setFragment(Fragment
);
394 // As we emit symbols into a section, track the order so that they can
395 // be sorted upon later. Zero is reserved to mean 'unemitted'.
396 SymbolOrdering
[Symbol
] = 1 + SymbolOrdering
.size();
399 void MCStreamer::EmitLabel(MCSymbol
*Symbol
, SMLoc Loc
) {
400 Symbol
->redefineIfPossible();
402 if (!Symbol
->isUndefined() || Symbol
->isVariable())
403 return getContext().reportError(Loc
, "invalid symbol redefinition");
405 assert(!Symbol
->isVariable() && "Cannot emit a variable symbol!");
406 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
407 assert(!Symbol
->getFragment() && "Unexpected fragment on symbol data!");
408 assert(Symbol
->isUndefined() && "Cannot define a symbol twice!");
410 Symbol
->setFragment(&getCurrentSectionOnly()->getDummyFragment());
412 MCTargetStreamer
*TS
= getTargetStreamer();
414 TS
->emitLabel(Symbol
);
417 void MCStreamer::EmitCFISections(bool EH
, bool Debug
) {
421 void MCStreamer::EmitCFIStartProc(bool IsSimple
, SMLoc Loc
) {
422 if (hasUnfinishedDwarfFrameInfo())
423 return getContext().reportError(
424 Loc
, "starting new .cfi frame before finishing the previous one");
426 MCDwarfFrameInfo Frame
;
427 Frame
.IsSimple
= IsSimple
;
428 EmitCFIStartProcImpl(Frame
);
430 const MCAsmInfo
* MAI
= Context
.getAsmInfo();
432 for (const MCCFIInstruction
& Inst
: MAI
->getInitialFrameState()) {
433 if (Inst
.getOperation() == MCCFIInstruction::OpDefCfa
||
434 Inst
.getOperation() == MCCFIInstruction::OpDefCfaRegister
) {
435 Frame
.CurrentCfaRegister
= Inst
.getRegister();
440 DwarfFrameInfos
.push_back(Frame
);
443 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) {
446 void MCStreamer::EmitCFIEndProc() {
447 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
450 EmitCFIEndProcImpl(*CurFrame
);
453 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) {
454 // Put a dummy non-null value in Frame.End to mark that this frame has been
456 Frame
.End
= (MCSymbol
*)1;
459 MCSymbol
*MCStreamer::EmitCFILabel() {
460 // Return a dummy non-null value so that label fields appear filled in when
461 // generating textual assembly.
462 return (MCSymbol
*)1;
465 void MCStreamer::EmitCFIDefCfa(int64_t Register
, int64_t Offset
) {
466 MCSymbol
*Label
= EmitCFILabel();
467 MCCFIInstruction Instruction
=
468 MCCFIInstruction::createDefCfa(Label
, Register
, Offset
);
469 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
472 CurFrame
->Instructions
.push_back(Instruction
);
473 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
476 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset
) {
477 MCSymbol
*Label
= EmitCFILabel();
478 MCCFIInstruction Instruction
=
479 MCCFIInstruction::createDefCfaOffset(Label
, Offset
);
480 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
483 CurFrame
->Instructions
.push_back(Instruction
);
486 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment
) {
487 MCSymbol
*Label
= EmitCFILabel();
488 MCCFIInstruction Instruction
=
489 MCCFIInstruction::createAdjustCfaOffset(Label
, Adjustment
);
490 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
493 CurFrame
->Instructions
.push_back(Instruction
);
496 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register
) {
497 MCSymbol
*Label
= EmitCFILabel();
498 MCCFIInstruction Instruction
=
499 MCCFIInstruction::createDefCfaRegister(Label
, Register
);
500 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
503 CurFrame
->Instructions
.push_back(Instruction
);
504 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
507 void MCStreamer::EmitCFIOffset(int64_t Register
, int64_t Offset
) {
508 MCSymbol
*Label
= EmitCFILabel();
509 MCCFIInstruction Instruction
=
510 MCCFIInstruction::createOffset(Label
, Register
, Offset
);
511 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
514 CurFrame
->Instructions
.push_back(Instruction
);
517 void MCStreamer::EmitCFIRelOffset(int64_t Register
, int64_t Offset
) {
518 MCSymbol
*Label
= EmitCFILabel();
519 MCCFIInstruction Instruction
=
520 MCCFIInstruction::createRelOffset(Label
, Register
, Offset
);
521 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
524 CurFrame
->Instructions
.push_back(Instruction
);
527 void MCStreamer::EmitCFIPersonality(const MCSymbol
*Sym
,
529 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
532 CurFrame
->Personality
= Sym
;
533 CurFrame
->PersonalityEncoding
= Encoding
;
536 void MCStreamer::EmitCFILsda(const MCSymbol
*Sym
, unsigned Encoding
) {
537 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
540 CurFrame
->Lsda
= Sym
;
541 CurFrame
->LsdaEncoding
= Encoding
;
544 void MCStreamer::EmitCFIRememberState() {
545 MCSymbol
*Label
= EmitCFILabel();
546 MCCFIInstruction Instruction
= MCCFIInstruction::createRememberState(Label
);
547 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
550 CurFrame
->Instructions
.push_back(Instruction
);
553 void MCStreamer::EmitCFIRestoreState() {
554 // FIXME: Error if there is no matching cfi_remember_state.
555 MCSymbol
*Label
= EmitCFILabel();
556 MCCFIInstruction Instruction
= MCCFIInstruction::createRestoreState(Label
);
557 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
560 CurFrame
->Instructions
.push_back(Instruction
);
563 void MCStreamer::EmitCFISameValue(int64_t Register
) {
564 MCSymbol
*Label
= EmitCFILabel();
565 MCCFIInstruction Instruction
=
566 MCCFIInstruction::createSameValue(Label
, Register
);
567 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
570 CurFrame
->Instructions
.push_back(Instruction
);
573 void MCStreamer::EmitCFIRestore(int64_t Register
) {
574 MCSymbol
*Label
= EmitCFILabel();
575 MCCFIInstruction Instruction
=
576 MCCFIInstruction::createRestore(Label
, Register
);
577 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
580 CurFrame
->Instructions
.push_back(Instruction
);
583 void MCStreamer::EmitCFIEscape(StringRef Values
) {
584 MCSymbol
*Label
= EmitCFILabel();
585 MCCFIInstruction Instruction
= MCCFIInstruction::createEscape(Label
, Values
);
586 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
589 CurFrame
->Instructions
.push_back(Instruction
);
592 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size
) {
593 MCSymbol
*Label
= EmitCFILabel();
594 MCCFIInstruction Instruction
=
595 MCCFIInstruction::createGnuArgsSize(Label
, Size
);
596 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
599 CurFrame
->Instructions
.push_back(Instruction
);
602 void MCStreamer::EmitCFISignalFrame() {
603 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
606 CurFrame
->IsSignalFrame
= true;
609 void MCStreamer::EmitCFIUndefined(int64_t Register
) {
610 MCSymbol
*Label
= EmitCFILabel();
611 MCCFIInstruction Instruction
=
612 MCCFIInstruction::createUndefined(Label
, Register
);
613 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
616 CurFrame
->Instructions
.push_back(Instruction
);
619 void MCStreamer::EmitCFIRegister(int64_t Register1
, int64_t Register2
) {
620 MCSymbol
*Label
= EmitCFILabel();
621 MCCFIInstruction Instruction
=
622 MCCFIInstruction::createRegister(Label
, Register1
, Register2
);
623 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
626 CurFrame
->Instructions
.push_back(Instruction
);
629 void MCStreamer::EmitCFIWindowSave() {
630 MCSymbol
*Label
= EmitCFILabel();
631 MCCFIInstruction Instruction
=
632 MCCFIInstruction::createWindowSave(Label
);
633 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
636 CurFrame
->Instructions
.push_back(Instruction
);
639 void MCStreamer::EmitCFINegateRAState() {
640 MCSymbol
*Label
= EmitCFILabel();
641 MCCFIInstruction Instruction
= MCCFIInstruction::createNegateRAState(Label
);
642 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
645 CurFrame
->Instructions
.push_back(Instruction
);
648 void MCStreamer::EmitCFIReturnColumn(int64_t Register
) {
649 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
652 CurFrame
->RAReg
= Register
;
655 WinEH::FrameInfo
*MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc
) {
656 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
657 if (!MAI
->usesWindowsCFI()) {
658 getContext().reportError(
659 Loc
, ".seh_* directives are not supported on this target");
662 if (!CurrentWinFrameInfo
|| CurrentWinFrameInfo
->End
) {
663 getContext().reportError(
664 Loc
, ".seh_ directive must appear within an active frame");
667 return CurrentWinFrameInfo
;
670 void MCStreamer::EmitWinCFIStartProc(const MCSymbol
*Symbol
, SMLoc Loc
) {
671 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
672 if (!MAI
->usesWindowsCFI())
673 return getContext().reportError(
674 Loc
, ".seh_* directives are not supported on this target");
675 if (CurrentWinFrameInfo
&& !CurrentWinFrameInfo
->End
)
676 getContext().reportError(
677 Loc
, "Starting a function before ending the previous one!");
679 MCSymbol
*StartProc
= EmitCFILabel();
681 WinFrameInfos
.emplace_back(
682 std::make_unique
<WinEH::FrameInfo
>(Symbol
, StartProc
));
683 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
684 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
687 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc
) {
688 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
691 if (CurFrame
->ChainedParent
)
692 getContext().reportError(Loc
, "Not all chained regions terminated!");
694 MCSymbol
*Label
= EmitCFILabel();
695 CurFrame
->End
= Label
;
698 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc
) {
699 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
702 if (CurFrame
->ChainedParent
)
703 getContext().reportError(Loc
, "Not all chained regions terminated!");
705 MCSymbol
*Label
= EmitCFILabel();
706 CurFrame
->FuncletOrFuncEnd
= Label
;
709 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc
) {
710 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
714 MCSymbol
*StartProc
= EmitCFILabel();
716 WinFrameInfos
.emplace_back(std::make_unique
<WinEH::FrameInfo
>(
717 CurFrame
->Function
, StartProc
, CurFrame
));
718 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
719 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
722 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc
) {
723 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
726 if (!CurFrame
->ChainedParent
)
727 return getContext().reportError(
728 Loc
, "End of a chained region outside a chained region!");
730 MCSymbol
*Label
= EmitCFILabel();
732 CurFrame
->End
= Label
;
733 CurrentWinFrameInfo
= const_cast<WinEH::FrameInfo
*>(CurFrame
->ChainedParent
);
736 void MCStreamer::EmitWinEHHandler(const MCSymbol
*Sym
, bool Unwind
, bool Except
,
738 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
741 if (CurFrame
->ChainedParent
)
742 return getContext().reportError(
743 Loc
, "Chained unwind areas can't have handlers!");
744 CurFrame
->ExceptionHandler
= Sym
;
745 if (!Except
&& !Unwind
)
746 getContext().reportError(Loc
, "Don't know what kind of handler this is!");
748 CurFrame
->HandlesUnwind
= true;
750 CurFrame
->HandlesExceptions
= true;
753 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc
) {
754 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
757 if (CurFrame
->ChainedParent
)
758 getContext().reportError(Loc
, "Chained unwind areas can't have handlers!");
761 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr
*From
,
762 const MCSymbolRefExpr
*To
, uint64_t Count
) {
765 static MCSection
*getWinCFISection(MCContext
&Context
, unsigned *NextWinCFIID
,
766 MCSection
*MainCFISec
,
767 const MCSection
*TextSec
) {
768 // If this is the main .text section, use the main unwind info section.
769 if (TextSec
== Context
.getObjectFileInfo()->getTextSection())
772 const auto *TextSecCOFF
= cast
<MCSectionCOFF
>(TextSec
);
773 auto *MainCFISecCOFF
= cast
<MCSectionCOFF
>(MainCFISec
);
774 unsigned UniqueID
= TextSecCOFF
->getOrAssignWinCFISectionID(NextWinCFIID
);
776 // If this section is COMDAT, this unwind section should be COMDAT associative
778 const MCSymbol
*KeySym
= nullptr;
779 if (TextSecCOFF
->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT
) {
780 KeySym
= TextSecCOFF
->getCOMDATSymbol();
782 // In a GNU environment, we can't use associative comdats. Instead, do what
783 // GCC does, which is to make plain comdat selectany section named like
784 // ".[px]data$_Z3foov".
785 if (!Context
.getAsmInfo()->hasCOFFAssociativeComdats()) {
786 std::string SectionName
=
787 (MainCFISecCOFF
->getSectionName() + "$" +
788 TextSecCOFF
->getSectionName().split('$').second
)
790 return Context
.getCOFFSection(
792 MainCFISecCOFF
->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT
,
793 MainCFISecCOFF
->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY
);
797 return Context
.getAssociativeCOFFSection(MainCFISecCOFF
, KeySym
, UniqueID
);
800 MCSection
*MCStreamer::getAssociatedPDataSection(const MCSection
*TextSec
) {
801 return getWinCFISection(getContext(), &NextWinCFIID
,
802 getContext().getObjectFileInfo()->getPDataSection(),
806 MCSection
*MCStreamer::getAssociatedXDataSection(const MCSection
*TextSec
) {
807 return getWinCFISection(getContext(), &NextWinCFIID
,
808 getContext().getObjectFileInfo()->getXDataSection(),
812 void MCStreamer::EmitSyntaxDirective() {}
814 static unsigned encodeSEHRegNum(MCContext
&Ctx
, MCRegister Reg
) {
815 return Ctx
.getRegisterInfo()->getSEHRegNum(Reg
);
818 void MCStreamer::EmitWinCFIPushReg(MCRegister Register
, SMLoc Loc
) {
819 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
823 MCSymbol
*Label
= EmitCFILabel();
825 WinEH::Instruction Inst
= Win64EH::Instruction::PushNonVol(
826 Label
, encodeSEHRegNum(Context
, Register
));
827 CurFrame
->Instructions
.push_back(Inst
);
830 void MCStreamer::EmitWinCFISetFrame(MCRegister Register
, unsigned Offset
,
832 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
835 if (CurFrame
->LastFrameInst
>= 0)
836 return getContext().reportError(
837 Loc
, "frame register and offset can be set at most once");
839 return getContext().reportError(Loc
, "offset is not a multiple of 16");
841 return getContext().reportError(
842 Loc
, "frame offset must be less than or equal to 240");
844 MCSymbol
*Label
= EmitCFILabel();
846 WinEH::Instruction Inst
= Win64EH::Instruction::SetFPReg(
847 Label
, encodeSEHRegNum(getContext(), Register
), Offset
);
848 CurFrame
->LastFrameInst
= CurFrame
->Instructions
.size();
849 CurFrame
->Instructions
.push_back(Inst
);
852 void MCStreamer::EmitWinCFIAllocStack(unsigned Size
, SMLoc Loc
) {
853 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
857 return getContext().reportError(Loc
,
858 "stack allocation size must be non-zero");
860 return getContext().reportError(
861 Loc
, "stack allocation size is not a multiple of 8");
863 MCSymbol
*Label
= EmitCFILabel();
865 WinEH::Instruction Inst
= Win64EH::Instruction::Alloc(Label
, Size
);
866 CurFrame
->Instructions
.push_back(Inst
);
869 void MCStreamer::EmitWinCFISaveReg(MCRegister Register
, unsigned Offset
,
871 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
876 return getContext().reportError(
877 Loc
, "register save offset is not 8 byte aligned");
879 MCSymbol
*Label
= EmitCFILabel();
881 WinEH::Instruction Inst
= Win64EH::Instruction::SaveNonVol(
882 Label
, encodeSEHRegNum(Context
, Register
), Offset
);
883 CurFrame
->Instructions
.push_back(Inst
);
886 void MCStreamer::EmitWinCFISaveXMM(MCRegister Register
, unsigned Offset
,
888 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
892 return getContext().reportError(Loc
, "offset is not a multiple of 16");
894 MCSymbol
*Label
= EmitCFILabel();
896 WinEH::Instruction Inst
= Win64EH::Instruction::SaveXMM(
897 Label
, encodeSEHRegNum(Context
, Register
), Offset
);
898 CurFrame
->Instructions
.push_back(Inst
);
901 void MCStreamer::EmitWinCFIPushFrame(bool Code
, SMLoc Loc
) {
902 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
905 if (!CurFrame
->Instructions
.empty())
906 return getContext().reportError(
907 Loc
, "If present, PushMachFrame must be the first UOP");
909 MCSymbol
*Label
= EmitCFILabel();
911 WinEH::Instruction Inst
= Win64EH::Instruction::PushMachFrame(Label
, Code
);
912 CurFrame
->Instructions
.push_back(Inst
);
915 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc
) {
916 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
920 MCSymbol
*Label
= EmitCFILabel();
922 CurFrame
->PrologEnd
= Label
;
925 void MCStreamer::EmitCOFFSafeSEH(MCSymbol
const *Symbol
) {}
927 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol
const *Symbol
) {}
929 void MCStreamer::EmitCOFFSectionIndex(MCSymbol
const *Symbol
) {}
931 void MCStreamer::EmitCOFFSecRel32(MCSymbol
const *Symbol
, uint64_t Offset
) {}
933 void MCStreamer::EmitCOFFImgRel32(MCSymbol
const *Symbol
, int64_t Offset
) {}
935 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
936 /// the specified string in the output .s file. This capability is
937 /// indicated by the hasRawTextSupport() predicate.
938 void MCStreamer::EmitRawTextImpl(StringRef String
) {
939 // This is not llvm_unreachable for the sake of out of tree backend
940 // developers who may not have assembly streamers and should serve as a
941 // reminder to not accidentally call EmitRawText in the absence of such.
942 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
943 "it (target backend is likely missing an AsmStreamer "
947 void MCStreamer::EmitRawText(const Twine
&T
) {
948 SmallString
<128> Str
;
949 EmitRawTextImpl(T
.toStringRef(Str
));
952 void MCStreamer::EmitWindowsUnwindTables() {
955 void MCStreamer::Finish() {
956 if ((!DwarfFrameInfos
.empty() && !DwarfFrameInfos
.back().End
) ||
957 (!WinFrameInfos
.empty() && !WinFrameInfos
.back()->End
)) {
958 getContext().reportError(SMLoc(), "Unfinished frame!");
962 MCTargetStreamer
*TS
= getTargetStreamer();
969 void MCStreamer::EmitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {
970 visitUsedExpr(*Value
);
971 Symbol
->setVariableValue(Value
);
973 MCTargetStreamer
*TS
= getTargetStreamer();
975 TS
->emitAssignment(Symbol
, Value
);
978 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter
&InstPrinter
,
979 raw_ostream
&OS
, const MCInst
&Inst
,
980 const MCSubtargetInfo
&STI
) {
981 InstPrinter
.printInst(&Inst
, OS
, "", STI
);
984 void MCStreamer::visitUsedSymbol(const MCSymbol
&Sym
) {
987 void MCStreamer::visitUsedExpr(const MCExpr
&Expr
) {
988 switch (Expr
.getKind()) {
990 cast
<MCTargetExpr
>(Expr
).visitUsedExpr(*this);
993 case MCExpr::Constant
:
996 case MCExpr::Binary
: {
997 const MCBinaryExpr
&BE
= cast
<MCBinaryExpr
>(Expr
);
998 visitUsedExpr(*BE
.getLHS());
999 visitUsedExpr(*BE
.getRHS());
1003 case MCExpr::SymbolRef
:
1004 visitUsedSymbol(cast
<MCSymbolRefExpr
>(Expr
).getSymbol());
1008 visitUsedExpr(*cast
<MCUnaryExpr
>(Expr
).getSubExpr());
1013 void MCStreamer::EmitInstruction(const MCInst
&Inst
, const MCSubtargetInfo
&) {
1015 for (unsigned i
= Inst
.getNumOperands(); i
--;)
1016 if (Inst
.getOperand(i
).isExpr())
1017 visitUsedExpr(*Inst
.getOperand(i
).getExpr());
1020 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol
*Hi
, const MCSymbol
*Lo
,
1022 // Get the Hi-Lo expression.
1023 const MCExpr
*Diff
=
1024 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
1025 MCSymbolRefExpr::create(Lo
, Context
), Context
);
1027 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
1028 if (!MAI
->doesSetDirectiveSuppressReloc()) {
1029 EmitValue(Diff
, Size
);
1033 // Otherwise, emit with .set (aka assignment).
1034 MCSymbol
*SetLabel
= Context
.createTempSymbol("set", true);
1035 EmitAssignment(SetLabel
, Diff
);
1036 EmitSymbolValue(SetLabel
, Size
);
1039 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol
*Hi
,
1040 const MCSymbol
*Lo
) {
1041 // Get the Hi-Lo expression.
1042 const MCExpr
*Diff
=
1043 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
1044 MCSymbolRefExpr::create(Lo
, Context
), Context
);
1046 EmitULEB128Value(Diff
);
1049 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag
) {}
1050 void MCStreamer::EmitThumbFunc(MCSymbol
*Func
) {}
1051 void MCStreamer::EmitSymbolDesc(MCSymbol
*Symbol
, unsigned DescValue
) {}
1052 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol
*Symbol
) {
1053 llvm_unreachable("this directive only supported on COFF targets");
1055 void MCStreamer::EndCOFFSymbolDef() {
1056 llvm_unreachable("this directive only supported on COFF targets");
1058 void MCStreamer::EmitFileDirective(StringRef Filename
) {}
1059 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass
) {
1060 llvm_unreachable("this directive only supported on COFF targets");
1062 void MCStreamer::EmitCOFFSymbolType(int Type
) {
1063 llvm_unreachable("this directive only supported on COFF targets");
1065 void MCStreamer::EmitXCOFFLocalCommonSymbol(MCSymbol
*Symbol
, uint64_t Size
,
1066 unsigned ByteAlign
) {
1067 llvm_unreachable("this directive only supported on XCOFF targets");
1069 void MCStreamer::emitELFSize(MCSymbol
*Symbol
, const MCExpr
*Value
) {}
1070 void MCStreamer::emitELFSymverDirective(StringRef AliasName
,
1071 const MCSymbol
*Aliasee
) {}
1072 void MCStreamer::EmitLocalCommonSymbol(MCSymbol
*Symbol
, uint64_t Size
,
1073 unsigned ByteAlignment
) {}
1074 void MCStreamer::EmitTBSSSymbol(MCSection
*Section
, MCSymbol
*Symbol
,
1075 uint64_t Size
, unsigned ByteAlignment
) {}
1076 void MCStreamer::ChangeSection(MCSection
*, const MCExpr
*) {}
1077 void MCStreamer::EmitWeakReference(MCSymbol
*Alias
, const MCSymbol
*Symbol
) {}
1078 void MCStreamer::EmitBytes(StringRef Data
) {}
1079 void MCStreamer::EmitBinaryData(StringRef Data
) { EmitBytes(Data
); }
1080 void MCStreamer::EmitValueImpl(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
1081 visitUsedExpr(*Value
);
1083 void MCStreamer::EmitULEB128Value(const MCExpr
*Value
) {}
1084 void MCStreamer::EmitSLEB128Value(const MCExpr
*Value
) {}
1085 void MCStreamer::emitFill(const MCExpr
&NumBytes
, uint64_t Value
, SMLoc Loc
) {}
1086 void MCStreamer::emitFill(const MCExpr
&NumValues
, int64_t Size
, int64_t Expr
,
1088 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment
, int64_t Value
,
1090 unsigned MaxBytesToEmit
) {}
1091 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment
,
1092 unsigned MaxBytesToEmit
) {}
1093 void MCStreamer::emitValueToOffset(const MCExpr
*Offset
, unsigned char Value
,
1095 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2
) {}
1096 void MCStreamer::EmitBundleLock(bool AlignToEnd
) {}
1097 void MCStreamer::FinishImpl() {}
1098 void MCStreamer::EmitBundleUnlock() {}
1100 void MCStreamer::SwitchSection(MCSection
*Section
, const MCExpr
*Subsection
) {
1101 assert(Section
&& "Cannot switch to a null section!");
1102 MCSectionSubPair curSection
= SectionStack
.back().first
;
1103 SectionStack
.back().second
= curSection
;
1104 if (MCSectionSubPair(Section
, Subsection
) != curSection
) {
1105 ChangeSection(Section
, Subsection
);
1106 SectionStack
.back().first
= MCSectionSubPair(Section
, Subsection
);
1107 assert(!Section
->hasEnded() && "Section already ended");
1108 MCSymbol
*Sym
= Section
->getBeginSymbol();
1109 if (Sym
&& !Sym
->isInSection())
1114 MCSymbol
*MCStreamer::endSection(MCSection
*Section
) {
1115 // TODO: keep track of the last subsection so that this symbol appears in the
1117 MCSymbol
*Sym
= Section
->getEndSymbol(Context
);
1118 if (Sym
->isInSection())
1121 SwitchSection(Section
);
1126 void MCStreamer::EmitVersionForTarget(const Triple
&Target
,
1127 const VersionTuple
&SDKVersion
) {
1128 if (!Target
.isOSBinFormatMachO() || !Target
.isOSDarwin())
1130 // Do we even know the version?
1131 if (Target
.getOSMajorVersion() == 0)
1137 if (Target
.isMacCatalystEnvironment()) {
1138 // Mac Catalyst always uses the build version load command.
1139 Target
.getiOSVersion(Major
, Minor
, Update
);
1140 assert(Major
&& "A non-zero major version is expected");
1141 EmitBuildVersion(MachO::PLATFORM_MACCATALYST
, Major
, Minor
, Update
,
1146 MCVersionMinType VersionType
;
1147 if (Target
.isWatchOS()) {
1148 VersionType
= MCVM_WatchOSVersionMin
;
1149 Target
.getWatchOSVersion(Major
, Minor
, Update
);
1150 } else if (Target
.isTvOS()) {
1151 VersionType
= MCVM_TvOSVersionMin
;
1152 Target
.getiOSVersion(Major
, Minor
, Update
);
1153 } else if (Target
.isMacOSX()) {
1154 VersionType
= MCVM_OSXVersionMin
;
1155 if (!Target
.getMacOSXVersion(Major
, Minor
, Update
))
1158 VersionType
= MCVM_IOSVersionMin
;
1159 Target
.getiOSVersion(Major
, Minor
, Update
);
1162 EmitVersionMin(VersionType
, Major
, Minor
, Update
, SDKVersion
);