brintos

brintos / llvm-project-archived public Read only

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