2005-04-16 15:20:36 -07:00
/ *
* linux/ a r c h / a r m / l i b / b a c k t r a c e . S
*
* Copyright ( C ) 1 9 9 5 , 1 9 9 6 R u s s e l l K i n g
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or modify
* it u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e v e r s i o n 2 a s
* published b y t h e F r e e S o f t w a r e F o u n d a t i o n .
*
* 2 7 / 0 3 / 0 3 Ian M o l t o n C l e a n u p C O N F I G _ C P U
*
* /
# include < l i n u x / c o n f i g . h >
# include < l i n u x / l i n k a g e . h >
# include < a s m / a s s e m b l e r . h >
.text
@ fp is 0 or stack frame
# define f r a m e r4
# define n e x t r5
# define s a v e r6
# define m a s k r7
# define o f f s e t r8
ENTRY( _ _ b a c k t r a c e )
mov r1 , #0x10
mov r0 , f p
ENTRY( c _ b a c k t r a c e )
2006-03-25 21:58:03 +00:00
# if ! d e f i n e d ( C O N F I G _ F R A M E _ P O I N T E R ) | | ! d e f i n e d ( C O N F I G _ P R I N T K )
2005-04-16 15:20:36 -07:00
mov p c , l r
# else
stmfd s p ! , { r4 - r8 , l r } @ Save an extra register so we have a location...
tst r1 , #0x10 @ 26 or 32-bit?
moveq m a s k , #0xfc000003
movne m a s k , #0
tst m a s k , r0
movne r0 , #0
movs f r a m e , r0
1 : moveq r0 , #- 2
LOADREGS( e q f d , s p ! , { r4 - r8 , p c } )
2 : stmfd s p ! , { p c } @ calculate offset of PC in STMIA instruction
ldr r0 , [ s p ] , #4
adr r1 , 2 b - 4
sub o f f s e t , r0 , r1
3 : tst f r a m e , m a s k @ Check for address exceptions...
bne 1 b
1001 : ldr n e x t , [ f r a m e , #- 12 ] @ get fp
1002 : ldr r2 , [ f r a m e , #- 4 ] @ get lr
1003 : ldr r3 , [ f r a m e , #0 ] @ get pc
sub s a v e , r3 , o f f s e t @ Correct PC for prefetching
bic s a v e , s a v e , m a s k
1004 : ldr r1 , [ s a v e , #0 ] @ get instruction at function
mov r1 , r1 , l s r #10
ldr r3 , . L d s i + 4
teq r1 , r3
subeq s a v e , s a v e , #4
mov r0 , s a v e
bic r1 , r2 , m a s k
bl d u m p _ b a c k t r a c e _ e n t r y
ldr r0 , [ f r a m e , #- 8 ] @ get sp
sub r0 , r0 , #4
1005 : ldr r1 , [ s a v e , #4 ] @ get instruction at function+4
mov r3 , r1 , l s r #10
ldr r2 , . L d s i + 4
teq r3 , r2 @ Check for stmia sp!, {args}
addeq s a v e , s a v e , #4 @ next instruction
bleq . L d u m p s t m
sub r0 , f r a m e , #16
1006 : ldr r1 , [ s a v e , #4 ] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
mov r3 , r1 , l s r #10
ldr r2 , . L d s i
teq r3 , r2
bleq . L d u m p s t m
/ *
* A z e r o n e x t f r a m e p o i n t e r m e a n s w e ' r e d o n e .
* /
teq n e x t , #0
LOADREGS( e q f d , s p ! , { r4 - r8 , p c } )
/ *
* The n e x t f r a m e p o i n t e r m u s t b e a b o v e t h e
* current f r a m e p o i n t e r .
* /
cmp n e x t , f r a m e
mov f r a m e , n e x t
bhi 3 b
b 1 0 0 7 f
/ *
* Fixup f o r L D M D B
* /
.section .fixup , " ax"
.align 0
1007 : ldr r0 , = . L b a d
mov r1 , f r a m e
bl p r i n t k
LOADREGS( f d , s p ! , { r4 - r8 , p c } )
.ltorg
.previous
.section _ _ ex_ t a b l e ," a "
.align 3
.long 1 0 0 1 b, 1 0 0 7 b
.long 1 0 0 2 b, 1 0 0 7 b
.long 1 0 0 3 b, 1 0 0 7 b
.long 1 0 0 4 b, 1 0 0 7 b
.long 1 0 0 5 b, 1 0 0 7 b
.long 1 0 0 6 b, 1 0 0 7 b
.previous
# define i n s t r r4
# define r e g r5
# define s t a c k r6
.Ldumpstm : stmfd s p ! , { i n s t r , r e g , s t a c k , r7 , l r }
mov s t a c k , r0
mov i n s t r , r1
mov r e g , #9
mov r7 , #0
1 : mov r3 , #1
tst i n s t r , r3 , l s l r e g
beq 2 f
add r7 , r7 , #1
teq r7 , #4
moveq r7 , #0
moveq r3 , #' \n '
movne r3 , #' '
ldr r2 , [ s t a c k ] , #- 4
mov r1 , r e g
adr r0 , . L f p
bl p r i n t k
2 : subs r e g , r e g , #1
bpl 1 b
teq r7 , #0
adrne r0 , . L c r
blne p r i n t k
mov r0 , s t a c k
LOADREGS( f d , s p ! , { i n s t r , r e g , s t a c k , r7 , p c } )
.Lfp : .asciz " r% d = % 0 8 X % c "
.Lcr : .asciz " \ n"
.Lbad : .asciz " Backtrace a b o r t e d d u e t o b a d f r a m e p o i n t e r < % p > \ n "
.align
.Ldsi : .word 0x00e92dd8 > > 2
.word 0x00e92d00 > > 2
# endif