home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
crt
/
src
/
trnsctrl.h
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-17
|
11KB
|
260 lines
/***
*trnsctrl.h - routines that do special transfer of control
*
* Copyright (c) 1993-1997, Microsoft Corporation. All rights reserved.
*
*Purpose:
* Declaration of routines that do special transfer of control.
* (and a few other implementation-dependant things).
*
* Implementations of these routines are in assembly (very implementation
* dependant). Currently, these are implemented as naked functions with
* inline asm.
*
* [Internal]
*
****/
#if _MSC_VER > 1000
#pragma once
#endif /* _MSC_VER > 1000 */
#ifndef _INC_TRNSCTRL
#define _INC_TRNSCTRL
#ifndef _CRTBLD
/*
* This is an internal C runtime header file. It is used when building
* the C runtimes only. It is not to be used as a public header file.
*/
#error ERROR: Use of C runtime library internal header file.
#endif /* _CRTBLD */
#if _M_MRX000 >= 4000
typedef struct FrameInfo {
PULONG pEstablisherFrame;
PRUNTIME_FUNCTION pFunctionEntry;
CONTEXT* pExitContext;
struct FrameInfo *pNext;
} FRAMEINFO;
extern FRAMEINFO* _CreateFrameInfo(FRAMEINFO*, DispatcherContext*, PULONG, CONTEXT*);
extern CONTEXT* _FindAndUnlinkFrame(PVOID, FRAMEINFO*);
extern VOID _JumpToContinuation( ULONG, CONTEXT*);
extern PVOID _OffsetToAddress( ptrdiff_t, PULONG, ULONG );
extern "C" VOID _UnwindNestedFrames( EHRegistrationNode*, EHExceptionRecord*, CONTEXT* );
extern "C" VOID _NLG_Notify( PVOID, PVOID );
extern "C" PVOID _CallSettingFrame( PVOID, PULONG, ULONG );
extern "C" PVOID _CallCatchBlock2( EHRegistrationNode*, FuncInfo*, PVOID, ULONG, ULONG );
extern "C" BOOL _CallSETranslator( EHExceptionRecord*, EHRegistrationNode*, CONTEXT*, DispatcherContext*, FuncInfo*, ULONG, EHRegistrationNode*, ULONG);
extern "C" VOID _EHRestoreContext(CONTEXT* pContext);
extern "C" CONTEXT* _GetUnwindContext(VOID);
extern "C" VOID _MoveContext(CONTEXT* pTarget, CONTEXT* pSource);
extern TryBlockMapEntry *_GetRangeOfTrysToCheck(EHRegistrationNode *, FuncInfo *, int, __ehstate_t, unsigned *, unsigned *);
extern VOID _DestructExceptionObject(EHExceptionRecord *, BOOLEAN);
#define _CallMemberFunction0(pthis, pmfn) (*(VOID(*)(PVOID))pmfn)(pthis)
#define _CallMemberFunction1(pthis, pmfn, pthat) (*(VOID(*)(PVOID,PVOID))pmfn)(pthis,pthat)
#define _CallMemberFunction2(pthis, pmfn, pthat, val2 ) (*(VOID(*)(PVOID,PVOID,int))pmfn)(pthis,pthat,val2)
#define UNWINDHELP(base,offset,index) (((char*)base) + (int)offset)[index]
#elif defined (_M_IA64)
typedef struct FrameInfo {
EHRegistrationNode EstablisherFrame;
PRUNTIME_FUNCTION pFunctionEntry;
CONTEXT* pExitContext;
__ehstate_t State;
struct FrameInfo *pNext;
} FRAMEINFO;
extern FRAMEINFO* _CreateFrameInfo(FRAMEINFO*, DispatcherContext*, EHRegistrationNode*, CONTEXT*, __ehstate_t);
extern CONTEXT* _FindAndUnlinkFrame(PVOID, FRAMEINFO*);
extern FRAMEINFO* _FindFrameInfo(DispatcherContext*, FRAMEINFO*);
extern VOID _JumpToContinuation( ULONG, CONTEXT*, EHExceptionRecord*);
extern BOOL _ExecutionInCatch(DispatcherContext*, FuncInfo*);
extern VOID __FrameUnwindToEmptyState(EHRegistrationNode*, DispatcherContext*, FuncInfo*);
extern "C" VOID _UnwindNestedFrames( EHRegistrationNode*, EHExceptionRecord*, CONTEXT* );
extern "C" VOID _NLG_Notify( PVOID, PVOID );
extern "C" PVOID _CallSettingFrame( void (*func)(void), EHRegistrationNode*, ULONG );
extern "C" BOOL _CallSETranslator( EHExceptionRecord*, EHRegistrationNode*, CONTEXT*, DispatcherContext*, FuncInfo*, ULONG, EHRegistrationNode*);
extern "C" VOID _EHRestoreContext(CONTEXT* pContext);
extern "C" VOID _SaveUnwindContext(CONTEXT* pContext);
extern "C" CONTEXT* _GetUnwindContext(VOID);
extern "C" VOID _MoveContext(CONTEXT* pTarget, CONTEXT* pSource);
extern TryBlockMapEntry *_GetRangeOfTrysToCheck(EHRegistrationNode *, FuncInfo *, int, __ehstate_t, unsigned *, unsigned *, DispatcherContext*);
extern VOID _DestructExceptionObject(EHExceptionRecord *, BOOLEAN);
extern EHRegistrationNode *_GetEstablisherFrame(EHRegistrationNode*, DispatcherContext*, FuncInfo*, EHRegistrationNode*);
#define _CallMemberFunction0(pthis, pmfn) (*(VOID(*)(PVOID))pmfn)(pthis)
#define _CallMemberFunction1(pthis, pmfn, pthat) (*(VOID(*)(PVOID,PVOID))pmfn)(pthis,pthat)
#define _CallMemberFunction2(pthis, pmfn, pthat, val2 ) (*(VOID(*)(PVOID,PVOID,int))pmfn)(pthis,pthat,val2)
#define UNWINDSTATE(base,offset) *((int*)((char*)base + offset))
#define UNWINDTRYBLOCK(base,offset) *((int*)((char*)base + offset + sizeof(int)))
#define UNWINDHELP(base,offset) *((__int64*)((char*)base + offset))
#define OffsetToAddress( off, FP ) (void*)(((char*)FP) + off)
#elif defined (_M_ALPHA)
//
// For Debugger handling of stepping with non-local gotos
//
extern "C" VOID __NLG_Notify( PVOID, PVOID, ULONG );
//
// For calling funclets (including the catch)
//
extern "C" void * _CallSettingFrame (
void *funcAddress,
void *realFP,
unsigned long NLGCode
);
extern void _JumpToContinuation(
void *TargetIp, // The target address
EHRegistrationNode *TargetFrame // The target virtual frame ptr
);
//
// For calling member functions:
//
extern "C" void _CallMemberFunction0( void *pthis, void *pmfn );
extern "C" void _CallMemberFunction1( void *pthis, void *pmfn, void *pthat );
extern "C" void _CallMemberFunction2( void *pthis, void *pmfn, void *pthat, int val2 );
//
// Translate an frame relative offset to a hard address based on address of
// a frame pointer (real or virtual).
//
#define OffsetToAddress( off, FP ) (void*)(((char*)FP) + off)
//
// Call RtlUnwind in a returning fashion
//
extern "C" VOID _UnwindNestedFrames (
IN EHRegistrationNode *TargetFrame,
IN EHExceptionRecord *ExceptionRecord
);
//
// Ditto the SE translator
//
BOOL _CallSETranslator( EHExceptionRecord*, EHRegistrationNode*, void*,
DispatcherContext*, FuncInfo*, int,
EHRegistrationNode*);
extern TryBlockMapEntry *_GetRangeOfTrysToCheck(FuncInfo *, int, __ehstate_t, unsigned *, unsigned *);
extern VOID _DestructExceptionObject(EHExceptionRecord *, BOOLEAN);
#elif defined (_M_IX86)
//
// For calling funclets (including the catch)
//
extern "C" void * __stdcall _CallSettingFrame( void *, EHRegistrationNode *, unsigned long );
extern void __stdcall _JumpToContinuation( void *, EHRegistrationNode * );
//
// For calling member functions:
//
extern void __stdcall _CallMemberFunction0( void *pthis, void *pmfn );
extern void __stdcall _CallMemberFunction1( void *pthis, void *pmfn, void *pthat );
extern void __stdcall _CallMemberFunction2( void *pthis, void *pmfn, void *pthat, int val2 );
//
// Translate an ebp-relative offset to a hard address based on address of
// registration node:
//
#if !CC_EXPLICITFRAME
#define OffsetToAddress( off, RN ) \
(void*)((char*)RN \
+ FRAME_OFFSET \
+ off)
#else /* !CC_EXPLICITFRAME */
#define OffsetToAddress( off, RN ) (void*)(((char*)RN->frame) + off)
#endif /* !CC_EXPLICITFRAME */
//
// Call RtlUnwind in a returning fassion
//
extern void __stdcall _UnwindNestedFrames( EHRegistrationNode*, EHExceptionRecord* );
//
// Do the nitty-gritty of calling the catch block safely
//
void *_CallCatchBlock2( EHRegistrationNode *, FuncInfo*, void*, int, unsigned long );
//
// Ditto the SE translator
//
BOOL _CallSETranslator( EHExceptionRecord*, EHRegistrationNode*, void*, DispatcherContext*, FuncInfo*, int, EHRegistrationNode*);
extern TryBlockMapEntry *_GetRangeOfTrysToCheck(FuncInfo *, int, __ehstate_t, unsigned *, unsigned *);
extern VOID _DestructExceptionObject(EHExceptionRecord *, BOOLEAN);
#elif defined (_M_MPPC) || defined (_M_PPC)
typedef struct FrameInfo {
PULONG pEstablisherFrame;
ULONG ControlPc;
PRUNTIME_FUNCTION pFunctionEntry;
CONTEXT *pExitContext;
__ehstate_t state;
struct FrameInfo *pNext;
} FRAMEINFO;
extern "C" PVOID _CallSettingFrame(PVOID, PULONG, ULONG);
extern "C" VOID _GetStackLimits(PULONG, PULONG);
extern EHRegistrationNode *_GetEstablisherFrame(DispatcherContext *, int *);
extern FRAMEINFO *_CreateFrameInfo(FRAMEINFO *, DispatcherContext *, PULONG, CONTEXT *, __ehstate_t);
extern "C" VOID _JumpToContinuation(ULONG, CONTEXT *);
extern "C" VOID _UnwindNestedFrames(EHRegistrationNode *, EHExceptionRecord *, CONTEXT *);
extern CONTEXT *_FindAndUnlinkFrame(PVOID, FRAMEINFO *);
extern FRAMEINFO *_FindFrameInfo(ULONG, FRAMEINFO *);
extern VOID __FrameUnwindToEmptyState(EHRegistrationNode *, DispatcherContext *, FuncInfo *);
extern BOOL _UnwindNestedCatch(EHRegistrationNode *, DispatcherContext *);
extern BOOL _CallSETranslator(EHExceptionRecord *, EHRegistrationNode *, CONTEXT *, DispatcherContext *, FuncInfo *, ULONG, EHRegistrationNode *);
extern TryBlockMapEntry *_GetRangeOfTrysToCheck(FuncInfo *, int, __ehstate_t, unsigned *, unsigned *);
extern VOID _DestructExceptionObject(EHExceptionRecord *, BOOLEAN);
#define OffsetToAddress(off, pRN) \
((void *)((char *)(pRN) + (off)))
#define _CallMemberFunction0(pthis, pmfn) \
(*(VOID(*)(PVOID))(pmfn))(pthis)
#define _CallMemberFunction1(pthis, pmfn, pthat) \
(*(VOID(*)(PVOID, PVOID))(pmfn))(pthis, pthat)
#define _CallMemberFunction2(pthis, pmfn, pthat, val2) \
(*(VOID(*)(PVOID, PVOID, int))(pmfn))(pthis, pthat, val2)
#if defined (_M_MPPC)
extern VOID _AllocExceptionData(PEXCEPTION_RECORD *, PCONTEXT *);
extern VOID _FreeExceptionData(EHExceptionRecord *);
extern ULONG _ConvertCFAddress(ULONG, DispatcherContext *, int);
#define CFREL_TO_ABS 0
#define ABS_TO_CFREL 1
#define TOC_LINK (-1)
#else /* defined (_M_MPPC) */
#define TOC_LINK 2
#endif /* defined (_M_MPPC) */
#define SET_UNWIND_FLAG(rTOC) ((rTOC) |= 1)
#define CLEAR_UNWIND_FLAG(rTOC) ((rTOC) &= ~1)
#define CHECK_UNWIND_FLAG(rTOC) (((rTOC) & 1) != 0)
#define SET_UNWIND_FRAME(pRN) SET_UNWIND_FLAG(((PULONG)(pRN))[TOC_LINK])
#define CHECK_UNWIND_FRAME(pRN) CHECK_UNWIND_FLAG(((PULONG)(pRN))[TOC_LINK])
#else /* defined (_M_MPPC) || defined (_M_PPC) */
#pragma message("Special transfer of control routines not defined for this platform")
#endif /* defined (_M_MPPC) || defined (_M_PPC) */
#endif /* _INC_TRNSCTRL */