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/MCSection.h"
25 #include "llvm/MC/MCSectionCOFF.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCWin64EH.h"
28 #include "llvm/MC/MCWinEH.h"
29 #include "llvm/Support/Casting.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/LEB128.h"
32 #include "llvm/Support/MathExtras.h"
33 #include "llvm/Support/raw_ostream.h"
41 MCTargetStreamer::MCTargetStreamer(MCStreamer
&S
) : Streamer(S
) {
42 S
.setTargetStreamer(this);
45 // Pin the vtables to this file.
46 MCTargetStreamer::~MCTargetStreamer() = default;
48 void MCTargetStreamer::emitLabel(MCSymbol
*Symbol
) {}
50 void MCTargetStreamer::finish() {}
52 void MCTargetStreamer::changeSection(const MCSection
*CurSection
,
54 const MCExpr
*Subsection
,
56 Section
->PrintSwitchToSection(
57 *Streamer
.getContext().getAsmInfo(),
58 Streamer
.getContext().getObjectFileInfo()->getTargetTriple(), OS
,
62 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive
) {
63 Streamer
.EmitRawText(Directive
);
66 void MCTargetStreamer::emitValue(const MCExpr
*Value
) {
68 raw_svector_ostream
OS(Str
);
70 Value
->print(OS
, Streamer
.getContext().getAsmInfo());
71 Streamer
.EmitRawText(OS
.str());
74 void MCTargetStreamer::emitRawBytes(StringRef Data
) {
75 const MCAsmInfo
*MAI
= Streamer
.getContext().getAsmInfo();
76 const char *Directive
= MAI
->getData8bitsDirective();
77 for (const unsigned char C
: Data
.bytes()) {
79 raw_svector_ostream
OS(Str
);
81 OS
<< Directive
<< (unsigned)C
;
82 Streamer
.EmitRawText(OS
.str());
86 void MCTargetStreamer::emitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {}
88 MCStreamer::MCStreamer(MCContext
&Ctx
)
89 : Context(Ctx
), CurrentWinFrameInfo(nullptr),
90 UseAssemblerInfoForParsing(false) {
91 SectionStack
.push_back(std::pair
<MCSectionSubPair
, MCSectionSubPair
>());
94 MCStreamer::~MCStreamer() {}
96 void MCStreamer::reset() {
97 DwarfFrameInfos
.clear();
98 CurrentWinFrameInfo
= nullptr;
99 WinFrameInfos
.clear();
100 SymbolOrdering
.clear();
101 SectionStack
.clear();
102 SectionStack
.push_back(std::pair
<MCSectionSubPair
, MCSectionSubPair
>());
105 raw_ostream
&MCStreamer::GetCommentOS() {
106 // By default, discard comments.
110 unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos
.size(); }
111 ArrayRef
<MCDwarfFrameInfo
> MCStreamer::getDwarfFrameInfos() const {
112 return DwarfFrameInfos
;
115 void MCStreamer::emitRawComment(const Twine
&T
, bool TabPrefix
) {}
117 void MCStreamer::addExplicitComment(const Twine
&T
) {}
118 void MCStreamer::emitExplicitComments() {}
120 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend
*MAB
) {
121 for (auto &FI
: DwarfFrameInfos
)
122 FI
.CompactUnwindEncoding
=
123 (MAB
? MAB
->generateCompactUnwindEncoding(FI
.Instructions
) : 0);
126 /// EmitIntValue - Special case of EmitValue that avoids the client having to
127 /// pass in a MCExpr for constant integers.
128 void MCStreamer::EmitIntValue(uint64_t Value
, unsigned Size
) {
129 assert(1 <= Size
&& Size
<= 8 && "Invalid size");
130 assert((isUIntN(8 * Size
, Value
) || isIntN(8 * Size
, Value
)) &&
133 const bool isLittleEndian
= Context
.getAsmInfo()->isLittleEndian();
134 for (unsigned i
= 0; i
!= Size
; ++i
) {
135 unsigned index
= isLittleEndian
? i
: (Size
- i
- 1);
136 buf
[i
] = uint8_t(Value
>> (index
* 8));
138 EmitBytes(StringRef(buf
, Size
));
141 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
142 /// client having to pass in a MCExpr for constant integers.
143 void MCStreamer::EmitULEB128IntValue(uint64_t Value
, unsigned PadTo
) {
144 SmallString
<128> Tmp
;
145 raw_svector_ostream
OSE(Tmp
);
146 encodeULEB128(Value
, OSE
, PadTo
);
147 EmitBytes(OSE
.str());
150 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
151 /// client having to pass in a MCExpr for constant integers.
152 void MCStreamer::EmitSLEB128IntValue(int64_t Value
) {
153 SmallString
<128> Tmp
;
154 raw_svector_ostream
OSE(Tmp
);
155 encodeSLEB128(Value
, OSE
);
156 EmitBytes(OSE
.str());
159 void MCStreamer::EmitValue(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
160 EmitValueImpl(Value
, Size
, Loc
);
163 void MCStreamer::EmitSymbolValue(const MCSymbol
*Sym
, unsigned Size
,
164 bool IsSectionRelative
) {
165 assert((!IsSectionRelative
|| Size
== 4) &&
166 "SectionRelative value requires 4-bytes");
168 if (!IsSectionRelative
)
169 EmitValueImpl(MCSymbolRefExpr::create(Sym
, getContext()), Size
);
171 EmitCOFFSecRel32(Sym
, /*Offset=*/0);
174 void MCStreamer::EmitDTPRel64Value(const MCExpr
*Value
) {
175 report_fatal_error("unsupported directive in streamer");
178 void MCStreamer::EmitDTPRel32Value(const MCExpr
*Value
) {
179 report_fatal_error("unsupported directive in streamer");
182 void MCStreamer::EmitTPRel64Value(const MCExpr
*Value
) {
183 report_fatal_error("unsupported directive in streamer");
186 void MCStreamer::EmitTPRel32Value(const MCExpr
*Value
) {
187 report_fatal_error("unsupported directive in streamer");
190 void MCStreamer::EmitGPRel64Value(const MCExpr
*Value
) {
191 report_fatal_error("unsupported directive in streamer");
194 void MCStreamer::EmitGPRel32Value(const MCExpr
*Value
) {
195 report_fatal_error("unsupported directive in streamer");
198 /// Emit NumBytes bytes worth of the value specified by FillValue.
199 /// This implements directives such as '.space'.
200 void MCStreamer::emitFill(uint64_t NumBytes
, uint8_t FillValue
) {
201 emitFill(*MCConstantExpr::create(NumBytes
, getContext()), FillValue
);
204 /// The implementation in this class just redirects to emitFill.
205 void MCStreamer::EmitZeros(uint64_t NumBytes
) {
206 emitFill(NumBytes
, 0);
210 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo
, StringRef Directory
,
212 Optional
<MD5::MD5Result
> Checksum
,
213 Optional
<StringRef
> Source
,
215 return getContext().getDwarfFile(Directory
, Filename
, FileNo
, Checksum
,
219 void MCStreamer::emitDwarfFile0Directive(StringRef Directory
,
221 Optional
<MD5::MD5Result
> Checksum
,
222 Optional
<StringRef
> Source
,
224 getContext().setMCLineTableRootFile(CUID
, Directory
, Filename
, Checksum
,
228 void MCStreamer::EmitCFIBKeyFrame() {
229 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
232 CurFrame
->IsBKeyFrame
= true;
235 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo
, unsigned Line
,
236 unsigned Column
, unsigned Flags
,
238 unsigned Discriminator
,
239 StringRef FileName
) {
240 getContext().setCurrentDwarfLoc(FileNo
, Line
, Column
, Flags
, Isa
,
244 MCSymbol
*MCStreamer::getDwarfLineTableSymbol(unsigned CUID
) {
245 MCDwarfLineTable
&Table
= getContext().getMCDwarfLineTable(CUID
);
246 if (!Table
.getLabel()) {
247 StringRef Prefix
= Context
.getAsmInfo()->getPrivateGlobalPrefix();
249 Context
.getOrCreateSymbol(Prefix
+ "line_table_start" + Twine(CUID
)));
251 return Table
.getLabel();
254 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
255 return !DwarfFrameInfos
.empty() && !DwarfFrameInfos
.back().End
;
258 MCDwarfFrameInfo
*MCStreamer::getCurrentDwarfFrameInfo() {
259 if (!hasUnfinishedDwarfFrameInfo()) {
260 getContext().reportError(SMLoc(), "this directive must appear between "
261 ".cfi_startproc and .cfi_endproc "
265 return &DwarfFrameInfos
.back();
268 bool MCStreamer::EmitCVFileDirective(unsigned FileNo
, StringRef Filename
,
269 ArrayRef
<uint8_t> Checksum
,
270 unsigned ChecksumKind
) {
271 return getContext().getCVContext().addFile(*this, FileNo
, Filename
, Checksum
,
275 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId
) {
276 return getContext().getCVContext().recordFunctionId(FunctionId
);
279 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId
,
280 unsigned IAFunc
, unsigned IAFile
,
281 unsigned IALine
, unsigned IACol
,
283 if (getContext().getCVContext().getCVFunctionInfo(IAFunc
) == nullptr) {
284 getContext().reportError(Loc
, "parent function id not introduced by "
285 ".cv_func_id or .cv_inline_site_id");
289 return getContext().getCVContext().recordInlinedCallSiteId(
290 FunctionId
, IAFunc
, IAFile
, IALine
, IACol
);
293 void MCStreamer::EmitCVLocDirective(unsigned FunctionId
, unsigned FileNo
,
294 unsigned Line
, unsigned Column
,
295 bool PrologueEnd
, bool IsStmt
,
296 StringRef FileName
, SMLoc Loc
) {}
298 bool MCStreamer::checkCVLocSection(unsigned FuncId
, unsigned FileNo
,
300 CodeViewContext
&CVC
= getContext().getCVContext();
301 MCCVFunctionInfo
*FI
= CVC
.getCVFunctionInfo(FuncId
);
303 getContext().reportError(
304 Loc
, "function id not introduced by .cv_func_id or .cv_inline_site_id");
309 if (FI
->Section
== nullptr)
310 FI
->Section
= getCurrentSectionOnly();
311 else if (FI
->Section
!= getCurrentSectionOnly()) {
312 getContext().reportError(
314 "all .cv_loc directives for a function must be in the same section");
320 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId
,
321 const MCSymbol
*Begin
,
322 const MCSymbol
*End
) {}
324 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId
,
325 unsigned SourceFileId
,
326 unsigned SourceLineNum
,
327 const MCSymbol
*FnStartSym
,
328 const MCSymbol
*FnEndSym
) {}
330 /// Only call this on endian-specific types like ulittle16_t and little32_t, or
331 /// structs composed of them.
332 template <typename T
>
333 static void copyBytesForDefRange(SmallString
<20> &BytePrefix
,
334 codeview::SymbolKind SymKind
,
335 const T
&DefRangeHeader
) {
336 BytePrefix
.resize(2 + sizeof(T
));
337 codeview::ulittle16_t SymKindLE
= codeview::ulittle16_t(SymKind
);
338 memcpy(&BytePrefix
[0], &SymKindLE
, 2);
339 memcpy(&BytePrefix
[2], &DefRangeHeader
, sizeof(T
));
342 void MCStreamer::EmitCVDefRangeDirective(
343 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
344 StringRef FixedSizePortion
) {}
346 void MCStreamer::EmitCVDefRangeDirective(
347 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
348 codeview::DefRangeRegisterRelSym::Header DRHdr
) {
349 SmallString
<20> BytePrefix
;
350 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_REGISTER_REL
, DRHdr
);
351 EmitCVDefRangeDirective(Ranges
, BytePrefix
);
354 void MCStreamer::EmitCVDefRangeDirective(
355 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
356 codeview::DefRangeSubfieldRegisterSym::Header DRHdr
) {
357 SmallString
<20> BytePrefix
;
358 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_SUBFIELD_REGISTER
,
360 EmitCVDefRangeDirective(Ranges
, BytePrefix
);
363 void MCStreamer::EmitCVDefRangeDirective(
364 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
365 codeview::DefRangeRegisterSym::Header DRHdr
) {
366 SmallString
<20> BytePrefix
;
367 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_REGISTER
, DRHdr
);
368 EmitCVDefRangeDirective(Ranges
, BytePrefix
);
371 void MCStreamer::EmitCVDefRangeDirective(
372 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
373 codeview::DefRangeFramePointerRelSym::Header DRHdr
) {
374 SmallString
<20> BytePrefix
;
375 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_FRAMEPOINTER_REL
,
377 EmitCVDefRangeDirective(Ranges
, BytePrefix
);
380 void MCStreamer::EmitEHSymAttributes(const MCSymbol
*Symbol
,
381 MCSymbol
*EHSymbol
) {
384 void MCStreamer::InitSections(bool NoExecStack
) {
385 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
388 void MCStreamer::AssignFragment(MCSymbol
*Symbol
, MCFragment
*Fragment
) {
390 Symbol
->setFragment(Fragment
);
392 // As we emit symbols into a section, track the order so that they can
393 // be sorted upon later. Zero is reserved to mean 'unemitted'.
394 SymbolOrdering
[Symbol
] = 1 + SymbolOrdering
.size();
397 void MCStreamer::EmitLabel(MCSymbol
*Symbol
, SMLoc Loc
) {
398 Symbol
->redefineIfPossible();
400 if (!Symbol
->isUndefined() || Symbol
->isVariable())
401 return getContext().reportError(Loc
, "invalid symbol redefinition");
403 assert(!Symbol
->isVariable() && "Cannot emit a variable symbol!");
404 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
405 assert(!Symbol
->getFragment() && "Unexpected fragment on symbol data!");
406 assert(Symbol
->isUndefined() && "Cannot define a symbol twice!");
408 Symbol
->setFragment(&getCurrentSectionOnly()->getDummyFragment());
410 MCTargetStreamer
*TS
= getTargetStreamer();
412 TS
->emitLabel(Symbol
);
415 void MCStreamer::EmitCFISections(bool EH
, bool Debug
) {
419 void MCStreamer::EmitCFIStartProc(bool IsSimple
, SMLoc Loc
) {
420 if (hasUnfinishedDwarfFrameInfo())
421 return getContext().reportError(
422 Loc
, "starting new .cfi frame before finishing the previous one");
424 MCDwarfFrameInfo Frame
;
425 Frame
.IsSimple
= IsSimple
;
426 EmitCFIStartProcImpl(Frame
);
428 const MCAsmInfo
* MAI
= Context
.getAsmInfo();
430 for (const MCCFIInstruction
& Inst
: MAI
->getInitialFrameState()) {
431 if (Inst
.getOperation() == MCCFIInstruction::OpDefCfa
||
432 Inst
.getOperation() == MCCFIInstruction::OpDefCfaRegister
) {
433 Frame
.CurrentCfaRegister
= Inst
.getRegister();
438 DwarfFrameInfos
.push_back(Frame
);
441 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) {
444 void MCStreamer::EmitCFIEndProc() {
445 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
448 EmitCFIEndProcImpl(*CurFrame
);
451 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) {
452 // Put a dummy non-null value in Frame.End to mark that this frame has been
454 Frame
.End
= (MCSymbol
*)1;
457 MCSymbol
*MCStreamer::EmitCFILabel() {
458 // Return a dummy non-null value so that label fields appear filled in when
459 // generating textual assembly.
460 return (MCSymbol
*)1;
463 void MCStreamer::EmitCFIDefCfa(int64_t Register
, int64_t Offset
) {
464 MCSymbol
*Label
= EmitCFILabel();
465 MCCFIInstruction Instruction
=
466 MCCFIInstruction::createDefCfa(Label
, Register
, Offset
);
467 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
470 CurFrame
->Instructions
.push_back(Instruction
);
471 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
474 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset
) {
475 MCSymbol
*Label
= EmitCFILabel();
476 MCCFIInstruction Instruction
=
477 MCCFIInstruction::createDefCfaOffset(Label
, Offset
);
478 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
481 CurFrame
->Instructions
.push_back(Instruction
);
484 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment
) {
485 MCSymbol
*Label
= EmitCFILabel();
486 MCCFIInstruction Instruction
=
487 MCCFIInstruction::createAdjustCfaOffset(Label
, Adjustment
);
488 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
491 CurFrame
->Instructions
.push_back(Instruction
);
494 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register
) {
495 MCSymbol
*Label
= EmitCFILabel();
496 MCCFIInstruction Instruction
=
497 MCCFIInstruction::createDefCfaRegister(Label
, Register
);
498 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
501 CurFrame
->Instructions
.push_back(Instruction
);
502 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
505 void MCStreamer::EmitCFIOffset(int64_t Register
, int64_t Offset
) {
506 MCSymbol
*Label
= EmitCFILabel();
507 MCCFIInstruction Instruction
=
508 MCCFIInstruction::createOffset(Label
, Register
, Offset
);
509 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
512 CurFrame
->Instructions
.push_back(Instruction
);
515 void MCStreamer::EmitCFIRelOffset(int64_t Register
, int64_t Offset
) {
516 MCSymbol
*Label
= EmitCFILabel();
517 MCCFIInstruction Instruction
=
518 MCCFIInstruction::createRelOffset(Label
, Register
, Offset
);
519 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
522 CurFrame
->Instructions
.push_back(Instruction
);
525 void MCStreamer::EmitCFIPersonality(const MCSymbol
*Sym
,
527 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
530 CurFrame
->Personality
= Sym
;
531 CurFrame
->PersonalityEncoding
= Encoding
;
534 void MCStreamer::EmitCFILsda(const MCSymbol
*Sym
, unsigned Encoding
) {
535 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
538 CurFrame
->Lsda
= Sym
;
539 CurFrame
->LsdaEncoding
= Encoding
;
542 void MCStreamer::EmitCFIRememberState() {
543 MCSymbol
*Label
= EmitCFILabel();
544 MCCFIInstruction Instruction
= MCCFIInstruction::createRememberState(Label
);
545 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
548 CurFrame
->Instructions
.push_back(Instruction
);
551 void MCStreamer::EmitCFIRestoreState() {
552 // FIXME: Error if there is no matching cfi_remember_state.
553 MCSymbol
*Label
= EmitCFILabel();
554 MCCFIInstruction Instruction
= MCCFIInstruction::createRestoreState(Label
);
555 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
558 CurFrame
->Instructions
.push_back(Instruction
);
561 void MCStreamer::EmitCFISameValue(int64_t Register
) {
562 MCSymbol
*Label
= EmitCFILabel();
563 MCCFIInstruction Instruction
=
564 MCCFIInstruction::createSameValue(Label
, Register
);
565 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
568 CurFrame
->Instructions
.push_back(Instruction
);
571 void MCStreamer::EmitCFIRestore(int64_t Register
) {
572 MCSymbol
*Label
= EmitCFILabel();
573 MCCFIInstruction Instruction
=
574 MCCFIInstruction::createRestore(Label
, Register
);
575 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
578 CurFrame
->Instructions
.push_back(Instruction
);
581 void MCStreamer::EmitCFIEscape(StringRef Values
) {
582 MCSymbol
*Label
= EmitCFILabel();
583 MCCFIInstruction Instruction
= MCCFIInstruction::createEscape(Label
, Values
);
584 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
587 CurFrame
->Instructions
.push_back(Instruction
);
590 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size
) {
591 MCSymbol
*Label
= EmitCFILabel();
592 MCCFIInstruction Instruction
=
593 MCCFIInstruction::createGnuArgsSize(Label
, Size
);
594 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
597 CurFrame
->Instructions
.push_back(Instruction
);
600 void MCStreamer::EmitCFISignalFrame() {
601 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
604 CurFrame
->IsSignalFrame
= true;
607 void MCStreamer::EmitCFIUndefined(int64_t Register
) {
608 MCSymbol
*Label
= EmitCFILabel();
609 MCCFIInstruction Instruction
=
610 MCCFIInstruction::createUndefined(Label
, Register
);
611 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
614 CurFrame
->Instructions
.push_back(Instruction
);
617 void MCStreamer::EmitCFIRegister(int64_t Register1
, int64_t Register2
) {
618 MCSymbol
*Label
= EmitCFILabel();
619 MCCFIInstruction Instruction
=
620 MCCFIInstruction::createRegister(Label
, Register1
, Register2
);
621 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
624 CurFrame
->Instructions
.push_back(Instruction
);
627 void MCStreamer::EmitCFIWindowSave() {
628 MCSymbol
*Label
= EmitCFILabel();
629 MCCFIInstruction Instruction
=
630 MCCFIInstruction::createWindowSave(Label
);
631 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
634 CurFrame
->Instructions
.push_back(Instruction
);
637 void MCStreamer::EmitCFINegateRAState() {
638 MCSymbol
*Label
= EmitCFILabel();
639 MCCFIInstruction Instruction
= MCCFIInstruction::createNegateRAState(Label
);
640 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
643 CurFrame
->Instructions
.push_back(Instruction
);
646 void MCStreamer::EmitCFIReturnColumn(int64_t Register
) {
647 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
650 CurFrame
->RAReg
= Register
;
653 WinEH::FrameInfo
*MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc
) {
654 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
655 if (!MAI
->usesWindowsCFI()) {
656 getContext().reportError(
657 Loc
, ".seh_* directives are not supported on this target");
660 if (!CurrentWinFrameInfo
|| CurrentWinFrameInfo
->End
) {
661 getContext().reportError(
662 Loc
, ".seh_ directive must appear within an active frame");
665 return CurrentWinFrameInfo
;
668 void MCStreamer::EmitWinCFIStartProc(const MCSymbol
*Symbol
, SMLoc Loc
) {
669 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
670 if (!MAI
->usesWindowsCFI())
671 return getContext().reportError(
672 Loc
, ".seh_* directives are not supported on this target");
673 if (CurrentWinFrameInfo
&& !CurrentWinFrameInfo
->End
)
674 getContext().reportError(
675 Loc
, "Starting a function before ending the previous one!");
677 MCSymbol
*StartProc
= EmitCFILabel();
679 WinFrameInfos
.emplace_back(
680 std::make_unique
<WinEH::FrameInfo
>(Symbol
, StartProc
));
681 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
682 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
685 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc
) {
686 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
689 if (CurFrame
->ChainedParent
)
690 getContext().reportError(Loc
, "Not all chained regions terminated!");
692 MCSymbol
*Label
= EmitCFILabel();
693 CurFrame
->End
= Label
;
696 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc
) {
697 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
700 if (CurFrame
->ChainedParent
)
701 getContext().reportError(Loc
, "Not all chained regions terminated!");
703 MCSymbol
*Label
= EmitCFILabel();
704 CurFrame
->FuncletOrFuncEnd
= Label
;
707 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc
) {
708 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
712 MCSymbol
*StartProc
= EmitCFILabel();
714 WinFrameInfos
.emplace_back(std::make_unique
<WinEH::FrameInfo
>(
715 CurFrame
->Function
, StartProc
, CurFrame
));
716 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
717 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
720 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc
) {
721 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
724 if (!CurFrame
->ChainedParent
)
725 return getContext().reportError(
726 Loc
, "End of a chained region outside a chained region!");
728 MCSymbol
*Label
= EmitCFILabel();
730 CurFrame
->End
= Label
;
731 CurrentWinFrameInfo
= const_cast<WinEH::FrameInfo
*>(CurFrame
->ChainedParent
);
734 void MCStreamer::EmitWinEHHandler(const MCSymbol
*Sym
, bool Unwind
, bool Except
,
736 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
739 if (CurFrame
->ChainedParent
)
740 return getContext().reportError(
741 Loc
, "Chained unwind areas can't have handlers!");
742 CurFrame
->ExceptionHandler
= Sym
;
743 if (!Except
&& !Unwind
)
744 getContext().reportError(Loc
, "Don't know what kind of handler this is!");
746 CurFrame
->HandlesUnwind
= true;
748 CurFrame
->HandlesExceptions
= true;
751 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc
) {
752 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
755 if (CurFrame
->ChainedParent
)
756 getContext().reportError(Loc
, "Chained unwind areas can't have handlers!");
759 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr
*From
,
760 const MCSymbolRefExpr
*To
, uint64_t Count
) {
763 static MCSection
*getWinCFISection(MCContext
&Context
, unsigned *NextWinCFIID
,
764 MCSection
*MainCFISec
,
765 const MCSection
*TextSec
) {
766 // If this is the main .text section, use the main unwind info section.
767 if (TextSec
== Context
.getObjectFileInfo()->getTextSection())
770 const auto *TextSecCOFF
= cast
<MCSectionCOFF
>(TextSec
);
771 auto *MainCFISecCOFF
= cast
<MCSectionCOFF
>(MainCFISec
);
772 unsigned UniqueID
= TextSecCOFF
->getOrAssignWinCFISectionID(NextWinCFIID
);
774 // If this section is COMDAT, this unwind section should be COMDAT associative
776 const MCSymbol
*KeySym
= nullptr;
777 if (TextSecCOFF
->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT
) {
778 KeySym
= TextSecCOFF
->getCOMDATSymbol();
780 // In a GNU environment, we can't use associative comdats. Instead, do what
781 // GCC does, which is to make plain comdat selectany section named like
782 // ".[px]data$_Z3foov".
783 if (!Context
.getAsmInfo()->hasCOFFAssociativeComdats()) {
784 std::string SectionName
=
785 (MainCFISecCOFF
->getSectionName() + "$" +
786 TextSecCOFF
->getSectionName().split('$').second
)
788 return Context
.getCOFFSection(
790 MainCFISecCOFF
->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT
,
791 MainCFISecCOFF
->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY
);
795 return Context
.getAssociativeCOFFSection(MainCFISecCOFF
, KeySym
, UniqueID
);
798 MCSection
*MCStreamer::getAssociatedPDataSection(const MCSection
*TextSec
) {
799 return getWinCFISection(getContext(), &NextWinCFIID
,
800 getContext().getObjectFileInfo()->getPDataSection(),
804 MCSection
*MCStreamer::getAssociatedXDataSection(const MCSection
*TextSec
) {
805 return getWinCFISection(getContext(), &NextWinCFIID
,
806 getContext().getObjectFileInfo()->getXDataSection(),
810 void MCStreamer::EmitSyntaxDirective() {}
812 void MCStreamer::EmitWinCFIPushReg(unsigned Register
, SMLoc Loc
) {
813 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
817 MCSymbol
*Label
= EmitCFILabel();
819 WinEH::Instruction Inst
= Win64EH::Instruction::PushNonVol(Label
, Register
);
820 CurFrame
->Instructions
.push_back(Inst
);
823 void MCStreamer::EmitWinCFISetFrame(unsigned Register
, unsigned Offset
,
825 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
828 if (CurFrame
->LastFrameInst
>= 0)
829 return getContext().reportError(
830 Loc
, "frame register and offset can be set at most once");
832 return getContext().reportError(Loc
, "offset is not a multiple of 16");
834 return getContext().reportError(
835 Loc
, "frame offset must be less than or equal to 240");
837 MCSymbol
*Label
= EmitCFILabel();
839 WinEH::Instruction Inst
=
840 Win64EH::Instruction::SetFPReg(Label
, Register
, Offset
);
841 CurFrame
->LastFrameInst
= CurFrame
->Instructions
.size();
842 CurFrame
->Instructions
.push_back(Inst
);
845 void MCStreamer::EmitWinCFIAllocStack(unsigned Size
, SMLoc Loc
) {
846 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
850 return getContext().reportError(Loc
,
851 "stack allocation size must be non-zero");
853 return getContext().reportError(
854 Loc
, "stack allocation size is not a multiple of 8");
856 MCSymbol
*Label
= EmitCFILabel();
858 WinEH::Instruction Inst
= Win64EH::Instruction::Alloc(Label
, Size
);
859 CurFrame
->Instructions
.push_back(Inst
);
862 void MCStreamer::EmitWinCFISaveReg(unsigned Register
, unsigned Offset
,
864 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
869 return getContext().reportError(
870 Loc
, "register save offset is not 8 byte aligned");
872 MCSymbol
*Label
= EmitCFILabel();
874 WinEH::Instruction Inst
=
875 Win64EH::Instruction::SaveNonVol(Label
, Register
, Offset
);
876 CurFrame
->Instructions
.push_back(Inst
);
879 void MCStreamer::EmitWinCFISaveXMM(unsigned Register
, unsigned Offset
,
881 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
885 return getContext().reportError(Loc
, "offset is not a multiple of 16");
887 MCSymbol
*Label
= EmitCFILabel();
889 WinEH::Instruction Inst
=
890 Win64EH::Instruction::SaveXMM(Label
, Register
, Offset
);
891 CurFrame
->Instructions
.push_back(Inst
);
894 void MCStreamer::EmitWinCFIPushFrame(bool Code
, SMLoc Loc
) {
895 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
898 if (!CurFrame
->Instructions
.empty())
899 return getContext().reportError(
900 Loc
, "If present, PushMachFrame must be the first UOP");
902 MCSymbol
*Label
= EmitCFILabel();
904 WinEH::Instruction Inst
= Win64EH::Instruction::PushMachFrame(Label
, Code
);
905 CurFrame
->Instructions
.push_back(Inst
);
908 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc
) {
909 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
913 MCSymbol
*Label
= EmitCFILabel();
915 CurFrame
->PrologEnd
= Label
;
918 void MCStreamer::EmitCOFFSafeSEH(MCSymbol
const *Symbol
) {}
920 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol
const *Symbol
) {}
922 void MCStreamer::EmitCOFFSectionIndex(MCSymbol
const *Symbol
) {}
924 void MCStreamer::EmitCOFFSecRel32(MCSymbol
const *Symbol
, uint64_t Offset
) {}
926 void MCStreamer::EmitCOFFImgRel32(MCSymbol
const *Symbol
, int64_t Offset
) {}
928 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
929 /// the specified string in the output .s file. This capability is
930 /// indicated by the hasRawTextSupport() predicate.
931 void MCStreamer::EmitRawTextImpl(StringRef String
) {
932 // This is not llvm_unreachable for the sake of out of tree backend
933 // developers who may not have assembly streamers and should serve as a
934 // reminder to not accidentally call EmitRawText in the absence of such.
935 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
936 "it (target backend is likely missing an AsmStreamer "
940 void MCStreamer::EmitRawText(const Twine
&T
) {
941 SmallString
<128> Str
;
942 EmitRawTextImpl(T
.toStringRef(Str
));
945 void MCStreamer::EmitWindowsUnwindTables() {
948 void MCStreamer::Finish() {
949 if ((!DwarfFrameInfos
.empty() && !DwarfFrameInfos
.back().End
) ||
950 (!WinFrameInfos
.empty() && !WinFrameInfos
.back()->End
)) {
951 getContext().reportError(SMLoc(), "Unfinished frame!");
955 MCTargetStreamer
*TS
= getTargetStreamer();
962 void MCStreamer::EmitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {
963 visitUsedExpr(*Value
);
964 Symbol
->setVariableValue(Value
);
966 MCTargetStreamer
*TS
= getTargetStreamer();
968 TS
->emitAssignment(Symbol
, Value
);
971 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter
&InstPrinter
,
972 raw_ostream
&OS
, const MCInst
&Inst
,
973 const MCSubtargetInfo
&STI
) {
974 InstPrinter
.printInst(&Inst
, OS
, "", STI
);
977 void MCStreamer::visitUsedSymbol(const MCSymbol
&Sym
) {
980 void MCStreamer::visitUsedExpr(const MCExpr
&Expr
) {
981 switch (Expr
.getKind()) {
983 cast
<MCTargetExpr
>(Expr
).visitUsedExpr(*this);
986 case MCExpr::Constant
:
989 case MCExpr::Binary
: {
990 const MCBinaryExpr
&BE
= cast
<MCBinaryExpr
>(Expr
);
991 visitUsedExpr(*BE
.getLHS());
992 visitUsedExpr(*BE
.getRHS());
996 case MCExpr::SymbolRef
:
997 visitUsedSymbol(cast
<MCSymbolRefExpr
>(Expr
).getSymbol());
1001 visitUsedExpr(*cast
<MCUnaryExpr
>(Expr
).getSubExpr());
1006 void MCStreamer::EmitInstruction(const MCInst
&Inst
, const MCSubtargetInfo
&) {
1008 for (unsigned i
= Inst
.getNumOperands(); i
--;)
1009 if (Inst
.getOperand(i
).isExpr())
1010 visitUsedExpr(*Inst
.getOperand(i
).getExpr());
1013 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol
*Hi
, const MCSymbol
*Lo
,
1015 // Get the Hi-Lo expression.
1016 const MCExpr
*Diff
=
1017 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
1018 MCSymbolRefExpr::create(Lo
, Context
), Context
);
1020 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
1021 if (!MAI
->doesSetDirectiveSuppressReloc()) {
1022 EmitValue(Diff
, Size
);
1026 // Otherwise, emit with .set (aka assignment).
1027 MCSymbol
*SetLabel
= Context
.createTempSymbol("set", true);
1028 EmitAssignment(SetLabel
, Diff
);
1029 EmitSymbolValue(SetLabel
, Size
);
1032 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol
*Hi
,
1033 const MCSymbol
*Lo
) {
1034 // Get the Hi-Lo expression.
1035 const MCExpr
*Diff
=
1036 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
1037 MCSymbolRefExpr::create(Lo
, Context
), Context
);
1039 EmitULEB128Value(Diff
);
1042 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag
) {}
1043 void MCStreamer::EmitThumbFunc(MCSymbol
*Func
) {}
1044 void MCStreamer::EmitSymbolDesc(MCSymbol
*Symbol
, unsigned DescValue
) {}
1045 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol
*Symbol
) {
1046 llvm_unreachable("this directive only supported on COFF targets");
1048 void MCStreamer::EndCOFFSymbolDef() {
1049 llvm_unreachable("this directive only supported on COFF targets");
1051 void MCStreamer::EmitFileDirective(StringRef Filename
) {}
1052 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass
) {
1053 llvm_unreachable("this directive only supported on COFF targets");
1055 void MCStreamer::EmitCOFFSymbolType(int Type
) {
1056 llvm_unreachable("this directive only supported on COFF targets");
1058 void MCStreamer::EmitXCOFFLocalCommonSymbol(MCSymbol
*Symbol
, uint64_t Size
,
1059 unsigned ByteAlign
) {
1060 llvm_unreachable("this directive only supported on XCOFF targets");
1062 void MCStreamer::emitELFSize(MCSymbol
*Symbol
, const MCExpr
*Value
) {}
1063 void MCStreamer::emitELFSymverDirective(StringRef AliasName
,
1064 const MCSymbol
*Aliasee
) {}
1065 void MCStreamer::EmitLocalCommonSymbol(MCSymbol
*Symbol
, uint64_t Size
,
1066 unsigned ByteAlignment
) {}
1067 void MCStreamer::EmitTBSSSymbol(MCSection
*Section
, MCSymbol
*Symbol
,
1068 uint64_t Size
, unsigned ByteAlignment
) {}
1069 void MCStreamer::ChangeSection(MCSection
*, const MCExpr
*) {}
1070 void MCStreamer::EmitWeakReference(MCSymbol
*Alias
, const MCSymbol
*Symbol
) {}
1071 void MCStreamer::EmitBytes(StringRef Data
) {}
1072 void MCStreamer::EmitBinaryData(StringRef Data
) { EmitBytes(Data
); }
1073 void MCStreamer::EmitValueImpl(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
1074 visitUsedExpr(*Value
);
1076 void MCStreamer::EmitULEB128Value(const MCExpr
*Value
) {}
1077 void MCStreamer::EmitSLEB128Value(const MCExpr
*Value
) {}
1078 void MCStreamer::emitFill(const MCExpr
&NumBytes
, uint64_t Value
, SMLoc Loc
) {}
1079 void MCStreamer::emitFill(const MCExpr
&NumValues
, int64_t Size
, int64_t Expr
,
1081 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment
, int64_t Value
,
1083 unsigned MaxBytesToEmit
) {}
1084 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment
,
1085 unsigned MaxBytesToEmit
) {}
1086 void MCStreamer::emitValueToOffset(const MCExpr
*Offset
, unsigned char Value
,
1088 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2
) {}
1089 void MCStreamer::EmitBundleLock(bool AlignToEnd
) {}
1090 void MCStreamer::FinishImpl() {}
1091 void MCStreamer::EmitBundleUnlock() {}
1093 void MCStreamer::SwitchSection(MCSection
*Section
, const MCExpr
*Subsection
) {
1094 assert(Section
&& "Cannot switch to a null section!");
1095 MCSectionSubPair curSection
= SectionStack
.back().first
;
1096 SectionStack
.back().second
= curSection
;
1097 if (MCSectionSubPair(Section
, Subsection
) != curSection
) {
1098 ChangeSection(Section
, Subsection
);
1099 SectionStack
.back().first
= MCSectionSubPair(Section
, Subsection
);
1100 assert(!Section
->hasEnded() && "Section already ended");
1101 MCSymbol
*Sym
= Section
->getBeginSymbol();
1102 if (Sym
&& !Sym
->isInSection())
1107 MCSymbol
*MCStreamer::endSection(MCSection
*Section
) {
1108 // TODO: keep track of the last subsection so that this symbol appears in the
1110 MCSymbol
*Sym
= Section
->getEndSymbol(Context
);
1111 if (Sym
->isInSection())
1114 SwitchSection(Section
);
1119 void MCStreamer::EmitVersionForTarget(const Triple
&Target
,
1120 const VersionTuple
&SDKVersion
) {
1121 if (!Target
.isOSBinFormatMachO() || !Target
.isOSDarwin())
1123 // Do we even know the version?
1124 if (Target
.getOSMajorVersion() == 0)
1130 if (Target
.isMacCatalystEnvironment()) {
1131 // Mac Catalyst always uses the build version load command.
1132 Target
.getiOSVersion(Major
, Minor
, Update
);
1133 assert(Major
&& "A non-zero major version is expected");
1134 EmitBuildVersion(MachO::PLATFORM_MACCATALYST
, Major
, Minor
, Update
,
1139 MCVersionMinType VersionType
;
1140 if (Target
.isWatchOS()) {
1141 VersionType
= MCVM_WatchOSVersionMin
;
1142 Target
.getWatchOSVersion(Major
, Minor
, Update
);
1143 } else if (Target
.isTvOS()) {
1144 VersionType
= MCVM_TvOSVersionMin
;
1145 Target
.getiOSVersion(Major
, Minor
, Update
);
1146 } else if (Target
.isMacOSX()) {
1147 VersionType
= MCVM_OSXVersionMin
;
1148 if (!Target
.getMacOSXVersion(Major
, Minor
, Update
))
1151 VersionType
= MCVM_IOSVersionMin
;
1152 Target
.getiOSVersion(Major
, Minor
, Update
);
1155 EmitVersionMin(VersionType
, Major
, Minor
, Update
, SDKVersion
);