38 useImageRel32 = (A->getDataLayout().getPointerSizeInBits() == 64);
51 if (
F.hasFnAttribute(
"safeseh"))
54 if (
M->getModuleFlag(
"ehcontguard") && !EHContTargets.empty()) {
58 OS.emitCOFFSymbolIndex(
S);
64 shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA =
false;
79 if (
F.hasPersonalityFn()) {
80 PerFn = dyn_cast<Function>(
F.getPersonalityFn()->stripPointerCasts());
84 bool forceEmitPersonality =
F.hasPersonalityFn() &&
86 F.needsUnwindTableEntry();
88 shouldEmitPersonality =
89 forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
93 shouldEmitLSDA = shouldEmitPersonality &&
106 emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
108 shouldEmitLSDA = hasEHFunclets;
109 shouldEmitPersonality =
false;
117 if (isAArch64 && CurrentFuncletEntry &&
118 (shouldEmitMoves || shouldEmitPersonality))
125 if (!shouldEmitPersonality && !shouldEmitMoves && !shouldEmitLSDA)
130 if (
F.hasPersonalityFn())
147 if (shouldEmitPersonality || shouldEmitLSDA) {
158 emitCSpecificHandlerTable(MF);
160 emitExceptHandlerTable(MF);
162 emitCXXFrameHandler3Table(MF);
164 emitCLRExceptionTable(MF);
195 FuncLinkageName +
"@4HA");
200 CurrentFuncletEntry = &
MBB;
224 if (shouldEmitMoves || shouldEmitPersonality) {
225 CurrentFuncletTextSection =
Asm->
OutStreamer->getCurrentSectionOnly();
229 if (shouldEmitPersonality) {
234 if (
F.hasPersonalityFn())
235 PerFn = dyn_cast<Function>(
F.getPersonalityFn()->stripPointerCasts());
250 if (isAArch64 && CurrentFuncletEntry &&
251 (shouldEmitMoves || shouldEmitPersonality)) {
258 void WinException::endFuncletImpl() {
260 if (!CurrentFuncletEntry)
264 if (shouldEmitMoves || shouldEmitPersonality) {
267 if (
F.hasPersonalityFn())
279 Twine(
"$cppxdata$", FuncLinkageName));
288 emitCSpecificHandlerTable(MF);
289 }
else if (shouldEmitPersonality || shouldEmitLSDA) {
309 CurrentFuncletEntry =
nullptr;
332 const MCExpr *WinException::getLabelPlusOne(
const MCSymbol *Label) {
345 const MCExpr *WinException::getOffsetPlusOne(
const MCSymbol *OffsetOf,
352 int WinException::getFrameIndexOffset(
int FrameIndex,
373 "Frame offsets with a scalable component are not supported");
380 const int NullState = -1;
382 struct InvokeStateChange {
404 class InvokeStateChangeIterator {
410 : EHInfo(EHInfo), MFI(MFI), MFE(MFE),
MBBI(
MBBI), BaseState(BaseState) {
411 LastStateChange.PreviousEndLabel =
nullptr;
412 LastStateChange.NewStartLabel =
nullptr;
413 LastStateChange.NewState = BaseState;
424 auto BlockBegin = Begin->begin();
425 auto BlockEnd = std::prev(End)->end();
427 InvokeStateChangeIterator(EHInfo, Begin, End, BlockBegin, BaseState),
428 InvokeStateChangeIterator(EHInfo, End, End, BlockEnd, BaseState));
432 bool operator==(
const InvokeStateChangeIterator &
O)
const {
433 assert(BaseState ==
O.BaseState);
444 return CurrentEndLabel ==
O.CurrentEndLabel;
447 bool operator!=(
const InvokeStateChangeIterator &
O)
const {
450 InvokeStateChange &
operator*() {
return LastStateChange; }
451 InvokeStateChange *operator->() {
return &LastStateChange; }
452 InvokeStateChangeIterator &operator++() {
return scan(); }
455 InvokeStateChangeIterator &
scan();
458 const MCSymbol *CurrentEndLabel =
nullptr;
462 InvokeStateChange LastStateChange;
463 bool VisitingInvoke =
false;
470 bool IsNewBlock =
false;
471 for (; MFI != MFE; ++MFI, IsNewBlock =
true) {
474 for (
auto MBBE = MFI->end();
MBBI != MBBE; ++
MBBI) {
476 if (!VisitingInvoke && LastStateChange.NewState != BaseState &&
481 LastStateChange.PreviousEndLabel = CurrentEndLabel;
482 LastStateChange.NewStartLabel =
nullptr;
483 LastStateChange.NewState = BaseState;
484 CurrentEndLabel =
nullptr;
494 if (Label == CurrentEndLabel) {
495 VisitingInvoke =
false;
502 auto &StateAndEnd = InvokeMapIter->second;
503 int NewState = StateAndEnd.first;
506 VisitingInvoke =
true;
507 if (NewState == LastStateChange.NewState) {
510 CurrentEndLabel = StateAndEnd.second;
514 LastStateChange.PreviousEndLabel = CurrentEndLabel;
515 LastStateChange.NewStartLabel =
Label;
516 LastStateChange.NewState = NewState;
518 CurrentEndLabel = StateAndEnd.second;
525 if (LastStateChange.NewState != BaseState) {
527 LastStateChange.PreviousEndLabel = CurrentEndLabel;
528 LastStateChange.NewStartLabel =
nullptr;
529 LastStateChange.NewState = BaseState;
531 assert(CurrentEndLabel !=
nullptr);
535 CurrentEndLabel =
nullptr;
567 void WinException::emitCSpecificHandlerTable(
const MachineFunction *MF) {
572 bool VerboseAsm = OS.isVerboseAsm();
575 OS.AddComment(Comment);
596 const MCExpr *LabelDiff = getOffset(TableEnd, TableBegin);
599 AddComment(
"Number of call sites");
600 OS.emitValue(EntryCount, 4);
602 OS.emitLabel(TableBegin);
611 const MCSymbol *LastStartLabel =
nullptr;
612 int LastEHState = -1;
617 while (Stop != End && !Stop->isEHFuncletEntry())
619 for (
const auto &StateChange :
620 InvokeStateChangeIterator::range(FuncInfo, MF->
begin(), Stop)) {
623 if (LastEHState != -1)
624 emitSEHActionsForRange(FuncInfo, LastStartLabel,
625 StateChange.PreviousEndLabel, LastEHState);
626 LastStartLabel = StateChange.NewStartLabel;
627 LastEHState = StateChange.NewState;
630 OS.emitLabel(TableEnd);
633 void WinException::emitSEHActionsForRange(
const WinEHFuncInfo &FuncInfo,
635 const MCSymbol *EndLabel,
int State) {
638 bool VerboseAsm = OS.isVerboseAsm();
641 OS.AddComment(Comment);
644 assert(BeginLabel && EndLabel);
645 while (State != -1) {
647 const MCExpr *FilterOrFinally;
648 const MCExpr *ExceptOrNull;
656 FilterOrFinally = UME.
Filter ? create32bitRef(UME.
Filter)
658 ExceptOrNull = create32bitRef(Handler->getSymbol());
661 AddComment(
"LabelStart");
662 OS.emitValue(getLabel(BeginLabel), 4);
663 AddComment(
"LabelEnd");
664 OS.emitValue(getLabelPlusOne(EndLabel), 4);
665 AddComment(UME.
IsFinally ?
"FinallyFunclet" : UME.
Filter ?
"FilterFunction"
667 OS.emitValue(FilterOrFinally, 4);
668 AddComment(UME.
IsFinally ?
"Null" :
"ExceptionHandler");
669 OS.emitValue(ExceptOrNull, 4);
676 void WinException::emitCXXFrameHandler3Table(
const MachineFunction *MF) {
685 if (shouldEmitPersonality) {
690 computeIP2StateTable(MF, FuncInfo, IPToStateTable);
695 int UnwindHelpOffset = 0;
706 MCSymbol *TryBlockMapXData =
nullptr;
710 Twine(
"$stateUnwindMap$", FuncLinkageName));
714 if (!IPToStateTable.empty())
718 bool VerboseAsm = OS.isVerboseAsm();
721 OS.AddComment(Comment);
739 OS.emitValueToAlignment(4);
740 OS.emitLabel(FuncInfoXData);
742 AddComment(
"MagicNumber");
743 OS.emitInt32(0x19930522);
745 AddComment(
"MaxState");
748 AddComment(
"UnwindMap");
749 OS.emitValue(create32bitRef(UnwindMapXData), 4);
751 AddComment(
"NumTryBlocks");
754 AddComment(
"TryBlockMap");
755 OS.emitValue(create32bitRef(TryBlockMapXData), 4);
757 AddComment(
"IPMapEntries");
758 OS.emitInt32(IPToStateTable.size());
760 AddComment(
"IPToStateXData");
761 OS.emitValue(create32bitRef(IPToStateXData), 4);
765 AddComment(
"UnwindHelp");
766 OS.emitInt32(UnwindHelpOffset);
769 AddComment(
"ESTypeList");
772 AddComment(
"EHFlags");
779 if (UnwindMapXData) {
780 OS.emitLabel(UnwindMapXData);
784 AddComment(
"ToState");
787 AddComment(
"Action");
788 OS.emitValue(create32bitRef(CleanupSym), 4);
799 if (TryBlockMapXData) {
800 OS.emitLabel(TryBlockMapXData);
805 MCSymbol *HandlerMapXData =
nullptr;
811 .
concat(FuncLinkageName));
812 HandlerMaps.push_back(HandlerMapXData);
819 "bad trymap interval");
821 AddComment(
"TryLow");
822 OS.emitInt32(TBME.
TryLow);
824 AddComment(
"TryHigh");
827 AddComment(
"CatchHigh");
830 AddComment(
"NumCatches");
833 AddComment(
"HandlerArray");
834 OS.emitValue(create32bitRef(HandlerMapXData), 4);
838 unsigned ParentFrameOffset = 0;
839 if (shouldEmitPersonality) {
846 MCSymbol *HandlerMapXData = HandlerMaps[
I];
847 if (!HandlerMapXData)
856 OS.emitLabel(HandlerMapXData);
861 const MCExpr *FrameAllocOffsetRef =
nullptr;
864 assert(Offset != 0 &&
"Illegal offset for catch object!");
873 AddComment(
"Adjectives");
879 AddComment(
"CatchObjOffset");
880 OS.emitValue(FrameAllocOffsetRef, 4);
882 AddComment(
"Handler");
883 OS.emitValue(create32bitRef(HandlerSym), 4);
885 if (shouldEmitPersonality) {
886 AddComment(
"ParentFrameOffset");
887 OS.emitInt32(ParentFrameOffset);
897 if (IPToStateXData) {
898 OS.emitLabel(IPToStateXData);
899 for (
auto &IPStatePair : IPToStateTable) {
901 OS.emitValue(IPStatePair.first, 4);
902 AddComment(
"ToState");
903 OS.emitInt32(IPStatePair.second);
908 void WinException::computeIP2StateTable(
913 FuncletEnd = MF->
begin(),
915 FuncletStart != End; FuncletStart = FuncletEnd) {
917 while (++FuncletEnd != End) {
918 if (FuncletEnd->isEHFuncletEntry()) {
926 if (FuncletStart->isCleanupFuncletEntry())
931 if (FuncletStart == MF->
begin()) {
932 BaseState = NullState;
936 cast<FuncletPadInst>(FuncletStart->getBasicBlock()->getFirstNonPHI());
941 assert(StartLabel &&
"need local function start label");
942 IPToStateTable.push_back(
943 std::make_pair(create32bitRef(StartLabel), BaseState));
945 for (
const auto &StateChange : InvokeStateChangeIterator::range(
946 FuncInfo, FuncletStart, FuncletEnd, BaseState)) {
951 const MCSymbol *ChangeLabel = StateChange.NewStartLabel;
953 ChangeLabel = StateChange.PreviousEndLabel;
959 const MCExpr *LabelExpression = (isAArch64 || isThumb)
960 ? getLabel(ChangeLabel)
961 : getLabelPlusOne(ChangeLabel);
962 IPToStateTable.push_back(
963 std::make_pair(LabelExpression, StateChange.NewState));
969 void WinException::emitEHRegistrationOffsetLabel(
const WinEHFuncInfo &FuncInfo,
1009 emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
1016 const auto *Per = cast<Function>(
F.getPersonalityFn()->stripPointerCasts());
1019 if (PerName ==
"_except_handler4") {
1042 int GSCookieOffset = -2;
1054 int EHCookieOffset = 9999;
1063 AddComment(
"GSCookieOffset");
1065 AddComment(
"GSCookieXOROffset");
1067 AddComment(
"EHCookieOffset");
1069 AddComment(
"EHCookieXOROffset");
1082 AddComment(
"ToState");
1084 AddComment(UME.
IsFinally ?
"Null" :
"FilterFunction");
1086 AddComment(UME.
IsFinally ?
"FinallyFunclet" :
"ExceptionHandler");
1087 OS.
emitValue(create32bitRef(ExceptOrFinally), 4);
1093 while (State != -1) {
1104 while (LeftRank < RightRank) {
1109 while (RightRank < LeftRank) {
1143 assert(NumStates > 0 &&
"Don't need exception table!");
1145 for (
int State = 0; State < NumStates; ++State) {
1148 HandlerStates[HandlerBlock] = State;
1153 "ill-formed state numbering");
1156 HandlerStates[&MF->
front()] = NullState;
1181 std::unique_ptr<MCSymbol *[]> EndSymbolMap(
new MCSymbol *[NumStates]);
1186 FuncletEnd = MF->
begin(),
1188 FuncletStart != End; FuncletStart = FuncletEnd) {
1189 int FuncletState = HandlerStates[&*FuncletStart];
1192 while (++FuncletEnd != End) {
1193 if (FuncletEnd->isEHFuncletEntry()) {
1200 OS.
emitValue(getOffset(EndSymbol, FuncBeginSym), 4);
1201 if (FuncletState != NullState) {
1203 EndSymbolMap[FuncletState] = EndSymbol;
1208 const MCSymbol *CurrentStartLabel =
nullptr;
1209 int CurrentState = NullState;
1210 assert(HandlerStack.empty());
1211 for (
const auto &StateChange :
1212 InvokeStateChangeIterator::range(FuncInfo, FuncletStart, FuncletEnd)) {
1214 int StillPendingState =
1216 while (CurrentState != StillPendingState) {
1217 assert(CurrentState != NullState &&
1218 "Failed to find still-pending state!");
1220 Clauses.push_back({CurrentStartLabel, StateChange.PreviousEndLabel,
1221 CurrentState, FuncletState});
1223 CurrentState = FuncInfo.
ClrEHUnwindMap[CurrentState].TryParentState;
1226 if (HandlerStack.back().second == CurrentState)
1230 if (StateChange.NewState != CurrentState) {
1234 for (
int EnteredState = StateChange.NewState;
1235 EnteredState != CurrentState;
1238 int &MinEnclosingState = MinClauseMap[EnteredState];
1239 if (FuncletState < MinEnclosingState)
1240 MinEnclosingState = FuncletState;
1244 HandlerStack.
emplace_back(CurrentStartLabel, CurrentState);
1245 CurrentStartLabel = StateChange.NewStartLabel;
1246 CurrentState = StateChange.NewState;
1249 assert(HandlerStack.empty());
1254 for (ClrClause &
Clause : Clauses) {
1303 const MCExpr *ClauseBegin =
1304 getOffsetPlusOne(
Clause.StartLabel, FuncBeginSym);
1305 const MCExpr *ClauseEnd = getOffsetPlusOne(
Clause.EndLabel, FuncBeginSym);
1310 const MCExpr *HandlerBegin = getOffset(BeginSym, FuncBeginSym);
1312 const MCExpr *HandlerEnd = getOffset(EndSym, FuncBeginSym);
1315 switch (Entry.HandlerType) {
1329 if (
Clause.EnclosingState != MinClauseMap[
Clause.State]) {