]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - arch/arm26/lib/backtrace.S
Linux-2.6.12-rc2
[mirror_ubuntu-artful-kernel.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