diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2007-03-02 10:01:36 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-04-21 15:34:34 -0400 |
commit | 7ab3f8d595a1b1e5cf8d726b72fd476fe0d0226c (patch) | |
tree | d37cf7290d5df5927ff870bfbb40673bead8f00d /arch/arm/kernel | |
parent | 46fcc86dd71d70211e965102fb69414c90381880 (diff) |
[ARM] Add ability to dump exception stacks to kernel backtraces
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 18 | ||||
-rw-r--r-- | arch/arm/kernel/vmlinux.lds.S | 3 |
3 files changed, 20 insertions, 3 deletions
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index e101846ab7dd..a72b82e727f1 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
@@ -109,7 +109,7 @@ static struct irq_desc bad_irq_desc = { | |||
109 | * come via this function. Instead, they should provide their | 109 | * come via this function. Instead, they should provide their |
110 | * own 'handler' | 110 | * own 'handler' |
111 | */ | 111 | */ |
112 | asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) | 112 | asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) |
113 | { | 113 | { |
114 | struct pt_regs *old_regs = set_irq_regs(regs); | 114 | struct pt_regs *old_regs = set_irq_regs(regs); |
115 | struct irq_desc *desc = irq_desc + irq; | 115 | struct irq_desc *desc = irq_desc + irq; |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 24095601359b..ba1c1884e68e 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -45,7 +45,18 @@ static int __init user_debug_setup(char *str) | |||
45 | __setup("user_debug=", user_debug_setup); | 45 | __setup("user_debug=", user_debug_setup); |
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | void dump_backtrace_entry(unsigned long where, unsigned long from) | 48 | static void dump_mem(const char *str, unsigned long bottom, unsigned long top); |
49 | |||
50 | static inline int in_exception_text(unsigned long ptr) | ||
51 | { | ||
52 | extern char __exception_text_start[]; | ||
53 | extern char __exception_text_end[]; | ||
54 | |||
55 | return ptr >= (unsigned long)&__exception_text_start && | ||
56 | ptr < (unsigned long)&__exception_text_end; | ||
57 | } | ||
58 | |||
59 | void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) | ||
49 | { | 60 | { |
50 | #ifdef CONFIG_KALLSYMS | 61 | #ifdef CONFIG_KALLSYMS |
51 | printk("[<%08lx>] ", where); | 62 | printk("[<%08lx>] ", where); |
@@ -55,6 +66,9 @@ void dump_backtrace_entry(unsigned long where, unsigned long from) | |||
55 | #else | 66 | #else |
56 | printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); | 67 | printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); |
57 | #endif | 68 | #endif |
69 | |||
70 | if (in_exception_text(where)) | ||
71 | dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); | ||
58 | } | 72 | } |
59 | 73 | ||
60 | /* | 74 | /* |
@@ -266,7 +280,7 @@ void unregister_undef_hook(struct undef_hook *hook) | |||
266 | spin_unlock_irqrestore(&undef_lock, flags); | 280 | spin_unlock_irqrestore(&undef_lock, flags); |
267 | } | 281 | } |
268 | 282 | ||
269 | asmlinkage void do_undefinstr(struct pt_regs *regs) | 283 | asmlinkage void __exception do_undefinstr(struct pt_regs *regs) |
270 | { | 284 | { |
271 | unsigned int correction = thumb_mode(regs) ? 2 : 4; | 285 | unsigned int correction = thumb_mode(regs) ? 2 : 4; |
272 | unsigned int instr; | 286 | unsigned int instr; |
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index ddbdad48f5b2..b295f6a85cf1 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
@@ -83,6 +83,9 @@ SECTIONS | |||
83 | 83 | ||
84 | .text : { /* Real text segment */ | 84 | .text : { /* Real text segment */ |
85 | _text = .; /* Text and read-only data */ | 85 | _text = .; /* Text and read-only data */ |
86 | __exception_text_start = .; | ||
87 | *(.exception.text) | ||
88 | __exception_text_end = .; | ||
86 | *(.text) | 89 | *(.text) |
87 | SCHED_TEXT | 90 | SCHED_TEXT |
88 | LOCK_TEXT | 91 | LOCK_TEXT |