X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fserver%2Fgdb_server.c;h=40852ab30d148efb1ec98f18b01ac0e042683fb2;hp=660e05ef949c3be64c0e38955bfd49ffa921ca22;hb=6fcaa4ae8f78790da8d3fbe05d87c355082febb4;hpb=4f885215816624df7bc19523ea2da94ca90772f3 diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 660e05ef94..40852ab30d 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -104,8 +104,8 @@ static int gdb_breakpoint_override; static enum breakpoint_type gdb_breakpoint_override_type; static int gdb_error(struct connection *connection, int retval); -static const char *gdb_port; -static const char *gdb_port_next; +static char *gdb_port; +static char *gdb_port_next; static void gdb_log_callback(void *priv, const char *file, unsigned line, const char *function, const char *string); @@ -617,11 +617,21 @@ static int gdb_get_packet_inner(struct connection *connection, case '$': break; case '+': - /* gdb sends a dummy ack '+' at every remote connect - see - * remote_start_remote (remote.c) - * in case anyone tries to debug why they receive this - * warning every time */ - LOG_WARNING("acknowledgment received, but no packet pending"); + /* According to the GDB documentation + * (https://sourceware.org/gdb/onlinedocs/gdb/Packet-Acknowledgment.html): + * "gdb sends a final `+` acknowledgment of the stub's `OK` + * response, which can be safely ignored by the stub." + * However OpenOCD server already is in noack mode at this + * point and instead of ignoring this it was emitting a + * warning. This code makes server ignore the first ACK + * that will be received after going into noack mode, + * warning only about subsequent ACK's. */ + if (gdb_con->noack_mode > 1) { + LOG_WARNING("acknowledgment received, but no packet pending"); + } else { + LOG_DEBUG("Received first acknowledgment after entering noack mode. Ignoring it."); + gdb_con->noack_mode = 2; + } break; case '-': LOG_WARNING("negative acknowledgment, but no packet pending"); @@ -728,15 +738,15 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio switch (hit_wp_type) { case WPT_WRITE: snprintf(stop_reason, sizeof(stop_reason), - "watch:%08x;", hit_wp_address); + "watch:%08" PRIx32 ";", hit_wp_address); break; case WPT_READ: snprintf(stop_reason, sizeof(stop_reason), - "rwatch:%08x;", hit_wp_address); + "rwatch:%08" PRIx32 ";", hit_wp_address); break; case WPT_ACCESS: snprintf(stop_reason, sizeof(stop_reason), - "awatch:%08x;", hit_wp_address); + "awatch:%08" PRIx32 ";", hit_wp_address); break; default: break; @@ -761,64 +771,64 @@ static void gdb_fileio_reply(struct target *target, struct connection *connectio bool program_exited = false; if (strcmp(target->fileio_info->identifier, "open") == 0) - sprintf(fileio_command, "F%s,%x/%x,%x,%x", target->fileio_info->identifier, + sprintf(fileio_command, "F%s,%" PRIx32 "/%" PRIx32 ",%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, target->fileio_info->param_1, target->fileio_info->param_2, target->fileio_info->param_3, target->fileio_info->param_4); else if (strcmp(target->fileio_info->identifier, "close") == 0) - sprintf(fileio_command, "F%s,%x", target->fileio_info->identifier, + sprintf(fileio_command, "F%s,%" PRIx32, target->fileio_info->identifier, target->fileio_info->param_1); else if (strcmp(target->fileio_info->identifier, "read") == 0) - sprintf(fileio_command, "F%s,%x,%x,%x", target->fileio_info->identifier, + sprintf(fileio_command, "F%s,%" PRIx32 ",%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, target->fileio_info->param_1, target->fileio_info->param_2, target->fileio_info->param_3); else if (strcmp(target->fileio_info->identifier, "write") == 0) - sprintf(fileio_command, "F%s,%x,%x,%x", target->fileio_info->identifier, + sprintf(fileio_command, "F%s,%" PRIx32 ",%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, target->fileio_info->param_1, target->fileio_info->param_2, target->fileio_info->param_3); else if (strcmp(target->fileio_info->identifier, "lseek") == 0) - sprintf(fileio_command, "F%s,%x,%x,%x", target->fileio_info->identifier, + sprintf(fileio_command, "F%s,%" PRIx32 ",%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, target->fileio_info->param_1, target->fileio_info->param_2, target->fileio_info->param_3); else if (strcmp(target->fileio_info->identifier, "rename") == 0) - sprintf(fileio_command, "F%s,%x/%x,%x/%x", target->fileio_info->identifier, + sprintf(fileio_command, "F%s,%" PRIx32 "/%" PRIx32 ",%" PRIx32 "/%" PRIx32, target->fileio_info->identifier, target->fileio_info->param_1, target->fileio_info->param_2, target->fileio_info->param_3, target->fileio_info->param_4); else if (strcmp(target->fileio_info->identifier, "unlink") == 0) - sprintf(fileio_command, "F%s,%x/%x", target->fileio_info->identifier, + sprintf(fileio_command, "F%s,%" PRIx32 "/%" PRIx32, target->fileio_info->identifier, target->fileio_info->param_1, target->fileio_info->param_2); else if (strcmp(target->fileio_info->identifier, "stat") == 0) - sprintf(fileio_command, "F%s,%x/%x,%x", target->fileio_info->identifier, + sprintf(fileio_command, "F%s,%" PRIx32 "/%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, target->fileio_info->param_1, target->fileio_info->param_2, target->fileio_info->param_3); else if (strcmp(target->fileio_info->identifier, "fstat") == 0) - sprintf(fileio_command, "F%s,%x,%x", target->fileio_info->identifier, + sprintf(fileio_command, "F%s,%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, target->fileio_info->param_1, target->fileio_info->param_2); else if (strcmp(target->fileio_info->identifier, "gettimeofday") == 0) - sprintf(fileio_command, "F%s,%x,%x", target->fileio_info->identifier, + sprintf(fileio_command, "F%s,%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, target->fileio_info->param_1, target->fileio_info->param_2); else if (strcmp(target->fileio_info->identifier, "isatty") == 0) - sprintf(fileio_command, "F%s,%x", target->fileio_info->identifier, + sprintf(fileio_command, "F%s,%" PRIx32, target->fileio_info->identifier, target->fileio_info->param_1); else if (strcmp(target->fileio_info->identifier, "system") == 0) - sprintf(fileio_command, "F%s,%x/%x", target->fileio_info->identifier, + sprintf(fileio_command, "F%s,%" PRIx32 "/%" PRIx32, target->fileio_info->identifier, target->fileio_info->param_1, target->fileio_info->param_2); else if (strcmp(target->fileio_info->identifier, "exit") == 0) { /* If target hits exit syscall, report to GDB the program is terminated. * In addition, let target run its own exit syscall handler. */ program_exited = true; - sprintf(fileio_command, "W%02x", target->fileio_info->param_1); + sprintf(fileio_command, "W%02" PRIx32, target->fileio_info->param_1); } else { LOG_DEBUG("Unknown syscall: %s", target->fileio_info->identifier); @@ -957,6 +967,9 @@ static int gdb_new_connection(struct connection *connection) int i; for (i = 0; i < flash_get_bank_count(); i++) { struct flash_bank *p; + p = get_flash_bank_by_num_noprobe(i); + if (p->target != gdb_service->target) + continue; retval = get_flash_bank_by_num(i, &p); if (retval != ERROR_OK) { LOG_ERROR("Connect failed. Consider setting up a gdb-attach event for the target " \ @@ -1349,6 +1362,12 @@ static int gdb_read_memory_packet(struct connection *connection, len = strtoul(separator + 1, NULL, 16); + if (!len) { + LOG_WARNING("invalid read memory packet received (len == 0)"); + gdb_put_packet(connection, NULL, 0); + return ERROR_OK; + } + buffer = malloc(len); LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len); @@ -1503,10 +1522,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]; @@ -1732,14 +1750,16 @@ static int gdb_memory_map(struct connection *connection, banks = malloc(sizeof(struct flash_bank *)*flash_get_bank_count()); for (i = 0; i < flash_get_bank_count(); i++) { + p = get_flash_bank_by_num_noprobe(i); + if (p->target != target) + continue; retval = get_flash_bank_by_num(i, &p); if (retval != ERROR_OK) { free(banks); gdb_error(connection, retval); return retval; } - if (p->target == target) - banks[target_flash_banks++] = p; + banks[target_flash_banks++] = p; } qsort(banks, target_flash_banks, sizeof(struct flash_bank *), @@ -1988,7 +2008,8 @@ static int get_reg_features_list(struct target *target, char **feature_list[], i if (reg_list[i]->exist == false) continue; - if ((reg_list[i]->feature->name != NULL) + if (reg_list[i]->feature != NULL + && reg_list[i]->feature->name != NULL && (strcmp(reg_list[i]->feature->name, ""))) { /* We found a feature, check if the feature is already in the * table. If not, allocate a new entry for the table and @@ -2193,6 +2214,7 @@ static int gdb_target_description_supported(struct target *target, int *supporte struct reg **reg_list = NULL; int reg_list_size = 0; int feature_list_size = 0; + char **features = NULL; retval = target_get_gdb_reg_list(target, ®_list, ®_list_size, REG_CLASS_ALL); @@ -2206,7 +2228,6 @@ static int gdb_target_description_supported(struct target *target, int *supporte goto error; } - char **features = NULL; /* Get a list of available target registers features */ retval = get_reg_features_list(target, &features, &feature_list_size, reg_list, reg_list_size); if (retval != ERROR_OK) { @@ -2900,7 +2921,7 @@ static int gdb_target_add_one(struct target *target) portnumber = strtol(gdb_port_next, &end, 0); if (!*end) { if (parse_long(gdb_port_next, &portnumber) == ERROR_OK) { - free((void *)gdb_port_next); + free(gdb_port_next); gdb_port_next = alloc_printf("%d", portnumber+1); } } @@ -2947,7 +2968,7 @@ COMMAND_HANDLER(handle_gdb_port_command) { int retval = CALL_COMMAND_HANDLER(server_pipe_command, &gdb_port); if (ERROR_OK == retval) { - free((void *)gdb_port_next); + free(gdb_port_next); gdb_port_next = strdup(gdb_port); } return retval;