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