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