📄 suppasm.s
字号:
SUBS a1, lr, a4 LDRNE pc, [sp], #4 CMP lr, #0 CMPNE a4, #0 SUBNES a3, a3, #1 BNE %0 LDR pc, [sp], #4 EXPORT __rt_strcpy__rt_strcpy ROUT MOV ip, a10 LDRB a3, [a2], #1 STRB a3, [ip], #1 CMP a3, #0 BNE %0 MOV pc, lr EXPORT __rt_strcat__rt_strcat ROUT MOV ip, a1 ; so we can return a10 LDRB a3, [ip], #1 CMP a3, #0 BNE %0 SUB ip, ip, #1 ; want to overwrite NUL 1 LDRB a3, [a2], #1 STRB a3, [ip], #1 CMP a3, #0 BNE %1 MOV pc, lr IF :DEF: LINKING_WITH_CLIB ; stack checking support is in the C lib ELSE ; --------------------------------------------------------------------- ; -- Software stack checking support ---------------------------------- ; --------------------------------------------------------------------- ; The following functions are provided for software stack ; checking. If hardware stack-checking is being used then the ; code can be compiled without the PCS entry checks, and ; simply rely on VM management to extend the stack for a ; thread. ; ; The stack extension event occurs when the PCS function ; entry code would result in a stack-pointer beneath the ; stack-limit register value. The system relies on the ; following map: ; ; +-----------------------------------+ <-- end of stack block ; | ... | ; | ... | ; | active stack | ; | ... | <-- sp (stack-pointer) somewhere in here ; | ... | ; +-----------------------------------+ <-- sl (stack-limit) ; | stack-extension handler workspace | ; +-----------------------------------+ <-- base of stack block ; ; The "stack-extension handler workspace" is an amount of ; memory in which the stack overflow support code must ; execute. It must be large enough to deal with the worst ; case through the stack overflow handler code. ; ; At the moment the compiler expects this to be AT LEAST ; 256bytes. It uses this fact to code functions with small ; local data usage within the overflow space. ; ; NOTE: We may need to increase the space between sl and the ; true limit to allow for the stack extension code and any ; other system software that may temporarily use the stack of ; the current foreground thread. ; ; The following example stack overflow handling code requires ; the following run-time functions: ; __rt_allocmem ; Kernel memory allocator "malloc" ; __rt_freemem ; Kernel memory allocator "free" ; We need to ensure that the MAXIMUM stack usage possible by the ; above routines, fits into the stack overflow handler space ; left beneath the "sl" value. The above routines also need to ; be compiled with stack-overflow checking disabled. ; ; If the "__rt_" routines needed by this code are not ; interrupt safe (i.e. if they cannot be called from within an ; interrupt handler) then this code must ensure that any code ; executing as part of an interrupt handler does NOT generate ; a stack extension event. AREA |StackOverflow$$Code|,CODE,READONLY KEEP ; NOTE: This code assumes that it is entered with a valid ; frame-pointer. If the system is being constructed without ; frame-pointer support, then the following code will not ; work, and an alternative means of providing soft ; stack-extension will need to be coded. EXPORT __rt_stkovf_split_small__rt_stkovf_split_small ; Called when we have a standard register saving only ; stack-limit check failure. MOV ip,sp ; ensure we can calculate the amount of stack required ; and then fall through to... IMPORT Angel_StackBase EXPORT __rt_stkovf_split_big__rt_stkovf_split_big ; If we are in a privileged mode then stack overflow is fatal, so ; we should do nothing more than output a debugging message and ; give up! MRS r0, CPSR AND r0, r0, #ModeMask CMP r0, #USRmode BEQ USRmodeStackCheck MOV r1, r0 ADR r0, PrivilegedStackOverflowMessage ; r0 == a1 B __rt_asm_fatalerror PrivilegedStackOverflowMessage DCB "Stack Overflow in mode %2X\n" ALIGNUSRmodeStackCheck ; If this is the AngelStack then sl should ; be somewhere within the Angel Stack range LDR r1, =Angel_StackBase LDR r1, [r1] ADD r0, r1, #Angel_AngelStackLimitOffset ADD r1, r1, #Angel_AngelStackOffset SUB r1, r1, #1 CMP sl, r0 CMPHS r1, slAngelStackOverflow BHS AngelStackOverflowRealStackCheckCode ; Called when we have a large local stack allocation (> ; 256bytes with the current C compiler) which would cause an ; overflow. This version is called when the compiler generated ; PCS code has checked its requirement against the stack-limit ; register. ; ; in: sp = current stack-pointer (beneath stack-limit) ; sl = current stack-limit ; ip = low stack point we require for the current function ; lr = return address back to the function requiring more stack ; fp = frame-pointer ; ; original sp --> +----------------------------------+ ; | pc (12 ahead of PCS entry store) | ; current fp ---> +----------------------------------+ ; | lr (on entry) pc (on exit) | ; +----------------------------------+ ; | sp ("original sp" on entry) | ; +----------------------------------+ ; | fp (on entry to function) | ; +----------------------------------+ ; | | ; | ..argument and work registers.. | ; | | ; current sp ---> +----------------------------------+ ; ; The "current sl" is somewhere between "original sp" and ; "current sp" but above "true sl". The "current sl" should be ; "APCS_STACKGUARD" bytes above the "true sl". The value ; "APCS_STACKGUARD" should be large enough to deal with the ; worst case function entry stacking (160bytes) plus the stack ; overflow handler stacking requirements, plus the stack ; required for the memory allocation routines, and the ; exception handling code. ; ; THINGS TO NOTE: ; We should ensure that every function that calls ; "__rt_stkovf_split_small" or "__rt_stkovf_split_big" does so ; with a valid PCS. ie. they should use "fp" to de-stack on ; exit (see notes above). ; ; Code should never poke values beneath sp. The sp register ; should always be "dropped" first to cover the data. This ; protects the data against any events that may try and use ; the stack. This is a requirement of APCS-3. ; SUB ip,sp,ip ; extra stack required for the function STMFD sp!,{v1,v2,lr} ; temporary work registers ; ; For simplicity never attempt to extend the stack just report ; an overflow.RaiseStackOverflow ; in: v1 = undefined ; v2 = undefined ; sl = stack-limit ; ip = amount of stack required ; sp = FD stack containing {v1,v2,lr} ; lr = undefined ; ;; 960506 KWelton ;; ;; I'm not sure what this is trying to do, but it all seems redundant ;; to me - what we *really* want to do is report the overflow, and ;; then stop in a tight loop. ;; others disagree... this kills Angel, and without angel debug ;; code, this is not useful. IJ has requested that such errors ;; cause a restart of angel (i.e. jump to __rt_angel_restart) ;; while debug builds can jump to Deadloop. -- 22/10/97 RIC IF {FALSE} MRS v1,CPSR ; get current PSR TST v1,#ModeMaskUFIS MOV v2, a1 LDR a1, =angel_SWIreason_EnterSVC DCD angel_SWI_ARM MOV a1, v2 ; We are now in a suitably priviledged mode. MSR SPSR,v1 ; get original PSR into SPSR STMFD sp!,{r10-r12} ; work registers LDR r10,=ADP_Stopped_RunTimeError MOV r11,#ADP_RunTime_Error_StackOverflow MOV lr,pc ; return address ELSE MOV a1, #angel_SWIreason_ReportException LDR a2, =ADP_Stopped_StackOverflow DCD angel_SWI_ARM ENDIF ;; If we get here, print a message and die... ADR a1, stkovfmsg B __rt_asm_fatalerrorstkovfmsg DCB "Stack Overflow\n" ALIGN ;; This instruction matched a STM above, but I can't see any way ;; of actualy executing it!! It should probably be removed. -- ric LDMFD sp!,{v1,v2,pc} ; and return to caller ENDIF ; :DEF: LINKING_WITH_CLIB ; --------------------------------------------------------------------- IF CACHE_SUPPORTED <> 0 ; Added for EBSARM, Instruction barrier range function. r0 ; contains start of range, r1 end.Cache_IBR ; Simply call the board dependent macro CACHE_IBR r0,r1,r2,r3 ; And return MOV pc,lr ENDIF IMPORT Angel_EnterSVC EXPORT __rt_uninterruptable_loop__rt_uninterruptable_loop MRS a1, CPSR AND a2, a1, #ModeMask CMP a2, #USRmode BLEQ Angel_EnterSVC ORRNE a1, a1, #IRQDisable + FIQDisable MSRNE CPSR_cxsf, a1DeadLoop B DeadLoop ; This code simulates the LogFatalError macro used in the C parts of ; Angel. Enter it with a1 pointing at the error message. EXPORT __rt_asm_fatalerror IMPORT __rt_logerror, WEAK IMPORT __rt_logmsginfo, WEAK__rt_asm_fatalerror ;; if the logerror routine exists, use it to print the message LDR a2, =__rt_logerror CMP a2, #0 BEQ no_logerror ;; these variables are used in C code to say where the call came from; ;; we don't have that info to hand for asm. STMFD sp!, {r1,r2,r3} MOV r1, #0 MOV r2, #0 MOV r3, #0 BL __rt_logmsginfo LDMFD sp!, {r1,r2,r3} BL __rt_logerrorno_logerror ; debug build jumps into DeadLoop, release build restarts Angel. IF DEBUG = 1 BL __rt_uninterruptable_loop ELSE BL __rt_angel_restart ENDIF ;; This routine exists as the action used when Angel needs to be ;; restarted. There are two occasions; when the debugger asks for ;; it, and when Angel detects a fatal error. The routine should ;; reload Angel from ROM, if possible, and restart as if a ;; power-on-reset had just occurred, as NOTHING can be assumed about ;; the current state of anything in RAM. ;; ;; THIS ROUTINE NEVER RETURNS! __rt_angel_restart IMPORT __rom EXPORT __rt_angel_restart ;; for the moment, just start at the beginning again... B __rom ;; This is the interrupt system initialisation routine added ;; to allow it to be called at will as a function.Init_Interrupt EXPORT Init_Interrupt IF :DEF: AT91_AIC_IRQ IF AT91_AIC_IRQ <> 0 GET aic.inc ;INITAIC r0,r1,r2,r3 ENDIF ENDIF mov pc,lr IF :DEF: AT91_AIC_IRQ IF AT91_AIC_IRQ <> 0Get_Mode EXPORT Get_Mode MRS r0, CPSR MOV pc, lr ENDIF ENDIF IF :DEF: AT91_AIC_IRQ IF AT91_AIC_IRQ = 2 EXPORT Interrupt_veneerInterrupt_veneer SUB lr, lr, #4 ; Return from int address STMFD sp!, {r0-r3,lr} ; Silicon bug fix - return if IRQ is taken whilst disabled MRS r0, SPSR ANDS r14, r0, #0x80 ; I_BIT LDMNEFD sp!,{r0-r3, pc}^ ; Now find out where the interrupt is called from (AIC vector) LDR r3, =INT_IVR LDR r3, [r3] ; Now call the Interrupt Handler MOV lr, pc MOV pc, r3 ; To handler ;; Should return here LDMFD sp!, {r0-r3, pc}^ ENDIF ENDIF END ; EOF suppasm.s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -