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