1 //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/MC/MCStreamer.h"
10 #include "llvm/ADT/Optional.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/DebugInfo/CodeView/SymbolRecord.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/MCRegister.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCSection.h"
28 #include "llvm/MC/MCSectionCOFF.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/MC/MCWin64EH.h"
31 #include "llvm/MC/MCWinEH.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/LEB128.h"
35 #include "llvm/Support/MathExtras.h"
36 #include "llvm/Support/raw_ostream.h"
44 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
45 S.setTargetStreamer(this);
48 // Pin the vtables to this file.
49 MCTargetStreamer::~MCTargetStreamer() = default;
51 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
53 void MCTargetStreamer::finish() {}
55 void MCTargetStreamer::changeSection(const MCSection *CurSection,
57 const MCExpr *Subsection,
59 Section->PrintSwitchToSection(
60 *Streamer.getContext().getAsmInfo(),
61 Streamer.getContext().getObjectFileInfo()->getTargetTriple(), OS,
65 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
66 Streamer.emitRawText(Directive);
69 void MCTargetStreamer::emitValue(const MCExpr *Value) {
71 raw_svector_ostream OS(Str);
73 Value->print(OS, Streamer.getContext().getAsmInfo());
74 Streamer.emitRawText(OS.str());
77 void MCTargetStreamer::emitRawBytes(StringRef Data) {
78 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
79 const char *Directive = MAI->getData8bitsDirective();
80 for (const unsigned char C : Data.bytes()) {
82 raw_svector_ostream OS(Str);
84 OS << Directive << (unsigned)C;
85 Streamer.emitRawText(OS.str());
89 void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
91 MCStreamer::MCStreamer(MCContext &Ctx)
92 : Context(Ctx), CurrentWinFrameInfo(nullptr),
93 UseAssemblerInfoForParsing(false) {
94 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
97 MCStreamer::~MCStreamer() {}
99 void MCStreamer::reset() {
100 DwarfFrameInfos.clear();
101 CurrentWinFrameInfo = nullptr;
102 WinFrameInfos.clear();
103 SymbolOrdering.clear();
104 SectionStack.clear();
105 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
108 raw_ostream &MCStreamer::GetCommentOS() {
109 // By default, discard comments.
113 unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos.size(); }
114 ArrayRef<MCDwarfFrameInfo> MCStreamer::getDwarfFrameInfos() const {
115 return DwarfFrameInfos;
118 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
120 void MCStreamer::addExplicitComment(const Twine &T) {}
121 void MCStreamer::emitExplicitComments() {}
123 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
124 for (auto &FI : DwarfFrameInfos)
125 FI.CompactUnwindEncoding =
126 (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
129 /// EmitIntValue - Special case of EmitValue that avoids the client having to
130 /// pass in a MCExpr for constant integers.
131 void MCStreamer::emitIntValue(uint64_t Value, unsigned Size) {
132 assert(1 <= Size && Size <= 8 && "Invalid size");
133 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
135 const bool IsLittleEndian = Context.getAsmInfo()->isLittleEndian();
136 uint64_t Swapped = support::endian::byte_swap(
137 Value, IsLittleEndian ? support::little : support::big);
138 unsigned Index = IsLittleEndian ? 0 : 8 - Size;
139 emitBytes(StringRef(reinterpret_cast<char *>(&Swapped) + Index, Size));
142 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
143 /// client having to pass in a MCExpr for constant integers.
144 void MCStreamer::emitULEB128IntValue(uint64_t Value, unsigned PadTo) {
145 SmallString<128> Tmp;
146 raw_svector_ostream OSE(Tmp);
147 encodeULEB128(Value, OSE, PadTo);
148 emitBytes(OSE.str());
151 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
152 /// client having to pass in a MCExpr for constant integers.
153 void MCStreamer::emitSLEB128IntValue(int64_t Value) {
154 SmallString<128> Tmp;
155 raw_svector_ostream OSE(Tmp);
156 encodeSLEB128(Value, OSE);
157 emitBytes(OSE.str());
160 void MCStreamer::emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
161 emitValueImpl(Value, Size, Loc);
164 void MCStreamer::emitSymbolValue(const MCSymbol *Sym, unsigned Size,
165 bool IsSectionRelative) {
166 assert((!IsSectionRelative || Size == 4) &&
167 "SectionRelative value requires 4-bytes");
169 if (!IsSectionRelative)
170 emitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
172 EmitCOFFSecRel32(Sym, /*Offset=*/0);
175 void MCStreamer::emitDTPRel64Value(const MCExpr *Value) {
176 report_fatal_error("unsupported directive in streamer");
179 void MCStreamer::emitDTPRel32Value(const MCExpr *Value) {
180 report_fatal_error("unsupported directive in streamer");
183 void MCStreamer::emitTPRel64Value(const MCExpr *Value) {
184 report_fatal_error("unsupported directive in streamer");
187 void MCStreamer::emitTPRel32Value(const MCExpr *Value) {
188 report_fatal_error("unsupported directive in streamer");
191 void MCStreamer::emitGPRel64Value(const MCExpr *Value) {
192 report_fatal_error("unsupported directive in streamer");
195 void MCStreamer::emitGPRel32Value(const MCExpr *Value) {
196 report_fatal_error("unsupported directive in streamer");
199 /// Emit NumBytes bytes worth of the value specified by FillValue.
200 /// This implements directives such as '.space'.
201 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
202 emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
205 /// The implementation in this class just redirects to emitFill.
206 void MCStreamer::emitZeros(uint64_t NumBytes) { emitFill(NumBytes, 0); }
209 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
211 Optional<MD5::MD5Result> Checksum,
212 Optional<StringRef> Source,
214 return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
218 void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
220 Optional<MD5::MD5Result> Checksum,
221 Optional<StringRef> Source,
223 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
227 void MCStreamer::emitCFIBKeyFrame() {
228 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
231 CurFrame->IsBKeyFrame = true;
234 void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
235 unsigned Column, unsigned Flags,
236 unsigned Isa, unsigned Discriminator,
237 StringRef FileName) {
238 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
242 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
243 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
244 if (!Table.getLabel()) {
245 StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
247 Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
249 return Table.getLabel();
252 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
253 return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
256 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
257 if (!hasUnfinishedDwarfFrameInfo()) {
258 getContext().reportError(SMLoc(), "this directive must appear between "
259 ".cfi_startproc and .cfi_endproc "
263 return &DwarfFrameInfos.back();
266 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
267 ArrayRef<uint8_t> Checksum,
268 unsigned ChecksumKind) {
269 return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
273 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
274 return getContext().getCVContext().recordFunctionId(FunctionId);
277 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
278 unsigned IAFunc, unsigned IAFile,
279 unsigned IALine, unsigned IACol,
281 if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
282 getContext().reportError(Loc, "parent function id not introduced by "
283 ".cv_func_id or .cv_inline_site_id");
287 return getContext().getCVContext().recordInlinedCallSiteId(
288 FunctionId, IAFunc, IAFile, IALine, IACol);
291 void MCStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
292 unsigned Line, unsigned Column,
293 bool PrologueEnd, bool IsStmt,
294 StringRef FileName, SMLoc Loc) {}
296 bool MCStreamer::checkCVLocSection(unsigned FuncId, unsigned FileNo,
298 CodeViewContext &CVC = getContext().getCVContext();
299 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId);
301 getContext().reportError(
302 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
307 if (FI->Section == nullptr)
308 FI->Section = getCurrentSectionOnly();
309 else if (FI->Section != getCurrentSectionOnly()) {
310 getContext().reportError(
312 "all .cv_loc directives for a function must be in the same section");
318 void MCStreamer::emitCVLinetableDirective(unsigned FunctionId,
319 const MCSymbol *Begin,
320 const MCSymbol *End) {}
322 void MCStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
323 unsigned SourceFileId,
324 unsigned SourceLineNum,
325 const MCSymbol *FnStartSym,
326 const MCSymbol *FnEndSym) {}
328 /// Only call this on endian-specific types like ulittle16_t and little32_t, or
329 /// structs composed of them.
330 template <typename T>
331 static void copyBytesForDefRange(SmallString<20> &BytePrefix,
332 codeview::SymbolKind SymKind,
333 const T &DefRangeHeader) {
334 BytePrefix.resize(2 + sizeof(T));
335 codeview::ulittle16_t SymKindLE = codeview::ulittle16_t(SymKind);
336 memcpy(&BytePrefix[0], &SymKindLE, 2);
337 memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T));
340 void MCStreamer::emitCVDefRangeDirective(
341 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
342 StringRef FixedSizePortion) {}
344 void MCStreamer::emitCVDefRangeDirective(
345 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
346 codeview::DefRangeRegisterRelHeader DRHdr) {
347 SmallString<20> BytePrefix;
348 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER_REL, DRHdr);
349 emitCVDefRangeDirective(Ranges, BytePrefix);
352 void MCStreamer::emitCVDefRangeDirective(
353 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
354 codeview::DefRangeSubfieldRegisterHeader DRHdr) {
355 SmallString<20> BytePrefix;
356 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_SUBFIELD_REGISTER,
358 emitCVDefRangeDirective(Ranges, BytePrefix);
361 void MCStreamer::emitCVDefRangeDirective(
362 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
363 codeview::DefRangeRegisterHeader DRHdr) {
364 SmallString<20> BytePrefix;
365 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER, DRHdr);
366 emitCVDefRangeDirective(Ranges, BytePrefix);
369 void MCStreamer::emitCVDefRangeDirective(
370 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
371 codeview::DefRangeFramePointerRelHeader DRHdr) {
372 SmallString<20> BytePrefix;
373 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_FRAMEPOINTER_REL,
375 emitCVDefRangeDirective(Ranges, BytePrefix);
378 void MCStreamer::emitEHSymAttributes(const MCSymbol *Symbol,
379 MCSymbol *EHSymbol) {
382 void MCStreamer::InitSections(bool NoExecStack) {
383 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
386 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
388 Symbol->setFragment(Fragment);
390 // As we emit symbols into a section, track the order so that they can
391 // be sorted upon later. Zero is reserved to mean 'unemitted'.
392 SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
395 void MCStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
396 Symbol->redefineIfPossible();
398 if (!Symbol->isUndefined() || Symbol->isVariable())
399 return getContext().reportError(Loc, "invalid symbol redefinition");
401 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
402 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
403 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
404 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
406 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
408 MCTargetStreamer *TS = getTargetStreamer();
410 TS->emitLabel(Symbol);
413 void MCStreamer::emitCFISections(bool EH, bool Debug) {
417 void MCStreamer::emitCFIStartProc(bool IsSimple, SMLoc Loc) {
418 if (hasUnfinishedDwarfFrameInfo())
419 return getContext().reportError(
420 Loc, "starting new .cfi frame before finishing the previous one");
422 MCDwarfFrameInfo Frame;
423 Frame.IsSimple = IsSimple;
424 emitCFIStartProcImpl(Frame);
426 const MCAsmInfo* MAI = Context.getAsmInfo();
428 for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
429 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
430 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
431 Frame.CurrentCfaRegister = Inst.getRegister();
436 DwarfFrameInfos.push_back(Frame);
439 void MCStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
442 void MCStreamer::emitCFIEndProc() {
443 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
446 emitCFIEndProcImpl(*CurFrame);
449 void MCStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
450 // Put a dummy non-null value in Frame.End to mark that this frame has been
452 Frame.End = (MCSymbol *)1;
455 MCSymbol *MCStreamer::emitCFILabel() {
456 // Return a dummy non-null value so that label fields appear filled in when
457 // generating textual assembly.
458 return (MCSymbol *)1;
461 void MCStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset) {
462 MCSymbol *Label = emitCFILabel();
463 MCCFIInstruction Instruction =
464 MCCFIInstruction::cfiDefCfa(Label, Register, Offset);
465 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
468 CurFrame->Instructions.push_back(Instruction);
469 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
472 void MCStreamer::emitCFIDefCfaOffset(int64_t Offset) {
473 MCSymbol *Label = emitCFILabel();
474 MCCFIInstruction Instruction =
475 MCCFIInstruction::cfiDefCfaOffset(Label, Offset);
476 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
479 CurFrame->Instructions.push_back(Instruction);
482 void MCStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment) {
483 MCSymbol *Label = emitCFILabel();
484 MCCFIInstruction Instruction =
485 MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
486 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
489 CurFrame->Instructions.push_back(Instruction);
492 void MCStreamer::emitCFIDefCfaRegister(int64_t Register) {
493 MCSymbol *Label = emitCFILabel();
494 MCCFIInstruction Instruction =
495 MCCFIInstruction::createDefCfaRegister(Label, Register);
496 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
499 CurFrame->Instructions.push_back(Instruction);
500 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
503 void MCStreamer::emitCFIOffset(int64_t Register, int64_t Offset) {
504 MCSymbol *Label = emitCFILabel();
505 MCCFIInstruction Instruction =
506 MCCFIInstruction::createOffset(Label, Register, Offset);
507 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
510 CurFrame->Instructions.push_back(Instruction);
513 void MCStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset) {
514 MCSymbol *Label = emitCFILabel();
515 MCCFIInstruction Instruction =
516 MCCFIInstruction::createRelOffset(Label, Register, Offset);
517 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
520 CurFrame->Instructions.push_back(Instruction);
523 void MCStreamer::emitCFIPersonality(const MCSymbol *Sym,
525 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
528 CurFrame->Personality = Sym;
529 CurFrame->PersonalityEncoding = Encoding;
532 void MCStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
533 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
536 CurFrame->Lsda = Sym;
537 CurFrame->LsdaEncoding = Encoding;
540 void MCStreamer::emitCFIRememberState() {
541 MCSymbol *Label = emitCFILabel();
542 MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
543 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
546 CurFrame->Instructions.push_back(Instruction);
549 void MCStreamer::emitCFIRestoreState() {
550 // FIXME: Error if there is no matching cfi_remember_state.
551 MCSymbol *Label = emitCFILabel();
552 MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
553 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
556 CurFrame->Instructions.push_back(Instruction);
559 void MCStreamer::emitCFISameValue(int64_t Register) {
560 MCSymbol *Label = emitCFILabel();
561 MCCFIInstruction Instruction =
562 MCCFIInstruction::createSameValue(Label, Register);
563 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
566 CurFrame->Instructions.push_back(Instruction);
569 void MCStreamer::emitCFIRestore(int64_t Register) {
570 MCSymbol *Label = emitCFILabel();
571 MCCFIInstruction Instruction =
572 MCCFIInstruction::createRestore(Label, Register);
573 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
576 CurFrame->Instructions.push_back(Instruction);
579 void MCStreamer::emitCFIEscape(StringRef Values) {
580 MCSymbol *Label = emitCFILabel();
581 MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
582 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
585 CurFrame->Instructions.push_back(Instruction);
588 void MCStreamer::emitCFIGnuArgsSize(int64_t Size) {
589 MCSymbol *Label = emitCFILabel();
590 MCCFIInstruction Instruction =
591 MCCFIInstruction::createGnuArgsSize(Label, Size);
592 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
595 CurFrame->Instructions.push_back(Instruction);
598 void MCStreamer::emitCFISignalFrame() {
599 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
602 CurFrame->IsSignalFrame = true;
605 void MCStreamer::emitCFIUndefined(int64_t Register) {
606 MCSymbol *Label = emitCFILabel();
607 MCCFIInstruction Instruction =
608 MCCFIInstruction::createUndefined(Label, Register);
609 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
612 CurFrame->Instructions.push_back(Instruction);
615 void MCStreamer::emitCFIRegister(int64_t Register1, int64_t Register2) {
616 MCSymbol *Label = emitCFILabel();
617 MCCFIInstruction Instruction =
618 MCCFIInstruction::createRegister(Label, Register1, Register2);
619 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
622 CurFrame->Instructions.push_back(Instruction);
625 void MCStreamer::emitCFIWindowSave() {
626 MCSymbol *Label = emitCFILabel();
627 MCCFIInstruction Instruction =
628 MCCFIInstruction::createWindowSave(Label);
629 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
632 CurFrame->Instructions.push_back(Instruction);
635 void MCStreamer::emitCFINegateRAState() {
636 MCSymbol *Label = emitCFILabel();
637 MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label);
638 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
641 CurFrame->Instructions.push_back(Instruction);
644 void MCStreamer::emitCFIReturnColumn(int64_t Register) {
645 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
648 CurFrame->RAReg = Register;
651 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
652 const MCAsmInfo *MAI = Context.getAsmInfo();
653 if (!MAI->usesWindowsCFI()) {
654 getContext().reportError(
655 Loc, ".seh_* directives are not supported on this target");
658 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
659 getContext().reportError(
660 Loc, ".seh_ directive must appear within an active frame");
663 return CurrentWinFrameInfo;
666 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
667 const MCAsmInfo *MAI = Context.getAsmInfo();
668 if (!MAI->usesWindowsCFI())
669 return getContext().reportError(
670 Loc, ".seh_* directives are not supported on this target");
671 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
672 getContext().reportError(
673 Loc, "Starting a function before ending the previous one!");
675 MCSymbol *StartProc = emitCFILabel();
677 WinFrameInfos.emplace_back(
678 std::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
679 CurrentWinFrameInfo = WinFrameInfos.back().get();
680 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
683 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
684 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
687 if (CurFrame->ChainedParent)
688 getContext().reportError(Loc, "Not all chained regions terminated!");
690 MCSymbol *Label = emitCFILabel();
691 CurFrame->End = Label;
694 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
695 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
698 if (CurFrame->ChainedParent)
699 getContext().reportError(Loc, "Not all chained regions terminated!");
701 MCSymbol *Label = emitCFILabel();
702 CurFrame->FuncletOrFuncEnd = Label;
705 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
706 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
710 MCSymbol *StartProc = emitCFILabel();
712 WinFrameInfos.emplace_back(std::make_unique<WinEH::FrameInfo>(
713 CurFrame->Function, StartProc, CurFrame));
714 CurrentWinFrameInfo = WinFrameInfos.back().get();
715 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
718 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
719 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
722 if (!CurFrame->ChainedParent)
723 return getContext().reportError(
724 Loc, "End of a chained region outside a chained region!");
726 MCSymbol *Label = emitCFILabel();
728 CurFrame->End = Label;
729 CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
732 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
734 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
737 if (CurFrame->ChainedParent)
738 return getContext().reportError(
739 Loc, "Chained unwind areas can't have handlers!");
740 CurFrame->ExceptionHandler = Sym;
741 if (!Except && !Unwind)
742 getContext().reportError(Loc, "Don't know what kind of handler this is!");
744 CurFrame->HandlesUnwind = true;
746 CurFrame->HandlesExceptions = true;
749 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
750 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
753 if (CurFrame->ChainedParent)
754 getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
757 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
758 const MCSymbolRefExpr *To, uint64_t Count) {
761 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
762 MCSection *MainCFISec,
763 const MCSection *TextSec) {
764 // If this is the main .text section, use the main unwind info section.
765 if (TextSec == Context.getObjectFileInfo()->getTextSection())
768 const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
769 auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
770 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
772 // If this section is COMDAT, this unwind section should be COMDAT associative
774 const MCSymbol *KeySym = nullptr;
775 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
776 KeySym = TextSecCOFF->getCOMDATSymbol();
778 // In a GNU environment, we can't use associative comdats. Instead, do what
779 // GCC does, which is to make plain comdat selectany section named like
780 // ".[px]data$_Z3foov".
781 if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
782 std::string SectionName = (MainCFISecCOFF->getName() + "$" +
783 TextSecCOFF->getName().split('$').second)
785 return Context.getCOFFSection(
787 MainCFISecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT,
788 MainCFISecCOFF->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY);
792 return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
795 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
796 return getWinCFISection(getContext(), &NextWinCFIID,
797 getContext().getObjectFileInfo()->getPDataSection(),
801 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
802 return getWinCFISection(getContext(), &NextWinCFIID,
803 getContext().getObjectFileInfo()->getXDataSection(),
807 void MCStreamer::emitSyntaxDirective() {}
809 static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
810 return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
813 void MCStreamer::EmitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
814 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
818 MCSymbol *Label = emitCFILabel();
820 WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(
821 Label, encodeSEHRegNum(Context, Register));
822 CurFrame->Instructions.push_back(Inst);
825 void MCStreamer::EmitWinCFISetFrame(MCRegister Register, unsigned Offset,
827 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
830 if (CurFrame->LastFrameInst >= 0)
831 return getContext().reportError(
832 Loc, "frame register and offset can be set at most once");
834 return getContext().reportError(Loc, "offset is not a multiple of 16");
836 return getContext().reportError(
837 Loc, "frame offset must be less than or equal to 240");
839 MCSymbol *Label = emitCFILabel();
841 WinEH::Instruction Inst = Win64EH::Instruction::SetFPReg(
842 Label, encodeSEHRegNum(getContext(), Register), Offset);
843 CurFrame->LastFrameInst = CurFrame->Instructions.size();
844 CurFrame->Instructions.push_back(Inst);
847 void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
848 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
852 return getContext().reportError(Loc,
853 "stack allocation size must be non-zero");
855 return getContext().reportError(
856 Loc, "stack allocation size is not a multiple of 8");
858 MCSymbol *Label = emitCFILabel();
860 WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
861 CurFrame->Instructions.push_back(Inst);
864 void MCStreamer::EmitWinCFISaveReg(MCRegister Register, unsigned Offset,
866 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
871 return getContext().reportError(
872 Loc, "register save offset is not 8 byte aligned");
874 MCSymbol *Label = emitCFILabel();
876 WinEH::Instruction Inst = Win64EH::Instruction::SaveNonVol(
877 Label, encodeSEHRegNum(Context, Register), Offset);
878 CurFrame->Instructions.push_back(Inst);
881 void MCStreamer::EmitWinCFISaveXMM(MCRegister Register, unsigned Offset,
883 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
887 return getContext().reportError(Loc, "offset is not a multiple of 16");
889 MCSymbol *Label = emitCFILabel();
891 WinEH::Instruction Inst = Win64EH::Instruction::SaveXMM(
892 Label, encodeSEHRegNum(Context, Register), Offset);
893 CurFrame->Instructions.push_back(Inst);
896 void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
897 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
900 if (!CurFrame->Instructions.empty())
901 return getContext().reportError(
902 Loc, "If present, PushMachFrame must be the first UOP");
904 MCSymbol *Label = emitCFILabel();
906 WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
907 CurFrame->Instructions.push_back(Inst);
910 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
911 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
915 MCSymbol *Label = emitCFILabel();
917 CurFrame->PrologEnd = Label;
920 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {}
922 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {}
924 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {}
926 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
928 void MCStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
930 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
931 /// the specified string in the output .s file. This capability is
932 /// indicated by the hasRawTextSupport() predicate.
933 void MCStreamer::emitRawTextImpl(StringRef String) {
934 // This is not llvm_unreachable for the sake of out of tree backend
935 // developers who may not have assembly streamers and should serve as a
936 // reminder to not accidentally call EmitRawText in the absence of such.
937 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
938 "it (target backend is likely missing an AsmStreamer "
942 void MCStreamer::emitRawText(const Twine &T) {
943 SmallString<128> Str;
944 emitRawTextImpl(T.toStringRef(Str));
947 void MCStreamer::EmitWindowsUnwindTables() {
950 void MCStreamer::Finish() {
951 if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
952 (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
953 getContext().reportError(SMLoc(), "Unfinished frame!");
957 MCTargetStreamer *TS = getTargetStreamer();
964 void MCStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
965 visitUsedExpr(*Value);
966 Symbol->setVariableValue(Value);
968 MCTargetStreamer *TS = getTargetStreamer();
970 TS->emitAssignment(Symbol, Value);
973 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
974 uint64_t Address, const MCInst &Inst,
975 const MCSubtargetInfo &STI,
977 InstPrinter.printInst(&Inst, Address, "", STI, OS);
980 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
983 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
984 switch (Expr.getKind()) {
986 cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
989 case MCExpr::Constant:
992 case MCExpr::Binary: {
993 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
994 visitUsedExpr(*BE.getLHS());
995 visitUsedExpr(*BE.getRHS());
999 case MCExpr::SymbolRef:
1000 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
1004 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
1009 void MCStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
1011 for (unsigned i = Inst.getNumOperands(); i--;)
1012 if (Inst.getOperand(i).isExpr())
1013 visitUsedExpr(*Inst.getOperand(i).getExpr());
1016 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
1018 // Get the Hi-Lo expression.
1019 const MCExpr *Diff =
1020 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1021 MCSymbolRefExpr::create(Lo, Context), Context);
1023 const MCAsmInfo *MAI = Context.getAsmInfo();
1024 if (!MAI->doesSetDirectiveSuppressReloc()) {
1025 emitValue(Diff, Size);
1029 // Otherwise, emit with .set (aka assignment).
1030 MCSymbol *SetLabel = Context.createTempSymbol("set", true);
1031 emitAssignment(SetLabel, Diff);
1032 emitSymbolValue(SetLabel, Size);
1035 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
1036 const MCSymbol *Lo) {
1037 // Get the Hi-Lo expression.
1038 const MCExpr *Diff =
1039 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1040 MCSymbolRefExpr::create(Lo, Context), Context);
1042 emitULEB128Value(Diff);
1045 void MCStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {}
1046 void MCStreamer::emitThumbFunc(MCSymbol *Func) {}
1047 void MCStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
1048 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
1049 llvm_unreachable("this directive only supported on COFF targets");
1051 void MCStreamer::EndCOFFSymbolDef() {
1052 llvm_unreachable("this directive only supported on COFF targets");
1054 void MCStreamer::emitFileDirective(StringRef Filename) {}
1055 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
1056 llvm_unreachable("this directive only supported on COFF targets");
1058 void MCStreamer::EmitCOFFSymbolType(int Type) {
1059 llvm_unreachable("this directive only supported on COFF targets");
1061 void MCStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
1063 unsigned ByteAlign) {
1064 llvm_unreachable("this directive only supported on XCOFF targets");
1067 void MCStreamer::emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
1068 MCSymbolAttr Linkage,
1069 MCSymbolAttr Visibility) {
1070 llvm_unreachable("emitXCOFFSymbolLinkageWithVisibility is only supported on "
1074 void MCStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
1076 llvm_unreachable("emitXCOFFRenameDirective is only supported on "
1080 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
1081 void MCStreamer::emitELFSymverDirective(StringRef AliasName,
1082 const MCSymbol *Aliasee) {}
1083 void MCStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1084 unsigned ByteAlignment) {}
1085 void MCStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1086 uint64_t Size, unsigned ByteAlignment) {}
1087 void MCStreamer::changeSection(MCSection *, const MCExpr *) {}
1088 void MCStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
1089 void MCStreamer::emitBytes(StringRef Data) {}
1090 void MCStreamer::emitBinaryData(StringRef Data) { emitBytes(Data); }
1091 void MCStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
1092 visitUsedExpr(*Value);
1094 void MCStreamer::emitULEB128Value(const MCExpr *Value) {}
1095 void MCStreamer::emitSLEB128Value(const MCExpr *Value) {}
1096 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
1097 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
1099 void MCStreamer::emitValueToAlignment(unsigned ByteAlignment, int64_t Value,
1101 unsigned MaxBytesToEmit) {}
1102 void MCStreamer::emitCodeAlignment(unsigned ByteAlignment,
1103 unsigned MaxBytesToEmit) {}
1104 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
1106 void MCStreamer::emitBundleAlignMode(unsigned AlignPow2) {}
1107 void MCStreamer::emitBundleLock(bool AlignToEnd) {}
1108 void MCStreamer::finishImpl() {}
1109 void MCStreamer::emitBundleUnlock() {}
1111 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
1112 assert(Section && "Cannot switch to a null section!");
1113 MCSectionSubPair curSection = SectionStack.back().first;
1114 SectionStack.back().second = curSection;
1115 if (MCSectionSubPair(Section, Subsection) != curSection) {
1116 changeSection(Section, Subsection);
1117 SectionStack.back().first = MCSectionSubPair(Section, Subsection);
1118 assert(!Section->hasEnded() && "Section already ended");
1119 MCSymbol *Sym = Section->getBeginSymbol();
1120 if (Sym && !Sym->isInSection())
1125 MCSymbol *MCStreamer::endSection(MCSection *Section) {
1126 // TODO: keep track of the last subsection so that this symbol appears in the
1128 MCSymbol *Sym = Section->getEndSymbol(Context);
1129 if (Sym->isInSection())
1132 SwitchSection(Section);
1138 targetVersionOrMinimumSupportedOSVersion(const Triple &Target,
1139 VersionTuple TargetVersion) {
1140 VersionTuple Min = Target.getMinimumSupportedOSVersion();
1141 return !Min.empty() && Min > TargetVersion ? Min : TargetVersion;
1144 static MCVersionMinType
1145 getMachoVersionMinLoadCommandType(const Triple &Target) {
1146 assert(Target.isOSDarwin() && "expected a darwin OS");
1147 switch (Target.getOS()) {
1148 case Triple::MacOSX:
1149 case Triple::Darwin:
1150 return MCVM_OSXVersionMin;
1152 assert(!Target.isMacCatalystEnvironment() &&
1153 "mac Catalyst should use LC_BUILD_VERSION");
1154 return MCVM_IOSVersionMin;
1156 return MCVM_TvOSVersionMin;
1157 case Triple::WatchOS:
1158 return MCVM_WatchOSVersionMin;
1162 llvm_unreachable("unexpected OS type");
1165 static VersionTuple getMachoBuildVersionSupportedOS(const Triple &Target) {
1166 assert(Target.isOSDarwin() && "expected a darwin OS");
1167 switch (Target.getOS()) {
1168 case Triple::MacOSX:
1169 case Triple::Darwin:
1170 return VersionTuple(10, 14);
1172 // Mac Catalyst always uses the build version load command.
1173 if (Target.isMacCatalystEnvironment())
1174 return VersionTuple();
1177 return VersionTuple(12);
1178 case Triple::WatchOS:
1179 return VersionTuple(5);
1183 llvm_unreachable("unexpected OS type");
1186 static MachO::PlatformType
1187 getMachoBuildVersionPlatformType(const Triple &Target) {
1188 assert(Target.isOSDarwin() && "expected a darwin OS");
1189 switch (Target.getOS()) {
1190 case Triple::MacOSX:
1191 case Triple::Darwin:
1192 return MachO::PLATFORM_MACOS;
1194 if (Target.isMacCatalystEnvironment())
1195 return MachO::PLATFORM_MACCATALYST;
1196 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
1197 : MachO::PLATFORM_IOS;
1199 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
1200 : MachO::PLATFORM_TVOS;
1201 case Triple::WatchOS:
1202 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
1203 : MachO::PLATFORM_WATCHOS;
1207 llvm_unreachable("unexpected OS type");
1210 void MCStreamer::emitVersionForTarget(const Triple &Target,
1211 const VersionTuple &SDKVersion) {
1212 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
1214 // Do we even know the version?
1215 if (Target.getOSMajorVersion() == 0)
1220 unsigned Update = 0;
1221 switch (Target.getOS()) {
1222 case Triple::MacOSX:
1223 case Triple::Darwin:
1224 Target.getMacOSXVersion(Major, Minor, Update);
1228 Target.getiOSVersion(Major, Minor, Update);
1230 case Triple::WatchOS:
1231 Target.getWatchOSVersion(Major, Minor, Update);
1234 llvm_unreachable("unexpected OS type");
1236 assert(Major != 0 && "A non-zero major version is expected");
1237 auto LinkedTargetVersion = targetVersionOrMinimumSupportedOSVersion(
1238 Target, VersionTuple(Major, Minor, Update));
1239 auto BuildVersionOSVersion = getMachoBuildVersionSupportedOS(Target);
1240 if (BuildVersionOSVersion.empty() ||
1241 LinkedTargetVersion >= BuildVersionOSVersion)
1242 return emitBuildVersion(getMachoBuildVersionPlatformType(Target),
1243 LinkedTargetVersion.getMajor(),
1244 *LinkedTargetVersion.getMinor(),
1245 *LinkedTargetVersion.getSubminor(), SDKVersion);
1247 emitVersionMin(getMachoVersionMinLoadCommandType(Target),
1248 LinkedTargetVersion.getMajor(),
1249 *LinkedTargetVersion.getMinor(),
1250 *LinkedTargetVersion.getSubminor(), SDKVersion);