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