⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 armtrap.s

📁 See Hanoi.cpp for the implementation of this cla
💻 S
📖 第 1 页 / 共 5 页
字号:
;
;       (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 + -