File: backtrace.S

package info (click to toggle)
kernel-source-2.4.14 2.4.14-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 139,160 kB
  • ctags: 428,423
  • sloc: ansic: 2,435,554; asm: 141,119; makefile: 8,258; sh: 3,099; perl: 2,561; yacc: 1,177; cpp: 755; tcl: 577; lex: 352; awk: 251; lisp: 218; sed: 72
file content (141 lines) | stat: -rw-r--r-- 2,887 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 *  linux/arch/arm/lib/backtrace.S
 *
 *  Copyright (C) 1995, 1996 Russell King
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/assembler.h>
		.text

@ fp is 0 or stack frame

#define frame	r4
#define next	r5
#define save	r6
#define mask	r7
#define offset	r8

ENTRY(__backtrace)
		mov	r1, #0x10
		mov	r0, fp

ENTRY(c_backtrace)

#ifdef CONFIG_NO_FRAME_POINTER
		mov	pc, lr
#else

		stmfd	sp!, {r4 - r8, lr}	@ Save an extra register so we have a location...
#ifdef CONFIG_CPU_32
		tst	r1, #0x10		@ 26 or 32-bit?
		moveq	mask, #0xfc000003
		movne	mask, #0
#else
		mov	mask, #0xfc000003
#endif
		tst	mask, r0
		movne	r0, #0
		movs	frame, r0
1:		moveq	r0, #-2
		LOADREGS(eqfd, sp!, {r4 - r8, pc})

2:		stmfd	sp!, {pc}		@ calculate offset of PC in STMIA instruction
		ldr	r0, [sp], #4
		adr	r1, 2b - 4
		sub	offset, r0, r1

3:		tst	frame, mask		@ Check for address exceptions...
		bne	1b

1001:		ldmda	frame, {r0, r1, r2, r3}	@ fp, sp, lr, pc
		mov	next, r0

		sub	save, r3, offset	@ Correct PC for prefetching
		bic	save, save, mask
		adr	r0, .Lfe
		mov	r1, save
		bic	r2, r2, mask
		bl	SYMBOL_NAME(printk)	@ print pc and link register

		sub	r0, frame, #16
1002:		ldr	r1, [save, #4]		@ get instruction at function+4
		mov	r3, r1, lsr #10
		ldr	r2, .Ldsi+4
		teq	r3, r2			@ Check for stmia sp!, {args}
		addeq	save, save, #4		@ next instruction
		bleq	.Ldumpstm

1003:		ldr	r1, [save, #4]		@ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
		mov	r3, r1, lsr #10
		ldr	r2, .Ldsi
		teq	r3, r2
		bleq	.Ldumpstm

		teq	frame, next
		movne	frame, next
		teqne	frame, #0
		bne	3b
		LOADREGS(fd, sp!, {r4 - r8, pc})

/*
 * Fixup for LDMDB
 */
		.section .fixup,"ax"
		.align	0
1004:		ldr	r0, =.Lbad
		mov	r1, frame
		bl	SYMBOL_NAME(printk)
		LOADREGS(fd, sp!, {r4 - r8, pc})
		.ltorg
		.previous
		
		.section __ex_table,"a"
		.align	3
		.long	1001b, 1004b
		.long	1002b, 1004b
		.long	1003b, 1004b
		.previous

#define instr r4
#define reg   r5
#define stack r6

.Ldumpstm:	stmfd	sp!, {instr, reg, stack, r7, lr}
		mov	stack, r0
		mov	instr, r1
		mov	reg, #9
		mov	r7, #0
1:		mov	r3, #1
		tst	instr, r3, lsl reg
		beq	2f
		add	r7, r7, #1
		teq	r7, #4
		moveq	r7, #0
		moveq	r3, #'\n'
		movne	r3, #' '
		ldr	r2, [stack], #-4
		mov	r1, reg
		adr	r0, .Lfp
		bl	SYMBOL_NAME(printk)
2:		subs	reg, reg, #1
		bpl	1b
		teq	r7, #0
		adrne	r0, .Lcr
		blne	SYMBOL_NAME(printk)
		mov	r0, stack
		LOADREGS(fd, sp!, {instr, reg, stack, r7, pc})

.Lfe:		.asciz	"Function entered at [<%p>] from [<%p>]\n"
.Lfp:		.asciz	" r%d = %08X%c"
.Lcr:		.asciz	"\n"
.Lbad:		.asciz	"Backtrace aborted due to bad frame pointer <%p>\n"
		.align
.Ldsi:		.word	0x00e92dd8 >> 2
		.word	0x00e92d00 >> 2

#endif