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);
41}
42
44
45
46
51 if (F.hasFnAttribute("safeseh"))
53
54 if (M->getModuleFlag("ehcontguard") && !EHContTargets.empty()) {
55
57 for (const MCSymbol *S : EHContTargets) {
58 OS.emitCOFFSymbolIndex(S);
59 }
60 }
61}
62
64 shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
65
66
69
71
73
76
78 const Function *PerFn = nullptr;
79 if (F.hasPersonalityFn()) {
80 PerFn = dyn_cast(F.getPersonalityFn()->stripPointerCasts());
82 }
83
84 bool forceEmitPersonality = F.hasPersonalityFn() &&
86 F.needsUnwindTableEntry();
87
88 shouldEmitPersonality =
89 forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
91
93 shouldEmitLSDA = shouldEmitPersonality &&
95
96
97
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))
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) {
141
142
146
147
148
150 emitCSpecificHandlerTable(MF);
152 emitExceptHandlerTable(MF);
154 emitCXXFrameHandler3Table(MF);
156 emitCLRExceptionTable(MF);
157 else
159
161 }
162
164
165 EHContTargets.insert(EHContTargets.end(), MF->getCatchretTargets().begin(),
167 }
168}
169
170
173 if ()
174 return nullptr;
175
177
178
179
187 FuncLinkageName + "@4HA");
188}
189
192 CurrentFuncletEntry = &MBB;
193
195
196 if () {
198
199
205
206
207
209 &F);
210
211
213 }
214
215
216 if (shouldEmitMoves || shouldEmitPersonality) {
217 CurrentFuncletTextSection = Asm->OutStreamer->getCurrentSectionOnly();
219 }
220
221 if (shouldEmitPersonality) {
223 const Function *PerFn = nullptr;
224
225
226 if (F.hasPersonalityFn())
227 PerFn = dyn_cast(F.getPersonalityFn()->stripPointerCasts());
228 const MCSymbol *PersHandlerSym =
230
231
232
233
234
235
237 Asm->OutStreamer->emitWinEHHandler(PersHandlerSym, true, true);
238 }
239}
240
242 if (isAArch64 && CurrentFuncletEntry &&
243 (shouldEmitMoves || shouldEmitPersonality)) {
244 Asm->OutStreamer->switchSection(CurrentFuncletTextSection);
246 }
247 endFuncletImpl();
248}
249
250void WinException::endFuncletImpl() {
251
252 if (!CurrentFuncletEntry)
253 return;
254
256 if (shouldEmitMoves || shouldEmitPersonality) {
259 if (F.hasPersonalityFn())
261
264
266
267
268
271 Twine("$cppxdata$", FuncLinkageName));
272 Asm->OutStreamer->emitValue(create32bitRef(FuncInfoXData), 4);
275
277
278
279
280 emitCSpecificHandlerTable(MF);
281 } else if (shouldEmitPersonality || shouldEmitLSDA) {
282
284
285
286
287 } else {
288
289
290
291 }
292
293
294
295
296 Asm->OutStreamer->switchSection(CurrentFuncletTextSection);
298 }
299
300
301 CurrentFuncletEntry = nullptr;
302}
303
311}
312
313const MCExpr *WinException::create32bitRef(const GlobalValue *GV) {
314 if (!GV)
317}
318
319const MCExpr *WinException::getLabel(const MCSymbol *Label) {
322}
323
324const MCExpr *WinException::getLabelPlusOne(const MCSymbol *Label) {
328}
329
330const MCExpr *WinException::getOffset(const MCSymbol *OffsetOf,
331 const MCSymbol *OffsetFrom) {
335}
336
337const MCExpr *WinException::getOffsetPlusOne(const MCSymbol *OffsetOf,
338 const MCSymbol *OffsetFrom) {
342}
343
344int WinException::getFrameIndexOffset(int FrameIndex,
351 true);
356 return Offset.getFixed();
357 }
358
359
360
365 "Frame offsets with a scalable component are not supported");
366 return Offset.getFixed();
367}
368
369namespace {
370
371
372const int NullState = -1;
373
374struct InvokeStateChange {
375
376
377 const MCSymbol *PreviousEndLabel;
378
379
380
381 const MCSymbol *NewStartLabel;
382
383
384
385 int NewState;
386};
387
388
389
390
391
392
393
394
395
396class InvokeStateChangeIterator {
397 InvokeStateChangeIterator(const WinEHFuncInfo &EHInfo,
401 int BaseState)
402 : EHInfo(EHInfo), MFI(MFI), MFE(MFE), MBBI(MBBI), BaseState(BaseState) {
403 LastStateChange.PreviousEndLabel = nullptr;
404 LastStateChange.NewStartLabel = nullptr;
405 LastStateChange.NewState = BaseState;
406 scan();
407 }
408
409public:
413
414
416 auto BlockBegin = Begin->begin();
417 auto BlockEnd = std::prev(End)->end();
419 InvokeStateChangeIterator(EHInfo, Begin, End, BlockBegin, BaseState),
420 InvokeStateChangeIterator(EHInfo, End, End, BlockEnd, BaseState));
421 }
422
423
424 bool operator==(const InvokeStateChangeIterator &O) const {
425 assert(BaseState == O.BaseState);
426
427 if (MFI != O.MFI)
428 return false;
429
431 return false;
432
433
434
435
436 return CurrentEndLabel == O.CurrentEndLabel;
437 }
438
439 bool operator!=(const InvokeStateChangeIterator &O) const {
441 }
442 InvokeStateChange &operator*() { return LastStateChange; }
443 InvokeStateChange *operator->() { return &LastStateChange; }
444 InvokeStateChangeIterator &operator++() { return scan(); }
445
446private:
447 InvokeStateChangeIterator &scan();
448
450 const MCSymbol *CurrentEndLabel = nullptr;
454 InvokeStateChange LastStateChange;
455 bool VisitingInvoke = false;
456 int BaseState;
457};
458
459}
460
461InvokeStateChangeIterator &InvokeStateChangeIterator::scan() {
462 bool IsNewBlock = false;
463 for (; MFI != MFE; ++MFI, IsNewBlock = true) {
464 if (IsNewBlock)
466 for (auto MBBE = MFI->end(); MBBI != MBBE; ++MBBI) {
468 if (!VisitingInvoke && LastStateChange.NewState != BaseState &&
470
471
472
473 LastStateChange.PreviousEndLabel = CurrentEndLabel;
474 LastStateChange.NewStartLabel = nullptr;
475 LastStateChange.NewState = BaseState;
476 CurrentEndLabel = nullptr;
477
479 return *this;
480 }
481
482
483 if (.isEHLabel())
484 continue;
486 if (Label == CurrentEndLabel) {
487 VisitingInvoke = false;
488 continue;
489 }
491
493 continue;
494 auto &StateAndEnd = InvokeMapIter->second;
495 int NewState = StateAndEnd.first;
496
497
498 VisitingInvoke = true;
499 if (NewState == LastStateChange.NewState) {
500
501
502 CurrentEndLabel = StateAndEnd.second;
503 continue;
504 }
505
506 LastStateChange.PreviousEndLabel = CurrentEndLabel;
507 LastStateChange.NewStartLabel = Label;
508 LastStateChange.NewState = NewState;
509
510 CurrentEndLabel = StateAndEnd.second;
511
513 return *this;
514 }
515 }
516
517 if (LastStateChange.NewState != BaseState) {
518
519 LastStateChange.PreviousEndLabel = CurrentEndLabel;
520 LastStateChange.NewStartLabel = nullptr;
521 LastStateChange.NewState = BaseState;
522
523 assert(CurrentEndLabel != nullptr);
524 return *this;
525 }
526
527 CurrentEndLabel = nullptr;
528 return *this;
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
555
556
557
558
559void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
563
564 bool VerboseAsm = OS.isVerboseAsm();
565 auto AddComment = [&](const Twine &Comment) {
566 if (VerboseAsm)
567 OS.AddComment(Comment);
568 };
569
570 if (!isAArch64) {
571
572
575 MCSymbol *ParentFrameOffset =
577 const MCExpr *MCOffset =
579 Asm->OutStreamer->emitAssignment(ParentFrameOffset, MCOffset);
580 }
581
582
583
585 Ctx.createTempSymbol("lsda_begin", true);
588 const MCExpr *LabelDiff = getOffset(TableEnd, TableBegin);
591 AddComment("Number of call sites");
592 OS.emitValue(EntryCount, 4);
593
594 OS.emitLabel(TableBegin);
595
596
597
598
599
600
601
602
603 const MCSymbol *LastStartLabel = nullptr;
604 int LastEHState = -1;
605
606
609 while (Stop != End && !Stop->isEHFuncletEntry())
610 ++Stop;
611 for (const auto &StateChange :
612 InvokeStateChangeIterator::range(FuncInfo, MF->begin(), Stop)) {
613
614
615 if (LastEHState != -1)
616 emitSEHActionsForRange(FuncInfo, LastStartLabel,
617 StateChange.PreviousEndLabel, LastEHState);
618 LastStartLabel = StateChange.NewStartLabel;
619 LastEHState = StateChange.NewState;
620 }
621
622 OS.emitLabel(TableEnd);
623}
624
625void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
627 const MCSymbol *EndLabel, int State) {
630 bool VerboseAsm = OS.isVerboseAsm();
631 auto AddComment = [&](const Twine &Comment) {
632 if (VerboseAsm)
633 OS.AddComment(Comment);
634 };
635
636 assert(BeginLabel && EndLabel);
637 while (State != -1) {
639 const MCExpr *FilterOrFinally;
640 const MCExpr *ExceptOrNull;
641 auto *Handler = cast<MachineBasicBlock *>(UME.Handler);
645 } else {
646
647
648 FilterOrFinally = UME.Filter ? create32bitRef(UME.Filter)
650 ExceptOrNull = create32bitRef(Handler->getSymbol());
651 }
652
653 AddComment("LabelStart");
654 OS.emitValue(getLabel(BeginLabel), 4);
655 AddComment("LabelEnd");
656 OS.emitValue(getLabelPlusOne(EndLabel), 4);
657 AddComment(UME.IsFinally ? "FinallyFunclet" : UME.Filter ? "FilterFunction"
658 : "CatchAll");
659 OS.emitValue(FilterOrFinally, 4);
660 AddComment(UME.IsFinally ? "Null" : "ExceptionHandler");
661 OS.emitValue(ExceptOrNull, 4);
662
663 assert(UME.ToState < State && "states should decrease");
665 }
666}
667
668void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
672
674
676 MCSymbol *FuncInfoXData = nullptr;
677 if (shouldEmitPersonality) {
678
679
680 FuncInfoXData =
682 computeIP2StateTable(MF, FuncInfo, IPToStateTable);
683 } else {
685 }
686
687 int UnwindHelpOffset = 0;
688
689
690
691
694 UnwindHelpOffset =
696
697 MCSymbol *UnwindMapXData = nullptr;
698 MCSymbol *TryBlockMapXData = nullptr;
699 MCSymbol *IPToStateXData = nullptr;
702 Twine("$stateUnwindMap$", FuncLinkageName));
704 TryBlockMapXData =
706 if (!IPToStateTable.empty())
707 IPToStateXData =
709
710 bool VerboseAsm = OS.isVerboseAsm();
711 auto AddComment = [&](const Twine &Comment) {
712 if (VerboseAsm)
713 OS.AddComment(Comment);
714 };
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731 OS.emitValueToAlignment(Align(4));
732 OS.emitLabel(FuncInfoXData);
733
734 AddComment("MagicNumber");
735 OS.emitInt32(0x19930522);
736
737 AddComment("MaxState");
739
740 AddComment("UnwindMap");
741 OS.emitValue(create32bitRef(UnwindMapXData), 4);
742
743 AddComment("NumTryBlocks");
745
746 AddComment("TryBlockMap");
747 OS.emitValue(create32bitRef(TryBlockMapXData), 4);
748
749 AddComment("IPMapEntries");
750 OS.emitInt32(IPToStateTable.size());
751
752 AddComment("IPToStateXData");
753 OS.emitValue(create32bitRef(IPToStateXData), 4);
754
757 AddComment("UnwindHelp");
758 OS.emitInt32(UnwindHelpOffset);
759 }
760
761 AddComment("ESTypeList");
762 OS.emitInt32(0);
763
764 AddComment("EHFlags");
766 OS.emitInt32(0);
767 } else {
768 OS.emitInt32(1);
769 }
770
771
772
773
774
775 if (UnwindMapXData) {
776 OS.emitLabel(UnwindMapXData);
779 Asm, dyn_cast_if_present<MachineBasicBlock *>(UME.Cleanup));
780 AddComment("ToState");
782
783 AddComment("Action");
784 OS.emitValue(create32bitRef(CleanupSym), 4);
785 }
786 }
787
788
789
790
791
792
793
794
795 if (TryBlockMapXData) {
796 OS.emitLabel(TryBlockMapXData);
798 for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
800
801 MCSymbol *HandlerMapXData = nullptr;
803 HandlerMapXData =
807 .concat(FuncLinkageName));
808 HandlerMaps.push_back(HandlerMapXData);
809
810
811 assert(0 <= TBME.TryLow && "bad trymap interval");
815 "bad trymap interval");
816
817 AddComment("TryLow");
819
820 AddComment("TryHigh");
822
823 AddComment("CatchHigh");
825
826 AddComment("NumCatches");
828
829 AddComment("HandlerArray");
830 OS.emitValue(create32bitRef(HandlerMapXData), 4);
831 }
832
833
834 unsigned ParentFrameOffset = 0;
835 if (shouldEmitPersonality) {
838 }
839
840 for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
842 MCSymbol *HandlerMapXData = HandlerMaps[I];
843 if (!HandlerMapXData)
844 continue;
845
846
847
848
849
850
851
852 OS.emitLabel(HandlerMapXData);
854
855
856
857 const MCExpr *FrameAllocOffsetRef = nullptr;
860 assert(Offset != 0 && "Illegal offset for catch object!");
862 } else {
864 }
865
867 Asm, dyn_cast_if_present<MachineBasicBlock *>(HT.Handler));
868
869 AddComment("Adjectives");
871
872 AddComment("Type");
874
875 AddComment("CatchObjOffset");
876 OS.emitValue(FrameAllocOffsetRef, 4);
877
878 AddComment("Handler");
879 OS.emitValue(create32bitRef(HandlerSym), 4);
880
881 if (shouldEmitPersonality) {
882 AddComment("ParentFrameOffset");
883 OS.emitInt32(ParentFrameOffset);
884 }
885 }
886 }
887 }
888
889
890
891
892
893 if (IPToStateXData) {
894 OS.emitLabel(IPToStateXData);
895 for (auto &IPStatePair : IPToStateTable) {
896 AddComment("IP");
897 OS.emitValue(IPStatePair.first, 4);
898 AddComment("ToState");
899 OS.emitInt32(IPStatePair.second);
900 }
901 }
902}
903
904void WinException::computeIP2StateTable(
906 SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable) {
907
909 FuncletEnd = MF->begin(),
911 FuncletStart != End; FuncletStart = FuncletEnd) {
912
913 while (++FuncletEnd != End) {
914 if (FuncletEnd->isEHFuncletEntry()) {
915 break;
916 }
917 }
918
919
920
921
922 if (FuncletStart->isCleanupFuncletEntry())
923 continue;
924
926 int BaseState;
927 if (FuncletStart == MF->begin()) {
928 BaseState = NullState;
930 } else {
931 auto *FuncletPad =
932 cast(FuncletStart->getBasicBlock()->getFirstNonPHI());
936 }
937 assert(StartLabel && "need local function start label");
938 IPToStateTable.push_back(
939 std::make_pair(create32bitRef(StartLabel), BaseState));
940
941 for (const auto &StateChange : InvokeStateChangeIterator::range(
942 FuncInfo, FuncletStart, FuncletEnd, BaseState)) {
943
944
945
946
947 const MCSymbol *ChangeLabel = StateChange.NewStartLabel;
948 if (!ChangeLabel)
949 ChangeLabel = StateChange.PreviousEndLabel;
950
951
952
953
954
955 const MCExpr *LabelExpression = (isAArch64 || isThumb)
956 ? getLabel(ChangeLabel)
957 : getLabelPlusOne(ChangeLabel);
958 IPToStateTable.push_back(
959 std::make_pair(LabelExpression, StateChange.NewState));
960
961 }
962 }
963}
964
965void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
967
968
969
970
971
972
973
974
975
978 if (FI != INT_MAX) {
981 }
982
984 MCSymbol *ParentFrameOffset =
988}
989
990
991
992
993void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
997
998 bool VerboseAsm = OS.isVerboseAsm();
999 auto AddComment = [&](const Twine &Comment) {
1000 if (VerboseAsm)
1001 OS.AddComment(Comment);
1002 };
1003
1005 emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
1006
1007
1009 OS.emitValueToAlignment(Align(4));
1010 OS.emitLabel(LSDALabel);
1011
1012 const auto *Per = cast(F.getPersonalityFn()->stripPointerCasts());
1013 StringRef PerName = Per->getName();
1014 int BaseState = -1;
1015 if (PerName == "_except_handler4") {
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038 int GSCookieOffset = -2;
1044 GSCookieOffset =
1046 }
1047
1048
1049
1050 int EHCookieOffset = 9999;
1055 EHCookieOffset =
1057 }
1058
1059 AddComment("GSCookieOffset");
1060 OS.emitInt32(GSCookieOffset);
1061 AddComment("GSCookieXOROffset");
1062 OS.emitInt32(0);
1063 AddComment("EHCookieOffset");
1064 OS.emitInt32(EHCookieOffset);
1065 AddComment("EHCookieXOROffset");
1066 OS.emitInt32(0);
1067 BaseState = -2;
1068 }
1069
1072 auto *Handler = cast<MachineBasicBlock *>(UME.Handler);
1073 const MCSymbol *ExceptOrFinally =
1075
1076
1077 int ToState = UME.ToState == -1 ? BaseState : UME.ToState;
1078 AddComment("ToState");
1079 OS.emitInt32(ToState);
1080 AddComment(UME.IsFinally ? "Null" : "FilterFunction");
1081 OS.emitValue(create32bitRef(UME.Filter), 4);
1082 AddComment(UME.IsFinally ? "FinallyFunclet" : "ExceptionHandler");
1083 OS.emitValue(create32bitRef(ExceptOrFinally), 4);
1084 }
1085}
1086
1088 int Rank = 0;
1089 while (State != -1) {
1090 ++Rank;
1091 State = FuncInfo.ClrEHUnwindMap[State].TryParentState;
1092 }
1093 return Rank;
1094}
1095
1099
1100 while (LeftRank < RightRank) {
1102 --RightRank;
1103 }
1104
1105 while (RightRank < LeftRank) {
1107 --LeftRank;
1108 }
1109
1113 }
1114
1115 return Left;
1116}
1117
1118void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
1119
1120
1121
1126
1127
1128 struct ClrClause {
1129 const MCSymbol *StartLabel;
1130 const MCSymbol *EndLabel;
1131 int State;
1132 int EnclosingState;
1133 };
1135
1136
1137
1139 assert(NumStates > 0 && "Don't need exception table!");
1141 for (int State = 0; State < NumStates; ++State) {
1143 cast<MachineBasicBlock *>(FuncInfo.ClrEHUnwindMap[State].Handler);
1144 HandlerStates[HandlerBlock] = State;
1145
1146
1147
1149 "ill-formed state numbering");
1150 }
1151
1152 HandlerStates[&MF->front()] = NullState;
1153
1154
1155
1156 OS.emitInt32(0xffffffff);
1157
1158 OS.emitInt32(NumStates);
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1176
1177 std::unique_ptr<MCSymbol *[]> EndSymbolMap(new MCSymbol *[NumStates]);
1179
1180
1182 FuncletEnd = MF->begin(),
1184 FuncletStart != End; FuncletStart = FuncletEnd) {
1185 int FuncletState = HandlerStates[&*FuncletStart];
1186
1187 MCSymbol *EndSymbol = FuncEndSym;
1188 while (++FuncletEnd != End) {
1189 if (FuncletEnd->isEHFuncletEntry()) {
1191 break;
1192 }
1193 }
1194
1195
1196 OS.emitValue(getOffset(EndSymbol, FuncBeginSym), 4);
1197 if (FuncletState != NullState) {
1198
1199 EndSymbolMap[FuncletState] = EndSymbol;
1200 }
1201
1202
1203
1204 const MCSymbol *CurrentStartLabel = nullptr;
1205 int CurrentState = NullState;
1207 for (const auto &StateChange :
1208 InvokeStateChangeIterator::range(FuncInfo, FuncletStart, FuncletEnd)) {
1209
1210 int StillPendingState =
1211 getTryAncestor(FuncInfo, CurrentState, StateChange.NewState);
1212 while (CurrentState != StillPendingState) {
1213 assert(CurrentState != NullState &&
1214 "Failed to find still-pending state!");
1215
1216 Clauses.push_back({CurrentStartLabel, StateChange.PreviousEndLabel,
1217 CurrentState, FuncletState});
1218
1219 CurrentState = FuncInfo.ClrEHUnwindMap[CurrentState].TryParentState;
1220
1221
1222 if (HandlerStack.back().second == CurrentState)
1223 CurrentStartLabel = HandlerStack.pop_back_val().first;
1224 }
1225
1226 if (StateChange.NewState != CurrentState) {
1227
1228
1229
1230 for (int EnteredState = StateChange.NewState;
1231 EnteredState != CurrentState;
1232 EnteredState =
1233 FuncInfo.ClrEHUnwindMap[EnteredState].TryParentState) {
1234 int &MinEnclosingState = MinClauseMap[EnteredState];
1235 if (FuncletState < MinEnclosingState)
1236 MinEnclosingState = FuncletState;
1237 }
1238
1239
1240 HandlerStack.emplace_back(CurrentStartLabel, CurrentState);
1241 CurrentStartLabel = StateChange.NewStartLabel;
1242 CurrentState = StateChange.NewState;
1243 }
1244 }
1246 }
1247
1248
1249 OS.emitInt32(Clauses.size());
1250 for (ClrClause &Clause : Clauses) {
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
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299 const MCExpr *ClauseBegin =
1300 getOffsetPlusOne(Clause.StartLabel, FuncBeginSym);
1301 const MCExpr *ClauseEnd = getOffsetPlusOne(Clause.EndLabel, FuncBeginSym);
1302
1306 const MCExpr *HandlerBegin = getOffset(BeginSym, FuncBeginSym);
1308 const MCExpr *HandlerEnd = getOffset(EndSym, FuncBeginSym);
1309
1311 switch (Entry.HandlerType) {
1313
1314 break;
1317 break;
1320 break;
1323 break;
1324 }
1325 if (Clause.EnclosingState != MinClauseMap[Clause.State]) {
1326
1327
1330 }
1331 OS.emitInt32(Flags);
1332
1333
1334 OS.emitValue(ClauseBegin, 4);
1335 OS.emitValue(ClauseEnd, 4);
1336
1337
1338 OS.emitValue(HandlerBegin, 4);
1339 OS.emitValue(HandlerEnd, 4);
1340
1341
1343 OS.emitInt32(Entry.TypeToken);
1344 }
1345}
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains constants used for implementing Dwarf debug support.
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file describes how to lower LLVM code to machine code.
static int getTryAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right)
static int getTryRank(const WinEHFuncInfo &FuncInfo, int State)
static MCSymbol * getMCSymbolForMBB(AsmPrinter *Asm, const MachineBasicBlock *MBB)
Retrieve the MCSymbol for a GlobalValue or MachineBasicBlock.
This class is intended to be used as a driving class for all asm writers.
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
MCSymbol * getSymbol(const GlobalValue *GV) const
TargetMachine & TM
Target machine description.
MCSymbol * getFunctionBegin() const
const MCAsmInfo * MAI
Target Asm Printer information.
MachineFunction * MF
The current machine function.
MCSymbol * CurrentFnSym
The symbol for the current function.
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
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.
MCSymbol * getFunctionEnd() const
Emits exception handling directives.
AsmPrinter * Asm
Target of directive emission.
MCSymbol * emitExceptionTable()
Emit landing pads and actions.
MachineModuleInfo * MMI
Collected machine module information.
static bool callToNoUnwindFunction(const MachineInstr *MI)
Return ‘true’ if this is a call to a function marked ‘nounwind’.
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
bool usesWindowsCFI() const
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
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 const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCObjectFileInfo * getObjectFileInfo() const
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
MCSymbol * getOrCreateParentFrameOffsetSymbol(const Twine &FuncName)
MCSymbol * getOrCreateLSDASymbol(const Twine &FuncName)
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.
MCSection * getGEHContSection() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Streaming machine code generation interface.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Align getAlignment() const
Return alignment of the basic block.
bool isCleanupFuncletEntry() const
Returns true if this is the entry block of a cleanup funclet.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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.
MCContext & getContext() const
Align getAlignment() const
getAlignment - Return the alignment of the function.
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 std::vector< MCSymbol * > & getCatchretTargets() const
Returns a reference to a list of symbols that we have catchrets.
const MachineBasicBlock & front() const
bool hasEHFunclets() const
BasicBlockListType::const_iterator const_iterator
Representation of each machine instruction.
const Module * getModule() const
A Module instance is used to store all the information related to an LLVM module.
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Wrapper class representing virtual and physical registers.
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)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
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.
Information about stack frame layout on the target.
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...
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
unsigned getLSDAEncoding() const
virtual MCSymbol * getCFIPersonalitySymbol(const GlobalValue *GV, const TargetMachine &TM, MachineModuleInfo *MMI) const
unsigned getPersonalityEncoding() const
const Triple & getTargetTriple() const
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetLowering * getTargetLowering() const
bool isThumb() const
Tests whether the target is Thumb (little and big endian).
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
StringRef getName() const
Return a constant reference to the value's name.
void endFunction(const MachineFunction *) override
Gather and emit post-function exception information.
void markFunctionEnd() override
void beginFunclet(const MachineBasicBlock &MBB, MCSymbol *Sym) override
Emit target-specific EH funclet machinery.
void endModule() override
Emit all exception information that should come after the content.
WinException(AsmPrinter *A)
void endFunclet() override
void beginFunction(const MachineFunction *MF) override
Gather pre-function exception information.
A range adaptor for a pair of iterators.
@ 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.
APInt operator*(APInt a, uint64_t RHS)
bool operator!=(uint64_t V1, const APInt &V2)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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...
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Similar to CxxUnwindMapEntry, but supports SEH filters.
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
union llvm::WinEHHandlerType::@253 CatchObj
The CatchObj starts out life as an LLVM alloca and is eventually turned frame index.
GlobalVariable * TypeDescriptor
SmallVector< WinEHHandlerType, 1 > HandlerArray