blob: d793fe4339fc75141a0003bddf7d494989aaee87 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
23ENTRY(__backtrace)
24 mov r1, #0x10
25 mov r0, fp
26
27ENTRY(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
381: moveq r0, #-2
39 LOADREGS(eqfd, sp!, {r4 - r8, pc})
40
412: 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
463: tst frame, mask @ Check for address exceptions...
47 bne 1b
48
491001: ldr next, [frame, #-12] @ get fp
501002: ldr r2, [frame, #-4] @ get lr
511003: ldr r3, [frame, #0] @ get pc
52 sub save, r3, offset @ Correct PC for prefetching
53 bic save, save, mask
541004: 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
661005: 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
741006: 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
911007: 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
1171: 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
1292: 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