1 //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/MC/MCStreamer.h"
11 #include "llvm/ADT/Optional.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/BinaryFormat/COFF.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/MCSection.h"
26 #include "llvm/MC/MCSectionCOFF.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/MCWin64EH.h"
29 #include "llvm/MC/MCWinEH.h"
30 #include "llvm/Support/Casting.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/LEB128.h"
33 #include "llvm/Support/MathExtras.h"
34 #include "llvm/Support/raw_ostream.h"
42 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
43 S.setTargetStreamer(this);
46 // Pin the vtables to this file.
47 MCTargetStreamer::~MCTargetStreamer() = default;
49 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
51 void MCTargetStreamer::finish() {}
53 void MCTargetStreamer::changeSection(const MCSection *CurSection,
55 const MCExpr *Subsection,
57 Section->PrintSwitchToSection(
58 *Streamer.getContext().getAsmInfo(),
59 Streamer.getContext().getObjectFileInfo()->getTargetTriple(), OS,
63 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
64 Streamer.EmitRawText(Directive);
67 void MCTargetStreamer::emitValue(const MCExpr *Value) {
69 raw_svector_ostream OS(Str);
71 Value->print(OS, Streamer.getContext().getAsmInfo());
72 Streamer.EmitRawText(OS.str());
75 void MCTargetStreamer::emitRawBytes(StringRef Data) {
76 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
77 const char *Directive = MAI->getData8bitsDirective();
78 for (const unsigned char C : Data.bytes()) {
80 raw_svector_ostream OS(Str);
82 OS << Directive << (unsigned)C;
83 Streamer.EmitRawText(OS.str());
87 void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
89 MCStreamer::MCStreamer(MCContext &Ctx)
90 : Context(Ctx), CurrentWinFrameInfo(nullptr),
91 UseAssemblerInfoForParsing(false) {
92 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
95 MCStreamer::~MCStreamer() {}
97 void MCStreamer::reset() {
98 DwarfFrameInfos.clear();
99 CurrentWinFrameInfo = nullptr;
100 WinFrameInfos.clear();
101 SymbolOrdering.clear();
102 SectionStack.clear();
103 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
106 raw_ostream &MCStreamer::GetCommentOS() {
107 // By default, discard comments.
111 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
113 void MCStreamer::addExplicitComment(const Twine &T) {}
114 void MCStreamer::emitExplicitComments() {}
116 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
117 for (auto &FI : DwarfFrameInfos)
118 FI.CompactUnwindEncoding =
119 (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
122 /// EmitIntValue - Special case of EmitValue that avoids the client having to
123 /// pass in a MCExpr for constant integers.
124 void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
125 assert(1 <= Size && Size <= 8 && "Invalid size");
126 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
129 const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian();
130 for (unsigned i = 0; i != Size; ++i) {
131 unsigned index = isLittleEndian ? i : (Size - i - 1);
132 buf[i] = uint8_t(Value >> (index * 8));
134 EmitBytes(StringRef(buf, Size));
137 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
138 /// client having to pass in a MCExpr for constant integers.
139 void MCStreamer::EmitULEB128IntValue(uint64_t Value) {
140 SmallString<128> Tmp;
141 raw_svector_ostream OSE(Tmp);
142 encodeULEB128(Value, OSE);
143 EmitBytes(OSE.str());
146 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
147 /// client having to pass in a MCExpr for constant integers.
148 void MCStreamer::EmitSLEB128IntValue(int64_t Value) {
149 SmallString<128> Tmp;
150 raw_svector_ostream OSE(Tmp);
151 encodeSLEB128(Value, OSE);
152 EmitBytes(OSE.str());
155 void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
156 EmitValueImpl(Value, Size, Loc);
159 void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
160 bool IsSectionRelative) {
161 assert((!IsSectionRelative || Size == 4) &&
162 "SectionRelative value requires 4-bytes");
164 if (!IsSectionRelative)
165 EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
167 EmitCOFFSecRel32(Sym, /*Offset=*/0);
170 void MCStreamer::EmitDTPRel64Value(const MCExpr *Value) {
171 report_fatal_error("unsupported directive in streamer");
174 void MCStreamer::EmitDTPRel32Value(const MCExpr *Value) {
175 report_fatal_error("unsupported directive in streamer");
178 void MCStreamer::EmitTPRel64Value(const MCExpr *Value) {
179 report_fatal_error("unsupported directive in streamer");
182 void MCStreamer::EmitTPRel32Value(const MCExpr *Value) {
183 report_fatal_error("unsupported directive in streamer");
186 void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
187 report_fatal_error("unsupported directive in streamer");
190 void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
191 report_fatal_error("unsupported directive in streamer");
194 /// Emit NumBytes bytes worth of the value specified by FillValue.
195 /// This implements directives such as '.space'.
196 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
197 emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
200 /// The implementation in this class just redirects to emitFill.
201 void MCStreamer::EmitZeros(uint64_t NumBytes) {
202 emitFill(NumBytes, 0);
206 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
208 MD5::MD5Result *Checksum,
209 Optional<StringRef> Source,
211 return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
215 void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
217 MD5::MD5Result *Checksum,
218 Optional<StringRef> Source,
220 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
224 void MCStreamer::EmitCFIBKeyFrame() {
225 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
228 CurFrame->IsBKeyFrame = true;
231 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
232 unsigned Column, unsigned Flags,
234 unsigned Discriminator,
235 StringRef FileName) {
236 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
240 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
241 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
242 if (!Table.getLabel()) {
243 StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
245 Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
247 return Table.getLabel();
250 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
251 return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
254 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
255 if (!hasUnfinishedDwarfFrameInfo()) {
256 getContext().reportError(SMLoc(), "this directive must appear between "
257 ".cfi_startproc and .cfi_endproc "
261 return &DwarfFrameInfos.back();
264 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
265 ArrayRef<uint8_t> Checksum,
266 unsigned ChecksumKind) {
267 return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
271 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
272 return getContext().getCVContext().recordFunctionId(FunctionId);
275 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
276 unsigned IAFunc, unsigned IAFile,
277 unsigned IALine, unsigned IACol,
279 if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
280 getContext().reportError(Loc, "parent function id not introduced by "
281 ".cv_func_id or .cv_inline_site_id");
285 return getContext().getCVContext().recordInlinedCallSiteId(
286 FunctionId, IAFunc, IAFile, IALine, IACol);
289 void MCStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
290 unsigned Line, unsigned Column,
291 bool PrologueEnd, bool IsStmt,
292 StringRef FileName, SMLoc Loc) {}
294 bool MCStreamer::checkCVLocSection(unsigned FuncId, unsigned FileNo,
296 CodeViewContext &CVC = getContext().getCVContext();
297 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId);
299 getContext().reportError(
300 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
305 if (FI->Section == nullptr)
306 FI->Section = getCurrentSectionOnly();
307 else if (FI->Section != getCurrentSectionOnly()) {
308 getContext().reportError(
310 "all .cv_loc directives for a function must be in the same section");
316 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId,
317 const MCSymbol *Begin,
318 const MCSymbol *End) {}
320 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
321 unsigned SourceFileId,
322 unsigned SourceLineNum,
323 const MCSymbol *FnStartSym,
324 const MCSymbol *FnEndSym) {}
326 void MCStreamer::EmitCVDefRangeDirective(
327 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
328 StringRef FixedSizePortion) {}
330 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
331 MCSymbol *EHSymbol) {
334 void MCStreamer::InitSections(bool NoExecStack) {
335 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
338 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
340 Symbol->setFragment(Fragment);
342 // As we emit symbols into a section, track the order so that they can
343 // be sorted upon later. Zero is reserved to mean 'unemitted'.
344 SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
347 void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
348 Symbol->redefineIfPossible();
350 if (!Symbol->isUndefined() || Symbol->isVariable())
351 return getContext().reportError(Loc, "invalid symbol redefinition");
353 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
354 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
355 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
356 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
358 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
360 MCTargetStreamer *TS = getTargetStreamer();
362 TS->emitLabel(Symbol);
365 void MCStreamer::EmitCFISections(bool EH, bool Debug) {
369 void MCStreamer::EmitCFIStartProc(bool IsSimple, SMLoc Loc) {
370 if (hasUnfinishedDwarfFrameInfo())
371 return getContext().reportError(
372 Loc, "starting new .cfi frame before finishing the previous one");
374 MCDwarfFrameInfo Frame;
375 Frame.IsSimple = IsSimple;
376 EmitCFIStartProcImpl(Frame);
378 const MCAsmInfo* MAI = Context.getAsmInfo();
380 for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
381 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
382 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
383 Frame.CurrentCfaRegister = Inst.getRegister();
388 DwarfFrameInfos.push_back(Frame);
391 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
394 void MCStreamer::EmitCFIEndProc() {
395 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
398 EmitCFIEndProcImpl(*CurFrame);
401 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
402 // Put a dummy non-null value in Frame.End to mark that this frame has been
404 Frame.End = (MCSymbol *)1;
407 MCSymbol *MCStreamer::EmitCFILabel() {
408 // Return a dummy non-null value so that label fields appear filled in when
409 // generating textual assembly.
410 return (MCSymbol *)1;
413 void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
414 MCSymbol *Label = EmitCFILabel();
415 MCCFIInstruction Instruction =
416 MCCFIInstruction::createDefCfa(Label, Register, Offset);
417 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
420 CurFrame->Instructions.push_back(Instruction);
421 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
424 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
425 MCSymbol *Label = EmitCFILabel();
426 MCCFIInstruction Instruction =
427 MCCFIInstruction::createDefCfaOffset(Label, Offset);
428 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
431 CurFrame->Instructions.push_back(Instruction);
434 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
435 MCSymbol *Label = EmitCFILabel();
436 MCCFIInstruction Instruction =
437 MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
438 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
441 CurFrame->Instructions.push_back(Instruction);
444 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
445 MCSymbol *Label = EmitCFILabel();
446 MCCFIInstruction Instruction =
447 MCCFIInstruction::createDefCfaRegister(Label, Register);
448 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
451 CurFrame->Instructions.push_back(Instruction);
452 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
455 void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
456 MCSymbol *Label = EmitCFILabel();
457 MCCFIInstruction Instruction =
458 MCCFIInstruction::createOffset(Label, Register, Offset);
459 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
462 CurFrame->Instructions.push_back(Instruction);
465 void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
466 MCSymbol *Label = EmitCFILabel();
467 MCCFIInstruction Instruction =
468 MCCFIInstruction::createRelOffset(Label, Register, Offset);
469 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
472 CurFrame->Instructions.push_back(Instruction);
475 void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
477 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
480 CurFrame->Personality = Sym;
481 CurFrame->PersonalityEncoding = Encoding;
484 void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
485 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
488 CurFrame->Lsda = Sym;
489 CurFrame->LsdaEncoding = Encoding;
492 void MCStreamer::EmitCFIRememberState() {
493 MCSymbol *Label = EmitCFILabel();
494 MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
495 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
498 CurFrame->Instructions.push_back(Instruction);
501 void MCStreamer::EmitCFIRestoreState() {
502 // FIXME: Error if there is no matching cfi_remember_state.
503 MCSymbol *Label = EmitCFILabel();
504 MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
505 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
508 CurFrame->Instructions.push_back(Instruction);
511 void MCStreamer::EmitCFISameValue(int64_t Register) {
512 MCSymbol *Label = EmitCFILabel();
513 MCCFIInstruction Instruction =
514 MCCFIInstruction::createSameValue(Label, Register);
515 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
518 CurFrame->Instructions.push_back(Instruction);
521 void MCStreamer::EmitCFIRestore(int64_t Register) {
522 MCSymbol *Label = EmitCFILabel();
523 MCCFIInstruction Instruction =
524 MCCFIInstruction::createRestore(Label, Register);
525 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
528 CurFrame->Instructions.push_back(Instruction);
531 void MCStreamer::EmitCFIEscape(StringRef Values) {
532 MCSymbol *Label = EmitCFILabel();
533 MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
534 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
537 CurFrame->Instructions.push_back(Instruction);
540 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
541 MCSymbol *Label = EmitCFILabel();
542 MCCFIInstruction Instruction =
543 MCCFIInstruction::createGnuArgsSize(Label, Size);
544 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
547 CurFrame->Instructions.push_back(Instruction);
550 void MCStreamer::EmitCFISignalFrame() {
551 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
554 CurFrame->IsSignalFrame = true;
557 void MCStreamer::EmitCFIUndefined(int64_t Register) {
558 MCSymbol *Label = EmitCFILabel();
559 MCCFIInstruction Instruction =
560 MCCFIInstruction::createUndefined(Label, Register);
561 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
564 CurFrame->Instructions.push_back(Instruction);
567 void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
568 MCSymbol *Label = EmitCFILabel();
569 MCCFIInstruction Instruction =
570 MCCFIInstruction::createRegister(Label, Register1, Register2);
571 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
574 CurFrame->Instructions.push_back(Instruction);
577 void MCStreamer::EmitCFIWindowSave() {
578 MCSymbol *Label = EmitCFILabel();
579 MCCFIInstruction Instruction =
580 MCCFIInstruction::createWindowSave(Label);
581 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
584 CurFrame->Instructions.push_back(Instruction);
587 void MCStreamer::EmitCFINegateRAState() {
588 MCSymbol *Label = EmitCFILabel();
589 MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label);
590 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
593 CurFrame->Instructions.push_back(Instruction);
596 void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
597 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
600 CurFrame->RAReg = Register;
603 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
604 const MCAsmInfo *MAI = Context.getAsmInfo();
605 if (!MAI->usesWindowsCFI()) {
606 getContext().reportError(
607 Loc, ".seh_* directives are not supported on this target");
610 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
611 getContext().reportError(
612 Loc, ".seh_ directive must appear within an active frame");
615 return CurrentWinFrameInfo;
618 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
619 const MCAsmInfo *MAI = Context.getAsmInfo();
620 if (!MAI->usesWindowsCFI())
621 return getContext().reportError(
622 Loc, ".seh_* directives are not supported on this target");
623 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
624 getContext().reportError(
625 Loc, "Starting a function before ending the previous one!");
627 MCSymbol *StartProc = EmitCFILabel();
629 WinFrameInfos.emplace_back(
630 llvm::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
631 CurrentWinFrameInfo = WinFrameInfos.back().get();
632 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
635 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
636 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
639 if (CurFrame->ChainedParent)
640 getContext().reportError(Loc, "Not all chained regions terminated!");
642 MCSymbol *Label = EmitCFILabel();
643 CurFrame->End = Label;
646 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
647 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
650 if (CurFrame->ChainedParent)
651 getContext().reportError(Loc, "Not all chained regions terminated!");
653 MCSymbol *Label = EmitCFILabel();
654 CurFrame->FuncletOrFuncEnd = Label;
657 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
658 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
662 MCSymbol *StartProc = EmitCFILabel();
664 WinFrameInfos.emplace_back(llvm::make_unique<WinEH::FrameInfo>(
665 CurFrame->Function, StartProc, CurFrame));
666 CurrentWinFrameInfo = WinFrameInfos.back().get();
667 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
670 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
671 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
674 if (!CurFrame->ChainedParent)
675 return getContext().reportError(
676 Loc, "End of a chained region outside a chained region!");
678 MCSymbol *Label = EmitCFILabel();
680 CurFrame->End = Label;
681 CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
684 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
686 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
689 if (CurFrame->ChainedParent)
690 return getContext().reportError(
691 Loc, "Chained unwind areas can't have handlers!");
692 CurFrame->ExceptionHandler = Sym;
693 if (!Except && !Unwind)
694 getContext().reportError(Loc, "Don't know what kind of handler this is!");
696 CurFrame->HandlesUnwind = true;
698 CurFrame->HandlesExceptions = true;
701 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
702 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
705 if (CurFrame->ChainedParent)
706 getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
709 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
710 const MCSymbolRefExpr *To, uint64_t Count) {
713 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
714 MCSection *MainCFISec,
715 const MCSection *TextSec) {
716 // If this is the main .text section, use the main unwind info section.
717 if (TextSec == Context.getObjectFileInfo()->getTextSection())
720 const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
721 auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
722 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
724 // If this section is COMDAT, this unwind section should be COMDAT associative
726 const MCSymbol *KeySym = nullptr;
727 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
728 KeySym = TextSecCOFF->getCOMDATSymbol();
730 // In a GNU environment, we can't use associative comdats. Instead, do what
731 // GCC does, which is to make plain comdat selectany section named like
732 // ".[px]data$_Z3foov".
733 if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
734 std::string SectionName =
735 (MainCFISecCOFF->getSectionName() + "$" +
736 TextSecCOFF->getSectionName().split('$').second)
738 return Context.getCOFFSection(
740 MainCFISecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT,
741 MainCFISecCOFF->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY);
745 return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
748 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
749 return getWinCFISection(getContext(), &NextWinCFIID,
750 getContext().getObjectFileInfo()->getPDataSection(),
754 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
755 return getWinCFISection(getContext(), &NextWinCFIID,
756 getContext().getObjectFileInfo()->getXDataSection(),
760 void MCStreamer::EmitSyntaxDirective() {}
762 void MCStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
763 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
767 MCSymbol *Label = EmitCFILabel();
769 WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register);
770 CurFrame->Instructions.push_back(Inst);
773 void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
775 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
778 if (CurFrame->LastFrameInst >= 0)
779 return getContext().reportError(
780 Loc, "frame register and offset can be set at most once");
782 return getContext().reportError(Loc, "offset is not a multiple of 16");
784 return getContext().reportError(
785 Loc, "frame offset must be less than or equal to 240");
787 MCSymbol *Label = EmitCFILabel();
789 WinEH::Instruction Inst =
790 Win64EH::Instruction::SetFPReg(Label, Register, Offset);
791 CurFrame->LastFrameInst = CurFrame->Instructions.size();
792 CurFrame->Instructions.push_back(Inst);
795 void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
796 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
800 return getContext().reportError(Loc,
801 "stack allocation size must be non-zero");
803 return getContext().reportError(
804 Loc, "stack allocation size is not a multiple of 8");
806 MCSymbol *Label = EmitCFILabel();
808 WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
809 CurFrame->Instructions.push_back(Inst);
812 void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
814 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
819 return getContext().reportError(
820 Loc, "register save offset is not 8 byte aligned");
822 MCSymbol *Label = EmitCFILabel();
824 WinEH::Instruction Inst =
825 Win64EH::Instruction::SaveNonVol(Label, Register, Offset);
826 CurFrame->Instructions.push_back(Inst);
829 void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
831 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
835 return getContext().reportError(Loc, "offset is not a multiple of 16");
837 MCSymbol *Label = EmitCFILabel();
839 WinEH::Instruction Inst =
840 Win64EH::Instruction::SaveXMM(Label, Register, Offset);
841 CurFrame->Instructions.push_back(Inst);
844 void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
845 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
848 if (!CurFrame->Instructions.empty())
849 return getContext().reportError(
850 Loc, "If present, PushMachFrame must be the first UOP");
852 MCSymbol *Label = EmitCFILabel();
854 WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
855 CurFrame->Instructions.push_back(Inst);
858 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
859 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
863 MCSymbol *Label = EmitCFILabel();
865 CurFrame->PrologEnd = Label;
868 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {}
870 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {}
872 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {}
874 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
876 void MCStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
878 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
879 /// the specified string in the output .s file. This capability is
880 /// indicated by the hasRawTextSupport() predicate.
881 void MCStreamer::EmitRawTextImpl(StringRef String) {
882 // This is not llvm_unreachable for the sake of out of tree backend
883 // developers who may not have assembly streamers and should serve as a
884 // reminder to not accidentally call EmitRawText in the absence of such.
885 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
886 "it (target backend is likely missing an AsmStreamer "
890 void MCStreamer::EmitRawText(const Twine &T) {
891 SmallString<128> Str;
892 EmitRawTextImpl(T.toStringRef(Str));
895 void MCStreamer::EmitWindowsUnwindTables() {
898 void MCStreamer::Finish() {
899 if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
900 (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
901 getContext().reportError(SMLoc(), "Unfinished frame!");
905 MCTargetStreamer *TS = getTargetStreamer();
912 void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
913 visitUsedExpr(*Value);
914 Symbol->setVariableValue(Value);
916 MCTargetStreamer *TS = getTargetStreamer();
918 TS->emitAssignment(Symbol, Value);
921 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
922 raw_ostream &OS, const MCInst &Inst,
923 const MCSubtargetInfo &STI) {
924 InstPrinter.printInst(&Inst, OS, "", STI);
927 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
930 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
931 switch (Expr.getKind()) {
933 cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
936 case MCExpr::Constant:
939 case MCExpr::Binary: {
940 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
941 visitUsedExpr(*BE.getLHS());
942 visitUsedExpr(*BE.getRHS());
946 case MCExpr::SymbolRef:
947 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
951 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
956 void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
959 for (unsigned i = Inst.getNumOperands(); i--;)
960 if (Inst.getOperand(i).isExpr())
961 visitUsedExpr(*Inst.getOperand(i).getExpr());
964 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
966 // Get the Hi-Lo expression.
968 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
969 MCSymbolRefExpr::create(Lo, Context), Context);
971 const MCAsmInfo *MAI = Context.getAsmInfo();
972 if (!MAI->doesSetDirectiveSuppressReloc()) {
973 EmitValue(Diff, Size);
977 // Otherwise, emit with .set (aka assignment).
978 MCSymbol *SetLabel = Context.createTempSymbol("set", true);
979 EmitAssignment(SetLabel, Diff);
980 EmitSymbolValue(SetLabel, Size);
983 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
984 const MCSymbol *Lo) {
985 // Get the Hi-Lo expression.
987 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
988 MCSymbolRefExpr::create(Lo, Context), Context);
990 EmitULEB128Value(Diff);
993 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
994 void MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
995 void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
996 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
997 llvm_unreachable("this directive only supported on COFF targets");
999 void MCStreamer::EndCOFFSymbolDef() {
1000 llvm_unreachable("this directive only supported on COFF targets");
1002 void MCStreamer::EmitFileDirective(StringRef Filename) {}
1003 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
1004 llvm_unreachable("this directive only supported on COFF targets");
1006 void MCStreamer::EmitCOFFSymbolType(int Type) {
1007 llvm_unreachable("this directive only supported on COFF targets");
1009 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
1010 void MCStreamer::emitELFSymverDirective(StringRef AliasName,
1011 const MCSymbol *Aliasee) {}
1012 void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1013 unsigned ByteAlignment) {}
1014 void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1015 uint64_t Size, unsigned ByteAlignment) {}
1016 void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {}
1017 void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
1018 void MCStreamer::EmitBytes(StringRef Data) {}
1019 void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); }
1020 void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
1021 visitUsedExpr(*Value);
1023 void MCStreamer::EmitULEB128Value(const MCExpr *Value) {}
1024 void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {}
1025 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
1026 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
1028 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
1030 unsigned MaxBytesToEmit) {}
1031 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment,
1032 unsigned MaxBytesToEmit) {}
1033 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
1035 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {}
1036 void MCStreamer::EmitBundleLock(bool AlignToEnd) {}
1037 void MCStreamer::FinishImpl() {}
1038 void MCStreamer::EmitBundleUnlock() {}
1040 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
1041 assert(Section && "Cannot switch to a null section!");
1042 MCSectionSubPair curSection = SectionStack.back().first;
1043 SectionStack.back().second = curSection;
1044 if (MCSectionSubPair(Section, Subsection) != curSection) {
1045 ChangeSection(Section, Subsection);
1046 SectionStack.back().first = MCSectionSubPair(Section, Subsection);
1047 assert(!Section->hasEnded() && "Section already ended");
1048 MCSymbol *Sym = Section->getBeginSymbol();
1049 if (Sym && !Sym->isInSection())
1054 MCSymbol *MCStreamer::endSection(MCSection *Section) {
1055 // TODO: keep track of the last subsection so that this symbol appears in the
1057 MCSymbol *Sym = Section->getEndSymbol(Context);
1058 if (Sym->isInSection())
1061 SwitchSection(Section);
1066 void MCStreamer::EmitVersionForTarget(const Triple &Target,
1067 const VersionTuple &SDKVersion) {
1068 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
1070 // Do we even know the version?
1071 if (Target.getOSMajorVersion() == 0)
1077 MCVersionMinType VersionType;
1078 if (Target.isWatchOS()) {
1079 VersionType = MCVM_WatchOSVersionMin;
1080 Target.getWatchOSVersion(Major, Minor, Update);
1081 } else if (Target.isTvOS()) {
1082 VersionType = MCVM_TvOSVersionMin;
1083 Target.getiOSVersion(Major, Minor, Update);
1084 } else if (Target.isMacOSX()) {
1085 VersionType = MCVM_OSXVersionMin;
1086 if (!Target.getMacOSXVersion(Major, Minor, Update))
1089 VersionType = MCVM_IOSVersionMin;
1090 Target.getiOSVersion(Major, Minor, Update);
1093 EmitVersionMin(VersionType, Major, Minor, Update, SDKVersion);