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

📄 dabort.s

📁 wince5.0 BSP包
💻 S
📖 第 1 页 / 共 5 页
字号:

          [ HandlerSL = ""
                INFO    ERROR, \
                        "'HandlerSL' has not been specified."
          ]

          [ ((HandlerSL:LEFT:1) = VBar) \
            :LEOR: ((HandlerSL:RIGHT:1) = VBar)
                INFO    ERROR, \
                        "Vertical bar error in 'HandlerSL'"
          ]
          [ (HandlerSL:LEFT:1) <> VBar
HandlerSL       SETS    VBar:CC:HandlerSL:CC:VBar
          ]

        |

          [ HandlerSL <> ""
                INFO    WARNING, \
                        "'HandlerSL' will not be used."
          ]

        ]

; * The parameter-passing options 'PassSPSR', 'PassInstrAddr',
;   'PassRegDumpAddr' and 'PassXferAddr' all default to {FALSE}.

        [ :LNOT::DEF:PassSPSR
                GBLL    PassSPSR
PassSPSR        SETL    {FALSE}
        ]

        [ :LNOT::DEF:PassInstrAddr
                GBLL    PassInstrAddr
PassInstrAddr   SETL    {FALSE}
        ]

        [ :LNOT::DEF:PassRegDumpAddr
                GBLL    PassRegDumpAddr
PassRegDumpAddr SETL    {FALSE}
        ]

        [ :LNOT::DEF:PassXferAddr
                GBLL    PassXferAddr
PassXferAddr    SETL    {FALSE}
        ]

; * The 'allowed return values' options all default to not allowing
;   the return value, but some must be specified, including at least
;   one that is legitimate when an error occurs.

        [ :LNOT::DEF:ReturnNormal
                GBLL    ReturnNormal
ReturnNormal    SETL    {FALSE}
        ]

        [ :LNOT::DEF:ReturnUndef
                GBLS    ReturnUndef
ReturnUndef     SETS    ""
        ]

        [ (ReturnUndef <> "") :LAND: ((ReturnUndef:LEFT:2) <> "0x")
          [ ((ReturnUndef:LEFT:1) = VBar) \
            :LEOR: ((ReturnUndef:RIGHT:1) = VBar)
                INFO    ERROR, \
                        "Vertical bar error in 'ReturnUndef'"
          ]
          [ (ReturnUndef:LEFT:1) <> VBar
ReturnUndef     SETS    VBar:CC:ReturnUndef:CC:VBar
          ]
        ]

        [ :LNOT::DEF:ReturnToNext
                GBLS    ReturnToNext
ReturnToNext    SETS    ""
        ]

        [ ReturnToNext <> ""
          [ ((ReturnToNext:LEFT:1) = VBar) \
            :LEOR: ((ReturnToNext:RIGHT:1) = VBar)
                INFO    ERROR, \
                        "Vertical bar error in 'ReturnToNext'"
          ]
          [ (ReturnToNext:LEFT:1) <> VBar
ReturnToNext    SETS    VBar:CC:ReturnToNext:CC:VBar
          ]
        ]

        [ :LNOT::DEF:ReturnAddress
                GBLL    ReturnAddress
ReturnAddress   SETL    {FALSE}
        ]

        [ (ReturnUndef = "") :LAND: (:LNOT:ReturnAddress)
                INFO    ERROR, \
                        "No legitimate return value for errors."
        ]

; * 'SuptThumb' defaults to {TRUE}.

        [ :LNOT::DEF:SuptThumb
                GBLL    SuptThumb
SuptThumb       SETL    {TRUE}
        ]

; * 'StrictErrors' defaults to {TRUE}.

        [ :LNOT::DEF:StrictErrors
                GBLL    StrictErrors
StrictErrors    SETL    {TRUE}
        ]

; * The defined-but-not-implemented options 'SuptBaseEqIndex' and
;   'SuptLoadBaseWB' get their default values, with errors/warnings if
;   the as-yet-unsupported option is chosen.

        [ :LNOT::DEF:SuptBaseEqIndex
                GBLL    SuptBaseEqIndex
SuptBaseEqIndex SETL    {FALSE}
        ]

        [ SuptBaseEqIndex
                INFO    ERROR, \
                        "'SuptBaseEqIndex' option not yet implemented"
        ]

        [ :LNOT::DEF:SuptLoadBaseWB
                GBLL    SuptLoadBaseWB
SuptLoadBaseWB  SETL    {FALSE}
        ]

        [ SuptLoadBaseWB
                INFO    ERROR, \
                        "'SuptLoadBaseWB' option not yet implemented"
        ]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Definitions that depend on assembly-time options
; ================================================
;
; The following macro does the final stages of the call to the
; OS-specific handler.

                MACRO
$label          HandlerInternalMacro
                ALIGN
$label
        [ HandlerCallStd = "APCS_MACRO"
                $HandlerName
        |
          [ HandlerCallStd = "APCS_SWST"
                LDR     R10, =$HandlerSL
          ]
                IMPORT  $HandlerName
                BL      $HandlerName
        ]
                MEND

; Specific return values allowed from OS-specific handler. These
; definitions are made dependent on the relevant assembly-time option
; in order to catch coding errors.

        [ ReturnNormal
DABORT_RETVAL_NORMAL    EQU     0x0
        ]

        [ ReturnUndef <> ""
DABORT_RETVAL_UNDEF     EQU     0x4
        ]

        [ ReturnToNext <> ""
DABORT_RETVAL_TONEXT    EQU     0x10
        ]

; Error codes.

DABORT_ERROR_BAD_REQUEST        EQU     -1
DABORT_ERROR_NONE               EQU     0
DABORT_ERROR_BASEEQINDEX_PRE    EQU     1
DABORT_ERROR_BASEEQINDEX_POST   EQU     2
DABORT_ERROR_R15_WB             EQU     3
DABORT_ERROR_BASE_R15           EQU     4
DABORT_ERROR_INDEX_R15          EQU     5
DABORT_ERROR_LOAD_WB            EQU     6
DABORT_ERROR_LDMSTM_EMPTY       EQU     7
DABORT_ERROR_USERBANK_WB        EQU     8
DABORT_ERROR_BAD_INSTR          EQU     9

; Abort models.

        [ BaseRestored
DABORT_MODEL_BASERESTORED       EQU     0
        ]

        [ EarlyAbort
DABORT_MODEL_EARLYABORT         EQU     1
        ]

        [ BaseUpdated
DABORT_MODEL_BASEUPDATED        EQU     3
        ]

        [ AbortModelInit <> ""
DABORT_MODEL_INITIALISATION     EQU     0x40000000      ; And higher
        ]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Start of generated code
; =======================
;
; Start by declaring the area.

                AREA    $AreaName, CODE

; The main entry point
; ====================

$VeneerEntry
                EXPORT  $VeneerEntry

; First thing the code must do is set up its register dump. This has
; to be done carefully, to ensure that the correct mode's registers
; are stored. We start by reserving the right amount of space and
; dumping the unbanked registers, to give ourselves some space to work
; in. We also get the return link and SPSR into callee-saved registers
; at this point, adjusting the return link to point to the aborting
; instruction in the process.

                SUB     R13, R13, #15*4
                STMIA   R13, {R0-R7}
                SUB     R4, R14, #PCOffset_DAbort
                MRS     R5, SPSR

; Now do the rest of the registers. This usually involves switching to
; the mode concerned (or strictly speaking, to its 32-bit equivalent),
; dumping the registers and switching back. However, if the mode
; concerned is a user mode, we must instead use a "user bank" STM, to
; avoid getting trapped in user mode.

                ADD     R0, R13, #8*4   ; Place to dump registers

                ANDS    R1, R5, #Mode_MainMask
                ASSERT  (Mode_User:AND:Mode_MainMask) = 0
                STMEQIA R0, {R8-R14}^
                BEQ     RegsDumped

                MRS     R2, CPSR
                BIC     R3, R2, #Mode_MainMask
                ORR     R1, R3, R1
                MSR     CPSR$all_fields, R1
                STMIA   R0, {R8-R14}
                MSR     CPSR$all_fields, R2

RegsDumped

; *** Live register values at this point are:
;     R4:  Pointer to aborting instruction
;     R5:  SPSR value
;     R13: Stack pointer (pointing to register dump)
;
; Find out what abort model we're using (if relevant) and initialise
; the error code.

        [ AbortModelVar <> ""
                IMPORT  $AbortModelVar
                LDR     R6, =$AbortModelVar
                LDR     R8, [R6]
          [ AbortModelInit <> ""
                CMP     R8, #DABORT_MODEL_INITIALISATION
                BHS     Initialisation_Handler
          ]
        ]

                MOV     R6, #DABORT_ERROR_NONE

; We need to obtain and analyse the aborting instruction in any of the
; following circumstances:
;
; * If "StrictErrors" is set.
;
; * If we're expected to pass the instruction's transfer address as a
;   parameter to the OS-specific handler.
;
; * If we're dealing with anything other than the Base Restored Abort
;   Model.

        [ StrictErrors \
          :LOR: PassXferAddr \
          :LOR: (:LNOT:BaseRestored) \
          :LOR: (AbortModelCount > 1)

          [ (:LNOT:StrictErrors) \
            :LAND: (:LNOT:PassXferAddr) \
            :LAND: BaseRestored

                ASSERT  AbortModelVar <> ""     ; So R8 was loaded
                CMP     R8, #DABORT_MODEL_BASERESTORED
                BEQ     CallOSHandlerWithError

          ]

          [ SuptThumb
; Test for whether the instruction is a Thumb instruction, and branch
; off to separate code to handle it if so.

                TST     R5, #T_bit
                BNE     ThumbInstruction
          ]

ARMInstruction

; ARM instruction analysis
; ========================
;
; Get the instruction. We can use a normal LDR instruction to do this,
; not an LDRT, even if we were invoked from user mode, because:
;
; * The fact that a data abort occurred on the offending instruction,
;   not a prefetch abort, indicates that the instruction was
;   accessible from user mode.
;
; * User mode programs cannot fake a data abort vector entry in order
;   to create a security loophole. (They can branch to location 0x10,
;   but cannot also get into a privileged mode unless they take the
;   data abort trap.)

                LDR     R0, [R4]

; *** Live register values at this point are:
;     R0:  Aborting instruction
;     R4:  Pointer to aborting instruction
;     R5:  SPSR value
;     R6:  Error code
;     R8:  Abort model (if relevant)
;     R13: Stack pointer (pointing to register dump)
;
; Now start analysing the instruction. The objective of this stage is
; to end up with:
;
;     R0:  M bit (bit 27) indicating multiple vs. single transfer.
;          P bit (bit 24) indicating pre- vs. post-indexing.
;          U bit (bit 23) indicating whether indexing is up or down.
;          W bit (bit 21) indicating whether base register writeback
;            is required.
;          L bit (bit 20) indicating whether a load or a store, at least
;            when writeback is involved or there is a potential "user bank"
;            LDM.
;     R1:  Number of base register, still in instruction position.
;     R2:  Offset value.
;     R3:  Number of destination register, still in instruction
;          position (for all but LDM/STM/LDC/STC).
;
; In many cases, R0 will be the unchanged instruction; however, it
; does get changed in some circumstances to "standardise" the meanings
; of the bits.
;
; R1 and R3 are particularly simple, since the base register field is
; in the same position for all ARM load/store instructions, and the
; destination field is in the same position for all single load
; instructions.

                AND     R1, R0, #ARM_Rn_mask
                AND     R3, R0, #ARM_Rd_mask

; Now split according to the major class of the instruction - i.e.
; bits 27:25.

                AND     R2, R0, #(0x7:SHL:25)
                ADD     PC, PC, R2, LSR #23

                NOP                             ;Branch table padding

                B       ARM_Odds_And_Ends       ;SWP, LDRH, etc.
                B       ARM_Should_Not_Happen   ;(Data processing)
                B       ARM_LDR_STR_Immed
                B       ARM_LDR_STR_Reg
                B       ARM_LDM_STM
                B       ARM_Should_Not_Happen   ;(B/BL)
                B       ARM_LDC_STC
ARM_Should_Not_Happen                           ;(CDP/MRC/MCR/SWI)
                MOV     R6, #DABORT_ERROR_BAD_INSTR
                B       CallOSHandlerWithError

; Analysis of ARM SWP/SWPB/LDRH/LDRSB/LDRSH/STRH instructions
; -----------------------------------------------------------
;
; Start by distinguishing SWP instructions from the rest.

ARM_Odds_And_Ends

⌨️ 快捷键说明

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