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