xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCStreamer.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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/SmallString.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/BinaryFormat/COFF.h"
14 #include "llvm/BinaryFormat/MachO.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 <optional>
42 #include <utility>
43 
44 using namespace llvm;
45 
MCTargetStreamer(MCStreamer & S)46 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
47   S.setTargetStreamer(this);
48 }
49 
50 // Pin the vtables to this file.
51 MCTargetStreamer::~MCTargetStreamer() = default;
52 
emitLabel(MCSymbol * Symbol)53 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
54 
finish()55 void MCTargetStreamer::finish() {}
56 
emitConstantPools()57 void MCTargetStreamer::emitConstantPools() {}
58 
changeSection(const MCSection * CurSection,MCSection * Section,uint32_t Subsection,raw_ostream & OS)59 void MCTargetStreamer::changeSection(const MCSection *CurSection,
60                                      MCSection *Section, uint32_t Subsection,
61                                      raw_ostream &OS) {
62   Section->printSwitchToSection(*Streamer.getContext().getAsmInfo(),
63                                 Streamer.getContext().getTargetTriple(), OS,
64                                 Subsection);
65 }
66 
emitDwarfFileDirective(StringRef Directive)67 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
68   Streamer.emitRawText(Directive);
69 }
70 
emitValue(const MCExpr * Value)71 void MCTargetStreamer::emitValue(const MCExpr *Value) {
72   SmallString<128> Str;
73   raw_svector_ostream OS(Str);
74 
75   Streamer.getContext().getAsmInfo()->printExpr(OS, *Value);
76   Streamer.emitRawText(OS.str());
77 }
78 
emitRawBytes(StringRef Data)79 void MCTargetStreamer::emitRawBytes(StringRef Data) {
80   const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
81   const char *Directive = MAI->getData8bitsDirective();
82   for (const unsigned char C : Data.bytes()) {
83     SmallString<128> Str;
84     raw_svector_ostream OS(Str);
85 
86     OS << Directive << (unsigned)C;
87     Streamer.emitRawText(OS.str());
88   }
89 }
90 
emitAssignment(MCSymbol * Symbol,const MCExpr * Value)91 void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
92 
MCStreamer(MCContext & Ctx)93 MCStreamer::MCStreamer(MCContext &Ctx)
94     : Context(Ctx), CurrentWinFrameInfo(nullptr),
95       CurrentProcWinFrameInfoStartIndex(0) {
96   SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
97 }
98 
99 MCStreamer::~MCStreamer() = default;
100 
reset()101 void MCStreamer::reset() {
102   DwarfFrameInfos.clear();
103   CurrentWinFrameInfo = nullptr;
104   WinFrameInfos.clear();
105   SectionStack.clear();
106   SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
107   CurFrag = nullptr;
108 }
109 
getCommentOS()110 raw_ostream &MCStreamer::getCommentOS() {
111   // By default, discard comments.
112   return nulls();
113 }
114 
getNumFrameInfos()115 unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos.size(); }
getDwarfFrameInfos() const116 ArrayRef<MCDwarfFrameInfo> MCStreamer::getDwarfFrameInfos() const {
117   return DwarfFrameInfos;
118 }
119 
emitRawComment(const Twine & T,bool TabPrefix)120 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
121 
addExplicitComment(const Twine & T)122 void MCStreamer::addExplicitComment(const Twine &T) {}
emitExplicitComments()123 void MCStreamer::emitExplicitComments() {}
124 
generateCompactUnwindEncodings(MCAsmBackend * MAB)125 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
126   for (auto &FI : DwarfFrameInfos)
127     FI.CompactUnwindEncoding =
128         (MAB ? MAB->generateCompactUnwindEncoding(&FI, &Context) : 0);
129 }
130 
131 /// EmitIntValue - Special case of EmitValue that avoids the client having to
132 /// pass in a MCExpr for constant integers.
emitIntValue(uint64_t Value,unsigned Size)133 void MCStreamer::emitIntValue(uint64_t Value, unsigned Size) {
134   assert(1 <= Size && Size <= 8 && "Invalid size");
135   assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
136          "Invalid size");
137   const bool IsLittleEndian = Context.getAsmInfo()->isLittleEndian();
138   uint64_t Swapped = support::endian::byte_swap(
139       Value, IsLittleEndian ? llvm::endianness::little : llvm::endianness::big);
140   unsigned Index = IsLittleEndian ? 0 : 8 - Size;
141   emitBytes(StringRef(reinterpret_cast<char *>(&Swapped) + Index, Size));
142 }
emitIntValue(const APInt & Value)143 void MCStreamer::emitIntValue(const APInt &Value) {
144   if (Value.getNumWords() == 1) {
145     emitIntValue(Value.getLimitedValue(), Value.getBitWidth() / 8);
146     return;
147   }
148 
149   const bool IsLittleEndianTarget = Context.getAsmInfo()->isLittleEndian();
150   const bool ShouldSwap = sys::IsLittleEndianHost != IsLittleEndianTarget;
151   const APInt Swapped = ShouldSwap ? Value.byteSwap() : Value;
152   const unsigned Size = Value.getBitWidth() / 8;
153   SmallString<10> Tmp;
154   Tmp.resize(Size);
155   StoreIntToMemory(Swapped, reinterpret_cast<uint8_t *>(Tmp.data()), Size);
156   emitBytes(Tmp.str());
157 }
158 
159 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
160 /// client having to pass in a MCExpr for constant integers.
emitULEB128IntValue(uint64_t Value,unsigned PadTo)161 unsigned MCStreamer::emitULEB128IntValue(uint64_t Value, unsigned PadTo) {
162   SmallString<128> Tmp;
163   raw_svector_ostream OSE(Tmp);
164   encodeULEB128(Value, OSE, PadTo);
165   emitBytes(OSE.str());
166   return Tmp.size();
167 }
168 
169 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
170 /// client having to pass in a MCExpr for constant integers.
emitSLEB128IntValue(int64_t Value)171 unsigned MCStreamer::emitSLEB128IntValue(int64_t Value) {
172   SmallString<128> Tmp;
173   raw_svector_ostream OSE(Tmp);
174   encodeSLEB128(Value, OSE);
175   emitBytes(OSE.str());
176   return Tmp.size();
177 }
178 
emitValue(const MCExpr * Value,unsigned Size,SMLoc Loc)179 void MCStreamer::emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
180   emitValueImpl(Value, Size, Loc);
181 }
182 
emitSymbolValue(const MCSymbol * Sym,unsigned Size,bool IsSectionRelative)183 void MCStreamer::emitSymbolValue(const MCSymbol *Sym, unsigned Size,
184                                  bool IsSectionRelative) {
185   assert((!IsSectionRelative || Size == 4) &&
186          "SectionRelative value requires 4-bytes");
187 
188   if (!IsSectionRelative)
189     emitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
190   else
191     emitCOFFSecRel32(Sym, /*Offset=*/0);
192 }
193 
194 /// Emit NumBytes bytes worth of the value specified by FillValue.
195 /// This implements directives such as '.space'.
emitFill(uint64_t NumBytes,uint8_t FillValue)196 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
197   if (NumBytes)
198     emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
199 }
200 
emitNops(int64_t NumBytes,int64_t ControlledNopLen,llvm::SMLoc,const MCSubtargetInfo & STI)201 void llvm::MCStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLen,
202                                 llvm::SMLoc, const MCSubtargetInfo& STI) {}
203 
204 /// The implementation in this class just redirects to emitFill.
emitZeros(uint64_t NumBytes)205 void MCStreamer::emitZeros(uint64_t NumBytes) { emitFill(NumBytes, 0); }
206 
tryEmitDwarfFileDirective(unsigned FileNo,StringRef Directory,StringRef Filename,std::optional<MD5::MD5Result> Checksum,std::optional<StringRef> Source,unsigned CUID)207 Expected<unsigned> MCStreamer::tryEmitDwarfFileDirective(
208     unsigned FileNo, StringRef Directory, StringRef Filename,
209     std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
210     unsigned CUID) {
211   return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
212                                    Source, CUID);
213 }
214 
emitDwarfFile0Directive(StringRef Directory,StringRef Filename,std::optional<MD5::MD5Result> Checksum,std::optional<StringRef> Source,unsigned CUID)215 void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
216                                          StringRef Filename,
217                                          std::optional<MD5::MD5Result> Checksum,
218                                          std::optional<StringRef> Source,
219                                          unsigned CUID) {
220   getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
221                                       Source);
222 }
223 
emitCFIBKeyFrame()224 void MCStreamer::emitCFIBKeyFrame() {
225   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
226   if (!CurFrame)
227     return;
228   CurFrame->IsBKeyFrame = true;
229 }
230 
emitCFIMTETaggedFrame()231 void MCStreamer::emitCFIMTETaggedFrame() {
232   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
233   if (!CurFrame)
234     return;
235   CurFrame->IsMTETaggedFrame = true;
236 }
237 
emitDwarfLocDirective(unsigned FileNo,unsigned Line,unsigned Column,unsigned Flags,unsigned Isa,unsigned Discriminator,StringRef FileName,StringRef Comment)238 void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
239                                        unsigned Column, unsigned Flags,
240                                        unsigned Isa, unsigned Discriminator,
241                                        StringRef FileName, StringRef Comment) {
242   getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
243                                   Discriminator);
244 }
245 
emitDwarfLocLabelDirective(SMLoc Loc,StringRef Name)246 void MCStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) {
247   getContext()
248       .getMCDwarfLineTable(getContext().getDwarfCompileUnitID())
249       .endCurrentSeqAndEmitLineStreamLabel(this, Loc, Name);
250 }
251 
getDwarfLineTableSymbol(unsigned CUID)252 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
253   MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
254   if (!Table.getLabel()) {
255     StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
256     Table.setLabel(
257         Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
258   }
259   return Table.getLabel();
260 }
261 
hasUnfinishedDwarfFrameInfo()262 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
263   return !FrameInfoStack.empty();
264 }
265 
getCurrentDwarfFrameInfo()266 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
267   if (!hasUnfinishedDwarfFrameInfo()) {
268     getContext().reportError(getStartTokLoc(),
269                              "this directive must appear between "
270                              ".cfi_startproc and .cfi_endproc directives");
271     return nullptr;
272   }
273   return &DwarfFrameInfos[FrameInfoStack.back().first];
274 }
275 
emitCVFileDirective(unsigned FileNo,StringRef Filename,ArrayRef<uint8_t> Checksum,unsigned ChecksumKind)276 bool MCStreamer::emitCVFileDirective(unsigned FileNo, StringRef Filename,
277                                      ArrayRef<uint8_t> Checksum,
278                                      unsigned ChecksumKind) {
279   return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
280                                              ChecksumKind);
281 }
282 
emitCVFuncIdDirective(unsigned FunctionId)283 bool MCStreamer::emitCVFuncIdDirective(unsigned FunctionId) {
284   return getContext().getCVContext().recordFunctionId(FunctionId);
285 }
286 
emitCVInlineSiteIdDirective(unsigned FunctionId,unsigned IAFunc,unsigned IAFile,unsigned IALine,unsigned IACol,SMLoc Loc)287 bool MCStreamer::emitCVInlineSiteIdDirective(unsigned FunctionId,
288                                              unsigned IAFunc, unsigned IAFile,
289                                              unsigned IALine, unsigned IACol,
290                                              SMLoc Loc) {
291   if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
292     getContext().reportError(Loc, "parent function id not introduced by "
293                                   ".cv_func_id or .cv_inline_site_id");
294     return true;
295   }
296 
297   return getContext().getCVContext().recordInlinedCallSiteId(
298       FunctionId, IAFunc, IAFile, IALine, IACol);
299 }
300 
emitCVLocDirective(unsigned FunctionId,unsigned FileNo,unsigned Line,unsigned Column,bool PrologueEnd,bool IsStmt,StringRef FileName,SMLoc Loc)301 void MCStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
302                                     unsigned Line, unsigned Column,
303                                     bool PrologueEnd, bool IsStmt,
304                                     StringRef FileName, SMLoc Loc) {}
305 
checkCVLocSection(unsigned FuncId,unsigned FileNo,SMLoc Loc)306 bool MCStreamer::checkCVLocSection(unsigned FuncId, unsigned FileNo,
307                                    SMLoc Loc) {
308   CodeViewContext &CVC = getContext().getCVContext();
309   MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId);
310   if (!FI) {
311     getContext().reportError(
312         Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
313     return false;
314   }
315 
316   // Track the section
317   if (FI->Section == nullptr)
318     FI->Section = getCurrentSectionOnly();
319   else if (FI->Section != getCurrentSectionOnly()) {
320     getContext().reportError(
321         Loc,
322         "all .cv_loc directives for a function must be in the same section");
323     return false;
324   }
325   return true;
326 }
327 
emitCVLinetableDirective(unsigned FunctionId,const MCSymbol * Begin,const MCSymbol * End)328 void MCStreamer::emitCVLinetableDirective(unsigned FunctionId,
329                                           const MCSymbol *Begin,
330                                           const MCSymbol *End) {}
331 
emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,unsigned SourceFileId,unsigned SourceLineNum,const MCSymbol * FnStartSym,const MCSymbol * FnEndSym)332 void MCStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
333                                                 unsigned SourceFileId,
334                                                 unsigned SourceLineNum,
335                                                 const MCSymbol *FnStartSym,
336                                                 const MCSymbol *FnEndSym) {}
337 
338 /// Only call this on endian-specific types like ulittle16_t and little32_t, or
339 /// structs composed of them.
340 template <typename T>
copyBytesForDefRange(SmallString<20> & BytePrefix,codeview::SymbolKind SymKind,const T & DefRangeHeader)341 static void copyBytesForDefRange(SmallString<20> &BytePrefix,
342                                  codeview::SymbolKind SymKind,
343                                  const T &DefRangeHeader) {
344   BytePrefix.resize(2 + sizeof(T));
345   codeview::ulittle16_t SymKindLE = codeview::ulittle16_t(SymKind);
346   memcpy(&BytePrefix[0], &SymKindLE, 2);
347   memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T));
348 }
349 
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,StringRef FixedSizePortion)350 void MCStreamer::emitCVDefRangeDirective(
351     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
352     StringRef FixedSizePortion) {}
353 
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeRegisterRelHeader DRHdr)354 void MCStreamer::emitCVDefRangeDirective(
355     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
356     codeview::DefRangeRegisterRelHeader DRHdr) {
357   SmallString<20> BytePrefix;
358   copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER_REL, DRHdr);
359   emitCVDefRangeDirective(Ranges, BytePrefix);
360 }
361 
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeSubfieldRegisterHeader DRHdr)362 void MCStreamer::emitCVDefRangeDirective(
363     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
364     codeview::DefRangeSubfieldRegisterHeader DRHdr) {
365   SmallString<20> BytePrefix;
366   copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_SUBFIELD_REGISTER,
367                        DRHdr);
368   emitCVDefRangeDirective(Ranges, BytePrefix);
369 }
370 
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeRegisterHeader DRHdr)371 void MCStreamer::emitCVDefRangeDirective(
372     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
373     codeview::DefRangeRegisterHeader DRHdr) {
374   SmallString<20> BytePrefix;
375   copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER, DRHdr);
376   emitCVDefRangeDirective(Ranges, BytePrefix);
377 }
378 
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeFramePointerRelHeader DRHdr)379 void MCStreamer::emitCVDefRangeDirective(
380     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
381     codeview::DefRangeFramePointerRelHeader DRHdr) {
382   SmallString<20> BytePrefix;
383   copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_FRAMEPOINTER_REL,
384                        DRHdr);
385   emitCVDefRangeDirective(Ranges, BytePrefix);
386 }
387 
emitEHSymAttributes(const MCSymbol * Symbol,MCSymbol * EHSymbol)388 void MCStreamer::emitEHSymAttributes(const MCSymbol *Symbol,
389                                      MCSymbol *EHSymbol) {
390 }
391 
initSections(bool NoExecStack,const MCSubtargetInfo & STI)392 void MCStreamer::initSections(bool NoExecStack, const MCSubtargetInfo &STI) {
393   switchSectionNoPrint(getContext().getObjectFileInfo()->getTextSection());
394 }
395 
emitLabel(MCSymbol * Symbol,SMLoc Loc)396 void MCStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
397   Symbol->redefineIfPossible();
398 
399   if (!Symbol->isUndefined() || Symbol->isVariable())
400     return getContext().reportError(Loc, "symbol '" + Twine(Symbol->getName()) +
401                                              "' is already defined");
402 
403   assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
404   assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
405   assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
406   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
407 
408   Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
409 
410   MCTargetStreamer *TS = getTargetStreamer();
411   if (TS)
412     TS->emitLabel(Symbol);
413 }
414 
emitConditionalAssignment(MCSymbol * Symbol,const MCExpr * Value)415 void MCStreamer::emitConditionalAssignment(MCSymbol *Symbol,
416                                            const MCExpr *Value) {}
417 
emitCFISections(bool EH,bool Debug)418 void MCStreamer::emitCFISections(bool EH, bool Debug) {}
419 
emitCFIStartProc(bool IsSimple,SMLoc Loc)420 void MCStreamer::emitCFIStartProc(bool IsSimple, SMLoc Loc) {
421   if (!FrameInfoStack.empty() &&
422       getCurrentSectionOnly() == FrameInfoStack.back().second)
423     return getContext().reportError(
424         Loc, "starting new .cfi frame before finishing the previous one");
425 
426   MCDwarfFrameInfo Frame;
427   Frame.IsSimple = IsSimple;
428   emitCFIStartProcImpl(Frame);
429 
430   const MCAsmInfo* MAI = Context.getAsmInfo();
431   if (MAI) {
432     for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
433       if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
434           Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister ||
435           Inst.getOperation() == MCCFIInstruction::OpLLVMDefAspaceCfa) {
436         Frame.CurrentCfaRegister = Inst.getRegister();
437       }
438     }
439   }
440 
441   FrameInfoStack.emplace_back(DwarfFrameInfos.size(), getCurrentSectionOnly());
442   DwarfFrameInfos.push_back(std::move(Frame));
443 }
444 
emitCFIStartProcImpl(MCDwarfFrameInfo & Frame)445 void MCStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
446 }
447 
emitCFIEndProc()448 void MCStreamer::emitCFIEndProc() {
449   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
450   if (!CurFrame)
451     return;
452   emitCFIEndProcImpl(*CurFrame);
453   FrameInfoStack.pop_back();
454 }
455 
emitCFIEndProcImpl(MCDwarfFrameInfo & Frame)456 void MCStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
457   // Put a dummy non-null value in Frame.End to mark that this frame has been
458   // closed.
459   Frame.End = (MCSymbol *)1;
460 }
461 
emitLineTableLabel()462 MCSymbol *MCStreamer::emitLineTableLabel() {
463   // Create a label and insert it into the line table and return this label
464   const MCDwarfLoc &DwarfLoc = getContext().getCurrentDwarfLoc();
465 
466   MCSymbol *LineStreamLabel = getContext().createTempSymbol();
467   MCDwarfLineEntry LabelLineEntry(nullptr, DwarfLoc, LineStreamLabel);
468   getContext()
469       .getMCDwarfLineTable(getContext().getDwarfCompileUnitID())
470       .getMCLineSections()
471       .addLineEntry(LabelLineEntry, getCurrentSectionOnly() /*Section*/);
472 
473   return LineStreamLabel;
474 }
475 
emitCFILabel()476 MCSymbol *MCStreamer::emitCFILabel() {
477   // Return a dummy non-null value so that label fields appear filled in when
478   // generating textual assembly.
479   return (MCSymbol *)1;
480 }
481 
emitCFIDefCfa(int64_t Register,int64_t Offset,SMLoc Loc)482 void MCStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) {
483   MCSymbol *Label = emitCFILabel();
484   MCCFIInstruction Instruction =
485       MCCFIInstruction::cfiDefCfa(Label, Register, Offset, Loc);
486   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
487   if (!CurFrame)
488     return;
489   CurFrame->Instructions.push_back(std::move(Instruction));
490   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
491 }
492 
emitCFIDefCfaOffset(int64_t Offset,SMLoc Loc)493 void MCStreamer::emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) {
494   MCSymbol *Label = emitCFILabel();
495   MCCFIInstruction Instruction =
496       MCCFIInstruction::cfiDefCfaOffset(Label, Offset);
497   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
498   if (!CurFrame)
499     return;
500   CurFrame->Instructions.push_back(std::move(Instruction));
501 }
502 
emitCFIAdjustCfaOffset(int64_t Adjustment,SMLoc Loc)503 void MCStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) {
504   MCSymbol *Label = emitCFILabel();
505   MCCFIInstruction Instruction =
506       MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment, Loc);
507   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
508   if (!CurFrame)
509     return;
510   CurFrame->Instructions.push_back(std::move(Instruction));
511 }
512 
emitCFIDefCfaRegister(int64_t Register,SMLoc Loc)513 void MCStreamer::emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) {
514   MCSymbol *Label = emitCFILabel();
515   MCCFIInstruction Instruction =
516       MCCFIInstruction::createDefCfaRegister(Label, Register, Loc);
517   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
518   if (!CurFrame)
519     return;
520   CurFrame->Instructions.push_back(std::move(Instruction));
521   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
522 }
523 
emitCFILLVMDefAspaceCfa(int64_t Register,int64_t Offset,int64_t AddressSpace,SMLoc Loc)524 void MCStreamer::emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
525                                          int64_t AddressSpace, SMLoc Loc) {
526   MCSymbol *Label = emitCFILabel();
527   MCCFIInstruction Instruction = MCCFIInstruction::createLLVMDefAspaceCfa(
528       Label, Register, Offset, AddressSpace, Loc);
529   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
530   if (!CurFrame)
531     return;
532   CurFrame->Instructions.push_back(std::move(Instruction));
533   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
534 }
535 
emitCFIOffset(int64_t Register,int64_t Offset,SMLoc Loc)536 void MCStreamer::emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
537   MCSymbol *Label = emitCFILabel();
538   MCCFIInstruction Instruction =
539       MCCFIInstruction::createOffset(Label, Register, Offset, Loc);
540   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
541   if (!CurFrame)
542     return;
543   CurFrame->Instructions.push_back(std::move(Instruction));
544 }
545 
emitCFIRelOffset(int64_t Register,int64_t Offset,SMLoc Loc)546 void MCStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
547   MCSymbol *Label = emitCFILabel();
548   MCCFIInstruction Instruction =
549       MCCFIInstruction::createRelOffset(Label, Register, Offset, Loc);
550   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
551   if (!CurFrame)
552     return;
553   CurFrame->Instructions.push_back(std::move(Instruction));
554 }
555 
emitCFIPersonality(const MCSymbol * Sym,unsigned Encoding)556 void MCStreamer::emitCFIPersonality(const MCSymbol *Sym,
557                                     unsigned Encoding) {
558   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
559   if (!CurFrame)
560     return;
561   CurFrame->Personality = Sym;
562   CurFrame->PersonalityEncoding = Encoding;
563 }
564 
emitCFILsda(const MCSymbol * Sym,unsigned Encoding)565 void MCStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
566   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
567   if (!CurFrame)
568     return;
569   CurFrame->Lsda = Sym;
570   CurFrame->LsdaEncoding = Encoding;
571 }
572 
emitCFIRememberState(SMLoc Loc)573 void MCStreamer::emitCFIRememberState(SMLoc Loc) {
574   MCSymbol *Label = emitCFILabel();
575   MCCFIInstruction Instruction =
576       MCCFIInstruction::createRememberState(Label, Loc);
577   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
578   if (!CurFrame)
579     return;
580   CurFrame->Instructions.push_back(std::move(Instruction));
581 }
582 
emitCFIRestoreState(SMLoc Loc)583 void MCStreamer::emitCFIRestoreState(SMLoc Loc) {
584   // FIXME: Error if there is no matching cfi_remember_state.
585   MCSymbol *Label = emitCFILabel();
586   MCCFIInstruction Instruction =
587       MCCFIInstruction::createRestoreState(Label, Loc);
588   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
589   if (!CurFrame)
590     return;
591   CurFrame->Instructions.push_back(std::move(Instruction));
592 }
593 
emitCFISameValue(int64_t Register,SMLoc Loc)594 void MCStreamer::emitCFISameValue(int64_t Register, SMLoc Loc) {
595   MCSymbol *Label = emitCFILabel();
596   MCCFIInstruction Instruction =
597       MCCFIInstruction::createSameValue(Label, Register, Loc);
598   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
599   if (!CurFrame)
600     return;
601   CurFrame->Instructions.push_back(std::move(Instruction));
602 }
603 
emitCFIRestore(int64_t Register,SMLoc Loc)604 void MCStreamer::emitCFIRestore(int64_t Register, SMLoc Loc) {
605   MCSymbol *Label = emitCFILabel();
606   MCCFIInstruction Instruction =
607       MCCFIInstruction::createRestore(Label, Register, Loc);
608   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
609   if (!CurFrame)
610     return;
611   CurFrame->Instructions.push_back(std::move(Instruction));
612 }
613 
emitCFIEscape(StringRef Values,SMLoc Loc)614 void MCStreamer::emitCFIEscape(StringRef Values, SMLoc Loc) {
615   MCSymbol *Label = emitCFILabel();
616   MCCFIInstruction Instruction =
617       MCCFIInstruction::createEscape(Label, Values, Loc, "");
618   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
619   if (!CurFrame)
620     return;
621   CurFrame->Instructions.push_back(std::move(Instruction));
622 }
623 
emitCFIGnuArgsSize(int64_t Size,SMLoc Loc)624 void MCStreamer::emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) {
625   MCSymbol *Label = emitCFILabel();
626   MCCFIInstruction Instruction =
627       MCCFIInstruction::createGnuArgsSize(Label, Size, Loc);
628   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
629   if (!CurFrame)
630     return;
631   CurFrame->Instructions.push_back(std::move(Instruction));
632 }
633 
emitCFISignalFrame()634 void MCStreamer::emitCFISignalFrame() {
635   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
636   if (!CurFrame)
637     return;
638   CurFrame->IsSignalFrame = true;
639 }
640 
emitCFIUndefined(int64_t Register,SMLoc Loc)641 void MCStreamer::emitCFIUndefined(int64_t Register, SMLoc Loc) {
642   MCSymbol *Label = emitCFILabel();
643   MCCFIInstruction Instruction =
644       MCCFIInstruction::createUndefined(Label, Register, Loc);
645   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
646   if (!CurFrame)
647     return;
648   CurFrame->Instructions.push_back(std::move(Instruction));
649 }
650 
emitCFIRegister(int64_t Register1,int64_t Register2,SMLoc Loc)651 void MCStreamer::emitCFIRegister(int64_t Register1, int64_t Register2,
652                                  SMLoc Loc) {
653   MCSymbol *Label = emitCFILabel();
654   MCCFIInstruction Instruction =
655       MCCFIInstruction::createRegister(Label, Register1, Register2, Loc);
656   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
657   if (!CurFrame)
658     return;
659   CurFrame->Instructions.push_back(std::move(Instruction));
660 }
661 
emitCFIWindowSave(SMLoc Loc)662 void MCStreamer::emitCFIWindowSave(SMLoc Loc) {
663   MCSymbol *Label = emitCFILabel();
664   MCCFIInstruction Instruction = MCCFIInstruction::createWindowSave(Label, Loc);
665   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
666   if (!CurFrame)
667     return;
668   CurFrame->Instructions.push_back(std::move(Instruction));
669 }
670 
emitCFINegateRAState(SMLoc Loc)671 void MCStreamer::emitCFINegateRAState(SMLoc Loc) {
672   MCSymbol *Label = emitCFILabel();
673   MCCFIInstruction Instruction =
674       MCCFIInstruction::createNegateRAState(Label, Loc);
675   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
676   if (!CurFrame)
677     return;
678   CurFrame->Instructions.push_back(std::move(Instruction));
679 }
680 
emitCFINegateRAStateWithPC(SMLoc Loc)681 void MCStreamer::emitCFINegateRAStateWithPC(SMLoc Loc) {
682   MCSymbol *Label = emitCFILabel();
683   MCCFIInstruction Instruction =
684       MCCFIInstruction::createNegateRAStateWithPC(Label, Loc);
685   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
686   if (!CurFrame)
687     return;
688   CurFrame->Instructions.push_back(std::move(Instruction));
689 }
690 
emitCFIReturnColumn(int64_t Register)691 void MCStreamer::emitCFIReturnColumn(int64_t Register) {
692   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
693   if (!CurFrame)
694     return;
695   CurFrame->RAReg = Register;
696 }
697 
emitCFILabelDirective(SMLoc Loc,StringRef Name)698 void MCStreamer::emitCFILabelDirective(SMLoc Loc, StringRef Name) {
699   MCSymbol *Label = emitCFILabel();
700   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
701   if (MCDwarfFrameInfo *F = getCurrentDwarfFrameInfo())
702     F->Instructions.push_back(MCCFIInstruction::createLabel(Label, Sym, Loc));
703 }
704 
emitCFIValOffset(int64_t Register,int64_t Offset,SMLoc Loc)705 void MCStreamer::emitCFIValOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
706   MCSymbol *Label = emitCFILabel();
707   MCCFIInstruction Instruction =
708       MCCFIInstruction::createValOffset(Label, Register, Offset, Loc);
709   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
710   if (!CurFrame)
711     return;
712   CurFrame->Instructions.push_back(std::move(Instruction));
713 }
714 
EnsureValidWinFrameInfo(SMLoc Loc)715 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
716   const MCAsmInfo *MAI = Context.getAsmInfo();
717   if (!MAI->usesWindowsCFI()) {
718     getContext().reportError(
719         Loc, ".seh_* directives are not supported on this target");
720     return nullptr;
721   }
722   if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
723     getContext().reportError(
724         Loc, ".seh_ directive must appear within an active frame");
725     return nullptr;
726   }
727   return CurrentWinFrameInfo;
728 }
729 
emitWinCFIStartProc(const MCSymbol * Symbol,SMLoc Loc)730 void MCStreamer::emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
731   const MCAsmInfo *MAI = Context.getAsmInfo();
732   if (!MAI->usesWindowsCFI())
733     return getContext().reportError(
734         Loc, ".seh_* directives are not supported on this target");
735   if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
736     getContext().reportError(
737         Loc, "Starting a function before ending the previous one!");
738 
739   MCSymbol *StartProc = emitCFILabel();
740 
741   CurrentProcWinFrameInfoStartIndex = WinFrameInfos.size();
742   WinFrameInfos.emplace_back(
743       std::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
744   CurrentWinFrameInfo = WinFrameInfos.back().get();
745   CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
746   CurrentWinFrameInfo->FunctionLoc = Loc;
747 }
748 
emitWinCFIEndProc(SMLoc Loc)749 void MCStreamer::emitWinCFIEndProc(SMLoc Loc) {
750   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
751   if (!CurFrame)
752     return;
753   if (CurFrame->ChainedParent)
754     getContext().reportError(Loc, "Not all chained regions terminated!");
755 
756   MCSymbol *Label = emitCFILabel();
757   CurFrame->End = Label;
758   if (!CurFrame->FuncletOrFuncEnd)
759     CurFrame->FuncletOrFuncEnd = CurFrame->End;
760 
761   for (size_t I = CurrentProcWinFrameInfoStartIndex, E = WinFrameInfos.size();
762        I != E; ++I)
763     emitWindowsUnwindTables(WinFrameInfos[I].get());
764   switchSection(CurFrame->TextSection);
765 }
766 
emitWinCFIFuncletOrFuncEnd(SMLoc Loc)767 void MCStreamer::emitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
768   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
769   if (!CurFrame)
770     return;
771   if (CurFrame->ChainedParent)
772     getContext().reportError(Loc, "Not all chained regions terminated!");
773 
774   MCSymbol *Label = emitCFILabel();
775   CurFrame->FuncletOrFuncEnd = Label;
776 }
777 
emitWinCFIStartChained(SMLoc Loc)778 void MCStreamer::emitWinCFIStartChained(SMLoc Loc) {
779   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
780   if (!CurFrame)
781     return;
782 
783   MCSymbol *StartProc = emitCFILabel();
784 
785   WinFrameInfos.emplace_back(std::make_unique<WinEH::FrameInfo>(
786       CurFrame->Function, StartProc, CurFrame));
787   CurrentWinFrameInfo = WinFrameInfos.back().get();
788   CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
789 }
790 
emitWinCFIEndChained(SMLoc Loc)791 void MCStreamer::emitWinCFIEndChained(SMLoc Loc) {
792   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
793   if (!CurFrame)
794     return;
795   if (!CurFrame->ChainedParent)
796     return getContext().reportError(
797         Loc, "End of a chained region outside a chained region!");
798 
799   MCSymbol *Label = emitCFILabel();
800 
801   CurFrame->End = Label;
802   CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
803 }
804 
emitWinEHHandler(const MCSymbol * Sym,bool Unwind,bool Except,SMLoc Loc)805 void MCStreamer::emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
806                                   SMLoc Loc) {
807   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
808   if (!CurFrame)
809     return;
810   if (CurFrame->ChainedParent)
811     return getContext().reportError(
812         Loc, "Chained unwind areas can't have handlers!");
813   CurFrame->ExceptionHandler = Sym;
814   if (!Except && !Unwind)
815     getContext().reportError(Loc, "Don't know what kind of handler this is!");
816   if (Unwind)
817     CurFrame->HandlesUnwind = true;
818   if (Except)
819     CurFrame->HandlesExceptions = true;
820 }
821 
emitWinEHHandlerData(SMLoc Loc)822 void MCStreamer::emitWinEHHandlerData(SMLoc Loc) {
823   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
824   if (!CurFrame)
825     return;
826   if (CurFrame->ChainedParent)
827     getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
828 }
829 
emitCGProfileEntry(const MCSymbolRefExpr * From,const MCSymbolRefExpr * To,uint64_t Count)830 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
831                                     const MCSymbolRefExpr *To, uint64_t Count) {
832 }
833 
getWinCFISection(MCContext & Context,unsigned * NextWinCFIID,MCSection * MainCFISec,const MCSection * TextSec)834 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
835                                    MCSection *MainCFISec,
836                                    const MCSection *TextSec) {
837   // If this is the main .text section, use the main unwind info section.
838   if (TextSec == Context.getObjectFileInfo()->getTextSection())
839     return MainCFISec;
840 
841   const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
842   auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
843   unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
844 
845   // If this section is COMDAT, this unwind section should be COMDAT associative
846   // with its group.
847   const MCSymbol *KeySym = nullptr;
848   if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
849     KeySym = TextSecCOFF->getCOMDATSymbol();
850 
851     // In a GNU environment, we can't use associative comdats. Instead, do what
852     // GCC does, which is to make plain comdat selectany section named like
853     // ".[px]data$_Z3foov".
854     if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
855       std::string SectionName = (MainCFISecCOFF->getName() + "$" +
856                                  TextSecCOFF->getName().split('$').second)
857                                     .str();
858       return Context.getCOFFSection(SectionName,
859                                     MainCFISecCOFF->getCharacteristics() |
860                                         COFF::IMAGE_SCN_LNK_COMDAT,
861                                     "", COFF::IMAGE_COMDAT_SELECT_ANY);
862     }
863   }
864 
865   return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
866 }
867 
getAssociatedPDataSection(const MCSection * TextSec)868 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
869   return getWinCFISection(getContext(), &NextWinCFIID,
870                           getContext().getObjectFileInfo()->getPDataSection(),
871                           TextSec);
872 }
873 
getAssociatedXDataSection(const MCSection * TextSec)874 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
875   return getWinCFISection(getContext(), &NextWinCFIID,
876                           getContext().getObjectFileInfo()->getXDataSection(),
877                           TextSec);
878 }
879 
emitSyntaxDirective()880 void MCStreamer::emitSyntaxDirective() {}
881 
encodeSEHRegNum(MCContext & Ctx,MCRegister Reg)882 static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
883   return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
884 }
885 
emitWinCFIPushReg(MCRegister Register,SMLoc Loc)886 void MCStreamer::emitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
887   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
888   if (!CurFrame)
889     return;
890 
891   MCSymbol *Label = emitCFILabel();
892 
893   WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(
894       Label, encodeSEHRegNum(Context, Register));
895   CurFrame->Instructions.push_back(Inst);
896 }
897 
emitWinCFISetFrame(MCRegister Register,unsigned Offset,SMLoc Loc)898 void MCStreamer::emitWinCFISetFrame(MCRegister Register, unsigned Offset,
899                                     SMLoc Loc) {
900   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
901   if (!CurFrame)
902     return;
903   if (CurFrame->LastFrameInst >= 0)
904     return getContext().reportError(
905         Loc, "frame register and offset can be set at most once");
906   if (Offset & 0x0F)
907     return getContext().reportError(Loc, "offset is not a multiple of 16");
908   if (Offset > 240)
909     return getContext().reportError(
910         Loc, "frame offset must be less than or equal to 240");
911 
912   MCSymbol *Label = emitCFILabel();
913 
914   WinEH::Instruction Inst = Win64EH::Instruction::SetFPReg(
915       Label, encodeSEHRegNum(getContext(), Register), Offset);
916   CurFrame->LastFrameInst = CurFrame->Instructions.size();
917   CurFrame->Instructions.push_back(Inst);
918 }
919 
emitWinCFIAllocStack(unsigned Size,SMLoc Loc)920 void MCStreamer::emitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
921   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
922   if (!CurFrame)
923     return;
924   if (Size == 0)
925     return getContext().reportError(Loc,
926                                     "stack allocation size must be non-zero");
927   if (Size & 7)
928     return getContext().reportError(
929         Loc, "stack allocation size is not a multiple of 8");
930 
931   MCSymbol *Label = emitCFILabel();
932 
933   WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
934   CurFrame->Instructions.push_back(Inst);
935 }
936 
emitWinCFISaveReg(MCRegister Register,unsigned Offset,SMLoc Loc)937 void MCStreamer::emitWinCFISaveReg(MCRegister Register, unsigned Offset,
938                                    SMLoc Loc) {
939   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
940   if (!CurFrame)
941     return;
942 
943   if (Offset & 7)
944     return getContext().reportError(
945         Loc, "register save offset is not 8 byte aligned");
946 
947   MCSymbol *Label = emitCFILabel();
948 
949   WinEH::Instruction Inst = Win64EH::Instruction::SaveNonVol(
950       Label, encodeSEHRegNum(Context, Register), Offset);
951   CurFrame->Instructions.push_back(Inst);
952 }
953 
emitWinCFISaveXMM(MCRegister Register,unsigned Offset,SMLoc Loc)954 void MCStreamer::emitWinCFISaveXMM(MCRegister Register, unsigned Offset,
955                                    SMLoc Loc) {
956   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
957   if (!CurFrame)
958     return;
959   if (Offset & 0x0F)
960     return getContext().reportError(Loc, "offset is not a multiple of 16");
961 
962   MCSymbol *Label = emitCFILabel();
963 
964   WinEH::Instruction Inst = Win64EH::Instruction::SaveXMM(
965       Label, encodeSEHRegNum(Context, Register), Offset);
966   CurFrame->Instructions.push_back(Inst);
967 }
968 
emitWinCFIPushFrame(bool Code,SMLoc Loc)969 void MCStreamer::emitWinCFIPushFrame(bool Code, SMLoc Loc) {
970   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
971   if (!CurFrame)
972     return;
973   if (!CurFrame->Instructions.empty())
974     return getContext().reportError(
975         Loc, "If present, PushMachFrame must be the first UOP");
976 
977   MCSymbol *Label = emitCFILabel();
978 
979   WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
980   CurFrame->Instructions.push_back(Inst);
981 }
982 
emitWinCFIEndProlog(SMLoc Loc)983 void MCStreamer::emitWinCFIEndProlog(SMLoc Loc) {
984   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
985   if (!CurFrame)
986     return;
987 
988   MCSymbol *Label = emitCFILabel();
989 
990   CurFrame->PrologEnd = Label;
991 }
992 
emitWinCFIBeginEpilogue(SMLoc Loc)993 void MCStreamer::emitWinCFIBeginEpilogue(SMLoc Loc) {
994   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
995   if (!CurFrame)
996     return;
997 
998   if (!CurFrame->PrologEnd)
999     return getContext().reportError(
1000         Loc, "starting epilogue (.seh_startepilogue) before prologue has ended "
1001              "(.seh_endprologue) in " +
1002                  CurFrame->Function->getName());
1003 
1004   MCSymbol *Label = emitCFILabel();
1005   CurrentWinEpilog =
1006       &CurFrame->EpilogMap.insert_or_assign(Label, WinEH::FrameInfo::Epilog())
1007            .first->second;
1008   CurrentWinEpilog->Start = Label;
1009   CurrentWinEpilog->Loc = Loc;
1010 }
1011 
emitWinCFIEndEpilogue(SMLoc Loc)1012 void MCStreamer::emitWinCFIEndEpilogue(SMLoc Loc) {
1013   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
1014   if (!CurFrame)
1015     return;
1016 
1017   if (!CurrentWinEpilog)
1018     return getContext().reportError(Loc, "Stray .seh_endepilogue in " +
1019                                              CurFrame->Function->getName());
1020 
1021   if ((CurFrame->Version >= 2) && !CurrentWinEpilog->UnwindV2Start)
1022     return getContext().reportError(Loc, "Missing .seh_unwindv2start in " +
1023                                              CurFrame->Function->getName());
1024 
1025   CurrentWinEpilog->End = emitCFILabel();
1026   CurrentWinEpilog = nullptr;
1027 }
1028 
emitWinCFIUnwindV2Start(SMLoc Loc)1029 void MCStreamer::emitWinCFIUnwindV2Start(SMLoc Loc) {
1030   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
1031   if (!CurFrame)
1032     return;
1033 
1034   if (!CurrentWinEpilog)
1035     return getContext().reportError(Loc, "Stray .seh_unwindv2start in " +
1036                                              CurFrame->Function->getName());
1037 
1038   if (CurrentWinEpilog->UnwindV2Start)
1039     return getContext().reportError(Loc, "Duplicate .seh_unwindv2start in " +
1040                                              CurFrame->Function->getName());
1041 
1042   MCSymbol *Label = emitCFILabel();
1043   CurrentWinEpilog->UnwindV2Start = Label;
1044 }
1045 
emitWinCFIUnwindVersion(uint8_t Version,SMLoc Loc)1046 void MCStreamer::emitWinCFIUnwindVersion(uint8_t Version, SMLoc Loc) {
1047   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
1048   if (!CurFrame)
1049     return;
1050 
1051   if (CurFrame->Version != WinEH::FrameInfo::DefaultVersion)
1052     return getContext().reportError(Loc, "Duplicate .seh_unwindversion in " +
1053                                              CurFrame->Function->getName());
1054 
1055   if (Version != 2)
1056     return getContext().reportError(
1057         Loc, "Unsupported version specified in .seh_unwindversion in " +
1058                  CurFrame->Function->getName());
1059 
1060   CurFrame->Version = Version;
1061 }
1062 
emitCOFFSafeSEH(MCSymbol const * Symbol)1063 void MCStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {}
1064 
emitCOFFSymbolIndex(MCSymbol const * Symbol)1065 void MCStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {}
1066 
emitCOFFSectionIndex(MCSymbol const * Symbol)1067 void MCStreamer::emitCOFFSectionIndex(MCSymbol const *Symbol) {}
1068 
emitCOFFSecRel32(MCSymbol const * Symbol,uint64_t Offset)1069 void MCStreamer::emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
1070 
emitCOFFImgRel32(MCSymbol const * Symbol,int64_t Offset)1071 void MCStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
1072 
emitCOFFSecNumber(MCSymbol const * Symbol)1073 void MCStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) {}
1074 
emitCOFFSecOffset(MCSymbol const * Symbol)1075 void MCStreamer::emitCOFFSecOffset(MCSymbol const *Symbol) {}
1076 
1077 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1078 /// the specified string in the output .s file.  This capability is
1079 /// indicated by the hasRawTextSupport() predicate.
emitRawTextImpl(StringRef String)1080 void MCStreamer::emitRawTextImpl(StringRef String) {
1081   // This is not llvm_unreachable for the sake of out of tree backend
1082   // developers who may not have assembly streamers and should serve as a
1083   // reminder to not accidentally call EmitRawText in the absence of such.
1084   report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
1085                      "it (target backend is likely missing an AsmStreamer "
1086                      "implementation)");
1087 }
1088 
emitRawText(const Twine & T)1089 void MCStreamer::emitRawText(const Twine &T) {
1090   SmallString<128> Str;
1091   emitRawTextImpl(T.toStringRef(Str));
1092 }
1093 
emitWindowsUnwindTables()1094 void MCStreamer::emitWindowsUnwindTables() {}
1095 
emitWindowsUnwindTables(WinEH::FrameInfo * Frame)1096 void MCStreamer::emitWindowsUnwindTables(WinEH::FrameInfo *Frame) {}
1097 
finish(SMLoc EndLoc)1098 void MCStreamer::finish(SMLoc EndLoc) {
1099   if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
1100       (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
1101     getContext().reportError(EndLoc, "Unfinished frame!");
1102     return;
1103   }
1104 
1105   MCTargetStreamer *TS = getTargetStreamer();
1106   if (TS)
1107     TS->finish();
1108 
1109   finishImpl();
1110 }
1111 
maybeEmitDwarf64Mark()1112 void MCStreamer::maybeEmitDwarf64Mark() {
1113   if (Context.getDwarfFormat() != dwarf::DWARF64)
1114     return;
1115   AddComment("DWARF64 Mark");
1116   emitInt32(dwarf::DW_LENGTH_DWARF64);
1117 }
1118 
emitDwarfUnitLength(uint64_t Length,const Twine & Comment)1119 void MCStreamer::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) {
1120   assert(Context.getDwarfFormat() == dwarf::DWARF64 ||
1121          Length <= dwarf::DW_LENGTH_lo_reserved);
1122   maybeEmitDwarf64Mark();
1123   AddComment(Comment);
1124   emitIntValue(Length, dwarf::getDwarfOffsetByteSize(Context.getDwarfFormat()));
1125 }
1126 
emitDwarfUnitLength(const Twine & Prefix,const Twine & Comment)1127 MCSymbol *MCStreamer::emitDwarfUnitLength(const Twine &Prefix,
1128                                           const Twine &Comment) {
1129   maybeEmitDwarf64Mark();
1130   AddComment(Comment);
1131   MCSymbol *Lo = Context.createTempSymbol(Prefix + "_start");
1132   MCSymbol *Hi = Context.createTempSymbol(Prefix + "_end");
1133 
1134   emitAbsoluteSymbolDiff(
1135       Hi, Lo, dwarf::getDwarfOffsetByteSize(Context.getDwarfFormat()));
1136   // emit the begin symbol after we generate the length field.
1137   emitLabel(Lo);
1138   // Return the Hi symbol to the caller.
1139   return Hi;
1140 }
1141 
emitDwarfLineStartLabel(MCSymbol * StartSym)1142 void MCStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
1143   // Set the value of the symbol, as we are at the start of the line table.
1144   emitLabel(StartSym);
1145 }
1146 
emitAssignment(MCSymbol * Symbol,const MCExpr * Value)1147 void MCStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
1148   visitUsedExpr(*Value);
1149   Symbol->setVariableValue(Value);
1150 
1151   MCTargetStreamer *TS = getTargetStreamer();
1152   if (TS)
1153     TS->emitAssignment(Symbol, Value);
1154 }
1155 
prettyPrintAsm(MCInstPrinter & InstPrinter,uint64_t Address,const MCInst & Inst,const MCSubtargetInfo & STI,raw_ostream & OS)1156 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
1157                                       uint64_t Address, const MCInst &Inst,
1158                                       const MCSubtargetInfo &STI,
1159                                       raw_ostream &OS) {
1160   InstPrinter.printInst(&Inst, Address, "", STI, OS);
1161 }
1162 
visitUsedSymbol(const MCSymbol & Sym)1163 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
1164 }
1165 
visitUsedExpr(const MCExpr & Expr)1166 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
1167   switch (Expr.getKind()) {
1168   case MCExpr::Target:
1169     cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
1170     break;
1171 
1172   case MCExpr::Constant:
1173     break;
1174 
1175   case MCExpr::Binary: {
1176     const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
1177     visitUsedExpr(*BE.getLHS());
1178     visitUsedExpr(*BE.getRHS());
1179     break;
1180   }
1181 
1182   case MCExpr::SymbolRef:
1183     visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
1184     break;
1185 
1186   case MCExpr::Unary:
1187     visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
1188     break;
1189 
1190   case MCExpr::Specifier:
1191     visitUsedExpr(*cast<MCSpecifierExpr>(Expr).getSubExpr());
1192     break;
1193   }
1194 }
1195 
emitInstruction(const MCInst & Inst,const MCSubtargetInfo &)1196 void MCStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
1197   // Scan for values.
1198   for (unsigned i = Inst.getNumOperands(); i--;)
1199     if (Inst.getOperand(i).isExpr())
1200       visitUsedExpr(*Inst.getOperand(i).getExpr());
1201 }
1202 
emitPseudoProbe(uint64_t Guid,uint64_t Index,uint64_t Type,uint64_t Attr,uint64_t Discriminator,const MCPseudoProbeInlineStack & InlineStack,MCSymbol * FnSym)1203 void MCStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
1204                                  uint64_t Attr, uint64_t Discriminator,
1205                                  const MCPseudoProbeInlineStack &InlineStack,
1206                                  MCSymbol *FnSym) {
1207   auto &Context = getContext();
1208 
1209   // Create a symbol at in the current section for use in the probe.
1210   MCSymbol *ProbeSym = Context.createTempSymbol();
1211 
1212   // Set the value of the symbol to use for the MCPseudoProbe.
1213   emitLabel(ProbeSym);
1214 
1215   // Create a (local) probe entry with the symbol.
1216   MCPseudoProbe Probe(ProbeSym, Guid, Index, Type, Attr, Discriminator);
1217 
1218   // Add the probe entry to this section's entries.
1219   Context.getMCPseudoProbeTable().getProbeSections().addPseudoProbe(
1220       FnSym, Probe, InlineStack);
1221 }
1222 
emitAbsoluteSymbolDiff(const MCSymbol * Hi,const MCSymbol * Lo,unsigned Size)1223 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
1224                                         unsigned Size) {
1225   // Get the Hi-Lo expression.
1226   const MCExpr *Diff =
1227       MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1228                               MCSymbolRefExpr::create(Lo, Context), Context);
1229 
1230   const MCAsmInfo *MAI = Context.getAsmInfo();
1231   if (!MAI->doesSetDirectiveSuppressReloc()) {
1232     emitValue(Diff, Size);
1233     return;
1234   }
1235 
1236   // Otherwise, emit with .set (aka assignment).
1237   MCSymbol *SetLabel = Context.createTempSymbol("set");
1238   emitAssignment(SetLabel, Diff);
1239   emitSymbolValue(SetLabel, Size);
1240 }
1241 
emitAbsoluteSymbolDiffAsULEB128(const MCSymbol * Hi,const MCSymbol * Lo)1242 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
1243                                                  const MCSymbol *Lo) {
1244   // Get the Hi-Lo expression.
1245   const MCExpr *Diff =
1246       MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1247                               MCSymbolRefExpr::create(Lo, Context), Context);
1248 
1249   emitULEB128Value(Diff);
1250 }
1251 
emitSubsectionsViaSymbols()1252 void MCStreamer::emitSubsectionsViaSymbols() {
1253   llvm_unreachable(
1254       "emitSubsectionsViaSymbols only supported on Mach-O targets");
1255 }
emitSymbolDesc(MCSymbol * Symbol,unsigned DescValue)1256 void MCStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
beginCOFFSymbolDef(const MCSymbol * Symbol)1257 void MCStreamer::beginCOFFSymbolDef(const MCSymbol *Symbol) {
1258   llvm_unreachable("this directive only supported on COFF targets");
1259 }
endCOFFSymbolDef()1260 void MCStreamer::endCOFFSymbolDef() {
1261   llvm_unreachable("this directive only supported on COFF targets");
1262 }
emitFileDirective(StringRef Filename)1263 void MCStreamer::emitFileDirective(StringRef Filename) {}
emitFileDirective(StringRef Filename,StringRef CompilerVersion,StringRef TimeStamp,StringRef Description)1264 void MCStreamer::emitFileDirective(StringRef Filename,
1265                                    StringRef CompilerVersion,
1266                                    StringRef TimeStamp, StringRef Description) {
1267 }
emitCOFFSymbolStorageClass(int StorageClass)1268 void MCStreamer::emitCOFFSymbolStorageClass(int StorageClass) {
1269   llvm_unreachable("this directive only supported on COFF targets");
1270 }
emitCOFFSymbolType(int Type)1271 void MCStreamer::emitCOFFSymbolType(int Type) {
1272   llvm_unreachable("this directive only supported on COFF targets");
1273 }
emitXCOFFLocalCommonSymbol(MCSymbol * LabelSym,uint64_t Size,MCSymbol * CsectSym,Align Alignment)1274 void MCStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
1275                                             MCSymbol *CsectSym,
1276                                             Align Alignment) {
1277   llvm_unreachable("this directive only supported on XCOFF targets");
1278 }
1279 
emitXCOFFSymbolLinkageWithVisibility(MCSymbol * Symbol,MCSymbolAttr Linkage,MCSymbolAttr Visibility)1280 void MCStreamer::emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
1281                                                       MCSymbolAttr Linkage,
1282                                                       MCSymbolAttr Visibility) {
1283   llvm_unreachable("emitXCOFFSymbolLinkageWithVisibility is only supported on "
1284                    "XCOFF targets");
1285 }
1286 
emitXCOFFRenameDirective(const MCSymbol * Name,StringRef Rename)1287 void MCStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
1288                                           StringRef Rename) {}
1289 
emitXCOFFRefDirective(const MCSymbol * Symbol)1290 void MCStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) {
1291   llvm_unreachable("emitXCOFFRefDirective is only supported on XCOFF targets");
1292 }
1293 
emitXCOFFExceptDirective(const MCSymbol * Symbol,const MCSymbol * Trap,unsigned Lang,unsigned Reason,unsigned FunctionSize,bool hasDebug)1294 void MCStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,
1295                                           const MCSymbol *Trap,
1296                                           unsigned Lang, unsigned Reason,
1297                                           unsigned FunctionSize,
1298                                           bool hasDebug) {
1299   report_fatal_error("emitXCOFFExceptDirective is only supported on "
1300                      "XCOFF targets");
1301 }
1302 
emitXCOFFCInfoSym(StringRef Name,StringRef Metadata)1303 void MCStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
1304   llvm_unreachable("emitXCOFFCInfoSym is only supported on"
1305                    "XCOFF targets");
1306 }
1307 
emitELFSize(MCSymbol * Symbol,const MCExpr * Value)1308 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
emitELFSymverDirective(const MCSymbol * OriginalSym,StringRef Name,bool KeepOriginalSym)1309 void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
1310                                         StringRef Name, bool KeepOriginalSym) {}
emitLocalCommonSymbol(MCSymbol * Symbol,uint64_t Size,Align ByteAlignment)1311 void MCStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1312                                        Align ByteAlignment) {}
emitZerofill(MCSection *,MCSymbol *,uint64_t,Align,SMLoc)1313 void MCStreamer::emitZerofill(MCSection *, MCSymbol *, uint64_t, Align, SMLoc) {
1314 }
emitTBSSSymbol(MCSection * Section,MCSymbol * Symbol,uint64_t Size,Align ByteAlignment)1315 void MCStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1316                                 uint64_t Size, Align ByteAlignment) {}
changeSection(MCSection * Section,uint32_t)1317 void MCStreamer::changeSection(MCSection *Section, uint32_t) {
1318   CurFrag = &Section->getDummyFragment();
1319 }
emitWeakReference(MCSymbol * Alias,const MCSymbol * Symbol)1320 void MCStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
emitBytes(StringRef Data)1321 void MCStreamer::emitBytes(StringRef Data) {}
emitBinaryData(StringRef Data)1322 void MCStreamer::emitBinaryData(StringRef Data) { emitBytes(Data); }
emitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)1323 void MCStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
1324   visitUsedExpr(*Value);
1325 }
emitULEB128Value(const MCExpr * Value)1326 void MCStreamer::emitULEB128Value(const MCExpr *Value) {}
emitSLEB128Value(const MCExpr * Value)1327 void MCStreamer::emitSLEB128Value(const MCExpr *Value) {}
emitFill(const MCExpr & NumBytes,uint64_t Value,SMLoc Loc)1328 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
emitFill(const MCExpr & NumValues,int64_t Size,int64_t Expr,SMLoc Loc)1329 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
1330                           SMLoc Loc) {}
emitValueToAlignment(Align,int64_t,uint8_t,unsigned)1331 void MCStreamer::emitValueToAlignment(Align, int64_t, uint8_t, unsigned) {}
emitCodeAlignment(Align Alignment,const MCSubtargetInfo * STI,unsigned MaxBytesToEmit)1332 void MCStreamer::emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
1333                                    unsigned MaxBytesToEmit) {}
emitValueToOffset(const MCExpr * Offset,unsigned char Value,SMLoc Loc)1334 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
1335                                    SMLoc Loc) {}
emitBundleAlignMode(Align Alignment)1336 void MCStreamer::emitBundleAlignMode(Align Alignment) {}
emitBundleLock(bool AlignToEnd)1337 void MCStreamer::emitBundleLock(bool AlignToEnd) {}
finishImpl()1338 void MCStreamer::finishImpl() {}
emitBundleUnlock()1339 void MCStreamer::emitBundleUnlock() {}
1340 
popSection()1341 bool MCStreamer::popSection() {
1342   if (SectionStack.size() <= 1)
1343     return false;
1344   auto I = SectionStack.end();
1345   --I;
1346   MCSectionSubPair OldSec = I->first;
1347   --I;
1348   MCSectionSubPair NewSec = I->first;
1349 
1350   if (NewSec.first && OldSec != NewSec)
1351     changeSection(NewSec.first, NewSec.second);
1352   SectionStack.pop_back();
1353   return true;
1354 }
1355 
switchSection(MCSection * Section,uint32_t Subsection)1356 void MCStreamer::switchSection(MCSection *Section, uint32_t Subsection) {
1357   assert(Section && "Cannot switch to a null section!");
1358   MCSectionSubPair curSection = SectionStack.back().first;
1359   SectionStack.back().second = curSection;
1360   if (MCSectionSubPair(Section, Subsection) != curSection) {
1361     changeSection(Section, Subsection);
1362     SectionStack.back().first = MCSectionSubPair(Section, Subsection);
1363     assert(!Section->hasEnded() && "Section already ended");
1364     MCSymbol *Sym = Section->getBeginSymbol();
1365     if (Sym && !Sym->isInSection())
1366       emitLabel(Sym);
1367   }
1368 }
1369 
switchSection(MCSection * Section,const MCExpr * SubsecExpr)1370 bool MCStreamer::switchSection(MCSection *Section, const MCExpr *SubsecExpr) {
1371   int64_t Subsec = 0;
1372   if (SubsecExpr) {
1373     if (!SubsecExpr->evaluateAsAbsolute(Subsec, getAssemblerPtr())) {
1374       getContext().reportError(SubsecExpr->getLoc(),
1375                                "cannot evaluate subsection number");
1376       return true;
1377     }
1378     if (!isUInt<31>(Subsec)) {
1379       getContext().reportError(SubsecExpr->getLoc(),
1380                                "subsection number " + Twine(Subsec) +
1381                                    " is not within [0,2147483647]");
1382       return true;
1383     }
1384   }
1385   switchSection(Section, Subsec);
1386   return false;
1387 }
1388 
switchSectionNoPrint(MCSection * Section)1389 void MCStreamer::switchSectionNoPrint(MCSection *Section) {
1390   SectionStack.back().second = SectionStack.back().first;
1391   SectionStack.back().first = MCSectionSubPair(Section, 0);
1392   changeSection(Section, 0);
1393   MCSymbol *Sym = Section->getBeginSymbol();
1394   if (Sym && !Sym->isInSection())
1395     emitLabel(Sym);
1396 }
1397 
endSection(MCSection * Section)1398 MCSymbol *MCStreamer::endSection(MCSection *Section) {
1399   // TODO: keep track of the last subsection so that this symbol appears in the
1400   // correct place.
1401   MCSymbol *Sym = Section->getEndSymbol(Context);
1402   if (Sym->isInSection())
1403     return Sym;
1404 
1405   switchSection(Section);
1406   emitLabel(Sym);
1407   return Sym;
1408 }
1409 
1410 static VersionTuple
targetVersionOrMinimumSupportedOSVersion(const Triple & Target,VersionTuple TargetVersion)1411 targetVersionOrMinimumSupportedOSVersion(const Triple &Target,
1412                                          VersionTuple TargetVersion) {
1413   VersionTuple Min = Target.getMinimumSupportedOSVersion();
1414   return !Min.empty() && Min > TargetVersion ? Min : TargetVersion;
1415 }
1416 
1417 static MCVersionMinType
getMachoVersionMinLoadCommandType(const Triple & Target)1418 getMachoVersionMinLoadCommandType(const Triple &Target) {
1419   assert(Target.isOSDarwin() && "expected a darwin OS");
1420   switch (Target.getOS()) {
1421   case Triple::MacOSX:
1422   case Triple::Darwin:
1423     return MCVM_OSXVersionMin;
1424   case Triple::IOS:
1425     assert(!Target.isMacCatalystEnvironment() &&
1426            "mac Catalyst should use LC_BUILD_VERSION");
1427     return MCVM_IOSVersionMin;
1428   case Triple::TvOS:
1429     return MCVM_TvOSVersionMin;
1430   case Triple::WatchOS:
1431     return MCVM_WatchOSVersionMin;
1432   default:
1433     break;
1434   }
1435   llvm_unreachable("unexpected OS type");
1436 }
1437 
getMachoBuildVersionSupportedOS(const Triple & Target)1438 static VersionTuple getMachoBuildVersionSupportedOS(const Triple &Target) {
1439   assert(Target.isOSDarwin() && "expected a darwin OS");
1440   switch (Target.getOS()) {
1441   case Triple::MacOSX:
1442   case Triple::Darwin:
1443     return VersionTuple(10, 14);
1444   case Triple::IOS:
1445     // Mac Catalyst always uses the build version load command.
1446     if (Target.isMacCatalystEnvironment())
1447       return VersionTuple();
1448     [[fallthrough]];
1449   case Triple::TvOS:
1450     return VersionTuple(12);
1451   case Triple::WatchOS:
1452     return VersionTuple(5);
1453   case Triple::DriverKit:
1454   case Triple::BridgeOS:
1455   case Triple::XROS:
1456     // DriverKit/BridgeOS/XROS always use the build version load command.
1457     return VersionTuple();
1458   default:
1459     break;
1460   }
1461   llvm_unreachable("unexpected OS type");
1462 }
1463 
1464 static MachO::PlatformType
getMachoBuildVersionPlatformType(const Triple & Target)1465 getMachoBuildVersionPlatformType(const Triple &Target) {
1466   assert(Target.isOSDarwin() && "expected a darwin OS");
1467   switch (Target.getOS()) {
1468   case Triple::MacOSX:
1469   case Triple::Darwin:
1470     return MachO::PLATFORM_MACOS;
1471   case Triple::IOS:
1472     if (Target.isMacCatalystEnvironment())
1473       return MachO::PLATFORM_MACCATALYST;
1474     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
1475                                            : MachO::PLATFORM_IOS;
1476   case Triple::TvOS:
1477     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
1478                                            : MachO::PLATFORM_TVOS;
1479   case Triple::WatchOS:
1480     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
1481                                            : MachO::PLATFORM_WATCHOS;
1482   case Triple::DriverKit:
1483     return MachO::PLATFORM_DRIVERKIT;
1484   case Triple::XROS:
1485     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_XROS_SIMULATOR
1486                                            : MachO::PLATFORM_XROS;
1487   case Triple::BridgeOS:
1488     return MachO::PLATFORM_BRIDGEOS;
1489   default:
1490     break;
1491   }
1492   llvm_unreachable("unexpected OS type");
1493 }
1494 
emitVersionForTarget(const Triple & Target,const VersionTuple & SDKVersion,const Triple * DarwinTargetVariantTriple,const VersionTuple & DarwinTargetVariantSDKVersion)1495 void MCStreamer::emitVersionForTarget(
1496     const Triple &Target, const VersionTuple &SDKVersion,
1497     const Triple *DarwinTargetVariantTriple,
1498     const VersionTuple &DarwinTargetVariantSDKVersion) {
1499   if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
1500     return;
1501   // Do we even know the version?
1502   if (Target.getOSMajorVersion() == 0)
1503     return;
1504 
1505   VersionTuple Version;
1506   switch (Target.getOS()) {
1507   case Triple::MacOSX:
1508   case Triple::Darwin:
1509     Target.getMacOSXVersion(Version);
1510     break;
1511   case Triple::IOS:
1512   case Triple::TvOS:
1513     Version = Target.getiOSVersion();
1514     break;
1515   case Triple::WatchOS:
1516     Version = Target.getWatchOSVersion();
1517     break;
1518   case Triple::DriverKit:
1519     Version = Target.getDriverKitVersion();
1520     break;
1521   case Triple::XROS:
1522   case Triple::BridgeOS:
1523     Version = Target.getOSVersion();
1524     break;
1525   default:
1526     llvm_unreachable("unexpected OS type");
1527   }
1528   assert(Version.getMajor() != 0 && "A non-zero major version is expected");
1529   auto LinkedTargetVersion =
1530       targetVersionOrMinimumSupportedOSVersion(Target, Version);
1531   auto BuildVersionOSVersion = getMachoBuildVersionSupportedOS(Target);
1532   bool ShouldEmitBuildVersion = false;
1533   if (BuildVersionOSVersion.empty() ||
1534       LinkedTargetVersion >= BuildVersionOSVersion) {
1535     if (Target.isMacCatalystEnvironment() && DarwinTargetVariantTriple &&
1536         DarwinTargetVariantTriple->isMacOSX()) {
1537       emitVersionForTarget(*DarwinTargetVariantTriple,
1538                            DarwinTargetVariantSDKVersion,
1539                            /*DarwinTargetVariantTriple=*/nullptr,
1540                            /*DarwinTargetVariantSDKVersion=*/VersionTuple());
1541       emitDarwinTargetVariantBuildVersion(
1542           getMachoBuildVersionPlatformType(Target),
1543           LinkedTargetVersion.getMajor(),
1544           LinkedTargetVersion.getMinor().value_or(0),
1545           LinkedTargetVersion.getSubminor().value_or(0), SDKVersion);
1546       return;
1547     }
1548     emitBuildVersion(getMachoBuildVersionPlatformType(Target),
1549                      LinkedTargetVersion.getMajor(),
1550                      LinkedTargetVersion.getMinor().value_or(0),
1551                      LinkedTargetVersion.getSubminor().value_or(0), SDKVersion);
1552     ShouldEmitBuildVersion = true;
1553   }
1554 
1555   if (const Triple *TVT = DarwinTargetVariantTriple) {
1556     if (Target.isMacOSX() && TVT->isMacCatalystEnvironment()) {
1557       auto TVLinkedTargetVersion =
1558           targetVersionOrMinimumSupportedOSVersion(*TVT, TVT->getiOSVersion());
1559       emitDarwinTargetVariantBuildVersion(
1560           getMachoBuildVersionPlatformType(*TVT),
1561           TVLinkedTargetVersion.getMajor(),
1562           TVLinkedTargetVersion.getMinor().value_or(0),
1563           TVLinkedTargetVersion.getSubminor().value_or(0),
1564           DarwinTargetVariantSDKVersion);
1565     }
1566   }
1567 
1568   if (ShouldEmitBuildVersion)
1569     return;
1570 
1571   emitVersionMin(getMachoVersionMinLoadCommandType(Target),
1572                  LinkedTargetVersion.getMajor(),
1573                  LinkedTargetVersion.getMinor().value_or(0),
1574                  LinkedTargetVersion.getSubminor().value_or(0), SDKVersion);
1575 }
1576