aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdbstub.c32
-rw-r--r--include/qom/cpu.h3
-rw-r--r--target-arm/cpu.c1
-rw-r--r--target-cris/cpu.c1
-rw-r--r--target-lm32/cpu.c1
-rw-r--r--target-mips/cpu.c1
-rw-r--r--target-xtensa/cpu.c1
7 files changed, 31 insertions, 9 deletions
diff --git a/gdbstub.c b/gdbstub.c
index 71aaa23da3..d1b5afd8fe 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -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;