This is an automated email from Gerrit. Franck Jullien ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/1051
-- gerrit commit 27308a2c9bd536f6d72b1e8d2537ff3e8c2e43a5 Author: Franck Jullien <[email protected]> Date: Thu Dec 13 12:51:45 2012 +0100 gdb_server: Add gdb_tdesc_path cmd and qXfer:features:read support v2 This patch is an enhanced version of Mathias Kuster's patch. (http://openocd.zylin.com/#/c/518/). This patch adds the command gdb_tdesc_path to set the path to gdb XML target description file(s). Also the gdb qXfer:features:read support is enabled if a path is set. This version adds support for larger tdesc files. It supports 'm' answers to qXfer to send chunks of data. Change-Id: Ia13414f8d35a3d5e5fe17e04f52d2e19c13d8fb7 Signed-off-by: Franck Jullien <[email protected]> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index ee7683a..a72e2ba 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -85,6 +85,8 @@ struct gdb_connection { #define _DEBUG_GDB_IO_ #endif +static int remaining_xfer = -1; + static struct gdb_connection *current_gdb_connection; static int gdb_breakpoint_override; @@ -93,6 +95,7 @@ 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 const char *gdb_tdesc_path; static const char DIGITS[16] = "0123456789abcdef"; static void gdb_log_callback(void *priv, const char *file, unsigned line, @@ -1777,9 +1780,10 @@ static int gdb_query_packet(struct connection *connection, &buffer, &pos, &size, - "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-;QStartNoAckMode+", + "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;QStartNoAckMode+", (GDB_BUFFER_SIZE - 1), - ((gdb_use_memory_map == 1) && (flash_get_bank_count() > 0)) ? '+' : '-'); + ((gdb_use_memory_map == 1) && (flash_get_bank_count() > 0)) ? '+' : '-', + (gdb_tdesc_path) ? '+' : '-'); if (retval != ERROR_OK) { gdb_send_error(connection, 01); @@ -1794,14 +1798,14 @@ static int gdb_query_packet(struct connection *connection, && (flash_get_bank_count() > 0)) return gdb_memory_map(connection, packet, packet_size); else if (strncmp(packet, "qXfer:features:read:", 20) == 0) { - char *xml = NULL; - int size = 0; - int pos = 0; int retval = ERROR_OK; - + char *filebuffer = NULL; int offset; unsigned int length; char *annex; + struct fileio fileio; + size_t read_bytes; + int filesize; /* skip command character */ packet += 20; @@ -1816,20 +1820,82 @@ static int gdb_query_packet(struct connection *connection, return ERROR_OK; } - xml_printf(&retval, - &xml, - &pos, - &size, \ - "l < target version=\"1.0\">\n < architecture > arm</architecture>\n</target>\n"); + /* Read the xml file */ + retval = fileio_open(&fileio, gdb_tdesc_path, FILEIO_READ, FILEIO_BINARY); if (retval != ERROR_OK) { - gdb_error(connection, retval); - return retval; + fileio_close(&fileio); + gdb_send_error(connection, 01); + return ERROR_OK; } - gdb_put_packet(connection, xml, strlen(xml)); + fileio_size(&fileio, &filesize); + + if (remaining_xfer == -1) + remaining_xfer = DIV_ROUND_UP(filesize, QXFER_CHUNK_SIZE); + + filebuffer = malloc(QXFER_CHUNK_SIZE + 1); + memset(filebuffer, 0, QXFER_CHUNK_SIZE + 1); + + if (remaining_xfer > 1) { + + filebuffer[0] = 'm'; + + retval = fileio_seek(&fileio, (DIV_ROUND_UP(filesize, QXFER_CHUNK_SIZE) + - remaining_xfer) * QXFER_CHUNK_SIZE); + + if (retval != ERROR_OK) { + fileio_close(&fileio); + free(filebuffer); + gdb_send_error(connection, 01); + return ERROR_OK; + } + + retval = fileio_read(&fileio, QXFER_CHUNK_SIZE, &filebuffer[1], &read_bytes); + + if (retval != ERROR_OK) { + free(filebuffer); + fileio_close(&fileio); + gdb_send_error(connection, 01); + return ERROR_OK; + } + + gdb_put_packet(connection, filebuffer, QXFER_CHUNK_SIZE + 1); + remaining_xfer--; + + } else { + + filebuffer = malloc(QXFER_CHUNK_SIZE + 1); + memset(filebuffer, 0, QXFER_CHUNK_SIZE + 1); + + filebuffer[0] = 'l'; + + retval = fileio_seek(&fileio, filesize - (filesize % QXFER_CHUNK_SIZE)); + + if (retval != ERROR_OK) { + fileio_close(&fileio); + free(filebuffer); + gdb_send_error(connection, 01); + return ERROR_OK; + } + + retval = fileio_read(&fileio, filesize % QXFER_CHUNK_SIZE, + &filebuffer[1], &read_bytes); + + if (retval != ERROR_OK) { + fileio_close(&fileio); + free(filebuffer); + gdb_send_error(connection, 01); + return ERROR_OK; + } + + gdb_put_packet(connection, filebuffer, (filesize % QXFER_CHUNK_SIZE) + 1); + remaining_xfer = -1; + } + + free(filebuffer); + fileio_close(&fileio); - free(xml); return ERROR_OK; } else if (strncmp(packet, "QStartNoAckMode", 15) == 0) { gdb_connection->noack_mode = 1; @@ -2405,6 +2471,19 @@ COMMAND_HANDLER(handle_gdb_breakpoint_override_command) return ERROR_OK; } +/* gdb_tdesc_path */ +COMMAND_HANDLER(handle_gdb_tdesc_path) +{ + if (CMD_ARGC == 0) { + gdb_tdesc_path = NULL; + } else if (CMD_ARGC == 1) { + if (gdb_tdesc_path) + free((void *)gdb_tdesc_path); + gdb_tdesc_path = strdup(CMD_ARGV[0]); + } + return ERROR_OK; +} + static const struct command_registration gdb_command_handlers[] = { { .name = "gdb_sync", @@ -2457,6 +2536,13 @@ static const struct command_registration gdb_command_handlers[] = { "to be used by gdb 'break' commands.", .usage = "('hard'|'soft'|'disable')" }, + { + .name = "gdb_tdesc_path", + .handler = handle_gdb_tdesc_path, + .mode = COMMAND_CONFIG, + .help = "Set or clear the path to the XML target description file", + .usage = "" + }, COMMAND_REGISTRATION_DONE }; @@ -2464,5 +2550,6 @@ int gdb_register_commands(struct command_context *cmd_ctx) { gdb_port = strdup("3333"); gdb_port_next = strdup("3333"); + gdb_tdesc_path = NULL; return register_commands(cmd_ctx, NULL, gdb_command_handlers); } diff --git a/src/server/gdb_server.h b/src/server/gdb_server.h index 74b80ad..9aa59a2 100644 --- a/src/server/gdb_server.h +++ b/src/server/gdb_server.h @@ -36,6 +36,8 @@ struct reg; #define GDB_BUFFER_SIZE 16384 +#define QXFER_CHUNK_SIZE (4096 - 2) + int gdb_target_add_all(struct target *target); int gdb_register_commands(struct command_context *command_context); -- ------------------------------------------------------------------------------ LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
