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 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, 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 670b57cec5SDimitry Andric void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) { 685ffd83dbSDimitry Andric Streamer.emitRawText(Directive); 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 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 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 910b57cec5SDimitry Andric void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {} 920b57cec5SDimitry Andric 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 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 11081ad6265SDimitry Andric raw_ostream &MCStreamer::getCommentOS() { 1110b57cec5SDimitry Andric // By default, discard comments. 1120b57cec5SDimitry Andric return nulls(); 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos.size(); } 1160b57cec5SDimitry Andric ArrayRef<MCDwarfFrameInfo> MCStreamer::getDwarfFrameInfos() const { 1170b57cec5SDimitry Andric return DwarfFrameInfos; 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {} 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric void MCStreamer::addExplicitComment(const Twine &T) {} 1230b57cec5SDimitry Andric void MCStreamer::emitExplicitComments() {} 1240b57cec5SDimitry Andric 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. 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 } 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. 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. 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 1795ffd83dbSDimitry Andric void MCStreamer::emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) { 1805ffd83dbSDimitry Andric emitValueImpl(Value, Size, Loc); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 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 1945ffd83dbSDimitry Andric void MCStreamer::emitDTPRel64Value(const MCExpr *Value) { 1950b57cec5SDimitry Andric report_fatal_error("unsupported directive in streamer"); 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric 1985ffd83dbSDimitry Andric void MCStreamer::emitDTPRel32Value(const MCExpr *Value) { 1990b57cec5SDimitry Andric report_fatal_error("unsupported directive in streamer"); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 2025ffd83dbSDimitry Andric void MCStreamer::emitTPRel64Value(const MCExpr *Value) { 2030b57cec5SDimitry Andric report_fatal_error("unsupported directive in streamer"); 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric 2065ffd83dbSDimitry Andric void MCStreamer::emitTPRel32Value(const MCExpr *Value) { 2070b57cec5SDimitry Andric report_fatal_error("unsupported directive in streamer"); 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2105ffd83dbSDimitry Andric void MCStreamer::emitGPRel64Value(const MCExpr *Value) { 2110b57cec5SDimitry Andric report_fatal_error("unsupported directive in streamer"); 2120b57cec5SDimitry Andric } 2130b57cec5SDimitry Andric 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'. 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 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 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 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 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() { 28106c3fb27SDimitry Andric return !FrameInfoStack.empty(); 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 } 29106c3fb27SDimitry Andric return &DwarfFrameInfos[FrameInfoStack.back().first]; 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 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 4330eae32dcSDimitry Andric void MCStreamer::emitConditionalAssignment(MCSymbol *Symbol, 4340eae32dcSDimitry Andric const MCExpr *Value) {} 4350eae32dcSDimitry Andric 436fe6060f1SDimitry Andric void MCStreamer::emitCFISections(bool EH, bool Debug) {} 4370b57cec5SDimitry Andric 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 4635ffd83dbSDimitry Andric void MCStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 8130b57cec5SDimitry Andric void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From, 8140b57cec5SDimitry Andric const MCSymbolRefExpr *To, uint64_t Count) { 8150b57cec5SDimitry Andric } 8160b57cec5SDimitry Andric 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 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 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 8635ffd83dbSDimitry Andric void MCStreamer::emitSyntaxDirective() {} 8640b57cec5SDimitry Andric 8658bcb0991SDimitry Andric static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) { 8668bcb0991SDimitry Andric return Ctx.getRegisterInfo()->getSEHRegNum(Reg); 8678bcb0991SDimitry Andric } 8688bcb0991SDimitry Andric 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 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 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 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 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 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 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 97681ad6265SDimitry Andric void MCStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {} 9770b57cec5SDimitry Andric 97881ad6265SDimitry Andric void MCStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {} 9790b57cec5SDimitry Andric 98081ad6265SDimitry Andric void MCStreamer::emitCOFFSectionIndex(MCSymbol const *Symbol) {} 9810b57cec5SDimitry Andric 98281ad6265SDimitry Andric void MCStreamer::emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {} 9830b57cec5SDimitry Andric 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. 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 9985ffd83dbSDimitry Andric void MCStreamer::emitRawText(const Twine &T) { 9990b57cec5SDimitry Andric SmallString<128> Str; 10005ffd83dbSDimitry Andric emitRawTextImpl(T.toStringRef(Str)); 10010b57cec5SDimitry Andric } 10020b57cec5SDimitry Andric 100381ad6265SDimitry Andric void MCStreamer::emitWindowsUnwindTables() {} 10040b57cec5SDimitry Andric 100581ad6265SDimitry Andric void MCStreamer::emitWindowsUnwindTables(WinEH::FrameInfo *Frame) {} 1006e8d8bef9SDimitry Andric 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 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 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 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 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 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 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 10720b57cec5SDimitry Andric void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) { 10730b57cec5SDimitry Andric } 10740b57cec5SDimitry Andric 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 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 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 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 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 11575ffd83dbSDimitry Andric void MCStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {} 11585ffd83dbSDimitry Andric void MCStreamer::emitThumbFunc(MCSymbol *Func) {} 11595ffd83dbSDimitry Andric void MCStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {} 116081ad6265SDimitry Andric void MCStreamer::beginCOFFSymbolDef(const MCSymbol *Symbol) { 11610b57cec5SDimitry Andric llvm_unreachable("this directive only supported on COFF targets"); 11620b57cec5SDimitry Andric } 116381ad6265SDimitry Andric void MCStreamer::endCOFFSymbolDef() { 11640b57cec5SDimitry Andric llvm_unreachable("this directive only supported on COFF targets"); 11650b57cec5SDimitry Andric } 11665ffd83dbSDimitry Andric void MCStreamer::emitFileDirective(StringRef Filename) {} 1167*0fca6ea1SDimitry Andric void MCStreamer::emitFileDirective(StringRef Filename, 1168*0fca6ea1SDimitry Andric StringRef CompilerVersion, 1169fe6060f1SDimitry Andric StringRef TimeStamp, StringRef Description) { 1170fe6060f1SDimitry Andric } 117181ad6265SDimitry Andric void MCStreamer::emitCOFFSymbolStorageClass(int StorageClass) { 11720b57cec5SDimitry Andric llvm_unreachable("this directive only supported on COFF targets"); 11730b57cec5SDimitry Andric } 117481ad6265SDimitry Andric void MCStreamer::emitCOFFSymbolType(int Type) { 11750b57cec5SDimitry Andric llvm_unreachable("this directive only supported on COFF targets"); 11760b57cec5SDimitry Andric } 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 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 11905ffd83dbSDimitry Andric void MCStreamer::emitXCOFFRenameDirective(const MCSymbol *Name, 11915f757f3fSDimitry Andric StringRef Rename) {} 11925ffd83dbSDimitry Andric 119306c3fb27SDimitry Andric void MCStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) { 119481ad6265SDimitry Andric llvm_unreachable("emitXCOFFRefDirective is only supported on XCOFF targets"); 119581ad6265SDimitry Andric } 119681ad6265SDimitry Andric 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 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 12110b57cec5SDimitry Andric void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {} 1212fe6060f1SDimitry Andric void MCStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym, 1213fe6060f1SDimitry Andric StringRef Name, bool KeepOriginalSym) {} 12145ffd83dbSDimitry Andric void MCStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 1215bdd1243dSDimitry Andric Align ByteAlignment) {} 12165ffd83dbSDimitry Andric void MCStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, 1217bdd1243dSDimitry Andric uint64_t Size, Align ByteAlignment) {} 1218*0fca6ea1SDimitry Andric void MCStreamer::changeSection(MCSection *Section, uint32_t) { 1219*0fca6ea1SDimitry Andric CurFrag = &Section->getDummyFragment(); 1220*0fca6ea1SDimitry Andric } 12215ffd83dbSDimitry Andric void MCStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {} 12225ffd83dbSDimitry Andric void MCStreamer::emitBytes(StringRef Data) {} 12235ffd83dbSDimitry Andric void MCStreamer::emitBinaryData(StringRef Data) { emitBytes(Data); } 12245ffd83dbSDimitry Andric void MCStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) { 12250b57cec5SDimitry Andric visitUsedExpr(*Value); 12260b57cec5SDimitry Andric } 12275ffd83dbSDimitry Andric void MCStreamer::emitULEB128Value(const MCExpr *Value) {} 12285ffd83dbSDimitry Andric void MCStreamer::emitSLEB128Value(const MCExpr *Value) {} 12290b57cec5SDimitry Andric void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {} 12300b57cec5SDimitry Andric void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr, 12310b57cec5SDimitry Andric SMLoc Loc) {} 1232bdd1243dSDimitry Andric void MCStreamer::emitValueToAlignment(Align Alignment, int64_t Value, 12330b57cec5SDimitry Andric unsigned ValueSize, 12340b57cec5SDimitry Andric unsigned MaxBytesToEmit) {} 1235bdd1243dSDimitry Andric void MCStreamer::emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, 12360b57cec5SDimitry Andric unsigned MaxBytesToEmit) {} 12370b57cec5SDimitry Andric void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value, 12380b57cec5SDimitry Andric SMLoc Loc) {} 1239bdd1243dSDimitry Andric void MCStreamer::emitBundleAlignMode(Align Alignment) {} 12405ffd83dbSDimitry Andric void MCStreamer::emitBundleLock(bool AlignToEnd) {} 12415ffd83dbSDimitry Andric void MCStreamer::finishImpl() {} 12425ffd83dbSDimitry Andric void MCStreamer::emitBundleUnlock() {} 12430b57cec5SDimitry Andric 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 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 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 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 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 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 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 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 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 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