This is an automated email from Gerrit. "Ian Thompson <ia...@cadence.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7082
-- gerrit commit bca1ffb3a374fc5cf8b47b423ac4f72f0955866e Author: Ian Thompson <ia...@cadence.com> Date: Sun Jul 10 17:14:10 2022 -0700 target/server: custom target-specific GDB queries, sparse register maps The following server extensions are provided in the context of generic Xtensa target support: - Handle sparse register addressing, where gaps may exist in reg_list[] - Add "SW breakpoints unsupported" non-error reply for Z-packets - Add customizable hook for handling target-specific GDB queries Valgrind-clean, no new Clang analyzer warnings Signed-off-by: Ian Thompson <ia...@cadence.com> Change-Id: I684a259ed29f3651cbce668101cff421e522f79e diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 4efdc1ee7e..c47510bd01 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1334,6 +1334,8 @@ static int gdb_set_registers_packet(struct connection *connection, packet_p = packet; for (i = 0; i < reg_list_size; i++) { uint8_t *bin_buf; + if (!reg_list[i] || !reg_list[i]->exist) + continue; int chars = (DIV_ROUND_UP(reg_list[i]->size, 8) * 2); if (packet_p + chars > packet + packet_size) @@ -1386,7 +1388,7 @@ static int gdb_get_register_packet(struct connection *connection, if (retval != ERROR_OK) return gdb_error(connection, retval); - if (reg_list_size <= reg_num) { + if ((reg_list_size <= reg_num) || !reg_list[reg_num]) { LOG_ERROR("gdb requested a non-existing register (reg_num=%d)", reg_num); return ERROR_SERVER_REMOTE_CLOSED; } @@ -1448,7 +1450,7 @@ static int gdb_set_register_packet(struct connection *connection, return gdb_error(connection, retval); } - if (reg_list_size <= reg_num) { + if ((reg_list_size <= reg_num) || !reg_list[reg_num]) { LOG_ERROR("gdb requested a non-existing register (reg_num=%d)", reg_num); free(bin_buf); free(reg_list); @@ -1781,7 +1783,10 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection, case 1: if (packet[0] == 'Z') { retval = breakpoint_add(target, address, size, bp_type); - if (retval != ERROR_OK) { + if (retval == ERROR_TARGET_INVALID) { + /* SW breakpoints not supported */ + gdb_put_packet(connection, "", 0); + } else if (retval != ERROR_OK) { retval = gdb_error(connection, retval); if (retval != ERROR_OK) return retval; @@ -2966,6 +2971,11 @@ static int gdb_query_packet(struct connection *connection, gdb_connection->noack_mode = 1; gdb_put_packet(connection, "OK", 2); return ERROR_OK; + } else if (target->type->gdb_query_custom) { + char *buffer = NULL; + int ret = target->type->gdb_query_custom(target, packet, &buffer); + gdb_put_packet(connection, buffer, strlen(buffer)); + return ret; } gdb_put_packet(connection, "", 0); diff --git a/src/target/target_type.h b/src/target/target_type.h index a26c2e7d87..82ef78e143 100644 --- a/src/target/target_type.h +++ b/src/target/target_type.h @@ -297,6 +297,10 @@ struct target_type { */ int (*gdb_fileio_end)(struct target *target, int retcode, int fileio_errno, bool ctrl_c); + /* parse target-specific GDB query commands + */ + int (*gdb_query_custom)(struct target *target, const char *packet, char **response_p); + /* do target profiling */ int (*profiling)(struct target *target, uint32_t *samples, --