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