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

Reply via email to