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