Leaked source code of windows server 2003
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.

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