LLVM 23.0.0git
MCStreamer.cpp
Go to the documentation of this file.
1//===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
11#include "llvm/ADT/StringRef.h"
12#include "llvm/ADT/Twine.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"
26#include "llvm/MC/MCRegister.h"
28#include "llvm/MC/MCSection.h"
30#include "llvm/MC/MCSymbol.h"
31#include "llvm/MC/MCWin64EH.h"
32#include "llvm/MC/MCWinEH.h"
35#include "llvm/Support/LEB128.h"
38#include <cassert>
39#include <cstdint>
40#include <cstdlib>
41#include <optional>
42#include <utility>
43
44using namespace llvm;
45
49
50// Pin the vtables to this file.
52
54
56
58
60 uint32_t Subsection, raw_ostream &OS) {
61 auto &MAI = Streamer.getContext().getAsmInfo();
62 MAI.printSwitchToSection(*Sec, Subsection,
63 Streamer.getContext().getTargetTriple(), OS);
64}
65
69
72 raw_svector_ostream OS(Str);
73
74 Streamer.getContext().getAsmInfo().printExpr(OS, *Value);
75 Streamer.emitRawText(OS.str());
76}
77
79 const MCAsmInfo &MAI = Streamer.getContext().getAsmInfo();
80 const char *Directive = MAI.getData8bitsDirective();
81 for (const unsigned char C : Data.bytes()) {
83 raw_svector_ostream OS(Str);
84
85 OS << Directive << (unsigned)C;
86 Streamer.emitRawText(OS.str());
87 }
88}
89
91
93 : Context(Ctx), CurrentWinFrameInfo(nullptr),
94 CurrentProcWinFrameInfoStartIndex(0) {
95 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
96}
97
98MCStreamer::~MCStreamer() = default;
99
100void MCStreamer::setLFIRewriter(std::unique_ptr<MCLFIRewriter> Rewriter) {
101 LFIRewriter = std::move(Rewriter);
102}
103
105 DwarfFrameInfos.clear();
106 CurrentWinFrameInfo = nullptr;
107 WinFrameInfos.clear();
108 SectionStack.clear();
109 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
110 CurFrag = nullptr;
111}
112
114 // By default, discard comments.
115 return nulls();
116}
117
122
123void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
124
127
128/// EmitIntValue - Special case of EmitValue that avoids the client having to
129/// pass in a MCExpr for constant integers.
131 assert(1 <= Size && Size <= 8 && "Invalid size");
132 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
133 "Invalid size");
134 const bool IsLittleEndian = Context.getAsmInfo().isLittleEndian();
137 unsigned Index = IsLittleEndian ? 0 : 8 - Size;
138 emitBytes(StringRef(reinterpret_cast<char *>(&Swapped) + Index, Size));
139}
141 if (Value.getNumWords() == 1) {
142 emitIntValue(Value.getLimitedValue(), Value.getBitWidth() / 8);
143 return;
144 }
145
146 const bool IsLittleEndianTarget = Context.getAsmInfo().isLittleEndian();
147 const bool ShouldSwap = sys::IsLittleEndianHost != IsLittleEndianTarget;
148 const APInt Swapped = ShouldSwap ? Value.byteSwap() : Value;
149 const unsigned Size = Value.getBitWidth() / 8;
150 SmallString<10> Tmp;
151 Tmp.resize(Size);
152 StoreIntToMemory(Swapped, reinterpret_cast<uint8_t *>(Tmp.data()), Size);
153 emitBytes(Tmp.str());
154}
155
156/// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
157/// client having to pass in a MCExpr for constant integers.
160 raw_svector_ostream OSE(Tmp);
161 encodeULEB128(Value, OSE, PadTo);
162 emitBytes(OSE.str());
163 return Tmp.size();
164}
165
166/// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
167/// client having to pass in a MCExpr for constant integers.
170 raw_svector_ostream OSE(Tmp);
171 encodeSLEB128(Value, OSE);
172 emitBytes(OSE.str());
173 return Tmp.size();
174}
175
178}
179
180void MCStreamer::emitSymbolValue(const MCSymbol *Sym, unsigned Size,
181 bool IsSectionRelative) {
182 assert((!IsSectionRelative || Size == 4) &&
183 "SectionRelative value requires 4-bytes");
184
185 if (!IsSectionRelative)
187 else
188 emitCOFFSecRel32(Sym, /*Offset=*/0);
189}
190
191/// Emit NumBytes bytes worth of the value specified by FillValue.
192/// This implements directives such as '.space'.
193void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
194 if (NumBytes)
195 emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
196}
197
198void llvm::MCStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLen,
199 llvm::SMLoc, const MCSubtargetInfo& STI) {}
200
201/// The implementation in this class just redirects to emitFill.
202void MCStreamer::emitZeros(uint64_t NumBytes) { emitFill(NumBytes, 0); }
203
205 unsigned FileNo, StringRef Directory, StringRef Filename,
206 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
207 unsigned CUID) {
208 return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
209 Source, CUID);
210}
211
214 std::optional<MD5::MD5Result> Checksum,
215 std::optional<StringRef> Source,
216 unsigned CUID) {
217 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
218 Source);
219}
220
222 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
223 if (!CurFrame)
224 return;
225 CurFrame->IsBKeyFrame = true;
226}
227
229 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
230 if (!CurFrame)
231 return;
232 CurFrame->IsMTETaggedFrame = true;
233}
234
235void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
236 unsigned Column, unsigned Flags,
237 unsigned Isa, unsigned Discriminator,
238 StringRef FileName, StringRef Comment) {
239 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
240 Discriminator);
241}
242
248
251 if (!Table.getLabel()) {
252 StringRef Prefix = Context.getAsmInfo().getInternalSymbolPrefix();
253 Table.setLabel(
254 Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
255 }
256 return Table.getLabel();
257}
258
260 return !FrameInfoStack.empty();
261}
262
263MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
266 "this directive must appear between "
267 ".cfi_startproc and .cfi_endproc directives");
268 return nullptr;
269 }
270 return &DwarfFrameInfos[FrameInfoStack.back().first];
271}
272
274 ArrayRef<uint8_t> Checksum,
275 unsigned ChecksumKind) {
276 return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
277 ChecksumKind);
278}
279
283
285 unsigned IAFunc, unsigned IAFile,
286 unsigned IALine, unsigned IACol,
287 SMLoc Loc) {
288 if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
289 getContext().reportError(Loc, "parent function id not introduced by "
290 ".cv_func_id or .cv_inline_site_id");
291 return true;
292 }
293
295 FunctionId, IAFunc, IAFile, IALine, IACol);
296}
297
298void MCStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
299 unsigned Line, unsigned Column,
300 bool PrologueEnd, bool IsStmt,
301 StringRef FileName, SMLoc Loc) {}
302
303bool MCStreamer::checkCVLocSection(unsigned FuncId, unsigned FileNo,
304 SMLoc Loc) {
306 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId);
307 if (!FI) {
309 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
310 return false;
311 }
312
313 // Track the section
314 if (FI->Section == nullptr)
316 else if (FI->Section != getCurrentSectionOnly()) {
318 Loc,
319 "all .cv_loc directives for a function must be in the same section");
320 return false;
321 }
322 return true;
323}
324
326 const MCSymbol *Begin,
327 const MCSymbol *End) {}
328
329void MCStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
330 unsigned SourceFileId,
331 unsigned SourceLineNum,
332 const MCSymbol *FnStartSym,
333 const MCSymbol *FnEndSym) {}
334
335/// Only call this on endian-specific types like ulittle16_t and little32_t, or
336/// structs composed of them.
337template <typename T>
338static void copyBytesForDefRange(SmallString<20> &BytePrefix,
339 codeview::SymbolKind SymKind,
340 const T &DefRangeHeader) {
341 BytePrefix.resize(2 + sizeof(T));
342 codeview::ulittle16_t SymKindLE = codeview::ulittle16_t(SymKind);
343 memcpy(&BytePrefix[0], &SymKindLE, 2);
344 memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T));
345}
346
348 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
349 StringRef FixedSizePortion) {}
350
352 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
354 SmallString<20> BytePrefix;
355 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER_REL, DRHdr);
356 emitCVDefRangeDirective(Ranges, BytePrefix);
357}
358
360 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
362 SmallString<20> BytePrefix;
363 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_SUBFIELD_REGISTER,
364 DRHdr);
365 emitCVDefRangeDirective(Ranges, BytePrefix);
366}
367
369 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
371 SmallString<20> BytePrefix;
372 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER, DRHdr);
373 emitCVDefRangeDirective(Ranges, BytePrefix);
374}
375
377 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
379 SmallString<20> BytePrefix;
380 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_FRAMEPOINTER_REL,
381 DRHdr);
382 emitCVDefRangeDirective(Ranges, BytePrefix);
383}
384
386 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
388 SmallString<20> BytePrefix;
389 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER_REL_INDIR,
390 DRHdr);
391 emitCVDefRangeDirective(Ranges, BytePrefix);
392}
393
395 MCSymbol *EHSymbol) {
396}
397
399 switchSectionNoPrint(getContext().getObjectFileInfo()->getTextSection());
400}
401
403 Symbol->redefineIfPossible();
404
405 if (!Symbol->isUndefined() || Symbol->isVariable())
406 return getContext().reportError(Loc, "symbol '" + Twine(Symbol->getName()) +
407 "' is already defined");
408
409 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
410 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
411 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
412 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
413
414 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
415
416 if (LFIRewriter)
417 LFIRewriter->onLabel(Symbol);
418
420 if (TS)
421 TS->emitLabel(Symbol);
422}
423
426
427void MCStreamer::emitCFISections(bool EH, bool Debug, bool SFrame) {}
428
430 if (!FrameInfoStack.empty() &&
431 getCurrentSectionOnly() == FrameInfoStack.back().second)
432 return getContext().reportError(
433 Loc, "starting new .cfi frame before finishing the previous one");
434
435 MCDwarfFrameInfo Frame;
436 Frame.IsSimple = IsSimple;
438
439 const MCAsmInfo &MAI = Context.getAsmInfo();
440 for (const MCCFIInstruction &Inst : MAI.getInitialFrameState()) {
441 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
442 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister ||
443 Inst.getOperation() == MCCFIInstruction::OpLLVMDefAspaceCfa) {
444 Frame.CurrentCfaRegister = Inst.getRegister();
445 }
446 }
447
448 FrameInfoStack.emplace_back(DwarfFrameInfos.size(), getCurrentSectionOnly());
449 DwarfFrameInfos.push_back(std::move(Frame));
450}
451
454
456 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
457 if (!CurFrame)
458 return;
459 emitCFIEndProcImpl(*CurFrame);
460 FrameInfoStack.pop_back();
461}
462
464 // Put a dummy non-null value in Frame.End to mark that this frame has been
465 // closed.
466 Frame.End = (MCSymbol *)1;
467}
468
470 // Create a label and insert it into the line table and return this label
471 const MCDwarfLoc &DwarfLoc = getContext().getCurrentDwarfLoc();
472
473 MCSymbol *LineStreamLabel = getContext().createTempSymbol();
474 MCDwarfLineEntry LabelLineEntry(nullptr, DwarfLoc, LineStreamLabel);
475 getContext()
476 .getMCDwarfLineTable(getContext().getDwarfCompileUnitID())
478 .addLineEntry(LabelLineEntry, getCurrentSectionOnly() /*Section*/);
479
480 return LineStreamLabel;
481}
482
484 // Return a dummy non-null value so that label fields appear filled in when
485 // generating textual assembly.
486 return (MCSymbol *)1;
487}
488
490 MCSymbol *Label = emitCFILabel();
493 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
494 if (!CurFrame)
495 return;
496 CurFrame->Instructions.push_back(std::move(Instruction));
497 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
498}
499
501 MCSymbol *Label = emitCFILabel();
504 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
505 if (!CurFrame)
506 return;
507 CurFrame->Instructions.push_back(std::move(Instruction));
508}
509
511 MCSymbol *Label = emitCFILabel();
514 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
515 if (!CurFrame)
516 return;
517 CurFrame->Instructions.push_back(std::move(Instruction));
518}
519
521 MCSymbol *Label = emitCFILabel();
524 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
525 if (!CurFrame)
526 return;
527 CurFrame->Instructions.push_back(std::move(Instruction));
528 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
529}
530
532 int64_t AddressSpace, SMLoc Loc) {
533 MCSymbol *Label = emitCFILabel();
535 Label, Register, Offset, AddressSpace, Loc);
536 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
537 if (!CurFrame)
538 return;
539 CurFrame->Instructions.push_back(std::move(Instruction));
540 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
541}
542
544 MCSymbol *Label = emitCFILabel();
547 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
548 if (!CurFrame)
549 return;
550 CurFrame->Instructions.push_back(std::move(Instruction));
551}
552
554 MCSymbol *Label = emitCFILabel();
557 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
558 if (!CurFrame)
559 return;
560 CurFrame->Instructions.push_back(std::move(Instruction));
561}
562
564 unsigned Encoding) {
565 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
566 if (!CurFrame)
567 return;
568 CurFrame->Personality = Sym;
569 CurFrame->PersonalityEncoding = Encoding;
570}
571
572void MCStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
573 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
574 if (!CurFrame)
575 return;
576 CurFrame->Lsda = Sym;
577 CurFrame->LsdaEncoding = Encoding;
578}
579
581 MCSymbol *Label = emitCFILabel();
584 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
585 if (!CurFrame)
586 return;
587 CurFrame->Instructions.push_back(std::move(Instruction));
588}
589
591 // FIXME: Error if there is no matching cfi_remember_state.
592 MCSymbol *Label = emitCFILabel();
595 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
596 if (!CurFrame)
597 return;
598 CurFrame->Instructions.push_back(std::move(Instruction));
599}
600
602 MCSymbol *Label = emitCFILabel();
605 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
606 if (!CurFrame)
607 return;
608 CurFrame->Instructions.push_back(std::move(Instruction));
609}
610
612 MCSymbol *Label = emitCFILabel();
615 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
616 if (!CurFrame)
617 return;
618 CurFrame->Instructions.push_back(std::move(Instruction));
619}
620
622 MCSymbol *Label = emitCFILabel();
624 MCCFIInstruction::createEscape(Label, Values, Loc, "");
625 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
626 if (!CurFrame)
627 return;
628 CurFrame->Instructions.push_back(std::move(Instruction));
629}
630
632 MCSymbol *Label = emitCFILabel();
635 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
636 if (!CurFrame)
637 return;
638 CurFrame->Instructions.push_back(std::move(Instruction));
639}
640
642 int64_t R1Size, int64_t R2,
643 int64_t R2Size, SMLoc Loc) {
644 MCSymbol *Label = emitCFILabel();
646 Label, Register, R1, R1Size, R2, R2Size, Loc);
647 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
648 if (!CurFrame)
649 return;
650 CurFrame->Instructions.push_back(std::move(Instruction));
651}
652
655 SMLoc Loc) {
656 MCSymbol *Label = emitCFILabel();
659 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
660 if (!CurFrame)
661 return;
662 CurFrame->Instructions.push_back(std::move(Instruction));
663}
664
666 int64_t RegisterSizeInBits,
667 int64_t MaskRegister,
668 int64_t MaskRegisterSizeInBits,
669 int64_t Offset, SMLoc Loc) {
670 MCSymbol *Label = emitCFILabel();
672 Label, Register, RegisterSizeInBits, MaskRegister, MaskRegisterSizeInBits,
673 Offset, Loc);
674 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
675 if (!CurFrame)
676 return;
677 CurFrame->Instructions.push_back(std::move(Instruction));
678}
679
681 int64_t Register, int64_t SpillRegister,
682 int64_t SpillRegisterLaneSizeInBits, int64_t MaskRegister,
683 int64_t MaskRegisterSizeInBits, SMLoc Loc) {
684
685 MCSymbol *Label = emitCFILabel();
687 Label, Register, SpillRegister, SpillRegisterLaneSizeInBits, MaskRegister,
688 MaskRegisterSizeInBits, Loc);
689 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
690 if (!CurFrame)
691 return;
692 CurFrame->Instructions.push_back(std::move(Instruction));
693}
694
696 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
697 if (!CurFrame)
698 return;
699 CurFrame->IsSignalFrame = true;
700}
701
703 MCSymbol *Label = emitCFILabel();
706 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
707 if (!CurFrame)
708 return;
709 CurFrame->Instructions.push_back(std::move(Instruction));
710}
711
712void MCStreamer::emitCFIRegister(int64_t Register1, int64_t Register2,
713 SMLoc Loc) {
714 MCSymbol *Label = emitCFILabel();
716 MCCFIInstruction::createRegister(Label, Register1, Register2, Loc);
717 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
718 if (!CurFrame)
719 return;
720 CurFrame->Instructions.push_back(std::move(Instruction));
721}
722
724 MCSymbol *Label = emitCFILabel();
726 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
727 if (!CurFrame)
728 return;
729 CurFrame->Instructions.push_back(std::move(Instruction));
730}
731
733 MCSymbol *Label = emitCFILabel();
736 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
737 if (!CurFrame)
738 return;
739 CurFrame->Instructions.push_back(std::move(Instruction));
740}
741
743 MCSymbol *Label = emitCFILabel();
746 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
747 if (!CurFrame)
748 return;
749 CurFrame->Instructions.push_back(std::move(Instruction));
750}
751
753 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
754 if (!CurFrame)
755 return;
756 CurFrame->RAReg = Register;
757}
758
760 MCSymbol *Label = emitCFILabel();
762 if (MCDwarfFrameInfo *F = getCurrentDwarfFrameInfo())
763 F->Instructions.push_back(MCCFIInstruction::createLabel(Label, Sym, Loc));
764}
765
767 MCSymbol *Label = emitCFILabel();
770 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
771 if (!CurFrame)
772 return;
773 CurFrame->Instructions.push_back(std::move(Instruction));
774}
775
777 const MCAsmInfo &MAI = Context.getAsmInfo();
778 if (!MAI.usesWindowsCFI()) {
780 Loc, ".seh_* directives are not supported on this target");
781 return nullptr;
782 }
783 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
785 Loc, ".seh_ directive must appear within an active frame");
786 return nullptr;
787 }
788 return CurrentWinFrameInfo;
790
792 const MCAsmInfo &MAI = Context.getAsmInfo();
793 if (!MAI.usesWindowsCFI())
794 return getContext().reportError(
795 Loc, ".seh_* directives are not supported on this target");
796 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
798 Loc, "Starting a function before ending the previous one!");
799
800 MCSymbol *StartProc = emitCFILabel();
801
802 CurrentProcWinFrameInfoStartIndex = WinFrameInfos.size();
803 WinFrameInfos.emplace_back(
804 std::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
805 CurrentWinFrameInfo = WinFrameInfos.back().get();
806 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
807 CurrentWinFrameInfo->FunctionLoc = Loc;
808 // Inherit the module-wide default unwind version.
809 CurrentWinFrameInfo->Version = DefaultWinCFIUnwindVersion;
810}
811
814 if (!CurFrame)
815 return;
816 CurrentWinFrameInfo = nullptr;
817
818 MCSymbol *Label = emitCFILabel();
819 CurFrame->End = Label;
820 const MCSymbol **FuncletOrFuncEndPtr =
821 CurFrame->ChainedParent ? &CurFrame->ChainedParent->FuncletOrFuncEnd
822 : &CurFrame->FuncletOrFuncEnd;
823 if (!*FuncletOrFuncEndPtr)
824 *FuncletOrFuncEndPtr = CurFrame->End;
825
826 if (CurrentWinEpilog) {
827 // Set End to... something... to prevent crashes later.
829 CurrentWinEpilog = nullptr;
830 getContext().reportError(Loc, "Missing .seh_endepilogue in " +
831 CurFrame->Function->getName());
832 }
833
834 for (size_t I = CurrentProcWinFrameInfoStartIndex, E = WinFrameInfos.size();
835 I != E; ++I)
836 emitWindowsUnwindTables(WinFrameInfos[I].get());
837 switchSection(CurFrame->TextSection);
838}
839
842 if (!CurFrame)
843 return;
844
845 MCSymbol *Label = emitCFILabel();
846 const MCSymbol **FuncletOrFuncEndPtr =
847 CurFrame->ChainedParent ? &CurFrame->ChainedParent->FuncletOrFuncEnd
848 : &CurFrame->FuncletOrFuncEnd;
849 *FuncletOrFuncEndPtr = Label;
850}
851
854 if (!CurFrame)
855 return;
856
857 if (!CurFrame->PrologEnd)
858 return getContext().reportError(
859 Loc, "can't split into a new chained region (.seh_splitchained) in the "
860 "middle of a prolog in " +
861 CurFrame->Function->getName());
862
863 MCSymbol *Label = emitCFILabel();
864
865 // Complete the current frame before starting a new, chained one.
866 CurFrame->End = Label;
867
868 // All chained frames point to the same parent.
869 WinEH::FrameInfo *ChainedParent =
870 CurFrame->ChainedParent ? CurFrame->ChainedParent : CurFrame;
871
872 WinFrameInfos.emplace_back(std::make_unique<WinEH::FrameInfo>(
873 CurFrame->Function, Label, ChainedParent));
874 CurrentWinFrameInfo = WinFrameInfos.back().get();
875 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
876}
877
878void MCStreamer::emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
879 SMLoc Loc) {
881 if (!CurFrame)
882 return;
883
884 // Handlers are always associated with the parent frame.
885 CurFrame = CurFrame->ChainedParent ? CurFrame->ChainedParent : CurFrame;
886
887 CurFrame->ExceptionHandler = Sym;
888 if (!Except && !Unwind)
889 getContext().reportError(Loc, "Don't know what kind of handler this is!");
890 if (Unwind)
891 CurFrame->HandlesUnwind = true;
892 if (Except)
893 CurFrame->HandlesExceptions = true;
894}
895
898 if (!CurFrame)
899 return;
900}
901
905
906static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
907 MCSection *MainCFISec,
908 const MCSection *TextSec) {
909 // If this is the main .text section, use the main unwind info section.
910 if (TextSec == Context.getObjectFileInfo()->getTextSection())
911 return MainCFISec;
912
913 const auto *TextSecCOFF = static_cast<const MCSectionCOFF *>(TextSec);
914 auto *MainCFISecCOFF = static_cast<MCSectionCOFF *>(MainCFISec);
915 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
916
917 // If this section is COMDAT, this unwind section should be COMDAT associative
918 // with its group.
919 const MCSymbol *KeySym = nullptr;
920 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
921 KeySym = TextSecCOFF->getCOMDATSymbol();
922
923 // In a GNU environment, we can't use associative comdats. Instead, do what
924 // GCC does, which is to make plain comdat selectany section named like
925 // ".[px]data$_Z3foov".
926 if (!Context.getAsmInfo().hasCOFFAssociativeComdats()) {
927 std::string SectionName = (MainCFISecCOFF->getName() + "$" +
928 TextSecCOFF->getName().split('$').second)
929 .str();
930 return Context.getCOFFSection(SectionName,
931 MainCFISecCOFF->getCharacteristics() |
934 }
935 }
936
937 return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
938}
939
941 return getWinCFISection(getContext(), &NextWinCFIID,
942 getContext().getObjectFileInfo()->getPDataSection(),
943 TextSec);
944}
945
947 return getWinCFISection(getContext(), &NextWinCFIID,
948 getContext().getObjectFileInfo()->getXDataSection(),
949 TextSec);
950}
951
953
954static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
955 return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
956}
957
960 if (!CurFrame)
961 return;
962
963 MCSymbol *Label = emitCFILabel();
964
966 Label, encodeSEHRegNum(Context, Register));
967 if (CurrentWinEpilog) {
968 if (CurFrame->Version < 3)
969 return getContext().reportError(
970 Loc, ".seh_pushreg inside epilog requires unwind v3");
971 CurrentWinEpilog->Instructions.push_back(Inst);
972 } else {
973 CurFrame->Instructions.push_back(Inst);
974 }
975}
976
978 SMLoc Loc) {
980 if (!CurFrame)
981 return;
982
983 // UOP_Push2 is V3-only - reject for V1/V2.
984 if (CurFrame->Version < 3)
985 return getContext().reportError(
986 Loc, ".seh_push2regs is only supported for unwind v3");
987
988 MCSymbol *Label = emitCFILabel();
989
991 Label, encodeSEHRegNum(Context, Reg1), encodeSEHRegNum(Context, Reg2));
993 CurrentWinEpilog->Instructions.push_back(Inst);
994 else
995 CurFrame->Instructions.push_back(Inst);
996}
997
999 SMLoc Loc) {
1001 if (!CurFrame)
1002 return;
1003 if (!CurrentWinEpilog && CurFrame->LastFrameInst >= 0)
1004 return getContext().reportError(
1005 Loc, "frame register and offset can be set at most once");
1006 if (Offset & 0x0F)
1007 return getContext().reportError(Loc, "offset is not a multiple of 16");
1008 if (Offset > 240)
1009 return getContext().reportError(
1010 Loc, "frame offset must be less than or equal to 240");
1011
1012 MCSymbol *Label = emitCFILabel();
1013
1016 if (CurrentWinEpilog) {
1017 if (CurFrame->Version < 3)
1018 return getContext().reportError(
1019 Loc, ".seh_setframe inside epilog requires unwind v3");
1020 CurrentWinEpilog->Instructions.push_back(Inst);
1021 } else {
1022 CurFrame->LastFrameInst = CurFrame->Instructions.size();
1023 CurFrame->Instructions.push_back(Inst);
1024 }
1025}
1026
1029 if (!CurFrame)
1030 return;
1031 if (Size == 0)
1032 return getContext().reportError(Loc,
1033 "stack allocation size must be non-zero");
1034 if (Size & 7)
1035 return getContext().reportError(
1036 Loc, "stack allocation size is not a multiple of 8");
1037
1038 MCSymbol *Label = emitCFILabel();
1039
1041 if (CurrentWinEpilog) {
1042 if (CurFrame->Version < 3)
1043 return getContext().reportError(
1044 Loc, ".seh_stackalloc inside epilog requires unwind v3");
1045 CurrentWinEpilog->Instructions.push_back(Inst);
1046 } else {
1047 CurFrame->Instructions.push_back(Inst);
1048 }
1049}
1050
1052 SMLoc Loc) {
1054 if (!CurFrame)
1055 return;
1056
1057 if (Offset & 7)
1058 return getContext().reportError(
1059 Loc, "register save offset is not 8 byte aligned");
1060
1061 MCSymbol *Label = emitCFILabel();
1062
1064 Label, encodeSEHRegNum(Context, Register), Offset);
1065 if (CurrentWinEpilog) {
1066 if (CurFrame->Version < 3)
1067 return getContext().reportError(
1068 Loc, ".seh_savereg inside epilog requires unwind v3");
1069 CurrentWinEpilog->Instructions.push_back(Inst);
1070 } else {
1071 CurFrame->Instructions.push_back(Inst);
1072 }
1073}
1074
1076 SMLoc Loc) {
1078 if (!CurFrame)
1079 return;
1080 if (Offset & 0x0F)
1081 return getContext().reportError(Loc, "offset is not a multiple of 16");
1082
1083 MCSymbol *Label = emitCFILabel();
1084
1086 Label, encodeSEHRegNum(Context, Register), Offset);
1087 if (CurrentWinEpilog) {
1088 if (CurFrame->Version < 3)
1089 return getContext().reportError(
1090 Loc, ".seh_savexmm inside epilog requires unwind v3");
1091 CurrentWinEpilog->Instructions.push_back(Inst);
1092 } else {
1093 CurFrame->Instructions.push_back(Inst);
1094 }
1095}
1096
1099 if (!CurFrame)
1100 return;
1101 if (CurrentWinEpilog) {
1102 if (CurFrame->Version < 3)
1103 return getContext().reportError(
1104 Loc, ".seh_pushframe inside epilog requires unwind v3");
1105 MCSymbol *Label = emitCFILabel();
1107 CurrentWinEpilog->Instructions.push_back(Inst);
1108 return;
1109 }
1110 if (!CurFrame->Instructions.empty())
1111 return getContext().reportError(
1112 Loc, "If present, PushMachFrame must be the first UOP");
1113
1114 MCSymbol *Label = emitCFILabel();
1115
1117 CurFrame->Instructions.push_back(Inst);
1118}
1119
1122 if (!CurFrame)
1123 return;
1124
1125 MCSymbol *Label = emitCFILabel();
1126
1127 CurFrame->PrologEnd = Label;
1128}
1129
1132 if (!CurFrame)
1133 return;
1134
1135 MCSymbol *Label = emitCFILabel();
1136
1137 if (!CurFrame->PrologEnd) {
1138 CurFrame->PrologEnd = Label;
1140 Loc, "starting epilogue (.seh_startepilogue) before prologue has ended "
1141 "(.seh_endprologue) in " +
1142 CurFrame->Function->getName());
1143 }
1145 &CurFrame->EpilogMap.insert_or_assign(Label, WinEH::FrameInfo::Epilog())
1146 .first->second;
1147 CurrentWinEpilog->Start = Label;
1148 CurrentWinEpilog->Loc = Loc;
1149}
1150
1153 if (!CurFrame)
1154 return;
1155
1156 if (!CurrentWinEpilog)
1157 return getContext().reportError(Loc, "Stray .seh_endepilogue in " +
1158 CurFrame->Function->getName());
1159
1160 if ((CurFrame->Version == 2) && !CurrentWinEpilog->UnwindV2Start) {
1161 // Set UnwindV2Start to... something... to prevent crashes later.
1162 CurrentWinEpilog->UnwindV2Start = CurrentWinEpilog->Start;
1163 getContext().reportError(Loc, "Missing .seh_unwindv2start in " +
1164 CurFrame->Function->getName());
1165 }
1166
1168 CurrentWinEpilog = nullptr;
1169}
1170
1173 if (!CurFrame)
1174 return;
1175
1176 if (!CurrentWinEpilog)
1177 return getContext().reportError(Loc, "Stray .seh_unwindv2start in " +
1178 CurFrame->Function->getName());
1179
1180 if (CurrentWinEpilog->UnwindV2Start)
1181 return getContext().reportError(Loc, "Duplicate .seh_unwindv2start in " +
1182 CurFrame->Function->getName());
1183
1184 MCSymbol *Label = emitCFILabel();
1185 CurrentWinEpilog->UnwindV2Start = Label;
1186}
1187
1189 bool SupportedVersion = (Version >= 1 && Version <= 3);
1190
1191 // If called outside a proc, set the module-level default.
1192 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
1193 if (!SupportedVersion)
1194 return getContext().reportError(
1195 Loc, "Unsupported version for .seh_unwindversion");
1197 return;
1198 }
1199
1200 // Per-function override (existing behaviour).
1201 WinEH::FrameInfo *CurFrame = CurrentWinFrameInfo;
1202
1203 if (CurFrame->Version != DefaultWinCFIUnwindVersion &&
1205 return getContext().reportError(Loc, "Duplicate .seh_unwindversion in " +
1206 CurFrame->Function->getName());
1207
1208 if (!SupportedVersion)
1209 return getContext().reportError(
1210 Loc, "Unsupported version specified in .seh_unwindversion in " +
1211 CurFrame->Function->getName());
1212
1213 CurFrame->Version = Version;
1214}
1215
1217
1219
1221
1223
1224void MCStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
1225
1227
1229
1230/// EmitRawText - If this file is backed by an assembly streamer, this dumps
1231/// the specified string in the output .s file. This capability is
1232/// indicated by the hasRawTextSupport() predicate.
1234 // This is not llvm_unreachable for the sake of out of tree backend
1235 // developers who may not have assembly streamers and should serve as a
1236 // reminder to not accidentally call EmitRawText in the absence of such.
1237 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
1238 "it (target backend is likely missing an AsmStreamer "
1239 "implementation)");
1240}
1241
1243 SmallString<128> Str;
1244 emitRawTextImpl(T.toStringRef(Str));
1245}
1246
1248
1250
1253 (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
1254 getContext().reportError(EndLoc, "Unfinished frame!");
1255 return;
1256 }
1257
1259 if (TS)
1260 TS->finish();
1261
1262 finishImpl();
1263}
1264
1266 if (Context.getDwarfFormat() != dwarf::DWARF64)
1267 return;
1268 AddComment("DWARF64 Mark");
1270}
1271
1273 assert(Context.getDwarfFormat() == dwarf::DWARF64 ||
1276 AddComment(Comment);
1277 emitIntValue(Length, dwarf::getDwarfOffsetByteSize(Context.getDwarfFormat()));
1278}
1279
1281 const Twine &Comment) {
1283 AddComment(Comment);
1284 MCSymbol *Lo = Context.createTempSymbol(Prefix + "_start");
1285 MCSymbol *Hi = Context.createTempSymbol(Prefix + "_end");
1286
1288 Hi, Lo, dwarf::getDwarfOffsetByteSize(Context.getDwarfFormat()));
1289 // emit the begin symbol after we generate the length field.
1290 emitLabel(Lo);
1291 // Return the Hi symbol to the caller.
1292 return Hi;
1293}
1294
1296 // Set the value of the symbol, as we are at the start of the line table.
1297 emitLabel(StartSym);
1298}
1299
1302 Symbol->setVariableValue(Value);
1303
1305 if (TS)
1306 TS->emitAssignment(Symbol, Value);
1307}
1308
1310 uint64_t Address, const MCInst &Inst,
1311 const MCSubtargetInfo &STI,
1312 raw_ostream &OS) {
1313 InstPrinter.printInst(&Inst, Address, "", STI, OS);
1314}
1315
1317}
1318
1320 switch (Expr.getKind()) {
1321 case MCExpr::Target:
1322 cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
1323 break;
1324
1325 case MCExpr::Constant:
1326 break;
1327
1328 case MCExpr::Binary: {
1329 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
1330 visitUsedExpr(*BE.getLHS());
1331 visitUsedExpr(*BE.getRHS());
1332 break;
1333 }
1334
1335 case MCExpr::SymbolRef:
1336 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
1337 break;
1338
1339 case MCExpr::Unary:
1340 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
1341 break;
1342
1343 case MCExpr::Specifier:
1344 visitUsedExpr(*cast<MCSpecifierExpr>(Expr).getSubExpr());
1345 break;
1346 }
1347}
1348
1350 // Scan for values.
1351 for (unsigned i = Inst.getNumOperands(); i--;)
1352 if (Inst.getOperand(i).isExpr())
1353 visitUsedExpr(*Inst.getOperand(i).getExpr());
1354}
1355
1357 uint64_t Attr, uint64_t Discriminator,
1358 const MCPseudoProbeInlineStack &InlineStack,
1359 MCSymbol *FnSym) {
1360 auto &Context = getContext();
1361
1362 // Create a symbol at in the current section for use in the probe.
1363 MCSymbol *ProbeSym = Context.createTempSymbol();
1364
1365 // Set the value of the symbol to use for the MCPseudoProbe.
1366 emitLabel(ProbeSym);
1367
1368 // Create a (local) probe entry with the symbol.
1369 MCPseudoProbe Probe(ProbeSym, Guid, Index, Type, Attr, Discriminator);
1370
1371 // Add the probe entry to this section's entries.
1372 Context.getMCPseudoProbeTable().getProbeSections().addPseudoProbe(
1373 FnSym, Probe, InlineStack);
1374}
1375
1377 unsigned Size) {
1378 // Get the Hi-Lo expression.
1379 const MCExpr *Diff =
1381 MCSymbolRefExpr::create(Lo, Context), Context);
1382
1383 const MCAsmInfo &MAI = Context.getAsmInfo();
1384 if (!MAI.doesSetDirectiveSuppressReloc()) {
1385 emitValue(Diff, Size);
1386 return;
1387 }
1388
1389 // Otherwise, emit with .set (aka assignment).
1390 MCSymbol *SetLabel = Context.createTempSymbol("set");
1391 emitAssignment(SetLabel, Diff);
1392 emitSymbolValue(SetLabel, Size);
1393}
1394
1396 const MCSymbol *Lo) {
1397 // Get the Hi-Lo expression.
1398 const MCExpr *Diff =
1400 MCSymbolRefExpr::create(Lo, Context), Context);
1401
1402 emitULEB128Value(Diff);
1403}
1404
1407 "emitSubsectionsViaSymbols only supported on Mach-O targets");
1408}
1409void MCStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
1411 llvm_unreachable("this directive only supported on COFF targets");
1412}
1414 llvm_unreachable("this directive only supported on COFF targets");
1415}
1418 StringRef CompilerVersion,
1419 StringRef TimeStamp, StringRef Description) {
1420}
1422 llvm_unreachable("this directive only supported on COFF targets");
1423}
1425 llvm_unreachable("this directive only supported on COFF targets");
1426}
1428 MCSymbol *CsectSym,
1429 Align Alignment) {
1430 llvm_unreachable("this directive only supported on XCOFF targets");
1431}
1432
1434 MCSymbolAttr Linkage,
1435 MCSymbolAttr Visibility) {
1436 llvm_unreachable("emitXCOFFSymbolLinkageWithVisibility is only supported on "
1437 "XCOFF targets");
1438}
1439
1442
1444 llvm_unreachable("emitXCOFFRefDirective is only supported on XCOFF targets");
1445}
1446
1448 const MCSymbol *Trap,
1449 unsigned Lang, unsigned Reason,
1450 unsigned FunctionSize,
1451 bool hasDebug) {
1452 report_fatal_error("emitXCOFFExceptDirective is only supported on "
1453 "XCOFF targets");
1454}
1455
1457 llvm_unreachable("emitXCOFFCInfoSym is only supported on"
1458 "XCOFF targets");
1459}
1460
1463 StringRef Name, bool KeepOriginalSym) {}
1465 Align ByteAlignment) {}
1469 uint64_t Size, Align ByteAlignment) {}
1470
1472 CurFrag = &Sec->getDummyFragment();
1473 auto *Sym = Sec->getBeginSymbol();
1474 if (!Sym || !Sym->isUndefined())
1475 return;
1476 // In Mach-O, DWARF sections use Begin as a temporary label, requiring a label
1477 // definition, unlike section symbols in other file formats.
1478 if (getContext().getObjectFileType() == MCContext::IsMachO)
1479 emitLabel(Sym);
1480 else
1481 Sym->setFragment(CurFrag);
1482}
1483
1489}
1493void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
1494 SMLoc Loc) {}
1496void MCStreamer::emitPrefAlign(Align A, const MCSymbol &End, bool EmitNops,
1497 uint8_t Fill, const MCSubtargetInfo &STI) {}
1499 unsigned MaxBytesToEmit) {}
1501 SMLoc Loc) {}
1503
1505 if (SectionStack.size() <= 1)
1506 return false;
1507 auto I = SectionStack.end();
1508 --I;
1509 MCSectionSubPair OldSec = I->first;
1510 --I;
1511 MCSectionSubPair NewSec = I->first;
1512
1513 if (NewSec.first && OldSec != NewSec)
1514 changeSection(NewSec.first, NewSec.second);
1515 SectionStack.pop_back();
1516 return true;
1517}
1518
1520 assert(Section && "Cannot switch to a null section!");
1521 MCSectionSubPair curSection = SectionStack.back().first;
1522 SectionStack.back().second = curSection;
1523 if (MCSectionSubPair(Section, Subsection) != curSection) {
1524 changeSection(Section, Subsection);
1525 SectionStack.back().first = MCSectionSubPair(Section, Subsection);
1526 assert(!Section->hasEnded() && "Section already ended");
1527 }
1528}
1529
1530bool MCStreamer::switchSection(MCSection *Section, const MCExpr *SubsecExpr) {
1531 int64_t Subsec = 0;
1532 if (SubsecExpr) {
1533 if (!SubsecExpr->evaluateAsAbsolute(Subsec, getAssemblerPtr())) {
1534 getContext().reportError(SubsecExpr->getLoc(),
1535 "cannot evaluate subsection number");
1536 return true;
1537 }
1538 if (!isUInt<31>(Subsec)) {
1539 getContext().reportError(SubsecExpr->getLoc(),
1540 "subsection number " + Twine(Subsec) +
1541 " is not within [0,2147483647]");
1542 return true;
1543 }
1544 }
1545 switchSection(Section, Subsec);
1546 return false;
1547}
1548
1550 SectionStack.back().second = SectionStack.back().first;
1551 SectionStack.back().first = MCSectionSubPair(Section, 0);
1552 changeSection(Section, 0);
1553}
1554
1556 // TODO: keep track of the last subsection so that this symbol appears in the
1557 // correct place.
1558 MCSymbol *Sym = Section->getEndSymbol(Context);
1559 if (Sym->isInSection())
1560 return Sym;
1561
1562 switchSection(Section);
1563 emitLabel(Sym);
1564 return Sym;
1565}
1566
1568 auto *Sec = CurFrag->getParent();
1569 F->setParent(Sec);
1570 F->setLayoutOrder(CurFrag->getLayoutOrder() + 1);
1571 CurFrag->Next = F;
1572 CurFrag = F;
1573 Sec->curFragList()->Tail = F;
1574}
1575
1576static VersionTuple
1578 VersionTuple TargetVersion) {
1579 VersionTuple Min = Target.getMinimumSupportedOSVersion();
1580 return !Min.empty() && Min > TargetVersion ? Min : TargetVersion;
1581}
1582
1583static MCVersionMinType
1585 assert(Target.isOSDarwin() && "expected a darwin OS");
1586 switch (Target.getOS()) {
1587 case Triple::MacOSX:
1588 case Triple::Darwin:
1589 return MCVM_OSXVersionMin;
1590 case Triple::IOS:
1591 assert(!Target.isMacCatalystEnvironment() &&
1592 "mac Catalyst should use LC_BUILD_VERSION");
1593 return MCVM_IOSVersionMin;
1594 case Triple::TvOS:
1595 return MCVM_TvOSVersionMin;
1596 case Triple::WatchOS:
1598 default:
1599 break;
1600 }
1601 llvm_unreachable("unexpected OS type");
1602}
1603
1605 assert(Target.isOSDarwin() && "expected a darwin OS");
1606 switch (Target.getOS()) {
1607 case Triple::MacOSX:
1608 case Triple::Darwin:
1609 return VersionTuple(10, 14);
1610 case Triple::IOS:
1611 // Mac Catalyst always uses the build version load command.
1612 if (Target.isMacCatalystEnvironment())
1613 return VersionTuple();
1614 [[fallthrough]];
1615 case Triple::TvOS:
1616 return VersionTuple(12);
1617 case Triple::WatchOS:
1618 return VersionTuple(5);
1619 case Triple::DriverKit:
1620 case Triple::BridgeOS:
1621 case Triple::XROS:
1622 // DriverKit/BridgeOS/XROS always use the build version load command.
1623 return VersionTuple();
1624 default:
1625 break;
1626 }
1627 llvm_unreachable("unexpected OS type");
1628}
1629
1632 assert(Target.isOSDarwin() && "expected a darwin OS");
1633 switch (Target.getOS()) {
1634 case Triple::MacOSX:
1635 case Triple::Darwin:
1636 return MachO::PLATFORM_MACOS;
1637 case Triple::IOS:
1638 if (Target.isMacCatalystEnvironment())
1639 return MachO::PLATFORM_MACCATALYST;
1640 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
1641 : MachO::PLATFORM_IOS;
1642 case Triple::TvOS:
1643 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
1644 : MachO::PLATFORM_TVOS;
1645 case Triple::WatchOS:
1646 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
1647 : MachO::PLATFORM_WATCHOS;
1648 case Triple::DriverKit:
1649 return MachO::PLATFORM_DRIVERKIT;
1650 case Triple::XROS:
1651 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_XROS_SIMULATOR
1652 : MachO::PLATFORM_XROS;
1653 case Triple::BridgeOS:
1654 return MachO::PLATFORM_BRIDGEOS;
1655 default:
1656 break;
1657 }
1658 llvm_unreachable("unexpected OS type");
1659}
1660
1662 const Triple &Target, const VersionTuple &SDKVersion,
1663 const Triple *DarwinTargetVariantTriple,
1664 const VersionTuple &DarwinTargetVariantSDKVersion) {
1665 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
1666 return;
1667 // Do we even know the version?
1668 if (Target.getOSMajorVersion() == 0)
1669 return;
1670
1672 switch (Target.getOS()) {
1673 case Triple::MacOSX:
1674 case Triple::Darwin:
1675 Target.getMacOSXVersion(Version);
1676 break;
1677 case Triple::IOS:
1678 case Triple::TvOS:
1679 Version = Target.getiOSVersion();
1680 break;
1681 case Triple::WatchOS:
1682 Version = Target.getWatchOSVersion();
1683 break;
1684 case Triple::DriverKit:
1685 Version = Target.getDriverKitVersion();
1686 break;
1687 case Triple::XROS:
1688 case Triple::BridgeOS:
1689 Version = Target.getOSVersion();
1690 break;
1691 default:
1692 llvm_unreachable("unexpected OS type");
1693 }
1694 assert(Version.getMajor() != 0 && "A non-zero major version is expected");
1695 auto LinkedTargetVersion =
1697 auto BuildVersionOSVersion = getMachoBuildVersionSupportedOS(Target);
1698 bool ShouldEmitBuildVersion = false;
1699 if (BuildVersionOSVersion.empty() ||
1700 LinkedTargetVersion >= BuildVersionOSVersion) {
1701 if (Target.isMacCatalystEnvironment() && DarwinTargetVariantTriple &&
1702 DarwinTargetVariantTriple->isMacOSX()) {
1703 emitVersionForTarget(*DarwinTargetVariantTriple,
1704 DarwinTargetVariantSDKVersion,
1705 /*DarwinTargetVariantTriple=*/nullptr,
1706 /*DarwinTargetVariantSDKVersion=*/VersionTuple());
1709 LinkedTargetVersion.getMajor(),
1710 LinkedTargetVersion.getMinor().value_or(0),
1711 LinkedTargetVersion.getSubminor().value_or(0), SDKVersion);
1712 return;
1713 }
1715 LinkedTargetVersion.getMajor(),
1716 LinkedTargetVersion.getMinor().value_or(0),
1717 LinkedTargetVersion.getSubminor().value_or(0), SDKVersion);
1718 ShouldEmitBuildVersion = true;
1719 }
1720
1721 if (const Triple *TVT = DarwinTargetVariantTriple) {
1722 if (Target.isMacOSX() && TVT->isMacCatalystEnvironment()) {
1723 auto TVLinkedTargetVersion =
1724 targetVersionOrMinimumSupportedOSVersion(*TVT, TVT->getiOSVersion());
1727 TVLinkedTargetVersion.getMajor(),
1728 TVLinkedTargetVersion.getMinor().value_or(0),
1729 TVLinkedTargetVersion.getSubminor().value_or(0),
1730 DarwinTargetVariantSDKVersion);
1731 }
1732 }
1733
1734 if (ShouldEmitBuildVersion)
1735 return;
1736
1738 LinkedTargetVersion.getMajor(),
1739 LinkedTargetVersion.getMinor().value_or(0),
1740 LinkedTargetVersion.getSubminor().value_or(0), SDKVersion);
1741}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static LVOptions Options
Definition LVOptions.cpp:25
This file declares the MCLFIRewriter class, an abstract class that encapsulates the rewriting logic f...
static VersionTuple getMachoBuildVersionSupportedOS(const Triple &Target)
static void copyBytesForDefRange(SmallString< 20 > &BytePrefix, codeview::SymbolKind SymKind, const T &DefRangeHeader)
Only call this on endian-specific types like ulittle16_t and little32_t, or structs composed of them.
static MCVersionMinType getMachoVersionMinLoadCommandType(const Triple &Target)
static VersionTuple targetVersionOrMinimumSupportedOSVersion(const Triple &Target, VersionTuple TargetVersion)
static MCSection * getWinCFISection(MCContext &Context, unsigned *NextWinCFIID, MCSection *MainCFISec, const MCSection *TextSec)
static MachO::PlatformType getMachoBuildVersionPlatformType(const Triple &Target)
static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
#define R2(n)
#define T
static constexpr StringLiteral Filename
This file defines the SmallString class.
Class for arbitrary precision integers.
Definition APInt.h:78
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Holds state from .cv_file and .cv_loc directives for later emission.
Definition MCCodeView.h:144
bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename, ArrayRef< uint8_t > ChecksumBytes, uint8_t ChecksumKind)
MCCVFunctionInfo * getCVFunctionInfo(unsigned FuncId)
Retreive the function info if this is a valid function id, or nullptr.
bool recordFunctionId(unsigned FuncId)
Records the function id of a normal function.
bool recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc, unsigned IAFile, unsigned IALine, unsigned IACol)
Records the function id of an inlined call site.
Tagged union holding either a T or a Error.
Definition Error.h:485
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition MCAsmInfo.h:66
const std::vector< MCCFIInstruction > & getInitialFrameState() const
Definition MCAsmInfo.h:700
const char * getData8bitsDirective() const
Definition MCAsmInfo.h:470
bool doesSetDirectiveSuppressReloc() const
Definition MCAsmInfo.h:614
bool usesWindowsCFI() const
Definition MCAsmInfo.h:674
Binary assembler expressions.
Definition MCExpr.h:299
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition MCExpr.h:446
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition MCExpr.h:449
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:428
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
Definition MCDwarf.h:622
static MCCFIInstruction createLLVMVectorOffset(MCSymbol *L, unsigned Register, unsigned RegisterSizeInBits, unsigned MaskRegister, unsigned MaskRegisterSizeInBits, int64_t Offset, SMLoc Loc={})
.cfi_llvm_vector_offset Previous value of Register is saved at Offset from CFA.
Definition MCDwarf.h:768
static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_undefined From now on the previous value of Register can't be restored anymore.
Definition MCDwarf.h:703
static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int64_t Size, SMLoc Loc={})
A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE.
Definition MCDwarf.h:736
static MCCFIInstruction createLLVMVectorRegisters(MCSymbol *L, unsigned Register, ArrayRef< VectorRegisterWithLane > VectorRegisters, SMLoc Loc={})
.cfi_llvm_vector_registers Previous value of Register is saved in lanes of vector registers.
Definition MCDwarf.h:758
static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_restore says that the rule for Register is now the same as it was at the beginning of the functi...
Definition MCDwarf.h:696
static MCCFIInstruction createLLVMDefAspaceCfa(MCSymbol *L, unsigned Register, int64_t Offset, unsigned AddressSpace, SMLoc Loc)
.cfi_llvm_def_aspace_cfa defines the rule for computing the CFA to be the result of evaluating the DW...
Definition MCDwarf.h:647
static MCCFIInstruction createLLVMVectorRegisterMask(MCSymbol *L, unsigned Register, unsigned SpillRegister, unsigned SpillRegisterLaneSizeInBits, unsigned MaskRegister, unsigned MaskRegisterSizeInBits, SMLoc Loc={})
.cfi_llvm_vector_register_mask Previous value of Register is saved in SpillRegister,...
Definition MCDwarf.h:779
static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1, unsigned Register2, SMLoc Loc={})
.cfi_register Previous value of Register1 is saved in register Register2.
Definition MCDwarf.h:672
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
Definition MCDwarf.h:615
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition MCDwarf.h:657
static MCCFIInstruction createValOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_val_offset Previous value of Register is offset Offset from the current CFA register.
Definition MCDwarf.h:799
static MCCFIInstruction createNegateRAStateWithPC(MCSymbol *L, SMLoc Loc={})
.cfi_negate_ra_state_with_pc AArch64 negate RA state with PC.
Definition MCDwarf.h:688
static MCCFIInstruction createNegateRAState(MCSymbol *L, SMLoc Loc={})
.cfi_negate_ra_state AArch64 negate RA state.
Definition MCDwarf.h:683
static MCCFIInstruction createRememberState(MCSymbol *L, SMLoc Loc={})
.cfi_remember_state Save all current rules for all registers.
Definition MCDwarf.h:716
static MCCFIInstruction createLLVMRegisterPair(MCSymbol *L, unsigned Register, unsigned R1, unsigned R1SizeInBits, unsigned R2, unsigned R2SizeInBits, SMLoc Loc={})
.cfi_llvm_register_pair Previous value of Register is saved in R1:R2.
Definition MCDwarf.h:748
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition MCDwarf.h:630
static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals, SMLoc Loc={}, StringRef Comment="")
.cfi_escape Allows the user to add arbitrary bytes to the unwind info.
Definition MCDwarf.h:727
static MCCFIInstruction createWindowSave(MCSymbol *L, SMLoc Loc={})
.cfi_window_save SPARC register window is saved.
Definition MCDwarf.h:678
static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int64_t Adjustment, SMLoc Loc={})
.cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but Offset is a relative value that is added/subt...
Definition MCDwarf.h:638
static MCCFIInstruction createRestoreState(MCSymbol *L, SMLoc Loc={})
.cfi_restore_state Restore the previously saved state.
Definition MCDwarf.h:721
static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_same_value Current value of Register is the same as in the previous frame.
Definition MCDwarf.h:710
static MCCFIInstruction createRelOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_rel_offset Previous value of Register is saved at offset Offset from the current CFA register.
Definition MCDwarf.h:665
static MCCFIInstruction createLabel(MCSymbol *L, MCSymbol *CfiLabel, SMLoc Loc)
Definition MCDwarf.h:741
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
LLVM_ABI Expected< unsigned > getDwarfFile(StringRef Directory, StringRef FileName, unsigned FileNumber, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, unsigned CUID)
Creates an entry in the dwarf file and directory tables.
MCDwarfLineTable & getMCDwarfLineTable(unsigned CUID)
Definition MCContext.h:714
LLVM_ABI CodeViewContext & getCVContext()
void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator)
Saves the information from the currently parsed dwarf .loc directive and sets DwarfLocSeen.
Definition MCContext.h:755
LLVM_ABI void reportError(SMLoc L, const Twine &Msg)
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCDwarfLoc & getCurrentDwarfLoc()
Definition MCContext.h:770
void setMCLineTableRootFile(unsigned CUID, StringRef CompilationDir, StringRef Filename, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source)
Specifies the "root" file and directory of the compilation unit.
Definition MCContext.h:738
Instances of this class represent the line information for the dwarf line table entries.
Definition MCDwarf.h:190
void setLabel(MCSymbol *Label)
Definition MCDwarf.h:431
LLVM_ABI void endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS, SMLoc DefLoc, StringRef Name)
Definition MCDwarf.cpp:289
const MCLineSection & getMCLineSections() const
Definition MCDwarf.h:451
MCSymbol * getLabel() const
Definition MCDwarf.h:427
Instances of this class represent the information from a dwarf .loc directive.
Definition MCDwarf.h:107
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
@ Unary
Unary expressions.
Definition MCExpr.h:44
@ Constant
Constant expressions.
Definition MCExpr.h:42
@ SymbolRef
References to labels and assigned expressions.
Definition MCExpr.h:43
@ Target
Target specific expression.
Definition MCExpr.h:46
@ Specifier
Expression with a relocation specifier.
Definition MCExpr.h:45
@ Binary
Binary expressions.
Definition MCExpr.h:41
ExprKind getKind() const
Definition MCExpr.h:85
SMLoc getLoc() const
Definition MCExpr.h:86
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
virtual void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &OS)=0
Print the specified MCInst to the specified raw_ostream.
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
unsigned getNumOperands() const
Definition MCInst.h:212
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec)
Definition MCDwarf.h:241
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
Instances of this class represent a pseudo probe instance for a pseudo probe table entry,...
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
This represents a section on Windows.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:573
MCFragment & getDummyFragment()
Definition MCSection.h:679
MCSymbol * getBeginSymbol()
Definition MCSection.h:646
Streaming machine code generation interface.
Definition MCStreamer.h:222
virtual void emitCFIGnuArgsSize(int64_t Size, SMLoc Loc={})
virtual void emitNops(int64_t NumBytes, int64_t ControlledNopLength, SMLoc Loc, const MCSubtargetInfo &STI)
MCSymbol * emitLineTableLabel()
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
virtual void emitCFILLVMVectorOffset(int64_t Register, int64_t RegisterSizeInBits, int64_t MaskRegister, int64_t MaskRegisterSizeInBits, int64_t Offset, SMLoc Loc={})
void switchSectionNoPrint(MCSection *Section)
Similar to switchSection, but does not print the section directive.
virtual void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc={})
virtual void emitWinCFIUnwindVersion(uint8_t Version, SMLoc Loc=SMLoc())
virtual void visitUsedSymbol(const MCSymbol &Sym)
void setDefaultWinCFIUnwindVersion(uint8_t V)
Set the default unwind version for new WinCFI frames.
void emitCFIStartProc(bool IsSimple, SMLoc Loc=SMLoc())
virtual bool emitCVFuncIdDirective(unsigned FunctionId)
Introduces a function id for use with .cv_loc.
virtual void finishImpl()
Streamer specific finalization.
virtual void emitCFIBKeyFrame()
virtual void beginCOFFSymbolDef(const MCSymbol *Symbol)
Start emitting COFF symbol definition.
virtual void emitWinCFIPushReg(MCRegister Register, SMLoc Loc=SMLoc())
virtual void emitBinaryData(StringRef Data)
Functionally identical to EmitBytes.
virtual bool popSection()
Restore the current and previous section from the section stack.
virtual MCSymbol * emitCFILabel()
When emitting an object file, create and emit a real label.
std::unique_ptr< MCLFIRewriter > LFIRewriter
Definition MCStreamer.h:299
virtual void emitWindowsUnwindTables()
virtual raw_ostream & getCommentOS()
Return a raw_ostream that comments can be written to.
virtual void emitZerofill(MCSection *Section, MCSymbol *Symbol=nullptr, uint64_t Size=0, Align ByteAlignment=Align(1), SMLoc Loc=SMLoc())
Emit the zerofill section and an optional symbol.
virtual void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except, SMLoc Loc=SMLoc())
virtual void emitCFISections(bool EH, bool Debug, bool SFrame)
MCSection * getAssociatedPDataSection(const MCSection *TextSec)
Get the .pdata section used for the given section.
virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name)
This implements the '.loc_label Name' directive.
bool hasUnfinishedDwarfFrameInfo()
virtual ~MCStreamer()
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitCFINegateRAStateWithPC(SMLoc Loc={})
virtual void emitCFISameValue(int64_t Register, SMLoc Loc={})
virtual void emitSyntaxDirective(StringRef Syntax, StringRef Options)
virtual bool emitCVFileDirective(unsigned FileNo, StringRef Filename, ArrayRef< uint8_t > Checksum, unsigned ChecksumKind)
Associate a filename with a specified logical file number, and also specify that file's checksum info...
virtual void emitCFIReturnColumn(int64_t Register)
virtual void emitCOFFSymbolType(int Type)
Emit the type of the symbol.
virtual void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding)
virtual void emitDwarfUnitLength(uint64_t Length, const Twine &Comment)
Emit a unit length field.
virtual void emitCFIWindowSave(SMLoc Loc={})
virtual void emitCOFFSymbolIndex(MCSymbol const *Symbol)
Emits the symbol table index of a Symbol into the current section.
virtual void emitCFILLVMRegisterPair(int64_t Register, int64_t R1, int64_t R1SizeInBits, int64_t R2, int64_t R2SizeInBits, SMLoc Loc={})
SmallVector< MCDwarfFrameInfo, 0 > DwarfFrameInfos
Definition MCStreamer.h:273
virtual void emitWinCFIUnwindV2Start(SMLoc Loc=SMLoc())
virtual void emitWinCFIEndEpilogue(SMLoc Loc=SMLoc())
virtual void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset)
Emits a COFF image relative relocation.
virtual void endCOFFSymbolDef()
Marks the end of the symbol definition.
virtual void emitWinCFIPushFrame(bool Code, SMLoc Loc=SMLoc())
virtual void emitWinEHHandlerData(SMLoc Loc=SMLoc())
virtual MCAssembler * getAssemblerPtr()
Definition MCStreamer.h:331
virtual void emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi, const MCSymbol *Lo)
Emit the absolute difference between two symbols encoded with ULEB128.
virtual void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility)
Emit a symbol's linkage and visibility with a linkage directive for XCOFF.
virtual void emitCFIUndefined(int64_t Register, SMLoc Loc={})
void setTargetStreamer(MCTargetStreamer *TS)
Definition MCStreamer.h:309
virtual void emitWinCFISaveXMM(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
virtual void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame)
virtual void emitCOFFSecNumber(MCSymbol const *Symbol)
Emits the physical number of the section containing the given symbol as assigned during object writin...
virtual void emitCFINegateRAState(SMLoc Loc={})
virtual void emitCFILsda(const MCSymbol *Sym, unsigned Encoding)
MCContext & getContext() const
Definition MCStreamer.h:326
SMLoc getStartTokLoc() const
Definition MCStreamer.h:314
virtual Expected< unsigned > tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, std::optional< MD5::MD5Result > Checksum=std::nullopt, std::optional< StringRef > Source=std::nullopt, unsigned CUID=0)
Associate a filename with a specified logical file number.
virtual void addExplicitComment(const Twine &T)
Add explicit comment T.
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition MCStreamer.h:397
virtual void emitWinCFIBeginEpilogue(SMLoc Loc=SMLoc())
virtual void initSections(const MCSubtargetInfo &STI)
Create the default sections and set the initial one.
virtual void emitELFSize(MCSymbol *Symbol, const MCExpr *Value)
Emit an ELF .size directive.
virtual void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size, MCSymbol *CsectSym, Align Alignment)
Emits an lcomm directive with XCOFF csect information.
virtual void emitCFIMTETaggedFrame()
virtual void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset)
Emits a COFF section relative relocation.
MCSection * getAssociatedXDataSection(const MCSection *TextSec)
Get the .xdata section used for the given section.
virtual void emitRawComment(const Twine &T, bool TabPrefix=true)
Print T and prefix it with the comment string (normally #) and optionally a tab.
virtual void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc=SMLoc())
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
void emitSymbolValue(const MCSymbol *Sym, unsigned Size, bool IsSectionRelative=false)
Special case of EmitValue that avoids the client having to pass in a MCExpr for MCSymbols.
bool checkCVLocSection(unsigned FuncId, unsigned FileNo, SMLoc Loc)
Returns true if the .cv_loc directive is in the right section.
virtual void emitDwarfLineStartLabel(MCSymbol *StartSym)
Emit the debug line start label.
virtual void emitCFIEscape(StringRef Values, SMLoc Loc={})
virtual void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size)
Emit the absolute difference between two symbols.
virtual void emitXCOFFExceptDirective(const MCSymbol *Symbol, const MCSymbol *Trap, unsigned Lang, unsigned Reason, unsigned FunctionSize, bool hasDebug)
Emit an XCOFF .except directive which adds information about a trap instruction to the object file ex...
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
virtual void emitCOFFSectionIndex(MCSymbol const *Symbol)
Emits a COFF section index.
virtual void emitCFIRememberState(SMLoc Loc)
virtual void reset()
State management.
virtual void emitValueToAlignment(Align Alignment, int64_t Fill=0, uint8_t FillLen=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
virtual void emitCFILabelDirective(SMLoc Loc, StringRef Name)
virtual void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, StringRef FileName, StringRef Comment={})
This implements the DWARF2 '.loc fileno lineno ...' assembler directive.
virtual void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart, const MCSymbol *FnEnd)
This implements the CodeView '.cv_linetable' assembler directive.
virtual void emitCOFFSecOffset(MCSymbol const *Symbol)
Emits the offset of the symbol from the beginning of the section during object writing (i....
MCTargetStreamer * getTargetStreamer()
Definition MCStreamer.h:336
MCStreamer(MCContext &Ctx)
MCFragment * CurFrag
Definition MCStreamer.h:271
virtual void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Definition MCStreamer.h:518
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
unsigned getNumFrameInfos()
virtual void emitWinCFISaveReg(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
virtual void emitWinCFIEndProlog(SMLoc Loc=SMLoc())
virtual void emitWinCFIEndProc(SMLoc Loc=SMLoc())
virtual void emitSubsectionsViaSymbols()
Emit a .subsection_via_symbols directive.
void emitVersionForTarget(const Triple &Target, const VersionTuple &SDKVersion, const Triple *DarwinTargetVariantTriple, const VersionTuple &DarwinTargetVariantSDKVersion)
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0)
Emit nops until the byte alignment ByteAlignment is reached.
virtual void emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame)
virtual void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue)
Set the DescValue for the Symbol.
virtual void emitCFIDefCfaRegister(int64_t Register, SMLoc Loc={})
virtual void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment)
Emit a local common (.lcomm) symbol.
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
virtual void emitCFIRegister(int64_t Register1, int64_t Register2, SMLoc Loc={})
virtual void emitCOFFSafeSEH(MCSymbol const *Symbol)
virtual void emitWinCFIFuncletOrFuncEnd(SMLoc Loc=SMLoc())
This is used on platforms, such as Windows on ARM64, that require function or funclet sizes to be emi...
virtual void emitXCOFFRenameDirective(const MCSymbol *Name, StringRef Rename)
Emit a XCOFF .rename directive which creates a synonym for an illegal or undesirable name.
virtual void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type, uint64_t Attr, uint64_t Discriminator, const MCPseudoProbeInlineStack &InlineStack, MCSymbol *FnSym)
Emit the a pseudo probe into the current section.
void setLFIRewriter(std::unique_ptr< MCLFIRewriter > Rewriter)
virtual void emitCGProfileEntry(const MCSymbolRefExpr *From, const MCSymbolRefExpr *To, uint64_t Count)
virtual void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc={})
unsigned emitULEB128IntValue(uint64_t Value, unsigned PadTo=0)
Special case of EmitULEB128Value that avoids the client having to pass in a MCExpr for constant integ...
virtual void emitWinCFIPush2Regs(MCRegister Reg1, MCRegister Reg2, SMLoc Loc=SMLoc())
virtual void emitULEB128Value(const MCExpr *Value)
ArrayRef< MCDwarfFrameInfo > getDwarfFrameInfos() const
virtual void emitPrefAlign(Align A, const MCSymbol &End, bool EmitNops, uint8_t Fill, const MCSubtargetInfo &STI)
virtual void emitCFILLVMVectorRegisterMask(int64_t Register, int64_t SpillRegister, int64_t SpillRegisterLaneSizeInBits, int64_t MaskRegister, int64_t MaskRegisterSizeInBits, SMLoc Loc={})
virtual void emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc)
virtual void emitValueToOffset(const MCExpr *Offset, unsigned char Value, SMLoc Loc)
Emit some number of copies of Value until the byte offset Offset is reached.
MCSymbol * endSection(MCSection *Section)
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
virtual void emitExplicitComments()
Emit added explicit comments.
WinEH::FrameInfo * EnsureValidWinFrameInfo(SMLoc Loc)
Retrieve the current frame info if one is available and it is not yet closed.
virtual void emitCFIRestoreState(SMLoc Loc)
virtual void emitXCOFFRefDirective(const MCSymbol *Symbol)
Emit a XCOFF .ref directive which creates R_REF type entry in the relocation table for one or more sy...
virtual void emitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol)
virtual void emitCVDefRangeDirective(ArrayRef< std::pair< const MCSymbol *, const MCSymbol * > > Ranges, StringRef FixedSizePortion)
This implements the CodeView '.cv_def_range' assembler directive.
void emitInt32(uint64_t Value)
Definition MCStreamer.h:760
virtual void emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc={})
virtual void emitWinCFISetFrame(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
void maybeEmitDwarf64Mark()
Emit a special value of 0xffffffff if producing 64-bit debugging info.
virtual void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc={})
virtual void emitWinCFISplitChained(SMLoc Loc=SMLoc())
virtual void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, unsigned Column, bool PrologueEnd, bool IsStmt, StringRef FileName, SMLoc Loc)
This implements the CodeView '.cv_loc' assembler directive.
virtual void emitWinCFIAllocStack(unsigned Size, SMLoc Loc=SMLoc())
virtual void emitFileDirective(StringRef Filename)
Switch to a new logical file.
virtual void emitSLEB128Value(const MCExpr *Value)
virtual void emitCFIValOffset(int64_t Register, int64_t Offset, SMLoc Loc={})
virtual void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name, bool KeepOriginalSym)
Emit an ELF .symver directive.
virtual void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata)
Emit a C_INFO symbol with XCOFF embedded metadata to the .info section.
MCSection * getCurrentSectionOnly() const
Definition MCStreamer.h:431
virtual void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Emit the expression Value into the output as a native integer of the given Size bytes.
void emitRawText(const Twine &String)
If this file is backed by a assembly streamer, this dumps the specified string in the output ....
void emitZeros(uint64_t NumBytes)
Emit NumBytes worth of zeros.
void addFragment(MCFragment *F)
unsigned emitSLEB128IntValue(int64_t Value)
Special case of EmitSLEB128Value that avoids the client having to pass in a MCExpr for constant integ...
virtual bool emitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc, unsigned IAFile, unsigned IALine, unsigned IACol, SMLoc Loc)
Introduces an inline call site id for use with .cv_loc.
virtual void emitCFISignalFrame()
virtual void emitCFILLVMVectorRegisters(int64_t Register, ArrayRef< MCCFIInstruction::VectorRegisterWithLane > VRs, SMLoc Loc={})
virtual void emitVersionMin(MCVersionMinType Type, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Specify the Mach-O minimum deployment target version.
Definition MCStreamer.h:508
virtual void emitCOFFSymbolStorageClass(int StorageClass)
Emit the storage class of the symbol.
virtual void emitConditionalAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol, but only if Value is also emitted.
virtual void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, Align ByteAlignment=Align(1))
Emit a thread local bss (.tbss) symbol.
virtual void emitCFIRestore(int64_t Register, SMLoc Loc={})
WinEH::FrameInfo::Epilog * CurrentWinEpilog
Definition MCStreamer.h:269
virtual void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym)
This implements the CodeView '.cv_inline_linetable' assembler directive.
void emitFill(uint64_t NumBytes, uint8_t FillValue)
Emit NumBytes bytes worth of the value specified by FillValue.
virtual void emitRawTextImpl(StringRef String)
EmitRawText - If this file is backed by an assembly streamer, this dumps the specified string in the ...
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
void finish(SMLoc EndLoc=SMLoc())
Finish emission of machine code.
virtual void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol)
Emit an weak reference from Alias to Symbol.
void visitUsedExpr(const MCExpr &Expr)
virtual void emitDwarfFile0Directive(StringRef Directory, StringRef Filename, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, unsigned CUID=0)
Specify the "root" file of the compilation, using the ".file 0" extension.
virtual void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Emit/Specify Mach-O build version command.
Definition MCStreamer.h:514
virtual void changeSection(MCSection *, uint32_t)
This is called by popSection and switchSection, if the current section changes.
virtual void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset, int64_t AddressSpace, SMLoc Loc={})
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
Definition MCExpr.h:190
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
Definition MCSymbol.h:237
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
Target specific streamer interface.
Definition MCStreamer.h:95
virtual void emitDwarfFileDirective(StringRef Directive)
virtual void emitValue(const MCExpr *Value)
virtual void prettyPrintAsm(MCInstPrinter &InstPrinter, uint64_t Address, const MCInst &Inst, const MCSubtargetInfo &STI, raw_ostream &OS)
virtual void finish()
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
virtual void emitRawBytes(StringRef Data)
Emit the bytes in Data into the output.
MCStreamer & Streamer
Definition MCStreamer.h:97
MCTargetStreamer(MCStreamer &S)
virtual void changeSection(const MCSection *CurSection, MCSection *Section, uint32_t SubSection, raw_ostream &OS)
Update streamer for a new active section.
virtual void emitLabel(MCSymbol *Symbol)
virtual void emitConstantPools()
Root of the metadata hierarchy.
Definition Metadata.h:64
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Represents a location in source code.
Definition SMLoc.h:22
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
StringRef str() const
Explicit conversion to StringRef.
void resize(size_type N)
pointer data()
Return a pointer to the vector's buffer, even if empty().
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
bool isMacOSX() const
Is this a Mac OS X triple.
Definition Triple.h:603
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM Value Representation.
Definition Value.h:75
Represents a version number in the form major[.minor[.subminor[.build]]].
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero).
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an SmallVector or SmallString.
StringRef str() const
Return a StringRef for the vector contents.
This class represents a function that is read from a sample profile.
Definition FunctionId.h:36
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ IMAGE_SCN_LNK_COMDAT
Definition COFF.h:309
@ IMAGE_COMDAT_SELECT_ANY
Definition COFF.h:456
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
detail::packed_endian_specific_integral< uint16_t, llvm::endianness::little, unaligned > ulittle16_t
Definition Endian.h:287
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
Definition CodeView.h:48
@ DWARF64
Definition Dwarf.h:93
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
Definition Dwarf.h:1109
@ DW_LENGTH_lo_reserved
Special values for an initial length field.
Definition Dwarf.h:56
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition Dwarf.h:57
value_type byte_swap(value_type value, endianness endian)
Definition Endian.h:44
detail::packed_endian_specific_integral< uint16_t, llvm::endianness::little, unaligned > ulittle16_t
Definition Endian.h:287
constexpr bool IsLittleEndianHost
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:558
@ Length
Definition DWP.cpp:558
LLVM_ABI void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, unsigned StoreBytes)
Fills the StoreBytes bytes of memory starting from Dst with the integer held in IntVal.
Definition APInt.cpp:3103
@ Debug
Register 'use' is for debugging purpose.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:243
FunctionAddr VTableAddr uintptr_t uintptr_t Version
Definition InstrProf.h:334
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
SmallVector< InlineSite, 8 > MCPseudoProbeInlineStack
MCVersionMinType
@ MCVM_WatchOSVersionMin
.watchos_version_min
@ MCVM_OSXVersionMin
.macosx_version_min
@ MCVM_TvOSVersionMin
.tvos_version_min
@ MCVM_IOSVersionMin
.ios_version_min
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:189
LLVM_ABI raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:221
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
Definition LEB128.h:24
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition MathExtras.h:248
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition LEB128.h:79
std::pair< MCSection *, uint32_t > MCSectionSubPair
Definition MCStreamer.h:68
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Information describing a function or inlined call site introduced by .cv_func_id or ....
Definition MCCodeView.h:98
MCSection * Section
The section of the first .cv_loc directive used for this function, or null if none has been seen yet.
Definition MCCodeView.h:118
const MCSymbol * Personality
Definition MCDwarf.h:860
unsigned PersonalityEncoding
Definition MCDwarf.h:864
std::vector< MCCFIInstruction > Instructions
Definition MCDwarf.h:862
const MCSymbol * Lsda
Definition MCDwarf.h:861
unsigned CurrentCfaRegister
Definition MCDwarf.h:863
static WinEH::Instruction SaveXMM(MCSymbol *L, unsigned Reg, unsigned Offset)
Definition MCWin64EH.h:45
static WinEH::Instruction PushNonVol(MCSymbol *L, unsigned Reg)
Definition MCWin64EH.h:26
static WinEH::Instruction PushMachFrame(MCSymbol *L, bool Code)
Definition MCWin64EH.h:36
static WinEH::Instruction SaveNonVol(MCSymbol *L, unsigned Reg, unsigned Offset)
Definition MCWin64EH.h:39
static WinEH::Instruction Alloc(MCSymbol *L, unsigned Size)
Definition MCWin64EH.h:32
static WinEH::Instruction SetFPReg(MCSymbol *L, unsigned Reg, unsigned Off)
Definition MCWin64EH.h:51
static WinEH::Instruction Push2(MCSymbol *L, unsigned Reg1, unsigned Reg2)
Definition MCWin64EH.h:29
std::vector< Instruction > Instructions
Definition MCWinEH.h:68
const MCSymbol * Function
Definition MCWinEH.h:51
MCSection * TextSection
Definition MCWinEH.h:55
FrameInfo * ChainedParent
Definition MCWinEH.h:67
const MCSymbol * PrologEnd
Definition MCWinEH.h:53
MapVector< MCSymbol *, Epilog > EpilogMap
Definition MCWinEH.h:77
const MCSymbol * FuncletOrFuncEnd
Definition MCWinEH.h:49
const MCSymbol * End
Definition MCWinEH.h:48
static constexpr uint8_t DefaultVersion
Definition MCWinEH.h:63
const MCSymbol * ExceptionHandler
Definition MCWinEH.h:50