Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/lib/backtrace.S
10817 views
1
/*
2
* linux/arch/arm/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
* 27/03/03 Ian Molton Clean up CONFIG_CPU
11
*
12
*/
13
#include <linux/linkage.h>
14
#include <asm/assembler.h>
15
.text
16
17
@ fp is 0 or stack frame
18
19
#define frame r4
20
#define sv_fp r5
21
#define sv_pc r6
22
#define mask r7
23
#define offset r8
24
25
ENTRY(__backtrace)
26
mov r1, #0x10
27
mov r0, fp
28
29
ENTRY(c_backtrace)
30
31
#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
32
mov pc, lr
33
ENDPROC(__backtrace)
34
ENDPROC(c_backtrace)
35
#else
36
stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location...
37
movs frame, r0 @ if frame pointer is zero
38
beq no_frame @ we have no stack frames
39
40
tst r1, #0x10 @ 26 or 32-bit mode?
41
ARM( moveq mask, #0xfc000003 )
42
THUMB( moveq mask, #0xfc000000 )
43
THUMB( orreq mask, #0x03 )
44
movne mask, #0 @ mask for 32-bit
45
46
1: stmfd sp!, {pc} @ calculate offset of PC stored
47
ldr r0, [sp], #4 @ by stmfd for this CPU
48
adr r1, 1b
49
sub offset, r0, r1
50
51
/*
52
* Stack frame layout:
53
* optionally saved caller registers (r4 - r10)
54
* saved fp
55
* saved sp
56
* saved lr
57
* frame => saved pc
58
* optionally saved arguments (r0 - r3)
59
* saved sp => <next word>
60
*
61
* Functions start with the following code sequence:
62
* mov ip, sp
63
* stmfd sp!, {r0 - r3} (optional)
64
* corrected pc => stmfd sp!, {..., fp, ip, lr, pc}
65
*/
66
for_each_frame: tst frame, mask @ Check for address exceptions
67
bne no_frame
68
69
1001: ldr sv_pc, [frame, #0] @ get saved pc
70
1002: ldr sv_fp, [frame, #-12] @ get saved fp
71
72
sub sv_pc, sv_pc, offset @ Correct PC for prefetching
73
bic sv_pc, sv_pc, mask @ mask PC/LR for the mode
74
75
1003: ldr r2, [sv_pc, #-4] @ if stmfd sp!, {args} exists,
76
ldr r3, .Ldsi+4 @ adjust saved 'pc' back one
77
teq r3, r2, lsr #10 @ instruction
78
subne r0, sv_pc, #4 @ allow for mov
79
subeq r0, sv_pc, #8 @ allow for mov + stmia
80
81
ldr r1, [frame, #-4] @ get saved lr
82
mov r2, frame
83
bic r1, r1, mask @ mask PC/LR for the mode
84
bl dump_backtrace_entry
85
86
ldr r1, [sv_pc, #-4] @ if stmfd sp!, {args} exists,
87
ldr r3, .Ldsi+4
88
teq r3, r1, lsr #10
89
ldreq r0, [frame, #-8] @ get sp
90
subeq r0, r0, #4 @ point at the last arg
91
bleq .Ldumpstm @ dump saved registers
92
93
1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc}
94
ldr r3, .Ldsi @ instruction exists,
95
teq r3, r1, lsr #10
96
subeq r0, frame, #16
97
bleq .Ldumpstm @ dump saved registers
98
99
teq sv_fp, #0 @ zero saved fp means
100
beq no_frame @ no further frames
101
102
cmp sv_fp, frame @ next frame must be
103
mov frame, sv_fp @ above the current frame
104
bhi for_each_frame
105
106
1006: adr r0, .Lbad
107
mov r1, frame
108
bl printk
109
no_frame: ldmfd sp!, {r4 - r8, pc}
110
ENDPROC(__backtrace)
111
ENDPROC(c_backtrace)
112
113
.pushsection __ex_table,"a"
114
.align 3
115
.long 1001b, 1006b
116
.long 1002b, 1006b
117
.long 1003b, 1006b
118
.long 1004b, 1006b
119
.popsection
120
121
#define instr r4
122
#define reg r5
123
#define stack r6
124
125
.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr}
126
mov stack, r0
127
mov instr, r1
128
mov reg, #10
129
mov r7, #0
130
1: mov r3, #1
131
ARM( tst instr, r3, lsl reg )
132
THUMB( lsl r3, reg )
133
THUMB( tst instr, r3 )
134
beq 2f
135
add r7, r7, #1
136
teq r7, #6
137
moveq r7, #1
138
moveq r1, #'\n'
139
movne r1, #' '
140
ldr r3, [stack], #-4
141
mov r2, reg
142
adr r0, .Lfp
143
bl printk
144
2: subs reg, reg, #1
145
bpl 1b
146
teq r7, #0
147
adrne r0, .Lcr
148
blne printk
149
ldmfd sp!, {instr, reg, stack, r7, pc}
150
151
.Lfp: .asciz "%cr%d:%08x"
152
.Lcr: .asciz "\n"
153
.Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n"
154
.align
155
.Ldsi: .word 0xe92dd800 >> 10 @ stmfd sp!, {... fp, ip, lr, pc}
156
.word 0xe92d0000 >> 10 @ stmfd sp!, {}
157
158
#endif
159
160