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.

328 lines
14 KiB

  1. /***
  2. *trnsctrl.h - routines that do special transfer of control
  3. *
  4. * Copyright (c) 1993-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Declaration of routines that do special transfer of control.
  8. * (and a few other implementation-dependant things).
  9. *
  10. * Implementations of these routines are in assembly (very implementation
  11. * dependant). Currently, these are implemented as naked functions with
  12. * inline asm.
  13. *
  14. * [Internal]
  15. *
  16. *Revision History:
  17. * 05-24-93 BS Module created.
  18. * 03-03-94 TL Added Mips (_M_MRX000 >= 4000) changes
  19. * 09-02-94 SKS This header file added.
  20. * 09-13-94 GJF Merged in changes from/for DEC Alpha (from Al Doser,
  21. * dated 6/21).
  22. * 10-09-94 BWT Add unknown machine merge from John Morgan
  23. * 02-14-95 CFW Clean up Mac merge.
  24. * 03-29-95 CFW Add error message to internal headers.
  25. * 04-11-95 JWM _CallSettingFrame() is now extern "C".
  26. * 12-14-95 JWM Add "#pragma once".
  27. * 02-24-97 GJF Detab-ed.
  28. * 06-01-97 TL Added P7 changes
  29. * 02-11-99 TL IA64: catch bug fix.
  30. * 05-17-99 PML Remove all Macintosh support.
  31. * 06-08-00 RDL VS#111429: IA64 workaround for AV while handling throw.
  32. * 06-05-01 GB AMD64 Eh support Added.
  33. *
  34. ****/
  35. #if _MSC_VER > 1000 /*IFSTRIP=IGN*/
  36. #pragma once
  37. #endif
  38. #ifndef _INC_TRNSCTRL
  39. #define _INC_TRNSCTRL
  40. #ifndef _CRTBLD
  41. /*
  42. * This is an internal C runtime header file. It is used when building
  43. * the C runtimes only. It is not to be used as a public header file.
  44. */
  45. #error ERROR: Use of C runtime library internal header file.
  46. #endif /* _CRTBLD */
  47. #if _M_MRX000 >= 4000 /*IFSTRIP=IGN*/
  48. typedef struct FrameInfo {
  49. PULONG pEstablisherFrame;
  50. PRUNTIME_FUNCTION pFunctionEntry;
  51. CONTEXT* pExitContext;
  52. struct FrameInfo *pNext;
  53. } FRAMEINFO;
  54. extern FRAMEINFO* _CreateFrameInfo(FRAMEINFO*, DispatcherContext*, PULONG, CONTEXT*);
  55. extern CONTEXT* _FindAndUnlinkFrame(PVOID, FRAMEINFO*);
  56. extern VOID _JumpToContinuation( ULONG, CONTEXT*);
  57. extern PVOID _OffsetToAddress( ptrdiff_t, PULONG, ULONG );
  58. extern "C" VOID _UnwindNestedFrames( EHRegistrationNode*, EHExceptionRecord*, CONTEXT* );
  59. extern "C" VOID _NLG_Notify( PVOID, PVOID );
  60. extern "C" PVOID _CallSettingFrame( PVOID, PULONG, ULONG );
  61. extern "C" PVOID _CallCatchBlock2( EHRegistrationNode*, FuncInfo*, PVOID, ULONG, ULONG );
  62. extern "C" BOOL _CallSETranslator( EHExceptionRecord*, EHRegistrationNode*, CONTEXT*, DispatcherContext*, FuncInfo*, ULONG, EHRegistrationNode*, ULONG);
  63. extern "C" VOID _EHRestoreContext(CONTEXT* pContext);
  64. extern "C" CONTEXT* _GetUnwindContext(VOID);
  65. extern "C" VOID _MoveContext(CONTEXT* pTarget, CONTEXT* pSource);
  66. extern TryBlockMapEntry *_GetRangeOfTrysToCheck(EHRegistrationNode *, FuncInfo *, int, __ehstate_t, unsigned *, unsigned *);
  67. #define _CallMemberFunction0(pthis, pmfn) (*(VOID(*)(PVOID))pmfn)(pthis)
  68. #define _CallMemberFunction1(pthis, pmfn, pthat) (*(VOID(*)(PVOID,PVOID))pmfn)(pthis,pthat)
  69. #define _CallMemberFunction2(pthis, pmfn, pthat, val2 ) (*(VOID(*)(PVOID,PVOID,int))pmfn)(pthis,pthat,val2)
  70. #define UNWINDHELP(base,offset,index) (((char*)base) + (int)offset)[index]
  71. #elif defined(_M_AMD64) /*IFSTRIP=IGN*/
  72. typedef struct FrameInfo {
  73. struct FrameInfo *pNext;
  74. PRUNTIME_FUNCTION pFunctionEntry;
  75. CONTEXT* pExitContext;
  76. PVOID pExceptionObjectDestroyed;
  77. PVOID pExceptionObjectToBeDestroyed;
  78. EHExceptionRecord *pExcept;
  79. __ehstate_t State;
  80. int dtorThrowFlag : 1;
  81. int isRethrow : 1;
  82. } FRAMEINFO;
  83. extern FRAMEINFO* _CreateFrameInfo(FRAMEINFO*, DispatcherContext*, CONTEXT*, __ehstate_t, PVOID, EHExceptionRecord*);
  84. extern CONTEXT* _FindAndUnlinkFrame(PVOID, FRAMEINFO*);
  85. extern void _UnlinkFrame(FRAMEINFO *pFrameInfo);
  86. extern void _MarkExceptionObjectDestroyed(EHExceptionRecord*);
  87. extern FRAMEINFO* _FindFrameInfo(PVOID, FRAMEINFO*);
  88. extern VOID _JumpToContinuation(unsigned __int64, CONTEXT*, EHExceptionRecord*);
  89. extern BOOL _ExecutionInCatch(DispatcherContext*, FuncInfo*);
  90. extern BOOL _IsExceptionObjectDestroyed(PVOID,FRAMEINFO*);
  91. extern VOID __FrameUnwindToEmptyState(EHRegistrationNode*, DispatcherContext*, FuncInfo*);
  92. extern "C" VOID _UnwindNestedFrames( EHRegistrationNode*, EHExceptionRecord*, CONTEXT* , DispatcherContext*);
  93. extern "C" PVOID _CallSettingFrame( void*, EHRegistrationNode*, ULONG );
  94. extern "C" BOOL _CallSETranslator( EHExceptionRecord*, EHRegistrationNode*, CONTEXT*, DispatcherContext*, FuncInfo*, ULONG, EHRegistrationNode*);
  95. extern "C" VOID _EHRestoreContext(CONTEXT* pContext);
  96. extern "C" VOID _SaveUnwindContext(CONTEXT* pContext);
  97. extern "C" CONTEXT* _GetUnwindContext(VOID);
  98. extern "C" unsigned __int64 _GetImageBase(VOID);
  99. extern "C" unsigned __int64 _GetThrowImageBase(VOID);
  100. extern "C" VOID _SetThrowImageBase(unsigned __int64 NewThrowImageBase);
  101. extern "C" VOID _MoveContext(CONTEXT* pTarget, CONTEXT* pSource);
  102. extern TryBlockMapEntry *_GetRangeOfTrysToCheck(EHRegistrationNode *, FuncInfo *, int, __ehstate_t, unsigned *, unsigned *, DispatcherContext*);
  103. extern EHRegistrationNode *_GetEstablisherFrame(EHRegistrationNode*, DispatcherContext*, FuncInfo*, EHRegistrationNode*);
  104. #define _CallMemberFunction0(pthis, pmfn) (*(VOID(*)(PVOID))pmfn)(pthis)
  105. #define _CallMemberFunction1(pthis, pmfn, pthat) (*(VOID(*)(PVOID,PVOID))pmfn)(pthis,pthat)
  106. #define _CallMemberFunction2(pthis, pmfn, pthat, val2 ) (*(VOID(*)(PVOID,PVOID,int))pmfn)(pthis,pthat,val2)
  107. #define OffsetToAddress( off, FP ) (void*)(((char*)FP) + off)
  108. #define UNWINDSTATE(base,offset) *((int*)((char*)base + offset))
  109. #define UNWINDTRYBLOCK(base,offset) *((int*)( (char*)(OffsetToAddress(offset,base)) + 4 ))
  110. #define UNWINDHELP(base,offset) *((__int64*)((char*)base + offset))
  111. #elif defined(_M_IA64) /*IFSTRIP=IGN*/
  112. typedef struct FrameInfo {
  113. struct FrameInfo *pNext;
  114. PRUNTIME_FUNCTION pFunctionEntry;
  115. CONTEXT* pExitContext;
  116. PVOID pExceptionObjectDestroyed;
  117. PVOID pExceptionObjectToBeDestroyed;
  118. EHExceptionRecord *pExcept;
  119. __ehstate_t State;
  120. int dtorThrowFlag : 1;
  121. int isRethrow : 1;
  122. } FRAMEINFO;
  123. extern FRAMEINFO* _CreateFrameInfo(FRAMEINFO*, DispatcherContext*, CONTEXT*, __ehstate_t, PVOID, EHExceptionRecord*);
  124. extern CONTEXT* _FindAndUnlinkFrame(PVOID, FRAMEINFO*);
  125. extern void _UnlinkFrame(FRAMEINFO *pFrameInfo);
  126. extern void _MarkExceptionObjectDestroyed(EHExceptionRecord*);
  127. extern FRAMEINFO* _FindFrameInfo(PVOID, FRAMEINFO*);
  128. extern VOID _JumpToContinuation(unsigned __int64, CONTEXT*, EHExceptionRecord*);
  129. extern BOOL _ExecutionInCatch(DispatcherContext*, FuncInfo*);
  130. extern BOOL _IsExceptionObjectDestroyed(PVOID,FRAMEINFO*);
  131. extern VOID __FrameUnwindToEmptyState(EHRegistrationNode*, DispatcherContext*, FuncInfo*);
  132. extern "C" VOID _UnwindNestedFrames( EHRegistrationNode*, EHExceptionRecord*, CONTEXT* );
  133. extern "C" PVOID _CallSettingFrame( void*, EHRegistrationNode*, ULONG );
  134. extern "C" BOOL _CallSETranslator( EHExceptionRecord*, EHRegistrationNode*, CONTEXT*, DispatcherContext*, FuncInfo*, ULONG, EHRegistrationNode*);
  135. extern "C" VOID _EHRestoreContext(CONTEXT* pContext);
  136. extern "C" VOID _SaveUnwindContext(CONTEXT* pContext);
  137. extern "C" CONTEXT* _GetUnwindContext(VOID);
  138. extern "C" unsigned __int64 _GetImageBase(VOID);
  139. extern "C" unsigned __int64 _GetThrowImageBase(VOID);
  140. extern "C" VOID _SetImageBase(unsigned __int64 ImageBaseToRestore);
  141. extern "C" VOID _SetThrowImageBase(unsigned __int64 NewThrowImageBase);
  142. extern "C" VOID _MoveContext(CONTEXT* pTarget, CONTEXT* pSource);
  143. extern TryBlockMapEntry *_GetRangeOfTrysToCheck(EHRegistrationNode *, FuncInfo *, int, __ehstate_t, unsigned *, unsigned *, DispatcherContext*);
  144. extern EHRegistrationNode *_GetEstablisherFrame(EHRegistrationNode*, DispatcherContext*, FuncInfo*, EHRegistrationNode*);
  145. #define _CallMemberFunction0(pthis, pmfn) (*(VOID(*)(PVOID))pmfn)(pthis)
  146. #define _CallMemberFunction1(pthis, pmfn, pthat) (*(VOID(*)(PVOID,PVOID))pmfn)(pthis,pthat)
  147. #define _CallMemberFunction2(pthis, pmfn, pthat, val2 ) (*(VOID(*)(PVOID,PVOID,int))pmfn)(pthis,pthat,val2)
  148. #define OffsetToAddress( off, FP ) (void*)(((char*)FP) + off)
  149. #define UNWINDSTATE(base,offset) *((int*)((char*)base + offset))
  150. #define UNWINDTRYBLOCK(base,offset) *((int*)( (char*)(OffsetToAddress(offset,base)) + 4 ))
  151. #define UNWINDHELP(base,offset) *((__int64*)((char*)base + offset))
  152. #elif defined(_M_ALPHA)
  153. //
  154. // For Debugger handling of stepping with non-local gotos
  155. //
  156. extern "C" VOID __NLG_Notify( PVOID, PVOID, ULONG );
  157. //
  158. // For calling funclets (including the catch)
  159. //
  160. extern "C" void * _CallSettingFrame (
  161. void *funcAddress,
  162. void *realFP,
  163. unsigned long NLGCode
  164. );
  165. extern void _JumpToContinuation(
  166. void *TargetIp, // The target address
  167. EHRegistrationNode *TargetFrame // The target virtual frame ptr
  168. );
  169. //
  170. // For calling member functions:
  171. //
  172. extern "C" void _CallMemberFunction0( void *pthis, void *pmfn );
  173. extern "C" void _CallMemberFunction1( void *pthis, void *pmfn, void *pthat );
  174. extern "C" void _CallMemberFunction2( void *pthis, void *pmfn, void *pthat, int val2 );
  175. //
  176. // Translate an frame relative offset to a hard address based on address of
  177. // a frame pointer (real or virtual).
  178. //
  179. #define OffsetToAddress( off, FP ) (void*)(((char*)FP) + off)
  180. //
  181. // Call RtlUnwind in a returning fashion
  182. //
  183. extern "C" VOID _UnwindNestedFrames (
  184. IN EHRegistrationNode *TargetFrame,
  185. IN EHExceptionRecord *ExceptionRecord
  186. );
  187. //
  188. // Ditto the SE translator
  189. //
  190. BOOL _CallSETranslator( EHExceptionRecord*, EHRegistrationNode*, void*,
  191. DispatcherContext*, FuncInfo*, int,
  192. EHRegistrationNode*);
  193. extern TryBlockMapEntry *_GetRangeOfTrysToCheck(FuncInfo *, int, __ehstate_t, unsigned *, unsigned *);
  194. #elif defined(_M_IX86) // x86
  195. //
  196. // For calling funclets (including the catch)
  197. //
  198. extern "C" void * __stdcall _CallSettingFrame( void *, EHRegistrationNode *, unsigned long );
  199. extern void __stdcall _JumpToContinuation( void *, EHRegistrationNode * );
  200. //
  201. // For calling member functions:
  202. //
  203. extern void __stdcall _CallMemberFunction0( void *pthis, void *pmfn );
  204. extern void __stdcall _CallMemberFunction1( void *pthis, void *pmfn, void *pthat );
  205. extern void __stdcall _CallMemberFunction2( void *pthis, void *pmfn, void *pthat, int val2 );
  206. //
  207. // Translate an ebp-relative offset to a hard address based on address of
  208. // registration node:
  209. //
  210. #if !CC_EXPLICITFRAME
  211. #define OffsetToAddress( off, RN ) \
  212. (void*)((char*)RN \
  213. + FRAME_OFFSET \
  214. + off)
  215. #else
  216. #define OffsetToAddress( off, RN ) (void*)(((char*)RN->frame) + off)
  217. #endif
  218. //
  219. // Call RtlUnwind in a returning fassion
  220. //
  221. extern void __stdcall _UnwindNestedFrames( EHRegistrationNode*, EHExceptionRecord* );
  222. //
  223. // Do the nitty-gritty of calling the catch block safely
  224. //
  225. void *_CallCatchBlock2( EHRegistrationNode *, FuncInfo*, void*, int, unsigned long );
  226. //
  227. // Link together all existing catch objects to determine when they should be destroyed
  228. //
  229. typedef struct FrameInfo {
  230. PVOID pExceptionObject;
  231. struct FrameInfo * pNext;
  232. } FRAMEINFO;
  233. extern FRAMEINFO * _CreateFrameInfo(FRAMEINFO*, PVOID);
  234. extern BOOL IsExceptionObjectToBeDestroyed(PVOID);
  235. extern void _FindAndUnlinkFrame(FRAMEINFO*);
  236. //
  237. // Ditto the SE translator
  238. //
  239. BOOL _CallSETranslator( EHExceptionRecord*, EHRegistrationNode*, void*, DispatcherContext*, FuncInfo*, int, EHRegistrationNode*);
  240. extern TryBlockMapEntry *_GetRangeOfTrysToCheck(FuncInfo *, int, __ehstate_t, unsigned *, unsigned *);
  241. #elif defined(_M_PPC)
  242. typedef struct FrameInfo {
  243. PULONG pEstablisherFrame;
  244. ULONG ControlPc;
  245. PRUNTIME_FUNCTION pFunctionEntry;
  246. CONTEXT *pExitContext;
  247. __ehstate_t state;
  248. struct FrameInfo *pNext;
  249. } FRAMEINFO;
  250. extern "C" PVOID _CallSettingFrame(PVOID, PULONG, ULONG);
  251. extern "C" VOID _GetStackLimits(PULONG, PULONG);
  252. extern EHRegistrationNode *_GetEstablisherFrame(DispatcherContext *, int *);
  253. extern FRAMEINFO *_CreateFrameInfo(FRAMEINFO *, DispatcherContext *, PULONG, CONTEXT *, __ehstate_t);
  254. extern "C" VOID _JumpToContinuation(ULONG, CONTEXT *);
  255. extern "C" VOID _UnwindNestedFrames(EHRegistrationNode *, EHExceptionRecord *, CONTEXT *);
  256. extern CONTEXT *_FindAndUnlinkFrame(PVOID, FRAMEINFO *);
  257. extern FRAMEINFO *_FindFrameInfo(ULONG, FRAMEINFO *);
  258. extern VOID __FrameUnwindToEmptyState(EHRegistrationNode *, DispatcherContext *, FuncInfo *);
  259. extern BOOL _UnwindNestedCatch(EHRegistrationNode *, DispatcherContext *);
  260. extern BOOL _CallSETranslator(EHExceptionRecord *, EHRegistrationNode *, CONTEXT *, DispatcherContext *, FuncInfo *, ULONG, EHRegistrationNode *);
  261. extern TryBlockMapEntry *_GetRangeOfTrysToCheck(FuncInfo *, int, __ehstate_t, unsigned *, unsigned *);
  262. #define OffsetToAddress(off, pRN) \
  263. ((void *)((char *)(pRN) + (off)))
  264. #define _CallMemberFunction0(pthis, pmfn) \
  265. (*(VOID(*)(PVOID))(pmfn))(pthis)
  266. #define _CallMemberFunction1(pthis, pmfn, pthat) \
  267. (*(VOID(*)(PVOID, PVOID))(pmfn))(pthis, pthat)
  268. #define _CallMemberFunction2(pthis, pmfn, pthat, val2) \
  269. (*(VOID(*)(PVOID, PVOID, int))(pmfn))(pthis, pthat, val2)
  270. #define TOC_LINK 2
  271. #define SET_UNWIND_FLAG(rTOC) ((rTOC) |= 1)
  272. #define CLEAR_UNWIND_FLAG(rTOC) ((rTOC) &= ~1)
  273. #define CHECK_UNWIND_FLAG(rTOC) (((rTOC) & 1) != 0)
  274. #define SET_UNWIND_FRAME(pRN) SET_UNWIND_FLAG(((PULONG)(pRN))[TOC_LINK])
  275. #define CHECK_UNWIND_FRAME(pRN) CHECK_UNWIND_FLAG(((PULONG)(pRN))[TOC_LINK])
  276. #else
  277. #pragma message("Special transfer of control routines not defined for this platform")
  278. #endif
  279. #endif /* _INC_TRNSCTRL */