+ GDBRegisterState *s;
+ GDBRegisterState **p;
+ static int last_reg = NUM_CORE_REGS;
+
+ s = (GDBRegisterState *)qemu_mallocz(sizeof(GDBRegisterState));
+ s->base_reg = last_reg;
+ s->num_regs = num_regs;
+ s->get_reg = get_reg;
+ s->set_reg = set_reg;
+ s->xml = xml;
+ p = &env->gdb_regs;
+ while (*p) {
+ /* Check for duplicates. */
+ if (strcmp((*p)->xml, xml) == 0)
+ return;
+ p = &(*p)->next;
+ }
+ /* Add to end of list. */
+ last_reg += num_regs;
+ *p = s;
+ if (g_pos) {
+ if (g_pos != s->base_reg) {
+ fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
+ "Expected %d got %d\n", xml, g_pos, s->base_reg);
+ } else {
+ num_g_regs = last_reg;
+ }
+ }
+}
+
+#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,
+};
+#endif
+
+static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
+{
+ CPUState *env;
+ int err = 0;
+
+ if (kvm_enabled())
+ return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+
+ switch (type) {
+ case GDB_BREAKPOINT_SW:
+ case GDB_BREAKPOINT_HW:
+ for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
+ if (err)
+ break;
+ }
+ return err;
+#ifndef CONFIG_USER_ONLY
+ case GDB_WATCHPOINT_WRITE:
+ case GDB_WATCHPOINT_READ:
+ case GDB_WATCHPOINT_ACCESS:
+ for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
+ NULL);
+ if (err)
+ break;
+ }
+ return err;
+#endif
+ default:
+ return -ENOSYS;
+ }