Linux-2.6.12-rc2
[linux-2.6.git] / arch / arm26 / lib / backtrace.S
1 /*
2  *  linux/arch/arm26/lib/backtrace.S
3  *
4  *  Copyright (C) 1995, 1996 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10 #include <linux/config.h>
11 #include <linux/linkage.h>
12 #include <asm/assembler.h>
13                 .text
14
15 @ fp is 0 or stack frame
16
17 #define frame   r4
18 #define next    r5
19 #define save    r6
20 #define mask    r7
21 #define offset  r8
22
23 ENTRY(__backtrace)
24                 mov     r1, #0x10
25                 mov     r0, fp
26
27 ENTRY(c_backtrace)
28
29 #ifdef CONFIG_NO_FRAME_POINTER
30                 mov     pc, lr
31 #else
32
33                 stmfd   sp!, {r4 - r8, lr}      @ Save an extra register so we have a location...
34                 mov     mask, #0xfc000003
35                 tst     mask, r0
36                 movne   r0, #0
37                 movs    frame, r0
38 1:              moveq   r0, #-2
39                 LOADREGS(eqfd, sp!, {r4 - r8, pc})
40
41 2:              stmfd   sp!, {pc}               @ calculate offset of PC in STMIA instruction
42                 ldr     r0, [sp], #4
43                 adr     r1, 2b - 4
44                 sub     offset, r0, r1
45
46 3:              tst     frame, mask             @ Check for address exceptions...
47                 bne     1b
48
49 1001:           ldr     next, [frame, #-12]     @ get fp
50 1002:           ldr     r2, [frame, #-4]        @ get lr
51 1003:           ldr     r3, [frame, #0]         @ get pc
52                 sub     save, r3, offset        @ Correct PC for prefetching
53                 bic     save, save, mask
54 1004:           ldr     r1, [save, #0]          @ get instruction at function
55                 mov     r1, r1, lsr #10
56                 ldr     r3, .Ldsi+4
57                 teq     r1, r3
58                 subeq   save, save, #4
59                 adr     r0, .Lfe
60                 mov     r1, save
61                 bic     r2, r2, mask
62                 bl      printk                  @ print pc and link register
63
64                 ldr     r0, [frame, #-8]        @ get sp
65                 sub     r0, r0, #4
66 1005:           ldr     r1, [save, #4]          @ get instruction at function+4
67                 mov     r3, r1, lsr #10
68                 ldr     r2, .Ldsi+4
69                 teq     r3, r2                  @ Check for stmia sp!, {args}
70                 addeq   save, save, #4          @ next instruction
71                 bleq    .Ldumpstm
72
73                 sub     r0, frame, #16
74 1006:           ldr     r1, [save, #4]          @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
75                 mov     r3, r1, lsr #10
76                 ldr     r2, .Ldsi
77                 teq     r3, r2
78                 bleq    .Ldumpstm
79
80                 teq     frame, next
81                 movne   frame, next
82                 teqne   frame, #0
83                 bne     3b
84                 LOADREGS(fd, sp!, {r4 - r8, pc})
85
86 /*
87  * Fixup for LDMDB
88  */
89                 .section .fixup,"ax"
90                 .align  0
91 1007:           ldr     r0, =.Lbad
92                 mov     r1, frame
93                 bl      printk
94                 LOADREGS(fd, sp!, {r4 - r8, pc})
95                 .ltorg
96                 .previous
97                 
98                 .section __ex_table,"a"
99                 .align  3
100                 .long   1001b, 1007b
101                 .long   1002b, 1007b
102                 .long   1003b, 1007b
103                 .long   1004b, 1007b
104                 .long   1005b, 1007b
105                 .long   1006b, 1007b
106                 .previous
107
108 #define instr r4
109 #define reg   r5
110 #define stack r6
111
112 .Ldumpstm:      stmfd   sp!, {instr, reg, stack, r7, lr}
113                 mov     stack, r0
114                 mov     instr, r1
115                 mov     reg, #9
116                 mov     r7, #0
117 1:              mov     r3, #1
118                 tst     instr, r3, lsl reg
119                 beq     2f
120                 add     r7, r7, #1
121                 teq     r7, #4
122                 moveq   r7, #0
123                 moveq   r3, #'\n'
124                 movne   r3, #' '
125                 ldr     r2, [stack], #-4
126                 mov     r1, reg
127                 adr     r0, .Lfp
128                 bl      printk
129 2:              subs    reg, reg, #1
130                 bpl     1b
131                 teq     r7, #0
132                 adrne   r0, .Lcr
133                 blne    printk
134                 mov     r0, stack
135                 LOADREGS(fd, sp!, {instr, reg, stack, r7, pc})
136
137 .Lfe:           .asciz  "Function entered at [<%p>] from [<%p>]\n"
138 .Lfp:           .asciz  " r%d = %08X%c"
139 .Lcr:           .asciz  "\n"
140 .Lbad:          .asciz  "Backtrace aborted due to bad frame pointer <%p>\n"
141                 .align
142 .Ldsi:          .word   0x00e92dd8 >> 2
143                 .word   0x00e92d00 >> 2
144
145 #endif