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