1 //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/MC/MCStreamer.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/MC/MCAsmBackend.h"
14 #include "llvm/MC/MCAsmInfo.h"
15 #include "llvm/MC/MCCodeView.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstPrinter.h"
20 #include "llvm/MC/MCObjectFileInfo.h"
21 #include "llvm/MC/MCObjectWriter.h"
22 #include "llvm/MC/MCSection.h"
23 #include "llvm/MC/MCSectionCOFF.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/MC/MCWin64EH.h"
26 #include "llvm/Support/COFF.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/LEB128.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include <cstdlib>
31 using namespace llvm;
32 
33 // Pin the vtables to this file.
34 MCTargetStreamer::~MCTargetStreamer() {}
35 
36 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
37   S.setTargetStreamer(this);
38 }
39 
40 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
41 
42 void MCTargetStreamer::finish() {}
43 
44 void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
45 
46 MCStreamer::MCStreamer(MCContext &Ctx)
47     : Context(Ctx), CurrentWinFrameInfo(nullptr) {
48   SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
49 }
50 
51 MCStreamer::~MCStreamer() {
52   for (unsigned i = 0; i < getNumWinFrameInfos(); ++i)
53     delete WinFrameInfos[i];
54 }
55 
56 void MCStreamer::reset() {
57   DwarfFrameInfos.clear();
58   for (unsigned i = 0; i < getNumWinFrameInfos(); ++i)
59     delete WinFrameInfos[i];
60   WinFrameInfos.clear();
61   CurrentWinFrameInfo = nullptr;
62   SymbolOrdering.clear();
63   SectionStack.clear();
64   SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
65 }
66 
67 raw_ostream &MCStreamer::GetCommentOS() {
68   // By default, discard comments.
69   return nulls();
70 }
71 
72 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
73 
74 void MCStreamer::addExplicitComment(const Twine &T) {}
75 void MCStreamer::emitExplicitComments() {}
76 
77 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
78   for (auto &FI : DwarfFrameInfos)
79     FI.CompactUnwindEncoding =
80         (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
81 }
82 
83 /// EmitIntValue - Special case of EmitValue that avoids the client having to
84 /// pass in a MCExpr for constant integers.
85 void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
86   assert(1 <= Size && Size <= 8 && "Invalid size");
87   assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
88          "Invalid size");
89   char buf[8];
90   const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian();
91   for (unsigned i = 0; i != Size; ++i) {
92     unsigned index = isLittleEndian ? i : (Size - i - 1);
93     buf[i] = uint8_t(Value >> (index * 8));
94   }
95   EmitBytes(StringRef(buf, Size));
96 }
97 
98 /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
99 /// client having to pass in a MCExpr for constant integers.
100 void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned Padding) {
101   SmallString<128> Tmp;
102   raw_svector_ostream OSE(Tmp);
103   encodeULEB128(Value, OSE, Padding);
104   EmitBytes(OSE.str());
105 }
106 
107 /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
108 /// client having to pass in a MCExpr for constant integers.
109 void MCStreamer::EmitSLEB128IntValue(int64_t Value) {
110   SmallString<128> Tmp;
111   raw_svector_ostream OSE(Tmp);
112   encodeSLEB128(Value, OSE);
113   EmitBytes(OSE.str());
114 }
115 
116 void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
117   EmitValueImpl(Value, Size, Loc);
118 }
119 
120 void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
121                                  bool IsSectionRelative) {
122   assert((!IsSectionRelative || Size == 4) &&
123          "SectionRelative value requires 4-bytes");
124 
125   if (!IsSectionRelative)
126     EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
127   else
128     EmitCOFFSecRel32(Sym, /*Offset=*/0);
129 }
130 
131 void MCStreamer::EmitDTPRel64Value(const MCExpr *Value) {
132   report_fatal_error("unsupported directive in streamer");
133 }
134 
135 void MCStreamer::EmitDTPRel32Value(const MCExpr *Value) {
136   report_fatal_error("unsupported directive in streamer");
137 }
138 
139 void MCStreamer::EmitTPRel64Value(const MCExpr *Value) {
140   report_fatal_error("unsupported directive in streamer");
141 }
142 
143 void MCStreamer::EmitTPRel32Value(const MCExpr *Value) {
144   report_fatal_error("unsupported directive in streamer");
145 }
146 
147 void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
148   report_fatal_error("unsupported directive in streamer");
149 }
150 
151 void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
152   report_fatal_error("unsupported directive in streamer");
153 }
154 
155 /// Emit NumBytes bytes worth of the value specified by FillValue.
156 /// This implements directives such as '.space'.
157 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
158   for (uint64_t i = 0, e = NumBytes; i != e; ++i)
159     EmitIntValue(FillValue, 1);
160 }
161 
162 void MCStreamer::emitFill(uint64_t NumValues, int64_t Size, int64_t Expr) {
163   int64_t NonZeroSize = Size > 4 ? 4 : Size;
164   Expr &= ~0ULL >> (64 - NonZeroSize * 8);
165   for (uint64_t i = 0, e = NumValues; i != e; ++i) {
166     EmitIntValue(Expr, NonZeroSize);
167     if (NonZeroSize < Size)
168       EmitIntValue(0, Size - NonZeroSize);
169   }
170 }
171 
172 /// The implementation in this class just redirects to emitFill.
173 void MCStreamer::EmitZeros(uint64_t NumBytes) {
174   emitFill(NumBytes, 0);
175 }
176 
177 unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
178                                             StringRef Directory,
179                                             StringRef Filename, unsigned CUID) {
180   return getContext().getDwarfFile(Directory, Filename, FileNo, CUID);
181 }
182 
183 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
184                                        unsigned Column, unsigned Flags,
185                                        unsigned Isa,
186                                        unsigned Discriminator,
187                                        StringRef FileName) {
188   getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
189                                   Discriminator);
190 }
191 
192 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
193   MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
194   if (!Table.getLabel()) {
195     StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
196     Table.setLabel(
197         Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
198   }
199   return Table.getLabel();
200 }
201 
202 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
203   if (DwarfFrameInfos.empty())
204     return nullptr;
205   return &DwarfFrameInfos.back();
206 }
207 
208 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
209   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
210   return CurFrame && !CurFrame->End;
211 }
212 
213 void MCStreamer::EnsureValidDwarfFrame() {
214   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
215   if (!CurFrame || CurFrame->End)
216     report_fatal_error("No open frame");
217 }
218 
219 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename) {
220   return getContext().getCVContext().addFile(FileNo, Filename);
221 }
222 
223 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
224   return getContext().getCVContext().recordFunctionId(FunctionId);
225 }
226 
227 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
228                                              unsigned IAFunc, unsigned IAFile,
229                                              unsigned IALine, unsigned IACol,
230                                              SMLoc Loc) {
231   if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
232     getContext().reportError(Loc, "parent function id not introduced by "
233                                   ".cv_func_id or .cv_inline_site_id");
234     return true;
235   }
236 
237   return getContext().getCVContext().recordInlinedCallSiteId(
238       FunctionId, IAFunc, IAFile, IALine, IACol);
239 }
240 
241 void MCStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
242                                     unsigned Line, unsigned Column,
243                                     bool PrologueEnd, bool IsStmt,
244                                     StringRef FileName, SMLoc Loc) {
245   CodeViewContext &CVC = getContext().getCVContext();
246   MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FunctionId);
247   if (!FI)
248     return getContext().reportError(
249         Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
250 
251   // Track the section
252   if (FI->Section == nullptr)
253     FI->Section = getCurrentSectionOnly();
254   else if (FI->Section != getCurrentSectionOnly())
255     return getContext().reportError(
256         Loc,
257         "all .cv_loc directives for a function must be in the same section");
258 
259   CVC.setCurrentCVLoc(FunctionId, FileNo, Line, Column, PrologueEnd, IsStmt);
260 }
261 
262 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId,
263                                           const MCSymbol *Begin,
264                                           const MCSymbol *End) {}
265 
266 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
267                                                 unsigned SourceFileId,
268                                                 unsigned SourceLineNum,
269                                                 const MCSymbol *FnStartSym,
270                                                 const MCSymbol *FnEndSym) {}
271 
272 void MCStreamer::EmitCVDefRangeDirective(
273     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
274     StringRef FixedSizePortion) {}
275 
276 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
277                                      MCSymbol *EHSymbol) {
278 }
279 
280 void MCStreamer::InitSections(bool NoExecStack) {
281   SwitchSection(getContext().getObjectFileInfo()->getTextSection());
282 }
283 
284 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
285   assert(Fragment);
286   Symbol->setFragment(Fragment);
287 
288   // As we emit symbols into a section, track the order so that they can
289   // be sorted upon later. Zero is reserved to mean 'unemitted'.
290   SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
291 }
292 
293 void MCStreamer::EmitLabel(MCSymbol *Symbol) {
294   assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
295   assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
296   assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
297   Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
298 
299   MCTargetStreamer *TS = getTargetStreamer();
300   if (TS)
301     TS->emitLabel(Symbol);
302 }
303 
304 void MCStreamer::EmitCFISections(bool EH, bool Debug) {
305   assert(EH || Debug);
306 }
307 
308 void MCStreamer::EmitCFIStartProc(bool IsSimple) {
309   if (hasUnfinishedDwarfFrameInfo())
310     report_fatal_error("Starting a frame before finishing the previous one!");
311 
312   MCDwarfFrameInfo Frame;
313   Frame.IsSimple = IsSimple;
314   EmitCFIStartProcImpl(Frame);
315 
316   const MCAsmInfo* MAI = Context.getAsmInfo();
317   if (MAI) {
318     for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
319       if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
320           Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
321         Frame.CurrentCfaRegister = Inst.getRegister();
322       }
323     }
324   }
325 
326   DwarfFrameInfos.push_back(Frame);
327 }
328 
329 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
330 }
331 
332 void MCStreamer::EmitCFIEndProc() {
333   EnsureValidDwarfFrame();
334   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
335   EmitCFIEndProcImpl(*CurFrame);
336 }
337 
338 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
339   // Put a dummy non-null value in Frame.End to mark that this frame has been
340   // closed.
341   Frame.End = (MCSymbol *) 1;
342 }
343 
344 MCSymbol *MCStreamer::EmitCFILabel() {
345   MCSymbol *Label = getContext().createTempSymbol("cfi", true);
346   EmitLabel(Label);
347   return Label;
348 }
349 
350 MCSymbol *MCStreamer::EmitCFICommon() {
351   EnsureValidDwarfFrame();
352   return EmitCFILabel();
353 }
354 
355 void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
356   MCSymbol *Label = EmitCFICommon();
357   MCCFIInstruction Instruction =
358     MCCFIInstruction::createDefCfa(Label, Register, Offset);
359   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
360   CurFrame->Instructions.push_back(Instruction);
361   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
362 }
363 
364 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
365   MCSymbol *Label = EmitCFICommon();
366   MCCFIInstruction Instruction =
367     MCCFIInstruction::createDefCfaOffset(Label, Offset);
368   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
369   CurFrame->Instructions.push_back(Instruction);
370 }
371 
372 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
373   MCSymbol *Label = EmitCFICommon();
374   MCCFIInstruction Instruction =
375     MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
376   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
377   CurFrame->Instructions.push_back(Instruction);
378 }
379 
380 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
381   MCSymbol *Label = EmitCFICommon();
382   MCCFIInstruction Instruction =
383     MCCFIInstruction::createDefCfaRegister(Label, Register);
384   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
385   CurFrame->Instructions.push_back(Instruction);
386   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
387 }
388 
389 void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
390   MCSymbol *Label = EmitCFICommon();
391   MCCFIInstruction Instruction =
392     MCCFIInstruction::createOffset(Label, Register, Offset);
393   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
394   CurFrame->Instructions.push_back(Instruction);
395 }
396 
397 void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
398   MCSymbol *Label = EmitCFICommon();
399   MCCFIInstruction Instruction =
400     MCCFIInstruction::createRelOffset(Label, Register, Offset);
401   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
402   CurFrame->Instructions.push_back(Instruction);
403 }
404 
405 void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
406                                     unsigned Encoding) {
407   EnsureValidDwarfFrame();
408   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
409   CurFrame->Personality = Sym;
410   CurFrame->PersonalityEncoding = Encoding;
411 }
412 
413 void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
414   EnsureValidDwarfFrame();
415   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
416   CurFrame->Lsda = Sym;
417   CurFrame->LsdaEncoding = Encoding;
418 }
419 
420 void MCStreamer::EmitCFIRememberState() {
421   MCSymbol *Label = EmitCFICommon();
422   MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
423   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
424   CurFrame->Instructions.push_back(Instruction);
425 }
426 
427 void MCStreamer::EmitCFIRestoreState() {
428   // FIXME: Error if there is no matching cfi_remember_state.
429   MCSymbol *Label = EmitCFICommon();
430   MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
431   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
432   CurFrame->Instructions.push_back(Instruction);
433 }
434 
435 void MCStreamer::EmitCFISameValue(int64_t Register) {
436   MCSymbol *Label = EmitCFICommon();
437   MCCFIInstruction Instruction =
438     MCCFIInstruction::createSameValue(Label, Register);
439   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
440   CurFrame->Instructions.push_back(Instruction);
441 }
442 
443 void MCStreamer::EmitCFIRestore(int64_t Register) {
444   MCSymbol *Label = EmitCFICommon();
445   MCCFIInstruction Instruction =
446     MCCFIInstruction::createRestore(Label, Register);
447   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
448   CurFrame->Instructions.push_back(Instruction);
449 }
450 
451 void MCStreamer::EmitCFIEscape(StringRef Values) {
452   MCSymbol *Label = EmitCFICommon();
453   MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
454   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
455   CurFrame->Instructions.push_back(Instruction);
456 }
457 
458 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
459   MCSymbol *Label = EmitCFICommon();
460   MCCFIInstruction Instruction =
461     MCCFIInstruction::createGnuArgsSize(Label, Size);
462   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
463   CurFrame->Instructions.push_back(Instruction);
464 }
465 
466 void MCStreamer::EmitCFISignalFrame() {
467   EnsureValidDwarfFrame();
468   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
469   CurFrame->IsSignalFrame = true;
470 }
471 
472 void MCStreamer::EmitCFIUndefined(int64_t Register) {
473   MCSymbol *Label = EmitCFICommon();
474   MCCFIInstruction Instruction =
475     MCCFIInstruction::createUndefined(Label, Register);
476   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
477   CurFrame->Instructions.push_back(Instruction);
478 }
479 
480 void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
481   MCSymbol *Label = EmitCFICommon();
482   MCCFIInstruction Instruction =
483     MCCFIInstruction::createRegister(Label, Register1, Register2);
484   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
485   CurFrame->Instructions.push_back(Instruction);
486 }
487 
488 void MCStreamer::EmitCFIWindowSave() {
489   MCSymbol *Label = EmitCFICommon();
490   MCCFIInstruction Instruction =
491     MCCFIInstruction::createWindowSave(Label);
492   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
493   CurFrame->Instructions.push_back(Instruction);
494 }
495 
496 void MCStreamer::EnsureValidWinFrameInfo() {
497   const MCAsmInfo *MAI = Context.getAsmInfo();
498   if (!MAI->usesWindowsCFI())
499     report_fatal_error(".seh_* directives are not supported on this target");
500   if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End)
501     report_fatal_error("No open Win64 EH frame function!");
502 }
503 
504 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
505   const MCAsmInfo *MAI = Context.getAsmInfo();
506   if (!MAI->usesWindowsCFI())
507     report_fatal_error(".seh_* directives are not supported on this target");
508   if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
509     report_fatal_error("Starting a function before ending the previous one!");
510 
511   MCSymbol *StartProc = EmitCFILabel();
512 
513   WinFrameInfos.push_back(new WinEH::FrameInfo(Symbol, StartProc));
514   CurrentWinFrameInfo = WinFrameInfos.back();
515   CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
516 }
517 
518 void MCStreamer::EmitWinCFIEndProc() {
519   EnsureValidWinFrameInfo();
520   if (CurrentWinFrameInfo->ChainedParent)
521     report_fatal_error("Not all chained regions terminated!");
522 
523   MCSymbol *Label = EmitCFILabel();
524   CurrentWinFrameInfo->End = Label;
525 }
526 
527 void MCStreamer::EmitWinCFIStartChained() {
528   EnsureValidWinFrameInfo();
529 
530   MCSymbol *StartProc = EmitCFILabel();
531 
532   WinFrameInfos.push_back(new WinEH::FrameInfo(CurrentWinFrameInfo->Function,
533                                                StartProc, CurrentWinFrameInfo));
534   CurrentWinFrameInfo = WinFrameInfos.back();
535   CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
536 }
537 
538 void MCStreamer::EmitWinCFIEndChained() {
539   EnsureValidWinFrameInfo();
540   if (!CurrentWinFrameInfo->ChainedParent)
541     report_fatal_error("End of a chained region outside a chained region!");
542 
543   MCSymbol *Label = EmitCFILabel();
544 
545   CurrentWinFrameInfo->End = Label;
546   CurrentWinFrameInfo =
547       const_cast<WinEH::FrameInfo *>(CurrentWinFrameInfo->ChainedParent);
548 }
549 
550 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
551                                   bool Except) {
552   EnsureValidWinFrameInfo();
553   if (CurrentWinFrameInfo->ChainedParent)
554     report_fatal_error("Chained unwind areas can't have handlers!");
555   CurrentWinFrameInfo->ExceptionHandler = Sym;
556   if (!Except && !Unwind)
557     report_fatal_error("Don't know what kind of handler this is!");
558   if (Unwind)
559     CurrentWinFrameInfo->HandlesUnwind = true;
560   if (Except)
561     CurrentWinFrameInfo->HandlesExceptions = true;
562 }
563 
564 void MCStreamer::EmitWinEHHandlerData() {
565   EnsureValidWinFrameInfo();
566   if (CurrentWinFrameInfo->ChainedParent)
567     report_fatal_error("Chained unwind areas can't have handlers!");
568 }
569 
570 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
571                                    MCSection *MainCFISec,
572                                    const MCSection *TextSec) {
573   // If this is the main .text section, use the main unwind info section.
574   if (TextSec == Context.getObjectFileInfo()->getTextSection())
575     return MainCFISec;
576 
577   const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
578   unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
579 
580   // If this section is COMDAT, this unwind section should be COMDAT associative
581   // with its group.
582   const MCSymbol *KeySym = nullptr;
583   if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
584     KeySym = TextSecCOFF->getCOMDATSymbol();
585 
586   return Context.getAssociativeCOFFSection(cast<MCSectionCOFF>(MainCFISec),
587                                            KeySym, UniqueID);
588 }
589 
590 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
591   return getWinCFISection(getContext(), &NextWinCFIID,
592                           getContext().getObjectFileInfo()->getPDataSection(),
593                           TextSec);
594 }
595 
596 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
597   return getWinCFISection(getContext(), &NextWinCFIID,
598                           getContext().getObjectFileInfo()->getXDataSection(),
599                           TextSec);
600 }
601 
602 void MCStreamer::EmitSyntaxDirective() {}
603 
604 void MCStreamer::EmitWinCFIPushReg(unsigned Register) {
605   EnsureValidWinFrameInfo();
606 
607   MCSymbol *Label = EmitCFILabel();
608 
609   WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register);
610   CurrentWinFrameInfo->Instructions.push_back(Inst);
611 }
612 
613 void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
614   EnsureValidWinFrameInfo();
615   if (CurrentWinFrameInfo->LastFrameInst >= 0)
616     report_fatal_error("Frame register and offset already specified!");
617   if (Offset & 0x0F)
618     report_fatal_error("Misaligned frame pointer offset!");
619   if (Offset > 240)
620     report_fatal_error("Frame offset must be less than or equal to 240!");
621 
622   MCSymbol *Label = EmitCFILabel();
623 
624   WinEH::Instruction Inst =
625       Win64EH::Instruction::SetFPReg(Label, Register, Offset);
626   CurrentWinFrameInfo->LastFrameInst = CurrentWinFrameInfo->Instructions.size();
627   CurrentWinFrameInfo->Instructions.push_back(Inst);
628 }
629 
630 void MCStreamer::EmitWinCFIAllocStack(unsigned Size) {
631   EnsureValidWinFrameInfo();
632   if (Size == 0)
633     report_fatal_error("Allocation size must be non-zero!");
634   if (Size & 7)
635     report_fatal_error("Misaligned stack allocation!");
636 
637   MCSymbol *Label = EmitCFILabel();
638 
639   WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
640   CurrentWinFrameInfo->Instructions.push_back(Inst);
641 }
642 
643 void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
644   EnsureValidWinFrameInfo();
645   if (Offset & 7)
646     report_fatal_error("Misaligned saved register offset!");
647 
648   MCSymbol *Label = EmitCFILabel();
649 
650   WinEH::Instruction Inst =
651       Win64EH::Instruction::SaveNonVol(Label, Register, Offset);
652   CurrentWinFrameInfo->Instructions.push_back(Inst);
653 }
654 
655 void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
656   EnsureValidWinFrameInfo();
657   if (Offset & 0x0F)
658     report_fatal_error("Misaligned saved vector register offset!");
659 
660   MCSymbol *Label = EmitCFILabel();
661 
662   WinEH::Instruction Inst =
663       Win64EH::Instruction::SaveXMM(Label, Register, Offset);
664   CurrentWinFrameInfo->Instructions.push_back(Inst);
665 }
666 
667 void MCStreamer::EmitWinCFIPushFrame(bool Code) {
668   EnsureValidWinFrameInfo();
669   if (CurrentWinFrameInfo->Instructions.size() > 0)
670     report_fatal_error("If present, PushMachFrame must be the first UOP");
671 
672   MCSymbol *Label = EmitCFILabel();
673 
674   WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
675   CurrentWinFrameInfo->Instructions.push_back(Inst);
676 }
677 
678 void MCStreamer::EmitWinCFIEndProlog() {
679   EnsureValidWinFrameInfo();
680 
681   MCSymbol *Label = EmitCFILabel();
682 
683   CurrentWinFrameInfo->PrologEnd = Label;
684 }
685 
686 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
687 }
688 
689 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
690 }
691 
692 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
693 
694 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
695 /// the specified string in the output .s file.  This capability is
696 /// indicated by the hasRawTextSupport() predicate.
697 void MCStreamer::EmitRawTextImpl(StringRef String) {
698   errs() << "EmitRawText called on an MCStreamer that doesn't support it, "
699   " something must not be fully mc'ized\n";
700   abort();
701 }
702 
703 void MCStreamer::EmitRawText(const Twine &T) {
704   SmallString<128> Str;
705   EmitRawTextImpl(T.toStringRef(Str));
706 }
707 
708 void MCStreamer::EmitWindowsUnwindTables() {
709 }
710 
711 void MCStreamer::Finish() {
712   if (!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End)
713     report_fatal_error("Unfinished frame!");
714 
715   MCTargetStreamer *TS = getTargetStreamer();
716   if (TS)
717     TS->finish();
718 
719   FinishImpl();
720 }
721 
722 void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
723   visitUsedExpr(*Value);
724   Symbol->setVariableValue(Value);
725 
726   MCTargetStreamer *TS = getTargetStreamer();
727   if (TS)
728     TS->emitAssignment(Symbol, Value);
729 }
730 
731 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS,
732                               const MCInst &Inst, const MCSubtargetInfo &STI) {
733   InstPrinter.printInst(&Inst, OS, "", STI);
734 }
735 
736 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
737 }
738 
739 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
740   switch (Expr.getKind()) {
741   case MCExpr::Target:
742     cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
743     break;
744 
745   case MCExpr::Constant:
746     break;
747 
748   case MCExpr::Binary: {
749     const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
750     visitUsedExpr(*BE.getLHS());
751     visitUsedExpr(*BE.getRHS());
752     break;
753   }
754 
755   case MCExpr::SymbolRef:
756     visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
757     break;
758 
759   case MCExpr::Unary:
760     visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
761     break;
762   }
763 }
764 
765 void MCStreamer::EmitInstruction(const MCInst &Inst,
766                                  const MCSubtargetInfo &STI) {
767   // Scan for values.
768   for (unsigned i = Inst.getNumOperands(); i--;)
769     if (Inst.getOperand(i).isExpr())
770       visitUsedExpr(*Inst.getOperand(i).getExpr());
771 }
772 
773 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
774                                         unsigned Size) {
775   // Get the Hi-Lo expression.
776   const MCExpr *Diff =
777       MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
778                               MCSymbolRefExpr::create(Lo, Context), Context);
779 
780   const MCAsmInfo *MAI = Context.getAsmInfo();
781   if (!MAI->doesSetDirectiveSuppressReloc()) {
782     EmitValue(Diff, Size);
783     return;
784   }
785 
786   // Otherwise, emit with .set (aka assignment).
787   MCSymbol *SetLabel = Context.createTempSymbol("set", true);
788   EmitAssignment(SetLabel, Diff);
789   EmitSymbolValue(SetLabel, Size);
790 }
791 
792 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
793 void MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
794 void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
795 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {}
796 void MCStreamer::EndCOFFSymbolDef() {}
797 void MCStreamer::EmitFileDirective(StringRef Filename) {}
798 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {}
799 void MCStreamer::EmitCOFFSymbolType(int Type) {}
800 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
801 void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
802                                        unsigned ByteAlignment) {}
803 void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
804                                 uint64_t Size, unsigned ByteAlignment) {}
805 void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {}
806 void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
807 void MCStreamer::EmitBytes(StringRef Data) {}
808 void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); }
809 void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
810   visitUsedExpr(*Value);
811 }
812 void MCStreamer::EmitULEB128Value(const MCExpr *Value) {}
813 void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {}
814 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
815 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
816                           SMLoc Loc) {}
817 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
818                                       unsigned ValueSize,
819                                       unsigned MaxBytesToEmit) {}
820 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment,
821                                    unsigned MaxBytesToEmit) {}
822 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
823                                    SMLoc Loc) {}
824 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {}
825 void MCStreamer::EmitBundleLock(bool AlignToEnd) {}
826 void MCStreamer::FinishImpl() {}
827 void MCStreamer::EmitBundleUnlock() {}
828 
829 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
830   assert(Section && "Cannot switch to a null section!");
831   MCSectionSubPair curSection = SectionStack.back().first;
832   SectionStack.back().second = curSection;
833   if (MCSectionSubPair(Section, Subsection) != curSection) {
834     ChangeSection(Section, Subsection);
835     SectionStack.back().first = MCSectionSubPair(Section, Subsection);
836     assert(!Section->hasEnded() && "Section already ended");
837     MCSymbol *Sym = Section->getBeginSymbol();
838     if (Sym && !Sym->isInSection())
839       EmitLabel(Sym);
840   }
841 }
842 
843 MCSymbol *MCStreamer::endSection(MCSection *Section) {
844   // TODO: keep track of the last subsection so that this symbol appears in the
845   // correct place.
846   MCSymbol *Sym = Section->getEndSymbol(Context);
847   if (Sym->isInSection())
848     return Sym;
849 
850   SwitchSection(Section);
851   EmitLabel(Sym);
852   return Sym;
853 }
854