Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1156 lines
40 KiB

  1. /***
  2. *ehdata.h -
  3. *
  4. * Copyright (c) 1993-1995, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Declare misc. types, macros, etc. for implementation
  8. * of C++ Exception Handling for the run-time and the compiler.
  9. * Hardware independent, assumes Windows NT.
  10. *
  11. * Portions of this header file can be disabled by defining the following
  12. * macros:
  13. * _EHDATA_NOHEADERS - suppresses inclusion of standard header files
  14. * If this is specified, then appropriate typedefs or macros must
  15. * be provided by some other means.
  16. * _EHDATA_NOTHROW - suppresses definitions used only to describe a throw
  17. * _EHDATA_NOFUNCINFO - suppresses definitions for the frame descriptor
  18. * _EHDATA_NONT - suppresses definitions of our version of NT's stuff
  19. *
  20. * Other conditional compilation macros:
  21. * CC_EXPLICITFRAME - if true, representation of registration node includes
  22. * the value of the frame-pointer for that frame, making the location
  23. * of the registration node on the frame flexible. This is intended
  24. * primarily for early testing.
  25. *
  26. * [Internal]
  27. *
  28. *Revision History:
  29. * 05-20-93 BS Module Created.
  30. * 03-01-94 CFW Remove CONTEXT def for x86 for TiborL.
  31. * 03-03-94 TL Mips (_M_MRX000 >= 4000) changes
  32. * 09-02-94 SKS This header file added.
  33. * 09-12-94 GJF Merged in changes from/for DEC (Al Doser, dated 6/20,
  34. * and Bill Baxter, dated 6/28).
  35. * 11-06-94 GJF Changed pack pragma to 8 byte alignment.
  36. * 02-14-95 CFW Clean up Mac merge.
  37. * 03-22-95 PML Add const for read-only structs
  38. * 03-29-95 CFW Add error message to internal headers.
  39. * 04-14-95 JWM Added EH_ABORT_FRAME_UNWIND_PART for EH/SEH exception handling.
  40. * 04-20-95 TGL Added iFrameNestLevel field to MIPS FuncInfo
  41. * 04-27-95 JWM EH_ABORT_FRAME_UNWIND_PART now #ifdef ALLOW_UNWIND_ABORT.
  42. * 06-08-95 JWM Merged CRT version of ehdata.h into langapi source.
  43. * 01-25-00 GB Declared _CxxThrowException __declspec(noreturn)
  44. * 02-08-00 GB Added HT_ISCOMPLUSEH
  45. * 03-27-00 PML Remove CC_P7_SOFT25, which is now on permanently.
  46. * 09-20-00 GB Add __cdecl to URT C++ EH support routines (vs7#89576)
  47. *
  48. ****/
  49. #ifndef _INC_EHDATA
  50. #define _INC_EHDATA
  51. #ifdef ONLY_VALUES
  52. #define _EHDATA_NOHEADERS
  53. #endif
  54. #ifndef _CRTBLD
  55. #ifndef _VC_VER_INC
  56. #ifdef _M_ALPHA
  57. #include "vcver.h"
  58. #else
  59. #include "..\include\vcver.h"
  60. #endif
  61. #endif
  62. #endif /* _CRTBLD */
  63. #if defined(_M_IX86) && _M_IX86 >= 300 /*IFSTRIP=IGN*/
  64. # ifndef CC_EXPLICITFRAME
  65. # define CC_EXPLICITFRAME 0 // If non-zero, we're using a hack version of the
  66. // registration node.
  67. # endif
  68. #endif
  69. #ifndef _EHDATA_NOHEADERS
  70. #include <stddef.h>
  71. #include <excpt.h>
  72. #if defined(_WIN32)
  73. #include <windows.h>
  74. #else
  75. #include <nowin.h>
  76. #endif
  77. #endif /* _EHDATA_NOHEADERS */
  78. #pragma pack(push, ehdata, 4)
  79. #define EH_EXCEPTION_NUMBER ('msc' | 0xE0000000) // The NT Exception # that we use
  80. #define EH_MAGIC_NUMBER1 0x19930520 // The magic # identifying this version
  81. // As magic numbers increase, we have to keep track of
  82. // the versions that we are backwards compatible with.
  83. #if defined(_M_IA64) || defined(_M_AMD64)
  84. #define EH_EXCEPTION_PARAMETERS 4 // Number of parameters in exception record
  85. #else
  86. #define EH_EXCEPTION_PARAMETERS 3 // Number of parameters in exception record
  87. #endif
  88. #ifdef ALLOW_UNWIND_ABORT
  89. #define EH_ABORT_FRAME_UNWIND_PART EH_EXCEPTION_NUMBER+1
  90. #endif
  91. #define EH_EMPTY_STATE -1
  92. #ifndef ONLY_VALUES
  93. //
  94. // PMD - Pointer to Member Data: generalized pointer-to-member descriptor
  95. //
  96. typedef struct PMD
  97. {
  98. #if defined(_WIN64) /*IFSTRIP=IGN*/
  99. __int32 mdisp; // Offset of intended data within base
  100. __int32 pdisp; // Displacement to virtual base pointer
  101. __int32 vdisp; // Index within vbTable to offset of base
  102. #else
  103. ptrdiff_t mdisp; // Offset of intended data within base
  104. ptrdiff_t pdisp; // Displacement to virtual base pointer
  105. ptrdiff_t vdisp; // Index within vbTable to offset of base
  106. #endif
  107. } PMD;
  108. //
  109. // PMFN - Pointer to Member Function
  110. // M00REVIEW: we may need something more than this, but this will do for now.
  111. //
  112. #ifndef WANT_NO_TYPES
  113. #if defined(_WIN64) /*IFSTRIP=IGN*/
  114. #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(VERSP_P7) /*IFSTRIP=IGN*/
  115. typedef __int32 PMFN; // Image relative offset of Member Function
  116. #else
  117. typedef void (* __ptr64 PMFN)(void* __ptr64);
  118. #endif
  119. #else
  120. typedef void (*PMFN)(void);
  121. #endif
  122. #endif // WANT_NO_TYPES
  123. //
  124. // TypeDescriptor - per-type record which uniquely identifies the type.
  125. //
  126. // Each type has a decorated name which uniquely identifies it, and a hash
  127. // value which is computed by the compiler. The hash function used is not
  128. // important; the only thing which is essential is that it be the same for
  129. // all time.
  130. //
  131. // The special type '...' (ellipsis) is represented by a null name.
  132. //
  133. #pragma warning(disable:4200) // get rid of obnoxious nonstandard extension warning
  134. #if defined(_M_ALPHA64) || defined(_M_IA64) || defined(VERSP_P7) || defined(_M_AMD64)
  135. #pragma pack(push, TypeDescriptor, 8)
  136. #endif
  137. #ifndef WANT_NO_TYPES
  138. typedef struct TypeDescriptor
  139. {
  140. #if defined(_WIN64) /*IFSTRIP=IGN*/
  141. const void * __ptr64 pVFTable; // Field overloaded by RTTI
  142. void * __ptr64 spare; // reserved, possible for RTTI
  143. #else // _WIN64
  144. #if defined(_RTTI)
  145. const void * pVFTable; // Field overloaded by RTTI
  146. #else
  147. DWORD hash; // Hash value computed from type's decorated name
  148. #endif
  149. void * spare; // reserved, possible for RTTI
  150. #endif // _WIN64
  151. char name[]; // The decorated name of the type; 0 terminated.
  152. } TypeDescriptor;
  153. #endif // WANT_NO_TYPES
  154. #if defined(_M_ALPHA64) || defined(_M_IA64) || defined(VERSP_P7) || defined(_M_AMD64)
  155. #pragma pack(pop, TypeDescriptor)
  156. #endif
  157. #pragma warning(default:4200)
  158. #define TD_HASH(td) ((td).hash)
  159. #define TD_NAME(td) ((td).name)
  160. #define TD_IS_TYPE_ELLIPSIS(td) ((td == NULL) || (TD_NAME(*td)[0] == '\0'))
  161. #ifndef _EHDATA_NOTHROW
  162. /////////////////////////////////////////////////////////////////////////////
  163. //
  164. // Description of the thrown object. (M00REVIEW: not final)
  165. //
  166. // This information is broken down into three levels, to allow for maximum
  167. // comdat folding (at the cost of some extra pointers).
  168. //
  169. // ThrowInfo is the head of the description, and contains information about
  170. // the particular variant thrown.
  171. // CatchableTypeArray is an array of pointers to type descriptors. It will
  172. // be shared between objects thrown by reference but with varying
  173. // qualifiers.
  174. // CatchableType is the description of an individual type, and how to effect
  175. // the conversion from a given type.
  176. //
  177. //---------------------------------------------------------------------------
  178. //
  179. // CatchableType - description of a type that can be caught.
  180. //
  181. // Note: although isSimpleType can be part of ThrowInfo, it is more
  182. // convenient for the run-time to have it here.
  183. //
  184. #ifndef WANT_NO_TYPES
  185. typedef const struct _s_CatchableType {
  186. unsigned int properties; // Catchable Type properties (Bit field)
  187. #if defined(_WIN64) /*IFSTRIP=IGN*/
  188. #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(VERSP_P7) /*IFSTRIP=IGN*/
  189. __int32 pType; // Image relative offset of TypeDescriptor
  190. #else
  191. TypeDescriptor * __ptr64 pType; // Pointer to the type descriptor for this type
  192. #endif
  193. #else
  194. TypeDescriptor *pType; // Pointer to the type descriptor for this type
  195. #endif
  196. PMD thisDisplacement; // Pointer to instance of catch type within
  197. // thrown object.
  198. int sizeOrOffset; // Size of simple-type object or offset into
  199. // buffer of 'this' pointer for catch object
  200. PMFN copyFunction; // Copy constructor or CC-closure
  201. } CatchableType;
  202. #endif // WANT_NO_TYPES
  203. #define CT_IsSimpleType 0x00000001 // type is a simple type
  204. #define CT_ByReferenceOnly 0x00000002 // type must be caught by reference
  205. #define CT_HasVirtualBase 0x00000004 // type is a class with virtual bases
  206. #define CT_PROPERTIES(ct) ((ct).properties)
  207. #if defined(_M_IA64) || defined(_M_AMD64)
  208. #define CT_PTD_IB(ct,ib) ((TypeDescriptor *)((ib) + (ct).pType))
  209. #define CT_COPYFUNC_IB(ct,ib) ((void (* __ptr64)(void* __ptr64))((ib) + (ct).copyFunction))
  210. #else
  211. #define CT_PTD(ct) ((ct).pType)
  212. #define CT_COPYFUNC(ct) ((ct).copyFunction)
  213. #endif
  214. #define CT_THISDISP(ct) ((ct).thisDisplacement)
  215. #define CT_SIZE(ct) ((ct).sizeOrOffset)
  216. #define CT_OFFSET(ct) ((ct).sizeOrOffset)
  217. #define CT_HASH(ct) (TD_HASH(*CT_PTD(ct)))
  218. #define CT_NAME(ct) (TD_NAME(*CT_PTD(ct)))
  219. #define SET_CT_ISSIMPLETYPE(ct) (CT_PROPERTIES(ct) |= CT_IsSimpleType)
  220. #define SET_CT_BYREFONLY(ct) (CT_PROPERTIES(ct) |= CT_ByReferenceOnly)
  221. #define SET_CT_HASVB(ct) (CT_PROPERTIES(ct) |= CT_HasVirtualBase)
  222. #define CT_ISSIMPLETYPE(ct) (CT_PROPERTIES(ct) & CT_IsSimpleType) // Is it a simple type?
  223. #define CT_BYREFONLY(ct) (CT_PROPERTIES(ct) & CT_ByReferenceOnly) // Must it be caught by reference?
  224. #define CT_HASVB(ct) (CT_PROPERTIES(ct) & CT_HasVirtualBase) // Is this type a class with virtual bases?
  225. //
  226. // CatchableTypeArray - array of pointers to catchable types, with length
  227. //
  228. #pragma warning(disable:4200) // get rid of obnoxious nonstandard extension warning
  229. #ifndef WANT_NO_TYPES
  230. typedef const struct _s_CatchableTypeArray {
  231. int nCatchableTypes;
  232. #if defined(_WIN64) /*IFSTRIP=IGN*/
  233. #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(VERSP_P7) /*IFSTRIP=IGN*/
  234. __int32 arrayOfCatchableTypes[]; // Image relative offset of Catchable Types
  235. #else
  236. CatchableType * __ptr64 arrayOfCatchableTypes[];
  237. #endif
  238. #else
  239. CatchableType *arrayOfCatchableTypes[];
  240. #endif
  241. } CatchableTypeArray;
  242. #endif // WANT_NO_TYPES
  243. #pragma warning(default:4200)
  244. //
  245. // ThrowInfo - information describing the thrown object, staticly built
  246. // at the throw site.
  247. //
  248. // pExceptionObject (the dynamic part of the throw; see below) is always a
  249. // reference, whether or not it is logically one. If 'isSimpleType' is true,
  250. // it is a reference to the simple type, which is 'size' bytes long. If
  251. // 'isReference' and 'isSimpleType' are both false, then it's a UDT or
  252. // a pointer to any type (ie pExceptionObject points to a pointer). If it's
  253. // a pointer, copyFunction is NULL, otherwise it is a pointer to a copy
  254. // constructor or copy constructor closure.
  255. //
  256. // The pForwardCompat function pointer is intended to be filled in by future
  257. // versions, so that if say a DLL built with a newer version (say C10) throws,
  258. // and a C9 frame attempts a catch, the frame handler attempting the catch (C9)
  259. // can let the version that knows all the latest stuff do the work.
  260. //
  261. #ifndef WANT_NO_TYPES
  262. typedef const struct _s_ThrowInfo {
  263. unsigned int attributes; // Throw Info attributes (Bit field)
  264. PMFN pmfnUnwind; // Destructor to call when exception
  265. // has been handled or aborted.
  266. #if defined(_WIN64) /*IFSTRIP=IGN*/
  267. #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(VERSP_P7) /*IFSTRIP=IGN*/
  268. __int32 pForwardCompat; // Image relative offset of Forward compatibility frame handler
  269. __int32 pCatchableTypeArray;// Image relative offset of CatchableTypeArray
  270. #else
  271. int (__cdecl* __ptr64 pForwardCompat)(...); // Forward compatibility frame handler
  272. CatchableTypeArray * __ptr64 pCatchableTypeArray; // Pointer to list of pointers to types.
  273. #endif
  274. #else
  275. int (__cdecl*pForwardCompat)(...); // Forward compatibility frame handler
  276. CatchableTypeArray *pCatchableTypeArray; // Pointer to list of pointers to types.
  277. #endif
  278. } ThrowInfo;
  279. #endif // WANT_NO_TYPES
  280. #define TI_IsConst 0x00000001 // thrown object has const qualifier
  281. #define TI_IsVolatile 0x00000002 // thrown object has volatile qualifier
  282. #define TI_IsUnaligned 0x00000004 // thrown object has unaligned qualifier
  283. #define THROW_ATTRS(t) ((t).attributes)
  284. #if defined(_M_IA64) || defined(_M_AMD64)
  285. #define THROW_UNWINDFUNC_IB(t,ib) ((void (* __ptr64)(void* __ptr64))((ib) + (t).pmfnUnwind))
  286. #define THROW_FORWARDCOMPAT_IB(t,ib) ((int(__cdecl * __ptr64)(...))((ib) + (t).pForwardCompat))
  287. #define THROW_CTARRAY_IB(t,ib) ((CatchableTypeArray*)((ib) + (t).pCatchableTypeArray))
  288. #define THROW_COUNT_IB(t,ib) (THROW_CTARRAY_IB(t,ib)->nCatchableTypes)
  289. #define THROW_CTLIST_IB(t,ib) (THROW_CTARRAY_IB(t,ib)->arrayOfCatchableTypes)
  290. #else
  291. #define THROW_FORWARDCOMPAT(t) ((t).pForwardCompat)
  292. #define THROW_COUNT(t) ((t).pCatchableTypeArray->nCatchableTypes)
  293. #define THROW_CTLIST(t) ((t).pCatchableTypeArray->arrayOfCatchableTypes)
  294. #endif
  295. #define THROW_UNWINDFUNC(t) ((t).pmfnUnwind)
  296. #define THROW_PCTLIST(t) (&THROW_CTLIST(t))
  297. #define THROW_CT(t, n) (*THROW_CTLIST(t)[n])
  298. #define THROW_PCT(t, n) (THROW_CTLIST(t)[n])
  299. #define SET_TI_ISCONST(t) (THROW_ATTRS(t) |= TI_IsConst) // Is the object thrown 'const' qualified
  300. #define SET_TI_ISVOLATILE(t) (THROW_ATTRS(t) |= TI_IsVolatile) // Is the object thrown 'volatile' qualified
  301. #define SET_TI_ISUNALIGNED(t) (THROW_ATTRS(t) |= TI_IsUnaligned) // Is the object thrown 'unaligned' qualified
  302. #define THROW_ISCONST(t) (THROW_ATTRS(t) & TI_IsConst)
  303. #define THROW_ISVOLATILE(t) (THROW_ATTRS(t) & TI_IsVolatile)
  304. #define THROW_ISUNALIGNED(t) (THROW_ATTRS(t) & TI_IsUnaligned)
  305. //
  306. // Here's how to throw:
  307. // M00HACK: _ThrowInfo is the name of the type that is 'pre-injected' into the
  308. // compiler; since this prototype is known to the FE along with the pre-injected
  309. // types, it has to match exactly.
  310. //
  311. #if _MSC_VER >= 900 /*IFSTRIP=IGN*/
  312. __declspec (noreturn) extern "C" void __stdcall _CxxThrowException(void* pExceptionObject, _ThrowInfo* pThrowInfo);
  313. #else
  314. // If we're not self-building, we need to use the name that we defined above.
  315. __declspec (noreturn) extern "C" void __stdcall _CxxThrowException(void* pExceptionObject, ThrowInfo* pThrowInfo);
  316. #endif
  317. #ifndef WANT_NO_TYPES
  318. extern "C" int __cdecl __CxxExceptionFilter(void*, void*, int, void *);
  319. // Returns true if the object is really a C++ exception
  320. // If it is, stores the previous exception in *storage, and saves the current one
  321. // This is needed to keep track of the current exception object (used for rethrow & destruction)
  322. extern "C" int __cdecl __CxxRegisterExceptionObject(void *exception, void *storage);
  323. // Returns true if exception is a C++ rethrown exception
  324. // This is needed, so Unregister can know whether or not to destroy the object
  325. extern "C" int __cdecl __CxxDetectRethrow(void *exception);
  326. // Returns the byte count of stack space required to store the exception info
  327. extern "C" int __cdecl __CxxQueryExceptionSize(void);
  328. // Pops the current exception, restoring the previous one from *storage
  329. // This detects whether or not the exception object needs to be destroyed
  330. extern "C" void __cdecl __CxxUnregisterExceptionObject(void *storage, int rethrow);
  331. #endif // WANT_NO_TYPES
  332. #endif /* _EHDATA_NOTHROW */
  333. #ifndef _EHDATA_NOFUNCINFO
  334. /////////////////////////////////////////////////////////////////////////////
  335. //
  336. // Describing 'try/catch' blocks:
  337. //
  338. //---------------------------------------------------------------------------
  339. //
  340. // Current state of a function.
  341. // -1 is the 'blank' state, ie there is nothing to unwind, no try blocks active.
  342. //
  343. typedef int __ehstate_t; // The type of a state index
  344. //
  345. // HandlerType - description of a single 'catch'
  346. //
  347. #ifndef WANT_NO_TYPES
  348. typedef const struct _s_HandlerType {
  349. unsigned int adjectives; // Handler Type adjectives (bitfield)
  350. #if defined(_M_IA64) || defined(_M_AMD64) /*IFSTRIP=IGN*/
  351. __int32 dispType; // Image relative offset of the corresponding type descriptor
  352. __int32 dispCatchObj; // Displacement of catch object from base
  353. __int32 dispOfHandler; // Image relative offset of 'catch' code
  354. #if defined(_M_AMD64)
  355. __int32 dispFrame; // displacement of address of function frame wrt establisher frame
  356. #endif
  357. #else
  358. TypeDescriptor *pType; // Pointer to the corresponding type descriptor
  359. #if defined(_M_ALPHA64)
  360. __int32 dispCatchObj; // Displacement of catch object from base
  361. #else
  362. ptrdiff_t dispCatchObj; // Displacement of catch object from base
  363. #endif
  364. #if _M_MRX000 >= 4000 /*IFSTRIP=IGN*/
  365. ULONG frameNestLevel; // The static nesting level of parent function
  366. #endif
  367. void * addressOfHandler; // Address of 'catch' code
  368. #endif
  369. } HandlerType;
  370. #endif
  371. #define HT_IsConst 0x00000001 // type referenced is 'const' qualified
  372. #define HT_IsVolatile 0x00000002 // type referenced is 'volatile' qualified
  373. #define HT_IsUnaligned 0x00000004 // type referenced is 'unaligned' qualified
  374. #define HT_IsReference 0x00000008 // catch type is by reference
  375. #define HT_IsResumable 0x00000010 // the catch may choose to resume (Reserved)
  376. #define HT_IsComplusEh 0x80000000 // Is handling within complus eh.
  377. #define HT_ADJECTIVES(ht) ((ht).adjectives)
  378. #if defined(_M_IA64) || defined(_M_AMD64) /*IFSTRIP=IGN*/
  379. #define HT_PTD_IB(ht,ib) ((TypeDescriptor*)((ib) + (ht).dispType))
  380. #define HT_HANDLER_IB(ht,ib) ((void* __ptr64)((ib) + (ht).dispOfHandler))
  381. #else
  382. #define HT_PTD(ht) ((ht).pType)
  383. #define HT_HANDLER(ht) ((ht).addressOfHandler)
  384. #endif
  385. #define HT_DISPCATCH(ht) ((ht).dispCatchObj)
  386. #if _M_MRX000 >= 4000 /*IFSTRIP=IGN*/
  387. #define HT_FRAMENEST(ht) ((ht).frameNestLevel)
  388. #endif
  389. #define HT_NAME(ht) (TD_NAME(*HT_PTD(ht)))
  390. #define HT_HASH(ht) (TD_HASH(*HT_PTD(ht)))
  391. #define HT_IS_TYPE_ELLIPSIS(ht) TD_IS_TYPE_ELLIPSIS(HT_PTD(ht))
  392. #define SET_HT_ISCONST(ht) (HT_ADJECTIVES(ht) |= HT_IsConst)
  393. #define SET_HT_ISVOLATILE(ht) (HT_ADJECTIVES(ht) |= HT_IsVolatile)
  394. #define SET_HT_ISUNALIGNED(ht) (HT_ADJECTIVES(ht) |= HT_IsUnaligned)
  395. #define SET_HT_ISREFERENCE(ht) (HT_ADJECTIVES(ht) |= HT_IsReference)
  396. #define SET_HT_ISRESUMABLE(ht) (HT_ADJECTIVES(ht) |= HT_IsResumable)
  397. #define SET_HT_ISCOMPLUSEH(ht) (HT_ADJECTIVES(ht) |= HT_IsComplusEh)
  398. #define HT_ISCONST(ht) (HT_ADJECTIVES(ht) & HT_IsConst) // Is the type referenced 'const' qualified
  399. #define HT_ISVOLATILE(ht) (HT_ADJECTIVES(ht) & HT_IsVolatile) // Is the type referenced 'volatile' qualified
  400. #define HT_ISUNALIGNED(ht) (HT_ADJECTIVES(ht) & HT_IsUnaligned) // Is the type referenced 'unaligned' qualified
  401. #define HT_ISREFERENCE(ht) (HT_ADJECTIVES(ht) & HT_IsReference) // Is the catch type by reference
  402. #define HT_ISRESUMABLE(ht) (HT_ADJECTIVES(ht) & HT_IsResumable) // Might the catch choose to resume (Reserved)
  403. #define HT_ISCOMPLUSEH(ht) (HT_ADJECTIVES(ht) & HT_IsComplusEh)
  404. //
  405. // HandlerMapEntry - associates a handler list (sequence of catches) with a
  406. // range of eh-states.
  407. //
  408. #ifndef WANT_NO_TYPES
  409. typedef const struct _s_TryBlockMapEntry {
  410. __ehstate_t tryLow; // Lowest state index of try
  411. __ehstate_t tryHigh; // Highest state index of try
  412. #if !defined(_M_ALPHA)
  413. __ehstate_t catchHigh; // Highest state index of any associated catch
  414. #endif
  415. int nCatches; // Number of entries in array
  416. #if defined(_M_IA64) || defined(_M_AMD64) /*IFSTRIP=IGN*/
  417. __int32 dispHandlerArray; // Image relative offset of list of handlers for this try
  418. #else
  419. HandlerType *pHandlerArray; // List of handlers for this try
  420. #endif
  421. } TryBlockMapEntry;
  422. #endif // WANT_NO_TYPES
  423. #define TBME_LOW(hm) ((hm).tryLow)
  424. #define TBME_HIGH(hm) ((hm).tryHigh)
  425. #define TBME_CATCHHIGH(hm) ((hm).catchHigh)
  426. #define TBME_NCATCHES(hm) ((hm).nCatches)
  427. #if defined(_M_IA64) || defined(_M_AMD64) /*IFSTRIP=IGN*/
  428. #define TBME_PLIST(hm,ib) ((HandlerType*)((ib) + (hm).dispHandlerArray))
  429. #define TBME_CATCH(hm,n,ib) (TBME_PLIST(hm,ib)[n])
  430. #define TBME_PCATCH(hm,n,ib)(&(TBME_PLIST(hm,ib)[n]))
  431. #else
  432. #define TBME_PLIST(hm) ((hm).pHandlerArray)
  433. #define TBME_CATCH(hm, n) (TBME_PLIST(hm)[n])
  434. #define TBME_PCATCH(hm, n) (&(TBME_PLIST(hm)[n]))
  435. #endif
  436. /////////////////////////////////////////////////////////////////////////////
  437. //
  438. // Description of the function:
  439. //
  440. //---------------------------------------------------------------------------
  441. //
  442. // UnwindMapEntry - Description of each state transition for unwinding
  443. // the stack (ie destructing objects).
  444. //
  445. // The unwind map is an array, indexed by current state. Each entry specifies
  446. // the state to go to during unwind, and the action required to get there.
  447. // Note that states are represented by a signed integer, and that the 'blank'
  448. // state is -1 so that the array remains 0-based (because by definition there
  449. // is never any unwind action to be performed from state -1). It is also
  450. // assumed that state indices will be dense, ie that there will be no gaps of
  451. // unused state indices in a function.
  452. //
  453. typedef const struct _s_UnwindMapEntry {
  454. __ehstate_t toState; // State this action takes us to
  455. #if defined(_M_IA64) || defined(_M_AMD64) /*IFSTRIP=IGN*/
  456. __int32 action; // Image relative offset of funclet
  457. #else
  458. void (*action)(void); // Funclet to call to effect state change
  459. #endif
  460. } UnwindMapEntry;
  461. #define UWE_TOSTATE(uwe) ((uwe).toState)
  462. #if defined(_M_IA64) || defined(_M_AMD64)
  463. #define UWE_ACTION_IB(uwe,ib) ((void (*__ptr64)(void))((ib) + (uwe).action))
  464. #else
  465. #define UWE_ACTION(uwe) ((uwe).action)
  466. #endif
  467. #if _M_MRX000 >= 4000 || defined(_M_MPPC) || defined(_M_PPC) || defined(_M_IA64) || defined(_M_AMD64) /*IFSTRIP=IGN*/
  468. typedef struct IptoStateMapEntry {
  469. #if defined(_M_IA64) || defined(_M_AMD64) /*IFSTRIP=IGN*/
  470. __int32 Ip; // Image relative offset of IP
  471. #else
  472. ULONG Ip;
  473. #endif
  474. __ehstate_t State;
  475. } IptoStateMapEntry;
  476. #endif
  477. //
  478. // FuncInfo - all the information that describes a function with exception
  479. // handling information.
  480. //
  481. // bbtFlags values
  482. #define BBT_UNIQUE_FUNCINFO 1
  483. #ifndef WANT_NO_TYPES
  484. typedef const struct _s_FuncInfo
  485. {
  486. unsigned int magicNumber:29; // Identifies version of compiler
  487. unsigned int bbtFlags:3; // flags that may be set by BBT processing
  488. __ehstate_t maxState; // Highest state number plus one (thus
  489. // number of entries in unwind map)
  490. #if defined(_M_IA64) || defined (_M_AMD64) /*IFSTRIP=IGN*/
  491. __int32 dispUnwindMap; // Image relative offset of the unwind map
  492. unsigned int nTryBlocks; // Number of 'try' blocks in this function
  493. __int32 dispTryBlockMap; // Image relative offset of the handler map
  494. unsigned int nIPMapEntries; // # entries in the IP-to-state map. NYI (reserved)
  495. __int32 dispIPtoStateMap; // Image relative offset of the IP to state map
  496. __int32 dispUwindHelp; // Displacement of unwind helpers from base
  497. #else
  498. UnwindMapEntry *pUnwindMap; // Where the unwind map is
  499. unsigned int nTryBlocks; // Number of 'try' blocks in this function
  500. TryBlockMapEntry *pTryBlockMap; // Where the handler map is
  501. #if defined(_M_ALPHA)
  502. signed int EHContextDelta; // Frame offset of EHContext record
  503. #endif
  504. unsigned int nIPMapEntries; // # entries in the IP-to-state map. NYI (reserved)
  505. #if _M_MRX000 >= 4000 /*IFSTRIP=IGN*/
  506. IptoStateMapEntry *pIPtoStateMap; // An IP to state map..
  507. ptrdiff_t dispUnwindHelp; // Displacement of unwind helpers from base
  508. int iTryBlockIndex; // Used by catch functions only
  509. int iFrameNestLevel; // The static nesting level of parent function
  510. #elif defined(_M_MPPC) || defined(_M_PPC)
  511. IptoStateMapEntry *pIPtoStateMap; // An IP to state map..
  512. #else
  513. void *pIPtoStateMap; // An IP to state map. NYI (reserved).
  514. #endif
  515. #endif
  516. } FuncInfo;
  517. #endif // WANT_NO_TYPES
  518. #define FUNC_MAGICNUM(fi) ((fi).magicNumber)
  519. #define FUNC_MAXSTATE(fi) ((fi).maxState)
  520. #define FUNC_NTRYBLOCKS(fi) ((fi).nTryBlocks)
  521. #define FUNC_NIPMAPENT(fi) ((fi).nIPMapEntries)
  522. #if defined(_M_IA64) || defined (_M_AMD64)
  523. #define FUNC_PUNWINDMAP(fi,ib) ((UnwindMapEntry*)((ib) + (fi).dispUnwindMap))
  524. #define FUNC_PHANDLERMAP(fi,ib) ((TryBlockMapEntry*)((ib) + (fi).dispTryBlockMap))
  525. #define FUNC_IPMAP(fi,ib) ((IptoStateMapEntry*)((ib) + (fi).dispIPtoStateMap))
  526. #define FUNC_UNWIND(fi,st,ib) (FUNC_PUNWINDMAP(fi,ib)[st])
  527. #define FUNC_PUNWIND(fi,st,ib) (&FUNC_UNWIND(fi,st,ib))
  528. #define FUNC_TRYBLOCK(fi,n,ib) (FUNC_PHANDLERMAP(fi,ib)[n])
  529. #define FUNC_PTRYBLOCK(fi,n,ib) (&FUNC_TRYBLOCK(fi,n,ib))
  530. #else
  531. #define FUNC_PUNWINDMAP(fi) ((fi).pUnwindMap)
  532. #define FUNC_PHANDLERMAP(fi) ((fi).pTryBlockMap)
  533. #define FUNC_IPMAP(fi) ((fi).pIPtoStateMap)
  534. #define FUNC_UNWIND(fi, st) ((fi).pUnwindMap[st])
  535. #define FUNC_PUNWIND(fi, st) (&FUNC_UNWIND(fi, st))
  536. #define FUNC_TRYBLOCK(fi,n) ((fi).pTryBlockMap[n])
  537. #define FUNC_PTRYBLOCK(fi,n) (&FUNC_TRYBLOCK(fi, n))
  538. #endif
  539. #if defined(_M_ALPHA)
  540. #define FUNC_EHCONTEXTDELTA(fi) ((fi).EHContextDelta)
  541. #endif
  542. #if _M_MRX000 >= 4000 /*IFSTRIP=IGN*/
  543. #define FUNC_IPTOSTATE(fi,n) ((fi).pIPtoStateMap[n])
  544. #define FUNC_PIPTOSTATE(fi,n) (&FUNC_IPTOSTATE(fi,n))
  545. #define FUNC_DISPUNWINDHELP(fi) ((fi).dispUnwindHelp)
  546. #define FUNC_TRYBLOCKINDEX(fi) ((fi).iTryBlockIndex)
  547. #define FUNC_FRAMENEST(fi) ((fi).iFrameNestLevel)
  548. #elif defined(_M_MPPC) || defined(_M_PPC)
  549. #define FUNC_IPTOSTATE(fi,n) ((fi).pIPtoStateMap[n])
  550. #define FUNC_PIPTOSTATE(fi,n) (&FUNC_IPTOSTATE(fi,n))
  551. #elif defined(_M_IA64) || defined (_M_AMD64)
  552. #define FUNC_IPTOSTATE(fi,n,ib) (FUNC_IPMAP(fi,ib)[n])
  553. #define FUNC_PIPTOSTATE(fi,n,ib)(&FUNC_IPTOSTATE(fi,n,ib))
  554. #define FUNC_DISPUNWINDHELP(fi) ((fi).dispUwindHelp)
  555. #else
  556. #define FUNC_IPTOSTATE(fi,n) __ERROR_NYI__
  557. #endif
  558. #endif /* _EHDATA_NOFUNCINFO */
  559. #ifndef _EHDATA_NONT
  560. /////////////////////////////////////////////////////////////////////////////
  561. //
  562. // Data types that are variants of data used by NT (and Chicago) to manage
  563. // exception handling.
  564. //
  565. //---------------------------------------------------------------------------
  566. /////////////////////////////////////////////////////////////////////////////
  567. //
  568. // A stack registration node (i386 only)
  569. //
  570. #if defined(_M_IX86) && _M_IX86 >= 300 /*IFSTRIP=IGN*/
  571. struct EHRegistrationNode {
  572. /* void * stackPtr */ // Stack ptr at entry to try (below address point)
  573. EHRegistrationNode *pNext; // Next node in the chain
  574. void * frameHandler; // The handler function for this frame
  575. __ehstate_t state; // The current state of this function
  576. #if CC_EXPLICITFRAME
  577. void * frame; // Value of ebp for this frame
  578. #endif
  579. };
  580. #if !CC_EXPLICITFRAME
  581. // Cannonical offset
  582. # define FRAME_OFFSET sizeof(EHRegistrationNode)
  583. #endif
  584. #define PRN_NEXT(prn) ((prn)->pNext)
  585. #define PRN_HANDLER(prn) ((prn)->frameHandler)
  586. #define PRN_STATE(prn) ((prn)->state)
  587. #define PRN_STACK(prn) (((void**)(prn))[-1])
  588. #if CC_EXPLICITFRAME
  589. # define PRN_FRAME(prn) ((prn)->frame)
  590. #else
  591. # define PRN_FRAME(prn) ((void*)(((char*)prn) + FRAME_OFFSET))
  592. #endif
  593. typedef void DispatcherContext; // Meaningless on Intel
  594. #elif _M_MRX000 >= 4000 /*IFSTRIP=IGN*/
  595. //
  596. // On MIPS we don't have a registration node, just a pointer to the stack frame base
  597. //
  598. typedef ULONG EHRegistrationNode;
  599. #define PRN_NEXT(prn) __ERROR__
  600. #define PRN_HANDLER(prn) __ERROR__
  601. #define PRN_STATE(prn) __ERROR__
  602. #define PRN_STACK(prn) __ERROR__
  603. #define PRN_FRAME(prn) __ERROR__
  604. #define FRAME_OFFSET 0
  605. #if !defined(_NTSUBSET_)
  606. typedef struct _RUNTIME_FUNCTION {
  607. ULONG BeginAddress;
  608. ULONG EndAddress;
  609. EXCEPTION_DISPOSITION (*ExceptionHandler)();
  610. PVOID HandlerData;
  611. ULONG PrologEndAddress;
  612. } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
  613. #endif
  614. typedef struct _xDISPATCHER_CONTEXT {
  615. ULONG ControlPc;
  616. PRUNTIME_FUNCTION FunctionEntry;
  617. ULONG EstablisherFrame;
  618. PCONTEXT ContextRecord;
  619. } DispatcherContext; // changed the case of the name to conform to EH conventions
  620. #elif defined(_M_IA64) /*IFSTRIP=IGN*/
  621. #define PRN_NEXT(prn) __ERROR__
  622. #define PRN_HANDLER(prn) __ERROR__
  623. #define PRN_STATE(prn) __ERROR__
  624. #define PRN_STACK(prn) __ERROR__
  625. #define PRN_FRAME(prn) __ERROR__
  626. #define FRAME_OFFSET 0
  627. #if !defined(_NTSUBSET_)
  628. typedef struct _FRAME_POINTERS {
  629. __int64 MemoryStackFp; // memory stack frame pointer
  630. __int64 BackingStoreFp; // backing store frame pointer
  631. } FRAME_POINTERS, *PFRAME_POINTERS;
  632. typedef struct _UNWIND_INFO {
  633. unsigned __int16 Version; // Version Number
  634. unsigned __int16 Flags; // Flags
  635. unsigned __int32 DataLength; // Length of Descriptor Data
  636. } UNWIND_INFO, *PUNWIND_INFO;
  637. typedef struct _RUNTIME_FUNCTION {
  638. unsigned __int32 BeginAddress; // image relative offset to start of function
  639. unsigned __int32 EndAddress; // image relative offset to end of function
  640. unsigned __int32 UnwindInfoAddress; // image relative offset to unwind info block
  641. } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
  642. #endif
  643. typedef struct _xDISPATCHER_CONTEXT {
  644. FRAME_POINTERS EstablisherFrame;
  645. __int64 ControlPc;
  646. __int64 ImageBase;
  647. PRUNTIME_FUNCTION FunctionEntry;
  648. PCONTEXT ContextRecord;
  649. } DispatcherContext; // changed the case of the name to conform to EH conventions
  650. //
  651. // On P7 we don't have a registration node, just a pointer to the stack frame base
  652. //
  653. typedef FRAME_POINTERS EHRegistrationNode;
  654. #elif defined(_M_AMD64)/*IFSTRIP=IGN*/
  655. #define PRN_NEXT(prn) __ERROR__
  656. #define PRN_HANDLER(prn) __ERROR__
  657. #define PRN_STATE(prn) __ERROR__
  658. #define PRN_STACK(prn) __ERROR__
  659. #define PRN_FRAME(prn) __ERROR__
  660. #define FRAME_OFFSET 0
  661. #if !defined(_NTSUBSET_)
  662. typedef union _UNWIND_CODE {
  663. struct {
  664. unsigned char CodeOffset;
  665. unsigned char UnwindOp : 4;
  666. unsigned char OpInfo : 4;
  667. };
  668. unsigned short FrameOffset;
  669. } UNWIND_CODE, *PUNWIND_CODE;
  670. typedef struct _UNWIND_INFO {
  671. unsigned char Version : 3; // Version Number
  672. unsigned char Flags : 5; // Flags
  673. unsigned char SizeOfProlog;
  674. unsigned char CountOfCodes;
  675. unsigned FrameRegister : 4;
  676. unsigned FrameOffset : 4;
  677. UNWIND_CODE UnwindCode[1];
  678. /* UNWIND_CODE MoreUnwindCode[((CountOfCodes+1)&~1)-1];
  679. * union {
  680. * OPTIONAL ULONG ExceptionHandler;
  681. * OPTIONAL ULONG FunctionEntry;
  682. * };
  683. * OPTIONAL ULONG ExceptionData[];
  684. */
  685. } UNWIND_INFO, *PUNWIND_INFO;
  686. typedef struct _RUNTIME_FUNCTION {
  687. unsigned __int32 BeginAddress; // image relative offset to start of function
  688. unsigned __int32 EndAddress; // image relative offset to end of function
  689. unsigned __int32 UnwindInfoAddress; // image relative offset to unwind info block
  690. } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
  691. #endif
  692. typedef struct _xDISPATCHER_CONTEXT {
  693. __int64 ControlPc;
  694. __int64 ImageBase;
  695. PRUNTIME_FUNCTION FunctionEntry;
  696. ULONG_PTR EstablisherFrame;
  697. ULONG64 TargetIp;
  698. PCONTEXT ContextRecord;
  699. PVOID LanguageHandler;
  700. PVOID HandlerData;
  701. PVOID HistoryTable;
  702. } DispatcherContext; // changed the case of the name to conform to EH conventions
  703. //
  704. // On P7 we don't have a registration node, just a pointer to the stack frame base
  705. //
  706. typedef ULONG_PTR EHRegistrationNode;
  707. #elif defined(_M_ALPHA)
  708. //
  709. // On Alpha we don't have a registration node,
  710. // just a pointer to the stack frame base
  711. //
  712. typedef ULONG_PTR EHRegistrationNode;
  713. #define PRN_NEXT(prn) __ERROR__
  714. #define PRN_HANDLER(prn) __ERROR__
  715. #define PRN_STATE(prn) __ERROR__
  716. #define PRN_STACK(prn) __ERROR__
  717. #define PRN_FRAME(prn) __ERROR__
  718. #if defined(_M_ALPHA64) /*IFSTRIP=IGN*/
  719. #pragma pack(push, EHContext, 8)
  720. #endif
  721. #define FRAME_OFFSET 0
  722. #if !defined(_NTSUBSET_)
  723. typedef struct _RUNTIME_FUNCTION {
  724. ULONG_PTR BeginAddress;
  725. ULONG_PTR EndAddress;
  726. EXCEPTION_DISPOSITION (*ExceptionHandler)();
  727. PVOID HandlerData; // ptr to FuncInfo record
  728. ULONG_PTR PrologEndAddress;
  729. } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
  730. #endif
  731. typedef struct _xDISPATCHER_CONTEXT {
  732. ULONG_PTR ControlPc;
  733. PRUNTIME_FUNCTION FunctionEntry;
  734. ULONG_PTR EstablisherFrame; // Virtual Frame Pointer
  735. PCONTEXT ContextRecord;
  736. } DispatcherContext; // changed the case of the name to conform to EH conventions
  737. //
  738. // _EHCONTEXT is a struct built in the frame by the compiler.
  739. // On entry to a function, compiler generated code stores the
  740. // address of the base of the fixed frame area (the so-called
  741. // Real Frame Pointer) into the Rfp. On every state transition,
  742. // compiler generated code stores the current state index into
  743. // the State field.
  744. //
  745. // The FuncInfo record for the function contains the offset of
  746. // the _EHCONTEXT record from the Virtual Frame Pointer - a
  747. // pointer to the highest address of the frame so this offset
  748. // is negative (frames grow down in the address space).
  749. //
  750. typedef struct _EHCONTEXT {
  751. ULONG State;
  752. PVOID Rfp;
  753. } EHContext;
  754. #if defined(_M_ALPHA64) /*IFSTRIP=IGN*/
  755. #pragma pack(pop, EHContext)
  756. #endif
  757. #define VIRTUAL_FP(pDC) (pDC->EstablisherFrame)
  758. #define REAL_FP(VirtualFP, pFuncInfo) \
  759. (((EHContext *)((char *)VirtualFP \
  760. + pFuncInfo->EHContextDelta)) -> Rfp)
  761. #define EH_STATE(VirtualFP, pFuncInfo) \
  762. (((EHContext *)((char *)VirtualFP \
  763. + pFuncInfo->EHContextDelta)) -> State)
  764. #elif defined(_M_M68K)
  765. struct EHRegistrationNode {
  766. /* void * _sp; // The stack pointer for the entry of try/catch */
  767. void * frameHandler; // The handler function for this frame
  768. __ehstate_t state; // The current state of this function
  769. };
  770. #define PRN_HANDLER(prn) ((prn)->frameHandler)
  771. #define PRN_STATE(prn) ((prn)->state)
  772. typedef void DispatcherContext; // Meaningless on Mac
  773. #elif defined(_M_PPC) || defined(_M_MPPC)
  774. //
  775. // On PowerPC we don't have a registration node, just a pointer to the stack
  776. // frame base
  777. //
  778. typedef ULONG EHRegistrationNode;
  779. #define PRN_NEXT(prn) __ERROR__
  780. #define PRN_HANDLER(prn) __ERROR__
  781. #define PRN_STATE(prn) __ERROR__
  782. #define PRN_STACK(prn) __ERROR__
  783. #define PRN_FRAME(prn) __ERROR__
  784. #define FRAME_OFFSET 0
  785. #if !defined(_NTSUBSET_)
  786. typedef struct _RUNTIME_FUNCTION {
  787. ULONG BeginAddress;
  788. ULONG EndAddress;
  789. EXCEPTION_DISPOSITION (*ExceptionHandler)(...);
  790. PVOID HandlerData;
  791. ULONG PrologEndAddress;
  792. } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
  793. #endif
  794. typedef struct _xDISPATCHER_CONTEXT {
  795. ULONG ControlPc;
  796. PRUNTIME_FUNCTION FunctionEntry;
  797. ULONG EstablisherFrame;
  798. PCONTEXT ContextRecord;
  799. } DispatcherContext;
  800. // changed the case of the name to conform to EH conventions
  801. #if defined(_M_MPPC)
  802. typedef struct _ftinfo {
  803. ULONG dwMagicNumber; // magic number
  804. void *pFrameInfo; // pointer to runtime frame info
  805. PRUNTIME_FUNCTION rgFuncTable; // function table
  806. ULONG cFuncTable; // number of function entry
  807. ULONG dwEntryCF; // address of starting of the code fragment
  808. ULONG dwSizeCF; // size of the code fragment
  809. } FTINFO, *PFTINFO;
  810. #define offsFTINFO 64
  811. #endif
  812. #else
  813. #error "Machine not supported"
  814. #endif
  815. /////////////////////////////////////////////////////////////////////////////
  816. //
  817. // The NT Exception record that we use to pass information from the throw to
  818. // the possible catches.
  819. //
  820. // The constants in the comments are the values we expect.
  821. // This is based on the definition of EXCEPTION_RECORD in winnt.h.
  822. //
  823. #if defined(_M_IA64) || defined(_M_ALPHA64) || defined(_M_AMD64) /*IFSTRIP=IGN*/
  824. #pragma pack(push, ExceptionRecord, 8)
  825. #endif
  826. #ifndef WANT_NO_TYPES
  827. typedef struct EHExceptionRecord {
  828. DWORD ExceptionCode; // The code of this exception. (= EH_EXCEPTION_NUMBER)
  829. DWORD ExceptionFlags; // Flags determined by NT
  830. struct _EXCEPTION_RECORD *ExceptionRecord; // An extra exception record (not used)
  831. void * ExceptionAddress; // Address at which exception occurred
  832. DWORD NumberParameters; // Number of extended parameters. (= EH_EXCEPTION_PARAMETERS)
  833. struct EHParameters {
  834. DWORD magicNumber; // = EH_MAGIC_NUMBER1
  835. void * pExceptionObject; // Pointer to the actual object thrown
  836. ThrowInfo *pThrowInfo; // Description of thrown object
  837. #if defined(_M_IA64) || defined(_M_AMD64)
  838. void *pThrowImageBase; // Image base of thrown object
  839. #endif
  840. } params;
  841. } EHExceptionRecord;
  842. #endif // WANT_NO_TYPES
  843. #if defined(_M_IA64) || defined(_M_ALPHA64) || defined(_M_AMD64) /*IFSTRIP=IGN*/
  844. #pragma pack(pop, ExceptionRecord)
  845. #endif
  846. #define PER_CODE(per) ((per)->ExceptionCode)
  847. #define PER_FLAGS(per) ((per)->ExceptionFlags)
  848. #define PER_NEXT(per) ((per)->ExceptionRecord)
  849. #define PER_ADDRESS(per) ((per)->ExceptionAddress)
  850. #define PER_NPARAMS(per) ((per)->NumberParameters)
  851. #define PER_MAGICNUM(per) ((per)->params.magicNumber)
  852. #define PER_PEXCEPTOBJ(per) ((per)->params.pExceptionObject)
  853. #define PER_PTHROW(per) ((per)->params.pThrowInfo)
  854. #if defined(_M_IA64) || defined(_M_AMD64)
  855. #define PER_PTHROWIB(per) ((per)->params.pThrowImageBase)
  856. #endif
  857. #define PER_THROW(per) (*PER_PTHROW(per))
  858. #define PER_ISSIMPLETYPE(t) (PER_THROW(t).isSimpleType)
  859. #define PER_ISREFERENCE(t) (PER_THROW(t).isReference)
  860. #define PER_ISCONST(t) (PER_THROW(t).isConst)
  861. #define PER_ISVOLATILE(t) (PER_THROW(t).isVolatile)
  862. #define PER_ISUNALIGNED(t) (PER_THROW(t).isUnaligned)
  863. #define PER_UNWINDFUNC(t) (PER_THROW(t).pmfnUnwind)
  864. #define PER_PCTLIST(t) (PER_THROW(t).pCatchable)
  865. #define PER_CTLIST(t) (*PER_PCTLIST(t))
  866. #define PER_IS_MSVC_EH(per) ((PER_CODE(per) == EH_EXCEPTION_NUMBER) && \
  867. (PER_NPARAMS(per) == EH_EXCEPTION_PARAMETERS) && \
  868. (PER_MAGICNUM(per) == EH_MAGIC_NUMBER1))
  869. /////////////////////////////////////////////////////////////////////////////
  870. //
  871. // NT kernel routines and definitions required to implement exception handling:
  872. //
  873. // (from ntxcapi.h, which is not a public header file)
  874. //
  875. //---------------------------------------------------------------------------
  876. #ifndef _NTXCAPI_
  877. // begin_ntddk
  878. //
  879. // Exception flag definitions.
  880. //
  881. // begin_winnt
  882. #define EXCEPTION_NONCONTINUABLE 0x1 // Noncontinuable exception
  883. // end_winnt
  884. // end_ntddk
  885. #define EXCEPTION_UNWINDING 0x2 // Unwind is in progress
  886. #define EXCEPTION_EXIT_UNWIND 0x4 // Exit unwind is in progress
  887. #define EXCEPTION_STACK_INVALID 0x8 // Stack out of limits or unaligned
  888. #define EXCEPTION_NESTED_CALL 0x10 // Nested exception handler call
  889. #define EXCEPTION_TARGET_UNWIND 0x20 // Target unwind in progress
  890. #define EXCEPTION_COLLIDED_UNWIND 0x40 // Collided exception handler call
  891. #define EXCEPTION_UNWIND (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND | \
  892. EXCEPTION_TARGET_UNWIND | EXCEPTION_COLLIDED_UNWIND)
  893. #define IS_UNWINDING(Flag) ((Flag & EXCEPTION_UNWIND) != 0)
  894. #define IS_DISPATCHING(Flag) ((Flag & EXCEPTION_UNWIND) == 0)
  895. #define IS_TARGET_UNWIND(Flag) (Flag & EXCEPTION_TARGET_UNWIND)
  896. #define IS_EXIT_UNWIND(Flag) (Flag & EXCEPTION_EXIT_UNWIND)
  897. #if !defined(_M_M68K)
  898. #ifdef __cplusplus
  899. extern "C" {
  900. #endif
  901. void WINAPI
  902. RtlUnwind (
  903. IN void * TargetFrame OPTIONAL,
  904. IN void * TargetIp OPTIONAL,
  905. IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
  906. IN void * ReturnValue
  907. );
  908. #if defined(_M_IA64) /*IFSTRIP=IGN*/
  909. #define STATUS_LONGJUMP 0x80000026
  910. RtlUnwind2 (
  911. IN FRAME_POINTERS TargetFrame OPTIONAL,
  912. IN void * TargetIp OPTIONAL,
  913. IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
  914. IN void * ReturnValue,
  915. IN PCONTEXT ContextRecord
  916. );
  917. PRUNTIME_FUNCTION
  918. RtlLookupFunctionEntry (
  919. unsigned __int64 ControlPc,
  920. unsigned __int64 *ImageBase,
  921. unsigned __int64 *TargetGp
  922. );
  923. #elif defined(_M_AMD64) /*IFSTRIP=IGN*/
  924. #define STATUS_LONGJUMP 0x80000026
  925. RtlUnwindEx (
  926. IN void * TargetFrame OPTIONAL,
  927. IN void * TargetIp OPTIONAL,
  928. IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
  929. IN void * ReturnValue,
  930. IN PCONTEXT ContextRecord,
  931. IN void *HistoryTable
  932. );
  933. PRUNTIME_FUNCTION
  934. RtlLookupFunctionEntry (
  935. unsigned __int64 ControlPc,
  936. unsigned __int64 *ImageBase,
  937. void *HistoryTable
  938. );
  939. VOID
  940. RtlRaiseException (
  941. IN PEXCEPTION_RECORD ExceptionRecord
  942. );
  943. #endif
  944. #if defined(_M_ALPHA)
  945. #define STATUS_UNWIND 0xc0000027
  946. void WINAPI
  947. RtlUnwindRfp (
  948. IN void * TargetRealFrame OPTIONAL,
  949. IN void * TargetIp OPTIONAL,
  950. IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
  951. IN void * ReturnValue
  952. );
  953. #endif
  954. #if defined(_M_PPC)
  955. ULONG WINAPI
  956. RtlVirtualUnwind (
  957. IN ULONG ControlPc,
  958. IN PRUNTIME_FUNCTION FunctionEntry,
  959. IN OUT PCONTEXT ContextRecord,
  960. OUT PBOOLEAN InFunction,
  961. OUT PULONG EstablisherFrame,
  962. IN OUT PVOID ContextPointers OPTIONAL,
  963. IN ULONG LowStackLimit,
  964. IN ULONG HighStackLimit
  965. );
  966. PRUNTIME_FUNCTION
  967. RtlLookupFunctionEntry (
  968. IN ULONG ControlPc
  969. );
  970. #endif
  971. #if defined(_M_MPPC)
  972. ULONG WINAPI
  973. RtlVirtualUnwind (
  974. IN ULONG ControlPc,
  975. IN PRUNTIME_FUNCTION FunctionEntry,
  976. IN OUT PCONTEXT ContextRecord,
  977. OUT PBOOLEAN InFunction,
  978. OUT PULONG EstablisherFrame,
  979. IN OUT PVOID ContextPointers OPTIONAL,
  980. IN ULONG LowStackLimit,
  981. IN ULONG HighStackLimit
  982. );
  983. PRUNTIME_FUNCTION
  984. RtlLookupFunctionEntry (
  985. IN PRUNTIME_FUNCTION RuntimeFunction,
  986. IN ULONG ControlPc,
  987. IN ULONG Rtoc
  988. );
  989. VOID
  990. RtlRaiseException (
  991. IN PEXCEPTION_RECORD ExceptionRecord
  992. );
  993. #endif
  994. #ifdef __cplusplus
  995. }
  996. #endif
  997. #endif
  998. #endif /* _NTXCAPI_ */
  999. #endif /* _EHDATA_NONT */
  1000. #endif /* ONLY_VALUES */
  1001. #pragma pack(pop, ehdata)
  1002. #endif /* _INC_EHDATA */