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