diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index b59b9f12f..836e78362 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1174,7 +1174,7 @@ static int gdb_get_registers_packet(struct connection *connection, for (i = 0; i < reg_list_size; i++) { if (!reg_list[i]->valid) { retval = reg_list[i]->type->get(reg_list[i]); - if (retval != ERROR_OK) { + if (retval != ERROR_OK && target->propagate_register_errors) { LOG_DEBUG("Couldn't get register %s.", reg_list[i]->name); free(reg_packet); free(reg_list); @@ -1242,7 +1242,7 @@ static int gdb_set_registers_packet(struct connection *connection, gdb_target_to_reg(target, packet_p, chars, bin_buf); retval = reg_list[i]->type->set(reg_list[i], bin_buf); - if (retval != ERROR_OK) { + if (retval != ERROR_OK && target->propagate_register_errors) { LOG_DEBUG("Couldn't set register %s.", reg_list[i]->name); free(reg_list); free(bin_buf); @@ -1289,7 +1289,7 @@ static int gdb_get_register_packet(struct connection *connection, if (!reg_list[reg_num]->valid) { retval = reg_list[reg_num]->type->get(reg_list[reg_num]); - if (retval != ERROR_OK) { + if (retval != ERROR_OK && target->propagate_register_errors) { LOG_DEBUG("Couldn't get register %s.", reg_list[reg_num]->name); free(reg_list); return gdb_error(connection, retval); @@ -1349,7 +1349,7 @@ static int gdb_set_register_packet(struct connection *connection, gdb_target_to_reg(target, separator + 1, chars, bin_buf); retval = reg_list[reg_num]->type->set(reg_list[reg_num], bin_buf); - if (retval != ERROR_OK) { + if (retval != ERROR_OK && target->propagate_register_errors) { LOG_DEBUG("Couldn't set register %s.", reg_list[reg_num]->name); free(bin_buf); free(reg_list); diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 60191d85d..6902ec283 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -245,6 +245,7 @@ static int riscv_init_target(struct command_context *cmd_ctx, struct target *target) { LOG_DEBUG("riscv_init_target()"); + target->propagate_register_errors = true; target->arch_info = calloc(1, sizeof(riscv_info_t)); if (!target->arch_info) return ERROR_FAIL; diff --git a/src/target/target.h b/src/target/target.h index 0096cae10..c11a626f8 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -204,6 +204,14 @@ struct target { /* file-I/O information for host to do syscall */ struct gdb_fileio_info *fileio_info; + + /** + * When true, send gdb an error result when reading/writing a register + * fails. This must be false for some ARM targets (Cortex-M3), where a 'g' + * packet results in an attempt to read 'r0', which fails, which causes gdb + * to close the connection. + */ + bool propagate_register_errors; }; struct target_list {