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