Sorry, I have forgotten to add a description for the last version, where
[openocd.git] / src / server / gdb_server.c
index 3481625e9a359eab8d9ccf3a70364b96e665cec8..657338ea7405e395639a207a8a5e7fb71743a1f8 100644 (file)
 
 static unsigned short gdb_port;
 
+enum gdb_detach_mode
+{
+       GDB_DETACH_RESUME,
+       GDB_DETACH_RESET,
+       GDB_DETACH_HALT,
+       GDB_DETACH_NOTHING
+};
+
+enum gdb_detach_mode detach_mode = GDB_DETACH_RESUME;
+
 int gdb_last_signal(target_t *target)
 {
        switch (target->debug_reason)
@@ -172,7 +182,6 @@ int gdb_put_packet(connection_t *connection, char *buffer, int len)
 
        while (1)
        {
-
                debug_buffer = malloc(len + 1);
                memcpy(debug_buffer, buffer, len);
                debug_buffer[len] = 0;
@@ -1158,7 +1167,7 @@ int gdb_breakpoint_watchpoint_packet(connection_t *connection, target_t *target,
        return ERROR_OK;
 }
 
-void gdb_query_packet(connection_t *connection, char *packet, int packet_size)
+int gdb_query_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
 {
        command_context_t *cmd_ctx = connection->cmd_ctx;
 
@@ -1180,10 +1189,52 @@ void gdb_query_packet(connection_t *connection, char *packet, int packet_size)
                        free(cmd);
                }
                gdb_put_packet(connection, "OK", 2);
-               return;
+               return ERROR_OK;
        }
 
+       if (strstr(packet, "qCRC:"))
+       {
+               if (packet_size > 5)
+               {
+                       int retval;
+                       u8 gdb_reply[9];
+                       char *separator;
+                       u32 checksum;
+                       u32 addr = 0;
+                       u32 len = 0;
+                       
+                       /* skip command character */
+                       packet += 5;
+                       
+                       addr = strtoul(packet, &separator, 16);
+                       
+                       if (*separator != ',')
+                       {
+                               ERROR("incomplete read memory packet received, dropping connection");
+                               return ERROR_SERVER_REMOTE_CLOSED;
+                       }
+                       
+                       len = strtoul(separator+1, NULL, 16);
+                       
+                       retval = target_checksum_memory(target, addr, len, &checksum);
+                       
+                       if (retval == ERROR_OK)
+                       {
+                               snprintf(gdb_reply, 9, "C%2.2x", checksum);
+                               gdb_put_packet(connection, gdb_reply, 9);
+                       }
+                       else
+                       {
+                               if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK)
+                                       return retval; 
+                       }
+                       
+                       return ERROR_OK;
+               }
+       }
+       
        gdb_put_packet(connection, "", 0);
+       return ERROR_OK;
 }
 
 int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
@@ -1270,29 +1321,29 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
 
        if (!strcmp(packet, "vFlashDone"))
        {
-               u32 image_size;
+               u32 written;
                char *error_str;
-               u32 *failed = malloc(sizeof(u32) * gdb_connection->vflash_image->num_sections);
-               
+
                /* process the flashing buffer */
-               if ((result = flash_write(gdb_service->target, gdb_connection->vflash_image, &image_size, &error_str, failed)) != ERROR_OK)
+               if ((result = flash_write(gdb_service->target, gdb_connection->vflash_image, &written, &error_str, NULL, 0)) != ERROR_OK)
                {
                        if (result == ERROR_FLASH_DST_OUT_OF_BANK)
                                gdb_put_packet(connection, "E.memtype", 9);
                        else
                                gdb_send_error(connection, EIO);
                        
-                       ERROR("flash writing failed: %s", error_str);
-                       free(error_str);
+                       if (error_str)
+                       {
+                               ERROR("flash writing failed: %s", error_str);
+                               free(error_str);
+                       }
                }
                else
                {
-                       DEBUG("wrote %u bytes from vFlash image to flash", image_size);
+                       DEBUG("wrote %u bytes from vFlash image to flash", written);
                        gdb_put_packet(connection, "OK", 2);
                }
                
-               free(failed);
-               
                image_close(gdb_connection->vflash_image);
                free(gdb_connection->vflash_image);
                gdb_connection->vflash_image = NULL;
@@ -1304,6 +1355,31 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
        return ERROR_OK;
 }
 
+int gdb_detach(connection_t *connection, target_t *target)
+{
+       switch( detach_mode )
+       {
+               case GDB_DETACH_RESUME:
+                       target->type->resume(target, 1, 0, 1, 0);
+                       break;
+               
+               case GDB_DETACH_RESET:
+                       target_process_reset(connection->cmd_ctx);
+                       break;
+               
+               case GDB_DETACH_HALT:
+                       target->type->halt(target);
+                       break;
+               
+               case GDB_DETACH_NOTHING:
+                       break;
+       }
+       
+       gdb_put_packet(connection, "OK", 2);
+       
+       return ERROR_OK;
+}
+
 int gdb_input(connection_t *connection)
 {
        gdb_service_t *gdb_service = connection->service->priv;
@@ -1335,7 +1411,7 @@ int gdb_input(connection_t *connection)
                /* terminate with zero */
                packet[packet_size] = 0;
 
-               DEBUG("recevied packet: '%s'", packet);
+               DEBUG("received packet: '%s'", packet);
 
                if (packet_size > 0)
                {
@@ -1348,7 +1424,7 @@ int gdb_input(connection_t *connection)
                                        gdb_put_packet(connection, NULL, 0);
                                        break;
                                case 'q':
-                                       gdb_query_packet(connection, packet, packet_size);
+                                       retval = gdb_query_packet(connection, target, packet, packet_size);
                                        break;
                                case 'g':
                                        retval = gdb_get_registers_packet(connection, target, packet, packet_size);
@@ -1383,8 +1459,7 @@ int gdb_input(connection_t *connection)
                                        retval = gdb_v_packet(connection, target, packet, packet_size);
                                        break;
                                case 'D':
-                                       target->type->resume(target, 1, 0, 1, 0);
-                                       gdb_put_packet(connection, "OK", 2);
+                                       retval = gdb_detach(connection, target);
                                        break;
                                case 'X':
                                        if ((retval = gdb_write_memory_binary_packet(connection, target, packet, packet_size)) != ERROR_OK)
@@ -1470,10 +1545,42 @@ int handle_gdb_port_command(struct command_context_s *cmd_ctx, char *cmd, char *
        return ERROR_OK;
 }
 
+int handle_gdb_detach_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       if (argc == 1)
+       {
+               if (strcmp(args[0], "resume") == 0)
+               {
+                       detach_mode = GDB_DETACH_RESUME;
+                       return ERROR_OK;
+               }
+               else if (strcmp(args[0], "reset") == 0)
+               {
+                       detach_mode = GDB_DETACH_RESET;
+                       return ERROR_OK;
+               }
+               else if (strcmp(args[0], "halt") == 0)
+               {
+                       detach_mode = GDB_DETACH_HALT;
+                       return ERROR_OK;
+               }
+               else if (strcmp(args[0], "nothing") == 0)
+               {
+                       detach_mode = GDB_DETACH_NOTHING;
+                       return ERROR_OK;
+               }
+       }
+       
+       WARNING("invalid gdb_detach configuration directive: %s", args[0]);
+       return ERROR_OK;
+}
+
 int gdb_register_commands(command_context_t *command_context)
 {
        register_command(command_context, NULL, "gdb_port", handle_gdb_port_command,
                        COMMAND_CONFIG, "");
-
+       register_command(command_context, NULL, "gdb_detach", handle_gdb_detach_command,
+                       COMMAND_CONFIG, "");
+       
        return ERROR_OK;
 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)