backtrace.S 3.1 KB
Newer Older
L
Linus Torvalds 已提交
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
/*
 *  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.
 *
 * 27/03/03 Ian Molton Clean up CONFIG_CPU
 *
 */
#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)

32
#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
L
Linus Torvalds 已提交
33 34 35 36 37 38 39 40 41 42 43
		mov	pc, lr
#else

		stmfd	sp!, {r4 - r8, lr}	@ Save an extra register so we have a location...
		tst	r1, #0x10		@ 26 or 32-bit?
		moveq	mask, #0xfc000003
		movne	mask, #0
		tst	mask, r0
		movne	r0, #0
		movs	frame, r0
1:		moveq	r0, #-2
R
Russell King 已提交
44
		ldmeqfd	sp!, {r4 - r8, pc}
L
Linus Torvalds 已提交
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

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:		ldr	next, [frame, #-12]	@ get fp
1002:		ldr	r2, [frame, #-4]	@ get lr
1003:		ldr	r3, [frame, #0]		@ get pc
		sub	save, r3, offset	@ Correct PC for prefetching
		bic	save, save, mask
1004:		ldr	r1, [save, #0]		@ get instruction at function
		mov	r1, r1, lsr #10
		ldr	r3, .Ldsi+4
		teq	r1, r3
		subeq	save, save, #4
		mov	r0, save
		bic	r1, r2, mask
		bl	dump_backtrace_entry

		ldr	r0, [frame, #-8]	@ get sp
		sub	r0, r0, #4
1005:		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

		sub	r0, frame, #16
1006:		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

		/*
		 * A zero next framepointer means we're done.
		 */
		teq	next, #0
R
Russell King 已提交
88
		ldmeqfd	sp!, {r4 - r8, pc}
L
Linus Torvalds 已提交
89 90 91 92 93 94 95 96 97 98 99

		/*
		 * The next framepointer must be above the
		 * current framepointer.
		 */
		cmp	next, frame
		mov	frame, next
		bhi	3b
		b	1007f

/*
100
 * Fixup for LDMDB.  Note that this must not be in the fixup section.
L
Linus Torvalds 已提交
101 102 103 104
 */
1007:		ldr	r0, =.Lbad
		mov	r1, frame
		bl	printk
R
Russell King 已提交
105
		ldmfd	sp!, {r4 - r8, pc}
L
Linus Torvalds 已提交
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
		.ltorg
		
		.section __ex_table,"a"
		.align	3
		.long	1001b, 1007b
		.long	1002b, 1007b
		.long	1003b, 1007b
		.long	1004b, 1007b
		.long	1005b, 1007b
		.long	1006b, 1007b
		.previous

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

122
.Ldumpstm:	stmfd	sp!, {instr, reg, stack, r7, r8, lr}
L
Linus Torvalds 已提交
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
		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	printk
2:		subs	reg, reg, #1
		bpl	1b
		teq	r7, #0
		adrne	r0, .Lcr
		blne	printk
		mov	r0, stack
R
Russell King 已提交
145
		ldmfd	sp!, {instr, reg, stack, r7, r8, pc}
L
Linus Torvalds 已提交
146 147 148 149 150 151 152 153 154

.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