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