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 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/MC/MCStreamer.h"
10 #include "llvm/ADT/Optional.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/BinaryFormat/COFF.h"
15 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
16 #include "llvm/MC/MCAsmBackend.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCCodeView.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCDwarf.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstPrinter.h"
24 #include "llvm/MC/MCObjectFileInfo.h"
25 #include "llvm/MC/MCRegister.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCSection.h"
28 #include "llvm/MC/MCSectionCOFF.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/MC/MCWin64EH.h"
31 #include "llvm/MC/MCWinEH.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/LEB128.h"
35 #include "llvm/Support/MathExtras.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include <cassert>
38 #include <cstdint>
39 #include <cstdlib>
40 #include <utility>
41 
42 using namespace llvm;
43 
44 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
45   S.setTargetStreamer(this);
46 }
47 
48 // Pin the vtables to this file.
49 MCTargetStreamer::~MCTargetStreamer() = default;
50 
51 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
52 
53 void MCTargetStreamer::finish() {}
54 
55 void MCTargetStreamer::changeSection(const MCSection *CurSection,
56                                      MCSection *Section,
57                                      const MCExpr *Subsection,
58                                      raw_ostream &OS) {
59   Section->PrintSwitchToSection(
60       *Streamer.getContext().getAsmInfo(),
61       Streamer.getContext().getObjectFileInfo()->getTargetTriple(), OS,
62       Subsection);
63 }
64 
65 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
66   Streamer.emitRawText(Directive);
67 }
68 
69 void MCTargetStreamer::emitValue(const MCExpr *Value) {
70   SmallString<128> Str;
71   raw_svector_ostream OS(Str);
72 
73   Value->print(OS, Streamer.getContext().getAsmInfo());
74   Streamer.emitRawText(OS.str());
75 }
76 
77 void MCTargetStreamer::emitRawBytes(StringRef Data) {
78   const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
79   const char *Directive = MAI->getData8bitsDirective();
80   for (const unsigned char C : Data.bytes()) {
81     SmallString<128> Str;
82     raw_svector_ostream OS(Str);
83 
84     OS << Directive << (unsigned)C;
85     Streamer.emitRawText(OS.str());
86   }
87 }
88 
89 void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
90 
91 MCStreamer::MCStreamer(MCContext &Ctx)
92     : Context(Ctx), CurrentWinFrameInfo(nullptr),
93       UseAssemblerInfoForParsing(false) {
94   SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
95 }
96 
97 MCStreamer::~MCStreamer() {}
98 
99 void MCStreamer::reset() {
100   DwarfFrameInfos.clear();
101   CurrentWinFrameInfo = nullptr;
102   WinFrameInfos.clear();
103   SymbolOrdering.clear();
104   SectionStack.clear();
105   SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
106 }
107 
108 raw_ostream &MCStreamer::GetCommentOS() {
109   // By default, discard comments.
110   return nulls();
111 }
112 
113 unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos.size(); }
114 ArrayRef<MCDwarfFrameInfo> MCStreamer::getDwarfFrameInfos() const {
115   return DwarfFrameInfos;
116 }
117 
118 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
119 
120 void MCStreamer::addExplicitComment(const Twine &T) {}
121 void MCStreamer::emitExplicitComments() {}
122 
123 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
124   for (auto &FI : DwarfFrameInfos)
125     FI.CompactUnwindEncoding =
126         (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
127 }
128 
129 /// EmitIntValue - Special case of EmitValue that avoids the client having to
130 /// pass in a MCExpr for constant integers.
131 void MCStreamer::emitIntValue(uint64_t Value, unsigned Size) {
132   assert(1 <= Size && Size <= 8 && "Invalid size");
133   assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
134          "Invalid size");
135   const bool IsLittleEndian = Context.getAsmInfo()->isLittleEndian();
136   uint64_t Swapped = support::endian::byte_swap(
137       Value, IsLittleEndian ? support::little : support::big);
138   unsigned Index = IsLittleEndian ? 0 : 8 - Size;
139   emitBytes(StringRef(reinterpret_cast<char *>(&Swapped) + Index, Size));
140 }
141 
142 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
143 /// client having to pass in a MCExpr for constant integers.
144 void MCStreamer::emitULEB128IntValue(uint64_t Value, unsigned PadTo) {
145   SmallString<128> Tmp;
146   raw_svector_ostream OSE(Tmp);
147   encodeULEB128(Value, OSE, PadTo);
148   emitBytes(OSE.str());
149 }
150 
151 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
152 /// client having to pass in a MCExpr for constant integers.
153 void MCStreamer::emitSLEB128IntValue(int64_t Value) {
154   SmallString<128> Tmp;
155   raw_svector_ostream OSE(Tmp);
156   encodeSLEB128(Value, OSE);
157   emitBytes(OSE.str());
158 }
159 
160 void MCStreamer::emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
161   emitValueImpl(Value, Size, Loc);
162 }
163 
164 void MCStreamer::emitSymbolValue(const MCSymbol *Sym, unsigned Size,
165                                  bool IsSectionRelative) {
166   assert((!IsSectionRelative || Size == 4) &&
167          "SectionRelative value requires 4-bytes");
168 
169   if (!IsSectionRelative)
170     emitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
171   else
172     EmitCOFFSecRel32(Sym, /*Offset=*/0);
173 }
174 
175 void MCStreamer::emitDTPRel64Value(const MCExpr *Value) {
176   report_fatal_error("unsupported directive in streamer");
177 }
178 
179 void MCStreamer::emitDTPRel32Value(const MCExpr *Value) {
180   report_fatal_error("unsupported directive in streamer");
181 }
182 
183 void MCStreamer::emitTPRel64Value(const MCExpr *Value) {
184   report_fatal_error("unsupported directive in streamer");
185 }
186 
187 void MCStreamer::emitTPRel32Value(const MCExpr *Value) {
188   report_fatal_error("unsupported directive in streamer");
189 }
190 
191 void MCStreamer::emitGPRel64Value(const MCExpr *Value) {
192   report_fatal_error("unsupported directive in streamer");
193 }
194 
195 void MCStreamer::emitGPRel32Value(const MCExpr *Value) {
196   report_fatal_error("unsupported directive in streamer");
197 }
198 
199 /// Emit NumBytes bytes worth of the value specified by FillValue.
200 /// This implements directives such as '.space'.
201 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
202   emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
203 }
204 
205 void llvm::MCStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLen,
206                                 llvm::SMLoc) {}
207 
208 /// The implementation in this class just redirects to emitFill.
209 void MCStreamer::emitZeros(uint64_t NumBytes) { emitFill(NumBytes, 0); }
210 
211 Expected<unsigned>
212 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
213                                       StringRef Filename,
214                                       Optional<MD5::MD5Result> Checksum,
215                                       Optional<StringRef> Source,
216                                       unsigned CUID) {
217   return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
218                                    Source, CUID);
219 }
220 
221 void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
222                                          StringRef Filename,
223                                          Optional<MD5::MD5Result> Checksum,
224                                          Optional<StringRef> Source,
225                                          unsigned CUID) {
226   getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
227                                       Source);
228 }
229 
230 void MCStreamer::emitCFIBKeyFrame() {
231   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
232   if (!CurFrame)
233     return;
234   CurFrame->IsBKeyFrame = true;
235 }
236 
237 void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
238                                        unsigned Column, unsigned Flags,
239                                        unsigned Isa, unsigned Discriminator,
240                                        StringRef FileName) {
241   getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
242                                   Discriminator);
243 }
244 
245 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
246   MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
247   if (!Table.getLabel()) {
248     StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
249     Table.setLabel(
250         Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
251   }
252   return Table.getLabel();
253 }
254 
255 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
256   return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
257 }
258 
259 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
260   if (!hasUnfinishedDwarfFrameInfo()) {
261     getContext().reportError(SMLoc(), "this directive must appear between "
262                                       ".cfi_startproc and .cfi_endproc "
263                                       "directives");
264     return nullptr;
265   }
266   return &DwarfFrameInfos.back();
267 }
268 
269 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
270                                      ArrayRef<uint8_t> Checksum,
271                                      unsigned ChecksumKind) {
272   return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
273                                              ChecksumKind);
274 }
275 
276 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
277   return getContext().getCVContext().recordFunctionId(FunctionId);
278 }
279 
280 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
281                                              unsigned IAFunc, unsigned IAFile,
282                                              unsigned IALine, unsigned IACol,
283                                              SMLoc Loc) {
284   if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
285     getContext().reportError(Loc, "parent function id not introduced by "
286                                   ".cv_func_id or .cv_inline_site_id");
287     return true;
288   }
289 
290   return getContext().getCVContext().recordInlinedCallSiteId(
291       FunctionId, IAFunc, IAFile, IALine, IACol);
292 }
293 
294 void MCStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
295                                     unsigned Line, unsigned Column,
296                                     bool PrologueEnd, bool IsStmt,
297                                     StringRef FileName, SMLoc Loc) {}
298 
299 bool MCStreamer::checkCVLocSection(unsigned FuncId, unsigned FileNo,
300                                    SMLoc Loc) {
301   CodeViewContext &CVC = getContext().getCVContext();
302   MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId);
303   if (!FI) {
304     getContext().reportError(
305         Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
306     return false;
307   }
308 
309   // Track the section
310   if (FI->Section == nullptr)
311     FI->Section = getCurrentSectionOnly();
312   else if (FI->Section != getCurrentSectionOnly()) {
313     getContext().reportError(
314         Loc,
315         "all .cv_loc directives for a function must be in the same section");
316     return false;
317   }
318   return true;
319 }
320 
321 void MCStreamer::emitCVLinetableDirective(unsigned FunctionId,
322                                           const MCSymbol *Begin,
323                                           const MCSymbol *End) {}
324 
325 void MCStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
326                                                 unsigned SourceFileId,
327                                                 unsigned SourceLineNum,
328                                                 const MCSymbol *FnStartSym,
329                                                 const MCSymbol *FnEndSym) {}
330 
331 /// Only call this on endian-specific types like ulittle16_t and little32_t, or
332 /// structs composed of them.
333 template <typename T>
334 static void copyBytesForDefRange(SmallString<20> &BytePrefix,
335                                  codeview::SymbolKind SymKind,
336                                  const T &DefRangeHeader) {
337   BytePrefix.resize(2 + sizeof(T));
338   codeview::ulittle16_t SymKindLE = codeview::ulittle16_t(SymKind);
339   memcpy(&BytePrefix[0], &SymKindLE, 2);
340   memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T));
341 }
342 
343 void MCStreamer::emitCVDefRangeDirective(
344     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
345     StringRef FixedSizePortion) {}
346 
347 void MCStreamer::emitCVDefRangeDirective(
348     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
349     codeview::DefRangeRegisterRelHeader DRHdr) {
350   SmallString<20> BytePrefix;
351   copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER_REL, DRHdr);
352   emitCVDefRangeDirective(Ranges, BytePrefix);
353 }
354 
355 void MCStreamer::emitCVDefRangeDirective(
356     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
357     codeview::DefRangeSubfieldRegisterHeader DRHdr) {
358   SmallString<20> BytePrefix;
359   copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_SUBFIELD_REGISTER,
360                        DRHdr);
361   emitCVDefRangeDirective(Ranges, BytePrefix);
362 }
363 
364 void MCStreamer::emitCVDefRangeDirective(
365     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
366     codeview::DefRangeRegisterHeader DRHdr) {
367   SmallString<20> BytePrefix;
368   copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER, DRHdr);
369   emitCVDefRangeDirective(Ranges, BytePrefix);
370 }
371 
372 void MCStreamer::emitCVDefRangeDirective(
373     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
374     codeview::DefRangeFramePointerRelHeader DRHdr) {
375   SmallString<20> BytePrefix;
376   copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_FRAMEPOINTER_REL,
377                        DRHdr);
378   emitCVDefRangeDirective(Ranges, BytePrefix);
379 }
380 
381 void MCStreamer::emitEHSymAttributes(const MCSymbol *Symbol,
382                                      MCSymbol *EHSymbol) {
383 }
384 
385 void MCStreamer::InitSections(bool NoExecStack) {
386   SwitchSection(getContext().getObjectFileInfo()->getTextSection());
387 }
388 
389 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
390   assert(Fragment);
391   Symbol->setFragment(Fragment);
392 
393   // As we emit symbols into a section, track the order so that they can
394   // be sorted upon later. Zero is reserved to mean 'unemitted'.
395   SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
396 }
397 
398 void MCStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
399   Symbol->redefineIfPossible();
400 
401   if (!Symbol->isUndefined() || Symbol->isVariable())
402     return getContext().reportError(Loc, "invalid symbol redefinition");
403 
404   assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
405   assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
406   assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
407   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
408 
409   Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
410 
411   MCTargetStreamer *TS = getTargetStreamer();
412   if (TS)
413     TS->emitLabel(Symbol);
414 }
415 
416 void MCStreamer::emitCFISections(bool EH, bool Debug) {
417   assert(EH || Debug);
418 }
419 
420 void MCStreamer::emitCFIStartProc(bool IsSimple, SMLoc Loc) {
421   if (hasUnfinishedDwarfFrameInfo())
422     return getContext().reportError(
423         Loc, "starting new .cfi frame before finishing the previous one");
424 
425   MCDwarfFrameInfo Frame;
426   Frame.IsSimple = IsSimple;
427   emitCFIStartProcImpl(Frame);
428 
429   const MCAsmInfo* MAI = Context.getAsmInfo();
430   if (MAI) {
431     for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
432       if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
433           Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
434         Frame.CurrentCfaRegister = Inst.getRegister();
435       }
436     }
437   }
438 
439   DwarfFrameInfos.push_back(Frame);
440 }
441 
442 void MCStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
443 }
444 
445 void MCStreamer::emitCFIEndProc() {
446   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
447   if (!CurFrame)
448     return;
449   emitCFIEndProcImpl(*CurFrame);
450 }
451 
452 void MCStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
453   // Put a dummy non-null value in Frame.End to mark that this frame has been
454   // closed.
455   Frame.End = (MCSymbol *)1;
456 }
457 
458 MCSymbol *MCStreamer::emitCFILabel() {
459   // Return a dummy non-null value so that label fields appear filled in when
460   // generating textual assembly.
461   return (MCSymbol *)1;
462 }
463 
464 void MCStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset) {
465   MCSymbol *Label = emitCFILabel();
466   MCCFIInstruction Instruction =
467       MCCFIInstruction::cfiDefCfa(Label, Register, Offset);
468   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
469   if (!CurFrame)
470     return;
471   CurFrame->Instructions.push_back(Instruction);
472   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
473 }
474 
475 void MCStreamer::emitCFIDefCfaOffset(int64_t Offset) {
476   MCSymbol *Label = emitCFILabel();
477   MCCFIInstruction Instruction =
478       MCCFIInstruction::cfiDefCfaOffset(Label, Offset);
479   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
480   if (!CurFrame)
481     return;
482   CurFrame->Instructions.push_back(Instruction);
483 }
484 
485 void MCStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment) {
486   MCSymbol *Label = emitCFILabel();
487   MCCFIInstruction Instruction =
488     MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
489   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
490   if (!CurFrame)
491     return;
492   CurFrame->Instructions.push_back(Instruction);
493 }
494 
495 void MCStreamer::emitCFIDefCfaRegister(int64_t Register) {
496   MCSymbol *Label = emitCFILabel();
497   MCCFIInstruction Instruction =
498     MCCFIInstruction::createDefCfaRegister(Label, Register);
499   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
500   if (!CurFrame)
501     return;
502   CurFrame->Instructions.push_back(Instruction);
503   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
504 }
505 
506 void MCStreamer::emitCFIOffset(int64_t Register, int64_t Offset) {
507   MCSymbol *Label = emitCFILabel();
508   MCCFIInstruction Instruction =
509     MCCFIInstruction::createOffset(Label, Register, Offset);
510   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
511   if (!CurFrame)
512     return;
513   CurFrame->Instructions.push_back(Instruction);
514 }
515 
516 void MCStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset) {
517   MCSymbol *Label = emitCFILabel();
518   MCCFIInstruction Instruction =
519     MCCFIInstruction::createRelOffset(Label, Register, Offset);
520   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
521   if (!CurFrame)
522     return;
523   CurFrame->Instructions.push_back(Instruction);
524 }
525 
526 void MCStreamer::emitCFIPersonality(const MCSymbol *Sym,
527                                     unsigned Encoding) {
528   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
529   if (!CurFrame)
530     return;
531   CurFrame->Personality = Sym;
532   CurFrame->PersonalityEncoding = Encoding;
533 }
534 
535 void MCStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
536   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
537   if (!CurFrame)
538     return;
539   CurFrame->Lsda = Sym;
540   CurFrame->LsdaEncoding = Encoding;
541 }
542 
543 void MCStreamer::emitCFIRememberState() {
544   MCSymbol *Label = emitCFILabel();
545   MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
546   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
547   if (!CurFrame)
548     return;
549   CurFrame->Instructions.push_back(Instruction);
550 }
551 
552 void MCStreamer::emitCFIRestoreState() {
553   // FIXME: Error if there is no matching cfi_remember_state.
554   MCSymbol *Label = emitCFILabel();
555   MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
556   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
557   if (!CurFrame)
558     return;
559   CurFrame->Instructions.push_back(Instruction);
560 }
561 
562 void MCStreamer::emitCFISameValue(int64_t Register) {
563   MCSymbol *Label = emitCFILabel();
564   MCCFIInstruction Instruction =
565     MCCFIInstruction::createSameValue(Label, Register);
566   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
567   if (!CurFrame)
568     return;
569   CurFrame->Instructions.push_back(Instruction);
570 }
571 
572 void MCStreamer::emitCFIRestore(int64_t Register) {
573   MCSymbol *Label = emitCFILabel();
574   MCCFIInstruction Instruction =
575     MCCFIInstruction::createRestore(Label, Register);
576   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
577   if (!CurFrame)
578     return;
579   CurFrame->Instructions.push_back(Instruction);
580 }
581 
582 void MCStreamer::emitCFIEscape(StringRef Values) {
583   MCSymbol *Label = emitCFILabel();
584   MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
585   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
586   if (!CurFrame)
587     return;
588   CurFrame->Instructions.push_back(Instruction);
589 }
590 
591 void MCStreamer::emitCFIGnuArgsSize(int64_t Size) {
592   MCSymbol *Label = emitCFILabel();
593   MCCFIInstruction Instruction =
594     MCCFIInstruction::createGnuArgsSize(Label, Size);
595   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
596   if (!CurFrame)
597     return;
598   CurFrame->Instructions.push_back(Instruction);
599 }
600 
601 void MCStreamer::emitCFISignalFrame() {
602   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
603   if (!CurFrame)
604     return;
605   CurFrame->IsSignalFrame = true;
606 }
607 
608 void MCStreamer::emitCFIUndefined(int64_t Register) {
609   MCSymbol *Label = emitCFILabel();
610   MCCFIInstruction Instruction =
611     MCCFIInstruction::createUndefined(Label, Register);
612   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
613   if (!CurFrame)
614     return;
615   CurFrame->Instructions.push_back(Instruction);
616 }
617 
618 void MCStreamer::emitCFIRegister(int64_t Register1, int64_t Register2) {
619   MCSymbol *Label = emitCFILabel();
620   MCCFIInstruction Instruction =
621     MCCFIInstruction::createRegister(Label, Register1, Register2);
622   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
623   if (!CurFrame)
624     return;
625   CurFrame->Instructions.push_back(Instruction);
626 }
627 
628 void MCStreamer::emitCFIWindowSave() {
629   MCSymbol *Label = emitCFILabel();
630   MCCFIInstruction Instruction =
631     MCCFIInstruction::createWindowSave(Label);
632   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
633   if (!CurFrame)
634     return;
635   CurFrame->Instructions.push_back(Instruction);
636 }
637 
638 void MCStreamer::emitCFINegateRAState() {
639   MCSymbol *Label = emitCFILabel();
640   MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label);
641   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
642   if (!CurFrame)
643     return;
644   CurFrame->Instructions.push_back(Instruction);
645 }
646 
647 void MCStreamer::emitCFIReturnColumn(int64_t Register) {
648   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
649   if (!CurFrame)
650     return;
651   CurFrame->RAReg = Register;
652 }
653 
654 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
655   const MCAsmInfo *MAI = Context.getAsmInfo();
656   if (!MAI->usesWindowsCFI()) {
657     getContext().reportError(
658         Loc, ".seh_* directives are not supported on this target");
659     return nullptr;
660   }
661   if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
662     getContext().reportError(
663         Loc, ".seh_ directive must appear within an active frame");
664     return nullptr;
665   }
666   return CurrentWinFrameInfo;
667 }
668 
669 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
670   const MCAsmInfo *MAI = Context.getAsmInfo();
671   if (!MAI->usesWindowsCFI())
672     return getContext().reportError(
673         Loc, ".seh_* directives are not supported on this target");
674   if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
675     getContext().reportError(
676         Loc, "Starting a function before ending the previous one!");
677 
678   MCSymbol *StartProc = emitCFILabel();
679 
680   WinFrameInfos.emplace_back(
681       std::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
682   CurrentWinFrameInfo = WinFrameInfos.back().get();
683   CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
684 }
685 
686 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
687   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
688   if (!CurFrame)
689     return;
690   if (CurFrame->ChainedParent)
691     getContext().reportError(Loc, "Not all chained regions terminated!");
692 
693   MCSymbol *Label = emitCFILabel();
694   CurFrame->End = Label;
695 }
696 
697 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
698   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
699   if (!CurFrame)
700     return;
701   if (CurFrame->ChainedParent)
702     getContext().reportError(Loc, "Not all chained regions terminated!");
703 
704   MCSymbol *Label = emitCFILabel();
705   CurFrame->FuncletOrFuncEnd = Label;
706 }
707 
708 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
709   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
710   if (!CurFrame)
711     return;
712 
713   MCSymbol *StartProc = emitCFILabel();
714 
715   WinFrameInfos.emplace_back(std::make_unique<WinEH::FrameInfo>(
716       CurFrame->Function, StartProc, CurFrame));
717   CurrentWinFrameInfo = WinFrameInfos.back().get();
718   CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
719 }
720 
721 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
722   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
723   if (!CurFrame)
724     return;
725   if (!CurFrame->ChainedParent)
726     return getContext().reportError(
727         Loc, "End of a chained region outside a chained region!");
728 
729   MCSymbol *Label = emitCFILabel();
730 
731   CurFrame->End = Label;
732   CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
733 }
734 
735 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
736                                   SMLoc Loc) {
737   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
738   if (!CurFrame)
739     return;
740   if (CurFrame->ChainedParent)
741     return getContext().reportError(
742         Loc, "Chained unwind areas can't have handlers!");
743   CurFrame->ExceptionHandler = Sym;
744   if (!Except && !Unwind)
745     getContext().reportError(Loc, "Don't know what kind of handler this is!");
746   if (Unwind)
747     CurFrame->HandlesUnwind = true;
748   if (Except)
749     CurFrame->HandlesExceptions = true;
750 }
751 
752 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
753   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
754   if (!CurFrame)
755     return;
756   if (CurFrame->ChainedParent)
757     getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
758 }
759 
760 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
761                                     const MCSymbolRefExpr *To, uint64_t Count) {
762 }
763 
764 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
765                                    MCSection *MainCFISec,
766                                    const MCSection *TextSec) {
767   // If this is the main .text section, use the main unwind info section.
768   if (TextSec == Context.getObjectFileInfo()->getTextSection())
769     return MainCFISec;
770 
771   const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
772   auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
773   unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
774 
775   // If this section is COMDAT, this unwind section should be COMDAT associative
776   // with its group.
777   const MCSymbol *KeySym = nullptr;
778   if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
779     KeySym = TextSecCOFF->getCOMDATSymbol();
780 
781     // In a GNU environment, we can't use associative comdats. Instead, do what
782     // GCC does, which is to make plain comdat selectany section named like
783     // ".[px]data$_Z3foov".
784     if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
785       std::string SectionName = (MainCFISecCOFF->getName() + "$" +
786                                  TextSecCOFF->getName().split('$').second)
787                                     .str();
788       return Context.getCOFFSection(
789           SectionName,
790           MainCFISecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT,
791           MainCFISecCOFF->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY);
792     }
793   }
794 
795   return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
796 }
797 
798 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
799   return getWinCFISection(getContext(), &NextWinCFIID,
800                           getContext().getObjectFileInfo()->getPDataSection(),
801                           TextSec);
802 }
803 
804 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
805   return getWinCFISection(getContext(), &NextWinCFIID,
806                           getContext().getObjectFileInfo()->getXDataSection(),
807                           TextSec);
808 }
809 
810 void MCStreamer::emitSyntaxDirective() {}
811 
812 static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
813   return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
814 }
815 
816 void MCStreamer::EmitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
817   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
818   if (!CurFrame)
819     return;
820 
821   MCSymbol *Label = emitCFILabel();
822 
823   WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(
824       Label, encodeSEHRegNum(Context, Register));
825   CurFrame->Instructions.push_back(Inst);
826 }
827 
828 void MCStreamer::EmitWinCFISetFrame(MCRegister Register, unsigned Offset,
829                                     SMLoc Loc) {
830   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
831   if (!CurFrame)
832     return;
833   if (CurFrame->LastFrameInst >= 0)
834     return getContext().reportError(
835         Loc, "frame register and offset can be set at most once");
836   if (Offset & 0x0F)
837     return getContext().reportError(Loc, "offset is not a multiple of 16");
838   if (Offset > 240)
839     return getContext().reportError(
840         Loc, "frame offset must be less than or equal to 240");
841 
842   MCSymbol *Label = emitCFILabel();
843 
844   WinEH::Instruction Inst = Win64EH::Instruction::SetFPReg(
845       Label, encodeSEHRegNum(getContext(), Register), Offset);
846   CurFrame->LastFrameInst = CurFrame->Instructions.size();
847   CurFrame->Instructions.push_back(Inst);
848 }
849 
850 void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
851   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
852   if (!CurFrame)
853     return;
854   if (Size == 0)
855     return getContext().reportError(Loc,
856                                     "stack allocation size must be non-zero");
857   if (Size & 7)
858     return getContext().reportError(
859         Loc, "stack allocation size is not a multiple of 8");
860 
861   MCSymbol *Label = emitCFILabel();
862 
863   WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
864   CurFrame->Instructions.push_back(Inst);
865 }
866 
867 void MCStreamer::EmitWinCFISaveReg(MCRegister Register, unsigned Offset,
868                                    SMLoc Loc) {
869   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
870   if (!CurFrame)
871     return;
872 
873   if (Offset & 7)
874     return getContext().reportError(
875         Loc, "register save offset is not 8 byte aligned");
876 
877   MCSymbol *Label = emitCFILabel();
878 
879   WinEH::Instruction Inst = Win64EH::Instruction::SaveNonVol(
880       Label, encodeSEHRegNum(Context, Register), Offset);
881   CurFrame->Instructions.push_back(Inst);
882 }
883 
884 void MCStreamer::EmitWinCFISaveXMM(MCRegister Register, unsigned Offset,
885                                    SMLoc Loc) {
886   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
887   if (!CurFrame)
888     return;
889   if (Offset & 0x0F)
890     return getContext().reportError(Loc, "offset is not a multiple of 16");
891 
892   MCSymbol *Label = emitCFILabel();
893 
894   WinEH::Instruction Inst = Win64EH::Instruction::SaveXMM(
895       Label, encodeSEHRegNum(Context, Register), Offset);
896   CurFrame->Instructions.push_back(Inst);
897 }
898 
899 void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
900   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
901   if (!CurFrame)
902     return;
903   if (!CurFrame->Instructions.empty())
904     return getContext().reportError(
905         Loc, "If present, PushMachFrame must be the first UOP");
906 
907   MCSymbol *Label = emitCFILabel();
908 
909   WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
910   CurFrame->Instructions.push_back(Inst);
911 }
912 
913 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
914   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
915   if (!CurFrame)
916     return;
917 
918   MCSymbol *Label = emitCFILabel();
919 
920   CurFrame->PrologEnd = Label;
921 }
922 
923 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {}
924 
925 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {}
926 
927 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {}
928 
929 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
930 
931 void MCStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
932 
933 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
934 /// the specified string in the output .s file.  This capability is
935 /// indicated by the hasRawTextSupport() predicate.
936 void MCStreamer::emitRawTextImpl(StringRef String) {
937   // This is not llvm_unreachable for the sake of out of tree backend
938   // developers who may not have assembly streamers and should serve as a
939   // reminder to not accidentally call EmitRawText in the absence of such.
940   report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
941                      "it (target backend is likely missing an AsmStreamer "
942                      "implementation)");
943 }
944 
945 void MCStreamer::emitRawText(const Twine &T) {
946   SmallString<128> Str;
947   emitRawTextImpl(T.toStringRef(Str));
948 }
949 
950 void MCStreamer::EmitWindowsUnwindTables() {
951 }
952 
953 void MCStreamer::Finish() {
954   if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
955       (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
956     getContext().reportError(SMLoc(), "Unfinished frame!");
957     return;
958   }
959 
960   MCTargetStreamer *TS = getTargetStreamer();
961   if (TS)
962     TS->finish();
963 
964   finishImpl();
965 }
966 
967 void MCStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
968   visitUsedExpr(*Value);
969   Symbol->setVariableValue(Value);
970 
971   MCTargetStreamer *TS = getTargetStreamer();
972   if (TS)
973     TS->emitAssignment(Symbol, Value);
974 }
975 
976 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
977                                       uint64_t Address, const MCInst &Inst,
978                                       const MCSubtargetInfo &STI,
979                                       raw_ostream &OS) {
980   InstPrinter.printInst(&Inst, Address, "", STI, OS);
981 }
982 
983 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
984 }
985 
986 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
987   switch (Expr.getKind()) {
988   case MCExpr::Target:
989     cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
990     break;
991 
992   case MCExpr::Constant:
993     break;
994 
995   case MCExpr::Binary: {
996     const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
997     visitUsedExpr(*BE.getLHS());
998     visitUsedExpr(*BE.getRHS());
999     break;
1000   }
1001 
1002   case MCExpr::SymbolRef:
1003     visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
1004     break;
1005 
1006   case MCExpr::Unary:
1007     visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
1008     break;
1009   }
1010 }
1011 
1012 void MCStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
1013   // Scan for values.
1014   for (unsigned i = Inst.getNumOperands(); i--;)
1015     if (Inst.getOperand(i).isExpr())
1016       visitUsedExpr(*Inst.getOperand(i).getExpr());
1017 }
1018 
1019 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
1020                                         unsigned Size) {
1021   // Get the Hi-Lo expression.
1022   const MCExpr *Diff =
1023       MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1024                               MCSymbolRefExpr::create(Lo, Context), Context);
1025 
1026   const MCAsmInfo *MAI = Context.getAsmInfo();
1027   if (!MAI->doesSetDirectiveSuppressReloc()) {
1028     emitValue(Diff, Size);
1029     return;
1030   }
1031 
1032   // Otherwise, emit with .set (aka assignment).
1033   MCSymbol *SetLabel = Context.createTempSymbol("set", true);
1034   emitAssignment(SetLabel, Diff);
1035   emitSymbolValue(SetLabel, Size);
1036 }
1037 
1038 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
1039                                                  const MCSymbol *Lo) {
1040   // Get the Hi-Lo expression.
1041   const MCExpr *Diff =
1042       MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1043                               MCSymbolRefExpr::create(Lo, Context), Context);
1044 
1045   emitULEB128Value(Diff);
1046 }
1047 
1048 void MCStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {}
1049 void MCStreamer::emitThumbFunc(MCSymbol *Func) {}
1050 void MCStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
1051 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
1052   llvm_unreachable("this directive only supported on COFF targets");
1053 }
1054 void MCStreamer::EndCOFFSymbolDef() {
1055   llvm_unreachable("this directive only supported on COFF targets");
1056 }
1057 void MCStreamer::emitFileDirective(StringRef Filename) {}
1058 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
1059   llvm_unreachable("this directive only supported on COFF targets");
1060 }
1061 void MCStreamer::EmitCOFFSymbolType(int Type) {
1062   llvm_unreachable("this directive only supported on COFF targets");
1063 }
1064 void MCStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
1065                                             MCSymbol *CsectSym,
1066                                             unsigned ByteAlign) {
1067   llvm_unreachable("this directive only supported on XCOFF targets");
1068 }
1069 
1070 void MCStreamer::emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
1071                                                       MCSymbolAttr Linkage,
1072                                                       MCSymbolAttr Visibility) {
1073   llvm_unreachable("emitXCOFFSymbolLinkageWithVisibility is only supported on "
1074                    "XCOFF targets");
1075 }
1076 
1077 void MCStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
1078                                           StringRef Rename) {
1079   llvm_unreachable("emitXCOFFRenameDirective is only supported on "
1080                    "XCOFF targets");
1081 }
1082 
1083 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
1084 void MCStreamer::emitELFSymverDirective(StringRef AliasName,
1085                                         const MCSymbol *Aliasee) {}
1086 void MCStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1087                                        unsigned ByteAlignment) {}
1088 void MCStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1089                                 uint64_t Size, unsigned ByteAlignment) {}
1090 void MCStreamer::changeSection(MCSection *, const MCExpr *) {}
1091 void MCStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
1092 void MCStreamer::emitBytes(StringRef Data) {}
1093 void MCStreamer::emitBinaryData(StringRef Data) { emitBytes(Data); }
1094 void MCStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
1095   visitUsedExpr(*Value);
1096 }
1097 void MCStreamer::emitULEB128Value(const MCExpr *Value) {}
1098 void MCStreamer::emitSLEB128Value(const MCExpr *Value) {}
1099 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
1100 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
1101                           SMLoc Loc) {}
1102 void MCStreamer::emitValueToAlignment(unsigned ByteAlignment, int64_t Value,
1103                                       unsigned ValueSize,
1104                                       unsigned MaxBytesToEmit) {}
1105 void MCStreamer::emitCodeAlignment(unsigned ByteAlignment,
1106                                    unsigned MaxBytesToEmit) {}
1107 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
1108                                    SMLoc Loc) {}
1109 void MCStreamer::emitBundleAlignMode(unsigned AlignPow2) {}
1110 void MCStreamer::emitBundleLock(bool AlignToEnd) {}
1111 void MCStreamer::finishImpl() {}
1112 void MCStreamer::emitBundleUnlock() {}
1113 
1114 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
1115   assert(Section && "Cannot switch to a null section!");
1116   MCSectionSubPair curSection = SectionStack.back().first;
1117   SectionStack.back().second = curSection;
1118   if (MCSectionSubPair(Section, Subsection) != curSection) {
1119     changeSection(Section, Subsection);
1120     SectionStack.back().first = MCSectionSubPair(Section, Subsection);
1121     assert(!Section->hasEnded() && "Section already ended");
1122     MCSymbol *Sym = Section->getBeginSymbol();
1123     if (Sym && !Sym->isInSection())
1124       emitLabel(Sym);
1125   }
1126 }
1127 
1128 MCSymbol *MCStreamer::endSection(MCSection *Section) {
1129   // TODO: keep track of the last subsection so that this symbol appears in the
1130   // correct place.
1131   MCSymbol *Sym = Section->getEndSymbol(Context);
1132   if (Sym->isInSection())
1133     return Sym;
1134 
1135   SwitchSection(Section);
1136   emitLabel(Sym);
1137   return Sym;
1138 }
1139 
1140 static VersionTuple
1141 targetVersionOrMinimumSupportedOSVersion(const Triple &Target,
1142                                          VersionTuple TargetVersion) {
1143   VersionTuple Min = Target.getMinimumSupportedOSVersion();
1144   return !Min.empty() && Min > TargetVersion ? Min : TargetVersion;
1145 }
1146 
1147 static MCVersionMinType
1148 getMachoVersionMinLoadCommandType(const Triple &Target) {
1149   assert(Target.isOSDarwin() && "expected a darwin OS");
1150   switch (Target.getOS()) {
1151   case Triple::MacOSX:
1152   case Triple::Darwin:
1153     return MCVM_OSXVersionMin;
1154   case Triple::IOS:
1155     assert(!Target.isMacCatalystEnvironment() &&
1156            "mac Catalyst should use LC_BUILD_VERSION");
1157     return MCVM_IOSVersionMin;
1158   case Triple::TvOS:
1159     return MCVM_TvOSVersionMin;
1160   case Triple::WatchOS:
1161     return MCVM_WatchOSVersionMin;
1162   default:
1163     break;
1164   }
1165   llvm_unreachable("unexpected OS type");
1166 }
1167 
1168 static VersionTuple getMachoBuildVersionSupportedOS(const Triple &Target) {
1169   assert(Target.isOSDarwin() && "expected a darwin OS");
1170   switch (Target.getOS()) {
1171   case Triple::MacOSX:
1172   case Triple::Darwin:
1173     return VersionTuple(10, 14);
1174   case Triple::IOS:
1175     // Mac Catalyst always uses the build version load command.
1176     if (Target.isMacCatalystEnvironment())
1177       return VersionTuple();
1178     LLVM_FALLTHROUGH;
1179   case Triple::TvOS:
1180     return VersionTuple(12);
1181   case Triple::WatchOS:
1182     return VersionTuple(5);
1183   default:
1184     break;
1185   }
1186   llvm_unreachable("unexpected OS type");
1187 }
1188 
1189 static MachO::PlatformType
1190 getMachoBuildVersionPlatformType(const Triple &Target) {
1191   assert(Target.isOSDarwin() && "expected a darwin OS");
1192   switch (Target.getOS()) {
1193   case Triple::MacOSX:
1194   case Triple::Darwin:
1195     return MachO::PLATFORM_MACOS;
1196   case Triple::IOS:
1197     if (Target.isMacCatalystEnvironment())
1198       return MachO::PLATFORM_MACCATALYST;
1199     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
1200                                            : MachO::PLATFORM_IOS;
1201   case Triple::TvOS:
1202     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
1203                                            : MachO::PLATFORM_TVOS;
1204   case Triple::WatchOS:
1205     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
1206                                            : MachO::PLATFORM_WATCHOS;
1207   default:
1208     break;
1209   }
1210   llvm_unreachable("unexpected OS type");
1211 }
1212 
1213 void MCStreamer::emitVersionForTarget(const Triple &Target,
1214                                       const VersionTuple &SDKVersion) {
1215   if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
1216     return;
1217   // Do we even know the version?
1218   if (Target.getOSMajorVersion() == 0)
1219     return;
1220 
1221   unsigned Major = 0;
1222   unsigned Minor = 0;
1223   unsigned Update = 0;
1224   switch (Target.getOS()) {
1225   case Triple::MacOSX:
1226   case Triple::Darwin:
1227     Target.getMacOSXVersion(Major, Minor, Update);
1228     break;
1229   case Triple::IOS:
1230   case Triple::TvOS:
1231     Target.getiOSVersion(Major, Minor, Update);
1232     break;
1233   case Triple::WatchOS:
1234     Target.getWatchOSVersion(Major, Minor, Update);
1235     break;
1236   default:
1237     llvm_unreachable("unexpected OS type");
1238   }
1239   assert(Major != 0 && "A non-zero major version is expected");
1240   auto LinkedTargetVersion = targetVersionOrMinimumSupportedOSVersion(
1241       Target, VersionTuple(Major, Minor, Update));
1242   auto BuildVersionOSVersion = getMachoBuildVersionSupportedOS(Target);
1243   if (BuildVersionOSVersion.empty() ||
1244       LinkedTargetVersion >= BuildVersionOSVersion)
1245     return emitBuildVersion(getMachoBuildVersionPlatformType(Target),
1246                             LinkedTargetVersion.getMajor(),
1247                             *LinkedTargetVersion.getMinor(),
1248                             *LinkedTargetVersion.getSubminor(), SDKVersion);
1249 
1250   emitVersionMin(getMachoVersionMinLoadCommandType(Target),
1251                  LinkedTargetVersion.getMajor(),
1252                  *LinkedTargetVersion.getMinor(),
1253                  *LinkedTargetVersion.getSubminor(), SDKVersion);
1254 }
1255