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