From f90e911026cb0e37e76ecdd36b901b0ed74296dd Mon Sep 17 00:00:00 2001 From: Spencer Oliver Date: Thu, 12 Sep 2013 14:49:19 +0100 Subject: [PATCH] gdb: cleanup gdb target description support Make sure we free any memory used for gdb_save_tdesc. Change-Id: Ia226f6134318c8c6b0ac4fa20fe70a570a08d80d Signed-off-by: Spencer Oliver Reviewed-on: http://openocd.zylin.com/1619 Tested-by: jenkins Reviewed-by: Andreas Fritiofson --- src/server/gdb_server.c | 63 ++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index a930ec41..97cf26f2 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -60,6 +60,11 @@ * found in most modern embedded processors. */ +struct target_desc_format { + char *tdesc; + uint32_t tdesc_length; +}; + /* private connection data for GDB */ struct gdb_connection { char buffer[GDB_BUFFER_SIZE]; @@ -85,6 +90,8 @@ struct gdb_connection { * normally we reply with a S reply via gdb_last_signal_packet. * as a side note this behaviour only effects gdb > 6.8 */ bool attached; + /* temporarily used for target description support */ + struct target_desc_format target_desc; }; #if 0 @@ -909,6 +916,8 @@ static int gdb_new_connection(struct connection *connection) gdb_connection->sync = false; gdb_connection->mem_write_error = false; gdb_connection->attached = true; + gdb_connection->target_desc.tdesc = NULL; + gdb_connection->target_desc.tdesc_length = 0; /* send ACK to GDB for debug request */ gdb_write(connection, "+", 1); @@ -1967,7 +1976,7 @@ static int gdb_generate_reg_type_description(struct target *target, /* Get a list of available target registers features. feature_list must * be freed by caller. */ -int get_reg_features_list(struct target *target, char **feature_list[], int *feature_list_size, +static int get_reg_features_list(struct target *target, char **feature_list[], int *feature_list_size, struct reg **reg_list, int reg_list_size) { int tbl_sz = 0; @@ -2118,14 +2127,24 @@ static int gdb_generate_target_description(struct target *target, char **tdesc) return ERROR_OK; } -static int gdb_get_target_description_chunk(struct target *target, char **chunk, - int32_t offset, uint32_t length) +static int gdb_get_target_description_chunk(struct target *target, struct target_desc_format *target_desc, + char **chunk, int32_t offset, uint32_t length) { - static char *tdesc; - static uint32_t tdesc_length; + if (target_desc == NULL) { + LOG_ERROR("Unable to Generate Target Description"); + return ERROR_FAIL; + } + + char *tdesc = target_desc->tdesc; + uint32_t tdesc_length = target_desc->tdesc_length; if (tdesc == NULL) { - gdb_generate_target_description(target, &tdesc); + int retval = gdb_generate_target_description(target, &tdesc); + if (retval != ERROR_OK) { + LOG_ERROR("Unable to Generate Target Description"); + return ERROR_FAIL; + } + tdesc_length = strlen(tdesc); } @@ -2137,6 +2156,11 @@ static int gdb_get_target_description_chunk(struct target *target, char **chunk, transfer_type = 'l'; *chunk = malloc(length + 2); + if (*chunk == NULL) { + LOG_ERROR("Unable to allocate memory"); + return ERROR_FAIL; + } + (*chunk)[0] = transfer_type; if (transfer_type == 'm') { strncpy((*chunk) + 1, tdesc + offset, length); @@ -2151,6 +2175,9 @@ static int gdb_get_target_description_chunk(struct target *target, char **chunk, tdesc_length = 0; } + target_desc->tdesc = tdesc; + target_desc->tdesc_length = tdesc_length; + return ERROR_OK; } @@ -2325,7 +2352,8 @@ static int gdb_query_packet(struct connection *connection, * there are *more* chunks to transfer. 'l' for it is the *last* * chunk of target description. */ - retval = gdb_get_target_description_chunk(target, &xml, offset, length); + retval = gdb_get_target_description_chunk(target, &gdb_connection->target_desc, + &xml, offset, length); if (retval != ERROR_OK) { gdb_error(connection, retval); return retval; @@ -2981,14 +3009,22 @@ COMMAND_HANDLER(handle_gdb_target_description_command) COMMAND_HANDLER(handle_gdb_save_tdesc_command) { - static char *tdesc; - static uint32_t tdesc_length; + char *tdesc; + uint32_t tdesc_length; struct target *target = get_current_target(CMD_CTX); char *tdesc_filename; - if (tdesc == NULL) { - gdb_generate_target_description(target, &tdesc); - tdesc_length = strlen(tdesc); + int retval = gdb_generate_target_description(target, &tdesc); + if (retval != ERROR_OK) { + LOG_ERROR("Unable to Generate Target Description"); + return ERROR_FAIL; + } + + tdesc_length = strlen(tdesc); + + if (tdesc_length == 0) { + LOG_ERROR("Unable to Generate Target Description"); + return ERROR_FAIL; } struct fileio fileio; @@ -2997,7 +3033,7 @@ COMMAND_HANDLER(handle_gdb_save_tdesc_command) tdesc_filename = malloc(strlen(target_type_name(target)) + 5); sprintf(tdesc_filename, "%s.xml", target_type_name(target)); - int retval = fileio_open(&fileio, tdesc_filename, FILEIO_WRITE, FILEIO_TEXT); + retval = fileio_open(&fileio, tdesc_filename, FILEIO_WRITE, FILEIO_TEXT); if (retval != ERROR_OK) { LOG_WARNING("Can't open %s for writing", tdesc_filename); @@ -3009,6 +3045,7 @@ COMMAND_HANDLER(handle_gdb_save_tdesc_command) fileio_close(&fileio); free(tdesc_filename); + free(tdesc); if (retval != ERROR_OK) { LOG_WARNING("Error while writing the tdesc file"); -- 2.39.5