Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
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
Hide 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 = {
...
@@ -109,7 +109,7 @@ static struct irq_desc bad_irq_desc = {
* come via this function. Instead, they should provide their
* come via this function. Instead, they should provide their
* own 'handler'
* 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
pt_regs
*
old_regs
=
set_irq_regs
(
regs
);
struct
irq_desc
*
desc
=
irq_desc
+
irq
;
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)
...
@@ -45,7 +45,18 @@ static int __init user_debug_setup(char *str)
__setup
(
"user_debug="
,
user_debug_setup
);
__setup
(
"user_debug="
,
user_debug_setup
);
#endif
#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
#ifdef CONFIG_KALLSYMS
printk
(
"[<%08lx>] "
,
where
);
printk
(
"[<%08lx>] "
,
where
);
...
@@ -55,6 +66,9 @@ void dump_backtrace_entry(unsigned long where, unsigned long from)
...
@@ -55,6 +66,9 @@ void dump_backtrace_entry(unsigned long where, unsigned long from)
#else
#else
printk
(
"Function entered at [<%08lx>] from [<%08lx>]
\n
"
,
where
,
from
);
printk
(
"Function entered at [<%08lx>] from [<%08lx>]
\n
"
,
where
,
from
);
#endif
#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)
...
@@ -266,7 +280,7 @@ void unregister_undef_hook(struct undef_hook *hook)
spin_unlock_irqrestore
(
&
undef_lock
,
flags
);
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
correction
=
thumb_mode
(
regs
)
?
2
:
4
;
unsigned
int
instr
;
unsigned
int
instr
;
...
...
arch/arm/kernel/vmlinux.lds.S
View file @
7ab3f8d5
...
@@ -83,6 +83,9 @@ SECTIONS
...
@@ -83,6 +83,9 @@ SECTIONS
.
text
:
{
/*
Real
text
segment
*/
.
text
:
{
/*
Real
text
segment
*/
_text
=
.
; /* Text and read-only data */
_text
=
.
; /* Text and read-only data */
__exception_text_start
=
.
;
*(.
exception.text
)
__exception_text_end
=
.
;
*(.
text
)
*(.
text
)
SCHED_TEXT
SCHED_TEXT
LOCK_TEXT
LOCK_TEXT
...
...
arch/arm/lib/backtrace.S
View file @
7ab3f8d5
...
@@ -17,8 +17,8 @@
...
@@ -17,8 +17,8 @@
@
fp
is
0
or
stack
frame
@
fp
is
0
or
stack
frame
#define frame r4
#define frame r4
#define
next
r5
#define
sv_fp
r5
#define s
ave
r6
#define s
v_pc
r6
#define mask r7
#define mask r7
#define offset r8
#define offset r8
...
@@ -31,108 +31,106 @@ ENTRY(c_backtrace)
...
@@ -31,108 +31,106 @@ ENTRY(c_backtrace)
#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
mov
pc
,
lr
mov
pc
,
lr
#else
#else
stmfd
sp
!,
{
r4
-
r8
,
lr
}
@
Save
an
extra
register
so
we
have
a
location
...
stmfd
sp
!,
{
r4
-
r8
,
lr
}
@
Save
an
extra
register
so
we
have
a
location
...
tst
r1
,
#
0x10
@
26
or
32
-
bit
?
movs
frame
,
r0
@
if
frame
pointer
is
zero
moveq
mask
,
#
0xfc000003
beq
no_frame
@
we
have
no
stack
frames
movne
mask
,
#
0
tst
mask
,
r0
tst
r1
,
#
0x10
@
26
or
32
-
bit
mode
?
movne
r0
,
#
0
moveq
mask
,
#
0xfc000003
@
mask
for
26
-
bit
movs
frame
,
r0
movne
mask
,
#
0
@
mask
for
32
-
bit
1
:
moveq
r0
,
#-
2
ldmeqfd
sp
!,
{
r4
-
r8
,
pc
}
1
:
stmfd
sp
!,
{
pc
}
@
calculate
offset
of
PC
stored
ldr
r0
,
[
sp
],
#
4
@
by
stmfd
for
this
CPU
2
:
stmfd
sp
!,
{
pc
}
@
calculate
offset
of
PC
in
STMIA
instruction
adr
r1
,
1
b
ldr
r0
,
[
sp
],
#
4
adr
r1
,
2
b
-
4
sub
offset
,
r0
,
r1
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
sv_pc
,
[
frame
,
#
0
]
@
get
saved
pc
1002
:
ldr
sv_fp
,
[
frame
,
#-
12
]
@
get
saved
fp
1001
:
ldr
next
,
[
frame
,
#-
12
]
@
get
fp
sub
sv_pc
,
sv_pc
,
offset
@
Correct
PC
for
prefetching
1002
:
ldr
r2
,
[
frame
,
#-
4
]
@
get
lr
bic
sv_pc
,
sv_pc
,
mask
@
mask
PC
/
LR
for
the
mode
1003
:
ldr
r3
,
[
frame
,
#
0
]
@
get
pc
sub
save
,
r3
,
offset
@
Correct
PC
for
prefetching
1003
:
ldr
r2
,
[
sv_pc
,
#-
4
]
@
if
stmfd
sp
!,
{
args
}
exists
,
bic
save
,
save
,
mask
ldr
r3
,
.
Ldsi
+
4
@
adjust
saved
'pc'
back
one
1004
:
ldr
r1
,
[
save
,
#
0
]
@
get
instruction
at
fun
ction
teq
r3
,
r2
,
lsr
#
10
@
instru
ction
mov
r1
,
r1
,
lsr
#
10
subne
r0
,
sv_pc
,
#
4
@
allow
for
mov
ldr
r3
,
.
Ldsi
+
4
subeq
r0
,
sv_pc
,
#
8
@
allow
for
mov
+
stmia
teq
r1
,
r3
subeq
save
,
save
,
#
4
ldr
r1
,
[
frame
,
#-
4
]
@
get
saved
lr
mov
r
0
,
sav
e
mov
r
2
,
fram
e
bic
r1
,
r
2
,
mask
bic
r1
,
r
1
,
mask
@
mask
PC
/
LR
for
the
mode
bl
dump_backtrace_entry
bl
dump_backtrace_entry
ldr
r0
,
[
frame
,
#-
8
]
@
get
sp
ldr
r1
,
[
sv_pc
,
#-
4
]
@
if
stmfd
sp
!,
{
args
}
exists
,
sub
r0
,
r0
,
#
4
ldr
r3
,
.
Ldsi
+
4
1005
:
ldr
r1
,
[
save
,
#
4
]
@
get
instruction
at
function
+
4
teq
r3
,
r1
,
lsr
#
10
mov
r3
,
r1
,
lsr
#
10
ldreq
r0
,
[
frame
,
#-
8
]
@
get
sp
ldr
r2
,
.
Ldsi
+
4
subeq
r0
,
r0
,
#
4
@
point
at
the
last
arg
teq
r3
,
r2
@
Check
for
stmia
sp
!,
{
args
}
bleq
.
Ldumpstm
@
dump
saved
registers
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
}
/
*
*
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
}
*
Fixup
for
LDMDB
.
Note
that
this
must
not
be
in
the
fixup
section
.
ldr
r3
,
.
Ldsi
@
instruction
exists
,
*/
teq
r3
,
r1
,
lsr
#
10
1007
:
ldr
r0
,
=
.
Lbad
subeq
r0
,
frame
,
#
16
bleq
.
Ldumpstm
@
dump
saved
registers
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
mov
r1
,
frame
bl
printk
bl
printk
ldmfd
sp
!,
{
r4
-
r8
,
pc
}
no_frame
:
ldmfd
sp
!,
{
r4
-
r8
,
pc
}
.
ltorg
.
section
__ex_table
,
"a"
.
section
__ex_table
,
"a"
.
align
3
.
align
3
.
long
1001
b
,
1007
b
.
long
1001
b
,
1006
b
.
long
1002
b
,
1007
b
.
long
1002
b
,
1006
b
.
long
1003
b
,
1007
b
.
long
1003
b
,
1006
b
.
long
1004
b
,
1007
b
.
long
1004
b
,
1006
b
.
long
1005
b
,
1007
b
.
long
1006
b
,
1007
b
.
previous
.
previous
#define instr r4
#define instr r4
#define reg r5
#define reg r5
#define stack r6
#define stack r6
.
Ldumpstm
:
stmfd
sp
!,
{
instr
,
reg
,
stack
,
r7
,
r8
,
lr
}
.
Ldumpstm
:
stmfd
sp
!,
{
instr
,
reg
,
stack
,
r7
,
lr
}
mov
stack
,
r0
mov
stack
,
r0
mov
instr
,
r1
mov
instr
,
r1
mov
reg
,
#
9
mov
reg
,
#
10
mov
r7
,
#
0
mov
r7
,
#
0
1
:
mov
r3
,
#
1
1
:
mov
r3
,
#
1
tst
instr
,
r3
,
lsl
reg
tst
instr
,
r3
,
lsl
reg
beq
2
f
beq
2
f
add
r7
,
r7
,
#
1
add
r7
,
r7
,
#
1
teq
r7
,
#
4
teq
r7
,
#
6
moveq
r7
,
#
0
moveq
r7
,
#
1
moveq
r
3
,
#
'\n'
moveq
r
1
,
#
'\n'
movne
r
3
,
#
' '
movne
r
1
,
#
' '
ldr
r
2
,
[
stack
],
#-
4
ldr
r
3
,
[
stack
],
#-
4
mov
r
1
,
reg
mov
r
2
,
reg
adr
r0
,
.
Lfp
adr
r0
,
.
Lfp
bl
printk
bl
printk
2
:
subs
reg
,
reg
,
#
1
2
:
subs
reg
,
reg
,
#
1
...
@@ -140,14 +138,13 @@ ENTRY(c_backtrace)
...
@@ -140,14 +138,13 @@ ENTRY(c_backtrace)
teq
r7
,
#
0
teq
r7
,
#
0
adrne
r0
,
.
Lcr
adrne
r0
,
.
Lcr
blne
printk
blne
printk
mov
r0
,
stack
ldmfd
sp
!,
{
instr
,
reg
,
stack
,
r7
,
pc
}
ldmfd
sp
!,
{
instr
,
reg
,
stack
,
r7
,
r8
,
pc
}
.
Lfp
:
.
asciz
"
r%d = %08X%c
"
.
Lfp
:
.
asciz
"
%cr%d:%08x
"
.
Lcr
:
.
asciz
"\n"
.
Lcr
:
.
asciz
"\n"
.
Lbad
:
.
asciz
"Backtrace aborted due to bad frame pointer <%p>\n"
.
Lbad
:
.
asciz
"Backtrace aborted due to bad frame pointer <%p>\n"
.
align
.
align
.
Ldsi
:
.
word
0x
00e92dd8
>>
2
.
Ldsi
:
.
word
0x
e92dd800
>>
10
@
stmfd
sp
!,
{
...
fp
,
ip
,
lr
,
pc
}
.
word
0x
00e92d00
>>
2
.
word
0x
e92d0000
>>
10
@
stmfd
sp
!,
{}
#endif
#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 *)
...
@@ -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.
* 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
)
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
);
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)
...
@@ -457,7 +457,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
notify_die
(
""
,
regs
,
&
info
,
fsr
,
0
);
notify_die
(
""
,
regs
,
&
info
,
fsr
,
0
);
}
}
asmlinkage
void
asmlinkage
void
__exception
do_PrefetchAbort
(
unsigned
long
addr
,
struct
pt_regs
*
regs
)
do_PrefetchAbort
(
unsigned
long
addr
,
struct
pt_regs
*
regs
)
{
{
do_translation_fault
(
addr
,
0
,
regs
);
do_translation_fault
(
addr
,
0
,
regs
);
...
...
include/asm-arm/system.h
View file @
7ab3f8d5
...
@@ -76,6 +76,8 @@
...
@@ -76,6 +76,8 @@
#include <linux/linkage.h>
#include <linux/linkage.h>
#include <linux/irqflags.h>
#include <linux/irqflags.h>
#define __exception __attribute__((section(".exception.text")))
struct
thread_info
;
struct
thread_info
;
struct
task_struct
;
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