|
|
|
|
@@ -177,7 +177,7 @@ static int check_pending(struct connection *connection,
|
|
|
|
|
fd_set read_fds;
|
|
|
|
|
struct gdb_connection *gdb_con = connection->priv;
|
|
|
|
|
int t;
|
|
|
|
|
if (got_data == NULL)
|
|
|
|
|
if (!got_data)
|
|
|
|
|
got_data = &t;
|
|
|
|
|
*got_data = 0;
|
|
|
|
|
|
|
|
|
|
@@ -369,7 +369,7 @@ static void gdb_log_incoming_packet(char *packet)
|
|
|
|
|
/* Does packet at least have a prefix that is printable?
|
|
|
|
|
* Look within the first 50 chars of the packet. */
|
|
|
|
|
const char *colon = memchr(packet, ':', MIN(50, packet_len));
|
|
|
|
|
const bool packet_has_prefix = (colon != NULL);
|
|
|
|
|
const bool packet_has_prefix = (colon);
|
|
|
|
|
const bool packet_prefix_printable = (packet_has_prefix && nonprint > colon);
|
|
|
|
|
|
|
|
|
|
if (packet_prefix_printable) {
|
|
|
|
|
@@ -737,7 +737,7 @@ static int gdb_output_con(struct connection *connection, const char *line)
|
|
|
|
|
bin_size = strlen(line);
|
|
|
|
|
|
|
|
|
|
hex_buffer = malloc(bin_size * 2 + 2);
|
|
|
|
|
if (hex_buffer == NULL)
|
|
|
|
|
if (!hex_buffer)
|
|
|
|
|
return ERROR_GDB_BUFFER_TOO_SMALL;
|
|
|
|
|
|
|
|
|
|
hex_buffer[0] = 'O';
|
|
|
|
|
@@ -771,7 +771,7 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio
|
|
|
|
|
sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "W00");
|
|
|
|
|
} else {
|
|
|
|
|
struct target *ct;
|
|
|
|
|
if (target->rtos != NULL) {
|
|
|
|
|
if (target->rtos) {
|
|
|
|
|
target->rtos->current_threadid = target->rtos->current_thread;
|
|
|
|
|
target->rtos->gdb_target_for_threadid(connection, target->rtos->current_threadid, &ct);
|
|
|
|
|
} else {
|
|
|
|
|
@@ -810,7 +810,7 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_thread[0] = '\0';
|
|
|
|
|
if (target->rtos != NULL)
|
|
|
|
|
if (target->rtos)
|
|
|
|
|
snprintf(current_thread, sizeof(current_thread), "thread:%" PRIx64 ";",
|
|
|
|
|
target->rtos->current_thread);
|
|
|
|
|
|
|
|
|
|
@@ -1212,7 +1212,7 @@ static int gdb_get_registers_packet(struct connection *connection,
|
|
|
|
|
LOG_DEBUG("-");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if ((target->rtos != NULL) && (ERROR_OK == rtos_get_gdb_reg_list(connection)))
|
|
|
|
|
if ((target->rtos) && (ERROR_OK == rtos_get_gdb_reg_list(connection)))
|
|
|
|
|
return ERROR_OK;
|
|
|
|
|
|
|
|
|
|
retval = target_get_gdb_reg_list(target, ®_list, ®_list_size,
|
|
|
|
|
@@ -1229,7 +1229,7 @@ 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)
|
|
|
|
|
if (!reg_packet)
|
|
|
|
|
return ERROR_FAIL;
|
|
|
|
|
|
|
|
|
|
reg_packet_p = reg_packet;
|
|
|
|
|
@@ -1342,7 +1342,7 @@ 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)))
|
|
|
|
|
if ((target->rtos) && (ERROR_OK == rtos_get_gdb_reg(connection, reg_num)))
|
|
|
|
|
return ERROR_OK;
|
|
|
|
|
|
|
|
|
|
retval = target_get_gdb_reg_list_noread(target, ®_list, ®_list_size,
|
|
|
|
|
@@ -1398,7 +1398,7 @@ static int gdb_set_register_packet(struct connection *connection,
|
|
|
|
|
uint8_t *bin_buf = malloc(chars / 2);
|
|
|
|
|
gdb_target_to_reg(target, separator + 1, chars, bin_buf);
|
|
|
|
|
|
|
|
|
|
if ((target->rtos != NULL) &&
|
|
|
|
|
if ((target->rtos) &&
|
|
|
|
|
(ERROR_OK == rtos_set_reg(connection, reg_num, bin_buf))) {
|
|
|
|
|
free(bin_buf);
|
|
|
|
|
gdb_put_packet(connection, "OK", 2);
|
|
|
|
|
@@ -1824,7 +1824,7 @@ static int decode_xfer_read(char const *buf, char **annex, int *ofs, unsigned in
|
|
|
|
|
{
|
|
|
|
|
/* Locate the annex. */
|
|
|
|
|
const char *annex_end = strchr(buf, ':');
|
|
|
|
|
if (annex_end == NULL)
|
|
|
|
|
if (!annex_end)
|
|
|
|
|
return ERROR_FAIL;
|
|
|
|
|
|
|
|
|
|
/* After the read marker and annex, qXfer looks like a
|
|
|
|
|
@@ -1838,7 +1838,7 @@ static int decode_xfer_read(char const *buf, char **annex, int *ofs, unsigned in
|
|
|
|
|
*len = strtoul(separator + 1, NULL, 16);
|
|
|
|
|
|
|
|
|
|
/* Extract the annex if needed */
|
|
|
|
|
if (annex != NULL) {
|
|
|
|
|
if (annex) {
|
|
|
|
|
*annex = strndup(buf, annex_end - buf);
|
|
|
|
|
if (*annex == NULL)
|
|
|
|
|
return ERROR_FAIL;
|
|
|
|
|
@@ -2102,7 +2102,7 @@ static int gdb_generate_reg_type_description(struct target *target,
|
|
|
|
|
} else if (type->type_class == REG_TYPE_CLASS_UNION) {
|
|
|
|
|
struct reg_data_type_union_field *field;
|
|
|
|
|
field = type->reg_type_union->fields;
|
|
|
|
|
while (field != NULL) {
|
|
|
|
|
while (field) {
|
|
|
|
|
struct reg_data_type *data_type = field->type;
|
|
|
|
|
if (data_type->type == REG_TYPE_ARCH_DEFINED) {
|
|
|
|
|
if (lookup_add_arch_defined_types(arch_defined_types_list, data_type->id,
|
|
|
|
|
@@ -2122,7 +2122,7 @@ static int gdb_generate_reg_type_description(struct target *target,
|
|
|
|
|
type->id);
|
|
|
|
|
|
|
|
|
|
field = type->reg_type_union->fields;
|
|
|
|
|
while (field != NULL) {
|
|
|
|
|
while (field) {
|
|
|
|
|
xml_printf(&retval, tdesc, pos, size,
|
|
|
|
|
"<field name=\"%s\" type=\"%s\"/>\n",
|
|
|
|
|
field->name, field->type->id);
|
|
|
|
|
@@ -2144,7 +2144,7 @@ static int gdb_generate_reg_type_description(struct target *target,
|
|
|
|
|
xml_printf(&retval, tdesc, pos, size,
|
|
|
|
|
"<struct id=\"%s\" size=\"%" PRIu32 "\">\n",
|
|
|
|
|
type->id, type->reg_type_struct->size);
|
|
|
|
|
while (field != NULL) {
|
|
|
|
|
while (field) {
|
|
|
|
|
xml_printf(&retval, tdesc, pos, size,
|
|
|
|
|
"<field name=\"%s\" start=\"%" PRIu32 "\" end=\"%" PRIu32 "\" type=\"%s\" />\n",
|
|
|
|
|
field->name, field->bitfield->start, field->bitfield->end,
|
|
|
|
|
@@ -2153,7 +2153,7 @@ static int gdb_generate_reg_type_description(struct target *target,
|
|
|
|
|
field = field->next;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
while (field != NULL) {
|
|
|
|
|
while (field) {
|
|
|
|
|
struct reg_data_type *data_type = field->type;
|
|
|
|
|
if (data_type->type == REG_TYPE_ARCH_DEFINED) {
|
|
|
|
|
if (lookup_add_arch_defined_types(arch_defined_types_list, data_type->id,
|
|
|
|
|
@@ -2170,7 +2170,7 @@ static int gdb_generate_reg_type_description(struct target *target,
|
|
|
|
|
xml_printf(&retval, tdesc, pos, size,
|
|
|
|
|
"<struct id=\"%s\">\n",
|
|
|
|
|
type->id);
|
|
|
|
|
while (field != NULL) {
|
|
|
|
|
while (field) {
|
|
|
|
|
xml_printf(&retval, tdesc, pos, size,
|
|
|
|
|
"<field name=\"%s\" type=\"%s\"/>\n",
|
|
|
|
|
field->name, field->type->id);
|
|
|
|
|
@@ -2192,7 +2192,7 @@ static int gdb_generate_reg_type_description(struct target *target,
|
|
|
|
|
|
|
|
|
|
struct reg_data_type_flags_field *field;
|
|
|
|
|
field = type->reg_type_flags->fields;
|
|
|
|
|
while (field != NULL) {
|
|
|
|
|
while (field) {
|
|
|
|
|
xml_printf(&retval, tdesc, pos, size,
|
|
|
|
|
"<field name=\"%s\" start=\"%" PRIu32 "\" end=\"%" PRIu32 "\" type=\"%s\" />\n",
|
|
|
|
|
field->name, field->bitfield->start, field->bitfield->end,
|
|
|
|
|
@@ -2297,12 +2297,12 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o
|
|
|
|
|
|
|
|
|
|
/* generate architecture element if supported by target */
|
|
|
|
|
architecture = target_get_gdb_arch(target);
|
|
|
|
|
if (architecture != NULL)
|
|
|
|
|
if (architecture)
|
|
|
|
|
xml_printf(&retval, &tdesc, &pos, &size,
|
|
|
|
|
"<architecture>%s</architecture>\n", architecture);
|
|
|
|
|
|
|
|
|
|
/* generate target description according to register list */
|
|
|
|
|
if (features != NULL) {
|
|
|
|
|
if (features) {
|
|
|
|
|
while (features[current_feature]) {
|
|
|
|
|
char const **arch_defined_types = NULL;
|
|
|
|
|
int num_arch_defined_types = 0;
|
|
|
|
|
@@ -2394,7 +2394,7 @@ error:
|
|
|
|
|
static int gdb_get_target_description_chunk(struct target *target, struct target_desc_format *target_desc,
|
|
|
|
|
char **chunk, int32_t offset, uint32_t length)
|
|
|
|
|
{
|
|
|
|
|
if (target_desc == NULL) {
|
|
|
|
|
if (!target_desc) {
|
|
|
|
|
LOG_ERROR("Unable to Generate Target Description");
|
|
|
|
|
return ERROR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
@@ -2402,7 +2402,7 @@ static int gdb_get_target_description_chunk(struct target *target, struct target
|
|
|
|
|
char *tdesc = target_desc->tdesc;
|
|
|
|
|
uint32_t tdesc_length = target_desc->tdesc_length;
|
|
|
|
|
|
|
|
|
|
if (tdesc == NULL) {
|
|
|
|
|
if (!tdesc) {
|
|
|
|
|
int retval = gdb_generate_target_description(target, &tdesc);
|
|
|
|
|
if (retval != ERROR_OK) {
|
|
|
|
|
LOG_ERROR("Unable to Generate Target Description");
|
|
|
|
|
@@ -2502,7 +2502,7 @@ static int gdb_generate_thread_list(struct target *target, char **thread_list_ou
|
|
|
|
|
"<?xml version=\"1.0\"?>\n"
|
|
|
|
|
"<threads>\n");
|
|
|
|
|
|
|
|
|
|
if (rtos != NULL) {
|
|
|
|
|
if (rtos) {
|
|
|
|
|
for (int i = 0; i < rtos->thread_count; i++) {
|
|
|
|
|
struct thread_detail *thread_detail = &rtos->thread_details[i];
|
|
|
|
|
|
|
|
|
|
@@ -2512,12 +2512,12 @@ static int gdb_generate_thread_list(struct target *target, char **thread_list_ou
|
|
|
|
|
xml_printf(&retval, &thread_list, &pos, &size,
|
|
|
|
|
"<thread id=\"%" PRIx64 "\">", thread_detail->threadid);
|
|
|
|
|
|
|
|
|
|
if (thread_detail->thread_name_str != NULL)
|
|
|
|
|
if (thread_detail->thread_name_str)
|
|
|
|
|
xml_printf(&retval, &thread_list, &pos, &size,
|
|
|
|
|
"Name: %s", thread_detail->thread_name_str);
|
|
|
|
|
|
|
|
|
|
if (thread_detail->extra_info_str != NULL) {
|
|
|
|
|
if (thread_detail->thread_name_str != NULL)
|
|
|
|
|
if (thread_detail->extra_info_str) {
|
|
|
|
|
if (thread_detail->thread_name_str)
|
|
|
|
|
xml_printf(&retval, &thread_list, &pos, &size,
|
|
|
|
|
", ");
|
|
|
|
|
xml_printf(&retval, &thread_list, &pos, &size,
|
|
|
|
|
@@ -2825,12 +2825,12 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p
|
|
|
|
|
packet_size -= 2;
|
|
|
|
|
|
|
|
|
|
thread_id = strtoll(parse, &endp, 16);
|
|
|
|
|
if (endp != NULL) {
|
|
|
|
|
if (endp) {
|
|
|
|
|
packet_size -= endp - parse;
|
|
|
|
|
parse = endp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (target->rtos != NULL) {
|
|
|
|
|
if (target->rtos) {
|
|
|
|
|
/* FIXME: why is this necessary? rtos state should be up-to-date here already! */
|
|
|
|
|
rtos_update_threads(target);
|
|
|
|
|
|
|
|
|
|
@@ -2948,7 +2948,7 @@ static char *next_hex_encoded_field(const char **str, char sep)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
const char *end = strchr(hex, sep);
|
|
|
|
|
if (end == NULL)
|
|
|
|
|
if (!end)
|
|
|
|
|
hexlen = strlen(hex);
|
|
|
|
|
else
|
|
|
|
|
hexlen = end - hex;
|
|
|
|
|
@@ -2961,7 +2961,7 @@ static char *next_hex_encoded_field(const char **str, char sep)
|
|
|
|
|
|
|
|
|
|
size_t count = hexlen / 2;
|
|
|
|
|
char *decoded = malloc(count + 1);
|
|
|
|
|
if (decoded == NULL)
|
|
|
|
|
if (!decoded)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
size_t converted = unhexify((void *)decoded, hex, count);
|
|
|
|
|
@@ -3014,8 +3014,8 @@ static bool gdb_handle_vrun_packet(struct connection *connection, const char *pa
|
|
|
|
|
cmdline = new_cmdline;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cmdline != NULL) {
|
|
|
|
|
if (target->semihosting != NULL) {
|
|
|
|
|
if (cmdline) {
|
|
|
|
|
if (target->semihosting) {
|
|
|
|
|
LOG_INFO("GDB set inferior command line to '%s'", cmdline);
|
|
|
|
|
free(target->semihosting->cmdline);
|
|
|
|
|
target->semihosting->cmdline = cmdline;
|
|
|
|
|
@@ -3142,7 +3142,7 @@ static int gdb_v_packet(struct connection *connection,
|
|
|
|
|
length = packet_size - (parse - packet);
|
|
|
|
|
|
|
|
|
|
/* create a new image if there isn't already one */
|
|
|
|
|
if (gdb_connection->vflash_image == NULL) {
|
|
|
|
|
if (!gdb_connection->vflash_image) {
|
|
|
|
|
gdb_connection->vflash_image = malloc(sizeof(struct image));
|
|
|
|
|
image_open(gdb_connection->vflash_image, "", "build");
|
|
|
|
|
}
|
|
|
|
|
@@ -3531,7 +3531,7 @@ static int gdb_target_start(struct target *target, const char *port)
|
|
|
|
|
int ret;
|
|
|
|
|
gdb_service = malloc(sizeof(struct gdb_service));
|
|
|
|
|
|
|
|
|
|
if (NULL == gdb_service)
|
|
|
|
|
if (!gdb_service)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
LOG_INFO("starting gdb server for %s on %s", target_name(target), port);
|
|
|
|
|
@@ -3615,12 +3615,12 @@ static int gdb_target_add_one(struct target *target)
|
|
|
|
|
|
|
|
|
|
int gdb_target_add_all(struct target *target)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == target) {
|
|
|
|
|
if (!target) {
|
|
|
|
|
LOG_WARNING("gdb services need one or more targets defined");
|
|
|
|
|
return ERROR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (NULL != target) {
|
|
|
|
|
while (target) {
|
|
|
|
|
int retval = gdb_target_add_one(target);
|
|
|
|
|
if (retval != ERROR_OK)
|
|
|
|
|
return retval;
|
|
|
|
|
@@ -3636,7 +3636,7 @@ COMMAND_HANDLER(handle_gdb_sync_command)
|
|
|
|
|
if (CMD_ARGC != 0)
|
|
|
|
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
|
|
|
|
|
|
|
|
|
if (current_gdb_connection == NULL) {
|
|
|
|
|
if (!current_gdb_connection) {
|
|
|
|
|
command_print(CMD,
|
|
|
|
|
"gdb_sync command can only be run from within gdb using \"monitor gdb_sync\"");
|
|
|
|
|
return ERROR_FAIL;
|
|
|
|
|
@@ -3745,7 +3745,7 @@ COMMAND_HANDLER(handle_gdb_save_tdesc_command)
|
|
|
|
|
size_t size_written;
|
|
|
|
|
|
|
|
|
|
char *tdesc_filename = alloc_printf("%s.xml", target_type_name(target));
|
|
|
|
|
if (tdesc_filename == NULL) {
|
|
|
|
|
if (!tdesc_filename) {
|
|
|
|
|
retval = ERROR_FAIL;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|