X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fserver%2Fgdb_server.c;h=ab3e6bef8d885079aa7c86543d3d7645595f2702;hp=f0b552ddedd1ce042861f1760cc6ddeabcbd16b9;hb=0cba5b4ea30a436e1ab381b374ea89743a23e09c;hpb=421e75722db1fa173747d07618ef4016b2e3c80e diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index f0b552dded..ab3e6bef8d 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -67,7 +67,7 @@ struct target_desc_format { /* private connection data for GDB */ struct gdb_connection { - char buffer[GDB_BUFFER_SIZE]; + char buffer[GDB_BUFFER_SIZE + 1]; /* Extra byte for nul-termination */ char *buf_p; int buf_cnt; int ctrl_c; @@ -153,6 +153,8 @@ static int gdb_last_signal(struct target *target) return 0x05; /* SIGTRAP */ case DBG_REASON_SINGLESTEP: return 0x05; /* SIGTRAP */ + case DBG_REASON_EXC_CATCH: + return 0x05; case DBG_REASON_NOTHALTED: return 0x0; /* no signal... shouldn't happen */ default: @@ -901,7 +903,6 @@ static void gdb_frontend_halted(struct target *target, struct connection *connec static int gdb_target_callback_event_handler(struct target *target, enum target_event event, void *priv) { - int retval; struct connection *connection = priv; struct gdb_service *gdb_service = connection->service->priv; @@ -915,11 +916,6 @@ static int gdb_target_callback_event_handler(struct target *target, case TARGET_EVENT_HALTED: target_call_event_callbacks(target, TARGET_EVENT_GDB_END); break; - case TARGET_EVENT_GDB_FLASH_ERASE_START: - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - break; default: break; } @@ -936,6 +932,7 @@ static int gdb_new_connection(struct connection *connection) target = get_target_from_connection(connection); connection->priv = gdb_connection; + connection->cmd_ctx->current_target = target; /* initialize gdb connection information */ gdb_connection->buf_p = gdb_connection->buffer; @@ -1178,8 +1175,11 @@ static int gdb_get_registers_packet(struct connection *connection, if (retval != ERROR_OK) return gdb_error(connection, retval); - for (i = 0; i < reg_list_size; i++) + for (i = 0; i < reg_list_size; i++) { + if (reg_list[i] == NULL || reg_list[i]->exist == false) + continue; reg_packet_size += DIV_ROUND_UP(reg_list[i]->size, 8) * 2; + } assert(reg_packet_size > 0); @@ -1190,6 +1190,8 @@ static int gdb_get_registers_packet(struct connection *connection, reg_packet_p = reg_packet; for (i = 0; i < reg_list_size; i++) { + if (reg_list[i] == NULL || reg_list[i]->exist == false) + continue; if (!reg_list[i]->valid) { retval = reg_list[i]->type->get(reg_list[i]); if (retval != ERROR_OK && gdb_report_register_access_error) { @@ -1295,6 +1297,9 @@ static int gdb_get_register_packet(struct connection *connection, LOG_DEBUG("-"); #endif + if ((target->rtos != NULL) && (ERROR_OK == rtos_get_gdb_reg(connection, reg_num))) + return ERROR_OK; + retval = target_get_gdb_reg_list(target, ®_list, ®_list_size, REG_CLASS_ALL); if (retval != ERROR_OK) @@ -1359,7 +1364,8 @@ static int gdb_set_register_packet(struct connection *connection, int chars = (DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2); if ((unsigned int)chars != strlen(separator + 1)) { - LOG_ERROR("gdb sent a packet with wrong register size"); + LOG_ERROR("gdb sent %zu bits for a %d-bit register (%s)", + strlen(separator + 1) * 4, chars * 4, reg_list[reg_num]->name); free(bin_buf); return ERROR_SERVER_REMOTE_CLOSED; } @@ -1395,8 +1401,6 @@ static int gdb_error(struct connection *connection, int retval) /* We don't have to worry about the default 2 second timeout for GDB packets, * because GDB breaks up large memory reads into smaller reads. - * - * 8191 bytes by the looks of it. Why 8191 bytes instead of 8192????? */ static int gdb_read_memory_packet(struct connection *connection, char const *packet, int packet_size) @@ -1425,7 +1429,7 @@ static int gdb_read_memory_packet(struct connection *connection, if (!len) { LOG_WARNING("invalid read memory packet received (len == 0)"); - gdb_put_packet(connection, NULL, 0); + gdb_put_packet(connection, "", 0); return ERROR_OK; } @@ -1909,11 +1913,10 @@ static int gdb_memory_map(struct connection *connection, if (ram_start != 0) xml_printf(&retval, &xml, &pos, &size, "\n", - ram_start, 0-ram_start); - /* ELSE a flash chip could be at the very end of the 32 bit address - * space, in which case ram_start will be precisely 0 - */ + "length=\"" TARGET_ADDR_FMT "\"/>\n", + ram_start, target_address_max(target) - ram_start + 1); + /* ELSE a flash chip could be at the very end of the address space, in + * which case ram_start will be precisely 0 */ free(banks); @@ -2186,6 +2189,7 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o int retval = ERROR_OK; struct reg **reg_list = NULL; int reg_list_size; + char const *architecture; char const **features = NULL; char const **arch_defined_types = NULL; int feature_list_size = 0; @@ -2227,6 +2231,12 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o "\n" "\n"); + /* generate architecture element if supported by target */ + architecture = target_get_gdb_arch(target); + if (architecture != NULL) + xml_printf(&retval, &tdesc, &pos, &size, + "%s\n", architecture); + /* generate target description according to register list */ if (features != NULL) { while (features[current_feature]) { @@ -2376,6 +2386,8 @@ static int gdb_target_description_supported(struct target *target, int *supporte char const **features = NULL; int feature_list_size = 0; + char const *architecture = target_get_gdb_arch(target); + retval = target_get_gdb_reg_list(target, ®_list, ®_list_size, REG_CLASS_ALL); if (retval != ERROR_OK) { @@ -2397,7 +2409,7 @@ static int gdb_target_description_supported(struct target *target, int *supporte } if (supported) { - if (feature_list_size) + if (architecture || feature_list_size) *supported = 1; else *supported = 0; @@ -2594,7 +2606,7 @@ static int gdb_query_packet(struct connection *connection, &pos, &size, "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;qXfer:threads:read+;QStartNoAckMode+;vContSupported+", - (GDB_BUFFER_SIZE - 1), + GDB_BUFFER_SIZE, ((gdb_use_memory_map == 1) && (flash_get_bank_count() > 0)) ? '+' : '-', (gdb_target_desc_supported == 1) ? '+' : '-'); @@ -2829,7 +2841,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p if (gdb_connection->sync) { gdb_connection->sync = false; if (ct->state == TARGET_HALTED) { - LOG_WARNING("stepi ignored. GDB will now fetch the register state " \ + LOG_DEBUG("stepi ignored. GDB will now fetch the register state " \ "from the target."); gdb_sig_halted(connection); log_remove_callback(gdb_log_callback, connection); @@ -3097,7 +3109,7 @@ static void gdb_sig_halted(struct connection *connection) static int gdb_input_inner(struct connection *connection) { /* Do not allocate this on the stack */ - static char gdb_packet_buffer[GDB_BUFFER_SIZE]; + static char gdb_packet_buffer[GDB_BUFFER_SIZE + 1]; /* Extra byte for nul-termination */ struct target *target; char const *packet = gdb_packet_buffer; @@ -3120,7 +3132,7 @@ static int gdb_input_inner(struct connection *connection) * drain the rest of the buffer. */ do { - packet_size = GDB_BUFFER_SIZE-1; + packet_size = GDB_BUFFER_SIZE; retval = gdb_get_packet(connection, gdb_packet_buffer, &packet_size); if (retval != ERROR_OK) return retval; @@ -3213,7 +3225,7 @@ static int gdb_input_inner(struct connection *connection) * make only the single stepping have the sync feature... */ nostep = true; - LOG_WARNING("stepi ignored. GDB will now fetch the register state " \ + LOG_DEBUG("stepi ignored. GDB will now fetch the register state " \ "from the target."); } gdb_con->sync = false; @@ -3316,7 +3328,7 @@ static int gdb_input_inner(struct connection *connection) default: /* ignore unknown packets */ LOG_DEBUG("ignoring 0x%2.2x packet", packet[0]); - gdb_put_packet(connection, NULL, 0); + gdb_put_packet(connection, "", 0); break; } @@ -3371,6 +3383,8 @@ static int gdb_target_start(struct target *target, const char *port) if (NULL == gdb_service) return -ENOMEM; + LOG_DEBUG("starting gdb server for %s on %s", target_name(target), port); + gdb_service->target = target; gdb_service->core[0] = -1; gdb_service->core[1] = -1; @@ -3396,16 +3410,36 @@ static int gdb_target_start(struct target *target, const char *port) static int gdb_target_add_one(struct target *target) { + /* one gdb instance per smp list */ + if ((target->smp) && (target->gdb_service)) + return ERROR_OK; + + /* skip targets that cannot handle a gdb connections (e.g. mem_ap) */ + if (!target_supports_gdb_connection(target)) { + LOG_DEBUG("skip gdb server for target %s", target_name(target)); + return ERROR_OK; + } + + if (target->gdb_port_override) { + if (strcmp(target->gdb_port_override, "disabled") == 0) { + LOG_INFO("gdb port disabled"); + return ERROR_OK; + } + return gdb_target_start(target, target->gdb_port_override); + } + if (strcmp(gdb_port, "disabled") == 0) { LOG_INFO("gdb port disabled"); return ERROR_OK; } - /* one gdb instance per smp list */ - if ((target->smp) && (target->gdb_service)) - return ERROR_OK; int retval = gdb_target_start(target, gdb_port_next); if (retval == ERROR_OK) { + /* save the port number so can be queried with + * $target_name cget -gdb-port + */ + target->gdb_port_override = strdup(gdb_port_next); + long portnumber; /* If we can parse the port number * then we increment the port number for the next target. @@ -3430,11 +3464,6 @@ static int gdb_target_add_one(struct target *target) int gdb_target_add_all(struct target *target) { - if (strcmp(gdb_port, "disabled") == 0) { - LOG_INFO("gdb server disabled"); - return ERROR_OK; - } - if (NULL == target) { LOG_WARNING("gdb services need one or more targets defined"); return ERROR_OK; @@ -3457,7 +3486,7 @@ COMMAND_HANDLER(handle_gdb_sync_command) return ERROR_COMMAND_SYNTAX_ERROR; if (current_gdb_connection == NULL) { - command_print(CMD_CTX, + command_print(CMD, "gdb_sync command can only be run from within gdb using \"monitor gdb_sync\""); return ERROR_FAIL; } @@ -3662,6 +3691,7 @@ static const struct command_registration gdb_command_handlers[] = { .handler = handle_gdb_save_tdesc_command, .mode = COMMAND_EXEC, .help = "Save the target description file", + .usage = "", }, COMMAND_REGISTRATION_DONE };