mirror of https://github.com/tongzx/nt5src
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.
798 lines
21 KiB
798 lines
21 KiB
// TITLE("Miscellaneous Exception Handling")
|
|
//++
|
|
//
|
|
// Module Name:
|
|
//
|
|
// xcptmisc.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements miscellaneous routines that are required to
|
|
// support exception handling. Functions are provided to call an exception
|
|
// handler for an exception, call an exception handler for unwinding, call
|
|
// an exception filter, and call a termination handler.
|
|
//
|
|
// Author:
|
|
//
|
|
// William K. Cheung (wcheung) 15-Jan-1996
|
|
//
|
|
// based on the version by David N. Cutler (davec) 12-Sep-1990
|
|
//
|
|
// Environment:
|
|
//
|
|
// Any mode.
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Updated to EAS2.1
|
|
//
|
|
//--
|
|
|
|
#include "ksia64.h"
|
|
|
|
.file "xcptmisc.s"
|
|
|
|
//++
|
|
//
|
|
// EXCEPTION_DISPOSITION
|
|
// RtlpExceptionHandler (
|
|
// IN PEXCEPTION_RECORD ExceptionRecord,
|
|
// IN FRAME_POINTERS EstablisherFrame,
|
|
// IN OUT PCONTEXT ContextRecord,
|
|
// IN OUT PDISPATCHER_CONTEXT DispatcherContext
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function is called when a nested exception occurs. Its function
|
|
// is to retrieve the establisher frame pointer from its establisher's
|
|
// call frame, store this information in the dispatcher context record,
|
|
// and return a disposition value of nested exception.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// ExceptionRecord (a0) - Supplies a pointer to an exception record.
|
|
//
|
|
// EstablisherFrame (a1,a2) - Supplies the memory stack and backing store
|
|
// frame pointers of the establisher of this exception handler.
|
|
//
|
|
// ContextRecord (a3) - Supplies a pointer to a context record.
|
|
//
|
|
// DispatcherContext (a4) - Supplies a pointer to the dispatcher context
|
|
// record.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// A disposition value ExceptionNestedException is returned if an unwind
|
|
// is not in progress. Otherwise a value of ExceptionContinueSearch is
|
|
// returned.
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(RtlpExceptionHandler)
|
|
|
|
//
|
|
// register aliases
|
|
//
|
|
|
|
pUwnd = pt0
|
|
pNot = pt1
|
|
|
|
|
|
//
|
|
// Check if unwind is in progress.
|
|
//
|
|
|
|
add t0 = ErExceptionFlags, a0
|
|
;;
|
|
ld4.nt1 t0 = [t0]
|
|
mov t1 = EXCEPTION_UNWIND
|
|
;;
|
|
|
|
add t3 = -8, a1
|
|
and t0 = t0, t1
|
|
add t2 = DcEstablisherFrame, a4
|
|
;;
|
|
|
|
ld8.nt1 t4 = [t3] // get dispatcher context addr
|
|
cmp4.ne pUwnd, pNot = zero, t0 // if ne, unwind in progress
|
|
;;
|
|
(pNot) add t5 = DcEstablisherFrame, t4
|
|
;;
|
|
|
|
//
|
|
// If unwind is not in progress - return nested exception disposition.
|
|
// And copy the establisher frame pointer structure (i.e. FRAME_POINTERS)
|
|
// to the current dispatcher context.
|
|
//
|
|
// Otherwise, return continue search disposition
|
|
//
|
|
|
|
(pNot) ld8.nt1 t6 = [t5], 8
|
|
(pNot) mov v0 = ExceptionNestedException // set disposition value
|
|
(pUwnd) mov v0 = ExceptionContinueSearch // set disposition value
|
|
;;
|
|
|
|
(pNot) ld8.nt1 t7 = [t5]
|
|
(pNot) st8 [t2] = t6, 8
|
|
nop.i 0
|
|
;;
|
|
|
|
(pNot) st8 [t2] = t7
|
|
nop.m 0
|
|
br.ret.sptk.clr brp
|
|
;;
|
|
|
|
LEAF_EXIT(RtlpExceptionHandler)
|
|
|
|
//++
|
|
//
|
|
// EXCEPTION_DISPOSITION
|
|
// RtlpExecuteEmHandlerForException (
|
|
// IN PEXCEPTION_RECORD ExceptionRecord,
|
|
// IN ULONGLONG MemoryStack,
|
|
// IN ULONGLONG BackingStore,
|
|
// IN OUT PCONTEXT ContextRecord,
|
|
// IN OUT PDISPATCHER_CONTEXT DispatcherContext,
|
|
// IN ULONGLONG GlobalPointer,
|
|
// IN PEXCEPTION_ROUTINE ExceptionRoutine
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function stores the establisher's dispatcher context in the stack
|
|
// scratch area, establishes an exception handler, and then calls
|
|
// the specified exception handler as an exception handler. If a nested
|
|
// exception occurs, then the exception handler of this function is called
|
|
// and the establisher frame pointer in the saved dispatcher context
|
|
// is returned to the exception dispatcher via the dispatcher context
|
|
// parameter of this function's exception handler. If control is returned
|
|
// to this routine, then the disposition status is returned to the
|
|
// exception dispatcher.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// ExceptionRecord (a0) - Supplies a pointer to an exception record.
|
|
//
|
|
// MemoryStack (a1) - Supplies the memory stack frame pointer of the
|
|
// activation record whose exception handler is to be called.
|
|
//
|
|
// BackingStore (a2) - Supplies the backing store pointer of the
|
|
// activation record whose exception handler is to be called.
|
|
//
|
|
// ContextRecord (a3) - Supplies a pointer to a context record.
|
|
//
|
|
// DispatcherContext (a4) - Supplies a pointer to the dispatcher context
|
|
// record.
|
|
//
|
|
// GlobalPointer (a5) - Supplies the global pointer value of the module
|
|
// to which the function belongs.
|
|
//
|
|
// ExceptionRoutine (a6) - supplies a pointer to the exception handler
|
|
// that is to be called.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The disposition value returned by the specified exception handler is
|
|
// returned as the function value.
|
|
//
|
|
//--
|
|
|
|
NESTED_ENTRY_EX(RtlpExecuteEmHandlerForException,RtlpExceptionHandler)
|
|
|
|
//
|
|
// register aliases
|
|
//
|
|
|
|
rpT0 = t8
|
|
rpT1 = t9
|
|
|
|
.prologue
|
|
.fframe 32, tg30
|
|
|
|
alloc t1 = ar.pfs, 0, 0, 7, 0
|
|
mov t0 = brp
|
|
mov rpT0 = sp
|
|
|
|
add rpT1 = 8, sp
|
|
[tg30:] add sp = -32, sp
|
|
;;
|
|
|
|
.savesp rp, 32
|
|
st8 [rpT0] = t0, -8 // save brp
|
|
.savesp ar.pfs, 32+8
|
|
st8 [rpT1] = t1, 8 // save pfs
|
|
;;
|
|
|
|
PROLOGUE_END
|
|
|
|
//
|
|
// Setup global pointer and branch register for the except handler
|
|
//
|
|
|
|
ld8 t2 = [a6], PlGlobalPointer - PlEntryPoint
|
|
st8.nta [rpT0] = a4 // save dispatcher context addr
|
|
;;
|
|
|
|
ld8 gp = [a6]
|
|
mov bt0 = t2
|
|
br.call.sptk.many brp = bt0 // call except handler
|
|
|
|
//
|
|
// Save swizzled dispatcher context address onto the stack
|
|
//
|
|
|
|
.restore tg40
|
|
[tg40:] add sp = 32, sp // deallocate stack frame
|
|
;;
|
|
ld8.nt1 t0 = [sp]
|
|
add rpT1 = 8, sp
|
|
;;
|
|
|
|
ld8.nt1 t1 = [rpT1]
|
|
nop.f 0
|
|
mov brp = t0 // restore return branch
|
|
;;
|
|
|
|
nop.m 0
|
|
mov ar.pfs = t1 // restore pfs
|
|
br.ret.sptk.clr brp // return
|
|
|
|
NESTED_EXIT(RtlpExecuteEmHandlerForException)
|
|
|
|
//++
|
|
//
|
|
// EXCEPTION_DISPOSITION
|
|
// RtlpEmUnwindHandler (
|
|
// IN PEXCEPTION_RECORD ExceptionRecord,
|
|
// IN FRAME_POINTERS EstablisherFrame,
|
|
// IN OUT PCONTEXT ContextRecord,
|
|
// IN OUT PVOID DispatcherContext
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function is called when a collided unwind occurs. Its function
|
|
// is to retrieve the establisher dispatcher context, copy it to the
|
|
// current dispatcher context, and return a disposition value of nested
|
|
// unwind.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// ExceptionRecord (a0) - Supplies a pointer to an exception record.
|
|
//
|
|
// EstablisherFrame (a1,a2) - Supplies the memory stack and backing store
|
|
// frame pointers of the establisher of this exception handler.
|
|
//
|
|
// ContextRecord (a3) - Supplies a pointer to a context record.
|
|
//
|
|
// DispatcherContext (a4) - Supplies a pointer to the dispatcher context
|
|
// record.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// A disposition value ExceptionCollidedUnwind is returned if an unwind is
|
|
// in progress. Otherwise, a value of ExceptionContinueSearch is returned.
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(RtlpEmUnwindHandler)
|
|
|
|
//
|
|
// register aliases
|
|
//
|
|
|
|
#if 0
|
|
|
|
pUwnd = pt0
|
|
pNot = pt1
|
|
|
|
//
|
|
// Check if unwind is in progress.
|
|
//
|
|
|
|
add t0 = ErExceptionFlags, a0
|
|
;;
|
|
ld4.nt1 t0 = [t0]
|
|
mov t1 = EXCEPTION_UNWIND
|
|
;;
|
|
and t0 = t0, t1
|
|
;;
|
|
|
|
cmp4.eq pNot, pUwnd = zero, t0 // if eq, unwind not in progress
|
|
(pNot) br.cond.sptk Ruh10
|
|
|
|
#endif // 0
|
|
|
|
add t2 = -8, a1
|
|
add t1 = 8, a4 // -> target dispatch context+8
|
|
;;
|
|
|
|
ld8.nt1 t2 = [t2] // -> source dispatch context
|
|
;;
|
|
add t3 = 8, t2 // -> source dispatch context+8
|
|
nop.i 0
|
|
;;
|
|
|
|
//
|
|
// Copy the establisher dispatcher context (i.e. DISPATCHER_CONTEXT) contents
|
|
// to the current dispatcher context.
|
|
//
|
|
|
|
ld8 t6 = [t2], 16
|
|
ld8 t7 = [t3], 16
|
|
nop.i 0
|
|
;;
|
|
|
|
ld8 t8 = [t2], 16
|
|
ld8 t9 = [t3], 16
|
|
nop.i 0
|
|
;;
|
|
|
|
st8 [a4] = t6, 16
|
|
st8 [t1] = t7, 16
|
|
nop.i 0
|
|
|
|
LDPTR (t10, t2)
|
|
LDPTR (t11, t3)
|
|
nop.i 0
|
|
;;
|
|
|
|
st8 [a4] = t8, 16
|
|
st8 [t1] = t9, 16
|
|
mov v0 = ExceptionCollidedUnwind // set disposition value
|
|
;;
|
|
|
|
STPTR (a4, t10)
|
|
STPTR (t1, t11)
|
|
br.ret.sptk.clr brp // return
|
|
;;
|
|
|
|
|
|
#if 0
|
|
|
|
Ruh10:
|
|
|
|
//
|
|
// If branched to here,
|
|
// unwind is not in progress - return continue search disposition.
|
|
//
|
|
|
|
nop.m 0
|
|
(pNot) mov v0 = ExceptionContinueSearch // set disposition value
|
|
br.ret.sptk.clr brp // return
|
|
|
|
#endif // 0
|
|
|
|
LEAF_EXIT(RtlpEmUnwindHandler)
|
|
|
|
//++
|
|
//
|
|
// EXCEPTION_DISPOSITION
|
|
// RtlpExecuteEmHandlerForUnwind (
|
|
// IN PEXCEPTION_RECORD ExceptionRecord,
|
|
// IN ULONGLONG MemoryStack,
|
|
// IN ULONGLONG BackingStore,
|
|
// IN OUT PCONTEXT ContextRecord,
|
|
// IN OUT PVOID DispatcherContext,
|
|
// IN ULONGLONG GlobalPointer,
|
|
// IN PEXCEPTION_ROUTINE ExceptionRoutine
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function allocates a call frame, stores the establisher frame
|
|
// pointer and the context record address in the frame, establishes an
|
|
// exception handler, and then calls the specified exception handler as
|
|
// an unwind handler. If a collided unwind occurs, then the exception
|
|
// handler of of this function is called and the establisher frame pointer
|
|
// and context record address are returned to the unwind dispatcher via
|
|
// the dispatcher context parameter. If control is returned to this routine,
|
|
// then the frame is deallocated and the disposition status is returned to
|
|
// the unwind dispatcher.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// ExceptionRecord (a0) - Supplies a pointer to an exception record.
|
|
//
|
|
// MemoryStack (a1) - Supplies the memory stack frame pointer of the
|
|
// activation record whose exception handler is to be called.
|
|
//
|
|
// BackingStore (a2) - Supplies the backing store pointer of the
|
|
// activation record whose exception handler is to be called.
|
|
//
|
|
// ContextRecord (a3) - Supplies a pointer to a context record.
|
|
//
|
|
// DispatcherContext (a4) - Supplies a pointer to the dispatcher context
|
|
// record.
|
|
//
|
|
// GlobalPointer (a5) - Supplies the global pointer value of the module
|
|
// to which the function belongs.
|
|
//
|
|
// ExceptionRoutine (a6) - supplies a pointer to the exception handler
|
|
// that is to be called.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The disposition value returned by the specified exception handler is
|
|
// returned as the function value.
|
|
//
|
|
//--
|
|
|
|
|
|
NESTED_ENTRY_EX(RtlpExecuteEmHandlerForUnwind, RtlpEmUnwindHandler)
|
|
|
|
//
|
|
// register aliases
|
|
//
|
|
|
|
.prologue
|
|
.fframe 32, tg10
|
|
|
|
rpT0 = t8
|
|
rpT1 = t9
|
|
|
|
|
|
alloc t1 = ar.pfs, 0, 0, 7, 0
|
|
mov t0 = brp
|
|
mov rpT0 = sp
|
|
|
|
add rpT1 = 8, sp
|
|
[tg10:] add sp = -32, sp
|
|
;;
|
|
|
|
.savepsp rp, 0
|
|
st8 [rpT0] = t0, -8 // save brp
|
|
.savepsp ar.pfs, -8
|
|
st8 [rpT1] = t1, 8 // save pfs
|
|
;;
|
|
|
|
PROLOGUE_END
|
|
|
|
//
|
|
// Setup global pointer and branch register for the except handler
|
|
//
|
|
|
|
ld8 t2 = [a6], PlGlobalPointer - PlEntryPoint
|
|
st8.nta [rpT0] = a4 // save dispatcher context addr
|
|
;;
|
|
|
|
ld8 gp = [a6]
|
|
mov bt0 = t2
|
|
(p0) br.call.sptk.many brp = bt0 // call except handler
|
|
|
|
//
|
|
// Save swizzled dispatcher context address onto the stack
|
|
//
|
|
|
|
.restore tg20
|
|
[tg20:] add sp = 32, sp // deallocate stack frame
|
|
;;
|
|
ld8.nt1 t0 = [sp]
|
|
add rpT1 = 8, sp
|
|
;;
|
|
|
|
ld8.nt1 t1 = [rpT1]
|
|
nop.f 0
|
|
mov brp = t0 // restore return branch
|
|
;;
|
|
|
|
nop.m 0
|
|
mov ar.pfs = t1 // restore pfs
|
|
br.ret.sptk.clr brp // return
|
|
;;
|
|
|
|
NESTED_EXIT(RtlpExecuteEmHandlerForUnwind)
|
|
|
|
#if 0
|
|
//++
|
|
//
|
|
// EXCEPTION_DISPOSITION
|
|
// RtlpUnwindHandler (
|
|
// IN PEXCEPTION_RECORD ExceptionRecord,
|
|
// IN FRAME_POINTERS EstablisherFrame,
|
|
// IN OUT PCONTEXT ContextRecord,
|
|
// IN OUT PVOID DispatcherContext
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function is called when a collided unwind occurs. Its function
|
|
// is to retrieve the establisher dispatcher context, copy it to the
|
|
// current dispatcher context, and return a disposition value of nested
|
|
// unwind.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// ExceptionRecord (a0) - Supplies a pointer to an exception record.
|
|
//
|
|
// EstablisherFrame (a1,a2) - Supplies the memory stack and backing store
|
|
// frame pointers of the establisher of this exception handler.
|
|
//
|
|
// ContextRecord (a3) - Supplies a pointer to a context record.
|
|
//
|
|
// DispatcherContext (a4) - Supplies a pointer to the dispatcher context
|
|
// record.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// A disposition value ExceptionCollidedUnwind is returned if an unwind is
|
|
// in progress. Otherwise, a value of ExceptionContinueSearch is returned.
|
|
//
|
|
//--
|
|
LEAF_ENTRY(RtlpUnwindHandler)
|
|
|
|
LEAF_RETURN
|
|
LEAF_EXIT(RtlpUnwindHandler)
|
|
|
|
|
|
//
|
|
// constants & register aliases for EM-iA transition stubs
|
|
//
|
|
|
|
rIA32Ptr = r2 // IA32 resources pointer
|
|
rTeb = r3 // TEB pointer
|
|
rIA32Rsrc = ar.k7 // Offset in TEB for iA32 stuff
|
|
|
|
rES = r16
|
|
rCS = r17
|
|
rSS = r18
|
|
rDS = r19
|
|
rFS = r20
|
|
rGS = r21
|
|
rLDT = r22
|
|
rEFLAG = ar24
|
|
rESD = r24
|
|
rCSD = ar25
|
|
rSSD = ar26
|
|
rDSD = r27
|
|
rFSD = r28
|
|
rGSD = r29
|
|
rLDTD = r30
|
|
rGDTD = r31
|
|
|
|
isIA = pt0
|
|
isTIA = pt1
|
|
|
|
|
|
|
|
//++
|
|
//
|
|
// EXCEPTION_DISPOSITION
|
|
// RtlpExecuteX86HandlerForException (
|
|
// IN PEXCEPTION_RECORD ExceptionRecord,
|
|
// IN PVOID EstablisherFrame,
|
|
// IN OUT PCONTEXT ContextRecord,
|
|
// IN OUT PDISPATCHER_CONTEXT DispatcherContext,
|
|
// IN PEXCEPTION_ROUTINE ExceptionRoutine
|
|
// )
|
|
//
|
|
// Arguments:
|
|
//
|
|
// ExceptionRecord (a0) - Supplies a pointer to an exception record.
|
|
//
|
|
// EstablisherFrame (a1) - Supplies the frame pointer of the establisher
|
|
// whose exception handler is to be called.
|
|
//
|
|
// ContextRecord (a2) - Supplies a pointer to a context record.
|
|
//
|
|
// DispatcherContext (a3) - Supplies a pointer to the dispatcher context
|
|
// record.
|
|
//
|
|
// ExceptionRoutine (a4) - supplies a pointer to the exception handler
|
|
// that is to be called.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The disposition value returned by the specified exception handler is
|
|
// returned as the function value.
|
|
//
|
|
//--
|
|
|
|
NESTED_ENTRY_EX(RtlpExecuteX86HandlerForException,RtlpExceptionHandler)
|
|
|
|
.regstk 5, 6, 0, 0
|
|
.prologue 0xe, loc0
|
|
|
|
alloc loc1 = ar.pfs, 5, 6, 0, 0
|
|
mov loc2 = brp
|
|
mov loc0 = sp
|
|
|
|
PROLOGUE_END
|
|
|
|
mov rTeb = teb
|
|
add r13 = 4, sp
|
|
mov r14 = sp
|
|
|
|
mov loc3 = ar.fpsr
|
|
sxt4 a3 = a3
|
|
sxt4 gp = a4
|
|
;;
|
|
|
|
mov rIA32Ptr = rIA32Rsrc
|
|
st4 [r14] = a0, 8
|
|
mov loc4 = pr
|
|
;;
|
|
|
|
st4 [r13] = a1, 8
|
|
st4 [r14] = a2, 16
|
|
mov loc5 = ar.lc
|
|
;;
|
|
|
|
st4 [r13] = a3
|
|
mov bt0 = gp
|
|
br.call.sptk brp = _EM_IA_ExecuteHandler_Transition
|
|
|
|
mov ar.fpsr = loc3
|
|
mov ar.pfs = loc0
|
|
mov brp = loc1
|
|
|
|
add sp = r0, loc2
|
|
mov pr = loc4, -1
|
|
mov ar.lc = loc5
|
|
|
|
nop.m 0
|
|
nop.m 0
|
|
br.ret.sptk.clr brp
|
|
|
|
NESTED_EXIT(RtlpExecuteX86HandlerForException)
|
|
|
|
|
|
LEAF_ENTRY(_EM_IA_ExecuteHandler_Transition)
|
|
|
|
alloc loc1 = ar.pfs, 0, 96, 0, 0
|
|
add rIA32Ptr = rIA32Ptr, rTeb
|
|
mov rES = _DataSelector
|
|
|
|
mov rESD = rSSD
|
|
mov rSS = _DataSelector
|
|
mov rDS = _DataSelector
|
|
|
|
mov rDSD = rSSD
|
|
mov rCS = _CodeSelector
|
|
mov rFS = _FsSelector
|
|
|
|
ld2 v0 = [gp], 8
|
|
add sp = -4, sp
|
|
mov rLDT = _LdtSelector
|
|
;;
|
|
|
|
ld8 rGDTD = [rIA32Ptr], 8
|
|
// movl r3 = @fptr(_EM_IA_STUBRET_ExecuteX86HandlerStub)
|
|
movl r3 = artificial_return
|
|
;;
|
|
|
|
ld8 rLDTD = [rIA32Ptr], 8
|
|
movl loc2 = JMPE_CONST
|
|
;;
|
|
|
|
st4 [sp] = r3
|
|
mov rGS = _DataSelector
|
|
cmp.eq isTIA, isIA = loc2, v0
|
|
;;
|
|
|
|
ld8 rFSD = [rIA32Ptr]
|
|
(isTIA) ld8 r2 = [gp], 8
|
|
br.ia.sptk bt0
|
|
;;
|
|
|
|
ld8 gp = [gp]
|
|
mov bt0 = r2
|
|
br bt0
|
|
|
|
LEAF_EXIT(_EM_IA_ExecuteHandler_Transition)
|
|
|
|
|
|
LEAF_ENTRY(_EM_IA_STUBRET_ExecuteX86HandlerStub)
|
|
|
|
//
|
|
// Artifical return to the bundle following the call to ReX86Transition
|
|
//
|
|
|
|
artificial_return:
|
|
.text
|
|
data8 0xab80f
|
|
data8 0x0
|
|
|
|
nop.m 0
|
|
nop.m 0
|
|
br.ret.sptk brp
|
|
|
|
LEAF_EXIT(_EM_IA_STUBRET_ExecuteX86HandlerStub)
|
|
|
|
|
|
//++
|
|
//
|
|
// EXCEPTION_DISPOSITION
|
|
// RtlpExecuteX86HandlerForUnwind (
|
|
// IN PEXCEPTION_RECORD ExceptionRecord,
|
|
// IN PVOID EstablisherFrame,
|
|
// IN OUT PCONTEXT ContextRecord,
|
|
// IN OUT PVOID DispatcherContext,
|
|
// IN PEXCEPTION_ROUTINE ExceptionRoutine
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function allocates a call frame, stores the establisher frame
|
|
// pointer and the context record address in the frame, establishes an
|
|
// exception handler, and then calls the specified exception handler as
|
|
// an unwind handler. If a collided unwind occurs, then the exception
|
|
// handler of of this function is called and the establisher frame pointer
|
|
// and context record address are returned to the unwind dispatcher via
|
|
// the dispatcher context parameter. If control is returned to this routine,
|
|
// then the frame is deallocated and the disposition status is returned to
|
|
// the unwind dispatcher.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// ExceptionRecord (a0) - Supplies a pointer to an exception record.
|
|
//
|
|
// EstablisherFrame (a1) - Supplies the memory stack and backing store
|
|
// frame pointers of the establisher whose exception handler is to
|
|
// be called.
|
|
//
|
|
// ContextRecord (a2) - Supplies a pointer to a context record.
|
|
//
|
|
// DispatcherContext (a3) - Supplies a pointer to the dispatcher context
|
|
// record.
|
|
//
|
|
// ExceptionRoutine (a4) - supplies a pointer to the exception handler
|
|
// that is to be called.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The disposition value returned by the specified exception handler is
|
|
// returned as the function value.
|
|
//
|
|
//--
|
|
|
|
NESTED_ENTRY_EX(RtlpExecuteX86HandlerForUnwind, RtlpUnwindHandler)
|
|
|
|
.regstk 5, 6, 0, 0
|
|
.prologue 0xe, loc0
|
|
|
|
alloc loc1 = ar.pfs, 5, 6, 0, 0
|
|
mov loc2 = brp
|
|
mov loc0 = sp
|
|
|
|
PROLOGUE_END
|
|
|
|
mov rTeb = teb
|
|
add r13 = 4, sp
|
|
mov r14 = sp
|
|
|
|
mov loc3 = ar.fpsr
|
|
sxt4 a3 = a3
|
|
sxt4 gp = a4
|
|
;;
|
|
|
|
mov rIA32Ptr = rIA32Rsrc
|
|
st4 [r14] = a0, 8
|
|
mov loc4 = pr
|
|
;;
|
|
|
|
st4 [r13] = a1, 8
|
|
st4 [r14] = a2, 16
|
|
mov loc5 = ar.lc
|
|
;;
|
|
|
|
st4 [r13] = a3
|
|
mov bt0 = a4
|
|
br.call.sptk brp = _EM_IA_ExecuteHandler_Transition
|
|
|
|
mov ar.fpsr = loc3
|
|
mov ar.pfs = loc0
|
|
mov brp = loc1
|
|
|
|
add sp = r0, loc2
|
|
mov pr = loc4, -1
|
|
mov ar.lc = loc5
|
|
|
|
nop.m 0
|
|
nop.m 0
|
|
br.ret.sptk.clr brp
|
|
|
|
NESTED_EXIT(RtlpExecuteX86HandlerForUnwind)
|
|
|
|
#endif //0
|