xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCStreamer.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
100b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
110b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
120b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
130b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h"
1481ad6265SDimitry Andric #include "llvm/BinaryFormat/MachO.h"
158bcb0991SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCCodeView.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCInstPrinter.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h"
25e8d8bef9SDimitry Andric #include "llvm/MC/MCPseudoProbe.h"
268bcb0991SDimitry Andric #include "llvm/MC/MCRegister.h"
278bcb0991SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
280b57cec5SDimitry Andric #include "llvm/MC/MCSection.h"
290b57cec5SDimitry Andric #include "llvm/MC/MCSectionCOFF.h"
300b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
310b57cec5SDimitry Andric #include "llvm/MC/MCWin64EH.h"
320b57cec5SDimitry Andric #include "llvm/MC/MCWinEH.h"
330b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
340b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
350b57cec5SDimitry Andric #include "llvm/Support/LEB128.h"
360b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
370b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
380b57cec5SDimitry Andric #include <cassert>
390b57cec5SDimitry Andric #include <cstdint>
400b57cec5SDimitry Andric #include <cstdlib>
41*bdd1243dSDimitry Andric #include <optional>
420b57cec5SDimitry Andric #include <utility>
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric using namespace llvm;
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
470b57cec5SDimitry Andric   S.setTargetStreamer(this);
480b57cec5SDimitry Andric }
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric // Pin the vtables to this file.
510b57cec5SDimitry Andric MCTargetStreamer::~MCTargetStreamer() = default;
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric void MCTargetStreamer::finish() {}
560b57cec5SDimitry Andric 
57349cc55cSDimitry Andric void MCTargetStreamer::emitConstantPools() {}
58349cc55cSDimitry Andric 
590b57cec5SDimitry Andric void MCTargetStreamer::changeSection(const MCSection *CurSection,
600b57cec5SDimitry Andric                                      MCSection *Section,
610b57cec5SDimitry Andric                                      const MCExpr *Subsection,
620b57cec5SDimitry Andric                                      raw_ostream &OS) {
6381ad6265SDimitry Andric   Section->printSwitchToSection(*Streamer.getContext().getAsmInfo(),
64fe6060f1SDimitry Andric                                 Streamer.getContext().getTargetTriple(), OS,
650b57cec5SDimitry Andric                                 Subsection);
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
695ffd83dbSDimitry Andric   Streamer.emitRawText(Directive);
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric void MCTargetStreamer::emitValue(const MCExpr *Value) {
730b57cec5SDimitry Andric   SmallString<128> Str;
740b57cec5SDimitry Andric   raw_svector_ostream OS(Str);
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   Value->print(OS, Streamer.getContext().getAsmInfo());
775ffd83dbSDimitry Andric   Streamer.emitRawText(OS.str());
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric void MCTargetStreamer::emitRawBytes(StringRef Data) {
810b57cec5SDimitry Andric   const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
820b57cec5SDimitry Andric   const char *Directive = MAI->getData8bitsDirective();
830b57cec5SDimitry Andric   for (const unsigned char C : Data.bytes()) {
840b57cec5SDimitry Andric     SmallString<128> Str;
850b57cec5SDimitry Andric     raw_svector_ostream OS(Str);
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric     OS << Directive << (unsigned)C;
885ffd83dbSDimitry Andric     Streamer.emitRawText(OS.str());
890b57cec5SDimitry Andric   }
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric MCStreamer::MCStreamer(MCContext &Ctx)
950b57cec5SDimitry Andric     : Context(Ctx), CurrentWinFrameInfo(nullptr),
96e8d8bef9SDimitry Andric       CurrentProcWinFrameInfoStartIndex(0), UseAssemblerInfoForParsing(false) {
970b57cec5SDimitry Andric   SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric 
10081ad6265SDimitry Andric MCStreamer::~MCStreamer() = default;
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric void MCStreamer::reset() {
1030b57cec5SDimitry Andric   DwarfFrameInfos.clear();
1040b57cec5SDimitry Andric   CurrentWinFrameInfo = nullptr;
1050b57cec5SDimitry Andric   WinFrameInfos.clear();
1060b57cec5SDimitry Andric   SymbolOrdering.clear();
1070b57cec5SDimitry Andric   SectionStack.clear();
1080b57cec5SDimitry Andric   SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
1090b57cec5SDimitry Andric }
1100b57cec5SDimitry Andric 
11181ad6265SDimitry Andric raw_ostream &MCStreamer::getCommentOS() {
1120b57cec5SDimitry Andric   // By default, discard comments.
1130b57cec5SDimitry Andric   return nulls();
1140b57cec5SDimitry Andric }
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos.size(); }
1170b57cec5SDimitry Andric ArrayRef<MCDwarfFrameInfo> MCStreamer::getDwarfFrameInfos() const {
1180b57cec5SDimitry Andric   return DwarfFrameInfos;
1190b57cec5SDimitry Andric }
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric void MCStreamer::addExplicitComment(const Twine &T) {}
1240b57cec5SDimitry Andric void MCStreamer::emitExplicitComments() {}
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
1270b57cec5SDimitry Andric   for (auto &FI : DwarfFrameInfos)
1280b57cec5SDimitry Andric     FI.CompactUnwindEncoding =
1290b57cec5SDimitry Andric         (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric /// EmitIntValue - Special case of EmitValue that avoids the client having to
1330b57cec5SDimitry Andric /// pass in a MCExpr for constant integers.
1345ffd83dbSDimitry Andric void MCStreamer::emitIntValue(uint64_t Value, unsigned Size) {
1350b57cec5SDimitry Andric   assert(1 <= Size && Size <= 8 && "Invalid size");
1360b57cec5SDimitry Andric   assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
1370b57cec5SDimitry Andric          "Invalid size");
1385ffd83dbSDimitry Andric   const bool IsLittleEndian = Context.getAsmInfo()->isLittleEndian();
1395ffd83dbSDimitry Andric   uint64_t Swapped = support::endian::byte_swap(
1405ffd83dbSDimitry Andric       Value, IsLittleEndian ? support::little : support::big);
1415ffd83dbSDimitry Andric   unsigned Index = IsLittleEndian ? 0 : 8 - Size;
1425ffd83dbSDimitry Andric   emitBytes(StringRef(reinterpret_cast<char *>(&Swapped) + Index, Size));
1430b57cec5SDimitry Andric }
144e8d8bef9SDimitry Andric void MCStreamer::emitIntValue(APInt Value) {
145e8d8bef9SDimitry Andric   if (Value.getNumWords() == 1) {
146e8d8bef9SDimitry Andric     emitIntValue(Value.getLimitedValue(), Value.getBitWidth() / 8);
147e8d8bef9SDimitry Andric     return;
148e8d8bef9SDimitry Andric   }
149e8d8bef9SDimitry Andric 
150e8d8bef9SDimitry Andric   const bool IsLittleEndianTarget = Context.getAsmInfo()->isLittleEndian();
151e8d8bef9SDimitry Andric   const bool ShouldSwap = sys::IsLittleEndianHost != IsLittleEndianTarget;
152e8d8bef9SDimitry Andric   const APInt Swapped = ShouldSwap ? Value.byteSwap() : Value;
153e8d8bef9SDimitry Andric   const unsigned Size = Value.getBitWidth() / 8;
154e8d8bef9SDimitry Andric   SmallString<10> Tmp;
155e8d8bef9SDimitry Andric   Tmp.resize(Size);
156e8d8bef9SDimitry Andric   StoreIntToMemory(Swapped, reinterpret_cast<uint8_t *>(Tmp.data()), Size);
157e8d8bef9SDimitry Andric   emitBytes(Tmp.str());
158e8d8bef9SDimitry Andric }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
1610b57cec5SDimitry Andric /// client having to pass in a MCExpr for constant integers.
162*bdd1243dSDimitry Andric unsigned MCStreamer::emitULEB128IntValue(uint64_t Value, unsigned PadTo) {
1630b57cec5SDimitry Andric   SmallString<128> Tmp;
1640b57cec5SDimitry Andric   raw_svector_ostream OSE(Tmp);
1650b57cec5SDimitry Andric   encodeULEB128(Value, OSE, PadTo);
1665ffd83dbSDimitry Andric   emitBytes(OSE.str());
167*bdd1243dSDimitry Andric   return Tmp.size();
1680b57cec5SDimitry Andric }
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
1710b57cec5SDimitry Andric /// client having to pass in a MCExpr for constant integers.
172*bdd1243dSDimitry Andric unsigned MCStreamer::emitSLEB128IntValue(int64_t Value) {
1730b57cec5SDimitry Andric   SmallString<128> Tmp;
1740b57cec5SDimitry Andric   raw_svector_ostream OSE(Tmp);
1750b57cec5SDimitry Andric   encodeSLEB128(Value, OSE);
1765ffd83dbSDimitry Andric   emitBytes(OSE.str());
177*bdd1243dSDimitry Andric   return Tmp.size();
1780b57cec5SDimitry Andric }
1790b57cec5SDimitry Andric 
1805ffd83dbSDimitry Andric void MCStreamer::emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
1815ffd83dbSDimitry Andric   emitValueImpl(Value, Size, Loc);
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric 
1845ffd83dbSDimitry Andric void MCStreamer::emitSymbolValue(const MCSymbol *Sym, unsigned Size,
1850b57cec5SDimitry Andric                                  bool IsSectionRelative) {
1860b57cec5SDimitry Andric   assert((!IsSectionRelative || Size == 4) &&
1870b57cec5SDimitry Andric          "SectionRelative value requires 4-bytes");
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric   if (!IsSectionRelative)
1905ffd83dbSDimitry Andric     emitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
1910b57cec5SDimitry Andric   else
19281ad6265SDimitry Andric     emitCOFFSecRel32(Sym, /*Offset=*/0);
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric 
1955ffd83dbSDimitry Andric void MCStreamer::emitDTPRel64Value(const MCExpr *Value) {
1960b57cec5SDimitry Andric   report_fatal_error("unsupported directive in streamer");
1970b57cec5SDimitry Andric }
1980b57cec5SDimitry Andric 
1995ffd83dbSDimitry Andric void MCStreamer::emitDTPRel32Value(const MCExpr *Value) {
2000b57cec5SDimitry Andric   report_fatal_error("unsupported directive in streamer");
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric 
2035ffd83dbSDimitry Andric void MCStreamer::emitTPRel64Value(const MCExpr *Value) {
2040b57cec5SDimitry Andric   report_fatal_error("unsupported directive in streamer");
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric 
2075ffd83dbSDimitry Andric void MCStreamer::emitTPRel32Value(const MCExpr *Value) {
2080b57cec5SDimitry Andric   report_fatal_error("unsupported directive in streamer");
2090b57cec5SDimitry Andric }
2100b57cec5SDimitry Andric 
2115ffd83dbSDimitry Andric void MCStreamer::emitGPRel64Value(const MCExpr *Value) {
2120b57cec5SDimitry Andric   report_fatal_error("unsupported directive in streamer");
2130b57cec5SDimitry Andric }
2140b57cec5SDimitry Andric 
2155ffd83dbSDimitry Andric void MCStreamer::emitGPRel32Value(const MCExpr *Value) {
2160b57cec5SDimitry Andric   report_fatal_error("unsupported directive in streamer");
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric /// Emit NumBytes bytes worth of the value specified by FillValue.
2200b57cec5SDimitry Andric /// This implements directives such as '.space'.
2210b57cec5SDimitry Andric void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
2220b57cec5SDimitry Andric   emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
2230b57cec5SDimitry Andric }
2240b57cec5SDimitry Andric 
225e8d8bef9SDimitry Andric void llvm::MCStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLen,
226349cc55cSDimitry Andric                                 llvm::SMLoc, const MCSubtargetInfo& STI) {}
227e8d8bef9SDimitry Andric 
2280b57cec5SDimitry Andric /// The implementation in this class just redirects to emitFill.
2295ffd83dbSDimitry Andric void MCStreamer::emitZeros(uint64_t NumBytes) { emitFill(NumBytes, 0); }
2300b57cec5SDimitry Andric 
231*bdd1243dSDimitry Andric Expected<unsigned> MCStreamer::tryEmitDwarfFileDirective(
232*bdd1243dSDimitry Andric     unsigned FileNo, StringRef Directory, StringRef Filename,
233*bdd1243dSDimitry Andric     std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
2340b57cec5SDimitry Andric     unsigned CUID) {
2350b57cec5SDimitry Andric   return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
2360b57cec5SDimitry Andric                                    Source, CUID);
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
2400b57cec5SDimitry Andric                                          StringRef Filename,
241*bdd1243dSDimitry Andric                                          std::optional<MD5::MD5Result> Checksum,
242*bdd1243dSDimitry Andric                                          std::optional<StringRef> Source,
2430b57cec5SDimitry Andric                                          unsigned CUID) {
2440b57cec5SDimitry Andric   getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
2450b57cec5SDimitry Andric                                       Source);
2460b57cec5SDimitry Andric }
2470b57cec5SDimitry Andric 
2485ffd83dbSDimitry Andric void MCStreamer::emitCFIBKeyFrame() {
2490b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
2500b57cec5SDimitry Andric   if (!CurFrame)
2510b57cec5SDimitry Andric     return;
2520b57cec5SDimitry Andric   CurFrame->IsBKeyFrame = true;
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
25581ad6265SDimitry Andric void MCStreamer::emitCFIMTETaggedFrame() {
25681ad6265SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
25781ad6265SDimitry Andric   if (!CurFrame)
25881ad6265SDimitry Andric     return;
25981ad6265SDimitry Andric   CurFrame->IsMTETaggedFrame = true;
26081ad6265SDimitry Andric }
26181ad6265SDimitry Andric 
2625ffd83dbSDimitry Andric void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
2630b57cec5SDimitry Andric                                        unsigned Column, unsigned Flags,
2645ffd83dbSDimitry Andric                                        unsigned Isa, unsigned Discriminator,
2650b57cec5SDimitry Andric                                        StringRef FileName) {
2660b57cec5SDimitry Andric   getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
2670b57cec5SDimitry Andric                                   Discriminator);
2680b57cec5SDimitry Andric }
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
2710b57cec5SDimitry Andric   MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
2720b57cec5SDimitry Andric   if (!Table.getLabel()) {
2730b57cec5SDimitry Andric     StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
2740b57cec5SDimitry Andric     Table.setLabel(
2750b57cec5SDimitry Andric         Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
2760b57cec5SDimitry Andric   }
2770b57cec5SDimitry Andric   return Table.getLabel();
2780b57cec5SDimitry Andric }
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
2810b57cec5SDimitry Andric   return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
2820b57cec5SDimitry Andric }
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
2850b57cec5SDimitry Andric   if (!hasUnfinishedDwarfFrameInfo()) {
286e8d8bef9SDimitry Andric     getContext().reportError(getStartTokLoc(),
287e8d8bef9SDimitry Andric                              "this directive must appear between "
288e8d8bef9SDimitry Andric                              ".cfi_startproc and .cfi_endproc directives");
2890b57cec5SDimitry Andric     return nullptr;
2900b57cec5SDimitry Andric   }
2910b57cec5SDimitry Andric   return &DwarfFrameInfos.back();
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric 
29481ad6265SDimitry Andric bool MCStreamer::emitCVFileDirective(unsigned FileNo, StringRef Filename,
2950b57cec5SDimitry Andric                                      ArrayRef<uint8_t> Checksum,
2960b57cec5SDimitry Andric                                      unsigned ChecksumKind) {
2970b57cec5SDimitry Andric   return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
2980b57cec5SDimitry Andric                                              ChecksumKind);
2990b57cec5SDimitry Andric }
3000b57cec5SDimitry Andric 
30181ad6265SDimitry Andric bool MCStreamer::emitCVFuncIdDirective(unsigned FunctionId) {
3020b57cec5SDimitry Andric   return getContext().getCVContext().recordFunctionId(FunctionId);
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric 
30581ad6265SDimitry Andric bool MCStreamer::emitCVInlineSiteIdDirective(unsigned FunctionId,
3060b57cec5SDimitry Andric                                              unsigned IAFunc, unsigned IAFile,
3070b57cec5SDimitry Andric                                              unsigned IALine, unsigned IACol,
3080b57cec5SDimitry Andric                                              SMLoc Loc) {
3090b57cec5SDimitry Andric   if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
3100b57cec5SDimitry Andric     getContext().reportError(Loc, "parent function id not introduced by "
3110b57cec5SDimitry Andric                                   ".cv_func_id or .cv_inline_site_id");
3120b57cec5SDimitry Andric     return true;
3130b57cec5SDimitry Andric   }
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric   return getContext().getCVContext().recordInlinedCallSiteId(
3160b57cec5SDimitry Andric       FunctionId, IAFunc, IAFile, IALine, IACol);
3170b57cec5SDimitry Andric }
3180b57cec5SDimitry Andric 
3195ffd83dbSDimitry Andric void MCStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
3200b57cec5SDimitry Andric                                     unsigned Line, unsigned Column,
3210b57cec5SDimitry Andric                                     bool PrologueEnd, bool IsStmt,
3220b57cec5SDimitry Andric                                     StringRef FileName, SMLoc Loc) {}
3230b57cec5SDimitry Andric 
3240b57cec5SDimitry Andric bool MCStreamer::checkCVLocSection(unsigned FuncId, unsigned FileNo,
3250b57cec5SDimitry Andric                                    SMLoc Loc) {
3260b57cec5SDimitry Andric   CodeViewContext &CVC = getContext().getCVContext();
3270b57cec5SDimitry Andric   MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId);
3280b57cec5SDimitry Andric   if (!FI) {
3290b57cec5SDimitry Andric     getContext().reportError(
3300b57cec5SDimitry Andric         Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
3310b57cec5SDimitry Andric     return false;
3320b57cec5SDimitry Andric   }
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric   // Track the section
3350b57cec5SDimitry Andric   if (FI->Section == nullptr)
3360b57cec5SDimitry Andric     FI->Section = getCurrentSectionOnly();
3370b57cec5SDimitry Andric   else if (FI->Section != getCurrentSectionOnly()) {
3380b57cec5SDimitry Andric     getContext().reportError(
3390b57cec5SDimitry Andric         Loc,
3400b57cec5SDimitry Andric         "all .cv_loc directives for a function must be in the same section");
3410b57cec5SDimitry Andric     return false;
3420b57cec5SDimitry Andric   }
3430b57cec5SDimitry Andric   return true;
3440b57cec5SDimitry Andric }
3450b57cec5SDimitry Andric 
3465ffd83dbSDimitry Andric void MCStreamer::emitCVLinetableDirective(unsigned FunctionId,
3470b57cec5SDimitry Andric                                           const MCSymbol *Begin,
3480b57cec5SDimitry Andric                                           const MCSymbol *End) {}
3490b57cec5SDimitry Andric 
3505ffd83dbSDimitry Andric void MCStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
3510b57cec5SDimitry Andric                                                 unsigned SourceFileId,
3520b57cec5SDimitry Andric                                                 unsigned SourceLineNum,
3530b57cec5SDimitry Andric                                                 const MCSymbol *FnStartSym,
3540b57cec5SDimitry Andric                                                 const MCSymbol *FnEndSym) {}
3550b57cec5SDimitry Andric 
3568bcb0991SDimitry Andric /// Only call this on endian-specific types like ulittle16_t and little32_t, or
3578bcb0991SDimitry Andric /// structs composed of them.
3588bcb0991SDimitry Andric template <typename T>
3598bcb0991SDimitry Andric static void copyBytesForDefRange(SmallString<20> &BytePrefix,
3608bcb0991SDimitry Andric                                  codeview::SymbolKind SymKind,
3618bcb0991SDimitry Andric                                  const T &DefRangeHeader) {
3628bcb0991SDimitry Andric   BytePrefix.resize(2 + sizeof(T));
3638bcb0991SDimitry Andric   codeview::ulittle16_t SymKindLE = codeview::ulittle16_t(SymKind);
3648bcb0991SDimitry Andric   memcpy(&BytePrefix[0], &SymKindLE, 2);
3658bcb0991SDimitry Andric   memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T));
3668bcb0991SDimitry Andric }
3678bcb0991SDimitry Andric 
3685ffd83dbSDimitry Andric void MCStreamer::emitCVDefRangeDirective(
3690b57cec5SDimitry Andric     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
3700b57cec5SDimitry Andric     StringRef FixedSizePortion) {}
3710b57cec5SDimitry Andric 
3725ffd83dbSDimitry Andric void MCStreamer::emitCVDefRangeDirective(
3738bcb0991SDimitry Andric     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
3748bcb0991SDimitry Andric     codeview::DefRangeRegisterRelHeader DRHdr) {
3758bcb0991SDimitry Andric   SmallString<20> BytePrefix;
3768bcb0991SDimitry Andric   copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER_REL, DRHdr);
3775ffd83dbSDimitry Andric   emitCVDefRangeDirective(Ranges, BytePrefix);
3788bcb0991SDimitry Andric }
3798bcb0991SDimitry Andric 
3805ffd83dbSDimitry Andric void MCStreamer::emitCVDefRangeDirective(
3818bcb0991SDimitry Andric     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
3828bcb0991SDimitry Andric     codeview::DefRangeSubfieldRegisterHeader DRHdr) {
3838bcb0991SDimitry Andric   SmallString<20> BytePrefix;
3848bcb0991SDimitry Andric   copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_SUBFIELD_REGISTER,
3858bcb0991SDimitry Andric                        DRHdr);
3865ffd83dbSDimitry Andric   emitCVDefRangeDirective(Ranges, BytePrefix);
3878bcb0991SDimitry Andric }
3888bcb0991SDimitry Andric 
3895ffd83dbSDimitry Andric void MCStreamer::emitCVDefRangeDirective(
3908bcb0991SDimitry Andric     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
3918bcb0991SDimitry Andric     codeview::DefRangeRegisterHeader DRHdr) {
3928bcb0991SDimitry Andric   SmallString<20> BytePrefix;
3938bcb0991SDimitry Andric   copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER, DRHdr);
3945ffd83dbSDimitry Andric   emitCVDefRangeDirective(Ranges, BytePrefix);
3958bcb0991SDimitry Andric }
3968bcb0991SDimitry Andric 
3975ffd83dbSDimitry Andric void MCStreamer::emitCVDefRangeDirective(
3988bcb0991SDimitry Andric     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
3998bcb0991SDimitry Andric     codeview::DefRangeFramePointerRelHeader DRHdr) {
4008bcb0991SDimitry Andric   SmallString<20> BytePrefix;
4018bcb0991SDimitry Andric   copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_FRAMEPOINTER_REL,
4028bcb0991SDimitry Andric                        DRHdr);
4035ffd83dbSDimitry Andric   emitCVDefRangeDirective(Ranges, BytePrefix);
4048bcb0991SDimitry Andric }
4058bcb0991SDimitry Andric 
4065ffd83dbSDimitry Andric void MCStreamer::emitEHSymAttributes(const MCSymbol *Symbol,
4070b57cec5SDimitry Andric                                      MCSymbol *EHSymbol) {
4080b57cec5SDimitry Andric }
4090b57cec5SDimitry Andric 
410349cc55cSDimitry Andric void MCStreamer::initSections(bool NoExecStack, const MCSubtargetInfo &STI) {
41181ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getTextSection());
4120b57cec5SDimitry Andric }
4130b57cec5SDimitry Andric 
41481ad6265SDimitry Andric void MCStreamer::assignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
4150b57cec5SDimitry Andric   assert(Fragment);
4160b57cec5SDimitry Andric   Symbol->setFragment(Fragment);
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   // As we emit symbols into a section, track the order so that they can
4190b57cec5SDimitry Andric   // be sorted upon later. Zero is reserved to mean 'unemitted'.
4200b57cec5SDimitry Andric   SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric 
4235ffd83dbSDimitry Andric void MCStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
4240b57cec5SDimitry Andric   Symbol->redefineIfPossible();
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric   if (!Symbol->isUndefined() || Symbol->isVariable())
427fe6060f1SDimitry Andric     return getContext().reportError(Loc, "symbol '" + Twine(Symbol->getName()) +
428fe6060f1SDimitry Andric                                              "' is already defined");
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric   assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
4310b57cec5SDimitry Andric   assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
4320b57cec5SDimitry Andric   assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
4330b57cec5SDimitry Andric   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric   MCTargetStreamer *TS = getTargetStreamer();
4380b57cec5SDimitry Andric   if (TS)
4390b57cec5SDimitry Andric     TS->emitLabel(Symbol);
4400b57cec5SDimitry Andric }
4410b57cec5SDimitry Andric 
4420eae32dcSDimitry Andric void MCStreamer::emitConditionalAssignment(MCSymbol *Symbol,
4430eae32dcSDimitry Andric                                            const MCExpr *Value) {}
4440eae32dcSDimitry Andric 
445fe6060f1SDimitry Andric void MCStreamer::emitCFISections(bool EH, bool Debug) {}
4460b57cec5SDimitry Andric 
4475ffd83dbSDimitry Andric void MCStreamer::emitCFIStartProc(bool IsSimple, SMLoc Loc) {
4480b57cec5SDimitry Andric   if (hasUnfinishedDwarfFrameInfo())
4490b57cec5SDimitry Andric     return getContext().reportError(
4500b57cec5SDimitry Andric         Loc, "starting new .cfi frame before finishing the previous one");
4510b57cec5SDimitry Andric 
4520b57cec5SDimitry Andric   MCDwarfFrameInfo Frame;
4530b57cec5SDimitry Andric   Frame.IsSimple = IsSimple;
4545ffd83dbSDimitry Andric   emitCFIStartProcImpl(Frame);
4550b57cec5SDimitry Andric 
4560b57cec5SDimitry Andric   const MCAsmInfo* MAI = Context.getAsmInfo();
4570b57cec5SDimitry Andric   if (MAI) {
4580b57cec5SDimitry Andric     for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
4590b57cec5SDimitry Andric       if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
460fe6060f1SDimitry Andric           Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister ||
461fe6060f1SDimitry Andric           Inst.getOperation() == MCCFIInstruction::OpLLVMDefAspaceCfa) {
4620b57cec5SDimitry Andric         Frame.CurrentCfaRegister = Inst.getRegister();
4630b57cec5SDimitry Andric       }
4640b57cec5SDimitry Andric     }
4650b57cec5SDimitry Andric   }
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric   DwarfFrameInfos.push_back(Frame);
4680b57cec5SDimitry Andric }
4690b57cec5SDimitry Andric 
4705ffd83dbSDimitry Andric void MCStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
4710b57cec5SDimitry Andric }
4720b57cec5SDimitry Andric 
4735ffd83dbSDimitry Andric void MCStreamer::emitCFIEndProc() {
4740b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
4750b57cec5SDimitry Andric   if (!CurFrame)
4760b57cec5SDimitry Andric     return;
4775ffd83dbSDimitry Andric   emitCFIEndProcImpl(*CurFrame);
4780b57cec5SDimitry Andric }
4790b57cec5SDimitry Andric 
4805ffd83dbSDimitry Andric void MCStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
4810b57cec5SDimitry Andric   // Put a dummy non-null value in Frame.End to mark that this frame has been
4820b57cec5SDimitry Andric   // closed.
4830b57cec5SDimitry Andric   Frame.End = (MCSymbol *)1;
4840b57cec5SDimitry Andric }
4850b57cec5SDimitry Andric 
4865ffd83dbSDimitry Andric MCSymbol *MCStreamer::emitCFILabel() {
4870b57cec5SDimitry Andric   // Return a dummy non-null value so that label fields appear filled in when
4880b57cec5SDimitry Andric   // generating textual assembly.
4890b57cec5SDimitry Andric   return (MCSymbol *)1;
4900b57cec5SDimitry Andric }
4910b57cec5SDimitry Andric 
4925ffd83dbSDimitry Andric void MCStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset) {
4935ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
4940b57cec5SDimitry Andric   MCCFIInstruction Instruction =
4955ffd83dbSDimitry Andric       MCCFIInstruction::cfiDefCfa(Label, Register, Offset);
4960b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
4970b57cec5SDimitry Andric   if (!CurFrame)
4980b57cec5SDimitry Andric     return;
4990b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5000b57cec5SDimitry Andric   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
5010b57cec5SDimitry Andric }
5020b57cec5SDimitry Andric 
5035ffd83dbSDimitry Andric void MCStreamer::emitCFIDefCfaOffset(int64_t Offset) {
5045ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
5050b57cec5SDimitry Andric   MCCFIInstruction Instruction =
5065ffd83dbSDimitry Andric       MCCFIInstruction::cfiDefCfaOffset(Label, Offset);
5070b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5080b57cec5SDimitry Andric   if (!CurFrame)
5090b57cec5SDimitry Andric     return;
5100b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5110b57cec5SDimitry Andric }
5120b57cec5SDimitry Andric 
5135ffd83dbSDimitry Andric void MCStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment) {
5145ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
5150b57cec5SDimitry Andric   MCCFIInstruction Instruction =
5160b57cec5SDimitry Andric     MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
5170b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5180b57cec5SDimitry Andric   if (!CurFrame)
5190b57cec5SDimitry Andric     return;
5200b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5210b57cec5SDimitry Andric }
5220b57cec5SDimitry Andric 
5235ffd83dbSDimitry Andric void MCStreamer::emitCFIDefCfaRegister(int64_t Register) {
5245ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
5250b57cec5SDimitry Andric   MCCFIInstruction Instruction =
5260b57cec5SDimitry Andric     MCCFIInstruction::createDefCfaRegister(Label, Register);
5270b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5280b57cec5SDimitry Andric   if (!CurFrame)
5290b57cec5SDimitry Andric     return;
5300b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5310b57cec5SDimitry Andric   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
5320b57cec5SDimitry Andric }
5330b57cec5SDimitry Andric 
534fe6060f1SDimitry Andric void MCStreamer::emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
535fe6060f1SDimitry Andric                                          int64_t AddressSpace) {
536fe6060f1SDimitry Andric   MCSymbol *Label = emitCFILabel();
537fe6060f1SDimitry Andric   MCCFIInstruction Instruction = MCCFIInstruction::createLLVMDefAspaceCfa(
538fe6060f1SDimitry Andric       Label, Register, Offset, AddressSpace);
539fe6060f1SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
540fe6060f1SDimitry Andric   if (!CurFrame)
541fe6060f1SDimitry Andric     return;
542fe6060f1SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
543fe6060f1SDimitry Andric   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
544fe6060f1SDimitry Andric }
545fe6060f1SDimitry Andric 
5465ffd83dbSDimitry Andric void MCStreamer::emitCFIOffset(int64_t Register, int64_t Offset) {
5475ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
5480b57cec5SDimitry Andric   MCCFIInstruction Instruction =
5490b57cec5SDimitry Andric     MCCFIInstruction::createOffset(Label, Register, Offset);
5500b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5510b57cec5SDimitry Andric   if (!CurFrame)
5520b57cec5SDimitry Andric     return;
5530b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5540b57cec5SDimitry Andric }
5550b57cec5SDimitry Andric 
5565ffd83dbSDimitry Andric void MCStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset) {
5575ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
5580b57cec5SDimitry Andric   MCCFIInstruction Instruction =
5590b57cec5SDimitry Andric     MCCFIInstruction::createRelOffset(Label, Register, Offset);
5600b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5610b57cec5SDimitry Andric   if (!CurFrame)
5620b57cec5SDimitry Andric     return;
5630b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5640b57cec5SDimitry Andric }
5650b57cec5SDimitry Andric 
5665ffd83dbSDimitry Andric void MCStreamer::emitCFIPersonality(const MCSymbol *Sym,
5670b57cec5SDimitry Andric                                     unsigned Encoding) {
5680b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5690b57cec5SDimitry Andric   if (!CurFrame)
5700b57cec5SDimitry Andric     return;
5710b57cec5SDimitry Andric   CurFrame->Personality = Sym;
5720b57cec5SDimitry Andric   CurFrame->PersonalityEncoding = Encoding;
5730b57cec5SDimitry Andric }
5740b57cec5SDimitry Andric 
5755ffd83dbSDimitry Andric void MCStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
5760b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5770b57cec5SDimitry Andric   if (!CurFrame)
5780b57cec5SDimitry Andric     return;
5790b57cec5SDimitry Andric   CurFrame->Lsda = Sym;
5800b57cec5SDimitry Andric   CurFrame->LsdaEncoding = Encoding;
5810b57cec5SDimitry Andric }
5820b57cec5SDimitry Andric 
5835ffd83dbSDimitry Andric void MCStreamer::emitCFIRememberState() {
5845ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
5850b57cec5SDimitry Andric   MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
5860b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5870b57cec5SDimitry Andric   if (!CurFrame)
5880b57cec5SDimitry Andric     return;
5890b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric 
5925ffd83dbSDimitry Andric void MCStreamer::emitCFIRestoreState() {
5930b57cec5SDimitry Andric   // FIXME: Error if there is no matching cfi_remember_state.
5945ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
5950b57cec5SDimitry Andric   MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
5960b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5970b57cec5SDimitry Andric   if (!CurFrame)
5980b57cec5SDimitry Andric     return;
5990b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6000b57cec5SDimitry Andric }
6010b57cec5SDimitry Andric 
6025ffd83dbSDimitry Andric void MCStreamer::emitCFISameValue(int64_t Register) {
6035ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6040b57cec5SDimitry Andric   MCCFIInstruction Instruction =
6050b57cec5SDimitry Andric     MCCFIInstruction::createSameValue(Label, Register);
6060b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6070b57cec5SDimitry Andric   if (!CurFrame)
6080b57cec5SDimitry Andric     return;
6090b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6100b57cec5SDimitry Andric }
6110b57cec5SDimitry Andric 
6125ffd83dbSDimitry Andric void MCStreamer::emitCFIRestore(int64_t Register) {
6135ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6140b57cec5SDimitry Andric   MCCFIInstruction Instruction =
6150b57cec5SDimitry Andric     MCCFIInstruction::createRestore(Label, Register);
6160b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6170b57cec5SDimitry Andric   if (!CurFrame)
6180b57cec5SDimitry Andric     return;
6190b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6200b57cec5SDimitry Andric }
6210b57cec5SDimitry Andric 
6225ffd83dbSDimitry Andric void MCStreamer::emitCFIEscape(StringRef Values) {
6235ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6240b57cec5SDimitry Andric   MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
6250b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6260b57cec5SDimitry Andric   if (!CurFrame)
6270b57cec5SDimitry Andric     return;
6280b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6290b57cec5SDimitry Andric }
6300b57cec5SDimitry Andric 
6315ffd83dbSDimitry Andric void MCStreamer::emitCFIGnuArgsSize(int64_t Size) {
6325ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6330b57cec5SDimitry Andric   MCCFIInstruction Instruction =
6340b57cec5SDimitry Andric     MCCFIInstruction::createGnuArgsSize(Label, Size);
6350b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6360b57cec5SDimitry Andric   if (!CurFrame)
6370b57cec5SDimitry Andric     return;
6380b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6390b57cec5SDimitry Andric }
6400b57cec5SDimitry Andric 
6415ffd83dbSDimitry Andric void MCStreamer::emitCFISignalFrame() {
6420b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6430b57cec5SDimitry Andric   if (!CurFrame)
6440b57cec5SDimitry Andric     return;
6450b57cec5SDimitry Andric   CurFrame->IsSignalFrame = true;
6460b57cec5SDimitry Andric }
6470b57cec5SDimitry Andric 
6485ffd83dbSDimitry Andric void MCStreamer::emitCFIUndefined(int64_t Register) {
6495ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6500b57cec5SDimitry Andric   MCCFIInstruction Instruction =
6510b57cec5SDimitry Andric     MCCFIInstruction::createUndefined(Label, Register);
6520b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6530b57cec5SDimitry Andric   if (!CurFrame)
6540b57cec5SDimitry Andric     return;
6550b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6560b57cec5SDimitry Andric }
6570b57cec5SDimitry Andric 
6585ffd83dbSDimitry Andric void MCStreamer::emitCFIRegister(int64_t Register1, int64_t Register2) {
6595ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6600b57cec5SDimitry Andric   MCCFIInstruction Instruction =
6610b57cec5SDimitry Andric     MCCFIInstruction::createRegister(Label, Register1, Register2);
6620b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6630b57cec5SDimitry Andric   if (!CurFrame)
6640b57cec5SDimitry Andric     return;
6650b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6660b57cec5SDimitry Andric }
6670b57cec5SDimitry Andric 
6685ffd83dbSDimitry Andric void MCStreamer::emitCFIWindowSave() {
6695ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6700b57cec5SDimitry Andric   MCCFIInstruction Instruction =
6710b57cec5SDimitry Andric     MCCFIInstruction::createWindowSave(Label);
6720b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6730b57cec5SDimitry Andric   if (!CurFrame)
6740b57cec5SDimitry Andric     return;
6750b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6760b57cec5SDimitry Andric }
6770b57cec5SDimitry Andric 
6785ffd83dbSDimitry Andric void MCStreamer::emitCFINegateRAState() {
6795ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6800b57cec5SDimitry Andric   MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label);
6810b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6820b57cec5SDimitry Andric   if (!CurFrame)
6830b57cec5SDimitry Andric     return;
6840b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6850b57cec5SDimitry Andric }
6860b57cec5SDimitry Andric 
6875ffd83dbSDimitry Andric void MCStreamer::emitCFIReturnColumn(int64_t Register) {
6880b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6890b57cec5SDimitry Andric   if (!CurFrame)
6900b57cec5SDimitry Andric     return;
6910b57cec5SDimitry Andric   CurFrame->RAReg = Register;
6920b57cec5SDimitry Andric }
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
6950b57cec5SDimitry Andric   const MCAsmInfo *MAI = Context.getAsmInfo();
6960b57cec5SDimitry Andric   if (!MAI->usesWindowsCFI()) {
6970b57cec5SDimitry Andric     getContext().reportError(
6980b57cec5SDimitry Andric         Loc, ".seh_* directives are not supported on this target");
6990b57cec5SDimitry Andric     return nullptr;
7000b57cec5SDimitry Andric   }
7010b57cec5SDimitry Andric   if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
7020b57cec5SDimitry Andric     getContext().reportError(
7030b57cec5SDimitry Andric         Loc, ".seh_ directive must appear within an active frame");
7040b57cec5SDimitry Andric     return nullptr;
7050b57cec5SDimitry Andric   }
7060b57cec5SDimitry Andric   return CurrentWinFrameInfo;
7070b57cec5SDimitry Andric }
7080b57cec5SDimitry Andric 
70981ad6265SDimitry Andric void MCStreamer::emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
7100b57cec5SDimitry Andric   const MCAsmInfo *MAI = Context.getAsmInfo();
7110b57cec5SDimitry Andric   if (!MAI->usesWindowsCFI())
7120b57cec5SDimitry Andric     return getContext().reportError(
7130b57cec5SDimitry Andric         Loc, ".seh_* directives are not supported on this target");
7140b57cec5SDimitry Andric   if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
7150b57cec5SDimitry Andric     getContext().reportError(
7160b57cec5SDimitry Andric         Loc, "Starting a function before ending the previous one!");
7170b57cec5SDimitry Andric 
7185ffd83dbSDimitry Andric   MCSymbol *StartProc = emitCFILabel();
7190b57cec5SDimitry Andric 
720e8d8bef9SDimitry Andric   CurrentProcWinFrameInfoStartIndex = WinFrameInfos.size();
7210b57cec5SDimitry Andric   WinFrameInfos.emplace_back(
7228bcb0991SDimitry Andric       std::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
7230b57cec5SDimitry Andric   CurrentWinFrameInfo = WinFrameInfos.back().get();
7240b57cec5SDimitry Andric   CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
7250b57cec5SDimitry Andric }
7260b57cec5SDimitry Andric 
72781ad6265SDimitry Andric void MCStreamer::emitWinCFIEndProc(SMLoc Loc) {
7280b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
7290b57cec5SDimitry Andric   if (!CurFrame)
7300b57cec5SDimitry Andric     return;
7310b57cec5SDimitry Andric   if (CurFrame->ChainedParent)
7320b57cec5SDimitry Andric     getContext().reportError(Loc, "Not all chained regions terminated!");
7330b57cec5SDimitry Andric 
7345ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
7350b57cec5SDimitry Andric   CurFrame->End = Label;
736e8d8bef9SDimitry Andric   if (!CurFrame->FuncletOrFuncEnd)
737e8d8bef9SDimitry Andric     CurFrame->FuncletOrFuncEnd = CurFrame->End;
738e8d8bef9SDimitry Andric 
739e8d8bef9SDimitry Andric   for (size_t I = CurrentProcWinFrameInfoStartIndex, E = WinFrameInfos.size();
740e8d8bef9SDimitry Andric        I != E; ++I)
74181ad6265SDimitry Andric     emitWindowsUnwindTables(WinFrameInfos[I].get());
74281ad6265SDimitry Andric   switchSection(CurFrame->TextSection);
7430b57cec5SDimitry Andric }
7440b57cec5SDimitry Andric 
74581ad6265SDimitry Andric void MCStreamer::emitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
7460b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
7470b57cec5SDimitry Andric   if (!CurFrame)
7480b57cec5SDimitry Andric     return;
7490b57cec5SDimitry Andric   if (CurFrame->ChainedParent)
7500b57cec5SDimitry Andric     getContext().reportError(Loc, "Not all chained regions terminated!");
7510b57cec5SDimitry Andric 
7525ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
7530b57cec5SDimitry Andric   CurFrame->FuncletOrFuncEnd = Label;
7540b57cec5SDimitry Andric }
7550b57cec5SDimitry Andric 
75681ad6265SDimitry Andric void MCStreamer::emitWinCFIStartChained(SMLoc Loc) {
7570b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
7580b57cec5SDimitry Andric   if (!CurFrame)
7590b57cec5SDimitry Andric     return;
7600b57cec5SDimitry Andric 
7615ffd83dbSDimitry Andric   MCSymbol *StartProc = emitCFILabel();
7620b57cec5SDimitry Andric 
7638bcb0991SDimitry Andric   WinFrameInfos.emplace_back(std::make_unique<WinEH::FrameInfo>(
7640b57cec5SDimitry Andric       CurFrame->Function, StartProc, CurFrame));
7650b57cec5SDimitry Andric   CurrentWinFrameInfo = WinFrameInfos.back().get();
7660b57cec5SDimitry Andric   CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
7670b57cec5SDimitry Andric }
7680b57cec5SDimitry Andric 
76981ad6265SDimitry Andric void MCStreamer::emitWinCFIEndChained(SMLoc Loc) {
7700b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
7710b57cec5SDimitry Andric   if (!CurFrame)
7720b57cec5SDimitry Andric     return;
7730b57cec5SDimitry Andric   if (!CurFrame->ChainedParent)
7740b57cec5SDimitry Andric     return getContext().reportError(
7750b57cec5SDimitry Andric         Loc, "End of a chained region outside a chained region!");
7760b57cec5SDimitry Andric 
7775ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric   CurFrame->End = Label;
7800b57cec5SDimitry Andric   CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
7810b57cec5SDimitry Andric }
7820b57cec5SDimitry Andric 
78381ad6265SDimitry Andric void MCStreamer::emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
7840b57cec5SDimitry Andric                                   SMLoc Loc) {
7850b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
7860b57cec5SDimitry Andric   if (!CurFrame)
7870b57cec5SDimitry Andric     return;
7880b57cec5SDimitry Andric   if (CurFrame->ChainedParent)
7890b57cec5SDimitry Andric     return getContext().reportError(
7900b57cec5SDimitry Andric         Loc, "Chained unwind areas can't have handlers!");
7910b57cec5SDimitry Andric   CurFrame->ExceptionHandler = Sym;
7920b57cec5SDimitry Andric   if (!Except && !Unwind)
7930b57cec5SDimitry Andric     getContext().reportError(Loc, "Don't know what kind of handler this is!");
7940b57cec5SDimitry Andric   if (Unwind)
7950b57cec5SDimitry Andric     CurFrame->HandlesUnwind = true;
7960b57cec5SDimitry Andric   if (Except)
7970b57cec5SDimitry Andric     CurFrame->HandlesExceptions = true;
7980b57cec5SDimitry Andric }
7990b57cec5SDimitry Andric 
80081ad6265SDimitry Andric void MCStreamer::emitWinEHHandlerData(SMLoc Loc) {
8010b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
8020b57cec5SDimitry Andric   if (!CurFrame)
8030b57cec5SDimitry Andric     return;
8040b57cec5SDimitry Andric   if (CurFrame->ChainedParent)
8050b57cec5SDimitry Andric     getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
8060b57cec5SDimitry Andric }
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
8090b57cec5SDimitry Andric                                     const MCSymbolRefExpr *To, uint64_t Count) {
8100b57cec5SDimitry Andric }
8110b57cec5SDimitry Andric 
8120b57cec5SDimitry Andric static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
8130b57cec5SDimitry Andric                                    MCSection *MainCFISec,
8140b57cec5SDimitry Andric                                    const MCSection *TextSec) {
8150b57cec5SDimitry Andric   // If this is the main .text section, use the main unwind info section.
8160b57cec5SDimitry Andric   if (TextSec == Context.getObjectFileInfo()->getTextSection())
8170b57cec5SDimitry Andric     return MainCFISec;
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
8200b57cec5SDimitry Andric   auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
8210b57cec5SDimitry Andric   unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
8220b57cec5SDimitry Andric 
8230b57cec5SDimitry Andric   // If this section is COMDAT, this unwind section should be COMDAT associative
8240b57cec5SDimitry Andric   // with its group.
8250b57cec5SDimitry Andric   const MCSymbol *KeySym = nullptr;
8260b57cec5SDimitry Andric   if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
8270b57cec5SDimitry Andric     KeySym = TextSecCOFF->getCOMDATSymbol();
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric     // In a GNU environment, we can't use associative comdats. Instead, do what
8300b57cec5SDimitry Andric     // GCC does, which is to make plain comdat selectany section named like
8310b57cec5SDimitry Andric     // ".[px]data$_Z3foov".
8320b57cec5SDimitry Andric     if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
8335ffd83dbSDimitry Andric       std::string SectionName = (MainCFISecCOFF->getName() + "$" +
8345ffd83dbSDimitry Andric                                  TextSecCOFF->getName().split('$').second)
8350b57cec5SDimitry Andric                                     .str();
8360b57cec5SDimitry Andric       return Context.getCOFFSection(
8370b57cec5SDimitry Andric           SectionName,
8380b57cec5SDimitry Andric           MainCFISecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT,
8390b57cec5SDimitry Andric           MainCFISecCOFF->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY);
8400b57cec5SDimitry Andric     }
8410b57cec5SDimitry Andric   }
8420b57cec5SDimitry Andric 
8430b57cec5SDimitry Andric   return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
8440b57cec5SDimitry Andric }
8450b57cec5SDimitry Andric 
8460b57cec5SDimitry Andric MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
8470b57cec5SDimitry Andric   return getWinCFISection(getContext(), &NextWinCFIID,
8480b57cec5SDimitry Andric                           getContext().getObjectFileInfo()->getPDataSection(),
8490b57cec5SDimitry Andric                           TextSec);
8500b57cec5SDimitry Andric }
8510b57cec5SDimitry Andric 
8520b57cec5SDimitry Andric MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
8530b57cec5SDimitry Andric   return getWinCFISection(getContext(), &NextWinCFIID,
8540b57cec5SDimitry Andric                           getContext().getObjectFileInfo()->getXDataSection(),
8550b57cec5SDimitry Andric                           TextSec);
8560b57cec5SDimitry Andric }
8570b57cec5SDimitry Andric 
8585ffd83dbSDimitry Andric void MCStreamer::emitSyntaxDirective() {}
8590b57cec5SDimitry Andric 
8608bcb0991SDimitry Andric static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
8618bcb0991SDimitry Andric   return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
8628bcb0991SDimitry Andric }
8638bcb0991SDimitry Andric 
86481ad6265SDimitry Andric void MCStreamer::emitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
8650b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
8660b57cec5SDimitry Andric   if (!CurFrame)
8670b57cec5SDimitry Andric     return;
8680b57cec5SDimitry Andric 
8695ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
8700b57cec5SDimitry Andric 
8718bcb0991SDimitry Andric   WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(
8728bcb0991SDimitry Andric       Label, encodeSEHRegNum(Context, Register));
8730b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Inst);
8740b57cec5SDimitry Andric }
8750b57cec5SDimitry Andric 
87681ad6265SDimitry Andric void MCStreamer::emitWinCFISetFrame(MCRegister Register, unsigned Offset,
8770b57cec5SDimitry Andric                                     SMLoc Loc) {
8780b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
8790b57cec5SDimitry Andric   if (!CurFrame)
8800b57cec5SDimitry Andric     return;
8810b57cec5SDimitry Andric   if (CurFrame->LastFrameInst >= 0)
8820b57cec5SDimitry Andric     return getContext().reportError(
8830b57cec5SDimitry Andric         Loc, "frame register and offset can be set at most once");
8840b57cec5SDimitry Andric   if (Offset & 0x0F)
8850b57cec5SDimitry Andric     return getContext().reportError(Loc, "offset is not a multiple of 16");
8860b57cec5SDimitry Andric   if (Offset > 240)
8870b57cec5SDimitry Andric     return getContext().reportError(
8880b57cec5SDimitry Andric         Loc, "frame offset must be less than or equal to 240");
8890b57cec5SDimitry Andric 
8905ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
8910b57cec5SDimitry Andric 
8928bcb0991SDimitry Andric   WinEH::Instruction Inst = Win64EH::Instruction::SetFPReg(
8938bcb0991SDimitry Andric       Label, encodeSEHRegNum(getContext(), Register), Offset);
8940b57cec5SDimitry Andric   CurFrame->LastFrameInst = CurFrame->Instructions.size();
8950b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Inst);
8960b57cec5SDimitry Andric }
8970b57cec5SDimitry Andric 
89881ad6265SDimitry Andric void MCStreamer::emitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
8990b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
9000b57cec5SDimitry Andric   if (!CurFrame)
9010b57cec5SDimitry Andric     return;
9020b57cec5SDimitry Andric   if (Size == 0)
9030b57cec5SDimitry Andric     return getContext().reportError(Loc,
9040b57cec5SDimitry Andric                                     "stack allocation size must be non-zero");
9050b57cec5SDimitry Andric   if (Size & 7)
9060b57cec5SDimitry Andric     return getContext().reportError(
9070b57cec5SDimitry Andric         Loc, "stack allocation size is not a multiple of 8");
9080b57cec5SDimitry Andric 
9095ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
9100b57cec5SDimitry Andric 
9110b57cec5SDimitry Andric   WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
9120b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Inst);
9130b57cec5SDimitry Andric }
9140b57cec5SDimitry Andric 
91581ad6265SDimitry Andric void MCStreamer::emitWinCFISaveReg(MCRegister Register, unsigned Offset,
9160b57cec5SDimitry Andric                                    SMLoc Loc) {
9170b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
9180b57cec5SDimitry Andric   if (!CurFrame)
9190b57cec5SDimitry Andric     return;
9200b57cec5SDimitry Andric 
9210b57cec5SDimitry Andric   if (Offset & 7)
9220b57cec5SDimitry Andric     return getContext().reportError(
9230b57cec5SDimitry Andric         Loc, "register save offset is not 8 byte aligned");
9240b57cec5SDimitry Andric 
9255ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
9260b57cec5SDimitry Andric 
9278bcb0991SDimitry Andric   WinEH::Instruction Inst = Win64EH::Instruction::SaveNonVol(
9288bcb0991SDimitry Andric       Label, encodeSEHRegNum(Context, Register), Offset);
9290b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Inst);
9300b57cec5SDimitry Andric }
9310b57cec5SDimitry Andric 
93281ad6265SDimitry Andric void MCStreamer::emitWinCFISaveXMM(MCRegister Register, unsigned Offset,
9330b57cec5SDimitry Andric                                    SMLoc Loc) {
9340b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
9350b57cec5SDimitry Andric   if (!CurFrame)
9360b57cec5SDimitry Andric     return;
9370b57cec5SDimitry Andric   if (Offset & 0x0F)
9380b57cec5SDimitry Andric     return getContext().reportError(Loc, "offset is not a multiple of 16");
9390b57cec5SDimitry Andric 
9405ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
9410b57cec5SDimitry Andric 
9428bcb0991SDimitry Andric   WinEH::Instruction Inst = Win64EH::Instruction::SaveXMM(
9438bcb0991SDimitry Andric       Label, encodeSEHRegNum(Context, Register), Offset);
9440b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Inst);
9450b57cec5SDimitry Andric }
9460b57cec5SDimitry Andric 
94781ad6265SDimitry Andric void MCStreamer::emitWinCFIPushFrame(bool Code, SMLoc Loc) {
9480b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
9490b57cec5SDimitry Andric   if (!CurFrame)
9500b57cec5SDimitry Andric     return;
9510b57cec5SDimitry Andric   if (!CurFrame->Instructions.empty())
9520b57cec5SDimitry Andric     return getContext().reportError(
9530b57cec5SDimitry Andric         Loc, "If present, PushMachFrame must be the first UOP");
9540b57cec5SDimitry Andric 
9555ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
9560b57cec5SDimitry Andric 
9570b57cec5SDimitry Andric   WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
9580b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Inst);
9590b57cec5SDimitry Andric }
9600b57cec5SDimitry Andric 
96181ad6265SDimitry Andric void MCStreamer::emitWinCFIEndProlog(SMLoc Loc) {
9620b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
9630b57cec5SDimitry Andric   if (!CurFrame)
9640b57cec5SDimitry Andric     return;
9650b57cec5SDimitry Andric 
9665ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
9670b57cec5SDimitry Andric 
9680b57cec5SDimitry Andric   CurFrame->PrologEnd = Label;
9690b57cec5SDimitry Andric }
9700b57cec5SDimitry Andric 
97181ad6265SDimitry Andric void MCStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {}
9720b57cec5SDimitry Andric 
97381ad6265SDimitry Andric void MCStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {}
9740b57cec5SDimitry Andric 
97581ad6265SDimitry Andric void MCStreamer::emitCOFFSectionIndex(MCSymbol const *Symbol) {}
9760b57cec5SDimitry Andric 
97781ad6265SDimitry Andric void MCStreamer::emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
9780b57cec5SDimitry Andric 
97981ad6265SDimitry Andric void MCStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
9800b57cec5SDimitry Andric 
9810b57cec5SDimitry Andric /// EmitRawText - If this file is backed by an assembly streamer, this dumps
9820b57cec5SDimitry Andric /// the specified string in the output .s file.  This capability is
9830b57cec5SDimitry Andric /// indicated by the hasRawTextSupport() predicate.
9845ffd83dbSDimitry Andric void MCStreamer::emitRawTextImpl(StringRef String) {
9850b57cec5SDimitry Andric   // This is not llvm_unreachable for the sake of out of tree backend
9860b57cec5SDimitry Andric   // developers who may not have assembly streamers and should serve as a
9870b57cec5SDimitry Andric   // reminder to not accidentally call EmitRawText in the absence of such.
9880b57cec5SDimitry Andric   report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
9890b57cec5SDimitry Andric                      "it (target backend is likely missing an AsmStreamer "
9900b57cec5SDimitry Andric                      "implementation)");
9910b57cec5SDimitry Andric }
9920b57cec5SDimitry Andric 
9935ffd83dbSDimitry Andric void MCStreamer::emitRawText(const Twine &T) {
9940b57cec5SDimitry Andric   SmallString<128> Str;
9955ffd83dbSDimitry Andric   emitRawTextImpl(T.toStringRef(Str));
9960b57cec5SDimitry Andric }
9970b57cec5SDimitry Andric 
99881ad6265SDimitry Andric void MCStreamer::emitWindowsUnwindTables() {}
9990b57cec5SDimitry Andric 
100081ad6265SDimitry Andric void MCStreamer::emitWindowsUnwindTables(WinEH::FrameInfo *Frame) {}
1001e8d8bef9SDimitry Andric 
100281ad6265SDimitry Andric void MCStreamer::finish(SMLoc EndLoc) {
10030b57cec5SDimitry Andric   if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
10040b57cec5SDimitry Andric       (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
1005e8d8bef9SDimitry Andric     getContext().reportError(EndLoc, "Unfinished frame!");
10060b57cec5SDimitry Andric     return;
10070b57cec5SDimitry Andric   }
10080b57cec5SDimitry Andric 
10090b57cec5SDimitry Andric   MCTargetStreamer *TS = getTargetStreamer();
10100b57cec5SDimitry Andric   if (TS)
10110b57cec5SDimitry Andric     TS->finish();
10120b57cec5SDimitry Andric 
10135ffd83dbSDimitry Andric   finishImpl();
10140b57cec5SDimitry Andric }
10150b57cec5SDimitry Andric 
1016fe6060f1SDimitry Andric void MCStreamer::maybeEmitDwarf64Mark() {
1017fe6060f1SDimitry Andric   if (Context.getDwarfFormat() != dwarf::DWARF64)
1018fe6060f1SDimitry Andric     return;
1019fe6060f1SDimitry Andric   AddComment("DWARF64 Mark");
1020fe6060f1SDimitry Andric   emitInt32(dwarf::DW_LENGTH_DWARF64);
1021fe6060f1SDimitry Andric }
1022fe6060f1SDimitry Andric 
1023fe6060f1SDimitry Andric void MCStreamer::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) {
1024fe6060f1SDimitry Andric   assert(Context.getDwarfFormat() == dwarf::DWARF64 ||
1025fe6060f1SDimitry Andric          Length <= dwarf::DW_LENGTH_lo_reserved);
1026fe6060f1SDimitry Andric   maybeEmitDwarf64Mark();
1027fe6060f1SDimitry Andric   AddComment(Comment);
1028fe6060f1SDimitry Andric   emitIntValue(Length, dwarf::getDwarfOffsetByteSize(Context.getDwarfFormat()));
1029fe6060f1SDimitry Andric }
1030fe6060f1SDimitry Andric 
1031fe6060f1SDimitry Andric MCSymbol *MCStreamer::emitDwarfUnitLength(const Twine &Prefix,
1032fe6060f1SDimitry Andric                                           const Twine &Comment) {
1033fe6060f1SDimitry Andric   maybeEmitDwarf64Mark();
1034fe6060f1SDimitry Andric   AddComment(Comment);
1035fe6060f1SDimitry Andric   MCSymbol *Lo = Context.createTempSymbol(Prefix + "_start");
1036fe6060f1SDimitry Andric   MCSymbol *Hi = Context.createTempSymbol(Prefix + "_end");
1037fe6060f1SDimitry Andric 
1038fe6060f1SDimitry Andric   emitAbsoluteSymbolDiff(
1039fe6060f1SDimitry Andric       Hi, Lo, dwarf::getDwarfOffsetByteSize(Context.getDwarfFormat()));
1040fe6060f1SDimitry Andric   // emit the begin symbol after we generate the length field.
1041fe6060f1SDimitry Andric   emitLabel(Lo);
1042fe6060f1SDimitry Andric   // Return the Hi symbol to the caller.
1043fe6060f1SDimitry Andric   return Hi;
1044fe6060f1SDimitry Andric }
1045fe6060f1SDimitry Andric 
1046fe6060f1SDimitry Andric void MCStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
1047fe6060f1SDimitry Andric   // Set the value of the symbol, as we are at the start of the line table.
1048fe6060f1SDimitry Andric   emitLabel(StartSym);
1049fe6060f1SDimitry Andric }
1050fe6060f1SDimitry Andric 
10515ffd83dbSDimitry Andric void MCStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
10520b57cec5SDimitry Andric   visitUsedExpr(*Value);
10530b57cec5SDimitry Andric   Symbol->setVariableValue(Value);
10540b57cec5SDimitry Andric 
10550b57cec5SDimitry Andric   MCTargetStreamer *TS = getTargetStreamer();
10560b57cec5SDimitry Andric   if (TS)
10570b57cec5SDimitry Andric     TS->emitAssignment(Symbol, Value);
10580b57cec5SDimitry Andric }
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
1061480093f4SDimitry Andric                                       uint64_t Address, const MCInst &Inst,
1062480093f4SDimitry Andric                                       const MCSubtargetInfo &STI,
1063480093f4SDimitry Andric                                       raw_ostream &OS) {
1064480093f4SDimitry Andric   InstPrinter.printInst(&Inst, Address, "", STI, OS);
10650b57cec5SDimitry Andric }
10660b57cec5SDimitry Andric 
10670b57cec5SDimitry Andric void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
10680b57cec5SDimitry Andric }
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
10710b57cec5SDimitry Andric   switch (Expr.getKind()) {
10720b57cec5SDimitry Andric   case MCExpr::Target:
10730b57cec5SDimitry Andric     cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
10740b57cec5SDimitry Andric     break;
10750b57cec5SDimitry Andric 
10760b57cec5SDimitry Andric   case MCExpr::Constant:
10770b57cec5SDimitry Andric     break;
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric   case MCExpr::Binary: {
10800b57cec5SDimitry Andric     const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
10810b57cec5SDimitry Andric     visitUsedExpr(*BE.getLHS());
10820b57cec5SDimitry Andric     visitUsedExpr(*BE.getRHS());
10830b57cec5SDimitry Andric     break;
10840b57cec5SDimitry Andric   }
10850b57cec5SDimitry Andric 
10860b57cec5SDimitry Andric   case MCExpr::SymbolRef:
10870b57cec5SDimitry Andric     visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
10880b57cec5SDimitry Andric     break;
10890b57cec5SDimitry Andric 
10900b57cec5SDimitry Andric   case MCExpr::Unary:
10910b57cec5SDimitry Andric     visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
10920b57cec5SDimitry Andric     break;
10930b57cec5SDimitry Andric   }
10940b57cec5SDimitry Andric }
10950b57cec5SDimitry Andric 
10965ffd83dbSDimitry Andric void MCStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
10970b57cec5SDimitry Andric   // Scan for values.
10980b57cec5SDimitry Andric   for (unsigned i = Inst.getNumOperands(); i--;)
10990b57cec5SDimitry Andric     if (Inst.getOperand(i).isExpr())
11000b57cec5SDimitry Andric       visitUsedExpr(*Inst.getOperand(i).getExpr());
11010b57cec5SDimitry Andric }
11020b57cec5SDimitry Andric 
1103e8d8bef9SDimitry Andric void MCStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
1104e8d8bef9SDimitry Andric                                  uint64_t Attr,
1105*bdd1243dSDimitry Andric                                  const MCPseudoProbeInlineStack &InlineStack,
1106*bdd1243dSDimitry Andric                                  MCSymbol *FnSym) {
1107e8d8bef9SDimitry Andric   auto &Context = getContext();
1108e8d8bef9SDimitry Andric 
1109e8d8bef9SDimitry Andric   // Create a symbol at in the current section for use in the probe.
1110e8d8bef9SDimitry Andric   MCSymbol *ProbeSym = Context.createTempSymbol();
1111e8d8bef9SDimitry Andric 
1112e8d8bef9SDimitry Andric   // Set the value of the symbol to use for the MCPseudoProbe.
1113e8d8bef9SDimitry Andric   emitLabel(ProbeSym);
1114e8d8bef9SDimitry Andric 
1115e8d8bef9SDimitry Andric   // Create a (local) probe entry with the symbol.
1116e8d8bef9SDimitry Andric   MCPseudoProbe Probe(ProbeSym, Guid, Index, Type, Attr);
1117e8d8bef9SDimitry Andric 
1118e8d8bef9SDimitry Andric   // Add the probe entry to this section's entries.
1119e8d8bef9SDimitry Andric   Context.getMCPseudoProbeTable().getProbeSections().addPseudoProbe(
1120*bdd1243dSDimitry Andric       FnSym, Probe, InlineStack);
1121e8d8bef9SDimitry Andric }
1122e8d8bef9SDimitry Andric 
11230b57cec5SDimitry Andric void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
11240b57cec5SDimitry Andric                                         unsigned Size) {
11250b57cec5SDimitry Andric   // Get the Hi-Lo expression.
11260b57cec5SDimitry Andric   const MCExpr *Diff =
11270b57cec5SDimitry Andric       MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
11280b57cec5SDimitry Andric                               MCSymbolRefExpr::create(Lo, Context), Context);
11290b57cec5SDimitry Andric 
11300b57cec5SDimitry Andric   const MCAsmInfo *MAI = Context.getAsmInfo();
11310b57cec5SDimitry Andric   if (!MAI->doesSetDirectiveSuppressReloc()) {
11325ffd83dbSDimitry Andric     emitValue(Diff, Size);
11330b57cec5SDimitry Andric     return;
11340b57cec5SDimitry Andric   }
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric   // Otherwise, emit with .set (aka assignment).
1137e8d8bef9SDimitry Andric   MCSymbol *SetLabel = Context.createTempSymbol("set");
11385ffd83dbSDimitry Andric   emitAssignment(SetLabel, Diff);
11395ffd83dbSDimitry Andric   emitSymbolValue(SetLabel, Size);
11400b57cec5SDimitry Andric }
11410b57cec5SDimitry Andric 
11420b57cec5SDimitry Andric void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
11430b57cec5SDimitry Andric                                                  const MCSymbol *Lo) {
11440b57cec5SDimitry Andric   // Get the Hi-Lo expression.
11450b57cec5SDimitry Andric   const MCExpr *Diff =
11460b57cec5SDimitry Andric       MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
11470b57cec5SDimitry Andric                               MCSymbolRefExpr::create(Lo, Context), Context);
11480b57cec5SDimitry Andric 
11495ffd83dbSDimitry Andric   emitULEB128Value(Diff);
11500b57cec5SDimitry Andric }
11510b57cec5SDimitry Andric 
11525ffd83dbSDimitry Andric void MCStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {}
11535ffd83dbSDimitry Andric void MCStreamer::emitThumbFunc(MCSymbol *Func) {}
11545ffd83dbSDimitry Andric void MCStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
115581ad6265SDimitry Andric void MCStreamer::beginCOFFSymbolDef(const MCSymbol *Symbol) {
11560b57cec5SDimitry Andric   llvm_unreachable("this directive only supported on COFF targets");
11570b57cec5SDimitry Andric }
115881ad6265SDimitry Andric void MCStreamer::endCOFFSymbolDef() {
11590b57cec5SDimitry Andric   llvm_unreachable("this directive only supported on COFF targets");
11600b57cec5SDimitry Andric }
11615ffd83dbSDimitry Andric void MCStreamer::emitFileDirective(StringRef Filename) {}
1162fe6060f1SDimitry Andric void MCStreamer::emitFileDirective(StringRef Filename, StringRef CompilerVerion,
1163fe6060f1SDimitry Andric                                    StringRef TimeStamp, StringRef Description) {
1164fe6060f1SDimitry Andric }
116581ad6265SDimitry Andric void MCStreamer::emitCOFFSymbolStorageClass(int StorageClass) {
11660b57cec5SDimitry Andric   llvm_unreachable("this directive only supported on COFF targets");
11670b57cec5SDimitry Andric }
116881ad6265SDimitry Andric void MCStreamer::emitCOFFSymbolType(int Type) {
11690b57cec5SDimitry Andric   llvm_unreachable("this directive only supported on COFF targets");
11700b57cec5SDimitry Andric }
11715ffd83dbSDimitry Andric void MCStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
1172480093f4SDimitry Andric                                             MCSymbol *CsectSym,
1173*bdd1243dSDimitry Andric                                             Align Alignment) {
11748bcb0991SDimitry Andric   llvm_unreachable("this directive only supported on XCOFF targets");
11758bcb0991SDimitry Andric }
11765ffd83dbSDimitry Andric 
11775ffd83dbSDimitry Andric void MCStreamer::emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
11785ffd83dbSDimitry Andric                                                       MCSymbolAttr Linkage,
11795ffd83dbSDimitry Andric                                                       MCSymbolAttr Visibility) {
11805ffd83dbSDimitry Andric   llvm_unreachable("emitXCOFFSymbolLinkageWithVisibility is only supported on "
11815ffd83dbSDimitry Andric                    "XCOFF targets");
11825ffd83dbSDimitry Andric }
11835ffd83dbSDimitry Andric 
11845ffd83dbSDimitry Andric void MCStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
11855ffd83dbSDimitry Andric                                           StringRef Rename) {
11865ffd83dbSDimitry Andric   llvm_unreachable("emitXCOFFRenameDirective is only supported on "
11875ffd83dbSDimitry Andric                    "XCOFF targets");
11885ffd83dbSDimitry Andric }
11895ffd83dbSDimitry Andric 
119081ad6265SDimitry Andric void MCStreamer::emitXCOFFRefDirective(StringRef Name) {
119181ad6265SDimitry Andric   llvm_unreachable("emitXCOFFRefDirective is only supported on XCOFF targets");
119281ad6265SDimitry Andric }
119381ad6265SDimitry Andric 
1194*bdd1243dSDimitry Andric void MCStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,
1195*bdd1243dSDimitry Andric                                           const MCSymbol *Trap,
1196*bdd1243dSDimitry Andric                                           unsigned Lang, unsigned Reason,
1197*bdd1243dSDimitry Andric                                           unsigned FunctionSize,
1198*bdd1243dSDimitry Andric                                           bool hasDebug) {
1199*bdd1243dSDimitry Andric   report_fatal_error("emitXCOFFExceptDirective is only supported on "
1200*bdd1243dSDimitry Andric                      "XCOFF targets");
1201*bdd1243dSDimitry Andric }
1202*bdd1243dSDimitry Andric 
12030b57cec5SDimitry Andric void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
1204fe6060f1SDimitry Andric void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
1205fe6060f1SDimitry Andric                                         StringRef Name, bool KeepOriginalSym) {}
12065ffd83dbSDimitry Andric void MCStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1207*bdd1243dSDimitry Andric                                        Align ByteAlignment) {}
12085ffd83dbSDimitry Andric void MCStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1209*bdd1243dSDimitry Andric                                 uint64_t Size, Align ByteAlignment) {}
12105ffd83dbSDimitry Andric void MCStreamer::changeSection(MCSection *, const MCExpr *) {}
12115ffd83dbSDimitry Andric void MCStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
12125ffd83dbSDimitry Andric void MCStreamer::emitBytes(StringRef Data) {}
12135ffd83dbSDimitry Andric void MCStreamer::emitBinaryData(StringRef Data) { emitBytes(Data); }
12145ffd83dbSDimitry Andric void MCStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
12150b57cec5SDimitry Andric   visitUsedExpr(*Value);
12160b57cec5SDimitry Andric }
12175ffd83dbSDimitry Andric void MCStreamer::emitULEB128Value(const MCExpr *Value) {}
12185ffd83dbSDimitry Andric void MCStreamer::emitSLEB128Value(const MCExpr *Value) {}
12190b57cec5SDimitry Andric void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
12200b57cec5SDimitry Andric void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
12210b57cec5SDimitry Andric                           SMLoc Loc) {}
1222*bdd1243dSDimitry Andric void MCStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
12230b57cec5SDimitry Andric                                       unsigned ValueSize,
12240b57cec5SDimitry Andric                                       unsigned MaxBytesToEmit) {}
1225*bdd1243dSDimitry Andric void MCStreamer::emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
12260b57cec5SDimitry Andric                                    unsigned MaxBytesToEmit) {}
12270b57cec5SDimitry Andric void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
12280b57cec5SDimitry Andric                                    SMLoc Loc) {}
1229*bdd1243dSDimitry Andric void MCStreamer::emitBundleAlignMode(Align Alignment) {}
12305ffd83dbSDimitry Andric void MCStreamer::emitBundleLock(bool AlignToEnd) {}
12315ffd83dbSDimitry Andric void MCStreamer::finishImpl() {}
12325ffd83dbSDimitry Andric void MCStreamer::emitBundleUnlock() {}
12330b57cec5SDimitry Andric 
123481ad6265SDimitry Andric void MCStreamer::switchSection(MCSection *Section, const MCExpr *Subsection) {
12350b57cec5SDimitry Andric   assert(Section && "Cannot switch to a null section!");
12360b57cec5SDimitry Andric   MCSectionSubPair curSection = SectionStack.back().first;
12370b57cec5SDimitry Andric   SectionStack.back().second = curSection;
12380b57cec5SDimitry Andric   if (MCSectionSubPair(Section, Subsection) != curSection) {
12395ffd83dbSDimitry Andric     changeSection(Section, Subsection);
12400b57cec5SDimitry Andric     SectionStack.back().first = MCSectionSubPair(Section, Subsection);
12410b57cec5SDimitry Andric     assert(!Section->hasEnded() && "Section already ended");
12420b57cec5SDimitry Andric     MCSymbol *Sym = Section->getBeginSymbol();
12430b57cec5SDimitry Andric     if (Sym && !Sym->isInSection())
12445ffd83dbSDimitry Andric       emitLabel(Sym);
12450b57cec5SDimitry Andric   }
12460b57cec5SDimitry Andric }
12470b57cec5SDimitry Andric 
12480b57cec5SDimitry Andric MCSymbol *MCStreamer::endSection(MCSection *Section) {
12490b57cec5SDimitry Andric   // TODO: keep track of the last subsection so that this symbol appears in the
12500b57cec5SDimitry Andric   // correct place.
12510b57cec5SDimitry Andric   MCSymbol *Sym = Section->getEndSymbol(Context);
12520b57cec5SDimitry Andric   if (Sym->isInSection())
12530b57cec5SDimitry Andric     return Sym;
12540b57cec5SDimitry Andric 
125581ad6265SDimitry Andric   switchSection(Section);
12565ffd83dbSDimitry Andric   emitLabel(Sym);
12570b57cec5SDimitry Andric   return Sym;
12580b57cec5SDimitry Andric }
12590b57cec5SDimitry Andric 
12605ffd83dbSDimitry Andric static VersionTuple
12615ffd83dbSDimitry Andric targetVersionOrMinimumSupportedOSVersion(const Triple &Target,
12625ffd83dbSDimitry Andric                                          VersionTuple TargetVersion) {
12635ffd83dbSDimitry Andric   VersionTuple Min = Target.getMinimumSupportedOSVersion();
12645ffd83dbSDimitry Andric   return !Min.empty() && Min > TargetVersion ? Min : TargetVersion;
12655ffd83dbSDimitry Andric }
12665ffd83dbSDimitry Andric 
12675ffd83dbSDimitry Andric static MCVersionMinType
12685ffd83dbSDimitry Andric getMachoVersionMinLoadCommandType(const Triple &Target) {
12695ffd83dbSDimitry Andric   assert(Target.isOSDarwin() && "expected a darwin OS");
12705ffd83dbSDimitry Andric   switch (Target.getOS()) {
12715ffd83dbSDimitry Andric   case Triple::MacOSX:
12725ffd83dbSDimitry Andric   case Triple::Darwin:
12735ffd83dbSDimitry Andric     return MCVM_OSXVersionMin;
12745ffd83dbSDimitry Andric   case Triple::IOS:
12755ffd83dbSDimitry Andric     assert(!Target.isMacCatalystEnvironment() &&
12765ffd83dbSDimitry Andric            "mac Catalyst should use LC_BUILD_VERSION");
12775ffd83dbSDimitry Andric     return MCVM_IOSVersionMin;
12785ffd83dbSDimitry Andric   case Triple::TvOS:
12795ffd83dbSDimitry Andric     return MCVM_TvOSVersionMin;
12805ffd83dbSDimitry Andric   case Triple::WatchOS:
12815ffd83dbSDimitry Andric     return MCVM_WatchOSVersionMin;
12825ffd83dbSDimitry Andric   default:
12835ffd83dbSDimitry Andric     break;
12845ffd83dbSDimitry Andric   }
12855ffd83dbSDimitry Andric   llvm_unreachable("unexpected OS type");
12865ffd83dbSDimitry Andric }
12875ffd83dbSDimitry Andric 
12885ffd83dbSDimitry Andric static VersionTuple getMachoBuildVersionSupportedOS(const Triple &Target) {
12895ffd83dbSDimitry Andric   assert(Target.isOSDarwin() && "expected a darwin OS");
12905ffd83dbSDimitry Andric   switch (Target.getOS()) {
12915ffd83dbSDimitry Andric   case Triple::MacOSX:
12925ffd83dbSDimitry Andric   case Triple::Darwin:
12935ffd83dbSDimitry Andric     return VersionTuple(10, 14);
12945ffd83dbSDimitry Andric   case Triple::IOS:
12955ffd83dbSDimitry Andric     // Mac Catalyst always uses the build version load command.
12965ffd83dbSDimitry Andric     if (Target.isMacCatalystEnvironment())
12975ffd83dbSDimitry Andric       return VersionTuple();
1298*bdd1243dSDimitry Andric     [[fallthrough]];
12995ffd83dbSDimitry Andric   case Triple::TvOS:
13005ffd83dbSDimitry Andric     return VersionTuple(12);
13015ffd83dbSDimitry Andric   case Triple::WatchOS:
13025ffd83dbSDimitry Andric     return VersionTuple(5);
130381ad6265SDimitry Andric   case Triple::DriverKit:
130481ad6265SDimitry Andric     // DriverKit always uses the build version load command.
130581ad6265SDimitry Andric     return VersionTuple();
13065ffd83dbSDimitry Andric   default:
13075ffd83dbSDimitry Andric     break;
13085ffd83dbSDimitry Andric   }
13095ffd83dbSDimitry Andric   llvm_unreachable("unexpected OS type");
13105ffd83dbSDimitry Andric }
13115ffd83dbSDimitry Andric 
13125ffd83dbSDimitry Andric static MachO::PlatformType
13135ffd83dbSDimitry Andric getMachoBuildVersionPlatformType(const Triple &Target) {
13145ffd83dbSDimitry Andric   assert(Target.isOSDarwin() && "expected a darwin OS");
13155ffd83dbSDimitry Andric   switch (Target.getOS()) {
13165ffd83dbSDimitry Andric   case Triple::MacOSX:
13175ffd83dbSDimitry Andric   case Triple::Darwin:
13185ffd83dbSDimitry Andric     return MachO::PLATFORM_MACOS;
13195ffd83dbSDimitry Andric   case Triple::IOS:
13205ffd83dbSDimitry Andric     if (Target.isMacCatalystEnvironment())
13215ffd83dbSDimitry Andric       return MachO::PLATFORM_MACCATALYST;
13225ffd83dbSDimitry Andric     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
13235ffd83dbSDimitry Andric                                            : MachO::PLATFORM_IOS;
13245ffd83dbSDimitry Andric   case Triple::TvOS:
13255ffd83dbSDimitry Andric     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
13265ffd83dbSDimitry Andric                                            : MachO::PLATFORM_TVOS;
13275ffd83dbSDimitry Andric   case Triple::WatchOS:
13285ffd83dbSDimitry Andric     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
13295ffd83dbSDimitry Andric                                            : MachO::PLATFORM_WATCHOS;
133081ad6265SDimitry Andric   case Triple::DriverKit:
133181ad6265SDimitry Andric     return MachO::PLATFORM_DRIVERKIT;
13325ffd83dbSDimitry Andric   default:
13335ffd83dbSDimitry Andric     break;
13345ffd83dbSDimitry Andric   }
13355ffd83dbSDimitry Andric   llvm_unreachable("unexpected OS type");
13365ffd83dbSDimitry Andric }
13375ffd83dbSDimitry Andric 
13380eae32dcSDimitry Andric void MCStreamer::emitVersionForTarget(
13390eae32dcSDimitry Andric     const Triple &Target, const VersionTuple &SDKVersion,
13400eae32dcSDimitry Andric     const Triple *DarwinTargetVariantTriple,
13410eae32dcSDimitry Andric     const VersionTuple &DarwinTargetVariantSDKVersion) {
13420b57cec5SDimitry Andric   if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
13430b57cec5SDimitry Andric     return;
13440b57cec5SDimitry Andric   // Do we even know the version?
13450b57cec5SDimitry Andric   if (Target.getOSMajorVersion() == 0)
13460b57cec5SDimitry Andric     return;
13470b57cec5SDimitry Andric 
13480eae32dcSDimitry Andric   VersionTuple Version;
13495ffd83dbSDimitry Andric   switch (Target.getOS()) {
13505ffd83dbSDimitry Andric   case Triple::MacOSX:
13515ffd83dbSDimitry Andric   case Triple::Darwin:
13520eae32dcSDimitry Andric     Target.getMacOSXVersion(Version);
13535ffd83dbSDimitry Andric     break;
13545ffd83dbSDimitry Andric   case Triple::IOS:
13555ffd83dbSDimitry Andric   case Triple::TvOS:
13560eae32dcSDimitry Andric     Version = Target.getiOSVersion();
13575ffd83dbSDimitry Andric     break;
13585ffd83dbSDimitry Andric   case Triple::WatchOS:
13590eae32dcSDimitry Andric     Version = Target.getWatchOSVersion();
13605ffd83dbSDimitry Andric     break;
136181ad6265SDimitry Andric   case Triple::DriverKit:
136281ad6265SDimitry Andric     Version = Target.getDriverKitVersion();
136381ad6265SDimitry Andric     break;
13645ffd83dbSDimitry Andric   default:
13655ffd83dbSDimitry Andric     llvm_unreachable("unexpected OS type");
13660b57cec5SDimitry Andric   }
13670eae32dcSDimitry Andric   assert(Version.getMajor() != 0 && "A non-zero major version is expected");
13680eae32dcSDimitry Andric   auto LinkedTargetVersion =
13690eae32dcSDimitry Andric       targetVersionOrMinimumSupportedOSVersion(Target, Version);
13705ffd83dbSDimitry Andric   auto BuildVersionOSVersion = getMachoBuildVersionSupportedOS(Target);
13710eae32dcSDimitry Andric   bool ShouldEmitBuildVersion = false;
13725ffd83dbSDimitry Andric   if (BuildVersionOSVersion.empty() ||
13730eae32dcSDimitry Andric       LinkedTargetVersion >= BuildVersionOSVersion) {
13740eae32dcSDimitry Andric     if (Target.isMacCatalystEnvironment() && DarwinTargetVariantTriple &&
13750eae32dcSDimitry Andric         DarwinTargetVariantTriple->isMacOSX()) {
13760eae32dcSDimitry Andric       emitVersionForTarget(*DarwinTargetVariantTriple,
13770eae32dcSDimitry Andric                            DarwinTargetVariantSDKVersion,
137804eeddc0SDimitry Andric                            /*DarwinTargetVariantTriple=*/nullptr,
137904eeddc0SDimitry Andric                            /*DarwinTargetVariantSDKVersion=*/VersionTuple());
13800eae32dcSDimitry Andric       emitDarwinTargetVariantBuildVersion(
13810eae32dcSDimitry Andric           getMachoBuildVersionPlatformType(Target),
13825ffd83dbSDimitry Andric           LinkedTargetVersion.getMajor(),
138381ad6265SDimitry Andric           LinkedTargetVersion.getMinor().value_or(0),
138481ad6265SDimitry Andric           LinkedTargetVersion.getSubminor().value_or(0), SDKVersion);
13850eae32dcSDimitry Andric       return;
13860eae32dcSDimitry Andric     }
13870eae32dcSDimitry Andric     emitBuildVersion(getMachoBuildVersionPlatformType(Target),
13880eae32dcSDimitry Andric                      LinkedTargetVersion.getMajor(),
138981ad6265SDimitry Andric                      LinkedTargetVersion.getMinor().value_or(0),
139081ad6265SDimitry Andric                      LinkedTargetVersion.getSubminor().value_or(0), SDKVersion);
13910eae32dcSDimitry Andric     ShouldEmitBuildVersion = true;
13920eae32dcSDimitry Andric   }
13930eae32dcSDimitry Andric 
13940eae32dcSDimitry Andric   if (const Triple *TVT = DarwinTargetVariantTriple) {
13950eae32dcSDimitry Andric     if (Target.isMacOSX() && TVT->isMacCatalystEnvironment()) {
13960eae32dcSDimitry Andric       auto TVLinkedTargetVersion =
13970eae32dcSDimitry Andric           targetVersionOrMinimumSupportedOSVersion(*TVT, TVT->getiOSVersion());
13980eae32dcSDimitry Andric       emitDarwinTargetVariantBuildVersion(
13990eae32dcSDimitry Andric           getMachoBuildVersionPlatformType(*TVT),
14000eae32dcSDimitry Andric           TVLinkedTargetVersion.getMajor(),
140181ad6265SDimitry Andric           TVLinkedTargetVersion.getMinor().value_or(0),
140281ad6265SDimitry Andric           TVLinkedTargetVersion.getSubminor().value_or(0),
14030eae32dcSDimitry Andric           DarwinTargetVariantSDKVersion);
14040eae32dcSDimitry Andric     }
14050eae32dcSDimitry Andric   }
14060eae32dcSDimitry Andric 
14070eae32dcSDimitry Andric   if (ShouldEmitBuildVersion)
14080eae32dcSDimitry Andric     return;
14095ffd83dbSDimitry Andric 
14105ffd83dbSDimitry Andric   emitVersionMin(getMachoVersionMinLoadCommandType(Target),
14115ffd83dbSDimitry Andric                  LinkedTargetVersion.getMajor(),
141281ad6265SDimitry Andric                  LinkedTargetVersion.getMinor().value_or(0),
141381ad6265SDimitry Andric                  LinkedTargetVersion.getSubminor().value_or(0), SDKVersion);
14140b57cec5SDimitry Andric }
1415