From eeae8c4261e529f45ded618a6f92c32cd8160f3e Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Mon, 2 Apr 2018 13:37:53 -0700 Subject: [PATCH] Add gdb_report_register_access_error command This replaces the earlier mechanism which would propagate errors only for targets that decided they wanted to. It was suggested by Matthias Welwarsky from the OpenOCD team. Change-Id: Ibe8e97644abb47aff26d74b8280377d42615a4d3 --- src/server/gdb_server.c | 27 +++++++++++++++++++++++---- src/target/riscv/riscv.c | 1 - src/target/target.h | 8 -------- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 836e78362..4a5480352 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -126,6 +126,9 @@ static int gdb_flash_program = 1; * Disabled by default. */ static int gdb_report_data_abort; +/* If set, errors when accessing registers are reported to gdb. Disabled by + * default. */ +static int gdb_report_register_access_error; /* set if we are sending target descriptions to gdb * via qXfer:features:read packet */ @@ -1174,7 +1177,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 && target->propagate_register_errors) { + if (retval != ERROR_OK && gdb_report_register_access_error) { LOG_DEBUG("Couldn't get register %s.", reg_list[i]->name); free(reg_packet); free(reg_list); @@ -1242,7 +1245,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 && target->propagate_register_errors) { + if (retval != ERROR_OK && gdb_report_register_access_error) { LOG_DEBUG("Couldn't set register %s.", reg_list[i]->name); free(reg_list); free(bin_buf); @@ -1289,7 +1292,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 && target->propagate_register_errors) { + if (retval != ERROR_OK && gdb_report_register_access_error) { LOG_DEBUG("Couldn't get register %s.", reg_list[reg_num]->name); free(reg_list); return gdb_error(connection, retval); @@ -1349,7 +1352,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 && target->propagate_register_errors) { + if (retval != ERROR_OK && gdb_report_register_access_error) { LOG_DEBUG("Couldn't set register %s.", reg_list[reg_num]->name); free(bin_buf); free(reg_list); @@ -3209,6 +3212,15 @@ COMMAND_HANDLER(handle_gdb_report_data_abort_command) return ERROR_OK; } +COMMAND_HANDLER(handle_gdb_report_register_access_error) +{ + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_report_register_access_error); + return ERROR_OK; +} + /* gdb_breakpoint_override */ COMMAND_HANDLER(handle_gdb_breakpoint_override_command) { @@ -3330,6 +3342,13 @@ static const struct command_registration gdb_command_handlers[] = { .help = "enable or disable reporting data aborts", .usage = "('enable'|'disable')" }, + { + .name = "gdb_report_register_access_error", + .handler = handle_gdb_report_register_access_error, + .mode = COMMAND_CONFIG, + .help = "enable or disable reporting register access errors", + .usage = "('enable'|'disable')" + }, { .name = "gdb_breakpoint_override", .handler = handle_gdb_breakpoint_override_command, diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 3a7fe4150..2e980dcb4 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -247,7 +247,6 @@ 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 c11a626f8..0096cae10 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -204,14 +204,6 @@ 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 {