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