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