diff options
author | Mike Frysinger <vapier@gentoo.org> | 2011-05-27 01:25:45 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-27 02:12:36 +0200 |
commit | 63ab25ebbc50f74550bd8d164a34724b498f6fb9 (patch) | |
tree | 5753779e8ba6413174ee224286eabc18c2e9c6ee | |
parent | sh: convert to asm-generic ptrace.h (diff) | |
download | linux-63ab25ebbc50f74550bd8d164a34724b498f6fb9.tar.xz linux-63ab25ebbc50f74550bd8d164a34724b498f6fb9.zip |
kgdbts: unify/generalize gdb breakpoint adjustment
The Blackfin arch, like the x86 arch, needs to adjust the PC manually
after a breakpoint is hit as normally this is handled by the remote gdb.
However, rather than starting another arch ifdef mess, create a common
GDB_ADJUSTS_BREAK_OFFSET define for any arch to opt-in via their kgdb.h.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Jason Wessel <jason.wessel@windriver.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Acked-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Dongdong Deng <dongdong.deng@windriver.com>
Cc: Sergei Shtylyov <sshtylyov@mvista.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/blackfin/include/asm/kgdb.h | 1 | ||||
-rw-r--r-- | arch/sh/include/asm/kgdb.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/kgdb.h | 1 | ||||
-rw-r--r-- | drivers/misc/kgdbts.c | 29 |
4 files changed, 14 insertions, 18 deletions
diff --git a/arch/blackfin/include/asm/kgdb.h b/arch/blackfin/include/asm/kgdb.h index 3ac0c72e9fee..aaf884591b07 100644 --- a/arch/blackfin/include/asm/kgdb.h +++ b/arch/blackfin/include/asm/kgdb.h @@ -108,6 +108,7 @@ static inline void arch_kgdb_breakpoint(void) #else # define CACHE_FLUSH_IS_SAFE 1 #endif +#define GDB_ADJUSTS_BREAK_OFFSET #define HW_INST_WATCHPOINT_NUM 6 #define HW_WATCHPOINT_NUM 8 #define TYPE_INST_WATCHPOINT 0 diff --git a/arch/sh/include/asm/kgdb.h b/arch/sh/include/asm/kgdb.h index 4235e228d921..f3613952d1ae 100644 --- a/arch/sh/include/asm/kgdb.h +++ b/arch/sh/include/asm/kgdb.h @@ -34,5 +34,6 @@ static inline void arch_kgdb_breakpoint(void) #define CACHE_FLUSH_IS_SAFE 1 #define BREAK_INSTR_SIZE 2 +#define GDB_ADJUSTS_BREAK_OFFSET #endif /* __ASM_SH_KGDB_H */ diff --git a/arch/x86/include/asm/kgdb.h b/arch/x86/include/asm/kgdb.h index 396f5b5fc4d7..77e95f54570a 100644 --- a/arch/x86/include/asm/kgdb.h +++ b/arch/x86/include/asm/kgdb.h @@ -77,6 +77,7 @@ static inline void arch_kgdb_breakpoint(void) } #define BREAK_INSTR_SIZE 1 #define CACHE_FLUSH_IS_SAFE 1 +#define GDB_ADJUSTS_BREAK_OFFSET extern int kgdb_ll_trap(int cmd, const char *str, struct pt_regs *regs, long err, int trap, int sig); diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index 74f16f167b8e..b0c56313dbbb 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c @@ -285,33 +285,26 @@ static void hw_break_val_write(void) static int check_and_rewind_pc(char *put_str, char *arg) { unsigned long addr = lookup_addr(arg); + unsigned long ip; int offset = 0; kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs, NUMREGBYTES); gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs); - v2printk("Stopped at IP: %lx\n", instruction_pointer(&kgdbts_regs)); -#ifdef CONFIG_X86 - /* On x86 a breakpoint stop requires it to be decremented */ - if (addr + 1 == kgdbts_regs.ip) - offset = -1; -#elif defined(CONFIG_SUPERH) - /* On SUPERH a breakpoint stop requires it to be decremented */ - if (addr + 2 == kgdbts_regs.pc) - offset = -2; + ip = instruction_pointer(&kgdbts_regs); + v2printk("Stopped at IP: %lx\n", ip); +#ifdef GDB_ADJUSTS_BREAK_OFFSET + /* On some arches, a breakpoint stop requires it to be decremented */ + if (addr + BREAK_INSTR_SIZE == ip) + offset = -BREAK_INSTR_SIZE; #endif - if (strcmp(arg, "silent") && - instruction_pointer(&kgdbts_regs) + offset != addr) { + if (strcmp(arg, "silent") && ip + offset != addr) { eprintk("kgdbts: BP mismatch %lx expected %lx\n", - instruction_pointer(&kgdbts_regs) + offset, addr); + ip + offset, addr); return 1; } -#ifdef CONFIG_X86 - /* On x86 adjust the instruction pointer if needed */ - kgdbts_regs.ip += offset; -#elif defined(CONFIG_SUPERH) - kgdbts_regs.pc += offset; -#endif + /* Readjust the instruction pointer if needed */ + instruction_pointer_set(&kgdbts_regs, ip + offset); return 0; } |