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