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 void MCStreamer::EmitCVDefRangeDirective(
331 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
332 StringRef FixedSizePortion
) {}
334 void MCStreamer::EmitEHSymAttributes(const MCSymbol
*Symbol
,
335 MCSymbol
*EHSymbol
) {
338 void MCStreamer::InitSections(bool NoExecStack
) {
339 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
342 void MCStreamer::AssignFragment(MCSymbol
*Symbol
, MCFragment
*Fragment
) {
344 Symbol
->setFragment(Fragment
);
346 // As we emit symbols into a section, track the order so that they can
347 // be sorted upon later. Zero is reserved to mean 'unemitted'.
348 SymbolOrdering
[Symbol
] = 1 + SymbolOrdering
.size();
351 void MCStreamer::EmitLabel(MCSymbol
*Symbol
, SMLoc Loc
) {
352 Symbol
->redefineIfPossible();
354 if (!Symbol
->isUndefined() || Symbol
->isVariable())
355 return getContext().reportError(Loc
, "invalid symbol redefinition");
357 assert(!Symbol
->isVariable() && "Cannot emit a variable symbol!");
358 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
359 assert(!Symbol
->getFragment() && "Unexpected fragment on symbol data!");
360 assert(Symbol
->isUndefined() && "Cannot define a symbol twice!");
362 Symbol
->setFragment(&getCurrentSectionOnly()->getDummyFragment());
364 MCTargetStreamer
*TS
= getTargetStreamer();
366 TS
->emitLabel(Symbol
);
369 void MCStreamer::EmitCFISections(bool EH
, bool Debug
) {
373 void MCStreamer::EmitCFIStartProc(bool IsSimple
, SMLoc Loc
) {
374 if (hasUnfinishedDwarfFrameInfo())
375 return getContext().reportError(
376 Loc
, "starting new .cfi frame before finishing the previous one");
378 MCDwarfFrameInfo Frame
;
379 Frame
.IsSimple
= IsSimple
;
380 EmitCFIStartProcImpl(Frame
);
382 const MCAsmInfo
* MAI
= Context
.getAsmInfo();
384 for (const MCCFIInstruction
& Inst
: MAI
->getInitialFrameState()) {
385 if (Inst
.getOperation() == MCCFIInstruction::OpDefCfa
||
386 Inst
.getOperation() == MCCFIInstruction::OpDefCfaRegister
) {
387 Frame
.CurrentCfaRegister
= Inst
.getRegister();
392 DwarfFrameInfos
.push_back(Frame
);
395 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) {
398 void MCStreamer::EmitCFIEndProc() {
399 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
402 EmitCFIEndProcImpl(*CurFrame
);
405 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) {
406 // Put a dummy non-null value in Frame.End to mark that this frame has been
408 Frame
.End
= (MCSymbol
*)1;
411 MCSymbol
*MCStreamer::EmitCFILabel() {
412 // Return a dummy non-null value so that label fields appear filled in when
413 // generating textual assembly.
414 return (MCSymbol
*)1;
417 void MCStreamer::EmitCFIDefCfa(int64_t Register
, int64_t Offset
) {
418 MCSymbol
*Label
= EmitCFILabel();
419 MCCFIInstruction Instruction
=
420 MCCFIInstruction::createDefCfa(Label
, Register
, Offset
);
421 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
424 CurFrame
->Instructions
.push_back(Instruction
);
425 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
428 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset
) {
429 MCSymbol
*Label
= EmitCFILabel();
430 MCCFIInstruction Instruction
=
431 MCCFIInstruction::createDefCfaOffset(Label
, Offset
);
432 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
435 CurFrame
->Instructions
.push_back(Instruction
);
438 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment
) {
439 MCSymbol
*Label
= EmitCFILabel();
440 MCCFIInstruction Instruction
=
441 MCCFIInstruction::createAdjustCfaOffset(Label
, Adjustment
);
442 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
445 CurFrame
->Instructions
.push_back(Instruction
);
448 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register
) {
449 MCSymbol
*Label
= EmitCFILabel();
450 MCCFIInstruction Instruction
=
451 MCCFIInstruction::createDefCfaRegister(Label
, Register
);
452 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
455 CurFrame
->Instructions
.push_back(Instruction
);
456 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
459 void MCStreamer::EmitCFIOffset(int64_t Register
, int64_t Offset
) {
460 MCSymbol
*Label
= EmitCFILabel();
461 MCCFIInstruction Instruction
=
462 MCCFIInstruction::createOffset(Label
, Register
, Offset
);
463 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
466 CurFrame
->Instructions
.push_back(Instruction
);
469 void MCStreamer::EmitCFIRelOffset(int64_t Register
, int64_t Offset
) {
470 MCSymbol
*Label
= EmitCFILabel();
471 MCCFIInstruction Instruction
=
472 MCCFIInstruction::createRelOffset(Label
, Register
, Offset
);
473 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
476 CurFrame
->Instructions
.push_back(Instruction
);
479 void MCStreamer::EmitCFIPersonality(const MCSymbol
*Sym
,
481 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
484 CurFrame
->Personality
= Sym
;
485 CurFrame
->PersonalityEncoding
= Encoding
;
488 void MCStreamer::EmitCFILsda(const MCSymbol
*Sym
, unsigned Encoding
) {
489 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
492 CurFrame
->Lsda
= Sym
;
493 CurFrame
->LsdaEncoding
= Encoding
;
496 void MCStreamer::EmitCFIRememberState() {
497 MCSymbol
*Label
= EmitCFILabel();
498 MCCFIInstruction Instruction
= MCCFIInstruction::createRememberState(Label
);
499 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
502 CurFrame
->Instructions
.push_back(Instruction
);
505 void MCStreamer::EmitCFIRestoreState() {
506 // FIXME: Error if there is no matching cfi_remember_state.
507 MCSymbol
*Label
= EmitCFILabel();
508 MCCFIInstruction Instruction
= MCCFIInstruction::createRestoreState(Label
);
509 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
512 CurFrame
->Instructions
.push_back(Instruction
);
515 void MCStreamer::EmitCFISameValue(int64_t Register
) {
516 MCSymbol
*Label
= EmitCFILabel();
517 MCCFIInstruction Instruction
=
518 MCCFIInstruction::createSameValue(Label
, Register
);
519 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
522 CurFrame
->Instructions
.push_back(Instruction
);
525 void MCStreamer::EmitCFIRestore(int64_t Register
) {
526 MCSymbol
*Label
= EmitCFILabel();
527 MCCFIInstruction Instruction
=
528 MCCFIInstruction::createRestore(Label
, Register
);
529 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
532 CurFrame
->Instructions
.push_back(Instruction
);
535 void MCStreamer::EmitCFIEscape(StringRef Values
) {
536 MCSymbol
*Label
= EmitCFILabel();
537 MCCFIInstruction Instruction
= MCCFIInstruction::createEscape(Label
, Values
);
538 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
541 CurFrame
->Instructions
.push_back(Instruction
);
544 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size
) {
545 MCSymbol
*Label
= EmitCFILabel();
546 MCCFIInstruction Instruction
=
547 MCCFIInstruction::createGnuArgsSize(Label
, Size
);
548 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
551 CurFrame
->Instructions
.push_back(Instruction
);
554 void MCStreamer::EmitCFISignalFrame() {
555 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
558 CurFrame
->IsSignalFrame
= true;
561 void MCStreamer::EmitCFIUndefined(int64_t Register
) {
562 MCSymbol
*Label
= EmitCFILabel();
563 MCCFIInstruction Instruction
=
564 MCCFIInstruction::createUndefined(Label
, Register
);
565 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
568 CurFrame
->Instructions
.push_back(Instruction
);
571 void MCStreamer::EmitCFIRegister(int64_t Register1
, int64_t Register2
) {
572 MCSymbol
*Label
= EmitCFILabel();
573 MCCFIInstruction Instruction
=
574 MCCFIInstruction::createRegister(Label
, Register1
, Register2
);
575 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
578 CurFrame
->Instructions
.push_back(Instruction
);
581 void MCStreamer::EmitCFIWindowSave() {
582 MCSymbol
*Label
= EmitCFILabel();
583 MCCFIInstruction Instruction
=
584 MCCFIInstruction::createWindowSave(Label
);
585 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
588 CurFrame
->Instructions
.push_back(Instruction
);
591 void MCStreamer::EmitCFINegateRAState() {
592 MCSymbol
*Label
= EmitCFILabel();
593 MCCFIInstruction Instruction
= MCCFIInstruction::createNegateRAState(Label
);
594 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
597 CurFrame
->Instructions
.push_back(Instruction
);
600 void MCStreamer::EmitCFIReturnColumn(int64_t Register
) {
601 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
604 CurFrame
->RAReg
= Register
;
607 WinEH::FrameInfo
*MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc
) {
608 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
609 if (!MAI
->usesWindowsCFI()) {
610 getContext().reportError(
611 Loc
, ".seh_* directives are not supported on this target");
614 if (!CurrentWinFrameInfo
|| CurrentWinFrameInfo
->End
) {
615 getContext().reportError(
616 Loc
, ".seh_ directive must appear within an active frame");
619 return CurrentWinFrameInfo
;
622 void MCStreamer::EmitWinCFIStartProc(const MCSymbol
*Symbol
, SMLoc Loc
) {
623 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
624 if (!MAI
->usesWindowsCFI())
625 return getContext().reportError(
626 Loc
, ".seh_* directives are not supported on this target");
627 if (CurrentWinFrameInfo
&& !CurrentWinFrameInfo
->End
)
628 getContext().reportError(
629 Loc
, "Starting a function before ending the previous one!");
631 MCSymbol
*StartProc
= EmitCFILabel();
633 WinFrameInfos
.emplace_back(
634 llvm::make_unique
<WinEH::FrameInfo
>(Symbol
, StartProc
));
635 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
636 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
639 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc
) {
640 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
643 if (CurFrame
->ChainedParent
)
644 getContext().reportError(Loc
, "Not all chained regions terminated!");
646 MCSymbol
*Label
= EmitCFILabel();
647 CurFrame
->End
= Label
;
650 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc
) {
651 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
654 if (CurFrame
->ChainedParent
)
655 getContext().reportError(Loc
, "Not all chained regions terminated!");
657 MCSymbol
*Label
= EmitCFILabel();
658 CurFrame
->FuncletOrFuncEnd
= Label
;
661 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc
) {
662 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
666 MCSymbol
*StartProc
= EmitCFILabel();
668 WinFrameInfos
.emplace_back(llvm::make_unique
<WinEH::FrameInfo
>(
669 CurFrame
->Function
, StartProc
, CurFrame
));
670 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
671 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
674 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc
) {
675 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
678 if (!CurFrame
->ChainedParent
)
679 return getContext().reportError(
680 Loc
, "End of a chained region outside a chained region!");
682 MCSymbol
*Label
= EmitCFILabel();
684 CurFrame
->End
= Label
;
685 CurrentWinFrameInfo
= const_cast<WinEH::FrameInfo
*>(CurFrame
->ChainedParent
);
688 void MCStreamer::EmitWinEHHandler(const MCSymbol
*Sym
, bool Unwind
, bool Except
,
690 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
693 if (CurFrame
->ChainedParent
)
694 return getContext().reportError(
695 Loc
, "Chained unwind areas can't have handlers!");
696 CurFrame
->ExceptionHandler
= Sym
;
697 if (!Except
&& !Unwind
)
698 getContext().reportError(Loc
, "Don't know what kind of handler this is!");
700 CurFrame
->HandlesUnwind
= true;
702 CurFrame
->HandlesExceptions
= true;
705 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc
) {
706 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
709 if (CurFrame
->ChainedParent
)
710 getContext().reportError(Loc
, "Chained unwind areas can't have handlers!");
713 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr
*From
,
714 const MCSymbolRefExpr
*To
, uint64_t Count
) {
717 static MCSection
*getWinCFISection(MCContext
&Context
, unsigned *NextWinCFIID
,
718 MCSection
*MainCFISec
,
719 const MCSection
*TextSec
) {
720 // If this is the main .text section, use the main unwind info section.
721 if (TextSec
== Context
.getObjectFileInfo()->getTextSection())
724 const auto *TextSecCOFF
= cast
<MCSectionCOFF
>(TextSec
);
725 auto *MainCFISecCOFF
= cast
<MCSectionCOFF
>(MainCFISec
);
726 unsigned UniqueID
= TextSecCOFF
->getOrAssignWinCFISectionID(NextWinCFIID
);
728 // If this section is COMDAT, this unwind section should be COMDAT associative
730 const MCSymbol
*KeySym
= nullptr;
731 if (TextSecCOFF
->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT
) {
732 KeySym
= TextSecCOFF
->getCOMDATSymbol();
734 // In a GNU environment, we can't use associative comdats. Instead, do what
735 // GCC does, which is to make plain comdat selectany section named like
736 // ".[px]data$_Z3foov".
737 if (!Context
.getAsmInfo()->hasCOFFAssociativeComdats()) {
738 std::string SectionName
=
739 (MainCFISecCOFF
->getSectionName() + "$" +
740 TextSecCOFF
->getSectionName().split('$').second
)
742 return Context
.getCOFFSection(
744 MainCFISecCOFF
->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT
,
745 MainCFISecCOFF
->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY
);
749 return Context
.getAssociativeCOFFSection(MainCFISecCOFF
, KeySym
, UniqueID
);
752 MCSection
*MCStreamer::getAssociatedPDataSection(const MCSection
*TextSec
) {
753 return getWinCFISection(getContext(), &NextWinCFIID
,
754 getContext().getObjectFileInfo()->getPDataSection(),
758 MCSection
*MCStreamer::getAssociatedXDataSection(const MCSection
*TextSec
) {
759 return getWinCFISection(getContext(), &NextWinCFIID
,
760 getContext().getObjectFileInfo()->getXDataSection(),
764 void MCStreamer::EmitSyntaxDirective() {}
766 void MCStreamer::EmitWinCFIPushReg(unsigned Register
, SMLoc Loc
) {
767 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
771 MCSymbol
*Label
= EmitCFILabel();
773 WinEH::Instruction Inst
= Win64EH::Instruction::PushNonVol(Label
, Register
);
774 CurFrame
->Instructions
.push_back(Inst
);
777 void MCStreamer::EmitWinCFISetFrame(unsigned Register
, unsigned Offset
,
779 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
782 if (CurFrame
->LastFrameInst
>= 0)
783 return getContext().reportError(
784 Loc
, "frame register and offset can be set at most once");
786 return getContext().reportError(Loc
, "offset is not a multiple of 16");
788 return getContext().reportError(
789 Loc
, "frame offset must be less than or equal to 240");
791 MCSymbol
*Label
= EmitCFILabel();
793 WinEH::Instruction Inst
=
794 Win64EH::Instruction::SetFPReg(Label
, Register
, Offset
);
795 CurFrame
->LastFrameInst
= CurFrame
->Instructions
.size();
796 CurFrame
->Instructions
.push_back(Inst
);
799 void MCStreamer::EmitWinCFIAllocStack(unsigned Size
, SMLoc Loc
) {
800 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
804 return getContext().reportError(Loc
,
805 "stack allocation size must be non-zero");
807 return getContext().reportError(
808 Loc
, "stack allocation size is not a multiple of 8");
810 MCSymbol
*Label
= EmitCFILabel();
812 WinEH::Instruction Inst
= Win64EH::Instruction::Alloc(Label
, Size
);
813 CurFrame
->Instructions
.push_back(Inst
);
816 void MCStreamer::EmitWinCFISaveReg(unsigned Register
, unsigned Offset
,
818 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
823 return getContext().reportError(
824 Loc
, "register save offset is not 8 byte aligned");
826 MCSymbol
*Label
= EmitCFILabel();
828 WinEH::Instruction Inst
=
829 Win64EH::Instruction::SaveNonVol(Label
, Register
, Offset
);
830 CurFrame
->Instructions
.push_back(Inst
);
833 void MCStreamer::EmitWinCFISaveXMM(unsigned Register
, unsigned Offset
,
835 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
839 return getContext().reportError(Loc
, "offset is not a multiple of 16");
841 MCSymbol
*Label
= EmitCFILabel();
843 WinEH::Instruction Inst
=
844 Win64EH::Instruction::SaveXMM(Label
, Register
, Offset
);
845 CurFrame
->Instructions
.push_back(Inst
);
848 void MCStreamer::EmitWinCFIPushFrame(bool Code
, SMLoc Loc
) {
849 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
852 if (!CurFrame
->Instructions
.empty())
853 return getContext().reportError(
854 Loc
, "If present, PushMachFrame must be the first UOP");
856 MCSymbol
*Label
= EmitCFILabel();
858 WinEH::Instruction Inst
= Win64EH::Instruction::PushMachFrame(Label
, Code
);
859 CurFrame
->Instructions
.push_back(Inst
);
862 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc
) {
863 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
867 MCSymbol
*Label
= EmitCFILabel();
869 CurFrame
->PrologEnd
= Label
;
872 void MCStreamer::EmitCOFFSafeSEH(MCSymbol
const *Symbol
) {}
874 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol
const *Symbol
) {}
876 void MCStreamer::EmitCOFFSectionIndex(MCSymbol
const *Symbol
) {}
878 void MCStreamer::EmitCOFFSecRel32(MCSymbol
const *Symbol
, uint64_t Offset
) {}
880 void MCStreamer::EmitCOFFImgRel32(MCSymbol
const *Symbol
, int64_t Offset
) {}
882 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
883 /// the specified string in the output .s file. This capability is
884 /// indicated by the hasRawTextSupport() predicate.
885 void MCStreamer::EmitRawTextImpl(StringRef String
) {
886 // This is not llvm_unreachable for the sake of out of tree backend
887 // developers who may not have assembly streamers and should serve as a
888 // reminder to not accidentally call EmitRawText in the absence of such.
889 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
890 "it (target backend is likely missing an AsmStreamer "
894 void MCStreamer::EmitRawText(const Twine
&T
) {
895 SmallString
<128> Str
;
896 EmitRawTextImpl(T
.toStringRef(Str
));
899 void MCStreamer::EmitWindowsUnwindTables() {
902 void MCStreamer::Finish() {
903 if ((!DwarfFrameInfos
.empty() && !DwarfFrameInfos
.back().End
) ||
904 (!WinFrameInfos
.empty() && !WinFrameInfos
.back()->End
)) {
905 getContext().reportError(SMLoc(), "Unfinished frame!");
909 MCTargetStreamer
*TS
= getTargetStreamer();
916 void MCStreamer::EmitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {
917 visitUsedExpr(*Value
);
918 Symbol
->setVariableValue(Value
);
920 MCTargetStreamer
*TS
= getTargetStreamer();
922 TS
->emitAssignment(Symbol
, Value
);
925 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter
&InstPrinter
,
926 raw_ostream
&OS
, const MCInst
&Inst
,
927 const MCSubtargetInfo
&STI
) {
928 InstPrinter
.printInst(&Inst
, OS
, "", STI
);
931 void MCStreamer::visitUsedSymbol(const MCSymbol
&Sym
) {
934 void MCStreamer::visitUsedExpr(const MCExpr
&Expr
) {
935 switch (Expr
.getKind()) {
937 cast
<MCTargetExpr
>(Expr
).visitUsedExpr(*this);
940 case MCExpr::Constant
:
943 case MCExpr::Binary
: {
944 const MCBinaryExpr
&BE
= cast
<MCBinaryExpr
>(Expr
);
945 visitUsedExpr(*BE
.getLHS());
946 visitUsedExpr(*BE
.getRHS());
950 case MCExpr::SymbolRef
:
951 visitUsedSymbol(cast
<MCSymbolRefExpr
>(Expr
).getSymbol());
955 visitUsedExpr(*cast
<MCUnaryExpr
>(Expr
).getSubExpr());
960 void MCStreamer::EmitInstruction(const MCInst
&Inst
, const MCSubtargetInfo
&) {
962 for (unsigned i
= Inst
.getNumOperands(); i
--;)
963 if (Inst
.getOperand(i
).isExpr())
964 visitUsedExpr(*Inst
.getOperand(i
).getExpr());
967 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol
*Hi
, const MCSymbol
*Lo
,
969 // Get the Hi-Lo expression.
971 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
972 MCSymbolRefExpr::create(Lo
, Context
), Context
);
974 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
975 if (!MAI
->doesSetDirectiveSuppressReloc()) {
976 EmitValue(Diff
, Size
);
980 // Otherwise, emit with .set (aka assignment).
981 MCSymbol
*SetLabel
= Context
.createTempSymbol("set", true);
982 EmitAssignment(SetLabel
, Diff
);
983 EmitSymbolValue(SetLabel
, Size
);
986 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol
*Hi
,
987 const MCSymbol
*Lo
) {
988 // Get the Hi-Lo expression.
990 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
991 MCSymbolRefExpr::create(Lo
, Context
), Context
);
993 EmitULEB128Value(Diff
);
996 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag
) {}
997 void MCStreamer::EmitThumbFunc(MCSymbol
*Func
) {}
998 void MCStreamer::EmitSymbolDesc(MCSymbol
*Symbol
, unsigned DescValue
) {}
999 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol
*Symbol
) {
1000 llvm_unreachable("this directive only supported on COFF targets");
1002 void MCStreamer::EndCOFFSymbolDef() {
1003 llvm_unreachable("this directive only supported on COFF targets");
1005 void MCStreamer::EmitFileDirective(StringRef Filename
) {}
1006 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass
) {
1007 llvm_unreachable("this directive only supported on COFF targets");
1009 void MCStreamer::EmitCOFFSymbolType(int Type
) {
1010 llvm_unreachable("this directive only supported on COFF targets");
1012 void MCStreamer::emitELFSize(MCSymbol
*Symbol
, const MCExpr
*Value
) {}
1013 void MCStreamer::emitELFSymverDirective(StringRef AliasName
,
1014 const MCSymbol
*Aliasee
) {}
1015 void MCStreamer::EmitLocalCommonSymbol(MCSymbol
*Symbol
, uint64_t Size
,
1016 unsigned ByteAlignment
) {}
1017 void MCStreamer::EmitTBSSSymbol(MCSection
*Section
, MCSymbol
*Symbol
,
1018 uint64_t Size
, unsigned ByteAlignment
) {}
1019 void MCStreamer::ChangeSection(MCSection
*, const MCExpr
*) {}
1020 void MCStreamer::EmitWeakReference(MCSymbol
*Alias
, const MCSymbol
*Symbol
) {}
1021 void MCStreamer::EmitBytes(StringRef Data
) {}
1022 void MCStreamer::EmitBinaryData(StringRef Data
) { EmitBytes(Data
); }
1023 void MCStreamer::EmitValueImpl(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
1024 visitUsedExpr(*Value
);
1026 void MCStreamer::EmitULEB128Value(const MCExpr
*Value
) {}
1027 void MCStreamer::EmitSLEB128Value(const MCExpr
*Value
) {}
1028 void MCStreamer::emitFill(const MCExpr
&NumBytes
, uint64_t Value
, SMLoc Loc
) {}
1029 void MCStreamer::emitFill(const MCExpr
&NumValues
, int64_t Size
, int64_t Expr
,
1031 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment
, int64_t Value
,
1033 unsigned MaxBytesToEmit
) {}
1034 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment
,
1035 unsigned MaxBytesToEmit
) {}
1036 void MCStreamer::emitValueToOffset(const MCExpr
*Offset
, unsigned char Value
,
1038 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2
) {}
1039 void MCStreamer::EmitBundleLock(bool AlignToEnd
) {}
1040 void MCStreamer::FinishImpl() {}
1041 void MCStreamer::EmitBundleUnlock() {}
1043 void MCStreamer::SwitchSection(MCSection
*Section
, const MCExpr
*Subsection
) {
1044 assert(Section
&& "Cannot switch to a null section!");
1045 MCSectionSubPair curSection
= SectionStack
.back().first
;
1046 SectionStack
.back().second
= curSection
;
1047 if (MCSectionSubPair(Section
, Subsection
) != curSection
) {
1048 ChangeSection(Section
, Subsection
);
1049 SectionStack
.back().first
= MCSectionSubPair(Section
, Subsection
);
1050 assert(!Section
->hasEnded() && "Section already ended");
1051 MCSymbol
*Sym
= Section
->getBeginSymbol();
1052 if (Sym
&& !Sym
->isInSection())
1057 MCSymbol
*MCStreamer::endSection(MCSection
*Section
) {
1058 // TODO: keep track of the last subsection so that this symbol appears in the
1060 MCSymbol
*Sym
= Section
->getEndSymbol(Context
);
1061 if (Sym
->isInSection())
1064 SwitchSection(Section
);
1069 void MCStreamer::EmitVersionForTarget(const Triple
&Target
,
1070 const VersionTuple
&SDKVersion
) {
1071 if (!Target
.isOSBinFormatMachO() || !Target
.isOSDarwin())
1073 // Do we even know the version?
1074 if (Target
.getOSMajorVersion() == 0)
1080 if (Target
.isMacCatalystEnvironment()) {
1081 // Mac Catalyst always uses the build version load command.
1082 Target
.getiOSVersion(Major
, Minor
, Update
);
1083 assert(Major
&& "A non-zero major version is expected");
1084 EmitBuildVersion(MachO::PLATFORM_MACCATALYST
, Major
, Minor
, Update
,
1089 MCVersionMinType VersionType
;
1090 if (Target
.isWatchOS()) {
1091 VersionType
= MCVM_WatchOSVersionMin
;
1092 Target
.getWatchOSVersion(Major
, Minor
, Update
);
1093 } else if (Target
.isTvOS()) {
1094 VersionType
= MCVM_TvOSVersionMin
;
1095 Target
.getiOSVersion(Major
, Minor
, Update
);
1096 } else if (Target
.isMacOSX()) {
1097 VersionType
= MCVM_OSXVersionMin
;
1098 if (!Target
.getMacOSXVersion(Major
, Minor
, Update
))
1101 VersionType
= MCVM_IOSVersionMin
;
1102 Target
.getiOSVersion(Major
, Minor
, Update
);
1105 EmitVersionMin(VersionType
, Major
, Minor
, Update
, SDKVersion
);