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