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/SmallString.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/BinaryFormat/COFF.h"
14 #include "llvm/BinaryFormat/MachO.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/MCPseudoProbe.h"
26 #include "llvm/MC/MCRegister.h"
27 #include "llvm/MC/MCRegisterInfo.h"
28 #include "llvm/MC/MCSection.h"
29 #include "llvm/MC/MCSectionCOFF.h"
30 #include "llvm/MC/MCSymbol.h"
31 #include "llvm/MC/MCWin64EH.h"
32 #include "llvm/MC/MCWinEH.h"
33 #include "llvm/Support/Casting.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/LEB128.h"
36 #include "llvm/Support/MathExtras.h"
37 #include "llvm/Support/raw_ostream.h"
46 MCTargetStreamer::MCTargetStreamer(MCStreamer
&S
) : Streamer(S
) {
47 S
.setTargetStreamer(this);
50 // Pin the vtables to this file.
51 MCTargetStreamer::~MCTargetStreamer() = default;
53 void MCTargetStreamer::emitLabel(MCSymbol
*Symbol
) {}
55 void MCTargetStreamer::finish() {}
57 void MCTargetStreamer::emitConstantPools() {}
59 void MCTargetStreamer::changeSection(const MCSection
*CurSection
,
60 MCSection
*Section
, uint32_t Subsection
,
62 Section
->printSwitchToSection(*Streamer
.getContext().getAsmInfo(),
63 Streamer
.getContext().getTargetTriple(), OS
,
67 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive
) {
68 Streamer
.emitRawText(Directive
);
71 void MCTargetStreamer::emitValue(const MCExpr
*Value
) {
73 raw_svector_ostream
OS(Str
);
75 Value
->print(OS
, Streamer
.getContext().getAsmInfo());
76 Streamer
.emitRawText(OS
.str());
79 void MCTargetStreamer::emitRawBytes(StringRef Data
) {
80 const MCAsmInfo
*MAI
= Streamer
.getContext().getAsmInfo();
81 const char *Directive
= MAI
->getData8bitsDirective();
82 for (const unsigned char C
: Data
.bytes()) {
84 raw_svector_ostream
OS(Str
);
86 OS
<< Directive
<< (unsigned)C
;
87 Streamer
.emitRawText(OS
.str());
91 void MCTargetStreamer::emitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {}
93 MCStreamer::MCStreamer(MCContext
&Ctx
)
94 : Context(Ctx
), CurrentWinFrameInfo(nullptr),
95 CurrentProcWinFrameInfoStartIndex(0) {
96 SectionStack
.push_back(std::pair
<MCSectionSubPair
, MCSectionSubPair
>());
99 MCStreamer::~MCStreamer() = default;
101 void MCStreamer::reset() {
102 DwarfFrameInfos
.clear();
103 CurrentWinFrameInfo
= nullptr;
104 WinFrameInfos
.clear();
105 SectionStack
.clear();
106 SectionStack
.push_back(std::pair
<MCSectionSubPair
, MCSectionSubPair
>());
110 raw_ostream
&MCStreamer::getCommentOS() {
111 // By default, discard comments.
115 unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos
.size(); }
116 ArrayRef
<MCDwarfFrameInfo
> MCStreamer::getDwarfFrameInfos() const {
117 return DwarfFrameInfos
;
120 void MCStreamer::emitRawComment(const Twine
&T
, bool TabPrefix
) {}
122 void MCStreamer::addExplicitComment(const Twine
&T
) {}
123 void MCStreamer::emitExplicitComments() {}
125 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend
*MAB
) {
126 for (auto &FI
: DwarfFrameInfos
)
127 FI
.CompactUnwindEncoding
=
128 (MAB
? MAB
->generateCompactUnwindEncoding(&FI
, &Context
) : 0);
131 /// EmitIntValue - Special case of EmitValue that avoids the client having to
132 /// pass in a MCExpr for constant integers.
133 void MCStreamer::emitIntValue(uint64_t Value
, unsigned Size
) {
134 assert(1 <= Size
&& Size
<= 8 && "Invalid size");
135 assert((isUIntN(8 * Size
, Value
) || isIntN(8 * Size
, Value
)) &&
137 const bool IsLittleEndian
= Context
.getAsmInfo()->isLittleEndian();
138 uint64_t Swapped
= support::endian::byte_swap(
139 Value
, IsLittleEndian
? llvm::endianness::little
: llvm::endianness::big
);
140 unsigned Index
= IsLittleEndian
? 0 : 8 - Size
;
141 emitBytes(StringRef(reinterpret_cast<char *>(&Swapped
) + Index
, Size
));
143 void MCStreamer::emitIntValue(const APInt
&Value
) {
144 if (Value
.getNumWords() == 1) {
145 emitIntValue(Value
.getLimitedValue(), Value
.getBitWidth() / 8);
149 const bool IsLittleEndianTarget
= Context
.getAsmInfo()->isLittleEndian();
150 const bool ShouldSwap
= sys::IsLittleEndianHost
!= IsLittleEndianTarget
;
151 const APInt Swapped
= ShouldSwap
? Value
.byteSwap() : Value
;
152 const unsigned Size
= Value
.getBitWidth() / 8;
155 StoreIntToMemory(Swapped
, reinterpret_cast<uint8_t *>(Tmp
.data()), Size
);
156 emitBytes(Tmp
.str());
159 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
160 /// client having to pass in a MCExpr for constant integers.
161 unsigned MCStreamer::emitULEB128IntValue(uint64_t Value
, unsigned PadTo
) {
162 SmallString
<128> Tmp
;
163 raw_svector_ostream
OSE(Tmp
);
164 encodeULEB128(Value
, OSE
, PadTo
);
165 emitBytes(OSE
.str());
169 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
170 /// client having to pass in a MCExpr for constant integers.
171 unsigned MCStreamer::emitSLEB128IntValue(int64_t Value
) {
172 SmallString
<128> Tmp
;
173 raw_svector_ostream
OSE(Tmp
);
174 encodeSLEB128(Value
, OSE
);
175 emitBytes(OSE
.str());
179 void MCStreamer::emitValue(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
180 emitValueImpl(Value
, Size
, Loc
);
183 void MCStreamer::emitSymbolValue(const MCSymbol
*Sym
, unsigned Size
,
184 bool IsSectionRelative
) {
185 assert((!IsSectionRelative
|| Size
== 4) &&
186 "SectionRelative value requires 4-bytes");
188 if (!IsSectionRelative
)
189 emitValueImpl(MCSymbolRefExpr::create(Sym
, getContext()), Size
);
191 emitCOFFSecRel32(Sym
, /*Offset=*/0);
194 void MCStreamer::emitDTPRel64Value(const MCExpr
*Value
) {
195 report_fatal_error("unsupported directive in streamer");
198 void MCStreamer::emitDTPRel32Value(const MCExpr
*Value
) {
199 report_fatal_error("unsupported directive in streamer");
202 void MCStreamer::emitTPRel64Value(const MCExpr
*Value
) {
203 report_fatal_error("unsupported directive in streamer");
206 void MCStreamer::emitTPRel32Value(const MCExpr
*Value
) {
207 report_fatal_error("unsupported directive in streamer");
210 void MCStreamer::emitGPRel64Value(const MCExpr
*Value
) {
211 report_fatal_error("unsupported directive in streamer");
214 void MCStreamer::emitGPRel32Value(const MCExpr
*Value
) {
215 report_fatal_error("unsupported directive in streamer");
218 /// Emit NumBytes bytes worth of the value specified by FillValue.
219 /// This implements directives such as '.space'.
220 void MCStreamer::emitFill(uint64_t NumBytes
, uint8_t FillValue
) {
222 emitFill(*MCConstantExpr::create(NumBytes
, getContext()), FillValue
);
225 void llvm::MCStreamer::emitNops(int64_t NumBytes
, int64_t ControlledNopLen
,
226 llvm::SMLoc
, const MCSubtargetInfo
& STI
) {}
228 /// The implementation in this class just redirects to emitFill.
229 void MCStreamer::emitZeros(uint64_t NumBytes
) { emitFill(NumBytes
, 0); }
231 Expected
<unsigned> MCStreamer::tryEmitDwarfFileDirective(
232 unsigned FileNo
, StringRef Directory
, StringRef Filename
,
233 std::optional
<MD5::MD5Result
> Checksum
, std::optional
<StringRef
> Source
,
235 return getContext().getDwarfFile(Directory
, Filename
, FileNo
, Checksum
,
239 void MCStreamer::emitDwarfFile0Directive(StringRef Directory
,
241 std::optional
<MD5::MD5Result
> Checksum
,
242 std::optional
<StringRef
> Source
,
244 getContext().setMCLineTableRootFile(CUID
, Directory
, Filename
, Checksum
,
248 void MCStreamer::emitCFIBKeyFrame() {
249 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
252 CurFrame
->IsBKeyFrame
= true;
255 void MCStreamer::emitCFIMTETaggedFrame() {
256 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
259 CurFrame
->IsMTETaggedFrame
= true;
262 void MCStreamer::emitDwarfLocDirective(unsigned FileNo
, unsigned Line
,
263 unsigned Column
, unsigned Flags
,
264 unsigned Isa
, unsigned Discriminator
,
265 StringRef FileName
) {
266 getContext().setCurrentDwarfLoc(FileNo
, Line
, Column
, Flags
, Isa
,
270 MCSymbol
*MCStreamer::getDwarfLineTableSymbol(unsigned CUID
) {
271 MCDwarfLineTable
&Table
= getContext().getMCDwarfLineTable(CUID
);
272 if (!Table
.getLabel()) {
273 StringRef Prefix
= Context
.getAsmInfo()->getPrivateGlobalPrefix();
275 Context
.getOrCreateSymbol(Prefix
+ "line_table_start" + Twine(CUID
)));
277 return Table
.getLabel();
280 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
281 return !FrameInfoStack
.empty();
284 MCDwarfFrameInfo
*MCStreamer::getCurrentDwarfFrameInfo() {
285 if (!hasUnfinishedDwarfFrameInfo()) {
286 getContext().reportError(getStartTokLoc(),
287 "this directive must appear between "
288 ".cfi_startproc and .cfi_endproc directives");
291 return &DwarfFrameInfos
[FrameInfoStack
.back().first
];
294 bool MCStreamer::emitCVFileDirective(unsigned FileNo
, StringRef Filename
,
295 ArrayRef
<uint8_t> Checksum
,
296 unsigned ChecksumKind
) {
297 return getContext().getCVContext().addFile(*this, FileNo
, Filename
, Checksum
,
301 bool MCStreamer::emitCVFuncIdDirective(unsigned FunctionId
) {
302 return getContext().getCVContext().recordFunctionId(FunctionId
);
305 bool MCStreamer::emitCVInlineSiteIdDirective(unsigned FunctionId
,
306 unsigned IAFunc
, unsigned IAFile
,
307 unsigned IALine
, unsigned IACol
,
309 if (getContext().getCVContext().getCVFunctionInfo(IAFunc
) == nullptr) {
310 getContext().reportError(Loc
, "parent function id not introduced by "
311 ".cv_func_id or .cv_inline_site_id");
315 return getContext().getCVContext().recordInlinedCallSiteId(
316 FunctionId
, IAFunc
, IAFile
, IALine
, IACol
);
319 void MCStreamer::emitCVLocDirective(unsigned FunctionId
, unsigned FileNo
,
320 unsigned Line
, unsigned Column
,
321 bool PrologueEnd
, bool IsStmt
,
322 StringRef FileName
, SMLoc Loc
) {}
324 bool MCStreamer::checkCVLocSection(unsigned FuncId
, unsigned FileNo
,
326 CodeViewContext
&CVC
= getContext().getCVContext();
327 MCCVFunctionInfo
*FI
= CVC
.getCVFunctionInfo(FuncId
);
329 getContext().reportError(
330 Loc
, "function id not introduced by .cv_func_id or .cv_inline_site_id");
335 if (FI
->Section
== nullptr)
336 FI
->Section
= getCurrentSectionOnly();
337 else if (FI
->Section
!= getCurrentSectionOnly()) {
338 getContext().reportError(
340 "all .cv_loc directives for a function must be in the same section");
346 void MCStreamer::emitCVLinetableDirective(unsigned FunctionId
,
347 const MCSymbol
*Begin
,
348 const MCSymbol
*End
) {}
350 void MCStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId
,
351 unsigned SourceFileId
,
352 unsigned SourceLineNum
,
353 const MCSymbol
*FnStartSym
,
354 const MCSymbol
*FnEndSym
) {}
356 /// Only call this on endian-specific types like ulittle16_t and little32_t, or
357 /// structs composed of them.
358 template <typename T
>
359 static void copyBytesForDefRange(SmallString
<20> &BytePrefix
,
360 codeview::SymbolKind SymKind
,
361 const T
&DefRangeHeader
) {
362 BytePrefix
.resize(2 + sizeof(T
));
363 codeview::ulittle16_t SymKindLE
= codeview::ulittle16_t(SymKind
);
364 memcpy(&BytePrefix
[0], &SymKindLE
, 2);
365 memcpy(&BytePrefix
[2], &DefRangeHeader
, sizeof(T
));
368 void MCStreamer::emitCVDefRangeDirective(
369 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
370 StringRef FixedSizePortion
) {}
372 void MCStreamer::emitCVDefRangeDirective(
373 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
374 codeview::DefRangeRegisterRelHeader DRHdr
) {
375 SmallString
<20> BytePrefix
;
376 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_REGISTER_REL
, DRHdr
);
377 emitCVDefRangeDirective(Ranges
, BytePrefix
);
380 void MCStreamer::emitCVDefRangeDirective(
381 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
382 codeview::DefRangeSubfieldRegisterHeader DRHdr
) {
383 SmallString
<20> BytePrefix
;
384 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_SUBFIELD_REGISTER
,
386 emitCVDefRangeDirective(Ranges
, BytePrefix
);
389 void MCStreamer::emitCVDefRangeDirective(
390 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
391 codeview::DefRangeRegisterHeader DRHdr
) {
392 SmallString
<20> BytePrefix
;
393 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_REGISTER
, DRHdr
);
394 emitCVDefRangeDirective(Ranges
, BytePrefix
);
397 void MCStreamer::emitCVDefRangeDirective(
398 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
399 codeview::DefRangeFramePointerRelHeader DRHdr
) {
400 SmallString
<20> BytePrefix
;
401 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_FRAMEPOINTER_REL
,
403 emitCVDefRangeDirective(Ranges
, BytePrefix
);
406 void MCStreamer::emitEHSymAttributes(const MCSymbol
*Symbol
,
407 MCSymbol
*EHSymbol
) {
410 void MCStreamer::initSections(bool NoExecStack
, const MCSubtargetInfo
&STI
) {
411 switchSection(getContext().getObjectFileInfo()->getTextSection());
414 void MCStreamer::emitLabel(MCSymbol
*Symbol
, SMLoc Loc
) {
415 Symbol
->redefineIfPossible();
417 if (!Symbol
->isUndefined() || Symbol
->isVariable())
418 return getContext().reportError(Loc
, "symbol '" + Twine(Symbol
->getName()) +
419 "' is already defined");
421 assert(!Symbol
->isVariable() && "Cannot emit a variable symbol!");
422 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
423 assert(!Symbol
->getFragment() && "Unexpected fragment on symbol data!");
424 assert(Symbol
->isUndefined() && "Cannot define a symbol twice!");
426 Symbol
->setFragment(&getCurrentSectionOnly()->getDummyFragment());
428 MCTargetStreamer
*TS
= getTargetStreamer();
430 TS
->emitLabel(Symbol
);
433 void MCStreamer::emitConditionalAssignment(MCSymbol
*Symbol
,
434 const MCExpr
*Value
) {}
436 void MCStreamer::emitCFISections(bool EH
, bool Debug
) {}
438 void MCStreamer::emitCFIStartProc(bool IsSimple
, SMLoc Loc
) {
439 if (!FrameInfoStack
.empty() &&
440 getCurrentSectionOnly() == FrameInfoStack
.back().second
)
441 return getContext().reportError(
442 Loc
, "starting new .cfi frame before finishing the previous one");
444 MCDwarfFrameInfo Frame
;
445 Frame
.IsSimple
= IsSimple
;
446 emitCFIStartProcImpl(Frame
);
448 const MCAsmInfo
* MAI
= Context
.getAsmInfo();
450 for (const MCCFIInstruction
& Inst
: MAI
->getInitialFrameState()) {
451 if (Inst
.getOperation() == MCCFIInstruction::OpDefCfa
||
452 Inst
.getOperation() == MCCFIInstruction::OpDefCfaRegister
||
453 Inst
.getOperation() == MCCFIInstruction::OpLLVMDefAspaceCfa
) {
454 Frame
.CurrentCfaRegister
= Inst
.getRegister();
459 FrameInfoStack
.emplace_back(DwarfFrameInfos
.size(), getCurrentSectionOnly());
460 DwarfFrameInfos
.push_back(Frame
);
463 void MCStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) {
466 void MCStreamer::emitCFIEndProc() {
467 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
470 emitCFIEndProcImpl(*CurFrame
);
471 FrameInfoStack
.pop_back();
474 void MCStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) {
475 // Put a dummy non-null value in Frame.End to mark that this frame has been
477 Frame
.End
= (MCSymbol
*)1;
480 MCSymbol
*MCStreamer::emitCFILabel() {
481 // Return a dummy non-null value so that label fields appear filled in when
482 // generating textual assembly.
483 return (MCSymbol
*)1;
486 void MCStreamer::emitCFIDefCfa(int64_t Register
, int64_t Offset
, SMLoc Loc
) {
487 MCSymbol
*Label
= emitCFILabel();
488 MCCFIInstruction Instruction
=
489 MCCFIInstruction::cfiDefCfa(Label
, Register
, Offset
, Loc
);
490 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
493 CurFrame
->Instructions
.push_back(Instruction
);
494 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
497 void MCStreamer::emitCFIDefCfaOffset(int64_t Offset
, SMLoc Loc
) {
498 MCSymbol
*Label
= emitCFILabel();
499 MCCFIInstruction Instruction
=
500 MCCFIInstruction::cfiDefCfaOffset(Label
, Offset
);
501 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
504 CurFrame
->Instructions
.push_back(Instruction
);
507 void MCStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment
, SMLoc Loc
) {
508 MCSymbol
*Label
= emitCFILabel();
509 MCCFIInstruction Instruction
=
510 MCCFIInstruction::createAdjustCfaOffset(Label
, Adjustment
, Loc
);
511 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
514 CurFrame
->Instructions
.push_back(Instruction
);
517 void MCStreamer::emitCFIDefCfaRegister(int64_t Register
, SMLoc Loc
) {
518 MCSymbol
*Label
= emitCFILabel();
519 MCCFIInstruction Instruction
=
520 MCCFIInstruction::createDefCfaRegister(Label
, Register
, Loc
);
521 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
524 CurFrame
->Instructions
.push_back(Instruction
);
525 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
528 void MCStreamer::emitCFILLVMDefAspaceCfa(int64_t Register
, int64_t Offset
,
529 int64_t AddressSpace
, SMLoc Loc
) {
530 MCSymbol
*Label
= emitCFILabel();
531 MCCFIInstruction Instruction
= MCCFIInstruction::createLLVMDefAspaceCfa(
532 Label
, Register
, Offset
, AddressSpace
, Loc
);
533 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
536 CurFrame
->Instructions
.push_back(Instruction
);
537 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
540 void MCStreamer::emitCFIOffset(int64_t Register
, int64_t Offset
, SMLoc Loc
) {
541 MCSymbol
*Label
= emitCFILabel();
542 MCCFIInstruction Instruction
=
543 MCCFIInstruction::createOffset(Label
, Register
, Offset
, Loc
);
544 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
547 CurFrame
->Instructions
.push_back(Instruction
);
550 void MCStreamer::emitCFIRelOffset(int64_t Register
, int64_t Offset
, SMLoc Loc
) {
551 MCSymbol
*Label
= emitCFILabel();
552 MCCFIInstruction Instruction
=
553 MCCFIInstruction::createRelOffset(Label
, Register
, Offset
, Loc
);
554 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
557 CurFrame
->Instructions
.push_back(Instruction
);
560 void MCStreamer::emitCFIPersonality(const MCSymbol
*Sym
,
562 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
565 CurFrame
->Personality
= Sym
;
566 CurFrame
->PersonalityEncoding
= Encoding
;
569 void MCStreamer::emitCFILsda(const MCSymbol
*Sym
, unsigned Encoding
) {
570 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
573 CurFrame
->Lsda
= Sym
;
574 CurFrame
->LsdaEncoding
= Encoding
;
577 void MCStreamer::emitCFIRememberState(SMLoc Loc
) {
578 MCSymbol
*Label
= emitCFILabel();
579 MCCFIInstruction Instruction
=
580 MCCFIInstruction::createRememberState(Label
, Loc
);
581 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
584 CurFrame
->Instructions
.push_back(Instruction
);
587 void MCStreamer::emitCFIRestoreState(SMLoc Loc
) {
588 // FIXME: Error if there is no matching cfi_remember_state.
589 MCSymbol
*Label
= emitCFILabel();
590 MCCFIInstruction Instruction
=
591 MCCFIInstruction::createRestoreState(Label
, Loc
);
592 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
595 CurFrame
->Instructions
.push_back(Instruction
);
598 void MCStreamer::emitCFISameValue(int64_t Register
, SMLoc Loc
) {
599 MCSymbol
*Label
= emitCFILabel();
600 MCCFIInstruction Instruction
=
601 MCCFIInstruction::createSameValue(Label
, Register
, Loc
);
602 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
605 CurFrame
->Instructions
.push_back(Instruction
);
608 void MCStreamer::emitCFIRestore(int64_t Register
, SMLoc Loc
) {
609 MCSymbol
*Label
= emitCFILabel();
610 MCCFIInstruction Instruction
=
611 MCCFIInstruction::createRestore(Label
, Register
, Loc
);
612 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
615 CurFrame
->Instructions
.push_back(Instruction
);
618 void MCStreamer::emitCFIEscape(StringRef Values
, SMLoc Loc
) {
619 MCSymbol
*Label
= emitCFILabel();
620 MCCFIInstruction Instruction
=
621 MCCFIInstruction::createEscape(Label
, Values
, Loc
, "");
622 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
625 CurFrame
->Instructions
.push_back(Instruction
);
628 void MCStreamer::emitCFIGnuArgsSize(int64_t Size
, SMLoc Loc
) {
629 MCSymbol
*Label
= emitCFILabel();
630 MCCFIInstruction Instruction
=
631 MCCFIInstruction::createGnuArgsSize(Label
, Size
, Loc
);
632 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
635 CurFrame
->Instructions
.push_back(Instruction
);
638 void MCStreamer::emitCFISignalFrame() {
639 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
642 CurFrame
->IsSignalFrame
= true;
645 void MCStreamer::emitCFIUndefined(int64_t Register
, SMLoc Loc
) {
646 MCSymbol
*Label
= emitCFILabel();
647 MCCFIInstruction Instruction
=
648 MCCFIInstruction::createUndefined(Label
, Register
, Loc
);
649 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
652 CurFrame
->Instructions
.push_back(Instruction
);
655 void MCStreamer::emitCFIRegister(int64_t Register1
, int64_t Register2
,
657 MCSymbol
*Label
= emitCFILabel();
658 MCCFIInstruction Instruction
=
659 MCCFIInstruction::createRegister(Label
, Register1
, Register2
, Loc
);
660 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
663 CurFrame
->Instructions
.push_back(Instruction
);
666 void MCStreamer::emitCFIWindowSave(SMLoc Loc
) {
667 MCSymbol
*Label
= emitCFILabel();
668 MCCFIInstruction Instruction
= MCCFIInstruction::createWindowSave(Label
, Loc
);
669 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
672 CurFrame
->Instructions
.push_back(Instruction
);
675 void MCStreamer::emitCFINegateRAState(SMLoc Loc
) {
676 MCSymbol
*Label
= emitCFILabel();
677 MCCFIInstruction Instruction
=
678 MCCFIInstruction::createNegateRAState(Label
, Loc
);
679 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
682 CurFrame
->Instructions
.push_back(Instruction
);
685 void MCStreamer::emitCFIReturnColumn(int64_t Register
) {
686 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
689 CurFrame
->RAReg
= Register
;
692 void MCStreamer::emitCFILabelDirective(SMLoc Loc
, StringRef Name
) {
693 MCSymbol
*Label
= emitCFILabel();
694 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
695 if (MCDwarfFrameInfo
*F
= getCurrentDwarfFrameInfo())
696 F
->Instructions
.push_back(MCCFIInstruction::createLabel(Label
, Sym
, Loc
));
699 WinEH::FrameInfo
*MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc
) {
700 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
701 if (!MAI
->usesWindowsCFI()) {
702 getContext().reportError(
703 Loc
, ".seh_* directives are not supported on this target");
706 if (!CurrentWinFrameInfo
|| CurrentWinFrameInfo
->End
) {
707 getContext().reportError(
708 Loc
, ".seh_ directive must appear within an active frame");
711 return CurrentWinFrameInfo
;
714 void MCStreamer::emitWinCFIStartProc(const MCSymbol
*Symbol
, SMLoc Loc
) {
715 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
716 if (!MAI
->usesWindowsCFI())
717 return getContext().reportError(
718 Loc
, ".seh_* directives are not supported on this target");
719 if (CurrentWinFrameInfo
&& !CurrentWinFrameInfo
->End
)
720 getContext().reportError(
721 Loc
, "Starting a function before ending the previous one!");
723 MCSymbol
*StartProc
= emitCFILabel();
725 CurrentProcWinFrameInfoStartIndex
= WinFrameInfos
.size();
726 WinFrameInfos
.emplace_back(
727 std::make_unique
<WinEH::FrameInfo
>(Symbol
, StartProc
));
728 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
729 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
732 void MCStreamer::emitWinCFIEndProc(SMLoc Loc
) {
733 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
736 if (CurFrame
->ChainedParent
)
737 getContext().reportError(Loc
, "Not all chained regions terminated!");
739 MCSymbol
*Label
= emitCFILabel();
740 CurFrame
->End
= Label
;
741 if (!CurFrame
->FuncletOrFuncEnd
)
742 CurFrame
->FuncletOrFuncEnd
= CurFrame
->End
;
744 for (size_t I
= CurrentProcWinFrameInfoStartIndex
, E
= WinFrameInfos
.size();
746 emitWindowsUnwindTables(WinFrameInfos
[I
].get());
747 switchSection(CurFrame
->TextSection
);
750 void MCStreamer::emitWinCFIFuncletOrFuncEnd(SMLoc Loc
) {
751 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
754 if (CurFrame
->ChainedParent
)
755 getContext().reportError(Loc
, "Not all chained regions terminated!");
757 MCSymbol
*Label
= emitCFILabel();
758 CurFrame
->FuncletOrFuncEnd
= Label
;
761 void MCStreamer::emitWinCFIStartChained(SMLoc Loc
) {
762 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
766 MCSymbol
*StartProc
= emitCFILabel();
768 WinFrameInfos
.emplace_back(std::make_unique
<WinEH::FrameInfo
>(
769 CurFrame
->Function
, StartProc
, CurFrame
));
770 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
771 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
774 void MCStreamer::emitWinCFIEndChained(SMLoc Loc
) {
775 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
778 if (!CurFrame
->ChainedParent
)
779 return getContext().reportError(
780 Loc
, "End of a chained region outside a chained region!");
782 MCSymbol
*Label
= emitCFILabel();
784 CurFrame
->End
= Label
;
785 CurrentWinFrameInfo
= const_cast<WinEH::FrameInfo
*>(CurFrame
->ChainedParent
);
788 void MCStreamer::emitWinEHHandler(const MCSymbol
*Sym
, bool Unwind
, bool Except
,
790 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
793 if (CurFrame
->ChainedParent
)
794 return getContext().reportError(
795 Loc
, "Chained unwind areas can't have handlers!");
796 CurFrame
->ExceptionHandler
= Sym
;
797 if (!Except
&& !Unwind
)
798 getContext().reportError(Loc
, "Don't know what kind of handler this is!");
800 CurFrame
->HandlesUnwind
= true;
802 CurFrame
->HandlesExceptions
= true;
805 void MCStreamer::emitWinEHHandlerData(SMLoc Loc
) {
806 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
809 if (CurFrame
->ChainedParent
)
810 getContext().reportError(Loc
, "Chained unwind areas can't have handlers!");
813 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr
*From
,
814 const MCSymbolRefExpr
*To
, uint64_t Count
) {
817 static MCSection
*getWinCFISection(MCContext
&Context
, unsigned *NextWinCFIID
,
818 MCSection
*MainCFISec
,
819 const MCSection
*TextSec
) {
820 // If this is the main .text section, use the main unwind info section.
821 if (TextSec
== Context
.getObjectFileInfo()->getTextSection())
824 const auto *TextSecCOFF
= cast
<MCSectionCOFF
>(TextSec
);
825 auto *MainCFISecCOFF
= cast
<MCSectionCOFF
>(MainCFISec
);
826 unsigned UniqueID
= TextSecCOFF
->getOrAssignWinCFISectionID(NextWinCFIID
);
828 // If this section is COMDAT, this unwind section should be COMDAT associative
830 const MCSymbol
*KeySym
= nullptr;
831 if (TextSecCOFF
->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT
) {
832 KeySym
= TextSecCOFF
->getCOMDATSymbol();
834 // In a GNU environment, we can't use associative comdats. Instead, do what
835 // GCC does, which is to make plain comdat selectany section named like
836 // ".[px]data$_Z3foov".
837 if (!Context
.getAsmInfo()->hasCOFFAssociativeComdats()) {
838 std::string SectionName
= (MainCFISecCOFF
->getName() + "$" +
839 TextSecCOFF
->getName().split('$').second
)
841 return Context
.getCOFFSection(SectionName
,
842 MainCFISecCOFF
->getCharacteristics() |
843 COFF::IMAGE_SCN_LNK_COMDAT
,
844 "", COFF::IMAGE_COMDAT_SELECT_ANY
);
848 return Context
.getAssociativeCOFFSection(MainCFISecCOFF
, KeySym
, UniqueID
);
851 MCSection
*MCStreamer::getAssociatedPDataSection(const MCSection
*TextSec
) {
852 return getWinCFISection(getContext(), &NextWinCFIID
,
853 getContext().getObjectFileInfo()->getPDataSection(),
857 MCSection
*MCStreamer::getAssociatedXDataSection(const MCSection
*TextSec
) {
858 return getWinCFISection(getContext(), &NextWinCFIID
,
859 getContext().getObjectFileInfo()->getXDataSection(),
863 void MCStreamer::emitSyntaxDirective() {}
865 static unsigned encodeSEHRegNum(MCContext
&Ctx
, MCRegister Reg
) {
866 return Ctx
.getRegisterInfo()->getSEHRegNum(Reg
);
869 void MCStreamer::emitWinCFIPushReg(MCRegister Register
, SMLoc Loc
) {
870 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
874 MCSymbol
*Label
= emitCFILabel();
876 WinEH::Instruction Inst
= Win64EH::Instruction::PushNonVol(
877 Label
, encodeSEHRegNum(Context
, Register
));
878 CurFrame
->Instructions
.push_back(Inst
);
881 void MCStreamer::emitWinCFISetFrame(MCRegister Register
, unsigned Offset
,
883 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
886 if (CurFrame
->LastFrameInst
>= 0)
887 return getContext().reportError(
888 Loc
, "frame register and offset can be set at most once");
890 return getContext().reportError(Loc
, "offset is not a multiple of 16");
892 return getContext().reportError(
893 Loc
, "frame offset must be less than or equal to 240");
895 MCSymbol
*Label
= emitCFILabel();
897 WinEH::Instruction Inst
= Win64EH::Instruction::SetFPReg(
898 Label
, encodeSEHRegNum(getContext(), Register
), Offset
);
899 CurFrame
->LastFrameInst
= CurFrame
->Instructions
.size();
900 CurFrame
->Instructions
.push_back(Inst
);
903 void MCStreamer::emitWinCFIAllocStack(unsigned Size
, SMLoc Loc
) {
904 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
908 return getContext().reportError(Loc
,
909 "stack allocation size must be non-zero");
911 return getContext().reportError(
912 Loc
, "stack allocation size is not a multiple of 8");
914 MCSymbol
*Label
= emitCFILabel();
916 WinEH::Instruction Inst
= Win64EH::Instruction::Alloc(Label
, Size
);
917 CurFrame
->Instructions
.push_back(Inst
);
920 void MCStreamer::emitWinCFISaveReg(MCRegister Register
, unsigned Offset
,
922 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
927 return getContext().reportError(
928 Loc
, "register save offset is not 8 byte aligned");
930 MCSymbol
*Label
= emitCFILabel();
932 WinEH::Instruction Inst
= Win64EH::Instruction::SaveNonVol(
933 Label
, encodeSEHRegNum(Context
, Register
), Offset
);
934 CurFrame
->Instructions
.push_back(Inst
);
937 void MCStreamer::emitWinCFISaveXMM(MCRegister Register
, unsigned Offset
,
939 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
943 return getContext().reportError(Loc
, "offset is not a multiple of 16");
945 MCSymbol
*Label
= emitCFILabel();
947 WinEH::Instruction Inst
= Win64EH::Instruction::SaveXMM(
948 Label
, encodeSEHRegNum(Context
, Register
), Offset
);
949 CurFrame
->Instructions
.push_back(Inst
);
952 void MCStreamer::emitWinCFIPushFrame(bool Code
, SMLoc Loc
) {
953 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
956 if (!CurFrame
->Instructions
.empty())
957 return getContext().reportError(
958 Loc
, "If present, PushMachFrame must be the first UOP");
960 MCSymbol
*Label
= emitCFILabel();
962 WinEH::Instruction Inst
= Win64EH::Instruction::PushMachFrame(Label
, Code
);
963 CurFrame
->Instructions
.push_back(Inst
);
966 void MCStreamer::emitWinCFIEndProlog(SMLoc Loc
) {
967 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
971 MCSymbol
*Label
= emitCFILabel();
973 CurFrame
->PrologEnd
= Label
;
976 void MCStreamer::emitCOFFSafeSEH(MCSymbol
const *Symbol
) {}
978 void MCStreamer::emitCOFFSymbolIndex(MCSymbol
const *Symbol
) {}
980 void MCStreamer::emitCOFFSectionIndex(MCSymbol
const *Symbol
) {}
982 void MCStreamer::emitCOFFSecRel32(MCSymbol
const *Symbol
, uint64_t Offset
) {}
984 void MCStreamer::emitCOFFImgRel32(MCSymbol
const *Symbol
, int64_t Offset
) {}
986 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
987 /// the specified string in the output .s file. This capability is
988 /// indicated by the hasRawTextSupport() predicate.
989 void MCStreamer::emitRawTextImpl(StringRef String
) {
990 // This is not llvm_unreachable for the sake of out of tree backend
991 // developers who may not have assembly streamers and should serve as a
992 // reminder to not accidentally call EmitRawText in the absence of such.
993 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
994 "it (target backend is likely missing an AsmStreamer "
998 void MCStreamer::emitRawText(const Twine
&T
) {
999 SmallString
<128> Str
;
1000 emitRawTextImpl(T
.toStringRef(Str
));
1003 void MCStreamer::emitWindowsUnwindTables() {}
1005 void MCStreamer::emitWindowsUnwindTables(WinEH::FrameInfo
*Frame
) {}
1007 void MCStreamer::finish(SMLoc EndLoc
) {
1008 if ((!DwarfFrameInfos
.empty() && !DwarfFrameInfos
.back().End
) ||
1009 (!WinFrameInfos
.empty() && !WinFrameInfos
.back()->End
)) {
1010 getContext().reportError(EndLoc
, "Unfinished frame!");
1014 MCTargetStreamer
*TS
= getTargetStreamer();
1021 void MCStreamer::maybeEmitDwarf64Mark() {
1022 if (Context
.getDwarfFormat() != dwarf::DWARF64
)
1024 AddComment("DWARF64 Mark");
1025 emitInt32(dwarf::DW_LENGTH_DWARF64
);
1028 void MCStreamer::emitDwarfUnitLength(uint64_t Length
, const Twine
&Comment
) {
1029 assert(Context
.getDwarfFormat() == dwarf::DWARF64
||
1030 Length
<= dwarf::DW_LENGTH_lo_reserved
);
1031 maybeEmitDwarf64Mark();
1032 AddComment(Comment
);
1033 emitIntValue(Length
, dwarf::getDwarfOffsetByteSize(Context
.getDwarfFormat()));
1036 MCSymbol
*MCStreamer::emitDwarfUnitLength(const Twine
&Prefix
,
1037 const Twine
&Comment
) {
1038 maybeEmitDwarf64Mark();
1039 AddComment(Comment
);
1040 MCSymbol
*Lo
= Context
.createTempSymbol(Prefix
+ "_start");
1041 MCSymbol
*Hi
= Context
.createTempSymbol(Prefix
+ "_end");
1043 emitAbsoluteSymbolDiff(
1044 Hi
, Lo
, dwarf::getDwarfOffsetByteSize(Context
.getDwarfFormat()));
1045 // emit the begin symbol after we generate the length field.
1047 // Return the Hi symbol to the caller.
1051 void MCStreamer::emitDwarfLineStartLabel(MCSymbol
*StartSym
) {
1052 // Set the value of the symbol, as we are at the start of the line table.
1053 emitLabel(StartSym
);
1056 void MCStreamer::emitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {
1057 visitUsedExpr(*Value
);
1058 Symbol
->setVariableValue(Value
);
1060 MCTargetStreamer
*TS
= getTargetStreamer();
1062 TS
->emitAssignment(Symbol
, Value
);
1065 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter
&InstPrinter
,
1066 uint64_t Address
, const MCInst
&Inst
,
1067 const MCSubtargetInfo
&STI
,
1069 InstPrinter
.printInst(&Inst
, Address
, "", STI
, OS
);
1072 void MCStreamer::visitUsedSymbol(const MCSymbol
&Sym
) {
1075 void MCStreamer::visitUsedExpr(const MCExpr
&Expr
) {
1076 switch (Expr
.getKind()) {
1077 case MCExpr::Target
:
1078 cast
<MCTargetExpr
>(Expr
).visitUsedExpr(*this);
1081 case MCExpr::Constant
:
1084 case MCExpr::Binary
: {
1085 const MCBinaryExpr
&BE
= cast
<MCBinaryExpr
>(Expr
);
1086 visitUsedExpr(*BE
.getLHS());
1087 visitUsedExpr(*BE
.getRHS());
1091 case MCExpr::SymbolRef
:
1092 visitUsedSymbol(cast
<MCSymbolRefExpr
>(Expr
).getSymbol());
1096 visitUsedExpr(*cast
<MCUnaryExpr
>(Expr
).getSubExpr());
1101 void MCStreamer::emitInstruction(const MCInst
&Inst
, const MCSubtargetInfo
&) {
1103 for (unsigned i
= Inst
.getNumOperands(); i
--;)
1104 if (Inst
.getOperand(i
).isExpr())
1105 visitUsedExpr(*Inst
.getOperand(i
).getExpr());
1108 void MCStreamer::emitPseudoProbe(uint64_t Guid
, uint64_t Index
, uint64_t Type
,
1109 uint64_t Attr
, uint64_t Discriminator
,
1110 const MCPseudoProbeInlineStack
&InlineStack
,
1112 auto &Context
= getContext();
1114 // Create a symbol at in the current section for use in the probe.
1115 MCSymbol
*ProbeSym
= Context
.createTempSymbol();
1117 // Set the value of the symbol to use for the MCPseudoProbe.
1118 emitLabel(ProbeSym
);
1120 // Create a (local) probe entry with the symbol.
1121 MCPseudoProbe
Probe(ProbeSym
, Guid
, Index
, Type
, Attr
, Discriminator
);
1123 // Add the probe entry to this section's entries.
1124 Context
.getMCPseudoProbeTable().getProbeSections().addPseudoProbe(
1125 FnSym
, Probe
, InlineStack
);
1128 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol
*Hi
, const MCSymbol
*Lo
,
1130 // Get the Hi-Lo expression.
1131 const MCExpr
*Diff
=
1132 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
1133 MCSymbolRefExpr::create(Lo
, Context
), Context
);
1135 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
1136 if (!MAI
->doesSetDirectiveSuppressReloc()) {
1137 emitValue(Diff
, Size
);
1141 // Otherwise, emit with .set (aka assignment).
1142 MCSymbol
*SetLabel
= Context
.createTempSymbol("set");
1143 emitAssignment(SetLabel
, Diff
);
1144 emitSymbolValue(SetLabel
, Size
);
1147 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol
*Hi
,
1148 const MCSymbol
*Lo
) {
1149 // Get the Hi-Lo expression.
1150 const MCExpr
*Diff
=
1151 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
1152 MCSymbolRefExpr::create(Lo
, Context
), Context
);
1154 emitULEB128Value(Diff
);
1157 void MCStreamer::emitAssemblerFlag(MCAssemblerFlag Flag
) {}
1158 void MCStreamer::emitThumbFunc(MCSymbol
*Func
) {}
1159 void MCStreamer::emitSymbolDesc(MCSymbol
*Symbol
, unsigned DescValue
) {}
1160 void MCStreamer::beginCOFFSymbolDef(const MCSymbol
*Symbol
) {
1161 llvm_unreachable("this directive only supported on COFF targets");
1163 void MCStreamer::endCOFFSymbolDef() {
1164 llvm_unreachable("this directive only supported on COFF targets");
1166 void MCStreamer::emitFileDirective(StringRef Filename
) {}
1167 void MCStreamer::emitFileDirective(StringRef Filename
,
1168 StringRef CompilerVersion
,
1169 StringRef TimeStamp
, StringRef Description
) {
1171 void MCStreamer::emitCOFFSymbolStorageClass(int StorageClass
) {
1172 llvm_unreachable("this directive only supported on COFF targets");
1174 void MCStreamer::emitCOFFSymbolType(int Type
) {
1175 llvm_unreachable("this directive only supported on COFF targets");
1177 void MCStreamer::emitXCOFFLocalCommonSymbol(MCSymbol
*LabelSym
, uint64_t Size
,
1180 llvm_unreachable("this directive only supported on XCOFF targets");
1183 void MCStreamer::emitXCOFFSymbolLinkageWithVisibility(MCSymbol
*Symbol
,
1184 MCSymbolAttr Linkage
,
1185 MCSymbolAttr Visibility
) {
1186 llvm_unreachable("emitXCOFFSymbolLinkageWithVisibility is only supported on "
1190 void MCStreamer::emitXCOFFRenameDirective(const MCSymbol
*Name
,
1191 StringRef Rename
) {}
1193 void MCStreamer::emitXCOFFRefDirective(const MCSymbol
*Symbol
) {
1194 llvm_unreachable("emitXCOFFRefDirective is only supported on XCOFF targets");
1197 void MCStreamer::emitXCOFFExceptDirective(const MCSymbol
*Symbol
,
1198 const MCSymbol
*Trap
,
1199 unsigned Lang
, unsigned Reason
,
1200 unsigned FunctionSize
,
1202 report_fatal_error("emitXCOFFExceptDirective is only supported on "
1206 void MCStreamer::emitXCOFFCInfoSym(StringRef Name
, StringRef Metadata
) {
1207 llvm_unreachable("emitXCOFFCInfoSym is only supported on"
1211 void MCStreamer::emitELFSize(MCSymbol
*Symbol
, const MCExpr
*Value
) {}
1212 void MCStreamer::emitELFSymverDirective(const MCSymbol
*OriginalSym
,
1213 StringRef Name
, bool KeepOriginalSym
) {}
1214 void MCStreamer::emitLocalCommonSymbol(MCSymbol
*Symbol
, uint64_t Size
,
1215 Align ByteAlignment
) {}
1216 void MCStreamer::emitTBSSSymbol(MCSection
*Section
, MCSymbol
*Symbol
,
1217 uint64_t Size
, Align ByteAlignment
) {}
1218 void MCStreamer::changeSection(MCSection
*Section
, uint32_t) {
1219 CurFrag
= &Section
->getDummyFragment();
1221 void MCStreamer::emitWeakReference(MCSymbol
*Alias
, const MCSymbol
*Symbol
) {}
1222 void MCStreamer::emitBytes(StringRef Data
) {}
1223 void MCStreamer::emitBinaryData(StringRef Data
) { emitBytes(Data
); }
1224 void MCStreamer::emitValueImpl(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
1225 visitUsedExpr(*Value
);
1227 void MCStreamer::emitULEB128Value(const MCExpr
*Value
) {}
1228 void MCStreamer::emitSLEB128Value(const MCExpr
*Value
) {}
1229 void MCStreamer::emitFill(const MCExpr
&NumBytes
, uint64_t Value
, SMLoc Loc
) {}
1230 void MCStreamer::emitFill(const MCExpr
&NumValues
, int64_t Size
, int64_t Expr
,
1232 void MCStreamer::emitValueToAlignment(Align Alignment
, int64_t Value
,
1234 unsigned MaxBytesToEmit
) {}
1235 void MCStreamer::emitCodeAlignment(Align Alignment
, const MCSubtargetInfo
*STI
,
1236 unsigned MaxBytesToEmit
) {}
1237 void MCStreamer::emitValueToOffset(const MCExpr
*Offset
, unsigned char Value
,
1239 void MCStreamer::emitBundleAlignMode(Align Alignment
) {}
1240 void MCStreamer::emitBundleLock(bool AlignToEnd
) {}
1241 void MCStreamer::finishImpl() {}
1242 void MCStreamer::emitBundleUnlock() {}
1244 bool MCStreamer::popSection() {
1245 if (SectionStack
.size() <= 1)
1247 auto I
= SectionStack
.end();
1249 MCSectionSubPair OldSec
= I
->first
;
1251 MCSectionSubPair NewSec
= I
->first
;
1253 if (NewSec
.first
&& OldSec
!= NewSec
)
1254 changeSection(NewSec
.first
, NewSec
.second
);
1255 SectionStack
.pop_back();
1259 void MCStreamer::switchSection(MCSection
*Section
, uint32_t Subsection
) {
1260 assert(Section
&& "Cannot switch to a null section!");
1261 MCSectionSubPair curSection
= SectionStack
.back().first
;
1262 SectionStack
.back().second
= curSection
;
1263 if (MCSectionSubPair(Section
, Subsection
) != curSection
) {
1264 changeSection(Section
, Subsection
);
1265 SectionStack
.back().first
= MCSectionSubPair(Section
, Subsection
);
1266 assert(!Section
->hasEnded() && "Section already ended");
1267 MCSymbol
*Sym
= Section
->getBeginSymbol();
1268 if (Sym
&& !Sym
->isInSection())
1273 bool MCStreamer::switchSection(MCSection
*Section
, const MCExpr
*SubsecExpr
) {
1276 if (!SubsecExpr
->evaluateAsAbsolute(Subsec
, getAssemblerPtr())) {
1277 getContext().reportError(SubsecExpr
->getLoc(),
1278 "cannot evaluate subsection number");
1281 if (!isUInt
<31>(Subsec
)) {
1282 getContext().reportError(SubsecExpr
->getLoc(),
1283 "subsection number " + Twine(Subsec
) +
1284 " is not within [0,2147483647]");
1288 switchSection(Section
, Subsec
);
1292 void MCStreamer::switchSectionNoPrint(MCSection
*Section
) {
1293 SectionStack
.back().second
= SectionStack
.back().first
;
1294 SectionStack
.back().first
= MCSectionSubPair(Section
, 0);
1295 CurFrag
= &Section
->getDummyFragment();
1298 MCSymbol
*MCStreamer::endSection(MCSection
*Section
) {
1299 // TODO: keep track of the last subsection so that this symbol appears in the
1301 MCSymbol
*Sym
= Section
->getEndSymbol(Context
);
1302 if (Sym
->isInSection())
1305 switchSection(Section
);
1311 targetVersionOrMinimumSupportedOSVersion(const Triple
&Target
,
1312 VersionTuple TargetVersion
) {
1313 VersionTuple Min
= Target
.getMinimumSupportedOSVersion();
1314 return !Min
.empty() && Min
> TargetVersion
? Min
: TargetVersion
;
1317 static MCVersionMinType
1318 getMachoVersionMinLoadCommandType(const Triple
&Target
) {
1319 assert(Target
.isOSDarwin() && "expected a darwin OS");
1320 switch (Target
.getOS()) {
1321 case Triple::MacOSX
:
1322 case Triple::Darwin
:
1323 return MCVM_OSXVersionMin
;
1325 assert(!Target
.isMacCatalystEnvironment() &&
1326 "mac Catalyst should use LC_BUILD_VERSION");
1327 return MCVM_IOSVersionMin
;
1329 return MCVM_TvOSVersionMin
;
1330 case Triple::WatchOS
:
1331 return MCVM_WatchOSVersionMin
;
1335 llvm_unreachable("unexpected OS type");
1338 static VersionTuple
getMachoBuildVersionSupportedOS(const Triple
&Target
) {
1339 assert(Target
.isOSDarwin() && "expected a darwin OS");
1340 switch (Target
.getOS()) {
1341 case Triple::MacOSX
:
1342 case Triple::Darwin
:
1343 return VersionTuple(10, 14);
1345 // Mac Catalyst always uses the build version load command.
1346 if (Target
.isMacCatalystEnvironment())
1347 return VersionTuple();
1350 return VersionTuple(12);
1351 case Triple::WatchOS
:
1352 return VersionTuple(5);
1353 case Triple::DriverKit
:
1354 // DriverKit always uses the build version load command.
1355 return VersionTuple();
1357 // XROS always uses the build version load command.
1358 return VersionTuple();
1362 llvm_unreachable("unexpected OS type");
1365 static MachO::PlatformType
1366 getMachoBuildVersionPlatformType(const Triple
&Target
) {
1367 assert(Target
.isOSDarwin() && "expected a darwin OS");
1368 switch (Target
.getOS()) {
1369 case Triple::MacOSX
:
1370 case Triple::Darwin
:
1371 return MachO::PLATFORM_MACOS
;
1373 if (Target
.isMacCatalystEnvironment())
1374 return MachO::PLATFORM_MACCATALYST
;
1375 return Target
.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
1376 : MachO::PLATFORM_IOS
;
1378 return Target
.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
1379 : MachO::PLATFORM_TVOS
;
1380 case Triple::WatchOS
:
1381 return Target
.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
1382 : MachO::PLATFORM_WATCHOS
;
1383 case Triple::DriverKit
:
1384 return MachO::PLATFORM_DRIVERKIT
;
1386 return Target
.isSimulatorEnvironment() ? MachO::PLATFORM_XROS_SIMULATOR
1387 : MachO::PLATFORM_XROS
;
1391 llvm_unreachable("unexpected OS type");
1394 void MCStreamer::emitVersionForTarget(
1395 const Triple
&Target
, const VersionTuple
&SDKVersion
,
1396 const Triple
*DarwinTargetVariantTriple
,
1397 const VersionTuple
&DarwinTargetVariantSDKVersion
) {
1398 if (!Target
.isOSBinFormatMachO() || !Target
.isOSDarwin())
1400 // Do we even know the version?
1401 if (Target
.getOSMajorVersion() == 0)
1404 VersionTuple Version
;
1405 switch (Target
.getOS()) {
1406 case Triple::MacOSX
:
1407 case Triple::Darwin
:
1408 Target
.getMacOSXVersion(Version
);
1412 Version
= Target
.getiOSVersion();
1414 case Triple::WatchOS
:
1415 Version
= Target
.getWatchOSVersion();
1417 case Triple::DriverKit
:
1418 Version
= Target
.getDriverKitVersion();
1421 Version
= Target
.getOSVersion();
1424 llvm_unreachable("unexpected OS type");
1426 assert(Version
.getMajor() != 0 && "A non-zero major version is expected");
1427 auto LinkedTargetVersion
=
1428 targetVersionOrMinimumSupportedOSVersion(Target
, Version
);
1429 auto BuildVersionOSVersion
= getMachoBuildVersionSupportedOS(Target
);
1430 bool ShouldEmitBuildVersion
= false;
1431 if (BuildVersionOSVersion
.empty() ||
1432 LinkedTargetVersion
>= BuildVersionOSVersion
) {
1433 if (Target
.isMacCatalystEnvironment() && DarwinTargetVariantTriple
&&
1434 DarwinTargetVariantTriple
->isMacOSX()) {
1435 emitVersionForTarget(*DarwinTargetVariantTriple
,
1436 DarwinTargetVariantSDKVersion
,
1437 /*DarwinTargetVariantTriple=*/nullptr,
1438 /*DarwinTargetVariantSDKVersion=*/VersionTuple());
1439 emitDarwinTargetVariantBuildVersion(
1440 getMachoBuildVersionPlatformType(Target
),
1441 LinkedTargetVersion
.getMajor(),
1442 LinkedTargetVersion
.getMinor().value_or(0),
1443 LinkedTargetVersion
.getSubminor().value_or(0), SDKVersion
);
1446 emitBuildVersion(getMachoBuildVersionPlatformType(Target
),
1447 LinkedTargetVersion
.getMajor(),
1448 LinkedTargetVersion
.getMinor().value_or(0),
1449 LinkedTargetVersion
.getSubminor().value_or(0), SDKVersion
);
1450 ShouldEmitBuildVersion
= true;
1453 if (const Triple
*TVT
= DarwinTargetVariantTriple
) {
1454 if (Target
.isMacOSX() && TVT
->isMacCatalystEnvironment()) {
1455 auto TVLinkedTargetVersion
=
1456 targetVersionOrMinimumSupportedOSVersion(*TVT
, TVT
->getiOSVersion());
1457 emitDarwinTargetVariantBuildVersion(
1458 getMachoBuildVersionPlatformType(*TVT
),
1459 TVLinkedTargetVersion
.getMajor(),
1460 TVLinkedTargetVersion
.getMinor().value_or(0),
1461 TVLinkedTargetVersion
.getSubminor().value_or(0),
1462 DarwinTargetVariantSDKVersion
);
1466 if (ShouldEmitBuildVersion
)
1469 emitVersionMin(getMachoVersionMinLoadCommandType(Target
),
1470 LinkedTargetVersion
.getMajor(),
1471 LinkedTargetVersion
.getMinor().value_or(0),
1472 LinkedTargetVersion
.getSubminor().value_or(0), SDKVersion
);