diff options
-rw-r--r-- | gdbstub.c | 32 | ||||
-rw-r--r-- | include/qom/cpu.h | 3 | ||||
-rw-r--r-- | target-arm/cpu.c | 1 | ||||
-rw-r--r-- | target-cris/cpu.c | 1 | ||||
-rw-r--r-- | target-lm32/cpu.c | 1 | ||||
-rw-r--r-- | target-mips/cpu.c | 1 | ||||
-rw-r--r-- | target-xtensa/cpu.c | 1 |
7 files changed, 31 insertions, 9 deletions
@@ -625,11 +625,23 @@ void gdb_register_coprocessor(CPUState *cpu, } #ifndef CONFIG_USER_ONLY -static const int xlat_gdb_type[] = { - [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE, - [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ, - [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS, -}; +/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */ +static inline int xlat_gdb_type(CPUState *cpu, int gdbtype) +{ + static const int xlat[] = { + [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE, + [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ, + [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS, + }; + + CPUClass *cc = CPU_GET_CLASS(cpu); + int cputype = xlat[gdbtype]; + + if (cc->gdb_stop_before_watchpoint) { + cputype |= BP_STOP_BEFORE_ACCESS; + } + return cputype; +} #endif static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) @@ -656,10 +668,11 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) case GDB_WATCHPOINT_READ: case GDB_WATCHPOINT_ACCESS: CPU_FOREACH(cpu) { - err = cpu_watchpoint_insert(cpu, addr, len, xlat_gdb_type[type], - NULL); - if (err) + err = cpu_watchpoint_insert(cpu, addr, len, + xlat_gdb_type(cpu, type), NULL); + if (err) { break; + } } return err; #endif @@ -692,7 +705,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type) case GDB_WATCHPOINT_READ: case GDB_WATCHPOINT_ACCESS: CPU_FOREACH(cpu) { - err = cpu_watchpoint_remove(cpu, addr, len, xlat_gdb_type[type]); + err = cpu_watchpoint_remove(cpu, addr, len, + xlat_gdb_type(cpu, type)); if (err) break; } diff --git a/include/qom/cpu.h b/include/qom/cpu.h index f576b472fd..2098f1cb50 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -99,6 +99,8 @@ struct TranslationBlock; * @vmsd: State description for migration. * @gdb_num_core_regs: Number of core registers accessible to GDB. * @gdb_core_xml_file: File name for core registers GDB XML description. + * @gdb_stop_before_watchpoint: Indicates whether GDB expects the CPU to stop + * before the insn which triggers a watchpoint rather than after it. * @cpu_exec_enter: Callback for cpu_exec preparation. * @cpu_exec_exit: Callback for cpu_exec cleanup. * @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec. @@ -152,6 +154,7 @@ typedef struct CPUClass { const struct VMStateDescription *vmsd; int gdb_num_core_regs; const char *gdb_core_xml_file; + bool gdb_stop_before_watchpoint; void (*cpu_exec_enter)(CPUState *cpu); void (*cpu_exec_exit)(CPUState *cpu); diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 8ab6d9532e..edfd5868b8 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -1117,6 +1117,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) #endif cc->gdb_num_core_regs = 26; cc->gdb_core_xml_file = "arm-core.xml"; + cc->gdb_stop_before_watchpoint = true; cc->debug_excp_handler = arm_debug_excp_handler; } diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 528e458aaa..16cfba95ff 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -291,6 +291,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data) #endif cc->gdb_num_core_regs = 49; + cc->gdb_stop_before_watchpoint = true; } static const TypeInfo cris_cpu_type_info = { diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index 6c5de660dd..f8081f52c1 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -273,6 +273,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data) cc->vmsd = &vmstate_lm32_cpu; #endif cc->gdb_num_core_regs = 32 + 7; + cc->gdb_stop_before_watchpoint = true; cc->debug_excp_handler = lm32_debug_excp_handler; } diff --git a/target-mips/cpu.c b/target-mips/cpu.c index 5ed60f78a7..98dc94e74b 100644 --- a/target-mips/cpu.c +++ b/target-mips/cpu.c @@ -151,6 +151,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) #endif cc->gdb_num_core_regs = 73; + cc->gdb_stop_before_watchpoint = true; } static const TypeInfo mips_cpu_type_info = { diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c index 51c41d526d..6a5414f815 100644 --- a/target-xtensa/cpu.c +++ b/target-xtensa/cpu.c @@ -147,6 +147,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data) cc->set_pc = xtensa_cpu_set_pc; cc->gdb_read_register = xtensa_cpu_gdb_read_register; cc->gdb_write_register = xtensa_cpu_gdb_write_register; + cc->gdb_stop_before_watchpoint = true; #ifndef CONFIG_USER_ONLY cc->do_unaligned_access = xtensa_cpu_do_unaligned_access; cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug; |