270 lines
6.1 KiB
ArmAsm
270 lines
6.1 KiB
ArmAsm
|
//++
|
|||
|
//
|
|||
|
// Module Name:
|
|||
|
//
|
|||
|
// jmpuwind.s
|
|||
|
//
|
|||
|
// Abstract:
|
|||
|
//
|
|||
|
// This module implements the IA64 specific routine to jump to the runtime
|
|||
|
// time library unwind routine.
|
|||
|
//
|
|||
|
// Author:
|
|||
|
//
|
|||
|
// William K. Cheung (wcheung) 4-Jan-1996
|
|||
|
//
|
|||
|
//
|
|||
|
// based on the version by David N. Cutler (davec) 12-Sep-1990
|
|||
|
//
|
|||
|
// Environment:
|
|||
|
//
|
|||
|
// Any mode.
|
|||
|
//
|
|||
|
// Revision History:
|
|||
|
//
|
|||
|
//--
|
|||
|
|
|||
|
#include "ksia64.h"
|
|||
|
|
|||
|
//++
|
|||
|
//
|
|||
|
// LONG
|
|||
|
// __C_ExecuteExceptionFilter (
|
|||
|
// ULONGLONG MemoryStack,
|
|||
|
// ULONGLONG BackingStore,
|
|||
|
// NTSTATUS ExceptionCode,
|
|||
|
// PEXCEPTION_POINTERS ExceptionPointers,
|
|||
|
// ULONGLONG ExceptionFilter,
|
|||
|
// ULONGLONG GlobalPointer
|
|||
|
// )
|
|||
|
//
|
|||
|
// Routine Description:
|
|||
|
//
|
|||
|
// This function sets the gp register and transfers control to the specified
|
|||
|
// exception filter routine.
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// MemoryStack (a0) - memory stack pointer of establisher frame
|
|||
|
//
|
|||
|
// BackingStore (a1) - backing store pointer of establisher frame
|
|||
|
//
|
|||
|
// ExceptionCode (a2) - Exception Code.
|
|||
|
//
|
|||
|
// ExceptionPointers (a3) - Supplies a pointer to the exception pointers
|
|||
|
// structure.
|
|||
|
//
|
|||
|
// ExceptionFilter (a4) - Entry point of exception filter
|
|||
|
//
|
|||
|
// GlobalPointer (a5) - GP of exception filter
|
|||
|
//
|
|||
|
// Return Value:
|
|||
|
//
|
|||
|
// The value returned by the exception filter routine.
|
|||
|
//
|
|||
|
//--
|
|||
|
|
|||
|
LEAF_ENTRY(__C_ExecuteExceptionFilter)
|
|||
|
|
|||
|
mov gp = a5
|
|||
|
mov bt0 = a4
|
|||
|
br bt0 // branch to exception filter
|
|||
|
;;
|
|||
|
|
|||
|
LEAF_EXIT(__C_ExecuteExceptionFilter)
|
|||
|
|
|||
|
//++
|
|||
|
//
|
|||
|
// VOID
|
|||
|
// __C_ExecuteTerminationHandler (
|
|||
|
// ULONGLONG MemoryStack,
|
|||
|
// ULONGLONG BackingStore,
|
|||
|
// BOOLEAN AbnormalTermination,
|
|||
|
// ULONGLONG TerminationHandler,
|
|||
|
// ULONGLONG GlobalPointer
|
|||
|
// )
|
|||
|
//
|
|||
|
// Routine Description:
|
|||
|
//
|
|||
|
// This function sets the gp register and transfers control to the specified
|
|||
|
// termination handler routine.
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// MemoryStack (a0) - memory stack pointer of establisher frame
|
|||
|
//
|
|||
|
// BackingStore (a1) - backing store pointer of establisher frame
|
|||
|
//
|
|||
|
// AbnormalTermination (a2) - Supplies a boolean value that determines
|
|||
|
// whether the termination is abnormal.
|
|||
|
//
|
|||
|
// TerminationHandler (a3) - Entry point of termination handler
|
|||
|
//
|
|||
|
// GlobalPointer (a4) - GP of termination handler
|
|||
|
//
|
|||
|
// Return Value:
|
|||
|
//
|
|||
|
// None.
|
|||
|
//
|
|||
|
//--
|
|||
|
|
|||
|
LEAF_ENTRY(__C_ExecuteTerminationHandler)
|
|||
|
|
|||
|
mov gp = a4
|
|||
|
mov bt0 = a3
|
|||
|
br bt0 // branch to termination handler
|
|||
|
;;
|
|||
|
|
|||
|
LEAF_EXIT(__C_ExecuteTerminationHandler)
|
|||
|
|
|||
|
//++
|
|||
|
//
|
|||
|
// VOID
|
|||
|
// __jump_unwind (
|
|||
|
// IN PVOID TargetMsFrame,
|
|||
|
// IN PVOID TargetBsFrame,
|
|||
|
// IN PVOID TargetPc,
|
|||
|
// )
|
|||
|
//
|
|||
|
// Routine Description:
|
|||
|
//
|
|||
|
// This function transfer control to unwind. It is used by the MIPS
|
|||
|
// compiler when a goto out of the body or a try statement occurs.
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// TargetMsFrame (a0) - Supplies the memory stack frame pointer of the
|
|||
|
// target of the unwind.
|
|||
|
//
|
|||
|
// TargetBsFrame (a1) - Supplies the backing store frame pointer of the
|
|||
|
// target of the unwind.
|
|||
|
//
|
|||
|
// TargetPc (a2) - Supplies the target instruction address where control
|
|||
|
// is to be transfered to after the unwind operation is complete.
|
|||
|
//
|
|||
|
// Return Value:
|
|||
|
//
|
|||
|
// None.
|
|||
|
//
|
|||
|
// N.B. The first 2 input registers are reused for local while the third
|
|||
|
// input register is reused as output register.
|
|||
|
//
|
|||
|
//--
|
|||
|
|
|||
|
.global RtlUnwind2
|
|||
|
.type RtlUnwind2, @function
|
|||
|
.global RtlPcToFileHeader
|
|||
|
.type RtlPcToFileHeader, @function
|
|||
|
|
|||
|
NESTED_ENTRY(__jump_unwind)
|
|||
|
|
|||
|
.regstk 3, 2, 6, 0
|
|||
|
.prologue 0xC, loc0
|
|||
|
.fframe ContextFrameLength, Jn10
|
|||
|
|
|||
|
alloc loc0 = ar.pfs, 3, 3, 6, 0
|
|||
|
mov loc1 = brp
|
|||
|
[Jn10:] add sp = -ContextFrameLength, sp
|
|||
|
;;
|
|||
|
|
|||
|
mov loc2 = gp
|
|||
|
|
|||
|
PROLOGUE_END
|
|||
|
|
|||
|
//
|
|||
|
// Call RtlPcToFileHeader to get the image base of caller
|
|||
|
// The image base is returned in memory location STACK_SCRATCH_AREA, sp
|
|||
|
// and also in register v0
|
|||
|
//
|
|||
|
mov out0 = brp
|
|||
|
add out1 = STACK_SCRATCH_AREA, sp
|
|||
|
br.call.sptk brp = RtlPcToFileHeader
|
|||
|
;;
|
|||
|
|
|||
|
mov gp = loc2
|
|||
|
//
|
|||
|
// Add image base to image relative offset passed in a2
|
|||
|
//
|
|||
|
add out2 = v0, a2
|
|||
|
//
|
|||
|
// Setup rest of arguments to RtlUnwind2
|
|||
|
//
|
|||
|
add out5 = STACK_SCRATCH_AREA, sp
|
|||
|
mov out4 = zero
|
|||
|
mov out3 = zero
|
|||
|
mov out1 = a1
|
|||
|
mov out0 = a0
|
|||
|
br.call.sptk brp = RtlUnwind2
|
|||
|
;;
|
|||
|
|
|||
|
.restore Jn20
|
|||
|
|
|||
|
[Jn20:] add sp = ContextFrameLength, sp
|
|||
|
nop.f 0
|
|||
|
mov ar.pfs = loc0
|
|||
|
|
|||
|
nop.m 0
|
|||
|
mov brp = loc1
|
|||
|
br.ret.sptk brp
|
|||
|
|
|||
|
NESTED_EXIT(__jump_unwind)
|
|||
|
|
|||
|
|
|||
|
//++
|
|||
|
// VOID
|
|||
|
// _NLG_Notify(
|
|||
|
// IN PVOID Funclet
|
|||
|
// IN FRAME_POINTERS EstablisherFrame,
|
|||
|
// IN ULONG NLGCode
|
|||
|
// )
|
|||
|
//
|
|||
|
// Routine Description:
|
|||
|
//
|
|||
|
// Provides the handler/longjmp addresses to the debugger
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Funclet (a0) - Supplies the target address of non-local goto
|
|||
|
// EstablisherFrame (a1,a2) - Supplies a pointer to frame of the establisher
|
|||
|
// function
|
|||
|
// NLGCode (a3) - Supplies NLG identifying value
|
|||
|
//
|
|||
|
// Return Value:
|
|||
|
//
|
|||
|
// None.
|
|||
|
//
|
|||
|
//--
|
|||
|
.global __NLG_Dispatch
|
|||
|
.global __NLG_Destination
|
|||
|
|
|||
|
.sdata
|
|||
|
__NLG_Destination::
|
|||
|
data8 0x19930520 // signature
|
|||
|
data8 0 // handler address
|
|||
|
data8 0 // code
|
|||
|
data8 0 // memory stack frame pointer
|
|||
|
data8 0 // register stack frame pointer
|
|||
|
|
|||
|
LEAF_ENTRY(_NLG_Notify)
|
|||
|
|
|||
|
add t0 = @gprel(__NLG_Destination+0x8), gp
|
|||
|
add t1 = @gprel(__NLG_Destination+0x10), gp
|
|||
|
nop.i 0
|
|||
|
;;
|
|||
|
|
|||
|
st8 [t0] = a0, 16
|
|||
|
st8 [t1] = a3, 16
|
|||
|
nop.i 0
|
|||
|
;;
|
|||
|
|
|||
|
st8 [t0] = a1
|
|||
|
st8 [t1] = a2
|
|||
|
nop.i 0
|
|||
|
|
|||
|
__NLG_Dispatch::
|
|||
|
nop.m 0
|
|||
|
nop.i 0
|
|||
|
br.ret.sptk b0
|
|||
|
|
|||
|
LEAF_EXIT(_NLG_Notify)
|