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

📄 tlundef.s

📁 realview22.rar
💻 S
📖 第 1 页 / 共 2 页
字号:
                SUB     R2,R2,#0xC0000000
                CMP     R2,#0x30000000
                BHS     Unknown_ARM_Handler    ; R14 -> ReturnFromHandler

CpInstructionBounce

; Jump to the correct handler via coprocessor handler address table.
; R0 already holds the instruction parameter, and R1 points to the
; register dump.  The call will preserve the values in R4-R7.

                ADR     R2,TLUndef_CpTable
                AND     R3,R0,#0x00000F00       ;Isolate CP number
                LDR     R3,[R2,R3,LSR #8-2]     ;Index table by CP no.
                ADD     R2, R2, R3
                BX      R2

ThumbStateBounce
; Get the Thumb instruction that bounced.  As for ArmStateBounce above.
; Thumb2 means we can have 32-bit instructiond including co-processor
; instructions. Bits 15:11 of hw1 are > 0x1c if instruction is 32 bit.

                LDRH    R0,[R6,#-2]
  if V6_ENDIAN_SWAP
                REV16   r0, r0
  endif

  if ARCH_HAS_THUMB2
                MOV     R2, R0, LSR #11
                CMP     R2, #0x1c              ; Check for 32-bit instruction
                BLE     Unknown_Thumb_Handler  ; R14 -> ReturnFromHandler
                LDRH    R2,[R6,#0]             ; Load second halfword
    if V6_ENDIAN_SWAP
                REV16   r2, r2
    endif
                ORR     R0, R2, R0, LSL #16    ; Construct whole instruction in R0
                ORR     R6, R6, #1             ; Use low bit of return address to
                                               ; remember it was a 32 bit instruction
                MOV     R2,R0,LSL #4
                SUB     R2,R2,#0xC0000000      ; Same check as above for ARM
                CMP     R2,#0x30000000         ; co-processor instruction.
                BLO     CpInstructionBounce
  endif
                B       Unknown_Thumb_Handler  ; R14 -> ReturnFromHandler

; The coprocessor handler address table.

        IMPORT Unknown_Coproc_Handler
        IMPORT VFP_Undef_Handler

TLUndef_CpTable
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 0
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 1
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 2
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 3
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 4
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 5
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 6
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 7
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 8
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 9
                DCD     VFP_Undef_Handler      - TLUndef_CpTable ; CP 10
                DCD     VFP_Undef_Handler      - TLUndef_CpTable ; CP 11
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 12
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 13
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 14
                DCD     Unknown_Coproc_Handler - TLUndef_CpTable ; CP 15

ReturnFromHandler

; At this point:
;   R0 = the value returned by the second-level handler:
;          0 to return to the bounced instruction,
;          1 to return to the following instruction.
;   R1 contains NULL, or R1 -> user-level exception control block
;   R4 -> final 2 words of register dump (just above banked registers)
;   R5 = the Mode_mask bits of SPSR_undef
;   R6 = R14_undef value
;   R7 = SPSR_undef value

; Correct the return address,
; if R0 indicates we should return to the bounced instruction.

                TEQ     R0,#0
 if ARCH_HAS_THUMB2
                ADDNE   R6, R6, #1          ; if it was a 32-bit Thumb instruction and 1 was
                BICNE   R6, R6, #1          ; returned move return address 2 bytes forward
 endif
                SUBEQ   R6,R6,#2            ; back 2 for Thumb
                TSTEQ   R7, #Thumb_bit
                SUBEQ   R6,R6,#2            ; back 4 for ARM

; Now start returning to the original program. First prepare the new
; flag values in R7 for SPSR_undef, ready for the return.

                LDR     R0,[R4,#4]
                AND     R0,R0,#Flags_mask
                BIC     R7,R7,#Flags_mask
                ORR     R7,R7,R0

; Value returned in R1 is 0 for a return to the application

                TEQ     R1,#0
                BEQ     StandardReturn

; Return via user-level exception handler

; R1 points to the relevant control buffer,
; with the first entry the target handler code location.
; Replace with the true return address and add the saved CPSR and R14.

                LDR     R8,[R4,#-4]
                LDR     R2,[R1]
                STMIA   R1,{R6,R7,R8}

; Replace the R14 in the register dump with a pointer to the
; control data area.

                STR     R1,[R4,#-4]

; Prepare R6,R7 for exit to handler code.
; All handlers are entered in ARM state.

                MOV     R6,R2
                BIC     R7,R7,#(Java_bit|Flags_mask)
                BIC     R7,R7,#Thumb_bit
  if ARCH_V6_OR_LATER
; All handlers are entered in the same endianness as this handler.
    if {ENDIAN} = "big" :LAND: :LNOT: :DEF: ENDIAN_BE_32
                ORR     R7,R7,#Endian_bit
    else
                BIC     R7,R7,#Endian_bit
    endif
  endif

                ; fall through to standard return mechanism

StandardReturn

; Restore R14_svc and SPSR_svc.
; We do this _before_ the register restore code below, in case the Undef
; trap was taken in Supervisor Mode, and the handler has modified R14.
; If R13_svc was saved then this was the current R13 and (so long as
; the handler has not modified it) restoring it should have no effect.

                LDR     R14,[R4,#-16*4]
                MSR     SPSR_cxsf,R14
                LDR     R14,[R4,#-17*4]

; Now restore the banked registers: this is precisely like storing
; them in the first place, except that we already have suitable R4, R5
; and R7 values loaded.

                MRS     R1,CPSR

                TEQ     R5,#Mode_Usr32
                LDMEQDB R4,{R8-R14}^            ; User mode case
                BEQ     BankedLoadDone

                BIC     R2,R1,#Mode_mask
                ORR     R2,R2,R5                ; Non-user mode case
                MSR     CPSR_c,R2
                LDMDB   R4,{R8-R14}
                MSR     CPSR_c,R1

BankedLoadDone

; We will switch back to Undef mode to return, so that we can use
; R14_und and SPSR_und.  R14_svc and SPSR_svc may be live on return,
; and must not be corrupted.

; At this point:
;   R1 = the current CPSR
;   R4 -> final 2 words of register dump (just above banked registers)
;   R6 = the address to return to
;   R7 = value prepared for SPSR_undef
;   R8-R14 have been restored

                LDR     R2,[R4,#-15*4]   ; saved R0

; Switch to Undef mode.

                ORR     R0,R1,#8
                ASSERT  (Mode_Svc :OR: 8) = Mode_Undef
                MSR     CPSR_c,R0

; Prepare R14_und and SPSR_und for the return.
; Push the saved value of R0 on the Undef stack.

                MOV     R14,R6
                MSR     SPSR_csxf,R7
                STR     R2,[R13,#-4]!

; Switch back to Supervisor mode.

                MSR     CPSR_c,R1

; Restore R13, pop saved registers R1-R7,
; and kill Supervisor stack space.

                SUB     R13,R4,#14*4  ;  R13 -> R1 in register dump
                LDMIA   R13!,{R1-R7}
                ADD     R13,R13,#9*4

; Now R1-R14 have been restored.
; Switch back to Undef mode, pop R0,
; and return by writing to the PC with a SPSR->CPSR transfer.

                MSR     CPSR_c,R0
                LDR     R0,[R13],#4
                MOVS    PC,R14

        END                             ; Of file tlundef.s

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -