xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCStreamer.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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>
41bdd1243dSDimitry Andric #include <optional>
420b57cec5SDimitry Andric #include <utility>
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric using namespace llvm;
450b57cec5SDimitry Andric 
MCTargetStreamer(MCStreamer & S)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 
emitLabel(MCSymbol * Symbol)530b57cec5SDimitry Andric void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
540b57cec5SDimitry Andric 
finish()550b57cec5SDimitry Andric void MCTargetStreamer::finish() {}
560b57cec5SDimitry Andric 
emitConstantPools()57349cc55cSDimitry Andric void MCTargetStreamer::emitConstantPools() {}
58349cc55cSDimitry Andric 
changeSection(const MCSection * CurSection,MCSection * Section,uint32_t Subsection,raw_ostream & OS)590b57cec5SDimitry Andric void MCTargetStreamer::changeSection(const MCSection *CurSection,
60*0fca6ea1SDimitry Andric                                      MCSection *Section, uint32_t Subsection,
610b57cec5SDimitry Andric                                      raw_ostream &OS) {
6281ad6265SDimitry Andric   Section->printSwitchToSection(*Streamer.getContext().getAsmInfo(),
63fe6060f1SDimitry Andric                                 Streamer.getContext().getTargetTriple(), OS,
640b57cec5SDimitry Andric                                 Subsection);
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
emitDwarfFileDirective(StringRef Directive)670b57cec5SDimitry Andric void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
685ffd83dbSDimitry Andric   Streamer.emitRawText(Directive);
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric 
emitValue(const MCExpr * Value)710b57cec5SDimitry Andric void MCTargetStreamer::emitValue(const MCExpr *Value) {
720b57cec5SDimitry Andric   SmallString<128> Str;
730b57cec5SDimitry Andric   raw_svector_ostream OS(Str);
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   Value->print(OS, Streamer.getContext().getAsmInfo());
765ffd83dbSDimitry Andric   Streamer.emitRawText(OS.str());
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric 
emitRawBytes(StringRef Data)790b57cec5SDimitry Andric void MCTargetStreamer::emitRawBytes(StringRef Data) {
800b57cec5SDimitry Andric   const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
810b57cec5SDimitry Andric   const char *Directive = MAI->getData8bitsDirective();
820b57cec5SDimitry Andric   for (const unsigned char C : Data.bytes()) {
830b57cec5SDimitry Andric     SmallString<128> Str;
840b57cec5SDimitry Andric     raw_svector_ostream OS(Str);
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric     OS << Directive << (unsigned)C;
875ffd83dbSDimitry Andric     Streamer.emitRawText(OS.str());
880b57cec5SDimitry Andric   }
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric 
emitAssignment(MCSymbol * Symbol,const MCExpr * Value)910b57cec5SDimitry Andric void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
920b57cec5SDimitry Andric 
MCStreamer(MCContext & Ctx)930b57cec5SDimitry Andric MCStreamer::MCStreamer(MCContext &Ctx)
940b57cec5SDimitry Andric     : Context(Ctx), CurrentWinFrameInfo(nullptr),
95*0fca6ea1SDimitry Andric       CurrentProcWinFrameInfoStartIndex(0) {
960b57cec5SDimitry Andric   SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
970b57cec5SDimitry Andric }
980b57cec5SDimitry Andric 
9981ad6265SDimitry Andric MCStreamer::~MCStreamer() = default;
1000b57cec5SDimitry Andric 
reset()1010b57cec5SDimitry Andric void MCStreamer::reset() {
1020b57cec5SDimitry Andric   DwarfFrameInfos.clear();
1030b57cec5SDimitry Andric   CurrentWinFrameInfo = nullptr;
1040b57cec5SDimitry Andric   WinFrameInfos.clear();
1050b57cec5SDimitry Andric   SectionStack.clear();
1060b57cec5SDimitry Andric   SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
107*0fca6ea1SDimitry Andric   CurFrag = nullptr;
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric 
getCommentOS()11081ad6265SDimitry Andric raw_ostream &MCStreamer::getCommentOS() {
1110b57cec5SDimitry Andric   // By default, discard comments.
1120b57cec5SDimitry Andric   return nulls();
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric 
getNumFrameInfos()1150b57cec5SDimitry Andric unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos.size(); }
getDwarfFrameInfos() const1160b57cec5SDimitry Andric ArrayRef<MCDwarfFrameInfo> MCStreamer::getDwarfFrameInfos() const {
1170b57cec5SDimitry Andric   return DwarfFrameInfos;
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric 
emitRawComment(const Twine & T,bool TabPrefix)1200b57cec5SDimitry Andric void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
1210b57cec5SDimitry Andric 
addExplicitComment(const Twine & T)1220b57cec5SDimitry Andric void MCStreamer::addExplicitComment(const Twine &T) {}
emitExplicitComments()1230b57cec5SDimitry Andric void MCStreamer::emitExplicitComments() {}
1240b57cec5SDimitry Andric 
generateCompactUnwindEncodings(MCAsmBackend * MAB)1250b57cec5SDimitry Andric void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
1260b57cec5SDimitry Andric   for (auto &FI : DwarfFrameInfos)
1270b57cec5SDimitry Andric     FI.CompactUnwindEncoding =
12806c3fb27SDimitry Andric         (MAB ? MAB->generateCompactUnwindEncoding(&FI, &Context) : 0);
1290b57cec5SDimitry Andric }
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric /// EmitIntValue - Special case of EmitValue that avoids the client having to
1320b57cec5SDimitry Andric /// pass in a MCExpr for constant integers.
emitIntValue(uint64_t Value,unsigned Size)1335ffd83dbSDimitry Andric void MCStreamer::emitIntValue(uint64_t Value, unsigned Size) {
1340b57cec5SDimitry Andric   assert(1 <= Size && Size <= 8 && "Invalid size");
1350b57cec5SDimitry Andric   assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
1360b57cec5SDimitry Andric          "Invalid size");
1375ffd83dbSDimitry Andric   const bool IsLittleEndian = Context.getAsmInfo()->isLittleEndian();
1385ffd83dbSDimitry Andric   uint64_t Swapped = support::endian::byte_swap(
1395f757f3fSDimitry Andric       Value, IsLittleEndian ? llvm::endianness::little : llvm::endianness::big);
1405ffd83dbSDimitry Andric   unsigned Index = IsLittleEndian ? 0 : 8 - Size;
1415ffd83dbSDimitry Andric   emitBytes(StringRef(reinterpret_cast<char *>(&Swapped) + Index, Size));
1420b57cec5SDimitry Andric }
emitIntValue(const APInt & Value)143*0fca6ea1SDimitry Andric void MCStreamer::emitIntValue(const APInt &Value) {
144e8d8bef9SDimitry Andric   if (Value.getNumWords() == 1) {
145e8d8bef9SDimitry Andric     emitIntValue(Value.getLimitedValue(), Value.getBitWidth() / 8);
146e8d8bef9SDimitry Andric     return;
147e8d8bef9SDimitry Andric   }
148e8d8bef9SDimitry Andric 
149e8d8bef9SDimitry Andric   const bool IsLittleEndianTarget = Context.getAsmInfo()->isLittleEndian();
150e8d8bef9SDimitry Andric   const bool ShouldSwap = sys::IsLittleEndianHost != IsLittleEndianTarget;
151e8d8bef9SDimitry Andric   const APInt Swapped = ShouldSwap ? Value.byteSwap() : Value;
152e8d8bef9SDimitry Andric   const unsigned Size = Value.getBitWidth() / 8;
153e8d8bef9SDimitry Andric   SmallString<10> Tmp;
154e8d8bef9SDimitry Andric   Tmp.resize(Size);
155e8d8bef9SDimitry Andric   StoreIntToMemory(Swapped, reinterpret_cast<uint8_t *>(Tmp.data()), Size);
156e8d8bef9SDimitry Andric   emitBytes(Tmp.str());
157e8d8bef9SDimitry Andric }
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
1600b57cec5SDimitry Andric /// client having to pass in a MCExpr for constant integers.
emitULEB128IntValue(uint64_t Value,unsigned PadTo)161bdd1243dSDimitry Andric unsigned MCStreamer::emitULEB128IntValue(uint64_t Value, unsigned PadTo) {
1620b57cec5SDimitry Andric   SmallString<128> Tmp;
1630b57cec5SDimitry Andric   raw_svector_ostream OSE(Tmp);
1640b57cec5SDimitry Andric   encodeULEB128(Value, OSE, PadTo);
1655ffd83dbSDimitry Andric   emitBytes(OSE.str());
166bdd1243dSDimitry Andric   return Tmp.size();
1670b57cec5SDimitry Andric }
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
1700b57cec5SDimitry Andric /// client having to pass in a MCExpr for constant integers.
emitSLEB128IntValue(int64_t Value)171bdd1243dSDimitry Andric unsigned MCStreamer::emitSLEB128IntValue(int64_t Value) {
1720b57cec5SDimitry Andric   SmallString<128> Tmp;
1730b57cec5SDimitry Andric   raw_svector_ostream OSE(Tmp);
1740b57cec5SDimitry Andric   encodeSLEB128(Value, OSE);
1755ffd83dbSDimitry Andric   emitBytes(OSE.str());
176bdd1243dSDimitry Andric   return Tmp.size();
1770b57cec5SDimitry Andric }
1780b57cec5SDimitry Andric 
emitValue(const MCExpr * Value,unsigned Size,SMLoc Loc)1795ffd83dbSDimitry Andric void MCStreamer::emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
1805ffd83dbSDimitry Andric   emitValueImpl(Value, Size, Loc);
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric 
emitSymbolValue(const MCSymbol * Sym,unsigned Size,bool IsSectionRelative)1835ffd83dbSDimitry Andric void MCStreamer::emitSymbolValue(const MCSymbol *Sym, unsigned Size,
1840b57cec5SDimitry Andric                                  bool IsSectionRelative) {
1850b57cec5SDimitry Andric   assert((!IsSectionRelative || Size == 4) &&
1860b57cec5SDimitry Andric          "SectionRelative value requires 4-bytes");
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric   if (!IsSectionRelative)
1895ffd83dbSDimitry Andric     emitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
1900b57cec5SDimitry Andric   else
19181ad6265SDimitry Andric     emitCOFFSecRel32(Sym, /*Offset=*/0);
1920b57cec5SDimitry Andric }
1930b57cec5SDimitry Andric 
emitDTPRel64Value(const MCExpr * Value)1945ffd83dbSDimitry Andric void MCStreamer::emitDTPRel64Value(const MCExpr *Value) {
1950b57cec5SDimitry Andric   report_fatal_error("unsupported directive in streamer");
1960b57cec5SDimitry Andric }
1970b57cec5SDimitry Andric 
emitDTPRel32Value(const MCExpr * Value)1985ffd83dbSDimitry Andric void MCStreamer::emitDTPRel32Value(const MCExpr *Value) {
1990b57cec5SDimitry Andric   report_fatal_error("unsupported directive in streamer");
2000b57cec5SDimitry Andric }
2010b57cec5SDimitry Andric 
emitTPRel64Value(const MCExpr * Value)2025ffd83dbSDimitry Andric void MCStreamer::emitTPRel64Value(const MCExpr *Value) {
2030b57cec5SDimitry Andric   report_fatal_error("unsupported directive in streamer");
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
emitTPRel32Value(const MCExpr * Value)2065ffd83dbSDimitry Andric void MCStreamer::emitTPRel32Value(const MCExpr *Value) {
2070b57cec5SDimitry Andric   report_fatal_error("unsupported directive in streamer");
2080b57cec5SDimitry Andric }
2090b57cec5SDimitry Andric 
emitGPRel64Value(const MCExpr * Value)2105ffd83dbSDimitry Andric void MCStreamer::emitGPRel64Value(const MCExpr *Value) {
2110b57cec5SDimitry Andric   report_fatal_error("unsupported directive in streamer");
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric 
emitGPRel32Value(const MCExpr * Value)2145ffd83dbSDimitry Andric void MCStreamer::emitGPRel32Value(const MCExpr *Value) {
2150b57cec5SDimitry Andric   report_fatal_error("unsupported directive in streamer");
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric /// Emit NumBytes bytes worth of the value specified by FillValue.
2190b57cec5SDimitry Andric /// This implements directives such as '.space'.
emitFill(uint64_t NumBytes,uint8_t FillValue)2200b57cec5SDimitry Andric void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
22106c3fb27SDimitry Andric   if (NumBytes)
2220b57cec5SDimitry Andric     emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
2230b57cec5SDimitry Andric }
2240b57cec5SDimitry Andric 
emitNops(int64_t NumBytes,int64_t ControlledNopLen,llvm::SMLoc,const MCSubtargetInfo & STI)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.
emitZeros(uint64_t NumBytes)2295ffd83dbSDimitry Andric void MCStreamer::emitZeros(uint64_t NumBytes) { emitFill(NumBytes, 0); }
2300b57cec5SDimitry Andric 
tryEmitDwarfFileDirective(unsigned FileNo,StringRef Directory,StringRef Filename,std::optional<MD5::MD5Result> Checksum,std::optional<StringRef> Source,unsigned CUID)231bdd1243dSDimitry Andric Expected<unsigned> MCStreamer::tryEmitDwarfFileDirective(
232bdd1243dSDimitry Andric     unsigned FileNo, StringRef Directory, StringRef Filename,
233bdd1243dSDimitry 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 
emitDwarfFile0Directive(StringRef Directory,StringRef Filename,std::optional<MD5::MD5Result> Checksum,std::optional<StringRef> Source,unsigned CUID)2390b57cec5SDimitry Andric void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
2400b57cec5SDimitry Andric                                          StringRef Filename,
241bdd1243dSDimitry Andric                                          std::optional<MD5::MD5Result> Checksum,
242bdd1243dSDimitry Andric                                          std::optional<StringRef> Source,
2430b57cec5SDimitry Andric                                          unsigned CUID) {
2440b57cec5SDimitry Andric   getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
2450b57cec5SDimitry Andric                                       Source);
2460b57cec5SDimitry Andric }
2470b57cec5SDimitry Andric 
emitCFIBKeyFrame()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 
emitCFIMTETaggedFrame()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 
emitDwarfLocDirective(unsigned FileNo,unsigned Line,unsigned Column,unsigned Flags,unsigned Isa,unsigned Discriminator,StringRef FileName)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 
getDwarfLineTableSymbol(unsigned CUID)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 
hasUnfinishedDwarfFrameInfo()2800b57cec5SDimitry Andric bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
28106c3fb27SDimitry Andric   return !FrameInfoStack.empty();
2820b57cec5SDimitry Andric }
2830b57cec5SDimitry Andric 
getCurrentDwarfFrameInfo()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   }
29106c3fb27SDimitry Andric   return &DwarfFrameInfos[FrameInfoStack.back().first];
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric 
emitCVFileDirective(unsigned FileNo,StringRef Filename,ArrayRef<uint8_t> Checksum,unsigned ChecksumKind)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 
emitCVFuncIdDirective(unsigned FunctionId)30181ad6265SDimitry Andric bool MCStreamer::emitCVFuncIdDirective(unsigned FunctionId) {
3020b57cec5SDimitry Andric   return getContext().getCVContext().recordFunctionId(FunctionId);
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric 
emitCVInlineSiteIdDirective(unsigned FunctionId,unsigned IAFunc,unsigned IAFile,unsigned IALine,unsigned IACol,SMLoc Loc)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 
emitCVLocDirective(unsigned FunctionId,unsigned FileNo,unsigned Line,unsigned Column,bool PrologueEnd,bool IsStmt,StringRef FileName,SMLoc Loc)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 
checkCVLocSection(unsigned FuncId,unsigned FileNo,SMLoc Loc)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 
emitCVLinetableDirective(unsigned FunctionId,const MCSymbol * Begin,const MCSymbol * End)3465ffd83dbSDimitry Andric void MCStreamer::emitCVLinetableDirective(unsigned FunctionId,
3470b57cec5SDimitry Andric                                           const MCSymbol *Begin,
3480b57cec5SDimitry Andric                                           const MCSymbol *End) {}
3490b57cec5SDimitry Andric 
emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,unsigned SourceFileId,unsigned SourceLineNum,const MCSymbol * FnStartSym,const MCSymbol * FnEndSym)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>
copyBytesForDefRange(SmallString<20> & BytePrefix,codeview::SymbolKind SymKind,const T & DefRangeHeader)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 
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,StringRef FixedSizePortion)3685ffd83dbSDimitry Andric void MCStreamer::emitCVDefRangeDirective(
3690b57cec5SDimitry Andric     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
3700b57cec5SDimitry Andric     StringRef FixedSizePortion) {}
3710b57cec5SDimitry Andric 
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeRegisterRelHeader DRHdr)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 
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeSubfieldRegisterHeader DRHdr)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 
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeRegisterHeader DRHdr)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 
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeFramePointerRelHeader DRHdr)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 
emitEHSymAttributes(const MCSymbol * Symbol,MCSymbol * EHSymbol)4065ffd83dbSDimitry Andric void MCStreamer::emitEHSymAttributes(const MCSymbol *Symbol,
4070b57cec5SDimitry Andric                                      MCSymbol *EHSymbol) {
4080b57cec5SDimitry Andric }
4090b57cec5SDimitry Andric 
initSections(bool NoExecStack,const MCSubtargetInfo & STI)410349cc55cSDimitry Andric void MCStreamer::initSections(bool NoExecStack, const MCSubtargetInfo &STI) {
41181ad6265SDimitry Andric   switchSection(getContext().getObjectFileInfo()->getTextSection());
4120b57cec5SDimitry Andric }
4130b57cec5SDimitry Andric 
emitLabel(MCSymbol * Symbol,SMLoc Loc)4145ffd83dbSDimitry Andric void MCStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
4150b57cec5SDimitry Andric   Symbol->redefineIfPossible();
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric   if (!Symbol->isUndefined() || Symbol->isVariable())
418fe6060f1SDimitry Andric     return getContext().reportError(Loc, "symbol '" + Twine(Symbol->getName()) +
419fe6060f1SDimitry Andric                                              "' is already defined");
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric   assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
4220b57cec5SDimitry Andric   assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
4230b57cec5SDimitry Andric   assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
4240b57cec5SDimitry Andric   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric   Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric   MCTargetStreamer *TS = getTargetStreamer();
4290b57cec5SDimitry Andric   if (TS)
4300b57cec5SDimitry Andric     TS->emitLabel(Symbol);
4310b57cec5SDimitry Andric }
4320b57cec5SDimitry Andric 
emitConditionalAssignment(MCSymbol * Symbol,const MCExpr * Value)4330eae32dcSDimitry Andric void MCStreamer::emitConditionalAssignment(MCSymbol *Symbol,
4340eae32dcSDimitry Andric                                            const MCExpr *Value) {}
4350eae32dcSDimitry Andric 
emitCFISections(bool EH,bool Debug)436fe6060f1SDimitry Andric void MCStreamer::emitCFISections(bool EH, bool Debug) {}
4370b57cec5SDimitry Andric 
emitCFIStartProc(bool IsSimple,SMLoc Loc)4385ffd83dbSDimitry Andric void MCStreamer::emitCFIStartProc(bool IsSimple, SMLoc Loc) {
43906c3fb27SDimitry Andric   if (!FrameInfoStack.empty() &&
44006c3fb27SDimitry Andric       getCurrentSectionOnly() == FrameInfoStack.back().second)
4410b57cec5SDimitry Andric     return getContext().reportError(
4420b57cec5SDimitry Andric         Loc, "starting new .cfi frame before finishing the previous one");
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric   MCDwarfFrameInfo Frame;
4450b57cec5SDimitry Andric   Frame.IsSimple = IsSimple;
4465ffd83dbSDimitry Andric   emitCFIStartProcImpl(Frame);
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric   const MCAsmInfo* MAI = Context.getAsmInfo();
4490b57cec5SDimitry Andric   if (MAI) {
4500b57cec5SDimitry Andric     for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
4510b57cec5SDimitry Andric       if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
452fe6060f1SDimitry Andric           Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister ||
453fe6060f1SDimitry Andric           Inst.getOperation() == MCCFIInstruction::OpLLVMDefAspaceCfa) {
4540b57cec5SDimitry Andric         Frame.CurrentCfaRegister = Inst.getRegister();
4550b57cec5SDimitry Andric       }
4560b57cec5SDimitry Andric     }
4570b57cec5SDimitry Andric   }
4580b57cec5SDimitry Andric 
45906c3fb27SDimitry Andric   FrameInfoStack.emplace_back(DwarfFrameInfos.size(), getCurrentSectionOnly());
4600b57cec5SDimitry Andric   DwarfFrameInfos.push_back(Frame);
4610b57cec5SDimitry Andric }
4620b57cec5SDimitry Andric 
emitCFIStartProcImpl(MCDwarfFrameInfo & Frame)4635ffd83dbSDimitry Andric void MCStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
4640b57cec5SDimitry Andric }
4650b57cec5SDimitry Andric 
emitCFIEndProc()4665ffd83dbSDimitry Andric void MCStreamer::emitCFIEndProc() {
4670b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
4680b57cec5SDimitry Andric   if (!CurFrame)
4690b57cec5SDimitry Andric     return;
4705ffd83dbSDimitry Andric   emitCFIEndProcImpl(*CurFrame);
47106c3fb27SDimitry Andric   FrameInfoStack.pop_back();
4720b57cec5SDimitry Andric }
4730b57cec5SDimitry Andric 
emitCFIEndProcImpl(MCDwarfFrameInfo & Frame)4745ffd83dbSDimitry Andric void MCStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
4750b57cec5SDimitry Andric   // Put a dummy non-null value in Frame.End to mark that this frame has been
4760b57cec5SDimitry Andric   // closed.
4770b57cec5SDimitry Andric   Frame.End = (MCSymbol *)1;
4780b57cec5SDimitry Andric }
4790b57cec5SDimitry Andric 
emitCFILabel()4805ffd83dbSDimitry Andric MCSymbol *MCStreamer::emitCFILabel() {
4810b57cec5SDimitry Andric   // Return a dummy non-null value so that label fields appear filled in when
4820b57cec5SDimitry Andric   // generating textual assembly.
4830b57cec5SDimitry Andric   return (MCSymbol *)1;
4840b57cec5SDimitry Andric }
4850b57cec5SDimitry Andric 
emitCFIDefCfa(int64_t Register,int64_t Offset,SMLoc Loc)48606c3fb27SDimitry Andric void MCStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) {
4875ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
4880b57cec5SDimitry Andric   MCCFIInstruction Instruction =
48906c3fb27SDimitry Andric       MCCFIInstruction::cfiDefCfa(Label, Register, Offset, Loc);
4900b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
4910b57cec5SDimitry Andric   if (!CurFrame)
4920b57cec5SDimitry Andric     return;
4930b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
4940b57cec5SDimitry Andric   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
4950b57cec5SDimitry Andric }
4960b57cec5SDimitry Andric 
emitCFIDefCfaOffset(int64_t Offset,SMLoc Loc)49706c3fb27SDimitry Andric void MCStreamer::emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) {
4985ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
4990b57cec5SDimitry Andric   MCCFIInstruction Instruction =
5005ffd83dbSDimitry Andric       MCCFIInstruction::cfiDefCfaOffset(Label, Offset);
5010b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5020b57cec5SDimitry Andric   if (!CurFrame)
5030b57cec5SDimitry Andric     return;
5040b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5050b57cec5SDimitry Andric }
5060b57cec5SDimitry Andric 
emitCFIAdjustCfaOffset(int64_t Adjustment,SMLoc Loc)50706c3fb27SDimitry Andric void MCStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) {
5085ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
5090b57cec5SDimitry Andric   MCCFIInstruction Instruction =
51006c3fb27SDimitry Andric       MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment, Loc);
5110b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5120b57cec5SDimitry Andric   if (!CurFrame)
5130b57cec5SDimitry Andric     return;
5140b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5150b57cec5SDimitry Andric }
5160b57cec5SDimitry Andric 
emitCFIDefCfaRegister(int64_t Register,SMLoc Loc)51706c3fb27SDimitry Andric void MCStreamer::emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) {
5185ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
5190b57cec5SDimitry Andric   MCCFIInstruction Instruction =
52006c3fb27SDimitry Andric       MCCFIInstruction::createDefCfaRegister(Label, Register, Loc);
5210b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5220b57cec5SDimitry Andric   if (!CurFrame)
5230b57cec5SDimitry Andric     return;
5240b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5250b57cec5SDimitry Andric   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
5260b57cec5SDimitry Andric }
5270b57cec5SDimitry Andric 
emitCFILLVMDefAspaceCfa(int64_t Register,int64_t Offset,int64_t AddressSpace,SMLoc Loc)528fe6060f1SDimitry Andric void MCStreamer::emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
52906c3fb27SDimitry Andric                                          int64_t AddressSpace, SMLoc Loc) {
530fe6060f1SDimitry Andric   MCSymbol *Label = emitCFILabel();
531fe6060f1SDimitry Andric   MCCFIInstruction Instruction = MCCFIInstruction::createLLVMDefAspaceCfa(
53206c3fb27SDimitry Andric       Label, Register, Offset, AddressSpace, Loc);
533fe6060f1SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
534fe6060f1SDimitry Andric   if (!CurFrame)
535fe6060f1SDimitry Andric     return;
536fe6060f1SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
537fe6060f1SDimitry Andric   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
538fe6060f1SDimitry Andric }
539fe6060f1SDimitry Andric 
emitCFIOffset(int64_t Register,int64_t Offset,SMLoc Loc)54006c3fb27SDimitry Andric void MCStreamer::emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
5415ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
5420b57cec5SDimitry Andric   MCCFIInstruction Instruction =
54306c3fb27SDimitry Andric       MCCFIInstruction::createOffset(Label, Register, Offset, Loc);
5440b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5450b57cec5SDimitry Andric   if (!CurFrame)
5460b57cec5SDimitry Andric     return;
5470b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5480b57cec5SDimitry Andric }
5490b57cec5SDimitry Andric 
emitCFIRelOffset(int64_t Register,int64_t Offset,SMLoc Loc)55006c3fb27SDimitry Andric void MCStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
5515ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
5520b57cec5SDimitry Andric   MCCFIInstruction Instruction =
55306c3fb27SDimitry Andric       MCCFIInstruction::createRelOffset(Label, Register, Offset, Loc);
5540b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5550b57cec5SDimitry Andric   if (!CurFrame)
5560b57cec5SDimitry Andric     return;
5570b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5580b57cec5SDimitry Andric }
5590b57cec5SDimitry Andric 
emitCFIPersonality(const MCSymbol * Sym,unsigned Encoding)5605ffd83dbSDimitry Andric void MCStreamer::emitCFIPersonality(const MCSymbol *Sym,
5610b57cec5SDimitry Andric                                     unsigned Encoding) {
5620b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5630b57cec5SDimitry Andric   if (!CurFrame)
5640b57cec5SDimitry Andric     return;
5650b57cec5SDimitry Andric   CurFrame->Personality = Sym;
5660b57cec5SDimitry Andric   CurFrame->PersonalityEncoding = Encoding;
5670b57cec5SDimitry Andric }
5680b57cec5SDimitry Andric 
emitCFILsda(const MCSymbol * Sym,unsigned Encoding)5695ffd83dbSDimitry Andric void MCStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
5700b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5710b57cec5SDimitry Andric   if (!CurFrame)
5720b57cec5SDimitry Andric     return;
5730b57cec5SDimitry Andric   CurFrame->Lsda = Sym;
5740b57cec5SDimitry Andric   CurFrame->LsdaEncoding = Encoding;
5750b57cec5SDimitry Andric }
5760b57cec5SDimitry Andric 
emitCFIRememberState(SMLoc Loc)57706c3fb27SDimitry Andric void MCStreamer::emitCFIRememberState(SMLoc Loc) {
5785ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
57906c3fb27SDimitry Andric   MCCFIInstruction Instruction =
58006c3fb27SDimitry Andric       MCCFIInstruction::createRememberState(Label, Loc);
5810b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5820b57cec5SDimitry Andric   if (!CurFrame)
5830b57cec5SDimitry Andric     return;
5840b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5850b57cec5SDimitry Andric }
5860b57cec5SDimitry Andric 
emitCFIRestoreState(SMLoc Loc)58706c3fb27SDimitry Andric void MCStreamer::emitCFIRestoreState(SMLoc Loc) {
5880b57cec5SDimitry Andric   // FIXME: Error if there is no matching cfi_remember_state.
5895ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
59006c3fb27SDimitry Andric   MCCFIInstruction Instruction =
59106c3fb27SDimitry Andric       MCCFIInstruction::createRestoreState(Label, Loc);
5920b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
5930b57cec5SDimitry Andric   if (!CurFrame)
5940b57cec5SDimitry Andric     return;
5950b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
5960b57cec5SDimitry Andric }
5970b57cec5SDimitry Andric 
emitCFISameValue(int64_t Register,SMLoc Loc)59806c3fb27SDimitry Andric void MCStreamer::emitCFISameValue(int64_t Register, SMLoc Loc) {
5995ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6000b57cec5SDimitry Andric   MCCFIInstruction Instruction =
60106c3fb27SDimitry Andric       MCCFIInstruction::createSameValue(Label, Register, Loc);
6020b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6030b57cec5SDimitry Andric   if (!CurFrame)
6040b57cec5SDimitry Andric     return;
6050b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6060b57cec5SDimitry Andric }
6070b57cec5SDimitry Andric 
emitCFIRestore(int64_t Register,SMLoc Loc)60806c3fb27SDimitry Andric void MCStreamer::emitCFIRestore(int64_t Register, SMLoc Loc) {
6095ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6100b57cec5SDimitry Andric   MCCFIInstruction Instruction =
61106c3fb27SDimitry Andric       MCCFIInstruction::createRestore(Label, Register, Loc);
6120b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6130b57cec5SDimitry Andric   if (!CurFrame)
6140b57cec5SDimitry Andric     return;
6150b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6160b57cec5SDimitry Andric }
6170b57cec5SDimitry Andric 
emitCFIEscape(StringRef Values,SMLoc Loc)61806c3fb27SDimitry Andric void MCStreamer::emitCFIEscape(StringRef Values, SMLoc Loc) {
6195ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6200b57cec5SDimitry Andric   MCCFIInstruction Instruction =
62106c3fb27SDimitry Andric       MCCFIInstruction::createEscape(Label, Values, Loc, "");
62206c3fb27SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
62306c3fb27SDimitry Andric   if (!CurFrame)
62406c3fb27SDimitry Andric     return;
62506c3fb27SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
62606c3fb27SDimitry Andric }
62706c3fb27SDimitry Andric 
emitCFIGnuArgsSize(int64_t Size,SMLoc Loc)62806c3fb27SDimitry Andric void MCStreamer::emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) {
62906c3fb27SDimitry Andric   MCSymbol *Label = emitCFILabel();
63006c3fb27SDimitry Andric   MCCFIInstruction Instruction =
63106c3fb27SDimitry Andric       MCCFIInstruction::createGnuArgsSize(Label, Size, Loc);
6320b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6330b57cec5SDimitry Andric   if (!CurFrame)
6340b57cec5SDimitry Andric     return;
6350b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6360b57cec5SDimitry Andric }
6370b57cec5SDimitry Andric 
emitCFISignalFrame()6385ffd83dbSDimitry Andric void MCStreamer::emitCFISignalFrame() {
6390b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6400b57cec5SDimitry Andric   if (!CurFrame)
6410b57cec5SDimitry Andric     return;
6420b57cec5SDimitry Andric   CurFrame->IsSignalFrame = true;
6430b57cec5SDimitry Andric }
6440b57cec5SDimitry Andric 
emitCFIUndefined(int64_t Register,SMLoc Loc)64506c3fb27SDimitry Andric void MCStreamer::emitCFIUndefined(int64_t Register, SMLoc Loc) {
6465ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6470b57cec5SDimitry Andric   MCCFIInstruction Instruction =
64806c3fb27SDimitry Andric       MCCFIInstruction::createUndefined(Label, Register, Loc);
6490b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6500b57cec5SDimitry Andric   if (!CurFrame)
6510b57cec5SDimitry Andric     return;
6520b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6530b57cec5SDimitry Andric }
6540b57cec5SDimitry Andric 
emitCFIRegister(int64_t Register1,int64_t Register2,SMLoc Loc)65506c3fb27SDimitry Andric void MCStreamer::emitCFIRegister(int64_t Register1, int64_t Register2,
65606c3fb27SDimitry Andric                                  SMLoc Loc) {
6575ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
6580b57cec5SDimitry Andric   MCCFIInstruction Instruction =
65906c3fb27SDimitry Andric       MCCFIInstruction::createRegister(Label, Register1, Register2, Loc);
6600b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6610b57cec5SDimitry Andric   if (!CurFrame)
6620b57cec5SDimitry Andric     return;
6630b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6640b57cec5SDimitry Andric }
6650b57cec5SDimitry Andric 
emitCFIWindowSave(SMLoc Loc)66606c3fb27SDimitry Andric void MCStreamer::emitCFIWindowSave(SMLoc Loc) {
6675ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
66806c3fb27SDimitry Andric   MCCFIInstruction Instruction = MCCFIInstruction::createWindowSave(Label, Loc);
6690b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6700b57cec5SDimitry Andric   if (!CurFrame)
6710b57cec5SDimitry Andric     return;
6720b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6730b57cec5SDimitry Andric }
6740b57cec5SDimitry Andric 
emitCFINegateRAState(SMLoc Loc)67506c3fb27SDimitry Andric void MCStreamer::emitCFINegateRAState(SMLoc Loc) {
6765ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
67706c3fb27SDimitry Andric   MCCFIInstruction Instruction =
67806c3fb27SDimitry Andric       MCCFIInstruction::createNegateRAState(Label, Loc);
6790b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6800b57cec5SDimitry Andric   if (!CurFrame)
6810b57cec5SDimitry Andric     return;
6820b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Instruction);
6830b57cec5SDimitry Andric }
6840b57cec5SDimitry Andric 
emitCFIReturnColumn(int64_t Register)6855ffd83dbSDimitry Andric void MCStreamer::emitCFIReturnColumn(int64_t Register) {
6860b57cec5SDimitry Andric   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
6870b57cec5SDimitry Andric   if (!CurFrame)
6880b57cec5SDimitry Andric     return;
6890b57cec5SDimitry Andric   CurFrame->RAReg = Register;
6900b57cec5SDimitry Andric }
6910b57cec5SDimitry Andric 
emitCFILabelDirective(SMLoc Loc,StringRef Name)692*0fca6ea1SDimitry Andric void MCStreamer::emitCFILabelDirective(SMLoc Loc, StringRef Name) {
693*0fca6ea1SDimitry Andric   MCSymbol *Label = emitCFILabel();
694*0fca6ea1SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
695*0fca6ea1SDimitry Andric   if (MCDwarfFrameInfo *F = getCurrentDwarfFrameInfo())
696*0fca6ea1SDimitry Andric     F->Instructions.push_back(MCCFIInstruction::createLabel(Label, Sym, Loc));
697*0fca6ea1SDimitry Andric }
698*0fca6ea1SDimitry Andric 
EnsureValidWinFrameInfo(SMLoc Loc)6990b57cec5SDimitry Andric WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
7000b57cec5SDimitry Andric   const MCAsmInfo *MAI = Context.getAsmInfo();
7010b57cec5SDimitry Andric   if (!MAI->usesWindowsCFI()) {
7020b57cec5SDimitry Andric     getContext().reportError(
7030b57cec5SDimitry Andric         Loc, ".seh_* directives are not supported on this target");
7040b57cec5SDimitry Andric     return nullptr;
7050b57cec5SDimitry Andric   }
7060b57cec5SDimitry Andric   if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
7070b57cec5SDimitry Andric     getContext().reportError(
7080b57cec5SDimitry Andric         Loc, ".seh_ directive must appear within an active frame");
7090b57cec5SDimitry Andric     return nullptr;
7100b57cec5SDimitry Andric   }
7110b57cec5SDimitry Andric   return CurrentWinFrameInfo;
7120b57cec5SDimitry Andric }
7130b57cec5SDimitry Andric 
emitWinCFIStartProc(const MCSymbol * Symbol,SMLoc Loc)71481ad6265SDimitry Andric void MCStreamer::emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
7150b57cec5SDimitry Andric   const MCAsmInfo *MAI = Context.getAsmInfo();
7160b57cec5SDimitry Andric   if (!MAI->usesWindowsCFI())
7170b57cec5SDimitry Andric     return getContext().reportError(
7180b57cec5SDimitry Andric         Loc, ".seh_* directives are not supported on this target");
7190b57cec5SDimitry Andric   if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
7200b57cec5SDimitry Andric     getContext().reportError(
7210b57cec5SDimitry Andric         Loc, "Starting a function before ending the previous one!");
7220b57cec5SDimitry Andric 
7235ffd83dbSDimitry Andric   MCSymbol *StartProc = emitCFILabel();
7240b57cec5SDimitry Andric 
725e8d8bef9SDimitry Andric   CurrentProcWinFrameInfoStartIndex = WinFrameInfos.size();
7260b57cec5SDimitry Andric   WinFrameInfos.emplace_back(
7278bcb0991SDimitry Andric       std::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
7280b57cec5SDimitry Andric   CurrentWinFrameInfo = WinFrameInfos.back().get();
7290b57cec5SDimitry Andric   CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
7300b57cec5SDimitry Andric }
7310b57cec5SDimitry Andric 
emitWinCFIEndProc(SMLoc Loc)73281ad6265SDimitry Andric void MCStreamer::emitWinCFIEndProc(SMLoc Loc) {
7330b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
7340b57cec5SDimitry Andric   if (!CurFrame)
7350b57cec5SDimitry Andric     return;
7360b57cec5SDimitry Andric   if (CurFrame->ChainedParent)
7370b57cec5SDimitry Andric     getContext().reportError(Loc, "Not all chained regions terminated!");
7380b57cec5SDimitry Andric 
7395ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
7400b57cec5SDimitry Andric   CurFrame->End = Label;
741e8d8bef9SDimitry Andric   if (!CurFrame->FuncletOrFuncEnd)
742e8d8bef9SDimitry Andric     CurFrame->FuncletOrFuncEnd = CurFrame->End;
743e8d8bef9SDimitry Andric 
744e8d8bef9SDimitry Andric   for (size_t I = CurrentProcWinFrameInfoStartIndex, E = WinFrameInfos.size();
745e8d8bef9SDimitry Andric        I != E; ++I)
74681ad6265SDimitry Andric     emitWindowsUnwindTables(WinFrameInfos[I].get());
74781ad6265SDimitry Andric   switchSection(CurFrame->TextSection);
7480b57cec5SDimitry Andric }
7490b57cec5SDimitry Andric 
emitWinCFIFuncletOrFuncEnd(SMLoc Loc)75081ad6265SDimitry Andric void MCStreamer::emitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
7510b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
7520b57cec5SDimitry Andric   if (!CurFrame)
7530b57cec5SDimitry Andric     return;
7540b57cec5SDimitry Andric   if (CurFrame->ChainedParent)
7550b57cec5SDimitry Andric     getContext().reportError(Loc, "Not all chained regions terminated!");
7560b57cec5SDimitry Andric 
7575ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
7580b57cec5SDimitry Andric   CurFrame->FuncletOrFuncEnd = Label;
7590b57cec5SDimitry Andric }
7600b57cec5SDimitry Andric 
emitWinCFIStartChained(SMLoc Loc)76181ad6265SDimitry Andric void MCStreamer::emitWinCFIStartChained(SMLoc Loc) {
7620b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
7630b57cec5SDimitry Andric   if (!CurFrame)
7640b57cec5SDimitry Andric     return;
7650b57cec5SDimitry Andric 
7665ffd83dbSDimitry Andric   MCSymbol *StartProc = emitCFILabel();
7670b57cec5SDimitry Andric 
7688bcb0991SDimitry Andric   WinFrameInfos.emplace_back(std::make_unique<WinEH::FrameInfo>(
7690b57cec5SDimitry Andric       CurFrame->Function, StartProc, CurFrame));
7700b57cec5SDimitry Andric   CurrentWinFrameInfo = WinFrameInfos.back().get();
7710b57cec5SDimitry Andric   CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
7720b57cec5SDimitry Andric }
7730b57cec5SDimitry Andric 
emitWinCFIEndChained(SMLoc Loc)77481ad6265SDimitry Andric void MCStreamer::emitWinCFIEndChained(SMLoc Loc) {
7750b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
7760b57cec5SDimitry Andric   if (!CurFrame)
7770b57cec5SDimitry Andric     return;
7780b57cec5SDimitry Andric   if (!CurFrame->ChainedParent)
7790b57cec5SDimitry Andric     return getContext().reportError(
7800b57cec5SDimitry Andric         Loc, "End of a chained region outside a chained region!");
7810b57cec5SDimitry Andric 
7825ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
7830b57cec5SDimitry Andric 
7840b57cec5SDimitry Andric   CurFrame->End = Label;
7850b57cec5SDimitry Andric   CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
7860b57cec5SDimitry Andric }
7870b57cec5SDimitry Andric 
emitWinEHHandler(const MCSymbol * Sym,bool Unwind,bool Except,SMLoc Loc)78881ad6265SDimitry Andric void MCStreamer::emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
7890b57cec5SDimitry Andric                                   SMLoc Loc) {
7900b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
7910b57cec5SDimitry Andric   if (!CurFrame)
7920b57cec5SDimitry Andric     return;
7930b57cec5SDimitry Andric   if (CurFrame->ChainedParent)
7940b57cec5SDimitry Andric     return getContext().reportError(
7950b57cec5SDimitry Andric         Loc, "Chained unwind areas can't have handlers!");
7960b57cec5SDimitry Andric   CurFrame->ExceptionHandler = Sym;
7970b57cec5SDimitry Andric   if (!Except && !Unwind)
7980b57cec5SDimitry Andric     getContext().reportError(Loc, "Don't know what kind of handler this is!");
7990b57cec5SDimitry Andric   if (Unwind)
8000b57cec5SDimitry Andric     CurFrame->HandlesUnwind = true;
8010b57cec5SDimitry Andric   if (Except)
8020b57cec5SDimitry Andric     CurFrame->HandlesExceptions = true;
8030b57cec5SDimitry Andric }
8040b57cec5SDimitry Andric 
emitWinEHHandlerData(SMLoc Loc)80581ad6265SDimitry Andric void MCStreamer::emitWinEHHandlerData(SMLoc Loc) {
8060b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
8070b57cec5SDimitry Andric   if (!CurFrame)
8080b57cec5SDimitry Andric     return;
8090b57cec5SDimitry Andric   if (CurFrame->ChainedParent)
8100b57cec5SDimitry Andric     getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
8110b57cec5SDimitry Andric }
8120b57cec5SDimitry Andric 
emitCGProfileEntry(const MCSymbolRefExpr * From,const MCSymbolRefExpr * To,uint64_t Count)8130b57cec5SDimitry Andric void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
8140b57cec5SDimitry Andric                                     const MCSymbolRefExpr *To, uint64_t Count) {
8150b57cec5SDimitry Andric }
8160b57cec5SDimitry Andric 
getWinCFISection(MCContext & Context,unsigned * NextWinCFIID,MCSection * MainCFISec,const MCSection * TextSec)8170b57cec5SDimitry Andric static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
8180b57cec5SDimitry Andric                                    MCSection *MainCFISec,
8190b57cec5SDimitry Andric                                    const MCSection *TextSec) {
8200b57cec5SDimitry Andric   // If this is the main .text section, use the main unwind info section.
8210b57cec5SDimitry Andric   if (TextSec == Context.getObjectFileInfo()->getTextSection())
8220b57cec5SDimitry Andric     return MainCFISec;
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric   const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
8250b57cec5SDimitry Andric   auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
8260b57cec5SDimitry Andric   unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
8270b57cec5SDimitry Andric 
8280b57cec5SDimitry Andric   // If this section is COMDAT, this unwind section should be COMDAT associative
8290b57cec5SDimitry Andric   // with its group.
8300b57cec5SDimitry Andric   const MCSymbol *KeySym = nullptr;
8310b57cec5SDimitry Andric   if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
8320b57cec5SDimitry Andric     KeySym = TextSecCOFF->getCOMDATSymbol();
8330b57cec5SDimitry Andric 
8340b57cec5SDimitry Andric     // In a GNU environment, we can't use associative comdats. Instead, do what
8350b57cec5SDimitry Andric     // GCC does, which is to make plain comdat selectany section named like
8360b57cec5SDimitry Andric     // ".[px]data$_Z3foov".
8370b57cec5SDimitry Andric     if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
8385ffd83dbSDimitry Andric       std::string SectionName = (MainCFISecCOFF->getName() + "$" +
8395ffd83dbSDimitry Andric                                  TextSecCOFF->getName().split('$').second)
8400b57cec5SDimitry Andric                                     .str();
841*0fca6ea1SDimitry Andric       return Context.getCOFFSection(SectionName,
842*0fca6ea1SDimitry Andric                                     MainCFISecCOFF->getCharacteristics() |
843*0fca6ea1SDimitry Andric                                         COFF::IMAGE_SCN_LNK_COMDAT,
844*0fca6ea1SDimitry Andric                                     "", COFF::IMAGE_COMDAT_SELECT_ANY);
8450b57cec5SDimitry Andric     }
8460b57cec5SDimitry Andric   }
8470b57cec5SDimitry Andric 
8480b57cec5SDimitry Andric   return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
8490b57cec5SDimitry Andric }
8500b57cec5SDimitry Andric 
getAssociatedPDataSection(const MCSection * TextSec)8510b57cec5SDimitry Andric MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
8520b57cec5SDimitry Andric   return getWinCFISection(getContext(), &NextWinCFIID,
8530b57cec5SDimitry Andric                           getContext().getObjectFileInfo()->getPDataSection(),
8540b57cec5SDimitry Andric                           TextSec);
8550b57cec5SDimitry Andric }
8560b57cec5SDimitry Andric 
getAssociatedXDataSection(const MCSection * TextSec)8570b57cec5SDimitry Andric MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
8580b57cec5SDimitry Andric   return getWinCFISection(getContext(), &NextWinCFIID,
8590b57cec5SDimitry Andric                           getContext().getObjectFileInfo()->getXDataSection(),
8600b57cec5SDimitry Andric                           TextSec);
8610b57cec5SDimitry Andric }
8620b57cec5SDimitry Andric 
emitSyntaxDirective()8635ffd83dbSDimitry Andric void MCStreamer::emitSyntaxDirective() {}
8640b57cec5SDimitry Andric 
encodeSEHRegNum(MCContext & Ctx,MCRegister Reg)8658bcb0991SDimitry Andric static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
8668bcb0991SDimitry Andric   return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
8678bcb0991SDimitry Andric }
8688bcb0991SDimitry Andric 
emitWinCFIPushReg(MCRegister Register,SMLoc Loc)86981ad6265SDimitry Andric void MCStreamer::emitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
8700b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
8710b57cec5SDimitry Andric   if (!CurFrame)
8720b57cec5SDimitry Andric     return;
8730b57cec5SDimitry Andric 
8745ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
8750b57cec5SDimitry Andric 
8768bcb0991SDimitry Andric   WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(
8778bcb0991SDimitry Andric       Label, encodeSEHRegNum(Context, Register));
8780b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Inst);
8790b57cec5SDimitry Andric }
8800b57cec5SDimitry Andric 
emitWinCFISetFrame(MCRegister Register,unsigned Offset,SMLoc Loc)88181ad6265SDimitry Andric void MCStreamer::emitWinCFISetFrame(MCRegister Register, unsigned Offset,
8820b57cec5SDimitry Andric                                     SMLoc Loc) {
8830b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
8840b57cec5SDimitry Andric   if (!CurFrame)
8850b57cec5SDimitry Andric     return;
8860b57cec5SDimitry Andric   if (CurFrame->LastFrameInst >= 0)
8870b57cec5SDimitry Andric     return getContext().reportError(
8880b57cec5SDimitry Andric         Loc, "frame register and offset can be set at most once");
8890b57cec5SDimitry Andric   if (Offset & 0x0F)
8900b57cec5SDimitry Andric     return getContext().reportError(Loc, "offset is not a multiple of 16");
8910b57cec5SDimitry Andric   if (Offset > 240)
8920b57cec5SDimitry Andric     return getContext().reportError(
8930b57cec5SDimitry Andric         Loc, "frame offset must be less than or equal to 240");
8940b57cec5SDimitry Andric 
8955ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
8960b57cec5SDimitry Andric 
8978bcb0991SDimitry Andric   WinEH::Instruction Inst = Win64EH::Instruction::SetFPReg(
8988bcb0991SDimitry Andric       Label, encodeSEHRegNum(getContext(), Register), Offset);
8990b57cec5SDimitry Andric   CurFrame->LastFrameInst = CurFrame->Instructions.size();
9000b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Inst);
9010b57cec5SDimitry Andric }
9020b57cec5SDimitry Andric 
emitWinCFIAllocStack(unsigned Size,SMLoc Loc)90381ad6265SDimitry Andric void MCStreamer::emitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
9040b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
9050b57cec5SDimitry Andric   if (!CurFrame)
9060b57cec5SDimitry Andric     return;
9070b57cec5SDimitry Andric   if (Size == 0)
9080b57cec5SDimitry Andric     return getContext().reportError(Loc,
9090b57cec5SDimitry Andric                                     "stack allocation size must be non-zero");
9100b57cec5SDimitry Andric   if (Size & 7)
9110b57cec5SDimitry Andric     return getContext().reportError(
9120b57cec5SDimitry Andric         Loc, "stack allocation size is not a multiple of 8");
9130b57cec5SDimitry Andric 
9145ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric   WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
9170b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Inst);
9180b57cec5SDimitry Andric }
9190b57cec5SDimitry Andric 
emitWinCFISaveReg(MCRegister Register,unsigned Offset,SMLoc Loc)92081ad6265SDimitry Andric void MCStreamer::emitWinCFISaveReg(MCRegister Register, unsigned Offset,
9210b57cec5SDimitry Andric                                    SMLoc Loc) {
9220b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
9230b57cec5SDimitry Andric   if (!CurFrame)
9240b57cec5SDimitry Andric     return;
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric   if (Offset & 7)
9270b57cec5SDimitry Andric     return getContext().reportError(
9280b57cec5SDimitry Andric         Loc, "register save offset is not 8 byte aligned");
9290b57cec5SDimitry Andric 
9305ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
9310b57cec5SDimitry Andric 
9328bcb0991SDimitry Andric   WinEH::Instruction Inst = Win64EH::Instruction::SaveNonVol(
9338bcb0991SDimitry Andric       Label, encodeSEHRegNum(Context, Register), Offset);
9340b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Inst);
9350b57cec5SDimitry Andric }
9360b57cec5SDimitry Andric 
emitWinCFISaveXMM(MCRegister Register,unsigned Offset,SMLoc Loc)93781ad6265SDimitry Andric void MCStreamer::emitWinCFISaveXMM(MCRegister Register, unsigned Offset,
9380b57cec5SDimitry Andric                                    SMLoc Loc) {
9390b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
9400b57cec5SDimitry Andric   if (!CurFrame)
9410b57cec5SDimitry Andric     return;
9420b57cec5SDimitry Andric   if (Offset & 0x0F)
9430b57cec5SDimitry Andric     return getContext().reportError(Loc, "offset is not a multiple of 16");
9440b57cec5SDimitry Andric 
9455ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
9460b57cec5SDimitry Andric 
9478bcb0991SDimitry Andric   WinEH::Instruction Inst = Win64EH::Instruction::SaveXMM(
9488bcb0991SDimitry Andric       Label, encodeSEHRegNum(Context, Register), Offset);
9490b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Inst);
9500b57cec5SDimitry Andric }
9510b57cec5SDimitry Andric 
emitWinCFIPushFrame(bool Code,SMLoc Loc)95281ad6265SDimitry Andric void MCStreamer::emitWinCFIPushFrame(bool Code, SMLoc Loc) {
9530b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
9540b57cec5SDimitry Andric   if (!CurFrame)
9550b57cec5SDimitry Andric     return;
9560b57cec5SDimitry Andric   if (!CurFrame->Instructions.empty())
9570b57cec5SDimitry Andric     return getContext().reportError(
9580b57cec5SDimitry Andric         Loc, "If present, PushMachFrame must be the first UOP");
9590b57cec5SDimitry Andric 
9605ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric   WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
9630b57cec5SDimitry Andric   CurFrame->Instructions.push_back(Inst);
9640b57cec5SDimitry Andric }
9650b57cec5SDimitry Andric 
emitWinCFIEndProlog(SMLoc Loc)96681ad6265SDimitry Andric void MCStreamer::emitWinCFIEndProlog(SMLoc Loc) {
9670b57cec5SDimitry Andric   WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
9680b57cec5SDimitry Andric   if (!CurFrame)
9690b57cec5SDimitry Andric     return;
9700b57cec5SDimitry Andric 
9715ffd83dbSDimitry Andric   MCSymbol *Label = emitCFILabel();
9720b57cec5SDimitry Andric 
9730b57cec5SDimitry Andric   CurFrame->PrologEnd = Label;
9740b57cec5SDimitry Andric }
9750b57cec5SDimitry Andric 
emitCOFFSafeSEH(MCSymbol const * Symbol)97681ad6265SDimitry Andric void MCStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {}
9770b57cec5SDimitry Andric 
emitCOFFSymbolIndex(MCSymbol const * Symbol)97881ad6265SDimitry Andric void MCStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {}
9790b57cec5SDimitry Andric 
emitCOFFSectionIndex(MCSymbol const * Symbol)98081ad6265SDimitry Andric void MCStreamer::emitCOFFSectionIndex(MCSymbol const *Symbol) {}
9810b57cec5SDimitry Andric 
emitCOFFSecRel32(MCSymbol const * Symbol,uint64_t Offset)98281ad6265SDimitry Andric void MCStreamer::emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
9830b57cec5SDimitry Andric 
emitCOFFImgRel32(MCSymbol const * Symbol,int64_t Offset)98481ad6265SDimitry Andric void MCStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
9850b57cec5SDimitry Andric 
9860b57cec5SDimitry Andric /// EmitRawText - If this file is backed by an assembly streamer, this dumps
9870b57cec5SDimitry Andric /// the specified string in the output .s file.  This capability is
9880b57cec5SDimitry Andric /// indicated by the hasRawTextSupport() predicate.
emitRawTextImpl(StringRef String)9895ffd83dbSDimitry Andric void MCStreamer::emitRawTextImpl(StringRef String) {
9900b57cec5SDimitry Andric   // This is not llvm_unreachable for the sake of out of tree backend
9910b57cec5SDimitry Andric   // developers who may not have assembly streamers and should serve as a
9920b57cec5SDimitry Andric   // reminder to not accidentally call EmitRawText in the absence of such.
9930b57cec5SDimitry Andric   report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
9940b57cec5SDimitry Andric                      "it (target backend is likely missing an AsmStreamer "
9950b57cec5SDimitry Andric                      "implementation)");
9960b57cec5SDimitry Andric }
9970b57cec5SDimitry Andric 
emitRawText(const Twine & T)9985ffd83dbSDimitry Andric void MCStreamer::emitRawText(const Twine &T) {
9990b57cec5SDimitry Andric   SmallString<128> Str;
10005ffd83dbSDimitry Andric   emitRawTextImpl(T.toStringRef(Str));
10010b57cec5SDimitry Andric }
10020b57cec5SDimitry Andric 
emitWindowsUnwindTables()100381ad6265SDimitry Andric void MCStreamer::emitWindowsUnwindTables() {}
10040b57cec5SDimitry Andric 
emitWindowsUnwindTables(WinEH::FrameInfo * Frame)100581ad6265SDimitry Andric void MCStreamer::emitWindowsUnwindTables(WinEH::FrameInfo *Frame) {}
1006e8d8bef9SDimitry Andric 
finish(SMLoc EndLoc)100781ad6265SDimitry Andric void MCStreamer::finish(SMLoc EndLoc) {
10080b57cec5SDimitry Andric   if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
10090b57cec5SDimitry Andric       (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
1010e8d8bef9SDimitry Andric     getContext().reportError(EndLoc, "Unfinished frame!");
10110b57cec5SDimitry Andric     return;
10120b57cec5SDimitry Andric   }
10130b57cec5SDimitry Andric 
10140b57cec5SDimitry Andric   MCTargetStreamer *TS = getTargetStreamer();
10150b57cec5SDimitry Andric   if (TS)
10160b57cec5SDimitry Andric     TS->finish();
10170b57cec5SDimitry Andric 
10185ffd83dbSDimitry Andric   finishImpl();
10190b57cec5SDimitry Andric }
10200b57cec5SDimitry Andric 
maybeEmitDwarf64Mark()1021fe6060f1SDimitry Andric void MCStreamer::maybeEmitDwarf64Mark() {
1022fe6060f1SDimitry Andric   if (Context.getDwarfFormat() != dwarf::DWARF64)
1023fe6060f1SDimitry Andric     return;
1024fe6060f1SDimitry Andric   AddComment("DWARF64 Mark");
1025fe6060f1SDimitry Andric   emitInt32(dwarf::DW_LENGTH_DWARF64);
1026fe6060f1SDimitry Andric }
1027fe6060f1SDimitry Andric 
emitDwarfUnitLength(uint64_t Length,const Twine & Comment)1028fe6060f1SDimitry Andric void MCStreamer::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) {
1029fe6060f1SDimitry Andric   assert(Context.getDwarfFormat() == dwarf::DWARF64 ||
1030fe6060f1SDimitry Andric          Length <= dwarf::DW_LENGTH_lo_reserved);
1031fe6060f1SDimitry Andric   maybeEmitDwarf64Mark();
1032fe6060f1SDimitry Andric   AddComment(Comment);
1033fe6060f1SDimitry Andric   emitIntValue(Length, dwarf::getDwarfOffsetByteSize(Context.getDwarfFormat()));
1034fe6060f1SDimitry Andric }
1035fe6060f1SDimitry Andric 
emitDwarfUnitLength(const Twine & Prefix,const Twine & Comment)1036fe6060f1SDimitry Andric MCSymbol *MCStreamer::emitDwarfUnitLength(const Twine &Prefix,
1037fe6060f1SDimitry Andric                                           const Twine &Comment) {
1038fe6060f1SDimitry Andric   maybeEmitDwarf64Mark();
1039fe6060f1SDimitry Andric   AddComment(Comment);
1040fe6060f1SDimitry Andric   MCSymbol *Lo = Context.createTempSymbol(Prefix + "_start");
1041fe6060f1SDimitry Andric   MCSymbol *Hi = Context.createTempSymbol(Prefix + "_end");
1042fe6060f1SDimitry Andric 
1043fe6060f1SDimitry Andric   emitAbsoluteSymbolDiff(
1044fe6060f1SDimitry Andric       Hi, Lo, dwarf::getDwarfOffsetByteSize(Context.getDwarfFormat()));
1045fe6060f1SDimitry Andric   // emit the begin symbol after we generate the length field.
1046fe6060f1SDimitry Andric   emitLabel(Lo);
1047fe6060f1SDimitry Andric   // Return the Hi symbol to the caller.
1048fe6060f1SDimitry Andric   return Hi;
1049fe6060f1SDimitry Andric }
1050fe6060f1SDimitry Andric 
emitDwarfLineStartLabel(MCSymbol * StartSym)1051fe6060f1SDimitry Andric void MCStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
1052fe6060f1SDimitry Andric   // Set the value of the symbol, as we are at the start of the line table.
1053fe6060f1SDimitry Andric   emitLabel(StartSym);
1054fe6060f1SDimitry Andric }
1055fe6060f1SDimitry Andric 
emitAssignment(MCSymbol * Symbol,const MCExpr * Value)10565ffd83dbSDimitry Andric void MCStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
10570b57cec5SDimitry Andric   visitUsedExpr(*Value);
10580b57cec5SDimitry Andric   Symbol->setVariableValue(Value);
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric   MCTargetStreamer *TS = getTargetStreamer();
10610b57cec5SDimitry Andric   if (TS)
10620b57cec5SDimitry Andric     TS->emitAssignment(Symbol, Value);
10630b57cec5SDimitry Andric }
10640b57cec5SDimitry Andric 
prettyPrintAsm(MCInstPrinter & InstPrinter,uint64_t Address,const MCInst & Inst,const MCSubtargetInfo & STI,raw_ostream & OS)10650b57cec5SDimitry Andric void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
1066480093f4SDimitry Andric                                       uint64_t Address, const MCInst &Inst,
1067480093f4SDimitry Andric                                       const MCSubtargetInfo &STI,
1068480093f4SDimitry Andric                                       raw_ostream &OS) {
1069480093f4SDimitry Andric   InstPrinter.printInst(&Inst, Address, "", STI, OS);
10700b57cec5SDimitry Andric }
10710b57cec5SDimitry Andric 
visitUsedSymbol(const MCSymbol & Sym)10720b57cec5SDimitry Andric void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
10730b57cec5SDimitry Andric }
10740b57cec5SDimitry Andric 
visitUsedExpr(const MCExpr & Expr)10750b57cec5SDimitry Andric void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
10760b57cec5SDimitry Andric   switch (Expr.getKind()) {
10770b57cec5SDimitry Andric   case MCExpr::Target:
10780b57cec5SDimitry Andric     cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
10790b57cec5SDimitry Andric     break;
10800b57cec5SDimitry Andric 
10810b57cec5SDimitry Andric   case MCExpr::Constant:
10820b57cec5SDimitry Andric     break;
10830b57cec5SDimitry Andric 
10840b57cec5SDimitry Andric   case MCExpr::Binary: {
10850b57cec5SDimitry Andric     const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
10860b57cec5SDimitry Andric     visitUsedExpr(*BE.getLHS());
10870b57cec5SDimitry Andric     visitUsedExpr(*BE.getRHS());
10880b57cec5SDimitry Andric     break;
10890b57cec5SDimitry Andric   }
10900b57cec5SDimitry Andric 
10910b57cec5SDimitry Andric   case MCExpr::SymbolRef:
10920b57cec5SDimitry Andric     visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
10930b57cec5SDimitry Andric     break;
10940b57cec5SDimitry Andric 
10950b57cec5SDimitry Andric   case MCExpr::Unary:
10960b57cec5SDimitry Andric     visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
10970b57cec5SDimitry Andric     break;
10980b57cec5SDimitry Andric   }
10990b57cec5SDimitry Andric }
11000b57cec5SDimitry Andric 
emitInstruction(const MCInst & Inst,const MCSubtargetInfo &)11015ffd83dbSDimitry Andric void MCStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
11020b57cec5SDimitry Andric   // Scan for values.
11030b57cec5SDimitry Andric   for (unsigned i = Inst.getNumOperands(); i--;)
11040b57cec5SDimitry Andric     if (Inst.getOperand(i).isExpr())
11050b57cec5SDimitry Andric       visitUsedExpr(*Inst.getOperand(i).getExpr());
11060b57cec5SDimitry Andric }
11070b57cec5SDimitry Andric 
emitPseudoProbe(uint64_t Guid,uint64_t Index,uint64_t Type,uint64_t Attr,uint64_t Discriminator,const MCPseudoProbeInlineStack & InlineStack,MCSymbol * FnSym)1108e8d8bef9SDimitry Andric void MCStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
110906c3fb27SDimitry Andric                                  uint64_t Attr, uint64_t Discriminator,
1110bdd1243dSDimitry Andric                                  const MCPseudoProbeInlineStack &InlineStack,
1111bdd1243dSDimitry Andric                                  MCSymbol *FnSym) {
1112e8d8bef9SDimitry Andric   auto &Context = getContext();
1113e8d8bef9SDimitry Andric 
1114e8d8bef9SDimitry Andric   // Create a symbol at in the current section for use in the probe.
1115e8d8bef9SDimitry Andric   MCSymbol *ProbeSym = Context.createTempSymbol();
1116e8d8bef9SDimitry Andric 
1117e8d8bef9SDimitry Andric   // Set the value of the symbol to use for the MCPseudoProbe.
1118e8d8bef9SDimitry Andric   emitLabel(ProbeSym);
1119e8d8bef9SDimitry Andric 
1120e8d8bef9SDimitry Andric   // Create a (local) probe entry with the symbol.
112106c3fb27SDimitry Andric   MCPseudoProbe Probe(ProbeSym, Guid, Index, Type, Attr, Discriminator);
1122e8d8bef9SDimitry Andric 
1123e8d8bef9SDimitry Andric   // Add the probe entry to this section's entries.
1124e8d8bef9SDimitry Andric   Context.getMCPseudoProbeTable().getProbeSections().addPseudoProbe(
1125bdd1243dSDimitry Andric       FnSym, Probe, InlineStack);
1126e8d8bef9SDimitry Andric }
1127e8d8bef9SDimitry Andric 
emitAbsoluteSymbolDiff(const MCSymbol * Hi,const MCSymbol * Lo,unsigned Size)11280b57cec5SDimitry Andric void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
11290b57cec5SDimitry Andric                                         unsigned Size) {
11300b57cec5SDimitry Andric   // Get the Hi-Lo expression.
11310b57cec5SDimitry Andric   const MCExpr *Diff =
11320b57cec5SDimitry Andric       MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
11330b57cec5SDimitry Andric                               MCSymbolRefExpr::create(Lo, Context), Context);
11340b57cec5SDimitry Andric 
11350b57cec5SDimitry Andric   const MCAsmInfo *MAI = Context.getAsmInfo();
11360b57cec5SDimitry Andric   if (!MAI->doesSetDirectiveSuppressReloc()) {
11375ffd83dbSDimitry Andric     emitValue(Diff, Size);
11380b57cec5SDimitry Andric     return;
11390b57cec5SDimitry Andric   }
11400b57cec5SDimitry Andric 
11410b57cec5SDimitry Andric   // Otherwise, emit with .set (aka assignment).
1142e8d8bef9SDimitry Andric   MCSymbol *SetLabel = Context.createTempSymbol("set");
11435ffd83dbSDimitry Andric   emitAssignment(SetLabel, Diff);
11445ffd83dbSDimitry Andric   emitSymbolValue(SetLabel, Size);
11450b57cec5SDimitry Andric }
11460b57cec5SDimitry Andric 
emitAbsoluteSymbolDiffAsULEB128(const MCSymbol * Hi,const MCSymbol * Lo)11470b57cec5SDimitry Andric void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
11480b57cec5SDimitry Andric                                                  const MCSymbol *Lo) {
11490b57cec5SDimitry Andric   // Get the Hi-Lo expression.
11500b57cec5SDimitry Andric   const MCExpr *Diff =
11510b57cec5SDimitry Andric       MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
11520b57cec5SDimitry Andric                               MCSymbolRefExpr::create(Lo, Context), Context);
11530b57cec5SDimitry Andric 
11545ffd83dbSDimitry Andric   emitULEB128Value(Diff);
11550b57cec5SDimitry Andric }
11560b57cec5SDimitry Andric 
emitAssemblerFlag(MCAssemblerFlag Flag)11575ffd83dbSDimitry Andric void MCStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {}
emitThumbFunc(MCSymbol * Func)11585ffd83dbSDimitry Andric void MCStreamer::emitThumbFunc(MCSymbol *Func) {}
emitSymbolDesc(MCSymbol * Symbol,unsigned DescValue)11595ffd83dbSDimitry Andric void MCStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
beginCOFFSymbolDef(const MCSymbol * Symbol)116081ad6265SDimitry Andric void MCStreamer::beginCOFFSymbolDef(const MCSymbol *Symbol) {
11610b57cec5SDimitry Andric   llvm_unreachable("this directive only supported on COFF targets");
11620b57cec5SDimitry Andric }
endCOFFSymbolDef()116381ad6265SDimitry Andric void MCStreamer::endCOFFSymbolDef() {
11640b57cec5SDimitry Andric   llvm_unreachable("this directive only supported on COFF targets");
11650b57cec5SDimitry Andric }
emitFileDirective(StringRef Filename)11665ffd83dbSDimitry Andric void MCStreamer::emitFileDirective(StringRef Filename) {}
emitFileDirective(StringRef Filename,StringRef CompilerVersion,StringRef TimeStamp,StringRef Description)1167*0fca6ea1SDimitry Andric void MCStreamer::emitFileDirective(StringRef Filename,
1168*0fca6ea1SDimitry Andric                                    StringRef CompilerVersion,
1169fe6060f1SDimitry Andric                                    StringRef TimeStamp, StringRef Description) {
1170fe6060f1SDimitry Andric }
emitCOFFSymbolStorageClass(int StorageClass)117181ad6265SDimitry Andric void MCStreamer::emitCOFFSymbolStorageClass(int StorageClass) {
11720b57cec5SDimitry Andric   llvm_unreachable("this directive only supported on COFF targets");
11730b57cec5SDimitry Andric }
emitCOFFSymbolType(int Type)117481ad6265SDimitry Andric void MCStreamer::emitCOFFSymbolType(int Type) {
11750b57cec5SDimitry Andric   llvm_unreachable("this directive only supported on COFF targets");
11760b57cec5SDimitry Andric }
emitXCOFFLocalCommonSymbol(MCSymbol * LabelSym,uint64_t Size,MCSymbol * CsectSym,Align Alignment)11775ffd83dbSDimitry Andric void MCStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
1178480093f4SDimitry Andric                                             MCSymbol *CsectSym,
1179bdd1243dSDimitry Andric                                             Align Alignment) {
11808bcb0991SDimitry Andric   llvm_unreachable("this directive only supported on XCOFF targets");
11818bcb0991SDimitry Andric }
11825ffd83dbSDimitry Andric 
emitXCOFFSymbolLinkageWithVisibility(MCSymbol * Symbol,MCSymbolAttr Linkage,MCSymbolAttr Visibility)11835ffd83dbSDimitry Andric void MCStreamer::emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
11845ffd83dbSDimitry Andric                                                       MCSymbolAttr Linkage,
11855ffd83dbSDimitry Andric                                                       MCSymbolAttr Visibility) {
11865ffd83dbSDimitry Andric   llvm_unreachable("emitXCOFFSymbolLinkageWithVisibility is only supported on "
11875ffd83dbSDimitry Andric                    "XCOFF targets");
11885ffd83dbSDimitry Andric }
11895ffd83dbSDimitry Andric 
emitXCOFFRenameDirective(const MCSymbol * Name,StringRef Rename)11905ffd83dbSDimitry Andric void MCStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
11915f757f3fSDimitry Andric                                           StringRef Rename) {}
11925ffd83dbSDimitry Andric 
emitXCOFFRefDirective(const MCSymbol * Symbol)119306c3fb27SDimitry Andric void MCStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) {
119481ad6265SDimitry Andric   llvm_unreachable("emitXCOFFRefDirective is only supported on XCOFF targets");
119581ad6265SDimitry Andric }
119681ad6265SDimitry Andric 
emitXCOFFExceptDirective(const MCSymbol * Symbol,const MCSymbol * Trap,unsigned Lang,unsigned Reason,unsigned FunctionSize,bool hasDebug)1197bdd1243dSDimitry Andric void MCStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,
1198bdd1243dSDimitry Andric                                           const MCSymbol *Trap,
1199bdd1243dSDimitry Andric                                           unsigned Lang, unsigned Reason,
1200bdd1243dSDimitry Andric                                           unsigned FunctionSize,
1201bdd1243dSDimitry Andric                                           bool hasDebug) {
1202bdd1243dSDimitry Andric   report_fatal_error("emitXCOFFExceptDirective is only supported on "
1203bdd1243dSDimitry Andric                      "XCOFF targets");
1204bdd1243dSDimitry Andric }
1205bdd1243dSDimitry Andric 
emitXCOFFCInfoSym(StringRef Name,StringRef Metadata)120606c3fb27SDimitry Andric void MCStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
120706c3fb27SDimitry Andric   llvm_unreachable("emitXCOFFCInfoSym is only supported on"
120806c3fb27SDimitry Andric                    "XCOFF targets");
120906c3fb27SDimitry Andric }
121006c3fb27SDimitry Andric 
emitELFSize(MCSymbol * Symbol,const MCExpr * Value)12110b57cec5SDimitry Andric void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
emitELFSymverDirective(const MCSymbol * OriginalSym,StringRef Name,bool KeepOriginalSym)1212fe6060f1SDimitry Andric void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
1213fe6060f1SDimitry Andric                                         StringRef Name, bool KeepOriginalSym) {}
emitLocalCommonSymbol(MCSymbol * Symbol,uint64_t Size,Align ByteAlignment)12145ffd83dbSDimitry Andric void MCStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1215bdd1243dSDimitry Andric                                        Align ByteAlignment) {}
emitTBSSSymbol(MCSection * Section,MCSymbol * Symbol,uint64_t Size,Align ByteAlignment)12165ffd83dbSDimitry Andric void MCStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1217bdd1243dSDimitry Andric                                 uint64_t Size, Align ByteAlignment) {}
changeSection(MCSection * Section,uint32_t)1218*0fca6ea1SDimitry Andric void MCStreamer::changeSection(MCSection *Section, uint32_t) {
1219*0fca6ea1SDimitry Andric   CurFrag = &Section->getDummyFragment();
1220*0fca6ea1SDimitry Andric }
emitWeakReference(MCSymbol * Alias,const MCSymbol * Symbol)12215ffd83dbSDimitry Andric void MCStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
emitBytes(StringRef Data)12225ffd83dbSDimitry Andric void MCStreamer::emitBytes(StringRef Data) {}
emitBinaryData(StringRef Data)12235ffd83dbSDimitry Andric void MCStreamer::emitBinaryData(StringRef Data) { emitBytes(Data); }
emitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)12245ffd83dbSDimitry Andric void MCStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
12250b57cec5SDimitry Andric   visitUsedExpr(*Value);
12260b57cec5SDimitry Andric }
emitULEB128Value(const MCExpr * Value)12275ffd83dbSDimitry Andric void MCStreamer::emitULEB128Value(const MCExpr *Value) {}
emitSLEB128Value(const MCExpr * Value)12285ffd83dbSDimitry Andric void MCStreamer::emitSLEB128Value(const MCExpr *Value) {}
emitFill(const MCExpr & NumBytes,uint64_t Value,SMLoc Loc)12290b57cec5SDimitry Andric void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
emitFill(const MCExpr & NumValues,int64_t Size,int64_t Expr,SMLoc Loc)12300b57cec5SDimitry Andric void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
12310b57cec5SDimitry Andric                           SMLoc Loc) {}
emitValueToAlignment(Align Alignment,int64_t Value,unsigned ValueSize,unsigned MaxBytesToEmit)1232bdd1243dSDimitry Andric void MCStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
12330b57cec5SDimitry Andric                                       unsigned ValueSize,
12340b57cec5SDimitry Andric                                       unsigned MaxBytesToEmit) {}
emitCodeAlignment(Align Alignment,const MCSubtargetInfo * STI,unsigned MaxBytesToEmit)1235bdd1243dSDimitry Andric void MCStreamer::emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
12360b57cec5SDimitry Andric                                    unsigned MaxBytesToEmit) {}
emitValueToOffset(const MCExpr * Offset,unsigned char Value,SMLoc Loc)12370b57cec5SDimitry Andric void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
12380b57cec5SDimitry Andric                                    SMLoc Loc) {}
emitBundleAlignMode(Align Alignment)1239bdd1243dSDimitry Andric void MCStreamer::emitBundleAlignMode(Align Alignment) {}
emitBundleLock(bool AlignToEnd)12405ffd83dbSDimitry Andric void MCStreamer::emitBundleLock(bool AlignToEnd) {}
finishImpl()12415ffd83dbSDimitry Andric void MCStreamer::finishImpl() {}
emitBundleUnlock()12425ffd83dbSDimitry Andric void MCStreamer::emitBundleUnlock() {}
12430b57cec5SDimitry Andric 
popSection()1244*0fca6ea1SDimitry Andric bool MCStreamer::popSection() {
1245*0fca6ea1SDimitry Andric   if (SectionStack.size() <= 1)
1246*0fca6ea1SDimitry Andric     return false;
1247*0fca6ea1SDimitry Andric   auto I = SectionStack.end();
1248*0fca6ea1SDimitry Andric   --I;
1249*0fca6ea1SDimitry Andric   MCSectionSubPair OldSec = I->first;
1250*0fca6ea1SDimitry Andric   --I;
1251*0fca6ea1SDimitry Andric   MCSectionSubPair NewSec = I->first;
1252*0fca6ea1SDimitry Andric 
1253*0fca6ea1SDimitry Andric   if (NewSec.first && OldSec != NewSec)
1254*0fca6ea1SDimitry Andric     changeSection(NewSec.first, NewSec.second);
1255*0fca6ea1SDimitry Andric   SectionStack.pop_back();
1256*0fca6ea1SDimitry Andric   return true;
1257*0fca6ea1SDimitry Andric }
1258*0fca6ea1SDimitry Andric 
switchSection(MCSection * Section,uint32_t Subsection)1259*0fca6ea1SDimitry Andric void MCStreamer::switchSection(MCSection *Section, uint32_t Subsection) {
12600b57cec5SDimitry Andric   assert(Section && "Cannot switch to a null section!");
12610b57cec5SDimitry Andric   MCSectionSubPair curSection = SectionStack.back().first;
12620b57cec5SDimitry Andric   SectionStack.back().second = curSection;
12630b57cec5SDimitry Andric   if (MCSectionSubPair(Section, Subsection) != curSection) {
12645ffd83dbSDimitry Andric     changeSection(Section, Subsection);
12650b57cec5SDimitry Andric     SectionStack.back().first = MCSectionSubPair(Section, Subsection);
12660b57cec5SDimitry Andric     assert(!Section->hasEnded() && "Section already ended");
12670b57cec5SDimitry Andric     MCSymbol *Sym = Section->getBeginSymbol();
12680b57cec5SDimitry Andric     if (Sym && !Sym->isInSection())
12695ffd83dbSDimitry Andric       emitLabel(Sym);
12700b57cec5SDimitry Andric   }
12710b57cec5SDimitry Andric }
12720b57cec5SDimitry Andric 
switchSection(MCSection * Section,const MCExpr * SubsecExpr)1273*0fca6ea1SDimitry Andric bool MCStreamer::switchSection(MCSection *Section, const MCExpr *SubsecExpr) {
1274*0fca6ea1SDimitry Andric   int64_t Subsec = 0;
1275*0fca6ea1SDimitry Andric   if (SubsecExpr) {
1276*0fca6ea1SDimitry Andric     if (!SubsecExpr->evaluateAsAbsolute(Subsec, getAssemblerPtr())) {
1277*0fca6ea1SDimitry Andric       getContext().reportError(SubsecExpr->getLoc(),
1278*0fca6ea1SDimitry Andric                                "cannot evaluate subsection number");
1279*0fca6ea1SDimitry Andric       return true;
1280*0fca6ea1SDimitry Andric     }
1281*0fca6ea1SDimitry Andric     if (!isUInt<31>(Subsec)) {
1282*0fca6ea1SDimitry Andric       getContext().reportError(SubsecExpr->getLoc(),
1283*0fca6ea1SDimitry Andric                                "subsection number " + Twine(Subsec) +
1284*0fca6ea1SDimitry Andric                                    " is not within [0,2147483647]");
1285*0fca6ea1SDimitry Andric       return true;
1286*0fca6ea1SDimitry Andric     }
1287*0fca6ea1SDimitry Andric   }
1288*0fca6ea1SDimitry Andric   switchSection(Section, Subsec);
1289*0fca6ea1SDimitry Andric   return false;
1290*0fca6ea1SDimitry Andric }
1291*0fca6ea1SDimitry Andric 
switchSectionNoPrint(MCSection * Section)1292*0fca6ea1SDimitry Andric void MCStreamer::switchSectionNoPrint(MCSection *Section) {
1293*0fca6ea1SDimitry Andric   SectionStack.back().second = SectionStack.back().first;
1294*0fca6ea1SDimitry Andric   SectionStack.back().first = MCSectionSubPair(Section, 0);
1295*0fca6ea1SDimitry Andric   CurFrag = &Section->getDummyFragment();
1296*0fca6ea1SDimitry Andric }
1297*0fca6ea1SDimitry Andric 
endSection(MCSection * Section)12980b57cec5SDimitry Andric MCSymbol *MCStreamer::endSection(MCSection *Section) {
12990b57cec5SDimitry Andric   // TODO: keep track of the last subsection so that this symbol appears in the
13000b57cec5SDimitry Andric   // correct place.
13010b57cec5SDimitry Andric   MCSymbol *Sym = Section->getEndSymbol(Context);
13020b57cec5SDimitry Andric   if (Sym->isInSection())
13030b57cec5SDimitry Andric     return Sym;
13040b57cec5SDimitry Andric 
130581ad6265SDimitry Andric   switchSection(Section);
13065ffd83dbSDimitry Andric   emitLabel(Sym);
13070b57cec5SDimitry Andric   return Sym;
13080b57cec5SDimitry Andric }
13090b57cec5SDimitry Andric 
13105ffd83dbSDimitry Andric static VersionTuple
targetVersionOrMinimumSupportedOSVersion(const Triple & Target,VersionTuple TargetVersion)13115ffd83dbSDimitry Andric targetVersionOrMinimumSupportedOSVersion(const Triple &Target,
13125ffd83dbSDimitry Andric                                          VersionTuple TargetVersion) {
13135ffd83dbSDimitry Andric   VersionTuple Min = Target.getMinimumSupportedOSVersion();
13145ffd83dbSDimitry Andric   return !Min.empty() && Min > TargetVersion ? Min : TargetVersion;
13155ffd83dbSDimitry Andric }
13165ffd83dbSDimitry Andric 
13175ffd83dbSDimitry Andric static MCVersionMinType
getMachoVersionMinLoadCommandType(const Triple & Target)13185ffd83dbSDimitry Andric getMachoVersionMinLoadCommandType(const Triple &Target) {
13195ffd83dbSDimitry Andric   assert(Target.isOSDarwin() && "expected a darwin OS");
13205ffd83dbSDimitry Andric   switch (Target.getOS()) {
13215ffd83dbSDimitry Andric   case Triple::MacOSX:
13225ffd83dbSDimitry Andric   case Triple::Darwin:
13235ffd83dbSDimitry Andric     return MCVM_OSXVersionMin;
13245ffd83dbSDimitry Andric   case Triple::IOS:
13255ffd83dbSDimitry Andric     assert(!Target.isMacCatalystEnvironment() &&
13265ffd83dbSDimitry Andric            "mac Catalyst should use LC_BUILD_VERSION");
13275ffd83dbSDimitry Andric     return MCVM_IOSVersionMin;
13285ffd83dbSDimitry Andric   case Triple::TvOS:
13295ffd83dbSDimitry Andric     return MCVM_TvOSVersionMin;
13305ffd83dbSDimitry Andric   case Triple::WatchOS:
13315ffd83dbSDimitry Andric     return MCVM_WatchOSVersionMin;
13325ffd83dbSDimitry Andric   default:
13335ffd83dbSDimitry Andric     break;
13345ffd83dbSDimitry Andric   }
13355ffd83dbSDimitry Andric   llvm_unreachable("unexpected OS type");
13365ffd83dbSDimitry Andric }
13375ffd83dbSDimitry Andric 
getMachoBuildVersionSupportedOS(const Triple & Target)13385ffd83dbSDimitry Andric static VersionTuple getMachoBuildVersionSupportedOS(const Triple &Target) {
13395ffd83dbSDimitry Andric   assert(Target.isOSDarwin() && "expected a darwin OS");
13405ffd83dbSDimitry Andric   switch (Target.getOS()) {
13415ffd83dbSDimitry Andric   case Triple::MacOSX:
13425ffd83dbSDimitry Andric   case Triple::Darwin:
13435ffd83dbSDimitry Andric     return VersionTuple(10, 14);
13445ffd83dbSDimitry Andric   case Triple::IOS:
13455ffd83dbSDimitry Andric     // Mac Catalyst always uses the build version load command.
13465ffd83dbSDimitry Andric     if (Target.isMacCatalystEnvironment())
13475ffd83dbSDimitry Andric       return VersionTuple();
1348bdd1243dSDimitry Andric     [[fallthrough]];
13495ffd83dbSDimitry Andric   case Triple::TvOS:
13505ffd83dbSDimitry Andric     return VersionTuple(12);
13515ffd83dbSDimitry Andric   case Triple::WatchOS:
13525ffd83dbSDimitry Andric     return VersionTuple(5);
135381ad6265SDimitry Andric   case Triple::DriverKit:
135481ad6265SDimitry Andric     // DriverKit always uses the build version load command.
135581ad6265SDimitry Andric     return VersionTuple();
13567a6dacacSDimitry Andric   case Triple::XROS:
13577a6dacacSDimitry Andric     // XROS always uses the build version load command.
13587a6dacacSDimitry Andric     return VersionTuple();
13595ffd83dbSDimitry Andric   default:
13605ffd83dbSDimitry Andric     break;
13615ffd83dbSDimitry Andric   }
13625ffd83dbSDimitry Andric   llvm_unreachable("unexpected OS type");
13635ffd83dbSDimitry Andric }
13645ffd83dbSDimitry Andric 
13655ffd83dbSDimitry Andric static MachO::PlatformType
getMachoBuildVersionPlatformType(const Triple & Target)13665ffd83dbSDimitry Andric getMachoBuildVersionPlatformType(const Triple &Target) {
13675ffd83dbSDimitry Andric   assert(Target.isOSDarwin() && "expected a darwin OS");
13685ffd83dbSDimitry Andric   switch (Target.getOS()) {
13695ffd83dbSDimitry Andric   case Triple::MacOSX:
13705ffd83dbSDimitry Andric   case Triple::Darwin:
13715ffd83dbSDimitry Andric     return MachO::PLATFORM_MACOS;
13725ffd83dbSDimitry Andric   case Triple::IOS:
13735ffd83dbSDimitry Andric     if (Target.isMacCatalystEnvironment())
13745ffd83dbSDimitry Andric       return MachO::PLATFORM_MACCATALYST;
13755ffd83dbSDimitry Andric     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
13765ffd83dbSDimitry Andric                                            : MachO::PLATFORM_IOS;
13775ffd83dbSDimitry Andric   case Triple::TvOS:
13785ffd83dbSDimitry Andric     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
13795ffd83dbSDimitry Andric                                            : MachO::PLATFORM_TVOS;
13805ffd83dbSDimitry Andric   case Triple::WatchOS:
13815ffd83dbSDimitry Andric     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
13825ffd83dbSDimitry Andric                                            : MachO::PLATFORM_WATCHOS;
138381ad6265SDimitry Andric   case Triple::DriverKit:
138481ad6265SDimitry Andric     return MachO::PLATFORM_DRIVERKIT;
13857a6dacacSDimitry Andric   case Triple::XROS:
13867a6dacacSDimitry Andric     return Target.isSimulatorEnvironment() ? MachO::PLATFORM_XROS_SIMULATOR
13877a6dacacSDimitry Andric                                            : MachO::PLATFORM_XROS;
13885ffd83dbSDimitry Andric   default:
13895ffd83dbSDimitry Andric     break;
13905ffd83dbSDimitry Andric   }
13915ffd83dbSDimitry Andric   llvm_unreachable("unexpected OS type");
13925ffd83dbSDimitry Andric }
13935ffd83dbSDimitry Andric 
emitVersionForTarget(const Triple & Target,const VersionTuple & SDKVersion,const Triple * DarwinTargetVariantTriple,const VersionTuple & DarwinTargetVariantSDKVersion)13940eae32dcSDimitry Andric void MCStreamer::emitVersionForTarget(
13950eae32dcSDimitry Andric     const Triple &Target, const VersionTuple &SDKVersion,
13960eae32dcSDimitry Andric     const Triple *DarwinTargetVariantTriple,
13970eae32dcSDimitry Andric     const VersionTuple &DarwinTargetVariantSDKVersion) {
13980b57cec5SDimitry Andric   if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
13990b57cec5SDimitry Andric     return;
14000b57cec5SDimitry Andric   // Do we even know the version?
14010b57cec5SDimitry Andric   if (Target.getOSMajorVersion() == 0)
14020b57cec5SDimitry Andric     return;
14030b57cec5SDimitry Andric 
14040eae32dcSDimitry Andric   VersionTuple Version;
14055ffd83dbSDimitry Andric   switch (Target.getOS()) {
14065ffd83dbSDimitry Andric   case Triple::MacOSX:
14075ffd83dbSDimitry Andric   case Triple::Darwin:
14080eae32dcSDimitry Andric     Target.getMacOSXVersion(Version);
14095ffd83dbSDimitry Andric     break;
14105ffd83dbSDimitry Andric   case Triple::IOS:
14115ffd83dbSDimitry Andric   case Triple::TvOS:
14120eae32dcSDimitry Andric     Version = Target.getiOSVersion();
14135ffd83dbSDimitry Andric     break;
14145ffd83dbSDimitry Andric   case Triple::WatchOS:
14150eae32dcSDimitry Andric     Version = Target.getWatchOSVersion();
14165ffd83dbSDimitry Andric     break;
141781ad6265SDimitry Andric   case Triple::DriverKit:
141881ad6265SDimitry Andric     Version = Target.getDriverKitVersion();
141981ad6265SDimitry Andric     break;
14207a6dacacSDimitry Andric   case Triple::XROS:
14217a6dacacSDimitry Andric     Version = Target.getOSVersion();
14227a6dacacSDimitry Andric     break;
14235ffd83dbSDimitry Andric   default:
14245ffd83dbSDimitry Andric     llvm_unreachable("unexpected OS type");
14250b57cec5SDimitry Andric   }
14260eae32dcSDimitry Andric   assert(Version.getMajor() != 0 && "A non-zero major version is expected");
14270eae32dcSDimitry Andric   auto LinkedTargetVersion =
14280eae32dcSDimitry Andric       targetVersionOrMinimumSupportedOSVersion(Target, Version);
14295ffd83dbSDimitry Andric   auto BuildVersionOSVersion = getMachoBuildVersionSupportedOS(Target);
14300eae32dcSDimitry Andric   bool ShouldEmitBuildVersion = false;
14315ffd83dbSDimitry Andric   if (BuildVersionOSVersion.empty() ||
14320eae32dcSDimitry Andric       LinkedTargetVersion >= BuildVersionOSVersion) {
14330eae32dcSDimitry Andric     if (Target.isMacCatalystEnvironment() && DarwinTargetVariantTriple &&
14340eae32dcSDimitry Andric         DarwinTargetVariantTriple->isMacOSX()) {
14350eae32dcSDimitry Andric       emitVersionForTarget(*DarwinTargetVariantTriple,
14360eae32dcSDimitry Andric                            DarwinTargetVariantSDKVersion,
143704eeddc0SDimitry Andric                            /*DarwinTargetVariantTriple=*/nullptr,
143804eeddc0SDimitry Andric                            /*DarwinTargetVariantSDKVersion=*/VersionTuple());
14390eae32dcSDimitry Andric       emitDarwinTargetVariantBuildVersion(
14400eae32dcSDimitry Andric           getMachoBuildVersionPlatformType(Target),
14415ffd83dbSDimitry Andric           LinkedTargetVersion.getMajor(),
144281ad6265SDimitry Andric           LinkedTargetVersion.getMinor().value_or(0),
144381ad6265SDimitry Andric           LinkedTargetVersion.getSubminor().value_or(0), SDKVersion);
14440eae32dcSDimitry Andric       return;
14450eae32dcSDimitry Andric     }
14460eae32dcSDimitry Andric     emitBuildVersion(getMachoBuildVersionPlatformType(Target),
14470eae32dcSDimitry Andric                      LinkedTargetVersion.getMajor(),
144881ad6265SDimitry Andric                      LinkedTargetVersion.getMinor().value_or(0),
144981ad6265SDimitry Andric                      LinkedTargetVersion.getSubminor().value_or(0), SDKVersion);
14500eae32dcSDimitry Andric     ShouldEmitBuildVersion = true;
14510eae32dcSDimitry Andric   }
14520eae32dcSDimitry Andric 
14530eae32dcSDimitry Andric   if (const Triple *TVT = DarwinTargetVariantTriple) {
14540eae32dcSDimitry Andric     if (Target.isMacOSX() && TVT->isMacCatalystEnvironment()) {
14550eae32dcSDimitry Andric       auto TVLinkedTargetVersion =
14560eae32dcSDimitry Andric           targetVersionOrMinimumSupportedOSVersion(*TVT, TVT->getiOSVersion());
14570eae32dcSDimitry Andric       emitDarwinTargetVariantBuildVersion(
14580eae32dcSDimitry Andric           getMachoBuildVersionPlatformType(*TVT),
14590eae32dcSDimitry Andric           TVLinkedTargetVersion.getMajor(),
146081ad6265SDimitry Andric           TVLinkedTargetVersion.getMinor().value_or(0),
146181ad6265SDimitry Andric           TVLinkedTargetVersion.getSubminor().value_or(0),
14620eae32dcSDimitry Andric           DarwinTargetVariantSDKVersion);
14630eae32dcSDimitry Andric     }
14640eae32dcSDimitry Andric   }
14650eae32dcSDimitry Andric 
14660eae32dcSDimitry Andric   if (ShouldEmitBuildVersion)
14670eae32dcSDimitry Andric     return;
14685ffd83dbSDimitry Andric 
14695ffd83dbSDimitry Andric   emitVersionMin(getMachoVersionMinLoadCommandType(Target),
14705ffd83dbSDimitry Andric                  LinkedTargetVersion.getMajor(),
147181ad6265SDimitry Andric                  LinkedTargetVersion.getMinor().value_or(0),
147281ad6265SDimitry Andric                  LinkedTargetVersion.getSubminor().value_or(0), SDKVersion);
14730b57cec5SDimitry Andric }
1474