📄 oemabort.lst
字号:
503 00000000 ]
504 00000000
505 00000000 ; * The defined-but-not-implemented options 'SuptBaseEqIndex' and
506 00000000 ; 'SuptLoadBaseWB' get their default values, with errors/warnings if
507 00000000 ; the as-yet-unsupported option is chosen.
508 00000000
509 00000000 [ :LNOT::DEF:SuptBaseEqIndex
510 00000000 GBLL SuptBaseEqIndex
511 00000000 SuptBaseEqIndex SETL {FALSE}
512 00000000 ]
513 00000000
514 00000000 [ SuptBaseEqIndex
517 00000000 ]
518 00000000
519 00000000 [ :LNOT::DEF:SuptLoadBaseWB
520 00000000 GBLL SuptLoadBaseWB
521 00000000 SuptLoadBaseWB SETL {FALSE}
522 00000000 ]
523 00000000
524 00000000 [ SuptLoadBaseWB
527 00000000 ]
528 00000000
529 00000000 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
530 00000000 ;
531 00000000 ; Definitions that depend on assembly-time options
532 00000000 ; ================================================
533 00000000 ;
534 00000000 ; The following macro does the final stages of the call to the
535 00000000 ; OS-specific handler.
536 00000000
537 00000000 MACRO
538 00000000 $label HandlerInternalMacro
539 00000000 ALIGN
540 00000000 $label
541 00000000 [ HandlerCallStd = "APCS_MACRO"
542 00000000 $HandlerName
543 00000000 |
544 00000000 [ HandlerCallStd = "APCS_SWST"
545 00000000 LDR R10, =$HandlerSL
546 00000000 ]
547 00000000 IMPORT $HandlerName
548 00000000 BL $HandlerName
549 00000000 ]
550 00000000 MEND
551 00000000
552 00000000 ; Specific return values allowed from OS-specific handler. These
553 00000000 ; definitions are made dependent on the relevant assembly-time option
554 00000000 ; in order to catch coding errors.
555 00000000
556 00000000 [ ReturnNormal
558 00000000 ]
559 00000000
560 00000000 [ ReturnUndef <> ""
561 00000000 DABORT_RETVAL_UNDEF EQU 0x4
562 00000000 ]
563 00000000
564 00000000 [ ReturnToNext <> ""
565 00000000 DABORT_RETVAL_TONEXT EQU 0x10
566 00000000 ]
567 00000000
568 00000000 ; Error codes.
569 00000000
570 00000000 DABORT_ERROR_BAD_REQUEST EQU -1
571 00000000 DABORT_ERROR_NONE EQU 0
572 00000000 DABORT_ERROR_BASEEQINDEX_PRE EQU 1
573 00000000 DABORT_ERROR_BASEEQINDEX_POST EQU 2
574 00000000 DABORT_ERROR_R15_WB EQU 3
575 00000000 DABORT_ERROR_BASE_R15 EQU 4
576 00000000 DABORT_ERROR_INDEX_R15 EQU 5
577 00000000 DABORT_ERROR_LOAD_WB EQU 6
578 00000000 DABORT_ERROR_LDMSTM_EMPTY EQU 7
579 00000000 DABORT_ERROR_USERBANK_WB EQU 8
580 00000000 DABORT_ERROR_BAD_INSTR EQU 9
581 00000000
582 00000000 ; Abort models.
583 00000000
584 00000000 [ BaseRestored
585 00000000 DABORT_MODEL_BASERESTORED EQU 0
586 00000000 ]
587 00000000
588 00000000 [ EarlyAbort
590 00000000 ]
591 00000000
592 00000000 [ BaseUpdated
594 00000000 ]
595 00000000
596 00000000 [ AbortModelInit <> ""
598 00000000 ]
599 00000000
600 00000000 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
601 00000000 ;
602 00000000 ; Start of generated code
603 00000000 ; =======================
604 00000000 ;
605 00000000 ; Start by declaring the area.
606 00000000
607 AREA |.text|, CODE
608 00000000
609 00000000 ; The main entry point
610 00000000 ; ====================
611 00000000
612 00000000 |OEMDataAbortHandler|
613 00000000 EXPORT |OEMDataAbortHandler|
614 00000000
615 00000000 ; First thing the code must do is set up its register dump. This has
616 00000000 ; to be done carefully, to ensure that the correct mode's registers
617 00000000 ; are stored. We start by reserving the right amount of space and
618 00000000 ; dumping the unbanked registers, to give ourselves some space to work
619 00000000 ; in. We also get the return link and SPSR into callee-saved registers
620 00000000 ; at this point, adjusting the return link to point to the aborting
621 00000000 ; instruction in the process.
622 00000000
623 00000000 e24dd03c SUB R13, R13, #15*4
624 00000004 e88d00ff STMIA R13, {R0-R7}
625 00000008 e24e4008 SUB R4, R14, #PCOffset_DAbort
626 0000000c e14f5000 MRS R5, SPSR
627 00000010
628 00000010 ; Now do the rest of the registers. This usually involves switching to
629 00000010 ; the mode concerned (or strictly speaking, to its 32-bit equivalent),
630 00000010 ; dumping the registers and switching back. However, if the mode
631 00000010 ; concerned is a user mode, we must instead use a "user bank" STM, to
632 00000010 ; avoid getting trapped in user mode.
633 00000010
634 00000010 e28d0020 ADD R0, R13, #8*4 ; Place to dump registers
635 00000014
636 00000014 e215100f ANDS R1, R5, #Mode_MainMask
637 00000018 ASSERT (Mode_User:AND:Mode_MainMask) = 0
638 00000018 08c07f00 STMEQIA R0, {R8-R14}^
639 0000001c 0a000005 BEQ RegsDumped
640 00000020
641 00000020 e10f2000 MRS R2, CPSR
642 00000024 e3c2300f BIC R3, R2, #Mode_MainMask
643 00000028 e1831001 ORR R1, R3, R1
644 0000002c e129f001 MSR CPSR_fc, R1
645 00000030 e8807f00 STMIA R0, {R8-R14}
646 00000034 e129f002 MSR CPSR_fc, R2
647 00000038
648 00000038 RegsDumped
649 00000038
650 00000038 ; *** Live register values at this point are:
651 00000038 ; R4: Pointer to aborting instruction
652 00000038 ; R5: SPSR value
653 00000038 ; R13: Stack pointer (pointing to register dump)
654 00000038 ;
655 00000038 ; Find out what abort model we're using (if relevant) and initialise
656 00000038 ; the error code.
657 00000038
658 00000038 [ AbortModelVar <> ""
666 00000038 ]
667 00000038
668 00000038 e3a06000 MOV R6, #DABORT_ERROR_NONE
669 0000003c
670 0000003c ; We need to obtain and analyse the aborting instruction in any of the
671 0000003c ; following circumstances:
672 0000003c ;
673 0000003c ; * If "StrictErrors" is set.
674 0000003c ;
675 0000003c ; * If we're expected to pass the instruction's transfer address as a
676 0000003c ; parameter to the OS-specific handler.
677 0000003c ;
678 0000003c ; * If we're dealing with anything other than the Base Restored Abort
679 0000003c ; Model.
680 0000003c
681 0000003c [ StrictErrors :LOR: PassXferAddr :LOR: (:LNOT:BaseRestored) :LOR: (AbortModelCount > 1)
685 0000003c
686 0000003c [ (:LNOT:StrictErrors) :LAND: (:LNOT:PassXferAddr) :LAND: BaseRestored
694 0000003c ]
695 0000003c
696 0000003c [ SuptThumb
697 0000003c ; Test for whether the instruction is a Thumb instruction, and branch
698 0000003c ; off to separate code to handle it if so.
699 0000003c
700 0000003c e3150020 TST R5, #T_bit
701 00000040 1a000078 BNE ThumbInstruction
702 00000044 ]
703 00000044
704 00000044 ARMInstruction
705 00000044
706 00000044 ; ARM instruction analysis
707 00000044 ; ========================
708 00000044 ;
709 00000044 ; Get the instruction. We can use a normal LDR instruction to do this,
710 00000044 ; not an LDRT, even if we were invoked from user mode, because:
711 00000044 ;
712 00000044 ; * The fact that a data abort occurred on the offending instruction,
713 00000044 ; not a prefetch abort, indicates that the instruction was
714 00000044 ; accessible from user mode.
715 00000044 ;
716 00000044 ; * User mode programs cannot fake a data abort vector entry in order
717 00000044 ; to create a security loophole. (They can branch to location 0x10,
718 00000044 ; but cannot also get into a privileged mode unless they take the
719 00000044 ; data abort trap.)
720 00000044
721 00000044 e5940000 LDR R0, [R4]
722 00000048
723 00000048 ; *** Live register values at this point are:
724 00000048 ; R0: Aborting instruction
725 00000048 ; R4: Pointer to aborting instruction
726 00000048 ; R5: SPSR value
727 00000048 ; R6: Error code
728 00000048 ; R8: Abort model (if relevant)
729 00000048 ; R13: Stack pointer (pointing to register dump)
730 00000048 ;
731 00000048 ; Now start analysing the instruction. The objective of this stage is
732 00000048 ; to end up with:
733 00000048 ;
734 00000048 ; R0: M bit (bit 27) indicating multiple vs. single transfer.
735 00000048 ; P bit (bit 24) indicating pre- vs. post-indexing.
736 00000048 ; U bit (bit 23) indicating whether indexing is up or down.
737 00000048 ; W bit (bit 21) indicating whether base register writeback
738 00000048 ; is required.
739 00000048 ; L bit (bit 20) indicating whether a load or a store, at least
740 00000048 ; when writeback is involved or there is a potential "user bank"
741 00000048 ; LDM.
742 00000048 ; R1: Number of base register, still in instruction position.
743 00000048 ; R2: Offset value.
744 00000048 ; R3: Number of destination register, still in instruction
745 00000048 ; position (for all but LDM/STM/LDC/STC).
746 00000048 ;
747 00000048 ; In many cases, R0 will be the unchanged instruction; however, it
748 00000048 ; does get changed in some circumstances to "standardise" the meanings
749 00000048 ; of the bits.
750 00000048 ;
751 00000048 ; R1 and R3 are particularly simple, since the base register field is
752 00000048 ; in the same position for all ARM load/store instructions, and the
753 00000048 ; destination field is in the same position for all single load
754 00000048 ; instructions.
755 00000048
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -