Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Mike Frysinger and committed by
Linus Torvalds
63ab25eb 3cea45c6

+14 -18
+1
arch/blackfin/include/asm/kgdb.h
··· 108 108 #else 109 109 # define CACHE_FLUSH_IS_SAFE 1 110 110 #endif 111 + #define GDB_ADJUSTS_BREAK_OFFSET 111 112 #define HW_INST_WATCHPOINT_NUM 6 112 113 #define HW_WATCHPOINT_NUM 8 113 114 #define TYPE_INST_WATCHPOINT 0
+1
arch/sh/include/asm/kgdb.h
··· 34 34 35 35 #define CACHE_FLUSH_IS_SAFE 1 36 36 #define BREAK_INSTR_SIZE 2 37 + #define GDB_ADJUSTS_BREAK_OFFSET 37 38 38 39 #endif /* __ASM_SH_KGDB_H */
+1
arch/x86/include/asm/kgdb.h
··· 77 77 } 78 78 #define BREAK_INSTR_SIZE 1 79 79 #define CACHE_FLUSH_IS_SAFE 1 80 + #define GDB_ADJUSTS_BREAK_OFFSET 80 81 81 82 extern int kgdb_ll_trap(int cmd, const char *str, 82 83 struct pt_regs *regs, long err, int trap, int sig);
+11 -18
drivers/misc/kgdbts.c
··· 285 285 static int check_and_rewind_pc(char *put_str, char *arg) 286 286 { 287 287 unsigned long addr = lookup_addr(arg); 288 + unsigned long ip; 288 289 int offset = 0; 289 290 290 291 kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs, 291 292 NUMREGBYTES); 292 293 gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs); 293 - v2printk("Stopped at IP: %lx\n", instruction_pointer(&kgdbts_regs)); 294 - #ifdef CONFIG_X86 295 - /* On x86 a breakpoint stop requires it to be decremented */ 296 - if (addr + 1 == kgdbts_regs.ip) 297 - offset = -1; 298 - #elif defined(CONFIG_SUPERH) 299 - /* On SUPERH a breakpoint stop requires it to be decremented */ 300 - if (addr + 2 == kgdbts_regs.pc) 301 - offset = -2; 294 + ip = instruction_pointer(&kgdbts_regs); 295 + v2printk("Stopped at IP: %lx\n", ip); 296 + #ifdef GDB_ADJUSTS_BREAK_OFFSET 297 + /* On some arches, a breakpoint stop requires it to be decremented */ 298 + if (addr + BREAK_INSTR_SIZE == ip) 299 + offset = -BREAK_INSTR_SIZE; 302 300 #endif 303 - if (strcmp(arg, "silent") && 304 - instruction_pointer(&kgdbts_regs) + offset != addr) { 301 + if (strcmp(arg, "silent") && ip + offset != addr) { 305 302 eprintk("kgdbts: BP mismatch %lx expected %lx\n", 306 - instruction_pointer(&kgdbts_regs) + offset, addr); 303 + ip + offset, addr); 307 304 return 1; 308 305 } 309 - #ifdef CONFIG_X86 310 - /* On x86 adjust the instruction pointer if needed */ 311 - kgdbts_regs.ip += offset; 312 - #elif defined(CONFIG_SUPERH) 313 - kgdbts_regs.pc += offset; 314 - #endif 306 + /* Readjust the instruction pointer if needed */ 307 + instruction_pointer_set(&kgdbts_regs, ip + offset); 315 308 return 0; 316 309 } 317 310