]> git.sur5r.net Git - openocd/commitdiff
- added faster gdb packet handling (thanks to oyvind harboe for the patch)
authorntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 10 Jan 2008 19:29:52 +0000 (19:29 +0000)
committerntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 10 Jan 2008 19:29:52 +0000 (19:29 +0000)
- code reformat

git-svn-id: svn://svn.berlios.de/openocd/trunk@251 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/helper/command.c
src/server/gdb_server.c

index e9ea06927759558e72a4189ce3e36ca361af92bd..afd866729f19d60f96815ec0e0cd04b9d47f03bc 100644 (file)
@@ -79,12 +79,12 @@ int build_unique_lengths(command_context_t *context, command_t *commands)
 /* Avoid evaluating this each time we add a command. Reduces overhead from O(n^2) to O(n). 
  * Makes a difference on ARM7 types machines and is not observable on GHz machines.
  */
-static int unique_length_dirty=1; 
+static int unique_length_dirty = 1; 
 
 command_t* register_command(command_context_t *context, command_t *parent, char *name, int (*handler)(struct command_context_s *context, char* name, char** args, int argc), enum command_mode mode, char *help)
 {
        command_t *c, *p;
-       unique_length_dirty=1;
+       unique_length_dirty = 1;
        
        if (!context || !name)
                return NULL;
@@ -138,7 +138,7 @@ command_t* register_command(command_context_t *context, command_t *parent, char
 
 int unregister_command(command_context_t *context, char *name)
 {
-       unique_length_dirty=1;
+       unique_length_dirty = 1;
        
        command_t *c, *p = NULL, *c2;
        
@@ -316,7 +316,7 @@ int find_and_run_command(command_context_t *context, command_t *commands, char *
        
        if (unique_length_dirty)
        {
-               unique_length_dirty=0;
+               unique_length_dirty = 0;
                /* update unique lengths */
                build_unique_lengths(context, context->commands);
        }
index 161448518e33023be3720a18596bf059d1dc62d0..01d09791ad97cc6f3118b29e80c233a04630ca5d 100644 (file)
@@ -38,7 +38,7 @@
 #include <unistd.h>
 #include <stdlib.h>
 
-#if 0
+#if 1
 #define _DEBUG_GDB_IO_
 #endif
 
@@ -185,7 +185,9 @@ int gdb_put_packet(connection_t *connection, char *buffer, int len)
        int i;
        unsigned char my_checksum = 0;
        char checksum[3];
+#ifdef _DEBUG_GDB_IO_
        char *debug_buffer;
+#endif
        int reply;
        int retval;
        gdb_connection_t *gdb_con = connection->priv;
@@ -195,12 +197,13 @@ int gdb_put_packet(connection_t *connection, char *buffer, int len)
 
        while (1)
        {
+#ifdef _DEBUG_GDB_IO_
                debug_buffer = malloc(len + 1);
                memcpy(debug_buffer, buffer, len);
                debug_buffer[len] = 0;
                DEBUG("sending packet '$%s#%2.2x'", debug_buffer, my_checksum);
                free(debug_buffer);
-
+#endif
                write_socket(connection->fd, "$", 1);
                if (len > 0)
                        write_socket(connection->fd, buffer, len);
@@ -283,9 +286,63 @@ int gdb_get_packet(connection_t *connection, char *buffer, int *len)
                } while (character != '$');
 
                my_checksum = 0;
-
-               do
+               
+               for (;;)
                {
+                       /* The common case is that we have an entire packet with no escape chars.
+                        * We need to leave at least 2 bytes in the buffer to have
+                        * gdb_get_char() update various bits and bobs correctly. 
+                        */
+                       if ((gdb_con->buf_cnt > 2) && ((gdb_con->buf_cnt+count) < *len))
+                       {
+                               /* The compiler will struggle a bit with constant propagation and
+                                * aliasing, so we help it by showing that these values do not
+                                * change inside the loop 
+                                */ 
+                               int i;
+                               char *buf = gdb_con->buf_p;
+                               int run = gdb_con->buf_cnt - 2;
+                               i = 0;
+                               int done = 0;
+                               while (i < run)
+                               {
+                                       character = *buf++;
+                                       i++;
+                                       if (character == '#')
+                                       {
+                                               /* Danger! character can be '#' when esc is 
+                                                * used so we need an explicit boolean for done here.
+                                                */
+                                               done = 1;
+                                               break;
+                                       }
+                                       
+                                       if (character == '}')
+                                       {
+                                               /* data transmitted in binary mode (X packet)
+                                                * uses 0x7d as escape character */
+                                               my_checksum += character & 0xff;
+                                               character = *buf++;
+                                               i++;
+                                               my_checksum += character & 0xff;
+                                               buffer[count++] = (character ^ 0x20) & 0xff;
+                                       } else
+                                       {
+                                               my_checksum += character & 0xff;
+                                               buffer[count++] = character & 0xff;
+                                       }
+                               }
+                               gdb_con->buf_p += i;
+                               gdb_con->buf_cnt -= i;
+                               if (done) 
+                                       break;
+                       } 
+                       if (count > *len)
+                       {
+                               ERROR("packet buffer too small");
+                               return ERROR_GDB_BUFFER_TOO_SMALL;
+                       }
+                       
                        if ((retval = gdb_get_char(connection, &character)) != ERROR_OK)
                                return retval;
 
@@ -308,12 +365,7 @@ int gdb_get_packet(connection_t *connection, char *buffer, int *len)
                                buffer[count++] = character & 0xff;
                        }
 
-                       if (count > *len)
-                       {
-                               ERROR("packet buffer too small");
-                               return ERROR_GDB_BUFFER_TOO_SMALL;
-                       }
-               } while (1);
+               }
 
                *len = count;
 
@@ -910,6 +962,18 @@ int gdb_read_memory_packet(connection_t *connection, target_t *target, char *pac
                                retval = target->type->read_memory(target, addr, 1, len, buffer);
        }
 
+#if 0
+       if (retval == ERROR_TARGET_DATA_ABORT)
+       {
+               /* TODO : Here we have to lie and send back all zero's lest stack traces won't work.
+                * At some point this might be fixed in GDB, in which case this code can be removed.
+                * http://sourceware.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=2395
+                */
+               memset(buffer, 0, len);
+               retval = ERROR_OK;
+       }
+#endif
+
        if (retval == ERROR_OK)
        {
                hex_buffer = malloc(len * 2 + 1);