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/MC/MCAsmBackend.h" 16 #include "llvm/MC/MCAsmInfo.h" 17 #include "llvm/MC/MCCodeView.h" 18 #include "llvm/MC/MCContext.h" 19 #include "llvm/MC/MCDwarf.h" 20 #include "llvm/MC/MCExpr.h" 21 #include "llvm/MC/MCInst.h" 22 #include "llvm/MC/MCInstPrinter.h" 23 #include "llvm/MC/MCObjectFileInfo.h" 24 #include "llvm/MC/MCSection.h" 25 #include "llvm/MC/MCSectionCOFF.h" 26 #include "llvm/MC/MCSymbol.h" 27 #include "llvm/MC/MCWin64EH.h" 28 #include "llvm/MC/MCWinEH.h" 29 #include "llvm/Support/Casting.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include "llvm/Support/LEB128.h" 32 #include "llvm/Support/MathExtras.h" 33 #include "llvm/Support/raw_ostream.h" 34 #include <cassert> 35 #include <cstdint> 36 #include <cstdlib> 37 #include <utility> 38 39 using namespace llvm; 40 41 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) { 42 S.setTargetStreamer(this); 43 } 44 45 // Pin the vtables to this file. 46 MCTargetStreamer::~MCTargetStreamer() = default; 47 48 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {} 49 50 void MCTargetStreamer::finish() {} 51 52 void MCTargetStreamer::changeSection(const MCSection *CurSection, 53 MCSection *Section, 54 const MCExpr *Subsection, 55 raw_ostream &OS) { 56 Section->PrintSwitchToSection( 57 *Streamer.getContext().getAsmInfo(), 58 Streamer.getContext().getObjectFileInfo()->getTargetTriple(), OS, 59 Subsection); 60 } 61 62 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) { 63 Streamer.EmitRawText(Directive); 64 } 65 66 void MCTargetStreamer::emitValue(const MCExpr *Value) { 67 SmallString<128> Str; 68 raw_svector_ostream OS(Str); 69 70 Value->print(OS, Streamer.getContext().getAsmInfo()); 71 Streamer.EmitRawText(OS.str()); 72 } 73 74 void MCTargetStreamer::emitRawBytes(StringRef Data) { 75 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); 76 const char *Directive = MAI->getData8bitsDirective(); 77 for (const unsigned char C : Data.bytes()) { 78 SmallString<128> Str; 79 raw_svector_ostream OS(Str); 80 81 OS << Directive << (unsigned)C; 82 Streamer.EmitRawText(OS.str()); 83 } 84 } 85 86 void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {} 87 88 MCStreamer::MCStreamer(MCContext &Ctx) 89 : Context(Ctx), CurrentWinFrameInfo(nullptr), 90 UseAssemblerInfoForParsing(false) { 91 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); 92 } 93 94 MCStreamer::~MCStreamer() {} 95 96 void MCStreamer::reset() { 97 DwarfFrameInfos.clear(); 98 CurrentWinFrameInfo = nullptr; 99 WinFrameInfos.clear(); 100 SymbolOrdering.clear(); 101 SectionStack.clear(); 102 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); 103 } 104 105 raw_ostream &MCStreamer::GetCommentOS() { 106 // By default, discard comments. 107 return nulls(); 108 } 109 110 unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos.size(); } 111 ArrayRef<MCDwarfFrameInfo> MCStreamer::getDwarfFrameInfos() const { 112 return DwarfFrameInfos; 113 } 114 115 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {} 116 117 void MCStreamer::addExplicitComment(const Twine &T) {} 118 void MCStreamer::emitExplicitComments() {} 119 120 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) { 121 for (auto &FI : DwarfFrameInfos) 122 FI.CompactUnwindEncoding = 123 (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0); 124 } 125 126 /// EmitIntValue - Special case of EmitValue that avoids the client having to 127 /// pass in a MCExpr for constant integers. 128 void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) { 129 assert(1 <= Size && Size <= 8 && "Invalid size"); 130 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) && 131 "Invalid size"); 132 char buf[8]; 133 const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian(); 134 for (unsigned i = 0; i != Size; ++i) { 135 unsigned index = isLittleEndian ? i : (Size - i - 1); 136 buf[i] = uint8_t(Value >> (index * 8)); 137 } 138 EmitBytes(StringRef(buf, Size)); 139 } 140 141 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the 142 /// client having to pass in a MCExpr for constant integers. 143 void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned PadTo) { 144 SmallString<128> Tmp; 145 raw_svector_ostream OSE(Tmp); 146 encodeULEB128(Value, OSE, PadTo); 147 EmitBytes(OSE.str()); 148 } 149 150 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the 151 /// client having to pass in a MCExpr for constant integers. 152 void MCStreamer::EmitSLEB128IntValue(int64_t Value) { 153 SmallString<128> Tmp; 154 raw_svector_ostream OSE(Tmp); 155 encodeSLEB128(Value, OSE); 156 EmitBytes(OSE.str()); 157 } 158 159 void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) { 160 EmitValueImpl(Value, Size, Loc); 161 } 162 163 void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, 164 bool IsSectionRelative) { 165 assert((!IsSectionRelative || Size == 4) && 166 "SectionRelative value requires 4-bytes"); 167 168 if (!IsSectionRelative) 169 EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size); 170 else 171 EmitCOFFSecRel32(Sym, /*Offset=*/0); 172 } 173 174 void MCStreamer::EmitDTPRel64Value(const MCExpr *Value) { 175 report_fatal_error("unsupported directive in streamer"); 176 } 177 178 void MCStreamer::EmitDTPRel32Value(const MCExpr *Value) { 179 report_fatal_error("unsupported directive in streamer"); 180 } 181 182 void MCStreamer::EmitTPRel64Value(const MCExpr *Value) { 183 report_fatal_error("unsupported directive in streamer"); 184 } 185 186 void MCStreamer::EmitTPRel32Value(const MCExpr *Value) { 187 report_fatal_error("unsupported directive in streamer"); 188 } 189 190 void MCStreamer::EmitGPRel64Value(const MCExpr *Value) { 191 report_fatal_error("unsupported directive in streamer"); 192 } 193 194 void MCStreamer::EmitGPRel32Value(const MCExpr *Value) { 195 report_fatal_error("unsupported directive in streamer"); 196 } 197 198 /// Emit NumBytes bytes worth of the value specified by FillValue. 199 /// This implements directives such as '.space'. 200 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) { 201 emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue); 202 } 203 204 /// The implementation in this class just redirects to emitFill. 205 void MCStreamer::EmitZeros(uint64_t NumBytes) { 206 emitFill(NumBytes, 0); 207 } 208 209 Expected<unsigned> 210 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, 211 StringRef Filename, 212 Optional<MD5::MD5Result> Checksum, 213 Optional<StringRef> Source, 214 unsigned CUID) { 215 return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum, 216 Source, CUID); 217 } 218 219 void MCStreamer::emitDwarfFile0Directive(StringRef Directory, 220 StringRef Filename, 221 Optional<MD5::MD5Result> Checksum, 222 Optional<StringRef> Source, 223 unsigned CUID) { 224 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum, 225 Source); 226 } 227 228 void MCStreamer::EmitCFIBKeyFrame() { 229 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 230 if (!CurFrame) 231 return; 232 CurFrame->IsBKeyFrame = true; 233 } 234 235 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 236 unsigned Column, unsigned Flags, 237 unsigned Isa, 238 unsigned Discriminator, 239 StringRef FileName) { 240 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa, 241 Discriminator); 242 } 243 244 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) { 245 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID); 246 if (!Table.getLabel()) { 247 StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix(); 248 Table.setLabel( 249 Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID))); 250 } 251 return Table.getLabel(); 252 } 253 254 bool MCStreamer::hasUnfinishedDwarfFrameInfo() { 255 return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End; 256 } 257 258 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() { 259 if (!hasUnfinishedDwarfFrameInfo()) { 260 getContext().reportError(SMLoc(), "this directive must appear between " 261 ".cfi_startproc and .cfi_endproc " 262 "directives"); 263 return nullptr; 264 } 265 return &DwarfFrameInfos.back(); 266 } 267 268 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename, 269 ArrayRef<uint8_t> Checksum, 270 unsigned ChecksumKind) { 271 return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum, 272 ChecksumKind); 273 } 274 275 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) { 276 return getContext().getCVContext().recordFunctionId(FunctionId); 277 } 278 279 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId, 280 unsigned IAFunc, unsigned IAFile, 281 unsigned IALine, unsigned IACol, 282 SMLoc Loc) { 283 if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) { 284 getContext().reportError(Loc, "parent function id not introduced by " 285 ".cv_func_id or .cv_inline_site_id"); 286 return true; 287 } 288 289 return getContext().getCVContext().recordInlinedCallSiteId( 290 FunctionId, IAFunc, IAFile, IALine, IACol); 291 } 292 293 void MCStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, 294 unsigned Line, unsigned Column, 295 bool PrologueEnd, bool IsStmt, 296 StringRef FileName, SMLoc Loc) {} 297 298 bool MCStreamer::checkCVLocSection(unsigned FuncId, unsigned FileNo, 299 SMLoc Loc) { 300 CodeViewContext &CVC = getContext().getCVContext(); 301 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId); 302 if (!FI) { 303 getContext().reportError( 304 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id"); 305 return false; 306 } 307 308 // Track the section 309 if (FI->Section == nullptr) 310 FI->Section = getCurrentSectionOnly(); 311 else if (FI->Section != getCurrentSectionOnly()) { 312 getContext().reportError( 313 Loc, 314 "all .cv_loc directives for a function must be in the same section"); 315 return false; 316 } 317 return true; 318 } 319 320 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId, 321 const MCSymbol *Begin, 322 const MCSymbol *End) {} 323 324 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId, 325 unsigned SourceFileId, 326 unsigned SourceLineNum, 327 const MCSymbol *FnStartSym, 328 const MCSymbol *FnEndSym) {} 329 330 void MCStreamer::EmitCVDefRangeDirective( 331 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, 332 StringRef FixedSizePortion) {} 333 334 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, 335 MCSymbol *EHSymbol) { 336 } 337 338 void MCStreamer::InitSections(bool NoExecStack) { 339 SwitchSection(getContext().getObjectFileInfo()->getTextSection()); 340 } 341 342 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) { 343 assert(Fragment); 344 Symbol->setFragment(Fragment); 345 346 // As we emit symbols into a section, track the order so that they can 347 // be sorted upon later. Zero is reserved to mean 'unemitted'. 348 SymbolOrdering[Symbol] = 1 + SymbolOrdering.size(); 349 } 350 351 void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { 352 Symbol->redefineIfPossible(); 353 354 if (!Symbol->isUndefined() || Symbol->isVariable()) 355 return getContext().reportError(Loc, "invalid symbol redefinition"); 356 357 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 358 assert(getCurrentSectionOnly() && "Cannot emit before setting section!"); 359 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!"); 360 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 361 362 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment()); 363 364 MCTargetStreamer *TS = getTargetStreamer(); 365 if (TS) 366 TS->emitLabel(Symbol); 367 } 368 369 void MCStreamer::EmitCFISections(bool EH, bool Debug) { 370 assert(EH || Debug); 371 } 372 373 void MCStreamer::EmitCFIStartProc(bool IsSimple, SMLoc Loc) { 374 if (hasUnfinishedDwarfFrameInfo()) 375 return getContext().reportError( 376 Loc, "starting new .cfi frame before finishing the previous one"); 377 378 MCDwarfFrameInfo Frame; 379 Frame.IsSimple = IsSimple; 380 EmitCFIStartProcImpl(Frame); 381 382 const MCAsmInfo* MAI = Context.getAsmInfo(); 383 if (MAI) { 384 for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) { 385 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa || 386 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) { 387 Frame.CurrentCfaRegister = Inst.getRegister(); 388 } 389 } 390 } 391 392 DwarfFrameInfos.push_back(Frame); 393 } 394 395 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 396 } 397 398 void MCStreamer::EmitCFIEndProc() { 399 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 400 if (!CurFrame) 401 return; 402 EmitCFIEndProcImpl(*CurFrame); 403 } 404 405 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 406 // Put a dummy non-null value in Frame.End to mark that this frame has been 407 // closed. 408 Frame.End = (MCSymbol *)1; 409 } 410 411 MCSymbol *MCStreamer::EmitCFILabel() { 412 // Return a dummy non-null value so that label fields appear filled in when 413 // generating textual assembly. 414 return (MCSymbol *)1; 415 } 416 417 void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { 418 MCSymbol *Label = EmitCFILabel(); 419 MCCFIInstruction Instruction = 420 MCCFIInstruction::createDefCfa(Label, Register, Offset); 421 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 422 if (!CurFrame) 423 return; 424 CurFrame->Instructions.push_back(Instruction); 425 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register); 426 } 427 428 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 429 MCSymbol *Label = EmitCFILabel(); 430 MCCFIInstruction Instruction = 431 MCCFIInstruction::createDefCfaOffset(Label, Offset); 432 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 433 if (!CurFrame) 434 return; 435 CurFrame->Instructions.push_back(Instruction); 436 } 437 438 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { 439 MCSymbol *Label = EmitCFILabel(); 440 MCCFIInstruction Instruction = 441 MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment); 442 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 443 if (!CurFrame) 444 return; 445 CurFrame->Instructions.push_back(Instruction); 446 } 447 448 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { 449 MCSymbol *Label = EmitCFILabel(); 450 MCCFIInstruction Instruction = 451 MCCFIInstruction::createDefCfaRegister(Label, Register); 452 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 453 if (!CurFrame) 454 return; 455 CurFrame->Instructions.push_back(Instruction); 456 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register); 457 } 458 459 void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 460 MCSymbol *Label = EmitCFILabel(); 461 MCCFIInstruction Instruction = 462 MCCFIInstruction::createOffset(Label, Register, Offset); 463 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 464 if (!CurFrame) 465 return; 466 CurFrame->Instructions.push_back(Instruction); 467 } 468 469 void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { 470 MCSymbol *Label = EmitCFILabel(); 471 MCCFIInstruction Instruction = 472 MCCFIInstruction::createRelOffset(Label, Register, Offset); 473 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 474 if (!CurFrame) 475 return; 476 CurFrame->Instructions.push_back(Instruction); 477 } 478 479 void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym, 480 unsigned Encoding) { 481 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 482 if (!CurFrame) 483 return; 484 CurFrame->Personality = Sym; 485 CurFrame->PersonalityEncoding = Encoding; 486 } 487 488 void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { 489 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 490 if (!CurFrame) 491 return; 492 CurFrame->Lsda = Sym; 493 CurFrame->LsdaEncoding = Encoding; 494 } 495 496 void MCStreamer::EmitCFIRememberState() { 497 MCSymbol *Label = EmitCFILabel(); 498 MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label); 499 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 500 if (!CurFrame) 501 return; 502 CurFrame->Instructions.push_back(Instruction); 503 } 504 505 void MCStreamer::EmitCFIRestoreState() { 506 // FIXME: Error if there is no matching cfi_remember_state. 507 MCSymbol *Label = EmitCFILabel(); 508 MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label); 509 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 510 if (!CurFrame) 511 return; 512 CurFrame->Instructions.push_back(Instruction); 513 } 514 515 void MCStreamer::EmitCFISameValue(int64_t Register) { 516 MCSymbol *Label = EmitCFILabel(); 517 MCCFIInstruction Instruction = 518 MCCFIInstruction::createSameValue(Label, Register); 519 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 520 if (!CurFrame) 521 return; 522 CurFrame->Instructions.push_back(Instruction); 523 } 524 525 void MCStreamer::EmitCFIRestore(int64_t Register) { 526 MCSymbol *Label = EmitCFILabel(); 527 MCCFIInstruction Instruction = 528 MCCFIInstruction::createRestore(Label, Register); 529 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 530 if (!CurFrame) 531 return; 532 CurFrame->Instructions.push_back(Instruction); 533 } 534 535 void MCStreamer::EmitCFIEscape(StringRef Values) { 536 MCSymbol *Label = EmitCFILabel(); 537 MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values); 538 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 539 if (!CurFrame) 540 return; 541 CurFrame->Instructions.push_back(Instruction); 542 } 543 544 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) { 545 MCSymbol *Label = EmitCFILabel(); 546 MCCFIInstruction Instruction = 547 MCCFIInstruction::createGnuArgsSize(Label, Size); 548 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 549 if (!CurFrame) 550 return; 551 CurFrame->Instructions.push_back(Instruction); 552 } 553 554 void MCStreamer::EmitCFISignalFrame() { 555 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 556 if (!CurFrame) 557 return; 558 CurFrame->IsSignalFrame = true; 559 } 560 561 void MCStreamer::EmitCFIUndefined(int64_t Register) { 562 MCSymbol *Label = EmitCFILabel(); 563 MCCFIInstruction Instruction = 564 MCCFIInstruction::createUndefined(Label, Register); 565 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 566 if (!CurFrame) 567 return; 568 CurFrame->Instructions.push_back(Instruction); 569 } 570 571 void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) { 572 MCSymbol *Label = EmitCFILabel(); 573 MCCFIInstruction Instruction = 574 MCCFIInstruction::createRegister(Label, Register1, Register2); 575 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 576 if (!CurFrame) 577 return; 578 CurFrame->Instructions.push_back(Instruction); 579 } 580 581 void MCStreamer::EmitCFIWindowSave() { 582 MCSymbol *Label = EmitCFILabel(); 583 MCCFIInstruction Instruction = 584 MCCFIInstruction::createWindowSave(Label); 585 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 586 if (!CurFrame) 587 return; 588 CurFrame->Instructions.push_back(Instruction); 589 } 590 591 void MCStreamer::EmitCFINegateRAState() { 592 MCSymbol *Label = EmitCFILabel(); 593 MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label); 594 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 595 if (!CurFrame) 596 return; 597 CurFrame->Instructions.push_back(Instruction); 598 } 599 600 void MCStreamer::EmitCFIReturnColumn(int64_t Register) { 601 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 602 if (!CurFrame) 603 return; 604 CurFrame->RAReg = Register; 605 } 606 607 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) { 608 const MCAsmInfo *MAI = Context.getAsmInfo(); 609 if (!MAI->usesWindowsCFI()) { 610 getContext().reportError( 611 Loc, ".seh_* directives are not supported on this target"); 612 return nullptr; 613 } 614 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) { 615 getContext().reportError( 616 Loc, ".seh_ directive must appear within an active frame"); 617 return nullptr; 618 } 619 return CurrentWinFrameInfo; 620 } 621 622 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) { 623 const MCAsmInfo *MAI = Context.getAsmInfo(); 624 if (!MAI->usesWindowsCFI()) 625 return getContext().reportError( 626 Loc, ".seh_* directives are not supported on this target"); 627 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End) 628 getContext().reportError( 629 Loc, "Starting a function before ending the previous one!"); 630 631 MCSymbol *StartProc = EmitCFILabel(); 632 633 WinFrameInfos.emplace_back( 634 llvm::make_unique<WinEH::FrameInfo>(Symbol, StartProc)); 635 CurrentWinFrameInfo = WinFrameInfos.back().get(); 636 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly(); 637 } 638 639 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) { 640 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 641 if (!CurFrame) 642 return; 643 if (CurFrame->ChainedParent) 644 getContext().reportError(Loc, "Not all chained regions terminated!"); 645 646 MCSymbol *Label = EmitCFILabel(); 647 CurFrame->End = Label; 648 } 649 650 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) { 651 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 652 if (!CurFrame) 653 return; 654 if (CurFrame->ChainedParent) 655 getContext().reportError(Loc, "Not all chained regions terminated!"); 656 657 MCSymbol *Label = EmitCFILabel(); 658 CurFrame->FuncletOrFuncEnd = Label; 659 } 660 661 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) { 662 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 663 if (!CurFrame) 664 return; 665 666 MCSymbol *StartProc = EmitCFILabel(); 667 668 WinFrameInfos.emplace_back(llvm::make_unique<WinEH::FrameInfo>( 669 CurFrame->Function, StartProc, CurFrame)); 670 CurrentWinFrameInfo = WinFrameInfos.back().get(); 671 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly(); 672 } 673 674 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) { 675 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 676 if (!CurFrame) 677 return; 678 if (!CurFrame->ChainedParent) 679 return getContext().reportError( 680 Loc, "End of a chained region outside a chained region!"); 681 682 MCSymbol *Label = EmitCFILabel(); 683 684 CurFrame->End = Label; 685 CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent); 686 } 687 688 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except, 689 SMLoc Loc) { 690 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 691 if (!CurFrame) 692 return; 693 if (CurFrame->ChainedParent) 694 return getContext().reportError( 695 Loc, "Chained unwind areas can't have handlers!"); 696 CurFrame->ExceptionHandler = Sym; 697 if (!Except && !Unwind) 698 getContext().reportError(Loc, "Don't know what kind of handler this is!"); 699 if (Unwind) 700 CurFrame->HandlesUnwind = true; 701 if (Except) 702 CurFrame->HandlesExceptions = true; 703 } 704 705 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) { 706 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 707 if (!CurFrame) 708 return; 709 if (CurFrame->ChainedParent) 710 getContext().reportError(Loc, "Chained unwind areas can't have handlers!"); 711 } 712 713 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From, 714 const MCSymbolRefExpr *To, uint64_t Count) { 715 } 716 717 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID, 718 MCSection *MainCFISec, 719 const MCSection *TextSec) { 720 // If this is the main .text section, use the main unwind info section. 721 if (TextSec == Context.getObjectFileInfo()->getTextSection()) 722 return MainCFISec; 723 724 const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec); 725 auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec); 726 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID); 727 728 // If this section is COMDAT, this unwind section should be COMDAT associative 729 // with its group. 730 const MCSymbol *KeySym = nullptr; 731 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) { 732 KeySym = TextSecCOFF->getCOMDATSymbol(); 733 734 // In a GNU environment, we can't use associative comdats. Instead, do what 735 // GCC does, which is to make plain comdat selectany section named like 736 // ".[px]data$_Z3foov". 737 if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) { 738 std::string SectionName = 739 (MainCFISecCOFF->getSectionName() + "$" + 740 TextSecCOFF->getSectionName().split('$').second) 741 .str(); 742 return Context.getCOFFSection( 743 SectionName, 744 MainCFISecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT, 745 MainCFISecCOFF->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY); 746 } 747 } 748 749 return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID); 750 } 751 752 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) { 753 return getWinCFISection(getContext(), &NextWinCFIID, 754 getContext().getObjectFileInfo()->getPDataSection(), 755 TextSec); 756 } 757 758 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) { 759 return getWinCFISection(getContext(), &NextWinCFIID, 760 getContext().getObjectFileInfo()->getXDataSection(), 761 TextSec); 762 } 763 764 void MCStreamer::EmitSyntaxDirective() {} 765 766 void MCStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) { 767 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 768 if (!CurFrame) 769 return; 770 771 MCSymbol *Label = EmitCFILabel(); 772 773 WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register); 774 CurFrame->Instructions.push_back(Inst); 775 } 776 777 void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset, 778 SMLoc Loc) { 779 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 780 if (!CurFrame) 781 return; 782 if (CurFrame->LastFrameInst >= 0) 783 return getContext().reportError( 784 Loc, "frame register and offset can be set at most once"); 785 if (Offset & 0x0F) 786 return getContext().reportError(Loc, "offset is not a multiple of 16"); 787 if (Offset > 240) 788 return getContext().reportError( 789 Loc, "frame offset must be less than or equal to 240"); 790 791 MCSymbol *Label = EmitCFILabel(); 792 793 WinEH::Instruction Inst = 794 Win64EH::Instruction::SetFPReg(Label, Register, Offset); 795 CurFrame->LastFrameInst = CurFrame->Instructions.size(); 796 CurFrame->Instructions.push_back(Inst); 797 } 798 799 void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) { 800 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 801 if (!CurFrame) 802 return; 803 if (Size == 0) 804 return getContext().reportError(Loc, 805 "stack allocation size must be non-zero"); 806 if (Size & 7) 807 return getContext().reportError( 808 Loc, "stack allocation size is not a multiple of 8"); 809 810 MCSymbol *Label = EmitCFILabel(); 811 812 WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size); 813 CurFrame->Instructions.push_back(Inst); 814 } 815 816 void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset, 817 SMLoc Loc) { 818 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 819 if (!CurFrame) 820 return; 821 822 if (Offset & 7) 823 return getContext().reportError( 824 Loc, "register save offset is not 8 byte aligned"); 825 826 MCSymbol *Label = EmitCFILabel(); 827 828 WinEH::Instruction Inst = 829 Win64EH::Instruction::SaveNonVol(Label, Register, Offset); 830 CurFrame->Instructions.push_back(Inst); 831 } 832 833 void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset, 834 SMLoc Loc) { 835 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 836 if (!CurFrame) 837 return; 838 if (Offset & 0x0F) 839 return getContext().reportError(Loc, "offset is not a multiple of 16"); 840 841 MCSymbol *Label = EmitCFILabel(); 842 843 WinEH::Instruction Inst = 844 Win64EH::Instruction::SaveXMM(Label, Register, Offset); 845 CurFrame->Instructions.push_back(Inst); 846 } 847 848 void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) { 849 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 850 if (!CurFrame) 851 return; 852 if (!CurFrame->Instructions.empty()) 853 return getContext().reportError( 854 Loc, "If present, PushMachFrame must be the first UOP"); 855 856 MCSymbol *Label = EmitCFILabel(); 857 858 WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code); 859 CurFrame->Instructions.push_back(Inst); 860 } 861 862 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) { 863 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc); 864 if (!CurFrame) 865 return; 866 867 MCSymbol *Label = EmitCFILabel(); 868 869 CurFrame->PrologEnd = Label; 870 } 871 872 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {} 873 874 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {} 875 876 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {} 877 878 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {} 879 880 void MCStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {} 881 882 /// EmitRawText - If this file is backed by an assembly streamer, this dumps 883 /// the specified string in the output .s file. This capability is 884 /// indicated by the hasRawTextSupport() predicate. 885 void MCStreamer::EmitRawTextImpl(StringRef String) { 886 // This is not llvm_unreachable for the sake of out of tree backend 887 // developers who may not have assembly streamers and should serve as a 888 // reminder to not accidentally call EmitRawText in the absence of such. 889 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support " 890 "it (target backend is likely missing an AsmStreamer " 891 "implementation)"); 892 } 893 894 void MCStreamer::EmitRawText(const Twine &T) { 895 SmallString<128> Str; 896 EmitRawTextImpl(T.toStringRef(Str)); 897 } 898 899 void MCStreamer::EmitWindowsUnwindTables() { 900 } 901 902 void MCStreamer::Finish() { 903 if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) || 904 (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) { 905 getContext().reportError(SMLoc(), "Unfinished frame!"); 906 return; 907 } 908 909 MCTargetStreamer *TS = getTargetStreamer(); 910 if (TS) 911 TS->finish(); 912 913 FinishImpl(); 914 } 915 916 void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 917 visitUsedExpr(*Value); 918 Symbol->setVariableValue(Value); 919 920 MCTargetStreamer *TS = getTargetStreamer(); 921 if (TS) 922 TS->emitAssignment(Symbol, Value); 923 } 924 925 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter, 926 raw_ostream &OS, const MCInst &Inst, 927 const MCSubtargetInfo &STI) { 928 InstPrinter.printInst(&Inst, OS, "", STI); 929 } 930 931 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) { 932 } 933 934 void MCStreamer::visitUsedExpr(const MCExpr &Expr) { 935 switch (Expr.getKind()) { 936 case MCExpr::Target: 937 cast<MCTargetExpr>(Expr).visitUsedExpr(*this); 938 break; 939 940 case MCExpr::Constant: 941 break; 942 943 case MCExpr::Binary: { 944 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr); 945 visitUsedExpr(*BE.getLHS()); 946 visitUsedExpr(*BE.getRHS()); 947 break; 948 } 949 950 case MCExpr::SymbolRef: 951 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol()); 952 break; 953 954 case MCExpr::Unary: 955 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr()); 956 break; 957 } 958 } 959 960 void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &) { 961 // Scan for values. 962 for (unsigned i = Inst.getNumOperands(); i--;) 963 if (Inst.getOperand(i).isExpr()) 964 visitUsedExpr(*Inst.getOperand(i).getExpr()); 965 } 966 967 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, 968 unsigned Size) { 969 // Get the Hi-Lo expression. 970 const MCExpr *Diff = 971 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context), 972 MCSymbolRefExpr::create(Lo, Context), Context); 973 974 const MCAsmInfo *MAI = Context.getAsmInfo(); 975 if (!MAI->doesSetDirectiveSuppressReloc()) { 976 EmitValue(Diff, Size); 977 return; 978 } 979 980 // Otherwise, emit with .set (aka assignment). 981 MCSymbol *SetLabel = Context.createTempSymbol("set", true); 982 EmitAssignment(SetLabel, Diff); 983 EmitSymbolValue(SetLabel, Size); 984 } 985 986 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi, 987 const MCSymbol *Lo) { 988 // Get the Hi-Lo expression. 989 const MCExpr *Diff = 990 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context), 991 MCSymbolRefExpr::create(Lo, Context), Context); 992 993 EmitULEB128Value(Diff); 994 } 995 996 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {} 997 void MCStreamer::EmitThumbFunc(MCSymbol *Func) {} 998 void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {} 999 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) { 1000 llvm_unreachable("this directive only supported on COFF targets"); 1001 } 1002 void MCStreamer::EndCOFFSymbolDef() { 1003 llvm_unreachable("this directive only supported on COFF targets"); 1004 } 1005 void MCStreamer::EmitFileDirective(StringRef Filename) {} 1006 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) { 1007 llvm_unreachable("this directive only supported on COFF targets"); 1008 } 1009 void MCStreamer::EmitCOFFSymbolType(int Type) { 1010 llvm_unreachable("this directive only supported on COFF targets"); 1011 } 1012 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {} 1013 void MCStreamer::emitELFSymverDirective(StringRef AliasName, 1014 const MCSymbol *Aliasee) {} 1015 void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 1016 unsigned ByteAlignment) {} 1017 void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, 1018 uint64_t Size, unsigned ByteAlignment) {} 1019 void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {} 1020 void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {} 1021 void MCStreamer::EmitBytes(StringRef Data) {} 1022 void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); } 1023 void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) { 1024 visitUsedExpr(*Value); 1025 } 1026 void MCStreamer::EmitULEB128Value(const MCExpr *Value) {} 1027 void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {} 1028 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {} 1029 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr, 1030 SMLoc Loc) {} 1031 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, 1032 unsigned ValueSize, 1033 unsigned MaxBytesToEmit) {} 1034 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment, 1035 unsigned MaxBytesToEmit) {} 1036 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value, 1037 SMLoc Loc) {} 1038 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {} 1039 void MCStreamer::EmitBundleLock(bool AlignToEnd) {} 1040 void MCStreamer::FinishImpl() {} 1041 void MCStreamer::EmitBundleUnlock() {} 1042 1043 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) { 1044 assert(Section && "Cannot switch to a null section!"); 1045 MCSectionSubPair curSection = SectionStack.back().first; 1046 SectionStack.back().second = curSection; 1047 if (MCSectionSubPair(Section, Subsection) != curSection) { 1048 ChangeSection(Section, Subsection); 1049 SectionStack.back().first = MCSectionSubPair(Section, Subsection); 1050 assert(!Section->hasEnded() && "Section already ended"); 1051 MCSymbol *Sym = Section->getBeginSymbol(); 1052 if (Sym && !Sym->isInSection()) 1053 EmitLabel(Sym); 1054 } 1055 } 1056 1057 MCSymbol *MCStreamer::endSection(MCSection *Section) { 1058 // TODO: keep track of the last subsection so that this symbol appears in the 1059 // correct place. 1060 MCSymbol *Sym = Section->getEndSymbol(Context); 1061 if (Sym->isInSection()) 1062 return Sym; 1063 1064 SwitchSection(Section); 1065 EmitLabel(Sym); 1066 return Sym; 1067 } 1068 1069 void MCStreamer::EmitVersionForTarget(const Triple &Target, 1070 const VersionTuple &SDKVersion) { 1071 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin()) 1072 return; 1073 // Do we even know the version? 1074 if (Target.getOSMajorVersion() == 0) 1075 return; 1076 1077 unsigned Major; 1078 unsigned Minor; 1079 unsigned Update; 1080 if (Target.isMacCatalystEnvironment()) { 1081 // Mac Catalyst always uses the build version load command. 1082 Target.getiOSVersion(Major, Minor, Update); 1083 assert(Major && "A non-zero major version is expected"); 1084 EmitBuildVersion(MachO::PLATFORM_MACCATALYST, Major, Minor, Update, 1085 SDKVersion); 1086 return; 1087 } 1088 1089 MCVersionMinType VersionType; 1090 if (Target.isWatchOS()) { 1091 VersionType = MCVM_WatchOSVersionMin; 1092 Target.getWatchOSVersion(Major, Minor, Update); 1093 } else if (Target.isTvOS()) { 1094 VersionType = MCVM_TvOSVersionMin; 1095 Target.getiOSVersion(Major, Minor, Update); 1096 } else if (Target.isMacOSX()) { 1097 VersionType = MCVM_OSXVersionMin; 1098 if (!Target.getMacOSXVersion(Major, Minor, Update)) 1099 Major = 0; 1100 } else { 1101 VersionType = MCVM_IOSVersionMin; 1102 Target.getiOSVersion(Major, Minor, Update); 1103 } 1104 if (Major != 0) 1105 EmitVersionMin(VersionType, Major, Minor, Update, SDKVersion); 1106 } 1107