📄 armtrap.s
字号:
;
; (sp) = aligned stack pointer
; (r0-r14), etc. - CPU state at the time of exception
;-------------------------------------------------------------------------------
; Fake prolog for unwinding.
NESTED_ENTRY xxCaptureContext
mrs r0, cpsr
stmdb sp!, {r0} ; Unwind the Psr register
; The following instruction is a special hint to the unwinder, giving
; the location of the exception PC. See unwind.c:ArmVirtualUnwind().
stmdb sp!, {pc} ; PC of exception for unwinding
stmdb sp!, {lr} ; Restore lr
sub sp, sp, #(4 * 2) ; Unlink past r12, sp
stmdb sp!, {r4-r11} ; Restore non-volatiles r4-r11
sub sp, sp, #(4 * 5) ; Unlink past flags, r0-r3
PROLOG_END
ALTERNATE_ENTRY CaptureContext
sub sp, sp, #CtxSizeof ; (sp) = CONTEXT_RECORD
stmib sp, {r0-r15} ; store all registers
mrs r1, cpsr ; (r1) = current status
mov r0, #CONTEXT_FULL
str r1, [sp,#CtxPsr]
str r0, [sp,#CtxFlags] ; set ContextFlags
mov r0, sp ; (r0) = Arg0 = ptr to CONTEXT_RECORD
CALL ExceptionDispatch
mov r1, sp ; (r1) = ptr to CONTEXT_RECORD
ldr r2, [r1,#CtxPsr] ; (r0) = new Psr
and r0, r2, #0x1f ; (r2) = destination mode
cmp r0, #USER_MODE
bne %F9 ; not returning to user mode
; Returning to user mode.
msr cpsr_c, #SVC_MODE:OR:0xC0 ; switch to Supervisor Mode w/IRQs disabled
msr spsr, r2
ldr lr, [r1,#CtxPc] ; (lr) = address to continue at
ldmib r1, {r0-r14}^ ; restore user mode registers
nop ; hazard from user mode bank switch
movs pc, lr ; return to user mode.
; Returning to a privileged mode.
;
; (r1) = ptr to CONTEXT_RECORD
; (r2) = new PSR
9
IF Interworking :LOR: Thumbing
tst r2, #THUMB_STATE ; returning to Thumb code ?
beq ARMDispatch ; if not then dispatch to ARM code
;
; Switch to Thumb mode before continuing.
; "push" r0 and PC onto the continuation stack, update the context, use
; r0 to switch to Thumb, and then pop r0 & the continuation PC
;
ThumbDispatch
bic r2, r2, #THUMB_STATE ; else update mode
msr cpsr, r2
ldr r2, [r1, #CtxR0] ; load saved R0 value
ldr r3, [r1, #CtxPc] ; and continuation PC
ldr r0, [r1, #CtxSp] ; get the continuation SP
stmdb r0!, {r2, r3} ; "push" new R0 & PC values
str r0, [r1, #CtxSp] ; and update new stack pointer
add r1, r1, #CtxR1 ; get pointer to R1 context
ldmia r1, {r1-r14} ; load context except for R0 & PC
orr r0, pc, #0x01
bx r0 ; and switch to Thumb code
IF {FALSE} ; CODE16 causes THUMB object type
CODE16
pop {r0, pc} ; pop R0 and continue
nop
CODE32
ENDIF
ThumbSwitch
DCW 0xBD01 ; pop {r0, pc}
DCW 0x46C0 ; nop
ARMDispatch
ENDIF
msr cpsr, r2 ; restore Psr & switch modes
ldmib r1, {r0-r15} ; restore all registers & return
ENTRY_END xxCaptureContext
;-------------------------------------------------------------------------------
;++
; EXCEPTION_DISPOSITION
; RtlpExecuteHandlerForException (
; IN PEXCEPTION_RECORD ExceptionRecord,
; IN ULONG EstablisherFrame,
; IN OUT PCONTEXT ContextRecord,
; IN OUT PDISPATCHER_CONTEXT DispatcherContext,
; IN PEXCEPTION_ROUTINE ExceptionRoutine,
; IN ULONG ExceptionMode
; )
;
; Routine Description:
; This function allocates a call frame, stores the establisher frame
; pointer in the frame, 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 is returned to the exception 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 exception dispatcher.
;
; Arguments:
; ExceptionRecord (r0) - Supplies a pointer to an exception record.
;
; EstablisherFrame (r1) - Supplies the frame pointer of the establisher
; of the exception handler that is to be called.
;
; ContextRecord (r2) - Supplies a pointer to a context record.
;
; DispatcherContext (r3) - Supplies a pointer to the dispatcher context
; record.
;
; ExceptionRoutine ((sp)) - supplies a pointer to the exception handler
; that is to be called.
;
; ExceptionMode (4(sp)) - PSR value for running ExceptionRoutine
;
; Return Value:
; The disposition value returned by the specified exception handler is
; returned as the function value.
;--
;-------------------------------------------------------------------------------
EXCEPTION_HANDLER RtlpExceptionHandler
NESTED_ENTRY RtlpExecuteHandlerForException
mov r12, sp
stmfd sp!, {r3} ; save ptr to DispatcherContext
; for RtlpExceptionHandler
stmfd sp!, {r11,r12,lr}
sub sp, sp, #CstkSizeof ; space for a CALLSTACK struct
sub r11, r12, #4 ; (r11) = frame pointer
PROLOG_END
ldr r12, [r11, #8] ; (r12) = handler's mode
add lr, pc, #reheRet-(.+8) ; (lr) = return address
tst r12, #0xF ; user mode??
IF Interworking :LOR: Thumbing
ldrne r12, [r11, #4] ; invoke handler in system mode
bxne r12
ELSE
ldrne pc, [r11, #4] ; invoke handler in system mode
ENDIF
ldr r12, =KData
ldr r12, [r12, #pCurThd] ; (r12) = ptr to current thread
ldr r12, [r12, #ThPcstkTop] ; (r12) = ptr to CALLSTACK
; Link CallStackReserve to thread's callstack list so the unwinder can
; unwind past SYSCALL_RETURN
mov r3, sp ; (r3) = ptr to CallStackReserve
str r12, [r3, #CstkNext] ; CallStackReserve->pcstkNext = pth->pcstkTop
ldr r12, =KData
ldr r12, [r12, #pCurThd] ; (r12) = pCurThread
str r3, [r12, #ThPcstkTop] ; pCurThread->pcstkTop = CallStackReserve
mov r12, r3 ; r12 = CallStackReserve
ldr r3, [r11, #0] ; restore r3
str lr, [r12, #CstkRa] ; set return address
mov lr, #0
str lr, [r12, #CstkAkyLast]
mov lr, #SYSTEM_MODE
str lr, [r12, #CstkPrcLast]
ldr lr, =SYSCALL_RETURN
ldr r12, [r11,#4] ; (r12) = address to continue at
msr cpsr_c, #SVC_MODE:OR:0xC0 ; switch to SVC Mode w/IRQs disabled
tst r12, #0x01 ; set continuation Psr based on
msreq spsr_c, #USER_MODE ; Thumb or ARM continuation
msrne spsr_c, #USER_MODE | THUMB_STATE
movs pc, r12 ; switch to user mode & jump to handler
nop ; NOP required to terminate unwinding
reheRet
IF Thumbing
ldmdb r11, {r11, sp, lr}
bx lr
ELSE
ldmdb r11, {r11, sp, pc}
ENDIF
ENTRY_END RtlpExecuteHandlerForException
;-------------------------------------------------------------------------------
;++
; EXCEPTION_DISPOSITION
; RtlpExceptionHandler (
; IN PEXCEPTION_RECORD ExceptionRecord,
; IN ULONG 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 (r0) - Supplies a pointer to an exception record.
;
; EstablisherFrame (r1) - Supplies the frame pointer of the establisher
; of this exception handler.
;
; ContextRecord (r2) - Supplies a pointer to a context record.
;
; DispatcherContext (r3) - 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
ldr r12, [r0, #ErExceptionFlags] ; (r12) = exception flags
tst r12, #EXCEPTION_UNWIND ; unwind in progress?
movne r0, #ExceptionContinueSearch ; Y: set dispostion value
RETURN_NE ; Y: & return
ldr r12, [r1, #-4] ; (r12) = ptr to DispatcherContext
ldr r12, [r12, #DcEstablisherFrame] ; (r12) = establisher frame pointer
str r12, [r3, #DcEstablisherFrame] ; copy to current dispatcher ctx
mov r0, #ExceptionNestedException ; set dispostion value
RETURN ; return to caller
ENTRY_END RtlpExeptionHandler
;-------------------------------------------------------------------------------
;++
; EXCEPTION_DISPOSITION
; RtlpExecuteHandlerForUnwind (
; 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 (r0) - Supplies a pointer to an exception record.
;
; EstablisherFrame (r1) - Supplies the frame pointer of the establisher
; of the exception handler that is to be called.
;
; ContextRecord (r2) - Supplies a pointer to a context record.
;
; DispatcherContext (r3) - Supplies a pointer to the dispatcher context
; record.
;
; ExceptionRoutine ((sp)) - 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.
;--
;-------------------------------------------------------------------------------
EXCEPTION_HANDLER RtlpUnwindHandler
NESTED_ENTRY RtlpExecuteHandlerForUnwind
mov r12, sp
stmfd sp!, {r3} ; save ptr to DispatcherContext
stmfd sp!, {r11,r12,lr} ; for RtlpUnwindHandler
sub sp, sp, #CstkSizeof ; space for a CALLSTACK struct
sub r11, r12, #4 ; (r11) = frame pointer
PROLOG_END
ldr r12, [r2, #CtxPsr] ; (r12) = handler's mode
add lr, pc, #rehuRet-(.+8) ; (lr) = return address
tst r12, #0xF ; user mode??
IF Thumbing
ldrne r12, [r11, #4]
bxne r12 ; invoke Thumb mode handler
ELSE
ldrne pc, [r11, #4] ; invoke handler in system mode
ENDIF
ldr r12, =KData
ldr r12, [r12, #pCurThd] ; (r12) = ptr to current thread
ldr r12, [r12, #ThPcstkTop] ; (r12) = ptr to CALLSTACK
; Link CallStackReserve to thread's callstack list so the unwinder can
; unwind past SYSCALL_RETURN
mov r3, sp ; (r3) = ptr to CallStackReserve
str
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -