X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fserver%2Fgdb_server.c;h=780359ea4510ac1ee344fcf6438834b9e338fdf2;hp=7bf7319c54cc60b338951f953890d1a457bb357f;hb=72466de39931cbe872db367c878c5ed17a4b67f3;hpb=e4125d136c72b1225c4547e670db102f88cf6efc diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 7bf7319c54..780359ea45 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -628,7 +628,7 @@ static int gdb_get_packet_inner(struct connection *connection, * warning only about subsequent ACK's. */ if (gdb_con->noack_mode > 1) { LOG_WARNING("acknowledgment received, but no packet pending"); - } else { + } else if (gdb_con->noack_mode) { LOG_DEBUG("Received first acknowledgment after entering noack mode. Ignoring it."); gdb_con->noack_mode = 2; } @@ -714,11 +714,14 @@ static int gdb_output(struct command_context *context, const char *line) static void gdb_signal_reply(struct target *target, struct connection *connection) { struct gdb_connection *gdb_connection = connection->priv; - char sig_reply[20]; + char sig_reply[45]; char stop_reason[20]; + char current_thread[25]; int sig_reply_len; int signal_var; + rtos_update_threads(target); + if (target->debug_reason == DBG_REASON_EXIT) { sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "W00"); } else { @@ -754,13 +757,18 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio } } - sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "T%2.2x%s", - signal_var, stop_reason); + current_thread[0] = '\0'; + if (target->rtos != NULL) { + snprintf(current_thread, sizeof(current_thread), "thread:%016" PRIx64 ";", target->rtos->current_thread); + target->rtos->current_threadid = target->rtos->current_thread; + } + + sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "T%2.2x%s%s", + signal_var, stop_reason, current_thread); } gdb_put_packet(connection, sig_reply, sig_reply_len); gdb_connection->frontend_state = TARGET_HALTED; - rtos_update_threads(target); } static void gdb_fileio_reply(struct target *target, struct connection *connection) @@ -1044,7 +1052,7 @@ static void gdb_send_error(struct connection *connection, uint8_t the_error) } static int gdb_last_signal_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct target *target = get_target_from_connection(connection); struct gdb_connection *gdb_con = connection->priv; @@ -1101,7 +1109,7 @@ static void gdb_str_to_target(struct target *target, /* copy over in register buffer */ static void gdb_target_to_reg(struct target *target, - char *tstr, int str_len, uint8_t *bin) + char const *tstr, int str_len, uint8_t *bin) { if (str_len % 2) { LOG_ERROR("BUG: gdb value with uneven number of characters encountered"); @@ -1122,7 +1130,7 @@ static void gdb_target_to_reg(struct target *target, } static int gdb_get_registers_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct target *target = get_target_from_connection(connection); struct reg **reg_list; @@ -1151,6 +1159,9 @@ static int gdb_get_registers_packet(struct connection *connection, assert(reg_packet_size > 0); reg_packet = malloc(reg_packet_size + 1); /* plus one for string termination null */ + if (reg_packet == NULL) + return ERROR_FAIL; + reg_packet_p = reg_packet; for (i = 0; i < reg_list_size; i++) { @@ -1178,14 +1189,14 @@ static int gdb_get_registers_packet(struct connection *connection, } static int gdb_set_registers_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct target *target = get_target_from_connection(connection); int i; struct reg **reg_list; int reg_list_size; int retval; - char *packet_p; + char const *packet_p; #ifdef _DEBUG_GDB_IO_ LOG_DEBUG("-"); @@ -1233,7 +1244,7 @@ static int gdb_set_registers_packet(struct connection *connection, } static int gdb_get_register_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct target *target = get_target_from_connection(connection); char *reg_packet; @@ -1272,7 +1283,7 @@ static int gdb_get_register_packet(struct connection *connection, } static int gdb_set_register_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct target *target = get_target_from_connection(connection); char *separator; @@ -1338,7 +1349,7 @@ static int gdb_error(struct connection *connection, int retval) * 8191 bytes by the looks of it. Why 8191 bytes instead of 8192????? */ static int gdb_read_memory_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct target *target = get_target_from_connection(connection); char *separator; @@ -1409,7 +1420,7 @@ static int gdb_read_memory_packet(struct connection *connection, } static int gdb_write_memory_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct target *target = get_target_from_connection(connection); char *separator; @@ -1456,7 +1467,7 @@ static int gdb_write_memory_packet(struct connection *connection, } static int gdb_write_memory_binary_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct target *target = get_target_from_connection(connection); char *separator; @@ -1513,7 +1524,7 @@ static int gdb_write_memory_binary_packet(struct connection *connection, } static int gdb_step_continue_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct target *target = get_target_from_connection(connection); int current = 0; @@ -1522,10 +1533,9 @@ static int gdb_step_continue_packet(struct connection *connection, LOG_DEBUG("-"); - if (packet_size > 1) { - packet[packet_size] = 0; + if (packet_size > 1) address = strtoul(packet + 1, NULL, 16); - } else + else current = 1; gdb_running_type = packet[0]; @@ -1542,7 +1552,7 @@ static int gdb_step_continue_packet(struct connection *connection, } static int gdb_breakpoint_watchpoint_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct target *target = get_target_from_connection(connection); int type; @@ -1670,29 +1680,31 @@ static void xml_printf(int *retval, char **xml, int *pos, int *size, } } -static int decode_xfer_read(char *buf, char **annex, int *ofs, unsigned int *len) +static int decode_xfer_read(char const *buf, char **annex, int *ofs, unsigned int *len) { - char *separator; - - /* Extract and NUL-terminate the annex. */ - *annex = buf; - while (*buf && *buf != ':') - buf++; - if (*buf == '\0') - return -1; - *buf++ = 0; + /* Locate the annex. */ + const char *annex_end = strchr(buf, ':'); + if (annex_end == NULL) + return ERROR_FAIL; /* After the read marker and annex, qXfer looks like a * traditional 'm' packet. */ - - *ofs = strtoul(buf, &separator, 16); + char *separator; + *ofs = strtoul(annex_end + 1, &separator, 16); if (*separator != ',') - return -1; + return ERROR_FAIL; *len = strtoul(separator + 1, NULL, 16); - return 0; + /* Extract the annex if needed */ + if (annex != NULL) { + *annex = strndup(buf, annex_end - buf); + if (*annex == NULL) + return ERROR_FAIL; + } + + return ERROR_OK; } static int compare_bank(const void *a, const void *b) @@ -1710,7 +1722,7 @@ static int compare_bank(const void *a, const void *b) } static int gdb_memory_map(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { /* We get away with only specifying flash here. Regions that are not * specified are treated as if we provided no memory map(if not we @@ -1997,7 +2009,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. */ -static 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 const **feature_list[], int *feature_list_size, struct reg **reg_list, int reg_list_size) { int tbl_sz = 0; @@ -2018,7 +2030,7 @@ static int get_reg_features_list(struct target *target, char **feature_list[], i */ for (int j = 0; j < (tbl_sz + 1); j++) { if (!((*feature_list)[j])) { - (*feature_list)[tbl_sz++] = strdup(reg_list[i]->feature->name); + (*feature_list)[tbl_sz++] = reg_list[i]->feature->name; *feature_list = realloc(*feature_list, sizeof(char *) * (tbl_sz + 1)); (*feature_list)[tbl_sz] = NULL; break; @@ -2039,8 +2051,10 @@ static int get_reg_features_list(struct target *target, char **feature_list[], i static int gdb_generate_target_description(struct target *target, char **tdesc_out) { int retval = ERROR_OK; - struct reg **reg_list; + struct reg **reg_list = NULL; int reg_list_size; + char const **features = NULL; + int feature_list_size = 0; char *tdesc = NULL; int pos = 0; int size = 0; @@ -2050,21 +2064,22 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o if (retval != ERROR_OK) { LOG_ERROR("get register list failed"); - return ERROR_FAIL; + retval = ERROR_FAIL; + goto error; } if (reg_list_size <= 0) { - free(reg_list); - return ERROR_FAIL; + LOG_ERROR("get register list failed"); + retval = ERROR_FAIL; + goto error; } - char **features = NULL; /* Get a list of available target registers features */ - retval = get_reg_features_list(target, &features, NULL, reg_list, reg_list_size); + retval = get_reg_features_list(target, &features, &feature_list_size, reg_list, reg_list_size); if (retval != ERROR_OK) { LOG_ERROR("Can't get the registers feature list"); - free(reg_list); - return ERROR_FAIL; + retval = ERROR_FAIL; + goto error; } /* If we found some features associated with registers, create sections */ @@ -2144,8 +2159,9 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o xml_printf(&retval, &tdesc, &pos, &size, "\n"); - free(reg_list); +error: free(features); + free(reg_list); if (retval == ERROR_OK) *tdesc_out = tdesc; @@ -2214,8 +2230,8 @@ static int gdb_target_description_supported(struct target *target, int *supporte int retval = ERROR_OK; struct reg **reg_list = NULL; int reg_list_size = 0; + char const **features = NULL; int feature_list_size = 0; - char **features = NULL; retval = target_get_gdb_reg_list(target, ®_list, ®_list_size, REG_CLASS_ALL); @@ -2225,6 +2241,7 @@ static int gdb_target_description_supported(struct target *target, int *supporte } if (reg_list_size <= 0) { + LOG_ERROR("get register list failed"); retval = ERROR_FAIL; goto error; } @@ -2244,17 +2261,15 @@ static int gdb_target_description_supported(struct target *target, int *supporte } error: - if (reg_list != NULL) - free(reg_list); + free(features); - if (features != NULL) - free(features); + free(reg_list); return retval; } static int gdb_query_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct command_context *cmd_ctx = connection->cmd_ctx; struct gdb_connection *gdb_connection = connection->priv; @@ -2365,12 +2380,11 @@ static int gdb_query_packet(struct connection *connection, int offset; unsigned int length; - char *annex; /* skip command character */ packet += 20; - if (decode_xfer_read(packet, &annex, &offset, &length) < 0) { + if (decode_xfer_read(packet, NULL, &offset, &length) < 0) { gdb_send_error(connection, 01); return ERROR_OK; } @@ -2402,7 +2416,7 @@ static int gdb_query_packet(struct connection *connection, } static int gdb_v_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct gdb_connection *gdb_connection = connection->priv; struct gdb_service *gdb_service = connection->service->priv; @@ -2419,20 +2433,20 @@ static int gdb_v_packet(struct connection *connection, unsigned long addr; unsigned long length; - char *parse = packet + 12; + char const *parse = packet + 12; if (*parse == '\0') { LOG_ERROR("incomplete vFlashErase packet received, dropping connection"); return ERROR_SERVER_REMOTE_CLOSED; } - addr = strtoul(parse, &parse, 16); + addr = strtoul(parse, (char **)&parse, 16); if (*(parse++) != ',' || *parse == '\0') { LOG_ERROR("incomplete vFlashErase packet received, dropping connection"); return ERROR_SERVER_REMOTE_CLOSED; } - length = strtoul(parse, &parse, 16); + length = strtoul(parse, (char **)&parse, 16); if (*parse != '\0') { LOG_ERROR("incomplete vFlashErase packet received, dropping connection"); @@ -2475,13 +2489,13 @@ static int gdb_v_packet(struct connection *connection, int retval; unsigned long addr; unsigned long length; - char *parse = packet + 12; + char const *parse = packet + 12; if (*parse == '\0') { LOG_ERROR("incomplete vFlashErase packet received, dropping connection"); return ERROR_SERVER_REMOTE_CLOSED; } - addr = strtoul(parse, &parse, 16); + addr = strtoul(parse, (char **)&parse, 16); if (*(parse++) != ':') { LOG_ERROR("incomplete vFlashErase packet received, dropping connection"); return ERROR_SERVER_REMOTE_CLOSED; @@ -2496,7 +2510,7 @@ static int gdb_v_packet(struct connection *connection, /* create new section with content from packet buffer */ retval = image_add_section(gdb_connection->vflash_image, - addr, length, 0x0, (uint8_t *)parse); + addr, length, 0x0, (uint8_t const *)parse); if (retval != ERROR_OK) return retval; @@ -2548,7 +2562,7 @@ static int gdb_detach(struct connection *connection) * Fretcode,errno,Ctrl-C flag;call-specific attachment */ static int gdb_fileio_response_packet(struct connection *connection, - char *packet, int packet_size) + char const *packet, int packet_size) { struct target *target = get_target_from_connection(connection); char *separator; @@ -2620,7 +2634,7 @@ static int gdb_input_inner(struct connection *connection) struct gdb_service *gdb_service = connection->service->priv; struct target *target = gdb_service->target; - char *packet = gdb_packet_buffer; + char const *packet = gdb_packet_buffer; int packet_size; int retval; struct gdb_connection *gdb_con = connection->priv; @@ -2639,12 +2653,12 @@ static int gdb_input_inner(struct connection *connection) */ do { packet_size = GDB_BUFFER_SIZE-1; - retval = gdb_get_packet(connection, packet, &packet_size); + retval = gdb_get_packet(connection, gdb_packet_buffer, &packet_size); if (retval != ERROR_OK) return retval; /* terminate with zero */ - packet[packet_size] = 0; + gdb_packet_buffer[packet_size] = '\0'; if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) { if (packet[0] == 'X') {