Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
7ab3f8d5
Commit
7ab3f8d5
authored
Mar 02, 2007
by
Russell King
Committed by
Russell King
Apr 21, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ARM] Add ability to dump exception stacks to kernel backtraces
Signed-off-by:
Russell King
<
rmk+kernel@arm.linux.org.uk
>
parent
46fcc86d
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
105 additions
and
89 deletions
+105
-89
arch/arm/kernel/irq.c
arch/arm/kernel/irq.c
+1
-1
arch/arm/kernel/traps.c
arch/arm/kernel/traps.c
+16
-2
arch/arm/kernel/vmlinux.lds.S
arch/arm/kernel/vmlinux.lds.S
+3
-0
arch/arm/lib/backtrace.S
arch/arm/lib/backtrace.S
+81
-84
arch/arm/mm/fault.c
arch/arm/mm/fault.c
+2
-2
include/asm-arm/system.h
include/asm-arm/system.h
+2
-0
No files found.
arch/arm/kernel/irq.c
View file @
7ab3f8d5
...
...
@@ -109,7 +109,7 @@ static struct irq_desc bad_irq_desc = {
* come via this function. Instead, they should provide their
* own 'handler'
*/
asmlinkage
void
asm_do_IRQ
(
unsigned
int
irq
,
struct
pt_regs
*
regs
)
asmlinkage
void
__exception
asm_do_IRQ
(
unsigned
int
irq
,
struct
pt_regs
*
regs
)
{
struct
pt_regs
*
old_regs
=
set_irq_regs
(
regs
);
struct
irq_desc
*
desc
=
irq_desc
+
irq
;
...
...
arch/arm/kernel/traps.c
View file @
7ab3f8d5
...
...
@@ -45,7 +45,18 @@ static int __init user_debug_setup(char *str)
__setup
(
"user_debug="
,
user_debug_setup
);
#endif
void
dump_backtrace_entry
(
unsigned
long
where
,
unsigned
long
from
)
static
void
dump_mem
(
const
char
*
str
,
unsigned
long
bottom
,
unsigned
long
top
);
static
inline
int
in_exception_text
(
unsigned
long
ptr
)
{
extern
char
__exception_text_start
[];
extern
char
__exception_text_end
[];
return
ptr
>=
(
unsigned
long
)
&
__exception_text_start
&&
ptr
<
(
unsigned
long
)
&
__exception_text_end
;
}
void
dump_backtrace_entry
(
unsigned
long
where
,
unsigned
long
from
,
unsigned
long
frame
)
{
#ifdef CONFIG_KALLSYMS
printk
(
"[<%08lx>] "
,
where
);
...
...
@@ -55,6 +66,9 @@ void dump_backtrace_entry(unsigned long where, unsigned long from)
#else
printk
(
"Function entered at [<%08lx>] from [<%08lx>]
\n
"
,
where
,
from
);
#endif
if
(
in_exception_text
(
where
))
dump_mem
(
"Exception stack"
,
frame
+
4
,
frame
+
4
+
sizeof
(
struct
pt_regs
));
}
/*
...
...
@@ -266,7 +280,7 @@ void unregister_undef_hook(struct undef_hook *hook)
spin_unlock_irqrestore
(
&
undef_lock
,
flags
);
}
asmlinkage
void
do_undefinstr
(
struct
pt_regs
*
regs
)
asmlinkage
void
__exception
do_undefinstr
(
struct
pt_regs
*
regs
)
{
unsigned
int
correction
=
thumb_mode
(
regs
)
?
2
:
4
;
unsigned
int
instr
;
...
...
arch/arm/kernel/vmlinux.lds.S
View file @
7ab3f8d5
...
...
@@ -83,6 +83,9 @@ SECTIONS
.
text
:
{
/*
Real
text
segment
*/
_text
=
.
; /* Text and read-only data */
__exception_text_start
=
.
;
*(.
exception.text
)
__exception_text_end
=
.
;
*(.
text
)
SCHED_TEXT
LOCK_TEXT
...
...
arch/arm/lib/backtrace.S
View file @
7ab3f8d5
...
...
@@ -17,8 +17,8 @@
@
fp
is
0
or
stack
frame
#define frame r4
#define
next
r5
#define s
ave
r6
#define
sv_fp
r5
#define s
v_pc
r6
#define mask r7
#define offset r8
...
...
@@ -31,108 +31,106 @@ ENTRY(c_backtrace)
#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
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
ldmeqfd
sp
!,
{
r4
-
r8
,
pc
}
2
:
stmfd
sp
!,
{
pc
}
@
calculate
offset
of
PC
in
STMIA
instruction
ldr
r0
,
[
sp
],
#
4
adr
r1
,
2
b
-
4
movs
frame
,
r0
@
if
frame
pointer
is
zero
beq
no_frame
@
we
have
no
stack
frames
tst
r1
,
#
0x10
@
26
or
32
-
bit
mode
?
moveq
mask
,
#
0xfc000003
@
mask
for
26
-
bit
movne
mask
,
#
0
@
mask
for
32
-
bit
1
:
stmfd
sp
!,
{
pc
}
@
calculate
offset
of
PC
stored
ldr
r0
,
[
sp
],
#
4
@
by
stmfd
for
this
CPU
adr
r1
,
1
b
sub
offset
,
r0
,
r1
3
:
tst
frame
,
mask
@
Check
for
address
exceptions
...
bne
1
b
/*
*
Stack
frame
layout
:
*
optionally
saved
caller
registers
(
r4
-
r10
)
*
saved
fp
*
saved
sp
*
saved
lr
*
frame
=>
saved
pc
*
optionally
saved
arguments
(
r0
-
r3
)
*
saved
sp
=>
<
next
word
>
*
*
Functions
start
with
the
following
code
sequence
:
*
mov
ip
,
sp
*
stmfd
sp
!,
{
r0
-
r3
}
(
optional
)
*
corrected
pc
=>
stmfd
sp
!,
{
...
,
fp
,
ip
,
lr
,
pc
}
*/
for_each_frame
:
tst
frame
,
mask
@
Check
for
address
exceptions
bne
no_frame
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
1001
:
ldr
sv_pc
,
[
frame
,
#
0
]
@
get
saved
pc
1002
:
ldr
sv_fp
,
[
frame
,
#-
12
]
@
get
saved
fp
sub
sv_pc
,
sv_pc
,
offset
@
Correct
PC
for
prefetching
bic
sv_pc
,
sv_pc
,
mask
@
mask
PC
/
LR
for
the
mode
1003
:
ldr
r2
,
[
sv_pc
,
#-
4
]
@
if
stmfd
sp
!,
{
args
}
exists
,
ldr
r3
,
.
Ldsi
+
4
@
adjust
saved
'pc'
back
one
teq
r3
,
r2
,
lsr
#
10
@
instruction
subne
r0
,
sv_pc
,
#
4
@
allow
for
mov
subeq
r0
,
sv_pc
,
#
8
@
allow
for
mov
+
stmia
ldr
r1
,
[
frame
,
#-
4
]
@
get
saved
lr
mov
r2
,
frame
bic
r1
,
r1
,
mask
@
mask
PC
/
LR
for
the
mode
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
ldmeqfd
sp
!,
{
r4
-
r8
,
pc
}
ldr
r1
,
[
sv_pc
,
#-
4
]
@
if
stmfd
sp
!,
{
args
}
exists
,
ldr
r3
,
.
Ldsi
+
4
teq
r3
,
r1
,
lsr
#
10
ldreq
r0
,
[
frame
,
#-
8
]
@
get
sp
subeq
r0
,
r0
,
#
4
@
point
at
the
last
arg
bleq
.
Ldumpstm
@
dump
saved
registers
/
*
*
The
next
framepointer
must
be
above
the
*
current
framepointer
.
*/
cmp
next
,
frame
mov
frame
,
next
bhi
3
b
b
1007
f
1004
:
ldr
r1
,
[
sv_pc
,
#
0
]
@
if
stmfd
sp
!,
{
...
,
fp
,
ip
,
lr
,
pc
}
ldr
r3
,
.
Ldsi
@
instruction
exists
,
teq
r3
,
r1
,
lsr
#
10
subeq
r0
,
frame
,
#
16
bleq
.
Ldumpstm
@
dump
saved
registers
/*
*
Fixup
for
LDMDB
.
Note
that
this
must
not
be
in
the
fixup
section
.
*/
1007
:
ldr
r0
,
=
.
Lbad
teq
sv_fp
,
#
0
@
zero
saved
fp
means
beq
no_frame
@
no
further
frames
cmp
sv_fp
,
frame
@
next
frame
must
be
mov
frame
,
sv_fp
@
above
the
current
frame
bhi
for_each_frame
1006
:
adr
r0
,
.
Lbad
mov
r1
,
frame
bl
printk
ldmfd
sp
!,
{
r4
-
r8
,
pc
}
.
ltorg
no_frame
:
ldmfd
sp
!,
{
r4
-
r8
,
pc
}
.
section
__ex_table
,
"a"
.
align
3
.
long
1001
b
,
1007
b
.
long
1002
b
,
1007
b
.
long
1003
b
,
1007
b
.
long
1004
b
,
1007
b
.
long
1005
b
,
1007
b
.
long
1006
b
,
1007
b
.
long
1001
b
,
1006
b
.
long
1002
b
,
1006
b
.
long
1003
b
,
1006
b
.
long
1004
b
,
1006
b
.
previous
#define instr r4
#define reg r5
#define stack r6
.
Ldumpstm
:
stmfd
sp
!,
{
instr
,
reg
,
stack
,
r7
,
r8
,
lr
}
.
Ldumpstm
:
stmfd
sp
!,
{
instr
,
reg
,
stack
,
r7
,
lr
}
mov
stack
,
r0
mov
instr
,
r1
mov
reg
,
#
9
mov
reg
,
#
10
mov
r7
,
#
0
1
:
mov
r3
,
#
1
tst
instr
,
r3
,
lsl
reg
beq
2
f
add
r7
,
r7
,
#
1
teq
r7
,
#
4
moveq
r7
,
#
0
moveq
r
3
,
#
'\n'
movne
r
3
,
#
' '
ldr
r
2
,
[
stack
],
#-
4
mov
r
1
,
reg
teq
r7
,
#
6
moveq
r7
,
#
1
moveq
r
1
,
#
'\n'
movne
r
1
,
#
' '
ldr
r
3
,
[
stack
],
#-
4
mov
r
2
,
reg
adr
r0
,
.
Lfp
bl
printk
2
:
subs
reg
,
reg
,
#
1
...
...
@@ -140,14 +138,13 @@ ENTRY(c_backtrace)
teq
r7
,
#
0
adrne
r0
,
.
Lcr
blne
printk
mov
r0
,
stack
ldmfd
sp
!,
{
instr
,
reg
,
stack
,
r7
,
r8
,
pc
}
ldmfd
sp
!,
{
instr
,
reg
,
stack
,
r7
,
pc
}
.
Lfp
:
.
asciz
"
r%d = %08X%c
"
.
Lfp
:
.
asciz
"
%cr%d:%08x
"
.
Lcr
:
.
asciz
"\n"
.
Lbad
:
.
asciz
"Backtrace aborted due to bad frame pointer <%p>\n"
.
align
.
Ldsi
:
.
word
0x
00e92dd8
>>
2
.
word
0x
00e92d00
>>
2
.
Ldsi
:
.
word
0x
e92dd800
>>
10
@
stmfd
sp
!,
{
...
fp
,
ip
,
lr
,
pc
}
.
word
0x
e92d0000
>>
10
@
stmfd
sp
!,
{}
#endif
arch/arm/mm/fault.c
View file @
7ab3f8d5
...
...
@@ -438,7 +438,7 @@ hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *)
/*
* Dispatch a data abort to the relevant handler.
*/
asmlinkage
void
asmlinkage
void
__exception
do_DataAbort
(
unsigned
long
addr
,
unsigned
int
fsr
,
struct
pt_regs
*
regs
)
{
const
struct
fsr_info
*
inf
=
fsr_info
+
(
fsr
&
15
)
+
((
fsr
&
(
1
<<
10
))
>>
6
);
...
...
@@ -457,7 +457,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
notify_die
(
""
,
regs
,
&
info
,
fsr
,
0
);
}
asmlinkage
void
asmlinkage
void
__exception
do_PrefetchAbort
(
unsigned
long
addr
,
struct
pt_regs
*
regs
)
{
do_translation_fault
(
addr
,
0
,
regs
);
...
...
include/asm-arm/system.h
View file @
7ab3f8d5
...
...
@@ -76,6 +76,8 @@
#include <linux/linkage.h>
#include <linux/irqflags.h>
#define __exception __attribute__((section(".exception.text")))
struct
thread_info
;
struct
task_struct
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment