LLVM: lib/CodeGen/AsmPrinter/WinException.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
33using namespace llvm;
34
36
37
38 useImageRel32 = (A->getDataLayout().getPointerSizeInBits() == 64);
39 isAArch64 = Asm->TM.getTargetTriple().isAArch64();
40 isThumb = Asm->TM.getTargetTriple().isThumb();
41}
42
44
45
46
48 auto &OS = *Asm->OutStreamer;
49 const Module *M = MMI->getModule();
51 if (F.hasFnAttribute("safeseh"))
52 OS.emitCOFFSafeSEH(Asm->getSymbol(&F));
53
54 if (M->getModuleFlag("ehcontguard") && !EHContTargets.empty()) {
55
56 OS.switchSection(Asm->OutContext.getObjectFileInfo()->getGEHContSection());
57 for (const MCSymbol *S : EHContTargets) {
58 OS.emitCOFFSymbolIndex(S);
59 }
60 }
61}
62
64 shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
65
66
69
71
72 shouldEmitMoves = Asm->needsSEHMoves() && MF->hasWinCFI();
73
76
78 const Function *PerFn = nullptr;
79 if (F.hasPersonalityFn()) {
82 }
83
84 bool forceEmitPersonality = F.hasPersonalityFn() &&
86 F.needsUnwindTableEntry();
87
88 shouldEmitPersonality =
89 forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
91
93 shouldEmitLSDA = shouldEmitPersonality &&
95
96
97
98 if (->MAI->usesWindowsCFI()) {
100
101
102
106 emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
107 }
108 shouldEmitLSDA = hasEHFunclets;
109 shouldEmitPersonality = false;
110 return;
111 }
112
114}
115
117 if (isAArch64 && CurrentFuncletEntry &&
118 (shouldEmitMoves || shouldEmitPersonality))
119 Asm->OutStreamer->emitWinCFIFuncletOrFuncEnd();
120}
121
122
123
125 if (!shouldEmitPersonality && !shouldEmitMoves && !shouldEmitLSDA)
126 return;
127
130 if (F.hasPersonalityFn())
132
133 endFuncletImpl();
134
135
137 return;
138
139 if (shouldEmitPersonality || shouldEmitLSDA) {
140 Asm->OutStreamer->pushSection();
141
142
143 MCSection *XData = Asm->OutStreamer->getAssociatedXDataSection(
144 Asm->OutStreamer->getCurrentSectionOnly());
145 Asm->OutStreamer->switchSection(XData);
146
147
148
150 emitCSpecificHandlerTable(MF);
152 emitExceptHandlerTable(MF);
154 emitCXXFrameHandler3Table(MF);
156 emitCLRExceptionTable(MF);
157 else
159
160 Asm->OutStreamer->popSection();
161 }
162
164
166 }
167}
168
169
172 if ()
173 return nullptr;
174
176
177
178
183 StringRef HandlerPrefix = MBB->isCleanupFuncletEntry() ? "dtor" : "catch";
184 return Ctx.getOrCreateSymbol("?" + HandlerPrefix + "$" +
185 Twine(MBB->getNumber()) + "@?0?" +
186 FuncLinkageName + "@4HA");
187}
188
191 CurrentFuncletEntry = &MBB;
192
194
195 if (!Sym) {
197
198
199 Asm->OutStreamer->beginCOFFSymbolDef(Sym);
203 Asm->OutStreamer->endCOFFSymbolDef();
204
205
206
207 Asm->emitAlignment(std::max(Asm->MF->getAlignment(), MBB.getAlignment()),
208 &F);
209
210
211 Asm->OutStreamer->emitLabel(Sym);
212 }
213
214
215 if (shouldEmitMoves || shouldEmitPersonality) {
216 CurrentFuncletTextSection = Asm->OutStreamer->getCurrentSectionOnly();
217 Asm->OutStreamer->emitWinCFIStartProc(Sym);
218 }
219
220 if (shouldEmitPersonality) {
222 const Function *PerFn = nullptr;
223
224
225 if (F.hasPersonalityFn())
227 const MCSymbol *PersHandlerSym =
229
230
231
232
233
234
235 if (!CurrentFuncletEntry->isCleanupFuncletEntry())
236 Asm->OutStreamer->emitWinEHHandler(PersHandlerSym, true, true);
237 }
238}
239
241 if (isAArch64 && CurrentFuncletEntry &&
242 (shouldEmitMoves || shouldEmitPersonality)) {
243 Asm->OutStreamer->switchSection(CurrentFuncletTextSection);
244 Asm->OutStreamer->emitWinCFIFuncletOrFuncEnd();
245 }
246 endFuncletImpl();
247}
248
249void WinException::endFuncletImpl() {
250
251 if (!CurrentFuncletEntry)
252 return;
253
255 if (shouldEmitMoves || shouldEmitPersonality) {
258 if (F.hasPersonalityFn())
260
263
265
266
267
270 Twine("$cppxdata$", FuncLinkageName));
271 Asm->OutStreamer->emitValue(create32bitRef(FuncInfoXData), 4);
274
276
277
278
279 emitCSpecificHandlerTable(MF);
280 } else if (shouldEmitPersonality || shouldEmitLSDA) {
281
282 Asm->OutStreamer->emitWinEHHandlerData();
283
284
285
286 } else {
287
288
289
290 }
291
293
295 }
296
297
298
299
300 Asm->OutStreamer->switchSection(CurrentFuncletTextSection);
301 Asm->OutStreamer->emitWinCFIEndProc();
302 }
303
304
305 CurrentFuncletEntry = nullptr;
306}
307
313}
314
315const MCExpr *WinException::create32bitRef(const GlobalValue *GV) {
316 if (!GV)
318 return create32bitRef(Asm->getSymbol(GV));
319}
320
321const MCExpr *WinException::getLabel(const MCSymbol *Label) {
323 Asm->OutContext);
324}
325
326const MCExpr *WinException::getOffset(const MCSymbol *OffsetOf,
327 const MCSymbol *OffsetFrom) {
331}
332
333const MCExpr *WinException::getOffsetPlusOne(const MCSymbol *OffsetOf,
334 const MCSymbol *OffsetFrom) {
337 Asm->OutContext);
338}
339
340int WinException::getFrameIndexOffset(int FrameIndex,
342 const TargetFrameLowering &TFI = *Asm->MF->getSubtarget().getFrameLowering();
344 if (Asm->MAI->usesWindowsCFI()) {
347 true);
349 Asm->MF->getSubtarget()
350 .getTargetLowering()
351 ->getStackPointerRegisterToSaveRestore());
352 return Offset.getFixed();
353 }
354
355
356
361 "Frame offsets with a scalable component are not supported");
362 return Offset.getFixed();
363}
364
365namespace {
366
367
368const int NullState = -1;
369
370struct InvokeStateChange {
371
372
373 const MCSymbol *PreviousEndLabel;
374
375
376
377 const MCSymbol *NewStartLabel;
378
379
380
381 int NewState;
382};
383
384
385
386
387
388
389
390
391
392class InvokeStateChangeIterator {
393 InvokeStateChangeIterator(const WinEHFuncInfo &EHInfo,
397 int BaseState)
398 : EHInfo(EHInfo), MFI(MFI), MFE(MFE), MBBI(MBBI), BaseState(BaseState) {
399 LastStateChange.PreviousEndLabel = nullptr;
400 LastStateChange.NewStartLabel = nullptr;
401 LastStateChange.NewState = BaseState;
402 scan();
403 }
404
405public:
409
410
411 assert(Begin != End);
412 auto BlockBegin = Begin->begin();
413 auto BlockEnd = std::prev(End)->end();
415 InvokeStateChangeIterator(EHInfo, Begin, End, BlockBegin, BaseState),
416 InvokeStateChangeIterator(EHInfo, End, End, BlockEnd, BaseState));
417 }
418
419
420 bool operator==(const InvokeStateChangeIterator &O) const {
421 assert(BaseState == O.BaseState);
422
423 if (MFI != O.MFI)
424 return false;
425
427 return false;
428
429
430
431
432 return CurrentEndLabel == O.CurrentEndLabel;
433 }
434
435 bool operator!=(const InvokeStateChangeIterator &O) const {
437 }
438 InvokeStateChange &operator*() { return LastStateChange; }
439 InvokeStateChange *operator->() { return &LastStateChange; }
440 InvokeStateChangeIterator &operator++() { return scan(); }
441
442private:
443 InvokeStateChangeIterator &scan();
444
445 const WinEHFuncInfo &EHInfo;
446 const MCSymbol *CurrentEndLabel = nullptr;
450 InvokeStateChange LastStateChange;
451 bool VisitingInvoke = false;
452 int BaseState;
453};
454
455}
456
457InvokeStateChangeIterator &InvokeStateChangeIterator::scan() {
458 bool IsNewBlock = false;
459 for (; MFI != MFE; ++MFI, IsNewBlock = true) {
460 if (IsNewBlock)
462 for (auto MBBE = MFI->end(); MBBI != MBBE; ++MBBI) {
464 if (!VisitingInvoke && LastStateChange.NewState != BaseState &&
466
467
468
469 LastStateChange.PreviousEndLabel = CurrentEndLabel;
470 LastStateChange.NewStartLabel = nullptr;
471 LastStateChange.NewState = BaseState;
472 CurrentEndLabel = nullptr;
473
475 return *this;
476 }
477
478
479 if (.isEHLabel())
480 continue;
482 if (Label == CurrentEndLabel) {
483 VisitingInvoke = false;
484 continue;
485 }
487
489 continue;
490 auto &StateAndEnd = InvokeMapIter->second;
491 int NewState = StateAndEnd.first;
492
493
494 VisitingInvoke = true;
495 if (NewState == LastStateChange.NewState) {
496
497
498 CurrentEndLabel = StateAndEnd.second;
499 continue;
500 }
501
502 LastStateChange.PreviousEndLabel = CurrentEndLabel;
503 LastStateChange.NewStartLabel = Label;
504 LastStateChange.NewState = NewState;
505
506 CurrentEndLabel = StateAndEnd.second;
507
509 return *this;
510 }
511 }
512
513 if (LastStateChange.NewState != BaseState) {
514
515 LastStateChange.PreviousEndLabel = CurrentEndLabel;
516 LastStateChange.NewStartLabel = nullptr;
517 LastStateChange.NewState = BaseState;
518
519 assert(CurrentEndLabel != nullptr);
520 return *this;
521 }
522
523 CurrentEndLabel = nullptr;
524 return *this;
525}
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
556 auto &OS = *Asm->OutStreamer;
557 MCContext &Ctx = Asm->OutContext;
559
560 bool VerboseAsm = OS.isVerboseAsm();
561 auto AddComment = [&](const Twine &Comment) {
562 if (VerboseAsm)
563 OS.AddComment(Comment);
564 };
565
566 if (!isAArch64) {
567
568
569 StringRef FLinkageName =
571 MCSymbol *ParentFrameOffset =
573 const MCExpr *MCOffset =
575 Asm->OutStreamer->emitAssignment(ParentFrameOffset, MCOffset);
576 }
577
578
579
581 Ctx.createTempSymbol("lsda_begin", true);
584 const MCExpr *LabelDiff = getOffset(TableEnd, TableBegin);
587 AddComment("Number of call sites");
588 OS.emitValue(EntryCount, 4);
589
590 OS.emitLabel(TableBegin);
591
592
593
594
595
596
597
598
599 const MCSymbol *LastStartLabel = nullptr;
600 int LastEHState = -1;
601
602
605 while (Stop != End && !Stop->isEHFuncletEntry())
606 ++Stop;
607 for (const auto &StateChange :
608 InvokeStateChangeIterator::range(FuncInfo, MF->begin(), Stop)) {
609
610
611 if (LastEHState != -1)
612 emitSEHActionsForRange(FuncInfo, LastStartLabel,
613 StateChange.PreviousEndLabel, LastEHState);
614 LastStartLabel = StateChange.NewStartLabel;
615 LastEHState = StateChange.NewState;
616 }
617
618 OS.emitLabel(TableEnd);
619}
620
621void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
623 const MCSymbol *EndLabel, int State) {
624 auto &OS = *Asm->OutStreamer;
625 MCContext &Ctx = Asm->OutContext;
626 bool VerboseAsm = OS.isVerboseAsm();
627 auto AddComment = [&](const Twine &Comment) {
628 if (VerboseAsm)
629 OS.AddComment(Comment);
630 };
631
632 assert(BeginLabel && EndLabel);
633 while (State != -1) {
634 const SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
635 const MCExpr *FilterOrFinally;
636 const MCExpr *ExceptOrNull;
641 } else {
642
643
644 FilterOrFinally = UME.Filter ? create32bitRef(UME.Filter)
645 : MCConstantExpr::create(1, Ctx);
646 ExceptOrNull = create32bitRef(Handler->getSymbol());
647 }
648
649 AddComment("LabelStart");
650 OS.emitValue(getLabel(BeginLabel), 4);
651 AddComment("LabelEnd");
652 OS.emitValue(getLabel(EndLabel), 4);
653 AddComment(UME.IsFinally ? "FinallyFunclet" : UME.Filter ? "FilterFunction"
654 : "CatchAll");
655 OS.emitValue(FilterOrFinally, 4);
656 AddComment(UME.IsFinally ? "Null" : "ExceptionHandler");
657 OS.emitValue(ExceptOrNull, 4);
658
659 assert(UME.ToState < State && "states should decrease");
661 }
662}
663
664void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
666 auto &OS = *Asm->OutStreamer;
668
670
672 MCSymbol *FuncInfoXData = nullptr;
673 if (shouldEmitPersonality) {
674
675
676 FuncInfoXData =
677 Asm->OutContext.getOrCreateSymbol(Twine("$cppxdata$", FuncLinkageName));
678 computeIP2StateTable(MF, FuncInfo, IPToStateTable);
679 } else {
680 FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(FuncLinkageName);
681 }
682
683 int UnwindHelpOffset = 0;
684
685
686
687
688 if (Asm->MAI->usesWindowsCFI() &&
690 UnwindHelpOffset =
692
693 MCSymbol *UnwindMapXData = nullptr;
694 MCSymbol *TryBlockMapXData = nullptr;
695 MCSymbol *IPToStateXData = nullptr;
697 UnwindMapXData = Asm->OutContext.getOrCreateSymbol(
698 Twine("$stateUnwindMap$", FuncLinkageName));
700 TryBlockMapXData =
701 Asm->OutContext.getOrCreateSymbol(Twine("$tryMap$", FuncLinkageName));
702 if (!IPToStateTable.empty())
703 IPToStateXData =
704 Asm->OutContext.getOrCreateSymbol(Twine("$ip2state$", FuncLinkageName));
705
706 bool VerboseAsm = OS.isVerboseAsm();
707 auto AddComment = [&](const Twine &Comment) {
708 if (VerboseAsm)
709 OS.AddComment(Comment);
710 };
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727 OS.emitValueToAlignment(Align(4));
728 OS.emitLabel(FuncInfoXData);
729
730 AddComment("MagicNumber");
731 OS.emitInt32(0x19930522);
732
733 AddComment("MaxState");
735
736 AddComment("UnwindMap");
737 OS.emitValue(create32bitRef(UnwindMapXData), 4);
738
739 AddComment("NumTryBlocks");
740 OS.emitInt32(FuncInfo.TryBlockMap.size());
741
742 AddComment("TryBlockMap");
743 OS.emitValue(create32bitRef(TryBlockMapXData), 4);
744
745 AddComment("IPMapEntries");
746 OS.emitInt32(IPToStateTable.size());
747
748 AddComment("IPToStateXData");
749 OS.emitValue(create32bitRef(IPToStateXData), 4);
750
751 if (Asm->MAI->usesWindowsCFI() &&
753 AddComment("UnwindHelp");
754 OS.emitInt32(UnwindHelpOffset);
755 }
756
757 AddComment("ESTypeList");
758 OS.emitInt32(0);
759
760 AddComment("EHFlags");
761 if (MMI->getModule()->getModuleFlag("eh-asynch")) {
762 OS.emitInt32(0);
763 } else {
764 OS.emitInt32(1);
765 }
766
767
768
769
770
771 if (UnwindMapXData) {
772 OS.emitLabel(UnwindMapXData);
773 for (const CxxUnwindMapEntry &UME : FuncInfo.CxxUnwindMap) {
776 AddComment("ToState");
777 OS.emitInt32(UME.ToState);
778
779 AddComment("Action");
780 OS.emitValue(create32bitRef(CleanupSym), 4);
781 }
782 }
783
784
785
786
787
788
789
790
791 if (TryBlockMapXData) {
792 OS.emitLabel(TryBlockMapXData);
794 for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
795 const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
796
797 MCSymbol *HandlerMapXData = nullptr;
799 HandlerMapXData =
800 Asm->OutContext.getOrCreateSymbol(Twine("$handlerMap$")
803 .concat(FuncLinkageName));
804 HandlerMaps.push_back(HandlerMapXData);
805
806
807 assert(0 <= TBME.TryLow && "bad trymap interval");
811 "bad trymap interval");
812
813 AddComment("TryLow");
814 OS.emitInt32(TBME.TryLow);
815
816 AddComment("TryHigh");
817 OS.emitInt32(TBME.TryHigh);
818
819 AddComment("CatchHigh");
821
822 AddComment("NumCatches");
824
825 AddComment("HandlerArray");
826 OS.emitValue(create32bitRef(HandlerMapXData), 4);
827 }
828
829
830 unsigned ParentFrameOffset = 0;
831 if (shouldEmitPersonality) {
834 }
835
836 for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
837 const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
838 MCSymbol *HandlerMapXData = HandlerMaps[I];
839 if (!HandlerMapXData)
840 continue;
841
842
843
844
845
846
847
848 OS.emitLabel(HandlerMapXData);
849 for (const WinEHHandlerType &HT : TBME.HandlerArray) {
850
851
852
853 const MCExpr *FrameAllocOffsetRef = nullptr;
856 assert(Offset != 0 && "Illegal offset for catch object!");
858 } else {
860 }
861
864
865 AddComment("Adjectives");
867
868 AddComment("Type");
870
871 AddComment("CatchObjOffset");
872 OS.emitValue(FrameAllocOffsetRef, 4);
873
874 AddComment("Handler");
875 OS.emitValue(create32bitRef(HandlerSym), 4);
876
877 if (shouldEmitPersonality) {
878 AddComment("ParentFrameOffset");
879 OS.emitInt32(ParentFrameOffset);
880 }
881 }
882 }
883 }
884
885
886
887
888
889 if (IPToStateXData) {
890 OS.emitLabel(IPToStateXData);
891 for (auto &IPStatePair : IPToStateTable) {
892 AddComment("IP");
893 OS.emitValue(IPStatePair.first, 4);
894 AddComment("ToState");
895 OS.emitInt32(IPStatePair.second);
896 }
897 }
898}
899
900void WinException::computeIP2StateTable(
902 SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable) {
903
905 FuncletEnd = MF->begin(),
906 End = MF->end();
907 FuncletStart != End; FuncletStart = FuncletEnd) {
908
909 while (++FuncletEnd != End) {
910 if (FuncletEnd->isEHFuncletEntry()) {
911 break;
912 }
913 }
914
915
916
917
918 if (FuncletStart->isCleanupFuncletEntry())
919 continue;
920
922 int BaseState;
923 if (FuncletStart == MF->begin()) {
924 BaseState = NullState;
925 StartLabel = Asm->getFunctionBegin();
926 } else {
928 FuncletStart->getBasicBlock()->getFirstNonPHIIt());
932 }
933 assert(StartLabel && "need local function start label");
934 IPToStateTable.push_back(
935 std::make_pair(create32bitRef(StartLabel), BaseState));
936
937 for (const auto &StateChange : InvokeStateChangeIterator::range(
938 FuncInfo, FuncletStart, FuncletEnd, BaseState)) {
939
940
941
942
943 const MCSymbol *ChangeLabel = StateChange.NewStartLabel;
944 if (!ChangeLabel)
945 ChangeLabel = StateChange.PreviousEndLabel;
946
947 const MCExpr *LabelExpression = getLabel(ChangeLabel);
948 IPToStateTable.push_back(
949 std::make_pair(LabelExpression, StateChange.NewState));
950
951 }
952 }
953}
954
955void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
957
958
959
960
961
962
963
964
965
968 if (FI != INT_MAX) {
969 const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
971 }
972
973 MCContext &Ctx = Asm->OutContext;
974 MCSymbol *ParentFrameOffset =
976 Asm->OutStreamer->emitAssignment(ParentFrameOffset,
978}
979
980
981
982
983void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
984 MCStreamer &OS = *Asm->OutStreamer;
987
989 auto AddComment = [&](const Twine &Comment) {
990 if (VerboseAsm)
992 };
993
995 emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
996
997
998 MCSymbol *LSDALabel = Asm->OutContext.getOrCreateLSDASymbol(FLinkageName);
1001
1002 const auto *Per = cast(F.getPersonalityFn()->stripPointerCasts());
1003 StringRef PerName = Per->getName();
1004 int BaseState = -1;
1005 if (PerName == "_except_handler4") {
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028 int GSCookieOffset = -2;
1029 const MachineFrameInfo &MFI = MF->getFrameInfo();
1034 GSCookieOffset =
1036 }
1037
1038
1039
1040 int EHCookieOffset = 9999;
1045 EHCookieOffset =
1047 }
1048
1049 AddComment("GSCookieOffset");
1051 AddComment("GSCookieXOROffset");
1053 AddComment("EHCookieOffset");
1055 AddComment("EHCookieXOROffset");
1057 BaseState = -2;
1058 }
1059
1061 for (const SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {
1063 const MCSymbol *ExceptOrFinally =
1065
1066
1067 int ToState = UME.ToState == -1 ? BaseState : UME.ToState;
1068 AddComment("ToState");
1070 AddComment(UME.IsFinally ? "Null" : "FilterFunction");
1072 AddComment(UME.IsFinally ? "FinallyFunclet" : "ExceptionHandler");
1073 OS.emitValue(create32bitRef(ExceptOrFinally), 4);
1074 }
1075}
1076
1078 int Rank = 0;
1079 while (State != -1) {
1080 ++Rank;
1081 State = FuncInfo.ClrEHUnwindMap[State].TryParentState;
1082 }
1083 return Rank;
1084}
1085
1089
1090 while (LeftRank < RightRank) {
1092 --RightRank;
1093 }
1094
1095 while (RightRank < LeftRank) {
1097 --LeftRank;
1098 }
1099
1103 }
1104
1105 return Left;
1106}
1107
1108void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
1109
1110
1111
1112 MCStreamer &OS = *Asm->OutStreamer;
1114 MCSymbol *FuncBeginSym = Asm->getFunctionBegin();
1115 MCSymbol *FuncEndSym = Asm->getFunctionEnd();
1116
1117
1118 struct ClrClause {
1119 const MCSymbol *StartLabel;
1120 const MCSymbol *EndLabel;
1121 int State;
1122 int EnclosingState;
1123 };
1125
1126
1127
1129 assert(NumStates > 0 && "Don't need exception table!");
1130 DenseMap<const MachineBasicBlock *, int> HandlerStates;
1131 for (int State = 0; State < NumStates; ++State) {
1132 MachineBasicBlock *HandlerBlock =
1134 HandlerStates[HandlerBlock] = State;
1135
1136
1137
1139 "ill-formed state numbering");
1140 }
1141
1142 HandlerStates[&MF->front()] = NullState;
1143
1144
1145
1147
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1166
1167 std::unique_ptr<MCSymbol *[]> EndSymbolMap(new MCSymbol *[NumStates]);
1168 SmallVector<int, 4> MinClauseMap((size_t)NumStates, NumStates);
1169
1170
1172 FuncletEnd = MF->begin(),
1173 End = MF->end();
1174 FuncletStart != End; FuncletStart = FuncletEnd) {
1175 int FuncletState = HandlerStates[&*FuncletStart];
1176
1177 MCSymbol *EndSymbol = FuncEndSym;
1178 while (++FuncletEnd != End) {
1179 if (FuncletEnd->isEHFuncletEntry()) {
1181 break;
1182 }
1183 }
1184
1185
1186 OS.emitValue(getOffset(EndSymbol, FuncBeginSym), 4);
1187 if (FuncletState != NullState) {
1188
1189 EndSymbolMap[FuncletState] = EndSymbol;
1190 }
1191
1192
1193
1194 const MCSymbol *CurrentStartLabel = nullptr;
1195 int CurrentState = NullState;
1197 for (const auto &StateChange :
1198 InvokeStateChangeIterator::range(FuncInfo, FuncletStart, FuncletEnd)) {
1199
1200 int StillPendingState =
1201 getTryAncestor(FuncInfo, CurrentState, StateChange.NewState);
1202 while (CurrentState != StillPendingState) {
1203 assert(CurrentState != NullState &&
1204 "Failed to find still-pending state!");
1205
1206 Clauses.push_back({CurrentStartLabel, StateChange.PreviousEndLabel,
1207 CurrentState, FuncletState});
1208
1209 CurrentState = FuncInfo.ClrEHUnwindMap[CurrentState].TryParentState;
1210
1211
1212 if (HandlerStack.back().second == CurrentState)
1213 CurrentStartLabel = HandlerStack.pop_back_val().first;
1214 }
1215
1216 if (StateChange.NewState != CurrentState) {
1217
1218
1219
1220 for (int EnteredState = StateChange.NewState;
1221 EnteredState != CurrentState;
1222 EnteredState =
1223 FuncInfo.ClrEHUnwindMap[EnteredState].TryParentState) {
1224 int &MinEnclosingState = MinClauseMap[EnteredState];
1225 if (FuncletState < MinEnclosingState)
1226 MinEnclosingState = FuncletState;
1227 }
1228
1229
1230 HandlerStack.emplace_back(CurrentStartLabel, CurrentState);
1231 CurrentStartLabel = StateChange.NewStartLabel;
1232 CurrentState = StateChange.NewState;
1233 }
1234 }
1236 }
1237
1238
1240 for (ClrClause &Clause : Clauses) {
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289 const MCExpr *ClauseBegin =
1290 getOffsetPlusOne(Clause.StartLabel, FuncBeginSym);
1291 const MCExpr *ClauseEnd = getOffsetPlusOne(Clause.EndLabel, FuncBeginSym);
1292
1293 const ClrEHUnwindMapEntry &Entry = FuncInfo.ClrEHUnwindMap[Clause.State];
1296 const MCExpr *HandlerBegin = getOffset(BeginSym, FuncBeginSym);
1297 MCSymbol *EndSym = EndSymbolMap[Clause.State];
1298 const MCExpr *HandlerEnd = getOffset(EndSym, FuncBeginSym);
1299
1300 uint32_t Flags = 0;
1301 switch (Entry.HandlerType) {
1303
1304 break;
1307 break;
1310 break;
1313 break;
1314 }
1315 if (Clause.EnclosingState != MinClauseMap[Clause.State]) {
1316
1317
1318 assert(Clause.EnclosingState > MinClauseMap[Clause.State]);
1320 }
1322
1323
1326
1327
1330
1331
1334 }
1335}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains constants used for implementing Dwarf debug support.
Module.h This file contains the declarations for the Module class.
Promote Memory to Register
This file describes how to lower LLVM code to machine code.
static int getTryAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right)
Definition WinException.cpp:1086
static int getTryRank(const WinEHFuncInfo &FuncInfo, int State)
Definition WinException.cpp:1077
static MCSymbol * getMCSymbolForMBB(AsmPrinter *Asm, const MachineBasicBlock *MBB)
Retrieve the MCSymbol for a GlobalValue or MachineBasicBlock.
Definition WinException.cpp:170
This class is intended to be used as a driving class for all asm writers.
MachineFunction * MF
The current machine function.
MCContext & OutContext
This is the context for the output file that we are streaming.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
static bool callToNoUnwindFunction(const MachineInstr *MI)
Return ‘true’ if this is a call to a function marked ‘nounwind’.
AsmPrinter * Asm
Target of directive emission.
MCSymbol * emitExceptionTable()
Emit landing pads and actions.
MachineModuleInfo * MMI
Collected machine module information.
EHStreamer(AsmPrinter *A)
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
LLVM_ABI MCSymbol * getOrCreateParentFrameOffsetSymbol(const Twine &FuncName)
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
virtual bool isVerboseAsm() const
Return true if this streamer supports verbose assembly and if it is enabled.
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
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.
void emitInt32(uint64_t Value)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MachineInstrBundleIterator< const MachineInstr > const_iterator
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
bool isCleanupFuncletEntry() const
Returns true if this is the entry block of a cleanup funclet.
int getStackProtectorIndex() const
Return the index for the stack protector object.
bool hasStackProtectorIndex() const
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const std::vector< MCSymbol * > & getEHContTargets() const
Returns a reference to a list of symbols that are targets for Windows EH Continuation Guard.
MCContext & getContext() const
Function & getFunction()
Return the LLVM function that this machine code represents.
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
const MachineBasicBlock & front() const
bool hasEHFunclets() const
BasicBlockListType::const_iterator const_iterator
Representation of each machine instruction.
A Module instance is used to store all the information related to an LLVM module.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
int64_t getFixed() const
Returns the fixed component of the stack.
static StackOffset getFixed(int64_t Fixed)
StringRef - Represent a constant reference to a string, i.e.
virtual StackOffset getNonLocalFrameIndexReference(const MachineFunction &MF, int FI) const
getNonLocalFrameIndexReference - This method returns the offset used to reference a frame index locat...
virtual StackOffset getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, Register &FrameReg, bool IgnoreSPUpdates) const
Same as getFrameIndexReference, except that the stack pointer (as opposed to the frame pointer) will ...
virtual unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const
virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
unsigned getLSDAEncoding() const
virtual MCSymbol * getCFIPersonalitySymbol(const GlobalValue *GV, const TargetMachine &TM, MachineModuleInfo *MMI) const
unsigned getPersonalityEncoding() const
virtual const TargetFrameLowering * getFrameLowering() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
void endFunction(const MachineFunction *) override
Gather and emit post-function exception information.
Definition WinException.cpp:124
void markFunctionEnd() override
Definition WinException.cpp:116
void beginFunclet(const MachineBasicBlock &MBB, MCSymbol *Sym) override
Emit target-specific EH funclet machinery.
Definition WinException.cpp:189
void endModule() override
Emit all exception information that should come after the content.
Definition WinException.cpp:47
WinException(AsmPrinter *A)
Definition WinException.cpp:35
void endFunclet() override
Definition WinException.cpp:240
void beginFunction(const MachineFunction *MF) override
Gather pre-function exception information.
Definition WinException.cpp:63
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ IMAGE_SYM_CLASS_STATIC
Static.
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
APInt operator*(APInt a, uint64_t RHS)
bool operator!=(uint64_t V1, const APInt &V2)
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present - Functionally identical to dyn_cast, except that a null (or none in the case ...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
bool isNoOpWithoutInvoke(EHPersonality Pers)
Return true if this personality may be safely removed if there are no invoke instructions remaining i...
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
int ToState
If unwinding continues through this handler, transition to the handler at this state.
MBBOrBasicBlock Handler
Holds the __except or __finally basic block.
const Function * Filter
Holds the filter expression function.
SmallVector< SEHUnwindMapEntry, 4 > SEHUnwindMap
SmallVector< ClrEHUnwindMapEntry, 4 > ClrEHUnwindMap
DenseMap< const FuncletPadInst *, int > FuncletBaseStateMap
SmallVector< WinEHTryBlockMapEntry, 4 > TryBlockMap
DenseMap< MCSymbol *, std::pair< int, MCSymbol * > > LabelToStateMap
SmallVector< CxxUnwindMapEntry, 4 > CxxUnwindMap
GlobalVariable * TypeDescriptor
union llvm::WinEHHandlerType::@246205307012256373115155017221207221353102114334 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
SmallVector< WinEHHandlerType, 1 > HandlerArray