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