produce syntax error
[openocd.git] / src / server / gdb_server.c
index ca8d94489f20b000a48bbc7d950035b8a8fe6e02..52f256a5741222978ce127fd6561a555ce3ce5de 100644 (file)
@@ -5,6 +5,9 @@
  *   Copyright (C) 2007,2008 Ã˜yvind Harboe                                 *
  *   oyvind.harboe@zylin.com                                               *
  *                                                                         *
+ *   Copyright (C) 2008 by Spencer Oliver                                  *
+ *   spen@spen-soft.co.uk                                                  *
+ *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
  *   the Free Software Foundation; either version 2 of the License, or     *
@@ -34,6 +37,7 @@
 #include "jtag.h"
 #include "breakpoints.h"
 #include "flash.h"
+#include "target.h"
 #include "target_request.h"
 #include "configuration.h"
 
@@ -116,10 +120,10 @@ int check_pending(connection_t *connection, int timeout_s, int *got_data)
                *got_data = 1;
                return ERROR_OK;
        }
-       
+
        FD_ZERO(&read_fds);
        FD_SET(connection->fd, &read_fds);
-       
+
        tv.tv_sec = timeout_s;
        tv.tv_usec = 0;
        if (select(connection->fd + 1, &read_fds, NULL, NULL, &tv) == 0)
@@ -288,7 +292,7 @@ int gdb_put_packet_inner(connection_t *connection, char *buffer, int len)
                my_checksum += buffer[i];
 
 #ifdef _DEBUG_GDB_IO_
-       /* 
+       /*
         * At this point we should have nothing in the input queue from GDB,
         * however sometimes '-' is sent even though we've already received
         * an ACK (+) for everything we've sent off.
@@ -302,6 +306,13 @@ int gdb_put_packet_inner(connection_t *connection, char *buffer, int len)
                        break;
                if ((retval = gdb_get_char(connection, &reply)) != ERROR_OK)
                        return retval;
+               if( reply == '$' ){
+                       // fix a problem with some IAR tools
+                       gdb_putback_char( connection, reply );
+                       LOG_DEBUG("Unexpected start of new packet");
+                       break;
+               }
+
                LOG_WARNING("Discard unexpected char %c", reply);
        }
 #endif
@@ -325,7 +336,10 @@ int gdb_put_packet_inner(connection_t *connection, char *buffer, int len)
                        local_buffer[len++] = '#';
                        local_buffer[len++] = DIGITS[(my_checksum >> 4) & 0xf];
                        local_buffer[len++] = DIGITS[my_checksum & 0xf];
-                       gdb_write(connection, local_buffer, len);
+                       if((retval = gdb_write(connection, local_buffer, len)) != ERROR_OK)
+                       {
+                               return retval;
+                       }
                }
                else
                {
@@ -334,14 +348,23 @@ int gdb_put_packet_inner(connection_t *connection, char *buffer, int len)
                        local_buffer[1] = '#';
                        local_buffer[2] = DIGITS[(my_checksum >> 4) & 0xf];
                        local_buffer[3] = DIGITS[my_checksum & 0xf];
-                       gdb_write(connection, local_buffer, 1);
-                       gdb_write(connection, buffer, len);
-                       gdb_write(connection, local_buffer+1, 3);
+                       if((retval = gdb_write(connection, local_buffer, 1)) != ERROR_OK)
+                       {
+                               return retval;
+                       }
+                       if((retval = gdb_write(connection, buffer, len)) != ERROR_OK)
+                       {
+                               return retval;
+                       }
+                       if((retval = gdb_write(connection, local_buffer+1, 3)) != ERROR_OK)
+                       {
+                               return retval;
+                       }
                }
-               
+
                if (gdb_con->noack_mode)
                        break;
-               
+
                if ((retval = gdb_get_char(connection, &reply)) != ERROR_OK)
                        return retval;
 
@@ -366,16 +389,25 @@ int gdb_put_packet_inner(connection_t *connection, char *buffer, int len)
                                log_remove_callback(gdb_log_callback, connection);
                                LOG_WARNING("negative reply, retrying");
                        }
-                       else
-                       {
-                               LOG_ERROR("unknown character 0x%2.2x in reply, dropping connection", reply);
+                       else if( reply == '$' ){
+                               LOG_ERROR("GDB missing ack(1) - assumed good");
+                               gdb_putback_char( connection, reply );
+                               return ERROR_OK;
+                       } else {
+
+                               LOG_ERROR("unknown character(1) 0x%2.2x in reply, dropping connection", reply);
                                gdb_con->closed=1;
                                return ERROR_SERVER_REMOTE_CLOSED;
                        }
                }
+               else if( reply == '$' ){
+                       LOG_ERROR("GDB missing ack(2) - assumed good");
+                       gdb_putback_char( connection, reply );
+                       return ERROR_OK;
+               }
                else
                {
-                       LOG_ERROR("unknown character 0x%2.2x in reply, dropping connection", reply);
+                       LOG_ERROR("unknown character(2) 0x%2.2x in reply, dropping connection", reply);
                        gdb_con->closed=1;
                        return ERROR_SERVER_REMOTE_CLOSED;
                }
@@ -392,6 +424,10 @@ int gdb_put_packet(connection_t *connection, char *buffer, int len)
        gdb_con->busy = 1;
        int retval = gdb_put_packet_inner(connection, buffer, len);
        gdb_con->busy = 0;
+
+       /* we sent some data, reset timer for keep alive messages */
+       kept_alive();
+
        return retval;
 }
 
@@ -401,7 +437,7 @@ static __inline__ int fetch_packet(connection_t *connection, int *checksum_ok, i
        char checksum[3];
        int character;
        int retval;
-       
+
        gdb_connection_t *gdb_con = connection->priv;
        my_checksum = 0;
        int count = 0;
@@ -495,12 +531,12 @@ static __inline__ int fetch_packet(connection_t *connection, int *checksum_ok, i
                return retval;
        checksum[1] = character;
        checksum[2] = 0;
-       
+
        if (!noack)
        {
                *checksum_ok=(my_checksum == strtoul(checksum, NULL, 16));
        }
-       
+
        return ERROR_OK;
 }
 
@@ -566,7 +602,10 @@ int gdb_get_packet_inner(connection_t *connection, char *buffer, int *len)
                }
                if (checksum_ok)
                {
-                       gdb_write(connection, "+", 1);
+                       if ((retval = gdb_write(connection, "+", 1)) != ERROR_OK)
+                       {
+                               return retval;
+                       }
                        break;
                }
        }
@@ -601,10 +640,10 @@ int gdb_output_con(connection_t *connection, const char* line)
                snprintf(hex_buffer + 1 + i*2, 3, "%2.2x", line[i]);
        hex_buffer[bin_size*2+1] = 0;
 
-       gdb_put_packet(connection, hex_buffer, bin_size*2 + 1);
+       int retval = gdb_put_packet(connection, hex_buffer, bin_size*2 + 1);
 
        free(hex_buffer);
-       return ERROR_OK;
+       return retval;
 }
 
 int gdb_output(struct command_context_s *context, const char* line)
@@ -618,7 +657,7 @@ int gdb_output(struct command_context_s *context, const char* line)
 static void gdb_frontend_halted(struct target_s *target, connection_t *connection)
 {
        gdb_connection_t *gdb_connection = connection->priv;
-       
+
        /* In the GDB protocol when we are stepping or coninuing execution,
         * we have a lingering reply. Upon receiving a halted event
         * when we have that lingering packet, we reply to the original
@@ -653,17 +692,21 @@ static void gdb_frontend_halted(struct target_s *target, connection_t *connectio
 
 int gdb_target_callback_event_handler(struct target_s *target, enum target_event event, void *priv)
 {
+       int retval;
        connection_t *connection = priv;
 
        target_handle_event( target, event );
        switch (event)
        {
-               case TARGET_EVENT_HALTED:
+               case TARGET_EVENT_EARLY_HALTED:
                        gdb_frontend_halted(target, connection);
                        break;
                case TARGET_EVENT_GDB_FLASH_ERASE_START:
                        target_handle_event( target, TARGET_EVENT_OLD_gdb_program_config );
-                       jtag_execute_queue();
+                       if((retval = jtag_execute_queue()) != ERROR_OK)
+                       {
+                               return retval;
+                       }
                        break;
                default:
                        break;
@@ -691,7 +734,7 @@ int gdb_new_connection(connection_t *connection)
        gdb_connection->closed = 0;
        gdb_connection->busy = 0;
        gdb_connection->noack_mode = 0;
-       
+
        /* send ACK to GDB for debug request */
        gdb_write(connection, "+", 1);
 
@@ -699,44 +742,44 @@ int gdb_new_connection(connection_t *connection)
        command_set_output_handler(connection->cmd_ctx, gdb_output, connection);
 
        /* we must remove all breakpoints registered to the target as a previous
-        * GDB session could leave dangling breakpoints if e.g. communication 
+        * GDB session could leave dangling breakpoints if e.g. communication
         * timed out.
         */
        breakpoint_clear_target(gdb_service->target);
        watchpoint_clear_target(gdb_service->target);
-       
+
        /* register callback to be informed about target events */
        target_register_event_callback(gdb_target_callback_event_handler, connection);
 
        /* a gdb session just attached, try to put the target in halt mode.
-        * 
-        * DANGER!!!! 
-        * 
+        *
+        * DANGER!!!!
+        *
         * If the halt fails(e.g. target needs a reset, JTAG communication not
         * working, etc.), then the GDB connect will succeed as
         * the get_gdb_reg_list() will lie and return a register list with
         * dummy values.
-        * 
+        *
         * This allows GDB monitor commands to be run from a GDB init script to
         * initialize the target
-        * 
+        *
         * Also, since the halt() is asynchronous target connect will be
         * instantaneous and thus avoiding annoying timeout problems during
-        * connect. 
+        * connect.
         */
        target_halt(gdb_service->target);
        /* FIX!!!! could extended-remote work better here?
-        * 
+        *
         *  wait a tiny bit for halted state or we just continue. The
-        * GDB register packet will then contain garbage 
+        * GDB register packet will then contain garbage
         */
        target_wait_state(gdb_service->target, TARGET_HALTED, 500);
-       
+
        /* remove the initial ACK from the incoming buffer */
        if ((retval = gdb_get_char(connection, &initial_ack)) != ERROR_OK)
                return retval;
 
-       /* FIX!!!??? would we actually ever receive a + here??? 
+       /* FIX!!!??? would we actually ever receive a + here???
         * Not observed.
         */
        if (initial_ack != '+')
@@ -775,6 +818,7 @@ int gdb_connection_closed(connection_t *connection)
        log_remove_callback(gdb_log_callback, connection);
 
        target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_DETACH );
+
        return ERROR_OK;
 }
 
@@ -929,11 +973,7 @@ int gdb_set_registers_packet(connection_t *connection, target_t *target, char *p
 
                /* get register arch_type, and call set method */
                arch_type = register_get_arch_type(reg_list[i]->arch_type);
-               if (arch_type == NULL)
-               {
-                       LOG_ERROR("BUG: encountered unregistered arch type");
-                       exit(-1);
-               }
+
                arch_type->set(reg_list[i], bin_buf);
 
                /* advance packet pointer */
@@ -1007,7 +1047,7 @@ int gdb_set_register_packet(connection_t *connection, target_t *target, char *pa
        if (reg_list_size < reg_num)
        {
                LOG_ERROR("gdb requested a non-existing register");
-               return ERROR_SERVER_REMOTE_CLOSED;      
+               return ERROR_SERVER_REMOTE_CLOSED;
        }
 
        if (*separator != '=')
@@ -1026,11 +1066,6 @@ int gdb_set_register_packet(connection_t *connection, target_t *target, char *pa
 
        /* get register arch_type, and call set method */
        arch_type = register_get_arch_type(reg_list[reg_num]->arch_type);
-       if (arch_type == NULL)
-       {
-               LOG_ERROR("BUG: encountered unregistered arch type");
-               exit(-1);
-       }
        arch_type->set(reg_list[reg_num], bin_buf);
 
        gdb_put_packet(connection, "OK", 2);
@@ -1308,7 +1343,7 @@ int gdb_breakpoint_watchpoint_packet(connection_t *connection, target_t *target,
                wp_type = WPT_READ;
        else if (type == 4) /* access watchpoint */
                wp_type = WPT_ACCESS;
-       
+
        if (gdb_breakpoint_override&&((bp_type==BKPT_SOFT)||(bp_type==BKPT_HARD)))
        {
                bp_type=gdb_breakpoint_override_type;
@@ -1471,7 +1506,7 @@ static int compare_bank (const void * a, const void * b)
        flash_bank_t *b1, *b2;
        b1=*((flash_bank_t **)a);
        b2=*((flash_bank_t **)b);
-       
+
        if (b1->base==b2->base)
        {
                return 0;
@@ -1488,7 +1523,7 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
 {
        command_context_t *cmd_ctx = connection->cmd_ctx;
        gdb_connection_t *gdb_connection = connection->priv;
-       
+
        if (strstr(packet, "qRcmd,"))
        {
                if (packet_size > 6)
@@ -1605,15 +1640,15 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
                length = strtoul(separator + 1, &separator, 16);
 
                xml_printf(&retval, &xml, &pos, &size, "<memory-map>\n");
-       
-               /* 
+
+               /*
                sort banks in ascending order, we need to make non-flash memory be ram(or rather
                read/write) by default for GDB.
                GDB does not have a concept of non-cacheable read/write memory.
                 */
                flash_bank_t **banks=malloc(sizeof(flash_bank_t *)*flash_get_bank_count());
                int i;
-               
+
                for (i=0; i<flash_get_bank_count(); i++)
                {
                        p = get_flash_bank_by_num(i);
@@ -1626,29 +1661,29 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
                        }
                        banks[i]=p;
                }
-               
+
                qsort(banks, flash_get_bank_count(), sizeof(flash_bank_t *), compare_bank);
-               
+
                u32 ram_start=0;
                for (i=0; i<flash_get_bank_count(); i++)
                {
                        p = banks[i];
-                       
+
                        if (ram_start<p->base)
                        {
                                xml_printf(&retval, &xml, &pos, &size, "<memory type=\"ram\" start=\"0x%x\" length=\"0x%x\"/>\n",
                                        ram_start, p->base-ram_start);
                        }
-                       
+
                        /* if device has uneven sector sizes, eg. str7, lpc
                         * we pass the smallest sector size to gdb memory map */
                        blocksize = gdb_calc_blocksize(p);
-       
+
                        xml_printf(&retval, &xml, &pos, &size, "<memory type=\"flash\" start=\"0x%x\" length=\"0x%x\">\n" \
                                "<property name=\"blocksize\">0x%x</property>\n" \
                                "</memory>\n", \
                                p->base, p->size, blocksize);
-                       ram_start=p->base+p->size;                      
+                       ram_start=p->base+p->size;
                }
                if (ram_start!=0)
                {
@@ -1659,7 +1694,7 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
                        /* a flash chip could be at the very end of the 32 bit address space, in which case
                        ram_start will be precisely 0 */
                }
-               
+
                free(banks);
                banks = NULL;
 
@@ -1804,6 +1839,7 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
 
        if (strstr(packet, "vFlashWrite:"))
        {
+               int retval;
                unsigned long addr;
                unsigned long length;
                char *parse = packet + 12;
@@ -1829,7 +1865,10 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
                }
 
                /* create new section with content from packet buffer */
-               image_add_section(gdb_connection->vflash_image, addr, length, 0x0, (u8*)parse);
+               if((retval = image_add_section(gdb_connection->vflash_image, addr, length, 0x0, (u8*)parse)) != ERROR_OK)
+               {
+                       return retval;
+               }
 
                gdb_put_packet(connection, "OK", 2);
 
@@ -1944,7 +1983,20 @@ int gdb_input_inner(connection_t *connection)
                /* terminate with zero */
                packet[packet_size] = 0;
 
-               LOG_DEBUG("received packet: '%s'", packet);
+               if( LOG_LEVEL_IS( LOG_LVL_DEBUG ) ){
+                       if( packet[0] == 'X' ){
+                               // binary packets spew junk into the debug log stream
+                               char buf[ 50 ];
+                               int x;
+                               for( x = 0 ; (x < 49) && (packet[x] != ':') ; x++ ){
+                                       buf[x] = packet[x];
+                               }
+                               buf[x] = 0;
+                               LOG_DEBUG("received packet: '%s:<binary-data>'", buf );
+                       } else {
+                               LOG_DEBUG("received packet: '%s'", packet );
+                       }
+               }
 
                if (packet_size > 0)
                {
@@ -1997,7 +2049,7 @@ int gdb_input_inner(connection_t *connection)
                                                } else
                                                {
                                                        /* We're running/stepping, in which case we can
-                                                        * forward log output until the target is halted 
+                                                        * forward log output until the target is halted
                                                         */
                                                        gdb_connection_t *gdb_con = connection->priv;
                                                        gdb_con->frontend_state = TARGET_RUNNING;
@@ -2006,7 +2058,7 @@ int gdb_input_inner(connection_t *connection)
                                                        if (retval!=ERROR_OK)
                                                        {
                                                                /* we'll never receive a halted condition... issue a false one.. */
-                                                               gdb_frontend_halted(target, connection); 
+                                                               gdb_frontend_halted(target, connection);
                                                        }
                                                }
                                        }
@@ -2074,7 +2126,7 @@ int gdb_input(connection_t *connection)
        /* logging does not propagate the error, yet can set th gdb_con->closed flag */
        if (gdb_con->closed)
                return ERROR_SERVER_REMOTE_CLOSED;
-       
+
        /* we'll recover from any other errors(e.g. temporary timeouts, etc.) */
        return ERROR_OK;
 }
@@ -2105,14 +2157,14 @@ int gdb_init(void)
                gdb_service = malloc(sizeof(gdb_service_t));
                gdb_service->target = target;
 
-               add_service("gdb", CONNECTION_GDB, 
-                           gdb_port + target->target_number, 
-                           1, gdb_new_connection, gdb_input, 
-                           gdb_connection_closed, 
+               add_service("gdb", CONNECTION_GDB,
+                           gdb_port + target->target_number,
+                           1, gdb_new_connection, gdb_input,
+                           gdb_connection_closed,
                            gdb_service);
 
-               LOG_DEBUG("gdb service for target %s at port %i", 
-                         target->type->name, 
+               LOG_DEBUG("gdb service for target %s at port %i",
+                         target->type->name,
                          gdb_port + target->target_number);
 
                target = target->next;
@@ -2125,7 +2177,10 @@ int gdb_init(void)
 int handle_gdb_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        if (argc == 0)
+       {
+               command_print(cmd_ctx, "gdb_port: %ld", gdb_port);
                return ERROR_OK;
+       }
 
        /* only if the port wasn't overwritten by cmdline */
        if (gdb_port == 0)
@@ -2158,10 +2213,11 @@ int handle_gdb_detach_command(struct command_context_s *cmd_ctx, char *cmd, char
                        detach_mode = GDB_DETACH_NOTHING;
                        return ERROR_OK;
                }
+               else
+                       LOG_WARNING("invalid gdb_detach configuration directive: %s", args[0]);
        }
 
-       LOG_WARNING("invalid gdb_detach configuration directive: %s", args[0]);
-       return ERROR_OK;
+       return ERROR_COMMAND_SYNTAX_ERROR;
 }
 
 int handle_gdb_memory_map_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
@@ -2178,10 +2234,11 @@ int handle_gdb_memory_map_command(struct command_context_s *cmd_ctx, char *cmd,
                        gdb_use_memory_map = 0;
                        return ERROR_OK;
                }
+               else
+                       LOG_WARNING("invalid gdb_memory_map configuration directive %s", args[0]);
        }
 
-       LOG_WARNING("invalid gdb_memory_map configuration directive: %s", args[0]);
-       return ERROR_OK;
+       return ERROR_COMMAND_SYNTAX_ERROR;
 }
 
 int handle_gdb_flash_program_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
@@ -2198,10 +2255,11 @@ int handle_gdb_flash_program_command(struct command_context_s *cmd_ctx, char *cm
                        gdb_flash_program = 0;
                        return ERROR_OK;
                }
+               else
+                       LOG_WARNING("invalid gdb_flash_program configuration directive: %s", args[0]);
        }
 
-       LOG_WARNING("invalid gdb_memory_map configuration directive: %s", args[0]);
-       return ERROR_OK;
+       return ERROR_COMMAND_SYNTAX_ERROR;
 }
 
 int handle_gdb_report_data_abort_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
@@ -2218,18 +2276,19 @@ int handle_gdb_report_data_abort_command(struct command_context_s *cmd_ctx, char
                        gdb_report_data_abort = 0;
                        return ERROR_OK;
                }
+               else
+                       LOG_WARNING("invalid gdb_report_data_abort configuration directive: %s", args[0]);
        }
 
-       LOG_WARNING("invalid gdb_report_data_abort configuration directive: %s", args[0]);
-       return ERROR_OK;
+       return ERROR_COMMAND_SYNTAX_ERROR;
 }
 
-/* daemon configuration command gdb_port */
+/* gdb_breakpoint_override */
 int handle_gdb_breakpoint_override_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        if (argc == 0)
        {
-               
+
        } else if (argc==1)
        {
                gdb_breakpoint_override = 1;
@@ -2254,7 +2313,7 @@ int handle_gdb_breakpoint_override_command(struct command_context_s *cmd_ctx, ch
        {
                LOG_USER("breakpoint type is not overriden");
        }
-       
+
        return ERROR_OK;
 }
 
@@ -2262,15 +2321,15 @@ int handle_gdb_breakpoint_override_command(struct command_context_s *cmd_ctx, ch
 int gdb_register_commands(command_context_t *command_context)
 {
        register_command(command_context, NULL, "gdb_port", handle_gdb_port_command,
-                       COMMAND_CONFIG, "");
+                       COMMAND_CONFIG, "daemon configuration command gdb_port");
        register_command(command_context, NULL, "gdb_detach", handle_gdb_detach_command,
                        COMMAND_CONFIG, "");
        register_command(command_context, NULL, "gdb_memory_map", handle_gdb_memory_map_command,
-                       COMMAND_CONFIG, "");
+                       COMMAND_CONFIG, "enable or disable memory map");
        register_command(command_context, NULL, "gdb_flash_program", handle_gdb_flash_program_command,
-                       COMMAND_CONFIG, "");
+                       COMMAND_CONFIG, "enable or disable flash program");
        register_command(command_context, NULL, "gdb_report_data_abort", handle_gdb_report_data_abort_command,
-                       COMMAND_CONFIG, "");
+                       COMMAND_CONFIG, "enable or disable report data");
        register_command(command_context, NULL, "gdb_breakpoint_override", handle_gdb_breakpoint_override_command,
                        COMMAND_EXEC, "hard/soft/disabled - force breakpoint type for gdb 'break' commands."
                        "The raison d'etre for this option is to support GDB GUI's without "
@@ -2278,12 +2337,3 @@ int gdb_register_commands(command_context_t *command_context)
                        "is not sufficient");
        return ERROR_OK;
 }
-
-
-
-/*
- * Local Variables: ***
- * c-basic-offset: 4 ***
- * tab-width: 4 ***
- * End: ***
- */

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)