1 //===- llvm/CodeGen/WinEHFuncInfo.h -----------------------------*- C++ -*-===// 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 // 9 // Data structures and associated state for Windows exception handling schemes. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CODEGEN_WINEHFUNCINFO_H 14 #define LLVM_CODEGEN_WINEHFUNCINFO_H 15 16 #include "llvm/ADT/DenseMap.h" 17 #include "llvm/ADT/PointerUnion.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include <cstdint> 20 #include <limits> 21 #include <utility> 22 23 namespace llvm { 24 25 class AllocaInst; 26 class BasicBlock; 27 class FuncletPadInst; 28 class Function; 29 class GlobalVariable; 30 class Instruction; 31 class InvokeInst; 32 class MachineBasicBlock; 33 class MCSymbol; 34 35 // The following structs respresent the .xdata tables for various 36 // Windows-related EH personalities. 37 38 using MBBOrBasicBlock = PointerUnion<const BasicBlock *, MachineBasicBlock *>; 39 40 struct CxxUnwindMapEntry { 41 int ToState; 42 MBBOrBasicBlock Cleanup; 43 }; 44 45 /// Similar to CxxUnwindMapEntry, but supports SEH filters. 46 struct SEHUnwindMapEntry { 47 /// If unwinding continues through this handler, transition to the handler at 48 /// this state. This indexes into SEHUnwindMap. 49 int ToState = -1; 50 51 bool IsFinally = false; 52 53 /// Holds the filter expression function. 54 const Function *Filter = nullptr; 55 56 /// Holds the __except or __finally basic block. 57 MBBOrBasicBlock Handler; 58 }; 59 60 struct WinEHHandlerType { 61 int Adjectives; 62 /// The CatchObj starts out life as an LLVM alloca and is eventually turned 63 /// frame index. 64 union { 65 const AllocaInst *Alloca; 66 int FrameIndex; 67 } CatchObj = {}; 68 GlobalVariable *TypeDescriptor; 69 MBBOrBasicBlock Handler; 70 }; 71 72 struct WinEHTryBlockMapEntry { 73 int TryLow = -1; 74 int TryHigh = -1; 75 int CatchHigh = -1; 76 SmallVector<WinEHHandlerType, 1> HandlerArray; 77 }; 78 79 enum class ClrHandlerType { Catch, Finally, Fault, Filter }; 80 81 struct ClrEHUnwindMapEntry { 82 MBBOrBasicBlock Handler; 83 uint32_t TypeToken; 84 int HandlerParentState; ///< Outer handler enclosing this entry's handler 85 int TryParentState; ///< Outer try region enclosing this entry's try region, 86 ///< treating later catches on same try as "outer" 87 ClrHandlerType HandlerType; 88 }; 89 90 struct WinEHFuncInfo { 91 DenseMap<const Instruction *, int> EHPadStateMap; 92 DenseMap<const FuncletPadInst *, int> FuncletBaseStateMap; 93 DenseMap<const InvokeInst *, int> InvokeStateMap; 94 DenseMap<MCSymbol *, std::pair<int, MCSymbol *>> LabelToStateMap; 95 DenseMap<const BasicBlock *, int> BlockToStateMap; // for AsynchEH 96 SmallVector<CxxUnwindMapEntry, 4> CxxUnwindMap; 97 SmallVector<WinEHTryBlockMapEntry, 4> TryBlockMap; 98 SmallVector<SEHUnwindMapEntry, 4> SEHUnwindMap; 99 SmallVector<ClrEHUnwindMapEntry, 4> ClrEHUnwindMap; 100 int UnwindHelpFrameIdx = std::numeric_limits<int>::max(); 101 int PSPSymFrameIdx = std::numeric_limits<int>::max(); 102 getLastStateNumberWinEHFuncInfo103 int getLastStateNumber() const { return CxxUnwindMap.size() - 1; } 104 105 void addIPToStateRange(const InvokeInst *II, MCSymbol *InvokeBegin, 106 MCSymbol *InvokeEnd); 107 108 void addIPToStateRange(int State, MCSymbol *InvokeBegin, MCSymbol *InvokeEnd); 109 110 int EHRegNodeFrameIndex = std::numeric_limits<int>::max(); 111 int EHRegNodeEndOffset = std::numeric_limits<int>::max(); 112 int EHGuardFrameIndex = std::numeric_limits<int>::max(); 113 int SEHSetFrameOffset = std::numeric_limits<int>::max(); 114 115 WinEHFuncInfo(); 116 }; 117 118 /// Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which 119 /// describes the state numbers and tables used by __CxxFrameHandler3. This 120 /// analysis assumes that WinEHPrepare has already been run. 121 void calculateWinCXXEHStateNumbers(const Function *ParentFn, 122 WinEHFuncInfo &FuncInfo); 123 124 void calculateSEHStateNumbers(const Function *ParentFn, 125 WinEHFuncInfo &FuncInfo); 126 127 void calculateClrEHStateNumbers(const Function *Fn, WinEHFuncInfo &FuncInfo); 128 129 // For AsynchEH (VC++ option -EHa) 130 void calculateCXXStateForAsynchEH(const BasicBlock *BB, int State, 131 WinEHFuncInfo &FuncInfo); 132 void calculateSEHStateForAsynchEH(const BasicBlock *BB, int State, 133 WinEHFuncInfo &FuncInfo); 134 135 } // end namespace llvm 136 137 #endif // LLVM_CODEGEN_WINEHFUNCINFO_H 138