From 5241de0fd007de746bfbd271da8d7a84409ba5d3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Lothar=20Wa=C3=9Fmann?= Date: Wed, 2 Jul 2014 14:23:56 +0200 Subject: [PATCH] arm: adjust PC displayed in exception handlers to point to the failing instruction --- arch/arm/lib/interrupts.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c index 787dceb93d..a122e74313 100644 --- a/arch/arm/lib/interrupts.c +++ b/arch/arm/lib/interrupts.c @@ -20,7 +20,7 @@ */ #include -#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -131,9 +131,17 @@ void show_regs (struct pt_regs *regs) thumb_mode (regs) ? " (T)" : ""); } +/* fixup PC to point to instruction leading to exception */ +static inline void fixup_pc(struct pt_regs *regs, int offset) +{ + uint32_t pc = instruction_pointer(regs) + offset; + regs->ARM_pc = pc | (regs->ARM_pc & PCMASK); +} + void do_undefined_instruction (struct pt_regs *pt_regs) { printf ("undefined instruction\n"); + fixup_pc(pt_regs, -4); show_regs (pt_regs); bad_mode (); } @@ -141,6 +149,7 @@ void do_undefined_instruction (struct pt_regs *pt_regs) void do_software_interrupt (struct pt_regs *pt_regs) { printf ("software interrupt\n"); + fixup_pc(pt_regs, -4); show_regs (pt_regs); bad_mode (); } @@ -148,6 +157,7 @@ void do_software_interrupt (struct pt_regs *pt_regs) void do_prefetch_abort (struct pt_regs *pt_regs) { printf ("prefetch abort\n"); + fixup_pc(pt_regs, -8); show_regs (pt_regs); bad_mode (); } @@ -162,6 +172,7 @@ void do_data_abort (struct pt_regs *pt_regs) printf ("data abort\n\n"); if (fsr & 1) printf ("MAYBE you should read doc/README.arm-unaligned-accesses\n\n"); + fixup_pc(pt_regs, -8); show_regs (pt_regs); bad_mode (); } @@ -169,6 +180,7 @@ void do_data_abort (struct pt_regs *pt_regs) void do_not_used (struct pt_regs *pt_regs) { printf ("not used\n"); + fixup_pc(pt_regs, -8); show_regs (pt_regs); bad_mode (); } @@ -176,6 +188,7 @@ void do_not_used (struct pt_regs *pt_regs) void do_fiq (struct pt_regs *pt_regs) { printf ("fast interrupt request\n"); + fixup_pc(pt_regs, -8); show_regs (pt_regs); bad_mode (); } @@ -184,6 +197,7 @@ void do_fiq (struct pt_regs *pt_regs) void do_irq (struct pt_regs *pt_regs) { printf ("interrupt request\n"); + fixup_pc(pt_regs, -8); show_regs (pt_regs); bad_mode (); } -- 2.39.2