[LoopSimplifyCFG] Do not require MSSA. Continue to preserve if available.
[llvm-project.git] / llvm / lib / MC / MCStreamer.cpp
blobf4e64b42c817be889b0fa0c5f57e54a519a9617e
1 //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
2 //
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
6 //
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"
38 #include <cassert>
39 #include <cstdint>
40 #include <cstdlib>
41 #include <utility>
43 using namespace llvm;
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,
59 MCSection *Section,
60 const MCExpr *Subsection,
61 raw_ostream &OS) {
62 Section->PrintSwitchToSection(*Streamer.getContext().getAsmInfo(),
63 Streamer.getContext().getTargetTriple(), OS,
64 Subsection);
67 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
68 Streamer.emitRawText(Directive);
71 void MCTargetStreamer::emitValue(const MCExpr *Value) {
72 SmallString<128> Str;
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()) {
83 SmallString<128> Str;
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.
112 return nulls();
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)) &&
136 "Invalid size");
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);
146 return;
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;
153 SmallString<10> Tmp;
154 Tmp.resize(Size);
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);
188 else
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); }
228 Expected<unsigned>
229 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
230 StringRef Filename,
231 Optional<MD5::MD5Result> Checksum,
232 Optional<StringRef> Source,
233 unsigned CUID) {
234 return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
235 Source, CUID);
238 void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
239 StringRef Filename,
240 Optional<MD5::MD5Result> Checksum,
241 Optional<StringRef> Source,
242 unsigned CUID) {
243 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
244 Source);
247 void MCStreamer::emitCFIBKeyFrame() {
248 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
249 if (!CurFrame)
250 return;
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,
259 Discriminator);
262 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
263 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
264 if (!Table.getLabel()) {
265 StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
266 Table.setLabel(
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");
281 return nullptr;
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,
290 ChecksumKind);
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,
300 SMLoc Loc) {
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");
304 return true;
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,
317 SMLoc Loc) {
318 CodeViewContext &CVC = getContext().getCVContext();
319 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId);
320 if (!FI) {
321 getContext().reportError(
322 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
323 return false;
326 // Track the section
327 if (FI->Section == nullptr)
328 FI->Section = getCurrentSectionOnly();
329 else if (FI->Section != getCurrentSectionOnly()) {
330 getContext().reportError(
331 Loc,
332 "all .cv_loc directives for a function must be in the same section");
333 return false;
335 return true;
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,
377 DRHdr);
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,
394 DRHdr);
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) {
407 assert(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();
430 if (TS)
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();
446 if (MAI) {
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();
464 if (!CurFrame)
465 return;
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
471 // closed.
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();
486 if (!CurFrame)
487 return;
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();
497 if (!CurFrame)
498 return;
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();
507 if (!CurFrame)
508 return;
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();
517 if (!CurFrame)
518 return;
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();
529 if (!CurFrame)
530 return;
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();
540 if (!CurFrame)
541 return;
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();
550 if (!CurFrame)
551 return;
552 CurFrame->Instructions.push_back(Instruction);
555 void MCStreamer::emitCFIPersonality(const MCSymbol *Sym,
556 unsigned Encoding) {
557 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
558 if (!CurFrame)
559 return;
560 CurFrame->Personality = Sym;
561 CurFrame->PersonalityEncoding = Encoding;
564 void MCStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
565 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
566 if (!CurFrame)
567 return;
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();
576 if (!CurFrame)
577 return;
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();
586 if (!CurFrame)
587 return;
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();
596 if (!CurFrame)
597 return;
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();
606 if (!CurFrame)
607 return;
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();
615 if (!CurFrame)
616 return;
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();
625 if (!CurFrame)
626 return;
627 CurFrame->Instructions.push_back(Instruction);
630 void MCStreamer::emitCFISignalFrame() {
631 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
632 if (!CurFrame)
633 return;
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();
642 if (!CurFrame)
643 return;
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();
652 if (!CurFrame)
653 return;
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();
662 if (!CurFrame)
663 return;
664 CurFrame->Instructions.push_back(Instruction);
667 void MCStreamer::emitCFINegateRAState() {
668 MCSymbol *Label = emitCFILabel();
669 MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label);
670 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
671 if (!CurFrame)
672 return;
673 CurFrame->Instructions.push_back(Instruction);
676 void MCStreamer::emitCFIReturnColumn(int64_t Register) {
677 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
678 if (!CurFrame)
679 return;
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");
688 return nullptr;
690 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
691 getContext().reportError(
692 Loc, ".seh_ directive must appear within an active frame");
693 return nullptr;
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);
718 if (!CurFrame)
719 return;
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();
729 I != E; ++I)
730 EmitWindowsUnwindTables(WinFrameInfos[I].get());
731 SwitchSection(CurFrame->TextSection);
734 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
735 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
736 if (!CurFrame)
737 return;
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);
747 if (!CurFrame)
748 return;
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);
760 if (!CurFrame)
761 return;
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,
773 SMLoc Loc) {
774 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
775 if (!CurFrame)
776 return;
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!");
783 if (Unwind)
784 CurFrame->HandlesUnwind = true;
785 if (Except)
786 CurFrame->HandlesExceptions = true;
789 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
790 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
791 if (!CurFrame)
792 return;
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())
806 return MainCFISec;
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
813 // with its group.
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)
824 .str();
825 return Context.getCOFFSection(
826 SectionName,
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(),
838 TextSec);
841 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
842 return getWinCFISection(getContext(), &NextWinCFIID,
843 getContext().getObjectFileInfo()->getXDataSection(),
844 TextSec);
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);
855 if (!CurFrame)
856 return;
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,
866 SMLoc Loc) {
867 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
868 if (!CurFrame)
869 return;
870 if (CurFrame->LastFrameInst >= 0)
871 return getContext().reportError(
872 Loc, "frame register and offset can be set at most once");
873 if (Offset & 0x0F)
874 return getContext().reportError(Loc, "offset is not a multiple of 16");
875 if (Offset > 240)
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);
889 if (!CurFrame)
890 return;
891 if (Size == 0)
892 return getContext().reportError(Loc,
893 "stack allocation size must be non-zero");
894 if (Size & 7)
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,
905 SMLoc Loc) {
906 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
907 if (!CurFrame)
908 return;
910 if (Offset & 7)
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,
922 SMLoc Loc) {
923 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
924 if (!CurFrame)
925 return;
926 if (Offset & 0x0F)
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);
938 if (!CurFrame)
939 return;
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);
952 if (!CurFrame)
953 return;
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 "
979 "implementation)");
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!");
997 return;
1000 MCTargetStreamer *TS = getTargetStreamer();
1001 if (TS)
1002 TS->finish();
1004 finishImpl();
1007 void MCStreamer::maybeEmitDwarf64Mark() {
1008 if (Context.getDwarfFormat() != dwarf::DWARF64)
1009 return;
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.
1032 emitLabel(Lo);
1033 // Return the Hi symbol to the caller.
1034 return Hi;
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();
1047 if (TS)
1048 TS->emitAssignment(Symbol, Value);
1051 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
1052 uint64_t Address, const MCInst &Inst,
1053 const MCSubtargetInfo &STI,
1054 raw_ostream &OS) {
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);
1065 break;
1067 case MCExpr::Constant:
1068 break;
1070 case MCExpr::Binary: {
1071 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
1072 visitUsedExpr(*BE.getLHS());
1073 visitUsedExpr(*BE.getRHS());
1074 break;
1077 case MCExpr::SymbolRef:
1078 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
1079 break;
1081 case MCExpr::Unary:
1082 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
1083 break;
1087 void MCStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
1088 // Scan for values.
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,
1095 uint64_t Attr,
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,
1114 unsigned Size) {
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);
1123 return;
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,
1162 MCSymbol *CsectSym,
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 "
1171 "XCOFF targets");
1174 void MCStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
1175 StringRef Rename) {
1176 llvm_unreachable("emitXCOFFRenameDirective is only supported on "
1177 "XCOFF targets");
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,
1198 SMLoc Loc) {}
1199 void MCStreamer::emitValueToAlignment(unsigned ByteAlignment, int64_t Value,
1200 unsigned ValueSize,
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,
1206 SMLoc Loc) {}
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())
1222 emitLabel(Sym);
1226 MCSymbol *MCStreamer::endSection(MCSection *Section) {
1227 // TODO: keep track of the last subsection so that this symbol appears in the
1228 // correct place.
1229 MCSymbol *Sym = Section->getEndSymbol(Context);
1230 if (Sym->isInSection())
1231 return Sym;
1233 SwitchSection(Section);
1234 emitLabel(Sym);
1235 return Sym;
1238 static VersionTuple
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;
1252 case Triple::IOS:
1253 assert(!Target.isMacCatalystEnvironment() &&
1254 "mac Catalyst should use LC_BUILD_VERSION");
1255 return MCVM_IOSVersionMin;
1256 case Triple::TvOS:
1257 return MCVM_TvOSVersionMin;
1258 case Triple::WatchOS:
1259 return MCVM_WatchOSVersionMin;
1260 default:
1261 break;
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);
1272 case Triple::IOS:
1273 // Mac Catalyst always uses the build version load command.
1274 if (Target.isMacCatalystEnvironment())
1275 return VersionTuple();
1276 LLVM_FALLTHROUGH;
1277 case Triple::TvOS:
1278 return VersionTuple(12);
1279 case Triple::WatchOS:
1280 return VersionTuple(5);
1281 default:
1282 break;
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;
1294 case Triple::IOS:
1295 if (Target.isMacCatalystEnvironment())
1296 return MachO::PLATFORM_MACCATALYST;
1297 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
1298 : MachO::PLATFORM_IOS;
1299 case Triple::TvOS:
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;
1305 default:
1306 break;
1308 llvm_unreachable("unexpected OS type");
1311 void MCStreamer::emitVersionForTarget(const Triple &Target,
1312 const VersionTuple &SDKVersion) {
1313 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
1314 return;
1315 // Do we even know the version?
1316 if (Target.getOSMajorVersion() == 0)
1317 return;
1319 unsigned Major = 0;
1320 unsigned Minor = 0;
1321 unsigned Update = 0;
1322 switch (Target.getOS()) {
1323 case Triple::MacOSX:
1324 case Triple::Darwin:
1325 Target.getMacOSXVersion(Major, Minor, Update);
1326 break;
1327 case Triple::IOS:
1328 case Triple::TvOS:
1329 Target.getiOSVersion(Major, Minor, Update);
1330 break;
1331 case Triple::WatchOS:
1332 Target.getWatchOSVersion(Major, Minor, Update);
1333 break;
1334 default:
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);