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