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