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/SmallString.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/BinaryFormat/COFF.h"
15 #include "llvm/MC/MCAsmBackend.h"
16 #include "llvm/MC/MCAsmInfo.h"
17 #include "llvm/MC/MCCodeView.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCDwarf.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstPrinter.h"
23 #include "llvm/MC/MCObjectFileInfo.h"
24 #include "llvm/MC/MCSection.h"
25 #include "llvm/MC/MCSectionCOFF.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCWin64EH.h"
28 #include "llvm/MC/MCWinEH.h"
29 #include "llvm/Support/Casting.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"
41 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
42 S.setTargetStreamer(this);
45 // Pin the vtables to this file.
46 MCTargetStreamer::~MCTargetStreamer() = default;
48 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
50 void MCTargetStreamer::finish() {}
52 void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
54 MCStreamer::MCStreamer(MCContext &Ctx)
55 : Context(Ctx), CurrentWinFrameInfo(nullptr) {
56 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
59 MCStreamer::~MCStreamer() {}
61 void MCStreamer::reset() {
62 DwarfFrameInfos.clear();
63 CurrentWinFrameInfo = nullptr;
64 WinFrameInfos.clear();
65 SymbolOrdering.clear();
67 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
70 raw_ostream &MCStreamer::GetCommentOS() {
71 // By default, discard comments.
75 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
77 void MCStreamer::addExplicitComment(const Twine &T) {}
78 void MCStreamer::emitExplicitComments() {}
80 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
81 for (auto &FI : DwarfFrameInfos)
82 FI.CompactUnwindEncoding =
83 (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
86 /// EmitIntValue - Special case of EmitValue that avoids the client having to
87 /// pass in a MCExpr for constant integers.
88 void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
89 assert(1 <= Size && Size <= 8 && "Invalid size");
90 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
93 const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian();
94 for (unsigned i = 0; i != Size; ++i) {
95 unsigned index = isLittleEndian ? i : (Size - i - 1);
96 buf[i] = uint8_t(Value >> (index * 8));
98 EmitBytes(StringRef(buf, Size));
101 /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
102 /// client having to pass in a MCExpr for constant integers.
103 void MCStreamer::EmitPaddedULEB128IntValue(uint64_t Value, unsigned PadTo) {
104 SmallString<128> Tmp;
105 raw_svector_ostream OSE(Tmp);
106 encodeULEB128(Value, OSE, PadTo);
107 EmitBytes(OSE.str());
110 void MCStreamer::EmitULEB128IntValue(uint64_t Value) {
111 EmitPaddedULEB128IntValue(Value, 0);
114 /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
115 /// client having to pass in a MCExpr for constant integers.
116 void MCStreamer::EmitSLEB128IntValue(int64_t Value) {
117 SmallString<128> Tmp;
118 raw_svector_ostream OSE(Tmp);
119 encodeSLEB128(Value, OSE);
120 EmitBytes(OSE.str());
123 void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
124 EmitValueImpl(Value, Size, Loc);
127 void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
128 bool IsSectionRelative) {
129 assert((!IsSectionRelative || Size == 4) &&
130 "SectionRelative value requires 4-bytes");
132 if (!IsSectionRelative)
133 EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
135 EmitCOFFSecRel32(Sym, /*Offset=*/0);
138 void MCStreamer::EmitDTPRel64Value(const MCExpr *Value) {
139 report_fatal_error("unsupported directive in streamer");
142 void MCStreamer::EmitDTPRel32Value(const MCExpr *Value) {
143 report_fatal_error("unsupported directive in streamer");
146 void MCStreamer::EmitTPRel64Value(const MCExpr *Value) {
147 report_fatal_error("unsupported directive in streamer");
150 void MCStreamer::EmitTPRel32Value(const MCExpr *Value) {
151 report_fatal_error("unsupported directive in streamer");
154 void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
155 report_fatal_error("unsupported directive in streamer");
158 void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
159 report_fatal_error("unsupported directive in streamer");
162 /// Emit NumBytes bytes worth of the value specified by FillValue.
163 /// This implements directives such as '.space'.
164 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
165 for (uint64_t i = 0, e = NumBytes; i != e; ++i)
166 EmitIntValue(FillValue, 1);
169 void MCStreamer::emitFill(uint64_t NumValues, int64_t Size, int64_t Expr) {
170 int64_t NonZeroSize = Size > 4 ? 4 : Size;
171 Expr &= ~0ULL >> (64 - NonZeroSize * 8);
172 for (uint64_t i = 0, e = NumValues; i != e; ++i) {
173 EmitIntValue(Expr, NonZeroSize);
174 if (NonZeroSize < Size)
175 EmitIntValue(0, Size - NonZeroSize);
179 /// The implementation in this class just redirects to emitFill.
180 void MCStreamer::EmitZeros(uint64_t NumBytes) {
181 emitFill(NumBytes, 0);
184 unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
186 StringRef Filename, unsigned CUID) {
187 return getContext().getDwarfFile(Directory, Filename, FileNo, CUID);
190 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
191 unsigned Column, unsigned Flags,
193 unsigned Discriminator,
194 StringRef FileName) {
195 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
199 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
200 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
201 if (!Table.getLabel()) {
202 StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
204 Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
206 return Table.getLabel();
209 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
210 return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
213 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
214 if (!hasUnfinishedDwarfFrameInfo()) {
215 getContext().reportError(SMLoc(), "this directive must appear between "
216 ".cfi_startproc and .cfi_endproc "
220 return &DwarfFrameInfos.back();
223 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
224 ArrayRef<uint8_t> Checksum,
225 unsigned ChecksumKind) {
226 return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
230 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
231 return getContext().getCVContext().recordFunctionId(FunctionId);
234 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
235 unsigned IAFunc, unsigned IAFile,
236 unsigned IALine, unsigned IACol,
238 if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
239 getContext().reportError(Loc, "parent function id not introduced by "
240 ".cv_func_id or .cv_inline_site_id");
244 return getContext().getCVContext().recordInlinedCallSiteId(
245 FunctionId, IAFunc, IAFile, IALine, IACol);
248 void MCStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
249 unsigned Line, unsigned Column,
250 bool PrologueEnd, bool IsStmt,
251 StringRef FileName, SMLoc Loc) {
252 CodeViewContext &CVC = getContext().getCVContext();
253 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FunctionId);
255 return getContext().reportError(
256 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
259 if (FI->Section == nullptr)
260 FI->Section = getCurrentSectionOnly();
261 else if (FI->Section != getCurrentSectionOnly())
262 return getContext().reportError(
264 "all .cv_loc directives for a function must be in the same section");
266 CVC.setCurrentCVLoc(FunctionId, FileNo, Line, Column, PrologueEnd, IsStmt);
269 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId,
270 const MCSymbol *Begin,
271 const MCSymbol *End) {}
273 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
274 unsigned SourceFileId,
275 unsigned SourceLineNum,
276 const MCSymbol *FnStartSym,
277 const MCSymbol *FnEndSym) {}
279 void MCStreamer::EmitCVDefRangeDirective(
280 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
281 StringRef FixedSizePortion) {}
283 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
284 MCSymbol *EHSymbol) {
287 void MCStreamer::InitSections(bool NoExecStack) {
288 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
291 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
293 Symbol->setFragment(Fragment);
295 // As we emit symbols into a section, track the order so that they can
296 // be sorted upon later. Zero is reserved to mean 'unemitted'.
297 SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
300 void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
301 Symbol->redefineIfPossible();
303 if (!Symbol->isUndefined() || Symbol->isVariable())
304 return getContext().reportError(Loc, "invalid symbol redefinition");
306 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
307 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
308 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
309 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
311 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
313 MCTargetStreamer *TS = getTargetStreamer();
315 TS->emitLabel(Symbol);
318 void MCStreamer::EmitCFISections(bool EH, bool Debug) {
322 void MCStreamer::EmitCFIStartProc(bool IsSimple) {
323 if (hasUnfinishedDwarfFrameInfo())
324 getContext().reportError(
325 SMLoc(), "starting new .cfi frame before finishing the previous one");
327 MCDwarfFrameInfo Frame;
328 Frame.IsSimple = IsSimple;
329 EmitCFIStartProcImpl(Frame);
331 const MCAsmInfo* MAI = Context.getAsmInfo();
333 for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
334 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
335 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
336 Frame.CurrentCfaRegister = Inst.getRegister();
341 DwarfFrameInfos.push_back(Frame);
344 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
347 void MCStreamer::EmitCFIEndProc() {
348 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
351 EmitCFIEndProcImpl(*CurFrame);
354 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
355 // Put a dummy non-null value in Frame.End to mark that this frame has been
357 Frame.End = (MCSymbol *)1;
360 MCSymbol *MCStreamer::EmitCFILabel() {
361 // Return a dummy non-null value so that label fields appear filled in when
362 // generating textual assembly.
363 return (MCSymbol *)1;
366 void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
367 MCSymbol *Label = EmitCFILabel();
368 MCCFIInstruction Instruction =
369 MCCFIInstruction::createDefCfa(Label, Register, Offset);
370 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
373 CurFrame->Instructions.push_back(Instruction);
374 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
377 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
378 MCSymbol *Label = EmitCFILabel();
379 MCCFIInstruction Instruction =
380 MCCFIInstruction::createDefCfaOffset(Label, Offset);
381 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
384 CurFrame->Instructions.push_back(Instruction);
387 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
388 MCSymbol *Label = EmitCFILabel();
389 MCCFIInstruction Instruction =
390 MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
391 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
394 CurFrame->Instructions.push_back(Instruction);
397 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
398 MCSymbol *Label = EmitCFILabel();
399 MCCFIInstruction Instruction =
400 MCCFIInstruction::createDefCfaRegister(Label, Register);
401 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
404 CurFrame->Instructions.push_back(Instruction);
405 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
408 void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
409 MCSymbol *Label = EmitCFILabel();
410 MCCFIInstruction Instruction =
411 MCCFIInstruction::createOffset(Label, Register, Offset);
412 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
415 CurFrame->Instructions.push_back(Instruction);
418 void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
419 MCSymbol *Label = EmitCFILabel();
420 MCCFIInstruction Instruction =
421 MCCFIInstruction::createRelOffset(Label, Register, Offset);
422 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
425 CurFrame->Instructions.push_back(Instruction);
428 void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
430 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
433 CurFrame->Personality = Sym;
434 CurFrame->PersonalityEncoding = Encoding;
437 void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
438 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
441 CurFrame->Lsda = Sym;
442 CurFrame->LsdaEncoding = Encoding;
445 void MCStreamer::EmitCFIRememberState() {
446 MCSymbol *Label = EmitCFILabel();
447 MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
448 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
451 CurFrame->Instructions.push_back(Instruction);
454 void MCStreamer::EmitCFIRestoreState() {
455 // FIXME: Error if there is no matching cfi_remember_state.
456 MCSymbol *Label = EmitCFILabel();
457 MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
458 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
461 CurFrame->Instructions.push_back(Instruction);
464 void MCStreamer::EmitCFISameValue(int64_t Register) {
465 MCSymbol *Label = EmitCFILabel();
466 MCCFIInstruction Instruction =
467 MCCFIInstruction::createSameValue(Label, Register);
468 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
471 CurFrame->Instructions.push_back(Instruction);
474 void MCStreamer::EmitCFIRestore(int64_t Register) {
475 MCSymbol *Label = EmitCFILabel();
476 MCCFIInstruction Instruction =
477 MCCFIInstruction::createRestore(Label, Register);
478 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
481 CurFrame->Instructions.push_back(Instruction);
484 void MCStreamer::EmitCFIEscape(StringRef Values) {
485 MCSymbol *Label = EmitCFILabel();
486 MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
487 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
490 CurFrame->Instructions.push_back(Instruction);
493 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
494 MCSymbol *Label = EmitCFILabel();
495 MCCFIInstruction Instruction =
496 MCCFIInstruction::createGnuArgsSize(Label, Size);
497 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
500 CurFrame->Instructions.push_back(Instruction);
503 void MCStreamer::EmitCFISignalFrame() {
504 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
507 CurFrame->IsSignalFrame = true;
510 void MCStreamer::EmitCFIUndefined(int64_t Register) {
511 MCSymbol *Label = EmitCFILabel();
512 MCCFIInstruction Instruction =
513 MCCFIInstruction::createUndefined(Label, Register);
514 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
517 CurFrame->Instructions.push_back(Instruction);
520 void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
521 MCSymbol *Label = EmitCFILabel();
522 MCCFIInstruction Instruction =
523 MCCFIInstruction::createRegister(Label, Register1, Register2);
524 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
527 CurFrame->Instructions.push_back(Instruction);
530 void MCStreamer::EmitCFIWindowSave() {
531 MCSymbol *Label = EmitCFILabel();
532 MCCFIInstruction Instruction =
533 MCCFIInstruction::createWindowSave(Label);
534 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
537 CurFrame->Instructions.push_back(Instruction);
540 void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
541 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
544 CurFrame->RAReg = Register;
547 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
548 const MCAsmInfo *MAI = Context.getAsmInfo();
549 if (!MAI->usesWindowsCFI()) {
550 getContext().reportError(
551 Loc, ".seh_* directives are not supported on this target");
554 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
555 getContext().reportError(
556 Loc, ".seh_ directive must appear within an active frame");
559 return CurrentWinFrameInfo;
562 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
563 const MCAsmInfo *MAI = Context.getAsmInfo();
564 if (!MAI->usesWindowsCFI())
565 return getContext().reportError(
566 Loc, ".seh_* directives are not supported on this target");
567 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
568 getContext().reportError(
569 Loc, "Starting a function before ending the previous one!");
571 MCSymbol *StartProc = EmitCFILabel();
573 WinFrameInfos.emplace_back(
574 llvm::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
575 CurrentWinFrameInfo = WinFrameInfos.back().get();
576 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
579 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
580 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
583 if (CurFrame->ChainedParent)
584 getContext().reportError(Loc, "Not all chained regions terminated!");
586 MCSymbol *Label = EmitCFILabel();
587 CurFrame->End = Label;
590 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
591 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
595 MCSymbol *StartProc = EmitCFILabel();
597 WinFrameInfos.emplace_back(llvm::make_unique<WinEH::FrameInfo>(
598 CurFrame->Function, StartProc, CurFrame));
599 CurrentWinFrameInfo = WinFrameInfos.back().get();
600 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
603 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
604 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
607 if (!CurFrame->ChainedParent)
608 return getContext().reportError(
609 Loc, "End of a chained region outside a chained region!");
611 MCSymbol *Label = EmitCFILabel();
613 CurFrame->End = Label;
614 CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
617 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
619 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
622 if (CurFrame->ChainedParent)
623 return getContext().reportError(
624 Loc, "Chained unwind areas can't have handlers!");
625 CurFrame->ExceptionHandler = Sym;
626 if (!Except && !Unwind)
627 getContext().reportError(Loc, "Don't know what kind of handler this is!");
629 CurFrame->HandlesUnwind = true;
631 CurFrame->HandlesExceptions = true;
634 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
635 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
638 if (CurFrame->ChainedParent)
639 getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
642 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
643 MCSection *MainCFISec,
644 const MCSection *TextSec) {
645 // If this is the main .text section, use the main unwind info section.
646 if (TextSec == Context.getObjectFileInfo()->getTextSection())
649 const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
650 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
652 // If this section is COMDAT, this unwind section should be COMDAT associative
654 const MCSymbol *KeySym = nullptr;
655 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
656 KeySym = TextSecCOFF->getCOMDATSymbol();
658 return Context.getAssociativeCOFFSection(cast<MCSectionCOFF>(MainCFISec),
662 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
663 return getWinCFISection(getContext(), &NextWinCFIID,
664 getContext().getObjectFileInfo()->getPDataSection(),
668 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
669 return getWinCFISection(getContext(), &NextWinCFIID,
670 getContext().getObjectFileInfo()->getXDataSection(),
674 void MCStreamer::EmitSyntaxDirective() {}
676 void MCStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
677 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
681 MCSymbol *Label = EmitCFILabel();
683 WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register);
684 CurFrame->Instructions.push_back(Inst);
687 void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
689 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
692 if (CurFrame->LastFrameInst >= 0)
693 return getContext().reportError(
694 Loc, "frame register and offset can be set at most once");
696 return getContext().reportError(Loc, "offset is not a multiple of 16");
698 return getContext().reportError(
699 Loc, "frame offset must be less than or equal to 240");
701 MCSymbol *Label = EmitCFILabel();
703 WinEH::Instruction Inst =
704 Win64EH::Instruction::SetFPReg(Label, Register, Offset);
705 CurFrame->LastFrameInst = CurFrame->Instructions.size();
706 CurFrame->Instructions.push_back(Inst);
709 void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
710 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
714 return getContext().reportError(Loc,
715 "stack allocation size must be non-zero");
717 return getContext().reportError(
718 Loc, "stack allocation size is not a multiple of 8");
720 MCSymbol *Label = EmitCFILabel();
722 WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
723 CurFrame->Instructions.push_back(Inst);
726 void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
728 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
733 return getContext().reportError(
734 Loc, "register save offset is not 8 byte aligned");
736 MCSymbol *Label = EmitCFILabel();
738 WinEH::Instruction Inst =
739 Win64EH::Instruction::SaveNonVol(Label, Register, Offset);
740 CurFrame->Instructions.push_back(Inst);
743 void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
745 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
749 return getContext().reportError(Loc, "offset is not a multiple of 16");
751 MCSymbol *Label = EmitCFILabel();
753 WinEH::Instruction Inst =
754 Win64EH::Instruction::SaveXMM(Label, Register, Offset);
755 CurFrame->Instructions.push_back(Inst);
758 void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
759 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
762 if (!CurFrame->Instructions.empty())
763 return getContext().reportError(
764 Loc, "If present, PushMachFrame must be the first UOP");
766 MCSymbol *Label = EmitCFILabel();
768 WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
769 CurFrame->Instructions.push_back(Inst);
772 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
773 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
777 MCSymbol *Label = EmitCFILabel();
779 CurFrame->PrologEnd = Label;
782 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
785 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
788 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
790 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
791 /// the specified string in the output .s file. This capability is
792 /// indicated by the hasRawTextSupport() predicate.
793 void MCStreamer::EmitRawTextImpl(StringRef String) {
794 errs() << "EmitRawText called on an MCStreamer that doesn't support it, "
795 " something must not be fully mc'ized\n";
799 void MCStreamer::EmitRawText(const Twine &T) {
800 SmallString<128> Str;
801 EmitRawTextImpl(T.toStringRef(Str));
804 void MCStreamer::EmitWindowsUnwindTables() {
807 void MCStreamer::Finish() {
808 if (!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End)
809 getContext().reportError(SMLoc(), "Unfinished frame!");
810 if (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)
811 getContext().reportError(SMLoc(), "Unfinished frame!");
813 MCTargetStreamer *TS = getTargetStreamer();
820 void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
821 visitUsedExpr(*Value);
822 Symbol->setVariableValue(Value);
824 MCTargetStreamer *TS = getTargetStreamer();
826 TS->emitAssignment(Symbol, Value);
829 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS,
830 const MCInst &Inst, const MCSubtargetInfo &STI) {
831 InstPrinter.printInst(&Inst, OS, "", STI);
834 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
837 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
838 switch (Expr.getKind()) {
840 cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
843 case MCExpr::Constant:
846 case MCExpr::Binary: {
847 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
848 visitUsedExpr(*BE.getLHS());
849 visitUsedExpr(*BE.getRHS());
853 case MCExpr::SymbolRef:
854 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
858 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
863 void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
866 for (unsigned i = Inst.getNumOperands(); i--;)
867 if (Inst.getOperand(i).isExpr())
868 visitUsedExpr(*Inst.getOperand(i).getExpr());
871 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
873 // Get the Hi-Lo expression.
875 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
876 MCSymbolRefExpr::create(Lo, Context), Context);
878 const MCAsmInfo *MAI = Context.getAsmInfo();
879 if (!MAI->doesSetDirectiveSuppressReloc()) {
880 EmitValue(Diff, Size);
884 // Otherwise, emit with .set (aka assignment).
885 MCSymbol *SetLabel = Context.createTempSymbol("set", true);
886 EmitAssignment(SetLabel, Diff);
887 EmitSymbolValue(SetLabel, Size);
890 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
891 void MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
892 void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
893 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
894 llvm_unreachable("this directive only supported on COFF targets");
896 void MCStreamer::EndCOFFSymbolDef() {
897 llvm_unreachable("this directive only supported on COFF targets");
899 void MCStreamer::EmitFileDirective(StringRef Filename) {}
900 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
901 llvm_unreachable("this directive only supported on COFF targets");
903 void MCStreamer::EmitCOFFSymbolType(int Type) {
904 llvm_unreachable("this directive only supported on COFF targets");
906 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
907 void MCStreamer::emitELFSymverDirective(MCSymbol *Alias,
908 const MCSymbol *Aliasee) {}
909 void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
910 unsigned ByteAlignment) {}
911 void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
912 uint64_t Size, unsigned ByteAlignment) {}
913 void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {}
914 void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
915 void MCStreamer::EmitBytes(StringRef Data) {}
916 void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); }
917 void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
918 visitUsedExpr(*Value);
920 void MCStreamer::EmitULEB128Value(const MCExpr *Value) {}
921 void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {}
922 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
923 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
925 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
927 unsigned MaxBytesToEmit) {}
928 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment,
929 unsigned MaxBytesToEmit) {}
930 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
932 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {}
933 void MCStreamer::EmitBundleLock(bool AlignToEnd) {}
934 void MCStreamer::FinishImpl() {}
935 void MCStreamer::EmitBundleUnlock() {}
937 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
938 assert(Section && "Cannot switch to a null section!");
939 MCSectionSubPair curSection = SectionStack.back().first;
940 SectionStack.back().second = curSection;
941 if (MCSectionSubPair(Section, Subsection) != curSection) {
942 ChangeSection(Section, Subsection);
943 SectionStack.back().first = MCSectionSubPair(Section, Subsection);
944 assert(!Section->hasEnded() && "Section already ended");
945 MCSymbol *Sym = Section->getBeginSymbol();
946 if (Sym && !Sym->isInSection())
951 MCSymbol *MCStreamer::endSection(MCSection *Section) {
952 // TODO: keep track of the last subsection so that this symbol appears in the
954 MCSymbol *Sym = Section->getEndSymbol(Context);
955 if (Sym->isInSection())
958 SwitchSection(Section);
963 void MCStreamer::EmitVersionForTarget(const Triple &Target) {
964 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
966 // Do we even know the version?
967 if (Target.getOSMajorVersion() == 0)
973 MCVersionMinType VersionType;
974 if (Target.isWatchOS()) {
975 VersionType = MCVM_WatchOSVersionMin;
976 Target.getWatchOSVersion(Major, Minor, Update);
977 } else if (Target.isTvOS()) {
978 VersionType = MCVM_TvOSVersionMin;
979 Target.getiOSVersion(Major, Minor, Update);
980 } else if (Target.isMacOSX()) {
981 VersionType = MCVM_OSXVersionMin;
982 if (!Target.getMacOSXVersion(Major, Minor, Update))
985 VersionType = MCVM_IOSVersionMin;
986 Target.getiOSVersion(Major, Minor, Update);
989 EmitVersionMin(VersionType, Major, Minor, Update);