1 //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ADT/SmallString.h" 11 #include "llvm/ADT/StringRef.h" 12 #include "llvm/ADT/Twine.h" 13 #include "llvm/MC/MCAsmBackend.h" 14 #include "llvm/MC/MCAsmInfo.h" 15 #include "llvm/MC/MCCodeView.h" 16 #include "llvm/MC/MCContext.h" 17 #include "llvm/MC/MCDwarf.h" 18 #include "llvm/MC/MCExpr.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCInstPrinter.h" 21 #include "llvm/MC/MCObjectFileInfo.h" 22 #include "llvm/MC/MCSection.h" 23 #include "llvm/MC/MCSectionCOFF.h" 24 #include "llvm/MC/MCStreamer.h" 25 #include "llvm/MC/MCSymbol.h" 26 #include "llvm/MC/MCWin64EH.h" 27 #include "llvm/MC/MCWinEH.h" 28 #include "llvm/Support/Casting.h" 29 #include "llvm/Support/COFF.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 <cstdlib> 35 #include <cassert> 36 #include <cstdint> 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::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {} 53 54 MCStreamer::MCStreamer(MCContext &Ctx) 55 : Context(Ctx), CurrentWinFrameInfo(nullptr) { 56 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); 57 } 58 59 MCStreamer::~MCStreamer() { 60 for (unsigned i = 0; i < getNumWinFrameInfos(); ++i) 61 delete WinFrameInfos[i]; 62 } 63 64 void MCStreamer::reset() { 65 DwarfFrameInfos.clear(); 66 for (unsigned i = 0; i < getNumWinFrameInfos(); ++i) 67 delete WinFrameInfos[i]; 68 WinFrameInfos.clear(); 69 CurrentWinFrameInfo = nullptr; 70 SymbolOrdering.clear(); 71 SectionStack.clear(); 72 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); 73 } 74 75 raw_ostream &MCStreamer::GetCommentOS() { 76 // By default, discard comments. 77 return nulls(); 78 } 79 80 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {} 81 82 void MCStreamer::addExplicitComment(const Twine &T) {} 83 void MCStreamer::emitExplicitComments() {} 84 85 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) { 86 for (auto &FI : DwarfFrameInfos) 87 FI.CompactUnwindEncoding = 88 (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0); 89 } 90 91 /// EmitIntValue - Special case of EmitValue that avoids the client having to 92 /// pass in a MCExpr for constant integers. 93 void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) { 94 assert(1 <= Size && Size <= 8 && "Invalid size"); 95 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) && 96 "Invalid size"); 97 char buf[8]; 98 const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian(); 99 for (unsigned i = 0; i != Size; ++i) { 100 unsigned index = isLittleEndian ? i : (Size - i - 1); 101 buf[i] = uint8_t(Value >> (index * 8)); 102 } 103 EmitBytes(StringRef(buf, Size)); 104 } 105 106 /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the 107 /// client having to pass in a MCExpr for constant integers. 108 void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned Padding) { 109 SmallString<128> Tmp; 110 raw_svector_ostream OSE(Tmp); 111 encodeULEB128(Value, OSE, Padding); 112 EmitBytes(OSE.str()); 113 } 114 115 /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the 116 /// client having to pass in a MCExpr for constant integers. 117 void MCStreamer::EmitSLEB128IntValue(int64_t Value) { 118 SmallString<128> Tmp; 119 raw_svector_ostream OSE(Tmp); 120 encodeSLEB128(Value, OSE); 121 EmitBytes(OSE.str()); 122 } 123 124 void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) { 125 EmitValueImpl(Value, Size, Loc); 126 } 127 128 void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, 129 bool IsSectionRelative) { 130 assert((!IsSectionRelative || Size == 4) && 131 "SectionRelative value requires 4-bytes"); 132 133 if (!IsSectionRelative) 134 EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size); 135 else 136 EmitCOFFSecRel32(Sym, /*Offset=*/0); 137 } 138 139 void MCStreamer::EmitDTPRel64Value(const MCExpr *Value) { 140 report_fatal_error("unsupported directive in streamer"); 141 } 142 143 void MCStreamer::EmitDTPRel32Value(const MCExpr *Value) { 144 report_fatal_error("unsupported directive in streamer"); 145 } 146 147 void MCStreamer::EmitTPRel64Value(const MCExpr *Value) { 148 report_fatal_error("unsupported directive in streamer"); 149 } 150 151 void MCStreamer::EmitTPRel32Value(const MCExpr *Value) { 152 report_fatal_error("unsupported directive in streamer"); 153 } 154 155 void MCStreamer::EmitGPRel64Value(const MCExpr *Value) { 156 report_fatal_error("unsupported directive in streamer"); 157 } 158 159 void MCStreamer::EmitGPRel32Value(const MCExpr *Value) { 160 report_fatal_error("unsupported directive in streamer"); 161 } 162 163 /// Emit NumBytes bytes worth of the value specified by FillValue. 164 /// This implements directives such as '.space'. 165 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) { 166 for (uint64_t i = 0, e = NumBytes; i != e; ++i) 167 EmitIntValue(FillValue, 1); 168 } 169 170 void MCStreamer::emitFill(uint64_t NumValues, int64_t Size, int64_t Expr) { 171 int64_t NonZeroSize = Size > 4 ? 4 : Size; 172 Expr &= ~0ULL >> (64 - NonZeroSize * 8); 173 for (uint64_t i = 0, e = NumValues; i != e; ++i) { 174 EmitIntValue(Expr, NonZeroSize); 175 if (NonZeroSize < Size) 176 EmitIntValue(0, Size - NonZeroSize); 177 } 178 } 179 180 /// The implementation in this class just redirects to emitFill. 181 void MCStreamer::EmitZeros(uint64_t NumBytes) { 182 emitFill(NumBytes, 0); 183 } 184 185 unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo, 186 StringRef Directory, 187 StringRef Filename, unsigned CUID) { 188 return getContext().getDwarfFile(Directory, Filename, FileNo, CUID); 189 } 190 191 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 192 unsigned Column, unsigned Flags, 193 unsigned Isa, 194 unsigned Discriminator, 195 StringRef FileName) { 196 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa, 197 Discriminator); 198 } 199 200 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) { 201 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID); 202 if (!Table.getLabel()) { 203 StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix(); 204 Table.setLabel( 205 Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID))); 206 } 207 return Table.getLabel(); 208 } 209 210 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() { 211 if (DwarfFrameInfos.empty()) 212 return nullptr; 213 return &DwarfFrameInfos.back(); 214 } 215 216 bool MCStreamer::hasUnfinishedDwarfFrameInfo() { 217 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 218 return CurFrame && !CurFrame->End; 219 } 220 221 void MCStreamer::EnsureValidDwarfFrame() { 222 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 223 if (!CurFrame || CurFrame->End) 224 report_fatal_error("No open frame"); 225 } 226 227 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename) { 228 return getContext().getCVContext().addFile(FileNo, Filename); 229 } 230 231 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) { 232 return getContext().getCVContext().recordFunctionId(FunctionId); 233 } 234 235 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId, 236 unsigned IAFunc, unsigned IAFile, 237 unsigned IALine, unsigned IACol, 238 SMLoc Loc) { 239 if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) { 240 getContext().reportError(Loc, "parent function id not introduced by " 241 ".cv_func_id or .cv_inline_site_id"); 242 return true; 243 } 244 245 return getContext().getCVContext().recordInlinedCallSiteId( 246 FunctionId, IAFunc, IAFile, IALine, IACol); 247 } 248 249 void MCStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, 250 unsigned Line, unsigned Column, 251 bool PrologueEnd, bool IsStmt, 252 StringRef FileName, SMLoc Loc) { 253 CodeViewContext &CVC = getContext().getCVContext(); 254 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FunctionId); 255 if (!FI) 256 return getContext().reportError( 257 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id"); 258 259 // Track the section 260 if (FI->Section == nullptr) 261 FI->Section = getCurrentSectionOnly(); 262 else if (FI->Section != getCurrentSectionOnly()) 263 return getContext().reportError( 264 Loc, 265 "all .cv_loc directives for a function must be in the same section"); 266 267 CVC.setCurrentCVLoc(FunctionId, FileNo, Line, Column, PrologueEnd, IsStmt); 268 } 269 270 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId, 271 const MCSymbol *Begin, 272 const MCSymbol *End) {} 273 274 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId, 275 unsigned SourceFileId, 276 unsigned SourceLineNum, 277 const MCSymbol *FnStartSym, 278 const MCSymbol *FnEndSym) {} 279 280 void MCStreamer::EmitCVDefRangeDirective( 281 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, 282 StringRef FixedSizePortion) {} 283 284 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, 285 MCSymbol *EHSymbol) { 286 } 287 288 void MCStreamer::InitSections(bool NoExecStack) { 289 SwitchSection(getContext().getObjectFileInfo()->getTextSection()); 290 } 291 292 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) { 293 assert(Fragment); 294 Symbol->setFragment(Fragment); 295 296 // As we emit symbols into a section, track the order so that they can 297 // be sorted upon later. Zero is reserved to mean 'unemitted'. 298 SymbolOrdering[Symbol] = 1 + SymbolOrdering.size(); 299 } 300 301 void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { 302 Symbol->redefineIfPossible(); 303 304 if (!Symbol->isUndefined() || Symbol->isVariable()) 305 return getContext().reportError(Loc, "invalid symbol redefinition"); 306 307 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 308 assert(getCurrentSectionOnly() && "Cannot emit before setting section!"); 309 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!"); 310 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 311 312 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment()); 313 314 MCTargetStreamer *TS = getTargetStreamer(); 315 if (TS) 316 TS->emitLabel(Symbol); 317 } 318 319 void MCStreamer::EmitCFISections(bool EH, bool Debug) { 320 assert(EH || Debug); 321 } 322 323 void MCStreamer::EmitCFIStartProc(bool IsSimple) { 324 if (hasUnfinishedDwarfFrameInfo()) 325 report_fatal_error("Starting a frame before finishing the previous one!"); 326 327 MCDwarfFrameInfo Frame; 328 Frame.IsSimple = IsSimple; 329 EmitCFIStartProcImpl(Frame); 330 331 const MCAsmInfo* MAI = Context.getAsmInfo(); 332 if (MAI) { 333 for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) { 334 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa || 335 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) { 336 Frame.CurrentCfaRegister = Inst.getRegister(); 337 } 338 } 339 } 340 341 DwarfFrameInfos.push_back(Frame); 342 } 343 344 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 345 } 346 347 void MCStreamer::EmitCFIEndProc() { 348 EnsureValidDwarfFrame(); 349 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 350 EmitCFIEndProcImpl(*CurFrame); 351 } 352 353 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 354 // Put a dummy non-null value in Frame.End to mark that this frame has been 355 // closed. 356 Frame.End = (MCSymbol *) 1; 357 } 358 359 MCSymbol *MCStreamer::EmitCFILabel() { 360 MCSymbol *Label = getContext().createTempSymbol("cfi", true); 361 EmitLabel(Label); 362 return Label; 363 } 364 365 MCSymbol *MCStreamer::EmitCFICommon() { 366 EnsureValidDwarfFrame(); 367 return EmitCFILabel(); 368 } 369 370 void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { 371 MCSymbol *Label = EmitCFICommon(); 372 MCCFIInstruction Instruction = 373 MCCFIInstruction::createDefCfa(Label, Register, Offset); 374 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 375 CurFrame->Instructions.push_back(Instruction); 376 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register); 377 } 378 379 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 380 MCSymbol *Label = EmitCFICommon(); 381 MCCFIInstruction Instruction = 382 MCCFIInstruction::createDefCfaOffset(Label, Offset); 383 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 384 CurFrame->Instructions.push_back(Instruction); 385 } 386 387 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { 388 MCSymbol *Label = EmitCFICommon(); 389 MCCFIInstruction Instruction = 390 MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment); 391 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 392 CurFrame->Instructions.push_back(Instruction); 393 } 394 395 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { 396 MCSymbol *Label = EmitCFICommon(); 397 MCCFIInstruction Instruction = 398 MCCFIInstruction::createDefCfaRegister(Label, Register); 399 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 400 CurFrame->Instructions.push_back(Instruction); 401 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register); 402 } 403 404 void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 405 MCSymbol *Label = EmitCFICommon(); 406 MCCFIInstruction Instruction = 407 MCCFIInstruction::createOffset(Label, Register, Offset); 408 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 409 CurFrame->Instructions.push_back(Instruction); 410 } 411 412 void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { 413 MCSymbol *Label = EmitCFICommon(); 414 MCCFIInstruction Instruction = 415 MCCFIInstruction::createRelOffset(Label, Register, Offset); 416 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 417 CurFrame->Instructions.push_back(Instruction); 418 } 419 420 void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym, 421 unsigned Encoding) { 422 EnsureValidDwarfFrame(); 423 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 424 CurFrame->Personality = Sym; 425 CurFrame->PersonalityEncoding = Encoding; 426 } 427 428 void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { 429 EnsureValidDwarfFrame(); 430 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 431 CurFrame->Lsda = Sym; 432 CurFrame->LsdaEncoding = Encoding; 433 } 434 435 void MCStreamer::EmitCFIRememberState() { 436 MCSymbol *Label = EmitCFICommon(); 437 MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label); 438 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 439 CurFrame->Instructions.push_back(Instruction); 440 } 441 442 void MCStreamer::EmitCFIRestoreState() { 443 // FIXME: Error if there is no matching cfi_remember_state. 444 MCSymbol *Label = EmitCFICommon(); 445 MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label); 446 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 447 CurFrame->Instructions.push_back(Instruction); 448 } 449 450 void MCStreamer::EmitCFISameValue(int64_t Register) { 451 MCSymbol *Label = EmitCFICommon(); 452 MCCFIInstruction Instruction = 453 MCCFIInstruction::createSameValue(Label, Register); 454 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 455 CurFrame->Instructions.push_back(Instruction); 456 } 457 458 void MCStreamer::EmitCFIRestore(int64_t Register) { 459 MCSymbol *Label = EmitCFICommon(); 460 MCCFIInstruction Instruction = 461 MCCFIInstruction::createRestore(Label, Register); 462 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 463 CurFrame->Instructions.push_back(Instruction); 464 } 465 466 void MCStreamer::EmitCFIEscape(StringRef Values) { 467 MCSymbol *Label = EmitCFICommon(); 468 MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values); 469 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 470 CurFrame->Instructions.push_back(Instruction); 471 } 472 473 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) { 474 MCSymbol *Label = EmitCFICommon(); 475 MCCFIInstruction Instruction = 476 MCCFIInstruction::createGnuArgsSize(Label, Size); 477 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 478 CurFrame->Instructions.push_back(Instruction); 479 } 480 481 void MCStreamer::EmitCFISignalFrame() { 482 EnsureValidDwarfFrame(); 483 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 484 CurFrame->IsSignalFrame = true; 485 } 486 487 void MCStreamer::EmitCFIUndefined(int64_t Register) { 488 MCSymbol *Label = EmitCFICommon(); 489 MCCFIInstruction Instruction = 490 MCCFIInstruction::createUndefined(Label, Register); 491 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 492 CurFrame->Instructions.push_back(Instruction); 493 } 494 495 void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) { 496 MCSymbol *Label = EmitCFICommon(); 497 MCCFIInstruction Instruction = 498 MCCFIInstruction::createRegister(Label, Register1, Register2); 499 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 500 CurFrame->Instructions.push_back(Instruction); 501 } 502 503 void MCStreamer::EmitCFIWindowSave() { 504 MCSymbol *Label = EmitCFICommon(); 505 MCCFIInstruction Instruction = 506 MCCFIInstruction::createWindowSave(Label); 507 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); 508 CurFrame->Instructions.push_back(Instruction); 509 } 510 511 void MCStreamer::EnsureValidWinFrameInfo() { 512 const MCAsmInfo *MAI = Context.getAsmInfo(); 513 if (!MAI->usesWindowsCFI()) 514 report_fatal_error(".seh_* directives are not supported on this target"); 515 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) 516 report_fatal_error("No open Win64 EH frame function!"); 517 } 518 519 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) { 520 const MCAsmInfo *MAI = Context.getAsmInfo(); 521 if (!MAI->usesWindowsCFI()) 522 report_fatal_error(".seh_* directives are not supported on this target"); 523 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End) 524 report_fatal_error("Starting a function before ending the previous one!"); 525 526 MCSymbol *StartProc = EmitCFILabel(); 527 528 WinFrameInfos.push_back(new WinEH::FrameInfo(Symbol, StartProc)); 529 CurrentWinFrameInfo = WinFrameInfos.back(); 530 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly(); 531 } 532 533 void MCStreamer::EmitWinCFIEndProc() { 534 EnsureValidWinFrameInfo(); 535 if (CurrentWinFrameInfo->ChainedParent) 536 report_fatal_error("Not all chained regions terminated!"); 537 538 MCSymbol *Label = EmitCFILabel(); 539 CurrentWinFrameInfo->End = Label; 540 } 541 542 void MCStreamer::EmitWinCFIStartChained() { 543 EnsureValidWinFrameInfo(); 544 545 MCSymbol *StartProc = EmitCFILabel(); 546 547 WinFrameInfos.push_back(new WinEH::FrameInfo(CurrentWinFrameInfo->Function, 548 StartProc, CurrentWinFrameInfo)); 549 CurrentWinFrameInfo = WinFrameInfos.back(); 550 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly(); 551 } 552 553 void MCStreamer::EmitWinCFIEndChained() { 554 EnsureValidWinFrameInfo(); 555 if (!CurrentWinFrameInfo->ChainedParent) 556 report_fatal_error("End of a chained region outside a chained region!"); 557 558 MCSymbol *Label = EmitCFILabel(); 559 560 CurrentWinFrameInfo->End = Label; 561 CurrentWinFrameInfo = 562 const_cast<WinEH::FrameInfo *>(CurrentWinFrameInfo->ChainedParent); 563 } 564 565 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, 566 bool Except) { 567 EnsureValidWinFrameInfo(); 568 if (CurrentWinFrameInfo->ChainedParent) 569 report_fatal_error("Chained unwind areas can't have handlers!"); 570 CurrentWinFrameInfo->ExceptionHandler = Sym; 571 if (!Except && !Unwind) 572 report_fatal_error("Don't know what kind of handler this is!"); 573 if (Unwind) 574 CurrentWinFrameInfo->HandlesUnwind = true; 575 if (Except) 576 CurrentWinFrameInfo->HandlesExceptions = true; 577 } 578 579 void MCStreamer::EmitWinEHHandlerData() { 580 EnsureValidWinFrameInfo(); 581 if (CurrentWinFrameInfo->ChainedParent) 582 report_fatal_error("Chained unwind areas can't have handlers!"); 583 } 584 585 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID, 586 MCSection *MainCFISec, 587 const MCSection *TextSec) { 588 // If this is the main .text section, use the main unwind info section. 589 if (TextSec == Context.getObjectFileInfo()->getTextSection()) 590 return MainCFISec; 591 592 const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec); 593 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID); 594 595 // If this section is COMDAT, this unwind section should be COMDAT associative 596 // with its group. 597 const MCSymbol *KeySym = nullptr; 598 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) 599 KeySym = TextSecCOFF->getCOMDATSymbol(); 600 601 return Context.getAssociativeCOFFSection(cast<MCSectionCOFF>(MainCFISec), 602 KeySym, UniqueID); 603 } 604 605 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) { 606 return getWinCFISection(getContext(), &NextWinCFIID, 607 getContext().getObjectFileInfo()->getPDataSection(), 608 TextSec); 609 } 610 611 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) { 612 return getWinCFISection(getContext(), &NextWinCFIID, 613 getContext().getObjectFileInfo()->getXDataSection(), 614 TextSec); 615 } 616 617 void MCStreamer::EmitSyntaxDirective() {} 618 619 void MCStreamer::EmitWinCFIPushReg(unsigned Register) { 620 EnsureValidWinFrameInfo(); 621 622 MCSymbol *Label = EmitCFILabel(); 623 624 WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register); 625 CurrentWinFrameInfo->Instructions.push_back(Inst); 626 } 627 628 void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) { 629 EnsureValidWinFrameInfo(); 630 if (CurrentWinFrameInfo->LastFrameInst >= 0) 631 report_fatal_error("Frame register and offset already specified!"); 632 if (Offset & 0x0F) 633 report_fatal_error("Misaligned frame pointer offset!"); 634 if (Offset > 240) 635 report_fatal_error("Frame offset must be less than or equal to 240!"); 636 637 MCSymbol *Label = EmitCFILabel(); 638 639 WinEH::Instruction Inst = 640 Win64EH::Instruction::SetFPReg(Label, Register, Offset); 641 CurrentWinFrameInfo->LastFrameInst = CurrentWinFrameInfo->Instructions.size(); 642 CurrentWinFrameInfo->Instructions.push_back(Inst); 643 } 644 645 void MCStreamer::EmitWinCFIAllocStack(unsigned Size) { 646 EnsureValidWinFrameInfo(); 647 if (Size == 0) 648 report_fatal_error("Allocation size must be non-zero!"); 649 if (Size & 7) 650 report_fatal_error("Misaligned stack allocation!"); 651 652 MCSymbol *Label = EmitCFILabel(); 653 654 WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size); 655 CurrentWinFrameInfo->Instructions.push_back(Inst); 656 } 657 658 void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) { 659 EnsureValidWinFrameInfo(); 660 if (Offset & 7) 661 report_fatal_error("Misaligned saved register offset!"); 662 663 MCSymbol *Label = EmitCFILabel(); 664 665 WinEH::Instruction Inst = 666 Win64EH::Instruction::SaveNonVol(Label, Register, Offset); 667 CurrentWinFrameInfo->Instructions.push_back(Inst); 668 } 669 670 void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) { 671 EnsureValidWinFrameInfo(); 672 if (Offset & 0x0F) 673 report_fatal_error("Misaligned saved vector register offset!"); 674 675 MCSymbol *Label = EmitCFILabel(); 676 677 WinEH::Instruction Inst = 678 Win64EH::Instruction::SaveXMM(Label, Register, Offset); 679 CurrentWinFrameInfo->Instructions.push_back(Inst); 680 } 681 682 void MCStreamer::EmitWinCFIPushFrame(bool Code) { 683 EnsureValidWinFrameInfo(); 684 if (!CurrentWinFrameInfo->Instructions.empty()) 685 report_fatal_error("If present, PushMachFrame must be the first UOP"); 686 687 MCSymbol *Label = EmitCFILabel(); 688 689 WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code); 690 CurrentWinFrameInfo->Instructions.push_back(Inst); 691 } 692 693 void MCStreamer::EmitWinCFIEndProlog() { 694 EnsureValidWinFrameInfo(); 695 696 MCSymbol *Label = EmitCFILabel(); 697 698 CurrentWinFrameInfo->PrologEnd = Label; 699 } 700 701 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) { 702 } 703 704 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { 705 } 706 707 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {} 708 709 /// EmitRawText - If this file is backed by an assembly streamer, this dumps 710 /// the specified string in the output .s file. This capability is 711 /// indicated by the hasRawTextSupport() predicate. 712 void MCStreamer::EmitRawTextImpl(StringRef String) { 713 errs() << "EmitRawText called on an MCStreamer that doesn't support it, " 714 " something must not be fully mc'ized\n"; 715 abort(); 716 } 717 718 void MCStreamer::EmitRawText(const Twine &T) { 719 SmallString<128> Str; 720 EmitRawTextImpl(T.toStringRef(Str)); 721 } 722 723 void MCStreamer::EmitWindowsUnwindTables() { 724 } 725 726 void MCStreamer::Finish() { 727 if (!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) 728 report_fatal_error("Unfinished frame!"); 729 730 MCTargetStreamer *TS = getTargetStreamer(); 731 if (TS) 732 TS->finish(); 733 734 FinishImpl(); 735 } 736 737 void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 738 visitUsedExpr(*Value); 739 Symbol->setVariableValue(Value); 740 741 MCTargetStreamer *TS = getTargetStreamer(); 742 if (TS) 743 TS->emitAssignment(Symbol, Value); 744 } 745 746 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS, 747 const MCInst &Inst, const MCSubtargetInfo &STI) { 748 InstPrinter.printInst(&Inst, OS, "", STI); 749 } 750 751 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) { 752 } 753 754 void MCStreamer::visitUsedExpr(const MCExpr &Expr) { 755 switch (Expr.getKind()) { 756 case MCExpr::Target: 757 cast<MCTargetExpr>(Expr).visitUsedExpr(*this); 758 break; 759 760 case MCExpr::Constant: 761 break; 762 763 case MCExpr::Binary: { 764 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr); 765 visitUsedExpr(*BE.getLHS()); 766 visitUsedExpr(*BE.getRHS()); 767 break; 768 } 769 770 case MCExpr::SymbolRef: 771 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol()); 772 break; 773 774 case MCExpr::Unary: 775 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr()); 776 break; 777 } 778 } 779 780 void MCStreamer::EmitInstruction(const MCInst &Inst, 781 const MCSubtargetInfo &STI) { 782 // Scan for values. 783 for (unsigned i = Inst.getNumOperands(); i--;) 784 if (Inst.getOperand(i).isExpr()) 785 visitUsedExpr(*Inst.getOperand(i).getExpr()); 786 } 787 788 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, 789 unsigned Size) { 790 // Get the Hi-Lo expression. 791 const MCExpr *Diff = 792 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context), 793 MCSymbolRefExpr::create(Lo, Context), Context); 794 795 const MCAsmInfo *MAI = Context.getAsmInfo(); 796 if (!MAI->doesSetDirectiveSuppressReloc()) { 797 EmitValue(Diff, Size); 798 return; 799 } 800 801 // Otherwise, emit with .set (aka assignment). 802 MCSymbol *SetLabel = Context.createTempSymbol("set", true); 803 EmitAssignment(SetLabel, Diff); 804 EmitSymbolValue(SetLabel, Size); 805 } 806 807 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {} 808 void MCStreamer::EmitThumbFunc(MCSymbol *Func) {} 809 void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {} 810 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) { 811 llvm_unreachable("this directive only supported on COFF targets"); 812 } 813 void MCStreamer::EndCOFFSymbolDef() { 814 llvm_unreachable("this directive only supported on COFF targets"); 815 } 816 void MCStreamer::EmitFileDirective(StringRef Filename) {} 817 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) { 818 llvm_unreachable("this directive only supported on COFF targets"); 819 } 820 void MCStreamer::EmitCOFFSymbolType(int Type) { 821 llvm_unreachable("this directive only supported on COFF targets"); 822 } 823 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {} 824 void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 825 unsigned ByteAlignment) {} 826 void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, 827 uint64_t Size, unsigned ByteAlignment) {} 828 void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {} 829 void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {} 830 void MCStreamer::EmitBytes(StringRef Data) {} 831 void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); } 832 void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) { 833 visitUsedExpr(*Value); 834 } 835 void MCStreamer::EmitULEB128Value(const MCExpr *Value) {} 836 void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {} 837 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {} 838 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr, 839 SMLoc Loc) {} 840 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, 841 unsigned ValueSize, 842 unsigned MaxBytesToEmit) {} 843 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment, 844 unsigned MaxBytesToEmit) {} 845 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value, 846 SMLoc Loc) {} 847 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {} 848 void MCStreamer::EmitBundleLock(bool AlignToEnd) {} 849 void MCStreamer::FinishImpl() {} 850 void MCStreamer::EmitBundleUnlock() {} 851 852 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) { 853 assert(Section && "Cannot switch to a null section!"); 854 MCSectionSubPair curSection = SectionStack.back().first; 855 SectionStack.back().second = curSection; 856 if (MCSectionSubPair(Section, Subsection) != curSection) { 857 ChangeSection(Section, Subsection); 858 SectionStack.back().first = MCSectionSubPair(Section, Subsection); 859 assert(!Section->hasEnded() && "Section already ended"); 860 MCSymbol *Sym = Section->getBeginSymbol(); 861 if (Sym && !Sym->isInSection()) 862 EmitLabel(Sym); 863 } 864 } 865 866 MCSymbol *MCStreamer::endSection(MCSection *Section) { 867 // TODO: keep track of the last subsection so that this symbol appears in the 868 // correct place. 869 MCSymbol *Sym = Section->getEndSymbol(Context); 870 if (Sym->isInSection()) 871 return Sym; 872 873 SwitchSection(Section); 874 EmitLabel(Sym); 875 return Sym; 876 } 877