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)
|