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/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"
45 MCTargetStreamer::MCTargetStreamer(MCStreamer
&S
) : Streamer(S
) {
46 S
.setTargetStreamer(this);
49 // Pin the vtables to this file.
50 MCTargetStreamer::~MCTargetStreamer() = default;
52 void MCTargetStreamer::emitLabel(MCSymbol
*Symbol
) {}
54 void MCTargetStreamer::finish() {}
56 void MCTargetStreamer::emitConstantPools() {}
58 void MCTargetStreamer::changeSection(const MCSection
*CurSection
,
60 const MCExpr
*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), UseAssemblerInfoForParsing(false) {
96 SectionStack
.push_back(std::pair
<MCSectionSubPair
, MCSectionSubPair
>());
99 MCStreamer::~MCStreamer() {}
101 void MCStreamer::reset() {
102 DwarfFrameInfos
.clear();
103 CurrentWinFrameInfo
= nullptr;
104 WinFrameInfos
.clear();
105 SymbolOrdering
.clear();
106 SectionStack
.clear();
107 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
.Instructions
) : 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
? support::little
: support::big
);
140 unsigned Index
= IsLittleEndian
? 0 : 8 - Size
;
141 emitBytes(StringRef(reinterpret_cast<char *>(&Swapped
) + Index
, Size
));
143 void MCStreamer::emitIntValue(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 void 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());
168 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
169 /// client having to pass in a MCExpr for constant integers.
170 void MCStreamer::emitSLEB128IntValue(int64_t Value
) {
171 SmallString
<128> Tmp
;
172 raw_svector_ostream
OSE(Tmp
);
173 encodeSLEB128(Value
, OSE
);
174 emitBytes(OSE
.str());
177 void MCStreamer::emitValue(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
178 emitValueImpl(Value
, Size
, Loc
);
181 void MCStreamer::emitSymbolValue(const MCSymbol
*Sym
, unsigned Size
,
182 bool IsSectionRelative
) {
183 assert((!IsSectionRelative
|| Size
== 4) &&
184 "SectionRelative value requires 4-bytes");
186 if (!IsSectionRelative
)
187 emitValueImpl(MCSymbolRefExpr::create(Sym
, getContext()), Size
);
189 EmitCOFFSecRel32(Sym
, /*Offset=*/0);
192 void MCStreamer::emitDTPRel64Value(const MCExpr
*Value
) {
193 report_fatal_error("unsupported directive in streamer");
196 void MCStreamer::emitDTPRel32Value(const MCExpr
*Value
) {
197 report_fatal_error("unsupported directive in streamer");
200 void MCStreamer::emitTPRel64Value(const MCExpr
*Value
) {
201 report_fatal_error("unsupported directive in streamer");
204 void MCStreamer::emitTPRel32Value(const MCExpr
*Value
) {
205 report_fatal_error("unsupported directive in streamer");
208 void MCStreamer::emitGPRel64Value(const MCExpr
*Value
) {
209 report_fatal_error("unsupported directive in streamer");
212 void MCStreamer::emitGPRel32Value(const MCExpr
*Value
) {
213 report_fatal_error("unsupported directive in streamer");
216 /// Emit NumBytes bytes worth of the value specified by FillValue.
217 /// This implements directives such as '.space'.
218 void MCStreamer::emitFill(uint64_t NumBytes
, uint8_t FillValue
) {
219 emitFill(*MCConstantExpr::create(NumBytes
, getContext()), FillValue
);
222 void llvm::MCStreamer::emitNops(int64_t NumBytes
, int64_t ControlledNopLen
,
223 llvm::SMLoc
, const MCSubtargetInfo
& STI
) {}
225 /// The implementation in this class just redirects to emitFill.
226 void MCStreamer::emitZeros(uint64_t NumBytes
) { emitFill(NumBytes
, 0); }
229 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo
, StringRef Directory
,
231 Optional
<MD5::MD5Result
> Checksum
,
232 Optional
<StringRef
> Source
,
234 return getContext().getDwarfFile(Directory
, Filename
, FileNo
, Checksum
,
238 void MCStreamer::emitDwarfFile0Directive(StringRef Directory
,
240 Optional
<MD5::MD5Result
> Checksum
,
241 Optional
<StringRef
> Source
,
243 getContext().setMCLineTableRootFile(CUID
, Directory
, Filename
, Checksum
,
247 void MCStreamer::emitCFIBKeyFrame() {
248 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
251 CurFrame
->IsBKeyFrame
= true;
254 void MCStreamer::emitDwarfLocDirective(unsigned FileNo
, unsigned Line
,
255 unsigned Column
, unsigned Flags
,
256 unsigned Isa
, unsigned Discriminator
,
257 StringRef FileName
) {
258 getContext().setCurrentDwarfLoc(FileNo
, Line
, Column
, Flags
, Isa
,
262 MCSymbol
*MCStreamer::getDwarfLineTableSymbol(unsigned CUID
) {
263 MCDwarfLineTable
&Table
= getContext().getMCDwarfLineTable(CUID
);
264 if (!Table
.getLabel()) {
265 StringRef Prefix
= Context
.getAsmInfo()->getPrivateGlobalPrefix();
267 Context
.getOrCreateSymbol(Prefix
+ "line_table_start" + Twine(CUID
)));
269 return Table
.getLabel();
272 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
273 return !DwarfFrameInfos
.empty() && !DwarfFrameInfos
.back().End
;
276 MCDwarfFrameInfo
*MCStreamer::getCurrentDwarfFrameInfo() {
277 if (!hasUnfinishedDwarfFrameInfo()) {
278 getContext().reportError(getStartTokLoc(),
279 "this directive must appear between "
280 ".cfi_startproc and .cfi_endproc directives");
283 return &DwarfFrameInfos
.back();
286 bool MCStreamer::EmitCVFileDirective(unsigned FileNo
, StringRef Filename
,
287 ArrayRef
<uint8_t> Checksum
,
288 unsigned ChecksumKind
) {
289 return getContext().getCVContext().addFile(*this, FileNo
, Filename
, Checksum
,
293 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId
) {
294 return getContext().getCVContext().recordFunctionId(FunctionId
);
297 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId
,
298 unsigned IAFunc
, unsigned IAFile
,
299 unsigned IALine
, unsigned IACol
,
301 if (getContext().getCVContext().getCVFunctionInfo(IAFunc
) == nullptr) {
302 getContext().reportError(Loc
, "parent function id not introduced by "
303 ".cv_func_id or .cv_inline_site_id");
307 return getContext().getCVContext().recordInlinedCallSiteId(
308 FunctionId
, IAFunc
, IAFile
, IALine
, IACol
);
311 void MCStreamer::emitCVLocDirective(unsigned FunctionId
, unsigned FileNo
,
312 unsigned Line
, unsigned Column
,
313 bool PrologueEnd
, bool IsStmt
,
314 StringRef FileName
, SMLoc Loc
) {}
316 bool MCStreamer::checkCVLocSection(unsigned FuncId
, unsigned FileNo
,
318 CodeViewContext
&CVC
= getContext().getCVContext();
319 MCCVFunctionInfo
*FI
= CVC
.getCVFunctionInfo(FuncId
);
321 getContext().reportError(
322 Loc
, "function id not introduced by .cv_func_id or .cv_inline_site_id");
327 if (FI
->Section
== nullptr)
328 FI
->Section
= getCurrentSectionOnly();
329 else if (FI
->Section
!= getCurrentSectionOnly()) {
330 getContext().reportError(
332 "all .cv_loc directives for a function must be in the same section");
338 void MCStreamer::emitCVLinetableDirective(unsigned FunctionId
,
339 const MCSymbol
*Begin
,
340 const MCSymbol
*End
) {}
342 void MCStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId
,
343 unsigned SourceFileId
,
344 unsigned SourceLineNum
,
345 const MCSymbol
*FnStartSym
,
346 const MCSymbol
*FnEndSym
) {}
348 /// Only call this on endian-specific types like ulittle16_t and little32_t, or
349 /// structs composed of them.
350 template <typename T
>
351 static void copyBytesForDefRange(SmallString
<20> &BytePrefix
,
352 codeview::SymbolKind SymKind
,
353 const T
&DefRangeHeader
) {
354 BytePrefix
.resize(2 + sizeof(T
));
355 codeview::ulittle16_t SymKindLE
= codeview::ulittle16_t(SymKind
);
356 memcpy(&BytePrefix
[0], &SymKindLE
, 2);
357 memcpy(&BytePrefix
[2], &DefRangeHeader
, sizeof(T
));
360 void MCStreamer::emitCVDefRangeDirective(
361 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
362 StringRef FixedSizePortion
) {}
364 void MCStreamer::emitCVDefRangeDirective(
365 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
366 codeview::DefRangeRegisterRelHeader DRHdr
) {
367 SmallString
<20> BytePrefix
;
368 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_REGISTER_REL
, DRHdr
);
369 emitCVDefRangeDirective(Ranges
, BytePrefix
);
372 void MCStreamer::emitCVDefRangeDirective(
373 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
374 codeview::DefRangeSubfieldRegisterHeader DRHdr
) {
375 SmallString
<20> BytePrefix
;
376 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_SUBFIELD_REGISTER
,
378 emitCVDefRangeDirective(Ranges
, BytePrefix
);
381 void MCStreamer::emitCVDefRangeDirective(
382 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
383 codeview::DefRangeRegisterHeader DRHdr
) {
384 SmallString
<20> BytePrefix
;
385 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_REGISTER
, DRHdr
);
386 emitCVDefRangeDirective(Ranges
, BytePrefix
);
389 void MCStreamer::emitCVDefRangeDirective(
390 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
391 codeview::DefRangeFramePointerRelHeader DRHdr
) {
392 SmallString
<20> BytePrefix
;
393 copyBytesForDefRange(BytePrefix
, codeview::S_DEFRANGE_FRAMEPOINTER_REL
,
395 emitCVDefRangeDirective(Ranges
, BytePrefix
);
398 void MCStreamer::emitEHSymAttributes(const MCSymbol
*Symbol
,
399 MCSymbol
*EHSymbol
) {
402 void MCStreamer::initSections(bool NoExecStack
, const MCSubtargetInfo
&STI
) {
403 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
406 void MCStreamer::AssignFragment(MCSymbol
*Symbol
, MCFragment
*Fragment
) {
408 Symbol
->setFragment(Fragment
);
410 // As we emit symbols into a section, track the order so that they can
411 // be sorted upon later. Zero is reserved to mean 'unemitted'.
412 SymbolOrdering
[Symbol
] = 1 + SymbolOrdering
.size();
415 void MCStreamer::emitLabel(MCSymbol
*Symbol
, SMLoc Loc
) {
416 Symbol
->redefineIfPossible();
418 if (!Symbol
->isUndefined() || Symbol
->isVariable())
419 return getContext().reportError(Loc
, "symbol '" + Twine(Symbol
->getName()) +
420 "' is already defined");
422 assert(!Symbol
->isVariable() && "Cannot emit a variable symbol!");
423 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
424 assert(!Symbol
->getFragment() && "Unexpected fragment on symbol data!");
425 assert(Symbol
->isUndefined() && "Cannot define a symbol twice!");
427 Symbol
->setFragment(&getCurrentSectionOnly()->getDummyFragment());
429 MCTargetStreamer
*TS
= getTargetStreamer();
431 TS
->emitLabel(Symbol
);
434 void MCStreamer::emitCFISections(bool EH
, bool Debug
) {}
436 void MCStreamer::emitCFIStartProc(bool IsSimple
, SMLoc Loc
) {
437 if (hasUnfinishedDwarfFrameInfo())
438 return getContext().reportError(
439 Loc
, "starting new .cfi frame before finishing the previous one");
441 MCDwarfFrameInfo Frame
;
442 Frame
.IsSimple
= IsSimple
;
443 emitCFIStartProcImpl(Frame
);
445 const MCAsmInfo
* MAI
= Context
.getAsmInfo();
447 for (const MCCFIInstruction
& Inst
: MAI
->getInitialFrameState()) {
448 if (Inst
.getOperation() == MCCFIInstruction::OpDefCfa
||
449 Inst
.getOperation() == MCCFIInstruction::OpDefCfaRegister
||
450 Inst
.getOperation() == MCCFIInstruction::OpLLVMDefAspaceCfa
) {
451 Frame
.CurrentCfaRegister
= Inst
.getRegister();
456 DwarfFrameInfos
.push_back(Frame
);
459 void MCStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) {
462 void MCStreamer::emitCFIEndProc() {
463 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
466 emitCFIEndProcImpl(*CurFrame
);
469 void MCStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) {
470 // Put a dummy non-null value in Frame.End to mark that this frame has been
472 Frame
.End
= (MCSymbol
*)1;
475 MCSymbol
*MCStreamer::emitCFILabel() {
476 // Return a dummy non-null value so that label fields appear filled in when
477 // generating textual assembly.
478 return (MCSymbol
*)1;
481 void MCStreamer::emitCFIDefCfa(int64_t Register
, int64_t Offset
) {
482 MCSymbol
*Label
= emitCFILabel();
483 MCCFIInstruction Instruction
=
484 MCCFIInstruction::cfiDefCfa(Label
, Register
, Offset
);
485 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
488 CurFrame
->Instructions
.push_back(Instruction
);
489 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
492 void MCStreamer::emitCFIDefCfaOffset(int64_t Offset
) {
493 MCSymbol
*Label
= emitCFILabel();
494 MCCFIInstruction Instruction
=
495 MCCFIInstruction::cfiDefCfaOffset(Label
, Offset
);
496 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
499 CurFrame
->Instructions
.push_back(Instruction
);
502 void MCStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment
) {
503 MCSymbol
*Label
= emitCFILabel();
504 MCCFIInstruction Instruction
=
505 MCCFIInstruction::createAdjustCfaOffset(Label
, Adjustment
);
506 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
509 CurFrame
->Instructions
.push_back(Instruction
);
512 void MCStreamer::emitCFIDefCfaRegister(int64_t Register
) {
513 MCSymbol
*Label
= emitCFILabel();
514 MCCFIInstruction Instruction
=
515 MCCFIInstruction::createDefCfaRegister(Label
, Register
);
516 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
519 CurFrame
->Instructions
.push_back(Instruction
);
520 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
523 void MCStreamer::emitCFILLVMDefAspaceCfa(int64_t Register
, int64_t Offset
,
524 int64_t AddressSpace
) {
525 MCSymbol
*Label
= emitCFILabel();
526 MCCFIInstruction Instruction
= MCCFIInstruction::createLLVMDefAspaceCfa(
527 Label
, Register
, Offset
, AddressSpace
);
528 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
531 CurFrame
->Instructions
.push_back(Instruction
);
532 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
535 void MCStreamer::emitCFIOffset(int64_t Register
, int64_t Offset
) {
536 MCSymbol
*Label
= emitCFILabel();
537 MCCFIInstruction Instruction
=
538 MCCFIInstruction::createOffset(Label
, Register
, Offset
);
539 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
542 CurFrame
->Instructions
.push_back(Instruction
);
545 void MCStreamer::emitCFIRelOffset(int64_t Register
, int64_t Offset
) {
546 MCSymbol
*Label
= emitCFILabel();
547 MCCFIInstruction Instruction
=
548 MCCFIInstruction::createRelOffset(Label
, Register
, Offset
);
549 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
552 CurFrame
->Instructions
.push_back(Instruction
);
555 void MCStreamer::emitCFIPersonality(const MCSymbol
*Sym
,
557 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
560 CurFrame
->Personality
= Sym
;
561 CurFrame
->PersonalityEncoding
= Encoding
;
564 void MCStreamer::emitCFILsda(const MCSymbol
*Sym
, unsigned Encoding
) {
565 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
568 CurFrame
->Lsda
= Sym
;
569 CurFrame
->LsdaEncoding
= Encoding
;
572 void MCStreamer::emitCFIRememberState() {
573 MCSymbol
*Label
= emitCFILabel();
574 MCCFIInstruction Instruction
= MCCFIInstruction::createRememberState(Label
);
575 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
578 CurFrame
->Instructions
.push_back(Instruction
);
581 void MCStreamer::emitCFIRestoreState() {
582 // FIXME: Error if there is no matching cfi_remember_state.
583 MCSymbol
*Label
= emitCFILabel();
584 MCCFIInstruction Instruction
= MCCFIInstruction::createRestoreState(Label
);
585 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
588 CurFrame
->Instructions
.push_back(Instruction
);
591 void MCStreamer::emitCFISameValue(int64_t Register
) {
592 MCSymbol
*Label
= emitCFILabel();
593 MCCFIInstruction Instruction
=
594 MCCFIInstruction::createSameValue(Label
, Register
);
595 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
598 CurFrame
->Instructions
.push_back(Instruction
);
601 void MCStreamer::emitCFIRestore(int64_t Register
) {
602 MCSymbol
*Label
= emitCFILabel();
603 MCCFIInstruction Instruction
=
604 MCCFIInstruction::createRestore(Label
, Register
);
605 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
608 CurFrame
->Instructions
.push_back(Instruction
);
611 void MCStreamer::emitCFIEscape(StringRef Values
) {
612 MCSymbol
*Label
= emitCFILabel();
613 MCCFIInstruction Instruction
= MCCFIInstruction::createEscape(Label
, Values
);
614 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
617 CurFrame
->Instructions
.push_back(Instruction
);
620 void MCStreamer::emitCFIGnuArgsSize(int64_t Size
) {
621 MCSymbol
*Label
= emitCFILabel();
622 MCCFIInstruction Instruction
=
623 MCCFIInstruction::createGnuArgsSize(Label
, Size
);
624 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
627 CurFrame
->Instructions
.push_back(Instruction
);
630 void MCStreamer::emitCFISignalFrame() {
631 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
634 CurFrame
->IsSignalFrame
= true;
637 void MCStreamer::emitCFIUndefined(int64_t Register
) {
638 MCSymbol
*Label
= emitCFILabel();
639 MCCFIInstruction Instruction
=
640 MCCFIInstruction::createUndefined(Label
, Register
);
641 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
644 CurFrame
->Instructions
.push_back(Instruction
);
647 void MCStreamer::emitCFIRegister(int64_t Register1
, int64_t Register2
) {
648 MCSymbol
*Label
= emitCFILabel();
649 MCCFIInstruction Instruction
=
650 MCCFIInstruction::createRegister(Label
, Register1
, Register2
);
651 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
654 CurFrame
->Instructions
.push_back(Instruction
);
657 void MCStreamer::emitCFIWindowSave() {
658 MCSymbol
*Label
= emitCFILabel();
659 MCCFIInstruction Instruction
=
660 MCCFIInstruction::createWindowSave(Label
);
661 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
664 CurFrame
->Instructions
.push_back(Instruction
);
667 void MCStreamer::emitCFINegateRAState() {
668 MCSymbol
*Label
= emitCFILabel();
669 MCCFIInstruction Instruction
= MCCFIInstruction::createNegateRAState(Label
);
670 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
673 CurFrame
->Instructions
.push_back(Instruction
);
676 void MCStreamer::emitCFIReturnColumn(int64_t Register
) {
677 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
680 CurFrame
->RAReg
= Register
;
683 WinEH::FrameInfo
*MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc
) {
684 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
685 if (!MAI
->usesWindowsCFI()) {
686 getContext().reportError(
687 Loc
, ".seh_* directives are not supported on this target");
690 if (!CurrentWinFrameInfo
|| CurrentWinFrameInfo
->End
) {
691 getContext().reportError(
692 Loc
, ".seh_ directive must appear within an active frame");
695 return CurrentWinFrameInfo
;
698 void MCStreamer::EmitWinCFIStartProc(const MCSymbol
*Symbol
, SMLoc Loc
) {
699 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
700 if (!MAI
->usesWindowsCFI())
701 return getContext().reportError(
702 Loc
, ".seh_* directives are not supported on this target");
703 if (CurrentWinFrameInfo
&& !CurrentWinFrameInfo
->End
)
704 getContext().reportError(
705 Loc
, "Starting a function before ending the previous one!");
707 MCSymbol
*StartProc
= emitCFILabel();
709 CurrentProcWinFrameInfoStartIndex
= WinFrameInfos
.size();
710 WinFrameInfos
.emplace_back(
711 std::make_unique
<WinEH::FrameInfo
>(Symbol
, StartProc
));
712 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
713 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
716 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc
) {
717 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
720 if (CurFrame
->ChainedParent
)
721 getContext().reportError(Loc
, "Not all chained regions terminated!");
723 MCSymbol
*Label
= emitCFILabel();
724 CurFrame
->End
= Label
;
725 if (!CurFrame
->FuncletOrFuncEnd
)
726 CurFrame
->FuncletOrFuncEnd
= CurFrame
->End
;
728 for (size_t I
= CurrentProcWinFrameInfoStartIndex
, E
= WinFrameInfos
.size();
730 EmitWindowsUnwindTables(WinFrameInfos
[I
].get());
731 SwitchSection(CurFrame
->TextSection
);
734 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc
) {
735 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
738 if (CurFrame
->ChainedParent
)
739 getContext().reportError(Loc
, "Not all chained regions terminated!");
741 MCSymbol
*Label
= emitCFILabel();
742 CurFrame
->FuncletOrFuncEnd
= Label
;
745 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc
) {
746 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
750 MCSymbol
*StartProc
= emitCFILabel();
752 WinFrameInfos
.emplace_back(std::make_unique
<WinEH::FrameInfo
>(
753 CurFrame
->Function
, StartProc
, CurFrame
));
754 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
755 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
758 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc
) {
759 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
762 if (!CurFrame
->ChainedParent
)
763 return getContext().reportError(
764 Loc
, "End of a chained region outside a chained region!");
766 MCSymbol
*Label
= emitCFILabel();
768 CurFrame
->End
= Label
;
769 CurrentWinFrameInfo
= const_cast<WinEH::FrameInfo
*>(CurFrame
->ChainedParent
);
772 void MCStreamer::EmitWinEHHandler(const MCSymbol
*Sym
, bool Unwind
, bool Except
,
774 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
777 if (CurFrame
->ChainedParent
)
778 return getContext().reportError(
779 Loc
, "Chained unwind areas can't have handlers!");
780 CurFrame
->ExceptionHandler
= Sym
;
781 if (!Except
&& !Unwind
)
782 getContext().reportError(Loc
, "Don't know what kind of handler this is!");
784 CurFrame
->HandlesUnwind
= true;
786 CurFrame
->HandlesExceptions
= true;
789 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc
) {
790 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
793 if (CurFrame
->ChainedParent
)
794 getContext().reportError(Loc
, "Chained unwind areas can't have handlers!");
797 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr
*From
,
798 const MCSymbolRefExpr
*To
, uint64_t Count
) {
801 static MCSection
*getWinCFISection(MCContext
&Context
, unsigned *NextWinCFIID
,
802 MCSection
*MainCFISec
,
803 const MCSection
*TextSec
) {
804 // If this is the main .text section, use the main unwind info section.
805 if (TextSec
== Context
.getObjectFileInfo()->getTextSection())
808 const auto *TextSecCOFF
= cast
<MCSectionCOFF
>(TextSec
);
809 auto *MainCFISecCOFF
= cast
<MCSectionCOFF
>(MainCFISec
);
810 unsigned UniqueID
= TextSecCOFF
->getOrAssignWinCFISectionID(NextWinCFIID
);
812 // If this section is COMDAT, this unwind section should be COMDAT associative
814 const MCSymbol
*KeySym
= nullptr;
815 if (TextSecCOFF
->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT
) {
816 KeySym
= TextSecCOFF
->getCOMDATSymbol();
818 // In a GNU environment, we can't use associative comdats. Instead, do what
819 // GCC does, which is to make plain comdat selectany section named like
820 // ".[px]data$_Z3foov".
821 if (!Context
.getAsmInfo()->hasCOFFAssociativeComdats()) {
822 std::string SectionName
= (MainCFISecCOFF
->getName() + "$" +
823 TextSecCOFF
->getName().split('$').second
)
825 return Context
.getCOFFSection(
827 MainCFISecCOFF
->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT
,
828 MainCFISecCOFF
->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY
);
832 return Context
.getAssociativeCOFFSection(MainCFISecCOFF
, KeySym
, UniqueID
);
835 MCSection
*MCStreamer::getAssociatedPDataSection(const MCSection
*TextSec
) {
836 return getWinCFISection(getContext(), &NextWinCFIID
,
837 getContext().getObjectFileInfo()->getPDataSection(),
841 MCSection
*MCStreamer::getAssociatedXDataSection(const MCSection
*TextSec
) {
842 return getWinCFISection(getContext(), &NextWinCFIID
,
843 getContext().getObjectFileInfo()->getXDataSection(),
847 void MCStreamer::emitSyntaxDirective() {}
849 static unsigned encodeSEHRegNum(MCContext
&Ctx
, MCRegister Reg
) {
850 return Ctx
.getRegisterInfo()->getSEHRegNum(Reg
);
853 void MCStreamer::EmitWinCFIPushReg(MCRegister Register
, SMLoc Loc
) {
854 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
858 MCSymbol
*Label
= emitCFILabel();
860 WinEH::Instruction Inst
= Win64EH::Instruction::PushNonVol(
861 Label
, encodeSEHRegNum(Context
, Register
));
862 CurFrame
->Instructions
.push_back(Inst
);
865 void MCStreamer::EmitWinCFISetFrame(MCRegister Register
, unsigned Offset
,
867 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
870 if (CurFrame
->LastFrameInst
>= 0)
871 return getContext().reportError(
872 Loc
, "frame register and offset can be set at most once");
874 return getContext().reportError(Loc
, "offset is not a multiple of 16");
876 return getContext().reportError(
877 Loc
, "frame offset must be less than or equal to 240");
879 MCSymbol
*Label
= emitCFILabel();
881 WinEH::Instruction Inst
= Win64EH::Instruction::SetFPReg(
882 Label
, encodeSEHRegNum(getContext(), Register
), Offset
);
883 CurFrame
->LastFrameInst
= CurFrame
->Instructions
.size();
884 CurFrame
->Instructions
.push_back(Inst
);
887 void MCStreamer::EmitWinCFIAllocStack(unsigned Size
, SMLoc Loc
) {
888 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
892 return getContext().reportError(Loc
,
893 "stack allocation size must be non-zero");
895 return getContext().reportError(
896 Loc
, "stack allocation size is not a multiple of 8");
898 MCSymbol
*Label
= emitCFILabel();
900 WinEH::Instruction Inst
= Win64EH::Instruction::Alloc(Label
, Size
);
901 CurFrame
->Instructions
.push_back(Inst
);
904 void MCStreamer::EmitWinCFISaveReg(MCRegister Register
, unsigned Offset
,
906 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
911 return getContext().reportError(
912 Loc
, "register save offset is not 8 byte aligned");
914 MCSymbol
*Label
= emitCFILabel();
916 WinEH::Instruction Inst
= Win64EH::Instruction::SaveNonVol(
917 Label
, encodeSEHRegNum(Context
, Register
), Offset
);
918 CurFrame
->Instructions
.push_back(Inst
);
921 void MCStreamer::EmitWinCFISaveXMM(MCRegister Register
, unsigned Offset
,
923 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
927 return getContext().reportError(Loc
, "offset is not a multiple of 16");
929 MCSymbol
*Label
= emitCFILabel();
931 WinEH::Instruction Inst
= Win64EH::Instruction::SaveXMM(
932 Label
, encodeSEHRegNum(Context
, Register
), Offset
);
933 CurFrame
->Instructions
.push_back(Inst
);
936 void MCStreamer::EmitWinCFIPushFrame(bool Code
, SMLoc Loc
) {
937 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
940 if (!CurFrame
->Instructions
.empty())
941 return getContext().reportError(
942 Loc
, "If present, PushMachFrame must be the first UOP");
944 MCSymbol
*Label
= emitCFILabel();
946 WinEH::Instruction Inst
= Win64EH::Instruction::PushMachFrame(Label
, Code
);
947 CurFrame
->Instructions
.push_back(Inst
);
950 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc
) {
951 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
955 MCSymbol
*Label
= emitCFILabel();
957 CurFrame
->PrologEnd
= Label
;
960 void MCStreamer::EmitCOFFSafeSEH(MCSymbol
const *Symbol
) {}
962 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol
const *Symbol
) {}
964 void MCStreamer::EmitCOFFSectionIndex(MCSymbol
const *Symbol
) {}
966 void MCStreamer::EmitCOFFSecRel32(MCSymbol
const *Symbol
, uint64_t Offset
) {}
968 void MCStreamer::EmitCOFFImgRel32(MCSymbol
const *Symbol
, int64_t Offset
) {}
970 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
971 /// the specified string in the output .s file. This capability is
972 /// indicated by the hasRawTextSupport() predicate.
973 void MCStreamer::emitRawTextImpl(StringRef String
) {
974 // This is not llvm_unreachable for the sake of out of tree backend
975 // developers who may not have assembly streamers and should serve as a
976 // reminder to not accidentally call EmitRawText in the absence of such.
977 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
978 "it (target backend is likely missing an AsmStreamer "
982 void MCStreamer::emitRawText(const Twine
&T
) {
983 SmallString
<128> Str
;
984 emitRawTextImpl(T
.toStringRef(Str
));
987 void MCStreamer::EmitWindowsUnwindTables() {
990 void MCStreamer::EmitWindowsUnwindTables(WinEH::FrameInfo
*Frame
) {
993 void MCStreamer::Finish(SMLoc EndLoc
) {
994 if ((!DwarfFrameInfos
.empty() && !DwarfFrameInfos
.back().End
) ||
995 (!WinFrameInfos
.empty() && !WinFrameInfos
.back()->End
)) {
996 getContext().reportError(EndLoc
, "Unfinished frame!");
1000 MCTargetStreamer
*TS
= getTargetStreamer();
1007 void MCStreamer::maybeEmitDwarf64Mark() {
1008 if (Context
.getDwarfFormat() != dwarf::DWARF64
)
1010 AddComment("DWARF64 Mark");
1011 emitInt32(dwarf::DW_LENGTH_DWARF64
);
1014 void MCStreamer::emitDwarfUnitLength(uint64_t Length
, const Twine
&Comment
) {
1015 assert(Context
.getDwarfFormat() == dwarf::DWARF64
||
1016 Length
<= dwarf::DW_LENGTH_lo_reserved
);
1017 maybeEmitDwarf64Mark();
1018 AddComment(Comment
);
1019 emitIntValue(Length
, dwarf::getDwarfOffsetByteSize(Context
.getDwarfFormat()));
1022 MCSymbol
*MCStreamer::emitDwarfUnitLength(const Twine
&Prefix
,
1023 const Twine
&Comment
) {
1024 maybeEmitDwarf64Mark();
1025 AddComment(Comment
);
1026 MCSymbol
*Lo
= Context
.createTempSymbol(Prefix
+ "_start");
1027 MCSymbol
*Hi
= Context
.createTempSymbol(Prefix
+ "_end");
1029 emitAbsoluteSymbolDiff(
1030 Hi
, Lo
, dwarf::getDwarfOffsetByteSize(Context
.getDwarfFormat()));
1031 // emit the begin symbol after we generate the length field.
1033 // Return the Hi symbol to the caller.
1037 void MCStreamer::emitDwarfLineStartLabel(MCSymbol
*StartSym
) {
1038 // Set the value of the symbol, as we are at the start of the line table.
1039 emitLabel(StartSym
);
1042 void MCStreamer::emitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {
1043 visitUsedExpr(*Value
);
1044 Symbol
->setVariableValue(Value
);
1046 MCTargetStreamer
*TS
= getTargetStreamer();
1048 TS
->emitAssignment(Symbol
, Value
);
1051 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter
&InstPrinter
,
1052 uint64_t Address
, const MCInst
&Inst
,
1053 const MCSubtargetInfo
&STI
,
1055 InstPrinter
.printInst(&Inst
, Address
, "", STI
, OS
);
1058 void MCStreamer::visitUsedSymbol(const MCSymbol
&Sym
) {
1061 void MCStreamer::visitUsedExpr(const MCExpr
&Expr
) {
1062 switch (Expr
.getKind()) {
1063 case MCExpr::Target
:
1064 cast
<MCTargetExpr
>(Expr
).visitUsedExpr(*this);
1067 case MCExpr::Constant
:
1070 case MCExpr::Binary
: {
1071 const MCBinaryExpr
&BE
= cast
<MCBinaryExpr
>(Expr
);
1072 visitUsedExpr(*BE
.getLHS());
1073 visitUsedExpr(*BE
.getRHS());
1077 case MCExpr::SymbolRef
:
1078 visitUsedSymbol(cast
<MCSymbolRefExpr
>(Expr
).getSymbol());
1082 visitUsedExpr(*cast
<MCUnaryExpr
>(Expr
).getSubExpr());
1087 void MCStreamer::emitInstruction(const MCInst
&Inst
, const MCSubtargetInfo
&) {
1089 for (unsigned i
= Inst
.getNumOperands(); i
--;)
1090 if (Inst
.getOperand(i
).isExpr())
1091 visitUsedExpr(*Inst
.getOperand(i
).getExpr());
1094 void MCStreamer::emitPseudoProbe(uint64_t Guid
, uint64_t Index
, uint64_t Type
,
1096 const MCPseudoProbeInlineStack
&InlineStack
) {
1097 auto &Context
= getContext();
1099 // Create a symbol at in the current section for use in the probe.
1100 MCSymbol
*ProbeSym
= Context
.createTempSymbol();
1102 // Set the value of the symbol to use for the MCPseudoProbe.
1103 emitLabel(ProbeSym
);
1105 // Create a (local) probe entry with the symbol.
1106 MCPseudoProbe
Probe(ProbeSym
, Guid
, Index
, Type
, Attr
);
1108 // Add the probe entry to this section's entries.
1109 Context
.getMCPseudoProbeTable().getProbeSections().addPseudoProbe(
1110 getCurrentSectionOnly(), Probe
, InlineStack
);
1113 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol
*Hi
, const MCSymbol
*Lo
,
1115 // Get the Hi-Lo expression.
1116 const MCExpr
*Diff
=
1117 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
1118 MCSymbolRefExpr::create(Lo
, Context
), Context
);
1120 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
1121 if (!MAI
->doesSetDirectiveSuppressReloc()) {
1122 emitValue(Diff
, Size
);
1126 // Otherwise, emit with .set (aka assignment).
1127 MCSymbol
*SetLabel
= Context
.createTempSymbol("set");
1128 emitAssignment(SetLabel
, Diff
);
1129 emitSymbolValue(SetLabel
, Size
);
1132 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol
*Hi
,
1133 const MCSymbol
*Lo
) {
1134 // Get the Hi-Lo expression.
1135 const MCExpr
*Diff
=
1136 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
1137 MCSymbolRefExpr::create(Lo
, Context
), Context
);
1139 emitULEB128Value(Diff
);
1142 void MCStreamer::emitAssemblerFlag(MCAssemblerFlag Flag
) {}
1143 void MCStreamer::emitThumbFunc(MCSymbol
*Func
) {}
1144 void MCStreamer::emitSymbolDesc(MCSymbol
*Symbol
, unsigned DescValue
) {}
1145 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol
*Symbol
) {
1146 llvm_unreachable("this directive only supported on COFF targets");
1148 void MCStreamer::EndCOFFSymbolDef() {
1149 llvm_unreachable("this directive only supported on COFF targets");
1151 void MCStreamer::emitFileDirective(StringRef Filename
) {}
1152 void MCStreamer::emitFileDirective(StringRef Filename
, StringRef CompilerVerion
,
1153 StringRef TimeStamp
, StringRef Description
) {
1155 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass
) {
1156 llvm_unreachable("this directive only supported on COFF targets");
1158 void MCStreamer::EmitCOFFSymbolType(int Type
) {
1159 llvm_unreachable("this directive only supported on COFF targets");
1161 void MCStreamer::emitXCOFFLocalCommonSymbol(MCSymbol
*LabelSym
, uint64_t Size
,
1163 unsigned ByteAlign
) {
1164 llvm_unreachable("this directive only supported on XCOFF targets");
1167 void MCStreamer::emitXCOFFSymbolLinkageWithVisibility(MCSymbol
*Symbol
,
1168 MCSymbolAttr Linkage
,
1169 MCSymbolAttr Visibility
) {
1170 llvm_unreachable("emitXCOFFSymbolLinkageWithVisibility is only supported on "
1174 void MCStreamer::emitXCOFFRenameDirective(const MCSymbol
*Name
,
1176 llvm_unreachable("emitXCOFFRenameDirective is only supported on "
1180 void MCStreamer::emitELFSize(MCSymbol
*Symbol
, const MCExpr
*Value
) {}
1181 void MCStreamer::emitELFSymverDirective(const MCSymbol
*OriginalSym
,
1182 StringRef Name
, bool KeepOriginalSym
) {}
1183 void MCStreamer::emitLocalCommonSymbol(MCSymbol
*Symbol
, uint64_t Size
,
1184 unsigned ByteAlignment
) {}
1185 void MCStreamer::emitTBSSSymbol(MCSection
*Section
, MCSymbol
*Symbol
,
1186 uint64_t Size
, unsigned ByteAlignment
) {}
1187 void MCStreamer::changeSection(MCSection
*, const MCExpr
*) {}
1188 void MCStreamer::emitWeakReference(MCSymbol
*Alias
, const MCSymbol
*Symbol
) {}
1189 void MCStreamer::emitBytes(StringRef Data
) {}
1190 void MCStreamer::emitBinaryData(StringRef Data
) { emitBytes(Data
); }
1191 void MCStreamer::emitValueImpl(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
1192 visitUsedExpr(*Value
);
1194 void MCStreamer::emitULEB128Value(const MCExpr
*Value
) {}
1195 void MCStreamer::emitSLEB128Value(const MCExpr
*Value
) {}
1196 void MCStreamer::emitFill(const MCExpr
&NumBytes
, uint64_t Value
, SMLoc Loc
) {}
1197 void MCStreamer::emitFill(const MCExpr
&NumValues
, int64_t Size
, int64_t Expr
,
1199 void MCStreamer::emitValueToAlignment(unsigned ByteAlignment
, int64_t Value
,
1201 unsigned MaxBytesToEmit
) {}
1202 void MCStreamer::emitCodeAlignment(unsigned ByteAlignment
,
1203 const MCSubtargetInfo
*STI
,
1204 unsigned MaxBytesToEmit
) {}
1205 void MCStreamer::emitValueToOffset(const MCExpr
*Offset
, unsigned char Value
,
1207 void MCStreamer::emitBundleAlignMode(unsigned AlignPow2
) {}
1208 void MCStreamer::emitBundleLock(bool AlignToEnd
) {}
1209 void MCStreamer::finishImpl() {}
1210 void MCStreamer::emitBundleUnlock() {}
1212 void MCStreamer::SwitchSection(MCSection
*Section
, const MCExpr
*Subsection
) {
1213 assert(Section
&& "Cannot switch to a null section!");
1214 MCSectionSubPair curSection
= SectionStack
.back().first
;
1215 SectionStack
.back().second
= curSection
;
1216 if (MCSectionSubPair(Section
, Subsection
) != curSection
) {
1217 changeSection(Section
, Subsection
);
1218 SectionStack
.back().first
= MCSectionSubPair(Section
, Subsection
);
1219 assert(!Section
->hasEnded() && "Section already ended");
1220 MCSymbol
*Sym
= Section
->getBeginSymbol();
1221 if (Sym
&& !Sym
->isInSection())
1226 MCSymbol
*MCStreamer::endSection(MCSection
*Section
) {
1227 // TODO: keep track of the last subsection so that this symbol appears in the
1229 MCSymbol
*Sym
= Section
->getEndSymbol(Context
);
1230 if (Sym
->isInSection())
1233 SwitchSection(Section
);
1239 targetVersionOrMinimumSupportedOSVersion(const Triple
&Target
,
1240 VersionTuple TargetVersion
) {
1241 VersionTuple Min
= Target
.getMinimumSupportedOSVersion();
1242 return !Min
.empty() && Min
> TargetVersion
? Min
: TargetVersion
;
1245 static MCVersionMinType
1246 getMachoVersionMinLoadCommandType(const Triple
&Target
) {
1247 assert(Target
.isOSDarwin() && "expected a darwin OS");
1248 switch (Target
.getOS()) {
1249 case Triple::MacOSX
:
1250 case Triple::Darwin
:
1251 return MCVM_OSXVersionMin
;
1253 assert(!Target
.isMacCatalystEnvironment() &&
1254 "mac Catalyst should use LC_BUILD_VERSION");
1255 return MCVM_IOSVersionMin
;
1257 return MCVM_TvOSVersionMin
;
1258 case Triple::WatchOS
:
1259 return MCVM_WatchOSVersionMin
;
1263 llvm_unreachable("unexpected OS type");
1266 static VersionTuple
getMachoBuildVersionSupportedOS(const Triple
&Target
) {
1267 assert(Target
.isOSDarwin() && "expected a darwin OS");
1268 switch (Target
.getOS()) {
1269 case Triple::MacOSX
:
1270 case Triple::Darwin
:
1271 return VersionTuple(10, 14);
1273 // Mac Catalyst always uses the build version load command.
1274 if (Target
.isMacCatalystEnvironment())
1275 return VersionTuple();
1278 return VersionTuple(12);
1279 case Triple::WatchOS
:
1280 return VersionTuple(5);
1284 llvm_unreachable("unexpected OS type");
1287 static MachO::PlatformType
1288 getMachoBuildVersionPlatformType(const Triple
&Target
) {
1289 assert(Target
.isOSDarwin() && "expected a darwin OS");
1290 switch (Target
.getOS()) {
1291 case Triple::MacOSX
:
1292 case Triple::Darwin
:
1293 return MachO::PLATFORM_MACOS
;
1295 if (Target
.isMacCatalystEnvironment())
1296 return MachO::PLATFORM_MACCATALYST
;
1297 return Target
.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
1298 : MachO::PLATFORM_IOS
;
1300 return Target
.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
1301 : MachO::PLATFORM_TVOS
;
1302 case Triple::WatchOS
:
1303 return Target
.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
1304 : MachO::PLATFORM_WATCHOS
;
1308 llvm_unreachable("unexpected OS type");
1311 void MCStreamer::emitVersionForTarget(const Triple
&Target
,
1312 const VersionTuple
&SDKVersion
) {
1313 if (!Target
.isOSBinFormatMachO() || !Target
.isOSDarwin())
1315 // Do we even know the version?
1316 if (Target
.getOSMajorVersion() == 0)
1321 unsigned Update
= 0;
1322 switch (Target
.getOS()) {
1323 case Triple::MacOSX
:
1324 case Triple::Darwin
:
1325 Target
.getMacOSXVersion(Major
, Minor
, Update
);
1329 Target
.getiOSVersion(Major
, Minor
, Update
);
1331 case Triple::WatchOS
:
1332 Target
.getWatchOSVersion(Major
, Minor
, Update
);
1335 llvm_unreachable("unexpected OS type");
1337 assert(Major
!= 0 && "A non-zero major version is expected");
1338 auto LinkedTargetVersion
= targetVersionOrMinimumSupportedOSVersion(
1339 Target
, VersionTuple(Major
, Minor
, Update
));
1340 auto BuildVersionOSVersion
= getMachoBuildVersionSupportedOS(Target
);
1341 if (BuildVersionOSVersion
.empty() ||
1342 LinkedTargetVersion
>= BuildVersionOSVersion
)
1343 return emitBuildVersion(getMachoBuildVersionPlatformType(Target
),
1344 LinkedTargetVersion
.getMajor(),
1345 *LinkedTargetVersion
.getMinor(),
1346 *LinkedTargetVersion
.getSubminor(), SDKVersion
);
1348 emitVersionMin(getMachoVersionMinLoadCommandType(Target
),
1349 LinkedTargetVersion
.getMajor(),
1350 *LinkedTargetVersion
.getMinor(),
1351 *LinkedTargetVersion
.getSubminor(), SDKVersion
);