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/DebugInfo/CodeView/SymbolRecord.h"
16 #include "llvm/MC/MCAsmBackend.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCCodeView.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCDwarf.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstPrinter.h"
24 #include "llvm/MC/MCObjectFileInfo.h"
25 #include "llvm/MC/MCRegister.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCSection.h"
28 #include "llvm/MC/MCSectionCOFF.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/MC/MCWin64EH.h"
31 #include "llvm/MC/MCWinEH.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/LEB128.h"
35 #include "llvm/Support/MathExtras.h"
36 #include "llvm/Support/raw_ostream.h"
44 MCTargetStreamer::MCTargetStreamer(MCStreamer
&S
) : Streamer(S
) {
45 S
.setTargetStreamer(this);
48 // Pin the vtables to this file.
49 MCTargetStreamer::~MCTargetStreamer() = default;
51 void MCTargetStreamer::emitLabel(MCSymbol
*Symbol
) {}
53 void MCTargetStreamer::finish() {}
55 void MCTargetStreamer::changeSection(const MCSection
*CurSection
,
57 const MCExpr
*Subsection
,
59 Section
->PrintSwitchToSection(
60 *Streamer
.getContext().getAsmInfo(),
61 Streamer
.getContext().getObjectFileInfo()->getTargetTriple(), OS
,
65 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive
) {
66 Streamer
.EmitRawText(Directive
);
69 void MCTargetStreamer::emitValue(const MCExpr
*Value
) {
71 raw_svector_ostream
OS(Str
);
73 Value
->print(OS
, Streamer
.getContext().getAsmInfo());
74 Streamer
.EmitRawText(OS
.str());
77 void MCTargetStreamer::emitRawBytes(StringRef Data
) {
78 const MCAsmInfo
*MAI
= Streamer
.getContext().getAsmInfo();
79 const char *Directive
= MAI
->getData8bitsDirective();
80 for (const unsigned char C
: Data
.bytes()) {
82 raw_svector_ostream
OS(Str
);
84 OS
<< Directive
<< (unsigned)C
;
85 Streamer
.EmitRawText(OS
.str());
89 void MCTargetStreamer::emitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {}
91 MCStreamer::MCStreamer(MCContext
&Ctx
)
92 : Context(Ctx
), CurrentWinFrameInfo(nullptr),
93 UseAssemblerInfoForParsing(false) {
94 SectionStack
.push_back(std::pair
<MCSectionSubPair
, MCSectionSubPair
>());
97 MCStreamer::~MCStreamer() {}
99 void MCStreamer::reset() {
100 DwarfFrameInfos
.clear();
101 CurrentWinFrameInfo
= nullptr;
102 WinFrameInfos
.clear();
103 SymbolOrdering
.clear();
104 SectionStack
.clear();
105 SectionStack
.push_back(std::pair
<MCSectionSubPair
, MCSectionSubPair
>());
108 raw_ostream
&MCStreamer::GetCommentOS() {
109 // By default, discard comments.
113 unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos
.size(); }
114 ArrayRef
<MCDwarfFrameInfo
> MCStreamer::getDwarfFrameInfos() const {
115 return DwarfFrameInfos
;
118 void MCStreamer::emitRawComment(const Twine
&T
, bool TabPrefix
) {}
120 void MCStreamer::addExplicitComment(const Twine
&T
) {}
121 void MCStreamer::emitExplicitComments() {}
123 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend
*MAB
) {
124 for (auto &FI
: DwarfFrameInfos
)
125 FI
.CompactUnwindEncoding
=
126 (MAB
? MAB
->generateCompactUnwindEncoding(FI
.Instructions
) : 0);
129 /// EmitIntValue - Special case of EmitValue that avoids the client having to
130 /// pass in a MCExpr for constant integers.
131 void MCStreamer::EmitIntValue(uint64_t Value
, unsigned Size
) {
132 assert(1 <= Size
&& Size
<= 8 && "Invalid size");
133 assert((isUIntN(8 * Size
, Value
) || isIntN(8 * Size
, Value
)) &&
136 const bool isLittleEndian
= Context
.getAsmInfo()->isLittleEndian();
137 for (unsigned i
= 0; i
!= Size
; ++i
) {
138 unsigned index
= isLittleEndian
? i
: (Size
- i
- 1);
139 buf
[i
] = uint8_t(Value
>> (index
* 8));
141 EmitBytes(StringRef(buf
, Size
));
144 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
145 /// client having to pass in a MCExpr for constant integers.
146 void MCStreamer::EmitULEB128IntValue(uint64_t Value
, unsigned PadTo
) {
147 SmallString
<128> Tmp
;
148 raw_svector_ostream
OSE(Tmp
);
149 encodeULEB128(Value
, OSE
, PadTo
);
150 EmitBytes(OSE
.str());
153 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
154 /// client having to pass in a MCExpr for constant integers.
155 void MCStreamer::EmitSLEB128IntValue(int64_t Value
) {
156 SmallString
<128> Tmp
;
157 raw_svector_ostream
OSE(Tmp
);
158 encodeSLEB128(Value
, OSE
);
159 EmitBytes(OSE
.str());
162 void MCStreamer::EmitValue(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
163 EmitValueImpl(Value
, Size
, Loc
);
166 void MCStreamer::EmitSymbolValue(const MCSymbol
*Sym
, unsigned Size
,
167 bool IsSectionRelative
) {
168 assert((!IsSectionRelative
|| Size
== 4) &&
169 "SectionRelative value requires 4-bytes");
171 if (!IsSectionRelative
)
172 EmitValueImpl(MCSymbolRefExpr::create(Sym
, getContext()), Size
);
174 EmitCOFFSecRel32(Sym
, /*Offset=*/0);
177 void MCStreamer::EmitDTPRel64Value(const MCExpr
*Value
) {
178 report_fatal_error("unsupported directive in streamer");
181 void MCStreamer::EmitDTPRel32Value(const MCExpr
*Value
) {
182 report_fatal_error("unsupported directive in streamer");
185 void MCStreamer::EmitTPRel64Value(const MCExpr
*Value
) {
186 report_fatal_error("unsupported directive in streamer");
189 void MCStreamer::EmitTPRel32Value(const MCExpr
*Value
) {
190 report_fatal_error("unsupported directive in streamer");
193 void MCStreamer::EmitGPRel64Value(const MCExpr
*Value
) {
194 report_fatal_error("unsupported directive in streamer");
197 void MCStreamer::EmitGPRel32Value(const MCExpr
*Value
) {
198 report_fatal_error("unsupported directive in streamer");
201 /// Emit NumBytes bytes worth of the value specified by FillValue.
202 /// This implements directives such as '.space'.
203 void MCStreamer::emitFill(uint64_t NumBytes
, uint8_t FillValue
) {
204 emitFill(*MCConstantExpr::create(NumBytes
, getContext()), FillValue
);
207 /// The implementation in this class just redirects to emitFill.
208 void MCStreamer::EmitZeros(uint64_t NumBytes
) {
209 emitFill(NumBytes
, 0);
213 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo
, StringRef Directory
,
215 Optional
<MD5::MD5Result
> Checksum
,
216 Optional
<StringRef
> Source
,
218 return getContext().getDwarfFile(Directory
, Filename
, FileNo
, Checksum
,
222 void MCStreamer::emitDwarfFile0Directive(StringRef Directory
,
224 Optional
<MD5::MD5Result
> Checksum
,
225 Optional
<StringRef
> Source
,
227 getContext().setMCLineTableRootFile(CUID
, Directory
, Filename
, Checksum
,
231 void MCStreamer::EmitCFIBKeyFrame() {
232 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
235 CurFrame
->IsBKeyFrame
= true;
238 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo
, unsigned Line
,
239 unsigned Column
, unsigned Flags
,
241 unsigned Discriminator
,
242 StringRef FileName
) {
243 getContext().setCurrentDwarfLoc(FileNo
, Line
, Column
, Flags
, Isa
,
247 MCSymbol
*MCStreamer::getDwarfLineTableSymbol(unsigned CUID
) {
248 MCDwarfLineTable
&Table
= getContext().getMCDwarfLineTable(CUID
);
249 if (!Table
.getLabel()) {
250 StringRef Prefix
= Context
.getAsmInfo()->getPrivateGlobalPrefix();
252 Context
.getOrCreateSymbol(Prefix
+ "line_table_start" + Twine(CUID
)));
254 return Table
.getLabel();
257 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
258 return !DwarfFrameInfos
.empty() && !DwarfFrameInfos
.back().End
;
261 MCDwarfFrameInfo
*MCStreamer::getCurrentDwarfFrameInfo() {
262 if (!hasUnfinishedDwarfFrameInfo()) {
263 getContext().reportError(SMLoc(), "this directive must appear between "
264 ".cfi_startproc and .cfi_endproc "
268 return &DwarfFrameInfos
.back();
271 bool MCStreamer::EmitCVFileDirective(unsigned FileNo
, StringRef Filename
,
272 ArrayRef
<uint8_t> Checksum
,
273 unsigned ChecksumKind
) {
274 return getContext().getCVContext().addFile(*this, FileNo
, Filename
, Checksum
,
278 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId
) {
279 return getContext().getCVContext().recordFunctionId(FunctionId
);
282 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId
,
283 unsigned IAFunc
, unsigned IAFile
,
284 unsigned IALine
, unsigned IACol
,
286 if (getContext().getCVContext().getCVFunctionInfo(IAFunc
) == nullptr) {
287 getContext().reportError(Loc
, "parent function id not introduced by "
288 ".cv_func_id or .cv_inline_site_id");
292 return getContext().getCVContext().recordInlinedCallSiteId(
293 FunctionId
, IAFunc
, IAFile
, IALine
, IACol
);
296 void MCStreamer::EmitCVLocDirective(unsigned FunctionId
, unsigned FileNo
,
297 unsigned Line
, unsigned Column
,
298 bool PrologueEnd
, bool IsStmt
,
299 StringRef FileName
, SMLoc Loc
) {}
301 bool MCStreamer::checkCVLocSection(unsigned FuncId
, unsigned FileNo
,
303 CodeViewContext
&CVC
= getContext().getCVContext();
304 MCCVFunctionInfo
*FI
= CVC
.getCVFunctionInfo(FuncId
);
306 getContext().reportError(
307 Loc
, "function id not introduced by .cv_func_id or .cv_inline_site_id");
312 if (FI
->Section
== nullptr)
313 FI
->Section
= getCurrentSectionOnly();
314 else if (FI
->Section
!= getCurrentSectionOnly()) {
315 getContext().reportError(
317 "all .cv_loc directives for a function must be in the same section");
323 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId
,
324 const MCSymbol
*Begin
,
325 const MCSymbol
*End
) {}
327 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId
,
328 unsigned SourceFileId
,
329 unsigned SourceLineNum
,
330 const MCSymbol
*FnStartSym
,
331 const MCSymbol
*FnEndSym
) {}
333 /// Only call this on endian-specific types like ulittle16_t and little32_t, or
334 /// structs composed of them.
335 template <typename T
>
336 static void copyBytesForDefRange(SmallString
<20> &BytePrefix
,
337 codeview::SymbolKind SymKind
,
338 const T
&DefRangeHeader
) {
339 BytePrefix
.resize(2 + sizeof(T
));
340 codeview::ulittle16_t SymKindLE
= codeview::ulittle16_t(SymKind
);
341 memcpy(&BytePrefix
[0], &SymKindLE
, 2);
342 memcpy(&BytePrefix
[2], &DefRangeHeader
, sizeof(T
));
345 void MCStreamer::EmitCVDefRangeDirective(
346 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
347 StringRef FixedSizePortion
) {}
349 void MCStreamer::EmitCVDefRangeDirective(
350 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
351 codeview::DefRangeRegisterRelHeader DRHdr
) {
352 SmallString
<20> BytePrefix
;
353 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_REGISTER_REL
, DRHdr
);
354 EmitCVDefRangeDirective(Ranges
, BytePrefix
);
357 void MCStreamer::EmitCVDefRangeDirective(
358 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
359 codeview::DefRangeSubfieldRegisterHeader DRHdr
) {
360 SmallString
<20> BytePrefix
;
361 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_SUBFIELD_REGISTER
,
363 EmitCVDefRangeDirective(Ranges
, BytePrefix
);
366 void MCStreamer::EmitCVDefRangeDirective(
367 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
368 codeview::DefRangeRegisterHeader DRHdr
) {
369 SmallString
<20> BytePrefix
;
370 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_REGISTER
, DRHdr
);
371 EmitCVDefRangeDirective(Ranges
, BytePrefix
);
374 void MCStreamer::EmitCVDefRangeDirective(
375 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
376 codeview::DefRangeFramePointerRelHeader DRHdr
) {
377 SmallString
<20> BytePrefix
;
378 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_FRAMEPOINTER_REL
,
380 EmitCVDefRangeDirective(Ranges
, BytePrefix
);
383 void MCStreamer::EmitEHSymAttributes(const MCSymbol
*Symbol
,
384 MCSymbol
*EHSymbol
) {
387 void MCStreamer::InitSections(bool NoExecStack
) {
388 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
391 void MCStreamer::AssignFragment(MCSymbol
*Symbol
, MCFragment
*Fragment
) {
393 Symbol
->setFragment(Fragment
);
395 // As we emit symbols into a section, track the order so that they can
396 // be sorted upon later. Zero is reserved to mean 'unemitted'.
397 SymbolOrdering
[Symbol
] = 1 + SymbolOrdering
.size();
400 void MCStreamer::EmitLabel(MCSymbol
*Symbol
, SMLoc Loc
) {
401 Symbol
->redefineIfPossible();
403 if (!Symbol
->isUndefined() || Symbol
->isVariable())
404 return getContext().reportError(Loc
, "invalid symbol redefinition");
406 assert(!Symbol
->isVariable() && "Cannot emit a variable symbol!");
407 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
408 assert(!Symbol
->getFragment() && "Unexpected fragment on symbol data!");
409 assert(Symbol
->isUndefined() && "Cannot define a symbol twice!");
411 Symbol
->setFragment(&getCurrentSectionOnly()->getDummyFragment());
413 MCTargetStreamer
*TS
= getTargetStreamer();
415 TS
->emitLabel(Symbol
);
418 void MCStreamer::EmitCFISections(bool EH
, bool Debug
) {
422 void MCStreamer::EmitCFIStartProc(bool IsSimple
, SMLoc Loc
) {
423 if (hasUnfinishedDwarfFrameInfo())
424 return getContext().reportError(
425 Loc
, "starting new .cfi frame before finishing the previous one");
427 MCDwarfFrameInfo Frame
;
428 Frame
.IsSimple
= IsSimple
;
429 EmitCFIStartProcImpl(Frame
);
431 const MCAsmInfo
* MAI
= Context
.getAsmInfo();
433 for (const MCCFIInstruction
& Inst
: MAI
->getInitialFrameState()) {
434 if (Inst
.getOperation() == MCCFIInstruction::OpDefCfa
||
435 Inst
.getOperation() == MCCFIInstruction::OpDefCfaRegister
) {
436 Frame
.CurrentCfaRegister
= Inst
.getRegister();
441 DwarfFrameInfos
.push_back(Frame
);
444 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) {
447 void MCStreamer::EmitCFIEndProc() {
448 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
451 EmitCFIEndProcImpl(*CurFrame
);
454 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) {
455 // Put a dummy non-null value in Frame.End to mark that this frame has been
457 Frame
.End
= (MCSymbol
*)1;
460 MCSymbol
*MCStreamer::EmitCFILabel() {
461 // Return a dummy non-null value so that label fields appear filled in when
462 // generating textual assembly.
463 return (MCSymbol
*)1;
466 void MCStreamer::EmitCFIDefCfa(int64_t Register
, int64_t Offset
) {
467 MCSymbol
*Label
= EmitCFILabel();
468 MCCFIInstruction Instruction
=
469 MCCFIInstruction::createDefCfa(Label
, Register
, Offset
);
470 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
473 CurFrame
->Instructions
.push_back(Instruction
);
474 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
477 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset
) {
478 MCSymbol
*Label
= EmitCFILabel();
479 MCCFIInstruction Instruction
=
480 MCCFIInstruction::createDefCfaOffset(Label
, Offset
);
481 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
484 CurFrame
->Instructions
.push_back(Instruction
);
487 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment
) {
488 MCSymbol
*Label
= EmitCFILabel();
489 MCCFIInstruction Instruction
=
490 MCCFIInstruction::createAdjustCfaOffset(Label
, Adjustment
);
491 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
494 CurFrame
->Instructions
.push_back(Instruction
);
497 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register
) {
498 MCSymbol
*Label
= EmitCFILabel();
499 MCCFIInstruction Instruction
=
500 MCCFIInstruction::createDefCfaRegister(Label
, Register
);
501 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
504 CurFrame
->Instructions
.push_back(Instruction
);
505 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
508 void MCStreamer::EmitCFIOffset(int64_t Register
, int64_t Offset
) {
509 MCSymbol
*Label
= EmitCFILabel();
510 MCCFIInstruction Instruction
=
511 MCCFIInstruction::createOffset(Label
, Register
, Offset
);
512 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
515 CurFrame
->Instructions
.push_back(Instruction
);
518 void MCStreamer::EmitCFIRelOffset(int64_t Register
, int64_t Offset
) {
519 MCSymbol
*Label
= EmitCFILabel();
520 MCCFIInstruction Instruction
=
521 MCCFIInstruction::createRelOffset(Label
, Register
, Offset
);
522 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
525 CurFrame
->Instructions
.push_back(Instruction
);
528 void MCStreamer::EmitCFIPersonality(const MCSymbol
*Sym
,
530 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
533 CurFrame
->Personality
= Sym
;
534 CurFrame
->PersonalityEncoding
= Encoding
;
537 void MCStreamer::EmitCFILsda(const MCSymbol
*Sym
, unsigned Encoding
) {
538 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
541 CurFrame
->Lsda
= Sym
;
542 CurFrame
->LsdaEncoding
= Encoding
;
545 void MCStreamer::EmitCFIRememberState() {
546 MCSymbol
*Label
= EmitCFILabel();
547 MCCFIInstruction Instruction
= MCCFIInstruction::createRememberState(Label
);
548 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
551 CurFrame
->Instructions
.push_back(Instruction
);
554 void MCStreamer::EmitCFIRestoreState() {
555 // FIXME: Error if there is no matching cfi_remember_state.
556 MCSymbol
*Label
= EmitCFILabel();
557 MCCFIInstruction Instruction
= MCCFIInstruction::createRestoreState(Label
);
558 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
561 CurFrame
->Instructions
.push_back(Instruction
);
564 void MCStreamer::EmitCFISameValue(int64_t Register
) {
565 MCSymbol
*Label
= EmitCFILabel();
566 MCCFIInstruction Instruction
=
567 MCCFIInstruction::createSameValue(Label
, Register
);
568 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
571 CurFrame
->Instructions
.push_back(Instruction
);
574 void MCStreamer::EmitCFIRestore(int64_t Register
) {
575 MCSymbol
*Label
= EmitCFILabel();
576 MCCFIInstruction Instruction
=
577 MCCFIInstruction::createRestore(Label
, Register
);
578 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
581 CurFrame
->Instructions
.push_back(Instruction
);
584 void MCStreamer::EmitCFIEscape(StringRef Values
) {
585 MCSymbol
*Label
= EmitCFILabel();
586 MCCFIInstruction Instruction
= MCCFIInstruction::createEscape(Label
, Values
);
587 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
590 CurFrame
->Instructions
.push_back(Instruction
);
593 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size
) {
594 MCSymbol
*Label
= EmitCFILabel();
595 MCCFIInstruction Instruction
=
596 MCCFIInstruction::createGnuArgsSize(Label
, Size
);
597 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
600 CurFrame
->Instructions
.push_back(Instruction
);
603 void MCStreamer::EmitCFISignalFrame() {
604 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
607 CurFrame
->IsSignalFrame
= true;
610 void MCStreamer::EmitCFIUndefined(int64_t Register
) {
611 MCSymbol
*Label
= EmitCFILabel();
612 MCCFIInstruction Instruction
=
613 MCCFIInstruction::createUndefined(Label
, Register
);
614 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
617 CurFrame
->Instructions
.push_back(Instruction
);
620 void MCStreamer::EmitCFIRegister(int64_t Register1
, int64_t Register2
) {
621 MCSymbol
*Label
= EmitCFILabel();
622 MCCFIInstruction Instruction
=
623 MCCFIInstruction::createRegister(Label
, Register1
, Register2
);
624 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
627 CurFrame
->Instructions
.push_back(Instruction
);
630 void MCStreamer::EmitCFIWindowSave() {
631 MCSymbol
*Label
= EmitCFILabel();
632 MCCFIInstruction Instruction
=
633 MCCFIInstruction::createWindowSave(Label
);
634 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
637 CurFrame
->Instructions
.push_back(Instruction
);
640 void MCStreamer::EmitCFINegateRAState() {
641 MCSymbol
*Label
= EmitCFILabel();
642 MCCFIInstruction Instruction
= MCCFIInstruction::createNegateRAState(Label
);
643 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
646 CurFrame
->Instructions
.push_back(Instruction
);
649 void MCStreamer::EmitCFIReturnColumn(int64_t Register
) {
650 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
653 CurFrame
->RAReg
= Register
;
656 WinEH::FrameInfo
*MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc
) {
657 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
658 if (!MAI
->usesWindowsCFI()) {
659 getContext().reportError(
660 Loc
, ".seh_* directives are not supported on this target");
663 if (!CurrentWinFrameInfo
|| CurrentWinFrameInfo
->End
) {
664 getContext().reportError(
665 Loc
, ".seh_ directive must appear within an active frame");
668 return CurrentWinFrameInfo
;
671 void MCStreamer::EmitWinCFIStartProc(const MCSymbol
*Symbol
, SMLoc Loc
) {
672 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
673 if (!MAI
->usesWindowsCFI())
674 return getContext().reportError(
675 Loc
, ".seh_* directives are not supported on this target");
676 if (CurrentWinFrameInfo
&& !CurrentWinFrameInfo
->End
)
677 getContext().reportError(
678 Loc
, "Starting a function before ending the previous one!");
680 MCSymbol
*StartProc
= EmitCFILabel();
682 WinFrameInfos
.emplace_back(
683 std::make_unique
<WinEH::FrameInfo
>(Symbol
, StartProc
));
684 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
685 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
688 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc
) {
689 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
692 if (CurFrame
->ChainedParent
)
693 getContext().reportError(Loc
, "Not all chained regions terminated!");
695 MCSymbol
*Label
= EmitCFILabel();
696 CurFrame
->End
= Label
;
699 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc
) {
700 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
703 if (CurFrame
->ChainedParent
)
704 getContext().reportError(Loc
, "Not all chained regions terminated!");
706 MCSymbol
*Label
= EmitCFILabel();
707 CurFrame
->FuncletOrFuncEnd
= Label
;
710 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc
) {
711 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
715 MCSymbol
*StartProc
= EmitCFILabel();
717 WinFrameInfos
.emplace_back(std::make_unique
<WinEH::FrameInfo
>(
718 CurFrame
->Function
, StartProc
, CurFrame
));
719 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
720 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
723 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc
) {
724 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
727 if (!CurFrame
->ChainedParent
)
728 return getContext().reportError(
729 Loc
, "End of a chained region outside a chained region!");
731 MCSymbol
*Label
= EmitCFILabel();
733 CurFrame
->End
= Label
;
734 CurrentWinFrameInfo
= const_cast<WinEH::FrameInfo
*>(CurFrame
->ChainedParent
);
737 void MCStreamer::EmitWinEHHandler(const MCSymbol
*Sym
, bool Unwind
, bool Except
,
739 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
742 if (CurFrame
->ChainedParent
)
743 return getContext().reportError(
744 Loc
, "Chained unwind areas can't have handlers!");
745 CurFrame
->ExceptionHandler
= Sym
;
746 if (!Except
&& !Unwind
)
747 getContext().reportError(Loc
, "Don't know what kind of handler this is!");
749 CurFrame
->HandlesUnwind
= true;
751 CurFrame
->HandlesExceptions
= true;
754 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc
) {
755 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
758 if (CurFrame
->ChainedParent
)
759 getContext().reportError(Loc
, "Chained unwind areas can't have handlers!");
762 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr
*From
,
763 const MCSymbolRefExpr
*To
, uint64_t Count
) {
766 static MCSection
*getWinCFISection(MCContext
&Context
, unsigned *NextWinCFIID
,
767 MCSection
*MainCFISec
,
768 const MCSection
*TextSec
) {
769 // If this is the main .text section, use the main unwind info section.
770 if (TextSec
== Context
.getObjectFileInfo()->getTextSection())
773 const auto *TextSecCOFF
= cast
<MCSectionCOFF
>(TextSec
);
774 auto *MainCFISecCOFF
= cast
<MCSectionCOFF
>(MainCFISec
);
775 unsigned UniqueID
= TextSecCOFF
->getOrAssignWinCFISectionID(NextWinCFIID
);
777 // If this section is COMDAT, this unwind section should be COMDAT associative
779 const MCSymbol
*KeySym
= nullptr;
780 if (TextSecCOFF
->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT
) {
781 KeySym
= TextSecCOFF
->getCOMDATSymbol();
783 // In a GNU environment, we can't use associative comdats. Instead, do what
784 // GCC does, which is to make plain comdat selectany section named like
785 // ".[px]data$_Z3foov".
786 if (!Context
.getAsmInfo()->hasCOFFAssociativeComdats()) {
787 std::string SectionName
=
788 (MainCFISecCOFF
->getSectionName() + "$" +
789 TextSecCOFF
->getSectionName().split('$').second
)
791 return Context
.getCOFFSection(
793 MainCFISecCOFF
->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT
,
794 MainCFISecCOFF
->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY
);
798 return Context
.getAssociativeCOFFSection(MainCFISecCOFF
, KeySym
, UniqueID
);
801 MCSection
*MCStreamer::getAssociatedPDataSection(const MCSection
*TextSec
) {
802 return getWinCFISection(getContext(), &NextWinCFIID
,
803 getContext().getObjectFileInfo()->getPDataSection(),
807 MCSection
*MCStreamer::getAssociatedXDataSection(const MCSection
*TextSec
) {
808 return getWinCFISection(getContext(), &NextWinCFIID
,
809 getContext().getObjectFileInfo()->getXDataSection(),
813 void MCStreamer::EmitSyntaxDirective() {}
815 static unsigned encodeSEHRegNum(MCContext
&Ctx
, MCRegister Reg
) {
816 return Ctx
.getRegisterInfo()->getSEHRegNum(Reg
);
819 void MCStreamer::EmitWinCFIPushReg(MCRegister Register
, SMLoc Loc
) {
820 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
824 MCSymbol
*Label
= EmitCFILabel();
826 WinEH::Instruction Inst
= Win64EH::Instruction::PushNonVol(
827 Label
, encodeSEHRegNum(Context
, Register
));
828 CurFrame
->Instructions
.push_back(Inst
);
831 void MCStreamer::EmitWinCFISetFrame(MCRegister Register
, unsigned Offset
,
833 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
836 if (CurFrame
->LastFrameInst
>= 0)
837 return getContext().reportError(
838 Loc
, "frame register and offset can be set at most once");
840 return getContext().reportError(Loc
, "offset is not a multiple of 16");
842 return getContext().reportError(
843 Loc
, "frame offset must be less than or equal to 240");
845 MCSymbol
*Label
= EmitCFILabel();
847 WinEH::Instruction Inst
= Win64EH::Instruction::SetFPReg(
848 Label
, encodeSEHRegNum(getContext(), Register
), Offset
);
849 CurFrame
->LastFrameInst
= CurFrame
->Instructions
.size();
850 CurFrame
->Instructions
.push_back(Inst
);
853 void MCStreamer::EmitWinCFIAllocStack(unsigned Size
, SMLoc Loc
) {
854 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
858 return getContext().reportError(Loc
,
859 "stack allocation size must be non-zero");
861 return getContext().reportError(
862 Loc
, "stack allocation size is not a multiple of 8");
864 MCSymbol
*Label
= EmitCFILabel();
866 WinEH::Instruction Inst
= Win64EH::Instruction::Alloc(Label
, Size
);
867 CurFrame
->Instructions
.push_back(Inst
);
870 void MCStreamer::EmitWinCFISaveReg(MCRegister Register
, unsigned Offset
,
872 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
877 return getContext().reportError(
878 Loc
, "register save offset is not 8 byte aligned");
880 MCSymbol
*Label
= EmitCFILabel();
882 WinEH::Instruction Inst
= Win64EH::Instruction::SaveNonVol(
883 Label
, encodeSEHRegNum(Context
, Register
), Offset
);
884 CurFrame
->Instructions
.push_back(Inst
);
887 void MCStreamer::EmitWinCFISaveXMM(MCRegister Register
, unsigned Offset
,
889 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
893 return getContext().reportError(Loc
, "offset is not a multiple of 16");
895 MCSymbol
*Label
= EmitCFILabel();
897 WinEH::Instruction Inst
= Win64EH::Instruction::SaveXMM(
898 Label
, encodeSEHRegNum(Context
, Register
), Offset
);
899 CurFrame
->Instructions
.push_back(Inst
);
902 void MCStreamer::EmitWinCFIPushFrame(bool Code
, SMLoc Loc
) {
903 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
906 if (!CurFrame
->Instructions
.empty())
907 return getContext().reportError(
908 Loc
, "If present, PushMachFrame must be the first UOP");
910 MCSymbol
*Label
= EmitCFILabel();
912 WinEH::Instruction Inst
= Win64EH::Instruction::PushMachFrame(Label
, Code
);
913 CurFrame
->Instructions
.push_back(Inst
);
916 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc
) {
917 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
921 MCSymbol
*Label
= EmitCFILabel();
923 CurFrame
->PrologEnd
= Label
;
926 void MCStreamer::EmitCOFFSafeSEH(MCSymbol
const *Symbol
) {}
928 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol
const *Symbol
) {}
930 void MCStreamer::EmitCOFFSectionIndex(MCSymbol
const *Symbol
) {}
932 void MCStreamer::EmitCOFFSecRel32(MCSymbol
const *Symbol
, uint64_t Offset
) {}
934 void MCStreamer::EmitCOFFImgRel32(MCSymbol
const *Symbol
, int64_t Offset
) {}
936 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
937 /// the specified string in the output .s file. This capability is
938 /// indicated by the hasRawTextSupport() predicate.
939 void MCStreamer::EmitRawTextImpl(StringRef String
) {
940 // This is not llvm_unreachable for the sake of out of tree backend
941 // developers who may not have assembly streamers and should serve as a
942 // reminder to not accidentally call EmitRawText in the absence of such.
943 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
944 "it (target backend is likely missing an AsmStreamer "
948 void MCStreamer::EmitRawText(const Twine
&T
) {
949 SmallString
<128> Str
;
950 EmitRawTextImpl(T
.toStringRef(Str
));
953 void MCStreamer::EmitWindowsUnwindTables() {
956 void MCStreamer::Finish() {
957 if ((!DwarfFrameInfos
.empty() && !DwarfFrameInfos
.back().End
) ||
958 (!WinFrameInfos
.empty() && !WinFrameInfos
.back()->End
)) {
959 getContext().reportError(SMLoc(), "Unfinished frame!");
963 MCTargetStreamer
*TS
= getTargetStreamer();
970 void MCStreamer::EmitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {
971 visitUsedExpr(*Value
);
972 Symbol
->setVariableValue(Value
);
974 MCTargetStreamer
*TS
= getTargetStreamer();
976 TS
->emitAssignment(Symbol
, Value
);
979 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter
&InstPrinter
,
980 raw_ostream
&OS
, const MCInst
&Inst
,
981 const MCSubtargetInfo
&STI
) {
982 InstPrinter
.printInst(&Inst
, OS
, "", STI
);
985 void MCStreamer::visitUsedSymbol(const MCSymbol
&Sym
) {
988 void MCStreamer::visitUsedExpr(const MCExpr
&Expr
) {
989 switch (Expr
.getKind()) {
991 cast
<MCTargetExpr
>(Expr
).visitUsedExpr(*this);
994 case MCExpr::Constant
:
997 case MCExpr::Binary
: {
998 const MCBinaryExpr
&BE
= cast
<MCBinaryExpr
>(Expr
);
999 visitUsedExpr(*BE
.getLHS());
1000 visitUsedExpr(*BE
.getRHS());
1004 case MCExpr::SymbolRef
:
1005 visitUsedSymbol(cast
<MCSymbolRefExpr
>(Expr
).getSymbol());
1009 visitUsedExpr(*cast
<MCUnaryExpr
>(Expr
).getSubExpr());
1014 void MCStreamer::EmitInstruction(const MCInst
&Inst
, const MCSubtargetInfo
&) {
1016 for (unsigned i
= Inst
.getNumOperands(); i
--;)
1017 if (Inst
.getOperand(i
).isExpr())
1018 visitUsedExpr(*Inst
.getOperand(i
).getExpr());
1021 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol
*Hi
, const MCSymbol
*Lo
,
1023 // Get the Hi-Lo expression.
1024 const MCExpr
*Diff
=
1025 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
1026 MCSymbolRefExpr::create(Lo
, Context
), Context
);
1028 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
1029 if (!MAI
->doesSetDirectiveSuppressReloc()) {
1030 EmitValue(Diff
, Size
);
1034 // Otherwise, emit with .set (aka assignment).
1035 MCSymbol
*SetLabel
= Context
.createTempSymbol("set", true);
1036 EmitAssignment(SetLabel
, Diff
);
1037 EmitSymbolValue(SetLabel
, Size
);
1040 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol
*Hi
,
1041 const MCSymbol
*Lo
) {
1042 // Get the Hi-Lo expression.
1043 const MCExpr
*Diff
=
1044 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
1045 MCSymbolRefExpr::create(Lo
, Context
), Context
);
1047 EmitULEB128Value(Diff
);
1050 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag
) {}
1051 void MCStreamer::EmitThumbFunc(MCSymbol
*Func
) {}
1052 void MCStreamer::EmitSymbolDesc(MCSymbol
*Symbol
, unsigned DescValue
) {}
1053 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol
*Symbol
) {
1054 llvm_unreachable("this directive only supported on COFF targets");
1056 void MCStreamer::EndCOFFSymbolDef() {
1057 llvm_unreachable("this directive only supported on COFF targets");
1059 void MCStreamer::EmitFileDirective(StringRef Filename
) {}
1060 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass
) {
1061 llvm_unreachable("this directive only supported on COFF targets");
1063 void MCStreamer::EmitCOFFSymbolType(int Type
) {
1064 llvm_unreachable("this directive only supported on COFF targets");
1066 void MCStreamer::EmitXCOFFLocalCommonSymbol(MCSymbol
*Symbol
, uint64_t Size
,
1067 unsigned ByteAlign
) {
1068 llvm_unreachable("this directive only supported on XCOFF targets");
1070 void MCStreamer::emitELFSize(MCSymbol
*Symbol
, const MCExpr
*Value
) {}
1071 void MCStreamer::emitELFSymverDirective(StringRef AliasName
,
1072 const MCSymbol
*Aliasee
) {}
1073 void MCStreamer::EmitLocalCommonSymbol(MCSymbol
*Symbol
, uint64_t Size
,
1074 unsigned ByteAlignment
) {}
1075 void MCStreamer::EmitTBSSSymbol(MCSection
*Section
, MCSymbol
*Symbol
,
1076 uint64_t Size
, unsigned ByteAlignment
) {}
1077 void MCStreamer::ChangeSection(MCSection
*, const MCExpr
*) {}
1078 void MCStreamer::EmitWeakReference(MCSymbol
*Alias
, const MCSymbol
*Symbol
) {}
1079 void MCStreamer::EmitBytes(StringRef Data
) {}
1080 void MCStreamer::EmitBinaryData(StringRef Data
) { EmitBytes(Data
); }
1081 void MCStreamer::EmitValueImpl(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
1082 visitUsedExpr(*Value
);
1084 void MCStreamer::EmitULEB128Value(const MCExpr
*Value
) {}
1085 void MCStreamer::EmitSLEB128Value(const MCExpr
*Value
) {}
1086 void MCStreamer::emitFill(const MCExpr
&NumBytes
, uint64_t Value
, SMLoc Loc
) {}
1087 void MCStreamer::emitFill(const MCExpr
&NumValues
, int64_t Size
, int64_t Expr
,
1089 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment
, int64_t Value
,
1091 unsigned MaxBytesToEmit
) {}
1092 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment
,
1093 unsigned MaxBytesToEmit
) {}
1094 void MCStreamer::emitValueToOffset(const MCExpr
*Offset
, unsigned char Value
,
1096 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2
) {}
1097 void MCStreamer::EmitBundleLock(bool AlignToEnd
) {}
1098 void MCStreamer::FinishImpl() {}
1099 void MCStreamer::EmitBundleUnlock() {}
1101 void MCStreamer::SwitchSection(MCSection
*Section
, const MCExpr
*Subsection
) {
1102 assert(Section
&& "Cannot switch to a null section!");
1103 MCSectionSubPair curSection
= SectionStack
.back().first
;
1104 SectionStack
.back().second
= curSection
;
1105 if (MCSectionSubPair(Section
, Subsection
) != curSection
) {
1106 ChangeSection(Section
, Subsection
);
1107 SectionStack
.back().first
= MCSectionSubPair(Section
, Subsection
);
1108 assert(!Section
->hasEnded() && "Section already ended");
1109 MCSymbol
*Sym
= Section
->getBeginSymbol();
1110 if (Sym
&& !Sym
->isInSection())
1115 MCSymbol
*MCStreamer::endSection(MCSection
*Section
) {
1116 // TODO: keep track of the last subsection so that this symbol appears in the
1118 MCSymbol
*Sym
= Section
->getEndSymbol(Context
);
1119 if (Sym
->isInSection())
1122 SwitchSection(Section
);
1127 void MCStreamer::EmitVersionForTarget(const Triple
&Target
,
1128 const VersionTuple
&SDKVersion
) {
1129 if (!Target
.isOSBinFormatMachO() || !Target
.isOSDarwin())
1131 // Do we even know the version?
1132 if (Target
.getOSMajorVersion() == 0)
1138 if (Target
.isMacCatalystEnvironment()) {
1139 // Mac Catalyst always uses the build version load command.
1140 Target
.getiOSVersion(Major
, Minor
, Update
);
1141 assert(Major
&& "A non-zero major version is expected");
1142 EmitBuildVersion(MachO::PLATFORM_MACCATALYST
, Major
, Minor
, Update
,
1147 MCVersionMinType VersionType
;
1148 if (Target
.isWatchOS()) {
1149 VersionType
= MCVM_WatchOSVersionMin
;
1150 Target
.getWatchOSVersion(Major
, Minor
, Update
);
1151 } else if (Target
.isTvOS()) {
1152 VersionType
= MCVM_TvOSVersionMin
;
1153 Target
.getiOSVersion(Major
, Minor
, Update
);
1154 } else if (Target
.isMacOSX()) {
1155 VersionType
= MCVM_OSXVersionMin
;
1156 if (!Target
.getMacOSXVersion(Major
, Minor
, Update
))
1159 VersionType
= MCVM_IOSVersionMin
;
1160 Target
.getiOSVersion(Major
, Minor
, Update
);
1163 EmitVersionMin(VersionType
, Major
, Minor
, Update
, SDKVersion
);