1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "replacements.h"
26 #include "gdb_server.h"
30 #include "binarybuffer.h"
32 #include "breakpoints.h"
34 #include "target_request.h"
42 #define _DEBUG_GDB_IO_
45 static unsigned short gdb_port
;
55 /* target behaviour on gdb detach */
56 enum gdb_detach_mode detach_mode
= GDB_DETACH_RESUME
;
58 /* set if we are sending a memory map to gdb
59 * via qXfer:memory-map:read packet */
60 int gdb_use_memory_map
= 0;
61 int gdb_flash_program
= 0;
63 int gdb_last_signal(target_t
*target
)
65 switch (target
->debug_reason
)
67 case DBG_REASON_DBGRQ
:
68 return 0x2; /* SIGINT */
69 case DBG_REASON_BREAKPOINT
:
70 case DBG_REASON_WATCHPOINT
:
71 case DBG_REASON_WPTANDBKPT
:
72 return 0x05; /* SIGTRAP */
73 case DBG_REASON_SINGLESTEP
:
74 return 0x05; /* SIGTRAP */
75 case DBG_REASON_NOTHALTED
:
76 return 0x0; /* no signal... shouldn't happen */
78 ERROR("BUG: undefined debug reason");
83 int gdb_get_char(connection_t
*connection
, int* next_char
)
85 gdb_connection_t
*gdb_con
= connection
->priv
;
91 if (gdb_con
->buf_cnt
-- > 0)
93 *next_char
= *(gdb_con
->buf_p
++);
94 if (gdb_con
->buf_cnt
> 0)
95 connection
->input_pending
= 1;
97 connection
->input_pending
= 0;
100 DEBUG("returned char '%c' (0x%2.2x)", *next_char
, *next_char
);
106 while ((gdb_con
->buf_cnt
= read_socket(connection
->fd
, gdb_con
->buffer
, GDB_BUFFER_SIZE
)) <= 0)
108 if (gdb_con
->buf_cnt
== 0)
109 return ERROR_SERVER_REMOTE_CLOSED
;
112 errno
= WSAGetLastError();
119 case WSAECONNABORTED
:
120 return ERROR_SERVER_REMOTE_CLOSED
;
122 return ERROR_SERVER_REMOTE_CLOSED
;
124 ERROR("read: %d", errno
);
134 return ERROR_SERVER_REMOTE_CLOSED
;
136 return ERROR_SERVER_REMOTE_CLOSED
;
138 ERROR("read: %s", strerror(errno
));
144 #ifdef _DEBUG_GDB_IO_
145 debug_buffer
= malloc(gdb_con
->buf_cnt
+ 1);
146 memcpy(debug_buffer
, gdb_con
->buffer
, gdb_con
->buf_cnt
);
147 debug_buffer
[gdb_con
->buf_cnt
] = 0;
148 DEBUG("received '%s'", debug_buffer
);
152 gdb_con
->buf_p
= gdb_con
->buffer
;
154 *next_char
= *(gdb_con
->buf_p
++);
155 if (gdb_con
->buf_cnt
> 0)
156 connection
->input_pending
= 1;
158 connection
->input_pending
= 0;
159 #ifdef _DEBUG_GDB_IO_
160 DEBUG("returned char '%c' (0x%2.2x)", *next_char
, *next_char
);
166 int gdb_putback_char(connection_t
*connection
, int last_char
)
168 gdb_connection_t
*gdb_con
= connection
->priv
;
170 if (gdb_con
->buf_p
> gdb_con
->buffer
)
172 *(--gdb_con
->buf_p
) = last_char
;
177 ERROR("BUG: couldn't put character back");
183 int gdb_put_packet(connection_t
*connection
, char *buffer
, int len
)
186 unsigned char my_checksum
= 0;
188 #ifdef _DEBUG_GDB_IO_
193 gdb_connection_t
*gdb_con
= connection
->priv
;
195 for (i
= 0; i
< len
; i
++)
196 my_checksum
+= buffer
[i
];
200 #ifdef _DEBUG_GDB_IO_
201 debug_buffer
= malloc(len
+ 1);
202 memcpy(debug_buffer
, buffer
, len
);
203 debug_buffer
[len
] = 0;
204 DEBUG("sending packet '$%s#%2.2x'", debug_buffer
, my_checksum
);
207 write_socket(connection
->fd
, "$", 1);
209 write_socket(connection
->fd
, buffer
, len
);
210 write_socket(connection
->fd
, "#", 1);
212 snprintf(checksum
, 3, "%2.2x", my_checksum
);
214 write_socket(connection
->fd
, checksum
, 2);
216 if ((retval
= gdb_get_char(connection
, &reply
)) != ERROR_OK
)
221 else if (reply
== '-')
222 WARNING("negative reply, retrying");
223 else if (reply
== 0x3)
226 if ((retval
= gdb_get_char(connection
, &reply
)) != ERROR_OK
)
230 else if (reply
== '-')
231 WARNING("negative reply, retrying");
234 ERROR("unknown character 0x%2.2x in reply, dropping connection", reply
);
235 return ERROR_SERVER_REMOTE_CLOSED
;
240 ERROR("unknown character 0x%2.2x in reply, dropping connection", reply
);
241 return ERROR_SERVER_REMOTE_CLOSED
;
248 int gdb_get_packet(connection_t
*connection
, char *buffer
, int *len
)
254 unsigned char my_checksum
= 0;
255 gdb_connection_t
*gdb_con
= connection
->priv
;
261 if ((retval
= gdb_get_char(connection
, &character
)) != ERROR_OK
)
264 #ifdef _DEBUG_GDB_IO_
265 DEBUG("character: '%c'", character
);
273 WARNING("acknowledgment received, but no packet pending");
276 WARNING("negative acknowledgment, but no packet pending");
283 WARNING("ignoring character 0x%x", character
);
286 } while (character
!= '$');
293 /* The common case is that we have an entire packet with no escape chars.
294 * We need to leave at least 2 bytes in the buffer to have
295 * gdb_get_char() update various bits and bobs correctly.
297 if ((gdb_con
->buf_cnt
> 2) && ((gdb_con
->buf_cnt
+count
) < *len
))
299 /* The compiler will struggle a bit with constant propagation and
300 * aliasing, so we help it by showing that these values do not
301 * change inside the loop
304 char *buf
= gdb_con
->buf_p
;
305 int run
= gdb_con
->buf_cnt
- 2;
312 if (character
== '#')
314 /* Danger! character can be '#' when esc is
315 * used so we need an explicit boolean for done here.
321 if (character
== '}')
323 /* data transmitted in binary mode (X packet)
324 * uses 0x7d as escape character */
325 my_checksum
+= character
& 0xff;
328 my_checksum
+= character
& 0xff;
329 buffer
[count
++] = (character
^ 0x20) & 0xff;
332 my_checksum
+= character
& 0xff;
333 buffer
[count
++] = character
& 0xff;
337 gdb_con
->buf_cnt
-= i
;
343 ERROR("packet buffer too small");
344 return ERROR_GDB_BUFFER_TOO_SMALL
;
347 if ((retval
= gdb_get_char(connection
, &character
)) != ERROR_OK
)
350 if (character
== '#')
353 if (character
== '}')
355 /* data transmitted in binary mode (X packet)
356 * uses 0x7d as escape character */
357 my_checksum
+= character
& 0xff;
358 if ((retval
= gdb_get_char(connection
, &character
)) != ERROR_OK
)
360 my_checksum
+= character
& 0xff;
361 buffer
[count
++] = (character
^ 0x20) & 0xff;
365 my_checksum
+= character
& 0xff;
366 buffer
[count
++] = character
& 0xff;
373 if ((retval
= gdb_get_char(connection
, &character
)) != ERROR_OK
)
375 checksum
[0] = character
;
376 if ((retval
= gdb_get_char(connection
, &character
)) != ERROR_OK
)
378 checksum
[1] = character
;
381 if (my_checksum
== strtoul(checksum
, NULL
, 16))
383 write_socket(connection
->fd
, "+", 1);
387 WARNING("checksum error, requesting retransmission");
388 write_socket(connection
->fd
, "-", 1);
394 int gdb_output(struct command_context_s
*context
, char* line
)
396 connection_t
*connection
= context
->output_handler_priv
;
397 gdb_connection_t
*gdb_connection
= connection
->priv
;
402 /* check if output is enabled */
403 if (gdb_connection
->output_disable
)
408 bin_size
= strlen(line
);
410 hex_buffer
= malloc(bin_size
*2 + 4);
413 for (i
=0; i
<bin_size
; i
++)
414 snprintf(hex_buffer
+ 1 + i
*2, 3, "%2.2x", line
[i
]);
415 hex_buffer
[bin_size
*2+1] = '0';
416 hex_buffer
[bin_size
*2+2] = 'a';
417 hex_buffer
[bin_size
*2+3] = 0x0;
419 gdb_put_packet(connection
, hex_buffer
, bin_size
*2 + 3);
425 int gdb_program_handler(struct target_s
*target
, enum target_event event
, void *priv
)
428 struct command_context_s
*cmd_ctx
= priv
;
430 if (target
->gdb_program_script
)
432 script
= fopen(target
->gdb_program_script
, "r");
435 ERROR("couldn't open script file %s", target
->gdb_program_script
);
439 INFO("executing gdb_program script '%s'", target
->gdb_program_script
);
440 command_run_file(cmd_ctx
, script
, COMMAND_EXEC
);
443 jtag_execute_queue();
449 int gdb_target_callback_event_handler(struct target_s
*target
, enum target_event event
, void *priv
)
451 connection_t
*connection
= priv
;
452 gdb_connection_t
*gdb_connection
= connection
->priv
;
458 case TARGET_EVENT_HALTED
:
459 if (gdb_connection
->frontend_state
== TARGET_RUNNING
)
461 if (gdb_connection
->ctrl_c
)
464 gdb_connection
->ctrl_c
= 0;
468 signal
= gdb_last_signal(target
);
471 snprintf(sig_reply
, 4, "T%2.2x", signal
);
472 gdb_put_packet(connection
, sig_reply
, 3);
473 gdb_connection
->frontend_state
= TARGET_HALTED
;
476 case TARGET_EVENT_RESUMED
:
477 if (gdb_connection
->frontend_state
== TARGET_HALTED
)
479 gdb_connection
->frontend_state
= TARGET_RUNNING
;
482 case TARGET_EVENT_GDB_PROGRAM
:
483 gdb_program_handler(target
, event
, connection
->cmd_ctx
);
492 int gdb_new_connection(connection_t
*connection
)
494 gdb_connection_t
*gdb_connection
= malloc(sizeof(gdb_connection_t
));
495 gdb_service_t
*gdb_service
= connection
->service
->priv
;
499 connection
->priv
= gdb_connection
;
501 /* initialize gdb connection information */
502 gdb_connection
->buf_p
= gdb_connection
->buffer
;
503 gdb_connection
->buf_cnt
= 0;
504 gdb_connection
->ctrl_c
= 0;
505 gdb_connection
->frontend_state
= TARGET_HALTED
;
506 gdb_connection
->vflash_image
= NULL
;
507 gdb_connection
->output_disable
= 0;
509 /* output goes through gdb connection */
510 command_set_output_handler(connection
->cmd_ctx
, gdb_output
, connection
);
512 /* register callback to be informed about target events */
513 target_register_event_callback(gdb_target_callback_event_handler
, connection
);
515 /* a gdb session just attached, put the target in halt mode */
516 if (((retval
= gdb_service
->target
->type
->halt(gdb_service
->target
)) != ERROR_OK
) &&
517 (retval
!= ERROR_TARGET_ALREADY_HALTED
))
519 ERROR("error when trying to halt target");
523 while (gdb_service
->target
->state
!= TARGET_HALTED
)
525 gdb_service
->target
->type
->poll(gdb_service
->target
);
528 /* remove the initial ACK from the incoming buffer */
529 if ((retval
= gdb_get_char(connection
, &initial_ack
)) != ERROR_OK
)
532 if (initial_ack
!= '+')
533 gdb_putback_char(connection
, initial_ack
);
538 int gdb_connection_closed(connection_t
*connection
)
540 gdb_service_t
*gdb_service
= connection
->service
->priv
;
541 gdb_connection_t
*gdb_connection
= connection
->priv
;
543 /* see if an image built with vFlash commands is left */
544 if (gdb_connection
->vflash_image
)
546 image_close(gdb_connection
->vflash_image
);
547 free(gdb_connection
->vflash_image
);
548 gdb_connection
->vflash_image
= NULL
;
551 /* if this connection registered a debug-message receiver delete it */
552 delete_debug_msg_receiver(connection
->cmd_ctx
, gdb_service
->target
);
554 if (connection
->priv
)
556 free(connection
->priv
);
557 connection
->priv
= NULL
;
561 ERROR("BUG: connection->priv == NULL");
564 target_unregister_event_callback(gdb_target_callback_event_handler
, connection
);
569 void gdb_send_error(connection_t
*connection
, u8 the_error
)
572 snprintf(err
, 4, "E%2.2X", the_error
);
573 gdb_put_packet(connection
, err
, 3);
576 int gdb_last_signal_packet(connection_t
*connection
, target_t
*target
, char* packet
, int packet_size
)
581 signal
= gdb_last_signal(target
);
583 snprintf(sig_reply
, 4, "S%2.2x", signal
);
584 gdb_put_packet(connection
, sig_reply
, 3);
589 /* Convert register to string of bits. NB! The # of bits in the
590 * register might be non-divisible by 8(a byte), in which
591 * case an entire byte is shown. */
592 void gdb_str_to_target(target_t
*target
, char *tstr
, reg_t
*reg
)
594 static const char *DIGITS
= "0123456789abcdef";
600 buf_len
= CEIL(reg
->size
, 8);
602 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
604 for (i
= 0; i
< buf_len
; i
++)
606 tstr
[i
*2] = DIGITS
[(buf
[i
]>>4) & 0xf];
607 tstr
[i
*2+1] = DIGITS
[buf
[i
]&0xf];
612 for (i
= 0; i
< buf_len
; i
++)
614 tstr
[(buf_len
-1-i
)*2] = DIGITS
[(buf
[i
]>>4)&0xf];
615 tstr
[(buf_len
-1-i
)*2+1] = DIGITS
[buf
[i
]&0xf];
620 void gdb_target_to_str(target_t
*target
, char *tstr
, char *str
)
622 int str_len
= strlen(tstr
);
627 ERROR("BUG: gdb value with uneven number of characters encountered");
631 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
633 for (i
= 0; i
< str_len
; i
+=2)
635 str
[str_len
- i
- 1] = tstr
[i
+ 1];
636 str
[str_len
- i
- 2] = tstr
[i
];
641 for (i
= 0; i
< str_len
; i
++)
648 int gdb_get_registers_packet(connection_t
*connection
, target_t
*target
, char* packet
, int packet_size
)
653 int reg_packet_size
= 0;
658 #ifdef _DEBUG_GDB_IO_
662 if ((retval
= target
->type
->get_gdb_reg_list(target
, ®_list
, ®_list_size
)) != ERROR_OK
)
666 case ERROR_TARGET_NOT_HALTED
:
667 ERROR("gdb requested registers but we're not halted, dropping connection");
668 return ERROR_SERVER_REMOTE_CLOSED
;
670 /* this is a bug condition - get_gdb_reg_list() may not return any other error */
671 ERROR("BUG: unexpected error returned by get_gdb_reg_list()");
676 for (i
= 0; i
< reg_list_size
; i
++)
678 reg_packet_size
+= reg_list
[i
]->size
;
681 reg_packet
= malloc(CEIL(reg_packet_size
, 8) * 2);
682 reg_packet_p
= reg_packet
;
684 for (i
= 0; i
< reg_list_size
; i
++)
686 gdb_str_to_target(target
, reg_packet_p
, reg_list
[i
]);
687 reg_packet_p
+= CEIL(reg_list
[i
]->size
, 8) * 2;
690 #ifdef _DEBUG_GDB_IO_
693 reg_packet_p
= strndup(reg_packet
, CEIL(reg_packet_size
, 8) * 2);
694 DEBUG("reg_packet: %s", reg_packet_p
);
699 gdb_put_packet(connection
, reg_packet
, CEIL(reg_packet_size
, 8) * 2);
707 int gdb_set_registers_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
715 #ifdef _DEBUG_GDB_IO_
719 /* skip command character */
725 WARNING("GDB set_registers packet with uneven characters received, dropping connection");
726 return ERROR_SERVER_REMOTE_CLOSED
;
729 if ((retval
= target
->type
->get_gdb_reg_list(target
, ®_list
, ®_list_size
)) != ERROR_OK
)
733 case ERROR_TARGET_NOT_HALTED
:
734 ERROR("gdb tried to registers but we're not halted, dropping connection");
735 return ERROR_SERVER_REMOTE_CLOSED
;
737 /* this is a bug condition - get_gdb_reg_list() may not return any other error */
738 ERROR("BUG: unexpected error returned by get_gdb_reg_list()");
744 for (i
= 0; i
< reg_list_size
; i
++)
748 reg_arch_type_t
*arch_type
;
750 /* convert from GDB-string (target-endian) to hex-string (big-endian) */
751 hex_buf
= malloc(CEIL(reg_list
[i
]->size
, 8) * 2);
752 gdb_target_to_str(target
, packet_p
, hex_buf
);
754 /* convert hex-string to binary buffer */
755 bin_buf
= malloc(CEIL(reg_list
[i
]->size
, 8));
756 str_to_buf(hex_buf
, CEIL(reg_list
[i
]->size
, 8) * 2, bin_buf
, reg_list
[i
]->size
, 16);
758 /* get register arch_type, and call set method */
759 arch_type
= register_get_arch_type(reg_list
[i
]->arch_type
);
760 if (arch_type
== NULL
)
762 ERROR("BUG: encountered unregistered arch type");
765 arch_type
->set(reg_list
[i
], bin_buf
);
767 /* advance packet pointer */
768 packet_p
+= (CEIL(reg_list
[i
]->size
, 8) * 2);
774 /* free reg_t *reg_list[] array allocated by get_gdb_reg_list */
777 gdb_put_packet(connection
, "OK", 2);
782 int gdb_get_register_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
785 int reg_num
= strtoul(packet
+ 1, NULL
, 16);
790 #ifdef _DEBUG_GDB_IO_
794 if ((retval
= target
->type
->get_gdb_reg_list(target
, ®_list
, ®_list_size
)) != ERROR_OK
)
798 case ERROR_TARGET_NOT_HALTED
:
799 ERROR("gdb requested registers but we're not halted, dropping connection");
800 return ERROR_SERVER_REMOTE_CLOSED
;
802 /* this is a bug condition - get_gdb_reg_list() may not return any other error */
803 ERROR("BUG: unexpected error returned by get_gdb_reg_list()");
808 if (reg_list_size
<= reg_num
)
810 ERROR("gdb requested a non-existing register");
814 reg_packet
= malloc(CEIL(reg_list
[reg_num
]->size
, 8) * 2);
816 gdb_str_to_target(target
, reg_packet
, reg_list
[reg_num
]);
818 gdb_put_packet(connection
, reg_packet
, CEIL(reg_list
[reg_num
]->size
, 8) * 2);
826 int gdb_set_register_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
831 int reg_num
= strtoul(packet
+ 1, &separator
, 16);
835 reg_arch_type_t
*arch_type
;
839 if ((retval
= target
->type
->get_gdb_reg_list(target
, ®_list
, ®_list_size
)) != ERROR_OK
)
843 case ERROR_TARGET_NOT_HALTED
:
844 ERROR("gdb tried to set a register but we're not halted, dropping connection");
845 return ERROR_SERVER_REMOTE_CLOSED
;
847 /* this is a bug condition - get_gdb_reg_list() may not return any other error */
848 ERROR("BUG: unexpected error returned by get_gdb_reg_list()");
853 if (reg_list_size
< reg_num
)
855 ERROR("gdb requested a non-existing register");
856 return ERROR_SERVER_REMOTE_CLOSED
;
859 if (*separator
!= '=')
861 ERROR("GDB 'set register packet', but no '=' following the register number");
862 return ERROR_SERVER_REMOTE_CLOSED
;
865 /* convert from GDB-string (target-endian) to hex-string (big-endian) */
866 hex_buf
= malloc(CEIL(reg_list
[reg_num
]->size
, 8) * 2);
867 gdb_target_to_str(target
, separator
+ 1, hex_buf
);
869 /* convert hex-string to binary buffer */
870 bin_buf
= malloc(CEIL(reg_list
[reg_num
]->size
, 8));
871 str_to_buf(hex_buf
, CEIL(reg_list
[reg_num
]->size
, 8) * 2, bin_buf
, reg_list
[reg_num
]->size
, 16);
873 /* get register arch_type, and call set method */
874 arch_type
= register_get_arch_type(reg_list
[reg_num
]->arch_type
);
875 if (arch_type
== NULL
)
877 ERROR("BUG: encountered unregistered arch type");
880 arch_type
->set(reg_list
[reg_num
], bin_buf
);
882 gdb_put_packet(connection
, "OK", 2);
891 int gdb_memory_packet_error(connection_t
*connection
, int retval
)
895 case ERROR_TARGET_NOT_HALTED
:
896 ERROR("gdb tried to read memory but we're not halted, dropping connection");
897 return ERROR_SERVER_REMOTE_CLOSED
;
899 case ERROR_TARGET_DATA_ABORT
:
900 gdb_send_error(connection
, EIO
);
902 case ERROR_TARGET_TRANSLATION_FAULT
:
903 gdb_send_error(connection
, EFAULT
);
905 case ERROR_TARGET_UNALIGNED_ACCESS
:
906 gdb_send_error(connection
, EFAULT
);
909 ERROR("BUG: unexpected error %i", retval
);
916 int gdb_read_memory_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
928 /* skip command character */
931 addr
= strtoul(packet
, &separator
, 16);
933 if (*separator
!= ',')
935 ERROR("incomplete read memory packet received, dropping connection");
936 return ERROR_SERVER_REMOTE_CLOSED
;
939 len
= strtoul(separator
+1, NULL
, 16);
941 buffer
= malloc(len
);
943 DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr
, len
);
949 retval
= target
->type
->read_memory(target
, addr
, 4, 1, buffer
);
951 retval
= target
->type
->read_memory(target
, addr
, 1, len
, buffer
);
955 retval
= target
->type
->read_memory(target
, addr
, 2, 1, buffer
);
957 retval
= target
->type
->read_memory(target
, addr
, 1, len
, buffer
);
960 if (((addr
% 4) == 0) && ((len
% 4) == 0))
961 retval
= target
->type
->read_memory(target
, addr
, 4, len
/ 4, buffer
);
963 retval
= target
->type
->read_memory(target
, addr
, 1, len
, buffer
);
967 if (retval
== ERROR_TARGET_DATA_ABORT
)
969 /* TODO : Here we have to lie and send back all zero's lest stack traces won't work.
970 * At some point this might be fixed in GDB, in which case this code can be removed.
971 * http://sourceware.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=2395
973 memset(buffer
, 0, len
);
978 if (retval
== ERROR_OK
)
980 hex_buffer
= malloc(len
* 2 + 1);
982 for (i
=0; i
<len
; i
++)
983 snprintf(hex_buffer
+ 2*i
, 3, "%2.2x", buffer
[i
]);
985 gdb_put_packet(connection
, hex_buffer
, len
* 2);
991 if ((retval
= gdb_memory_packet_error(connection
, retval
)) != ERROR_OK
)
1000 int gdb_write_memory_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
1011 /* skip command character */
1014 addr
= strtoul(packet
, &separator
, 16);
1016 if (*separator
!= ',')
1018 ERROR("incomplete write memory packet received, dropping connection");
1019 return ERROR_SERVER_REMOTE_CLOSED
;
1022 len
= strtoul(separator
+1, &separator
, 16);
1024 if (*(separator
++) != ':')
1026 ERROR("incomplete write memory packet received, dropping connection");
1027 return ERROR_SERVER_REMOTE_CLOSED
;
1030 buffer
= malloc(len
);
1032 DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr
, len
);
1034 for (i
=0; i
<len
; i
++)
1037 sscanf(separator
+ 2*i
, "%2x", &tmp
);
1044 /* handle sized writes */
1046 if ((addr
% 4) == 0)
1047 retval
= target
->type
->write_memory(target
, addr
, 4, 1, buffer
);
1049 retval
= target
->type
->write_memory(target
, addr
, 1, len
, buffer
);
1052 if ((addr
% 2) == 0)
1053 retval
= target
->type
->write_memory(target
, addr
, 2, 1, buffer
);
1055 retval
= target
->type
->write_memory(target
, addr
, 1, len
, buffer
);
1059 retval
= target
->type
->write_memory(target
, addr
, 1, len
, buffer
);
1061 /* handle bulk writes */
1063 retval
= target_write_buffer(target
, addr
, len
, buffer
);
1067 if (retval
== ERROR_OK
)
1069 gdb_put_packet(connection
, "OK", 2);
1073 if ((retval
= gdb_memory_packet_error(connection
, retval
)) != ERROR_OK
)
1082 int gdb_write_memory_binary_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
1091 /* skip command character */
1094 addr
= strtoul(packet
, &separator
, 16);
1096 if (*separator
!= ',')
1098 ERROR("incomplete write memory binary packet received, dropping connection");
1099 return ERROR_SERVER_REMOTE_CLOSED
;
1102 len
= strtoul(separator
+1, &separator
, 16);
1104 if (*(separator
++) != ':')
1106 ERROR("incomplete write memory binary packet received, dropping connection");
1107 return ERROR_SERVER_REMOTE_CLOSED
;
1113 buffer
= malloc(len
);
1115 DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr
, len
);
1117 memcpy( buffer
, separator
, len
);
1122 if ((addr
% 4) == 0)
1123 retval
= target
->type
->write_memory(target
, addr
, 4, 1, buffer
);
1125 retval
= target
->type
->write_memory(target
, addr
, 1, len
, buffer
);
1128 if ((addr
% 2) == 0)
1129 retval
= target
->type
->write_memory(target
, addr
, 2, 1, buffer
);
1131 retval
= target
->type
->write_memory(target
, addr
, 1, len
, buffer
);
1135 retval
= target
->type
->write_memory(target
, addr
, 1, len
, buffer
);
1138 retval
= target_write_buffer(target
, addr
, len
, buffer
);
1145 if (retval
== ERROR_OK
)
1147 gdb_put_packet(connection
, "OK", 2);
1151 if ((retval
= gdb_memory_packet_error(connection
, retval
)) != ERROR_OK
)
1158 void gdb_step_continue_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
1165 if (packet_size
> 1)
1167 packet
[packet_size
] = 0;
1168 address
= strtoul(packet
+ 1, NULL
, 16);
1175 if (packet
[0] == 'c')
1178 target
->type
->resume(target
, current
, address
, 0, 0); /* resume at current address, don't handle breakpoints, not debugging */
1180 else if (packet
[0] == 's')
1183 target
->type
->step(target
, current
, address
, 0); /* step at current or address, don't handle breakpoints */
1187 int gdb_bp_wp_packet_error(connection_t
*connection
, int retval
)
1191 case ERROR_TARGET_NOT_HALTED
:
1192 ERROR("gdb tried to set a breakpoint but we're not halted, dropping connection");
1193 return ERROR_SERVER_REMOTE_CLOSED
;
1195 case ERROR_TARGET_RESOURCE_NOT_AVAILABLE
:
1196 gdb_send_error(connection
, EBUSY
);
1199 ERROR("BUG: unexpected error %i", retval
);
1206 int gdb_breakpoint_watchpoint_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
1209 enum breakpoint_type bp_type
= BKPT_SOFT
/* dummy init to avoid warning */;
1210 enum watchpoint_rw wp_type
;
1218 type
= strtoul(packet
+ 1, &separator
, 16);
1220 if (type
== 0) /* memory breakpoint */
1221 bp_type
= BKPT_SOFT
;
1222 else if (type
== 1) /* hardware breakpoint */
1223 bp_type
= BKPT_HARD
;
1224 else if (type
== 2) /* write watchpoint */
1225 wp_type
= WPT_WRITE
;
1226 else if (type
== 3) /* read watchpoint */
1228 else if (type
== 4) /* access watchpoint */
1229 wp_type
= WPT_ACCESS
;
1231 if (*separator
!= ',')
1233 ERROR("incomplete breakpoint/watchpoint packet received, dropping connection");
1234 return ERROR_SERVER_REMOTE_CLOSED
;
1237 address
= strtoul(separator
+1, &separator
, 16);
1239 if (*separator
!= ',')
1241 ERROR("incomplete breakpoint/watchpoint packet received, dropping connection");
1242 return ERROR_SERVER_REMOTE_CLOSED
;
1245 size
= strtoul(separator
+1, &separator
, 16);
1251 if (packet
[0] == 'Z')
1253 if ((retval
= breakpoint_add(target
, address
, size
, bp_type
)) != ERROR_OK
)
1255 if ((retval
= gdb_bp_wp_packet_error(connection
, retval
)) != ERROR_OK
)
1260 gdb_put_packet(connection
, "OK", 2);
1265 breakpoint_remove(target
, address
);
1266 gdb_put_packet(connection
, "OK", 2);
1273 if (packet
[0] == 'Z')
1275 if ((retval
= watchpoint_add(target
, address
, size
, type
-2, 0, 0xffffffffu
)) != ERROR_OK
)
1277 if ((retval
= gdb_bp_wp_packet_error(connection
, retval
)) != ERROR_OK
)
1282 gdb_put_packet(connection
, "OK", 2);
1287 watchpoint_remove(target
, address
);
1288 gdb_put_packet(connection
, "OK", 2);
1299 /* print out a string and allocate more space as needed, mainly used for XML at this point */
1300 void xml_printf(int *retval
, char **xml
, int *pos
, int *size
, const char *fmt
, ...)
1302 if (*retval
!= ERROR_OK
)
1310 if ((*xml
== NULL
) || (!first
))
1312 /* start by 0 to exercise all the code paths.
1313 * Need minimum 2 bytes to fit 1 char and 0 terminator. */
1315 *size
= *size
* 2 + 2;
1317 *xml
= realloc(*xml
, *size
);
1322 *retval
= ERROR_SERVER_REMOTE_CLOSED
;
1330 ret
= vsnprintf(*xml
+ *pos
, *size
- *pos
, fmt
, ap
);
1332 if ((ret
> 0) && ((ret
+ 1) < *size
- *pos
))
1337 /* there was just enough or not enough space, allocate more. */
1342 static int decode_xfer_read (char *buf
, char **annex
, int *ofs
, unsigned int *len
)
1346 /* Extract and NUL-terminate the annex. */
1348 while (*buf
&& *buf
!= ':')
1354 /* After the read marker and annex, qXfer looks like a
1355 * traditional 'm' packet. */
1357 *ofs
= strtoul(buf
, &separator
, 16);
1359 if (*separator
!= ',')
1362 *len
= strtoul(separator
+1, NULL
, 16);
1367 int gdb_calc_blocksize(flash_bank_t
*bank
)
1370 int block_size
= 0xffffffff;
1372 /* loop through all sectors and return smallest sector size */
1374 for (i
= 0; i
< bank
->num_sectors
; i
++)
1376 if (bank
->sectors
[i
].size
< block_size
)
1377 block_size
= bank
->sectors
[i
].size
;
1383 int gdb_query_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
1385 command_context_t
*cmd_ctx
= connection
->cmd_ctx
;
1387 if (strstr(packet
, "qRcmd,"))
1389 if (packet_size
> 6)
1393 cmd
= malloc((packet_size
- 6)/2 + 1);
1394 for (i
=0; i
< (packet_size
- 6)/2; i
++)
1397 sscanf(packet
+ 6 + 2*i
, "%2x", &tmp
);
1400 cmd
[(packet_size
- 6)/2] = 0x0;
1401 target_call_timer_callbacks();
1402 command_run_line(cmd_ctx
, cmd
);
1405 gdb_put_packet(connection
, "OK", 2);
1408 else if (strstr(packet
, "qCRC:"))
1410 if (packet_size
> 5)
1419 /* skip command character */
1422 addr
= strtoul(packet
, &separator
, 16);
1424 if (*separator
!= ',')
1426 ERROR("incomplete read memory packet received, dropping connection");
1427 return ERROR_SERVER_REMOTE_CLOSED
;
1430 len
= strtoul(separator
+ 1, NULL
, 16);
1432 retval
= target_checksum_memory(target
, addr
, len
, &checksum
);
1434 if (retval
== ERROR_OK
)
1436 snprintf(gdb_reply
, 10, "C%8.8x", checksum
);
1437 gdb_put_packet(connection
, gdb_reply
, 9);
1441 if ((retval
= gdb_memory_packet_error(connection
, retval
)) != ERROR_OK
)
1448 else if (strstr(packet
, "qSupported"))
1450 /* we currently support packet size and qXfer:memory-map:read (if enabled)
1451 * disable qXfer:features:read for the moment */
1452 int retval
= ERROR_OK
;
1453 char *buffer
= NULL
;
1457 xml_printf(&retval
, &buffer
, &pos
, &size
,
1458 "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-",
1459 (GDB_BUFFER_SIZE
- 1), gdb_use_memory_map
== 1 ? '+' : '-');
1461 if (retval
!= ERROR_OK
)
1463 gdb_send_error(connection
, 01);
1467 gdb_put_packet(connection
, buffer
, strlen(buffer
));
1472 else if (strstr(packet
, "qXfer:memory-map:read::"))
1474 /* We get away with only specifying flash here. Regions that are not
1475 * specified are treated as if we provided no memory map(if not we
1476 * could detect the holes and mark them as RAM).
1477 * Normally we only execute this code once, but no big deal if we
1478 * have to regenerate it a couple of times. */
1484 int retval
= ERROR_OK
;
1491 /* skip command character */
1494 offset
= strtoul(packet
, &separator
, 16);
1495 length
= strtoul(separator
+ 1, &separator
, 16);
1497 xml_printf(&retval
, &xml
, &pos
, &size
, "<memory-map>\n");
1502 p
= get_flash_bank_by_num(i
);
1506 /* if device has uneven sector sizes, eg. str7, lpc
1507 * we pass the smallest sector size to gdb memory map */
1508 blocksize
= gdb_calc_blocksize(p
);
1510 xml_printf(&retval
, &xml
, &pos
, &size
, "<memory type=\"flash\" start=\"0x%x\" length=\"0x%x\">\n" \
1511 "<property name=\"blocksize\">0x%x</property>\n" \
1513 p
->base
, p
->size
, blocksize
);
1517 xml_printf(&retval
, &xml
, &pos
, &size
, "</memory-map>\n");
1519 if (retval
!= ERROR_OK
)
1521 gdb_send_error(connection
, retval
);
1525 if (offset
+ length
> pos
)
1527 length
= pos
- offset
;
1530 char *t
= malloc(length
+ 1);
1532 memcpy(t
+ 1, xml
+ offset
, length
);
1533 gdb_put_packet(connection
, t
, length
+ 1);
1539 else if (strstr(packet
, "qXfer:features:read:"))
1544 int retval
= ERROR_OK
;
1550 /* skip command character */
1553 if (decode_xfer_read( packet
, &annex
, &offset
, &length
) < 0)
1555 gdb_send_error(connection
, 01);
1559 if (strcmp(annex
, "target.xml") != 0)
1561 gdb_send_error(connection
, 01);
1565 xml_printf(&retval
, &xml
, &pos
, &size
, \
1566 "l<target version=\"1.0\">\n<architecture>arm</architecture>\n</target>\n");
1568 if (retval
!= ERROR_OK
)
1570 gdb_send_error(connection
, retval
);
1574 gdb_put_packet(connection
, xml
, strlen(xml
) + 1);
1580 gdb_put_packet(connection
, "", 0);
1584 int gdb_v_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
1586 gdb_connection_t
*gdb_connection
= connection
->priv
;
1587 gdb_service_t
*gdb_service
= connection
->service
->priv
;
1590 /* if flash programming disabled - send a empty reply */
1592 if (gdb_flash_program
== 0)
1594 gdb_put_packet(connection
, "", 0);
1598 if (strstr(packet
, "vFlashErase:"))
1601 unsigned long length
;
1603 char *parse
= packet
+ 12;
1606 ERROR("incomplete vFlashErase packet received, dropping connection");
1607 return ERROR_SERVER_REMOTE_CLOSED
;
1610 addr
= strtoul(parse
, &parse
, 16);
1612 if (*(parse
++) != ',' || *parse
== '\0')
1614 ERROR("incomplete vFlashErase packet received, dropping connection");
1615 return ERROR_SERVER_REMOTE_CLOSED
;
1618 length
= strtoul(parse
, &parse
, 16);
1622 ERROR("incomplete vFlashErase packet received, dropping connection");
1623 return ERROR_SERVER_REMOTE_CLOSED
;
1626 /* disable gdb output while programming */
1627 gdb_connection
->output_disable
= 1;
1629 /* assume all sectors need erasing - stops any problems
1630 * when flash_write is called multiple times */
1633 /* perform any target specific operations before the erase */
1634 target_call_event_callbacks(gdb_service
->target
, TARGET_EVENT_GDB_PROGRAM
);
1637 if ((result
= flash_erase_address_range(gdb_service
->target
, addr
, length
)) != ERROR_OK
)
1639 /* GDB doesn't evaluate the actual error number returned,
1640 * treat a failed erase as an I/O error
1642 gdb_send_error(connection
, EIO
);
1643 ERROR("flash_erase returned %i", result
);
1646 gdb_put_packet(connection
, "OK", 2);
1648 /* reenable gdb output */
1649 gdb_connection
->output_disable
= 0;
1654 if (strstr(packet
, "vFlashWrite:"))
1657 unsigned long length
;
1658 char *parse
= packet
+ 12;
1662 ERROR("incomplete vFlashErase packet received, dropping connection");
1663 return ERROR_SERVER_REMOTE_CLOSED
;
1665 addr
= strtoul(parse
, &parse
, 16);
1666 if (*(parse
++) != ':')
1668 ERROR("incomplete vFlashErase packet received, dropping connection");
1669 return ERROR_SERVER_REMOTE_CLOSED
;
1671 length
= packet_size
- (parse
- packet
);
1673 /* disable gdb output while programming */
1674 gdb_connection
->output_disable
= 1;
1676 /* create a new image if there isn't already one */
1677 if (gdb_connection
->vflash_image
== NULL
)
1679 gdb_connection
->vflash_image
= malloc(sizeof(image_t
));
1680 image_open(gdb_connection
->vflash_image
, "", "build");
1683 /* create new section with content from packet buffer */
1684 image_add_section(gdb_connection
->vflash_image
, addr
, length
, 0x0, (u8
*)parse
);
1686 gdb_put_packet(connection
, "OK", 2);
1688 /* reenable gdb output */
1689 gdb_connection
->output_disable
= 0;
1694 if (!strcmp(packet
, "vFlashDone"))
1699 /* disable gdb output while programming */
1700 gdb_connection
->output_disable
= 1;
1702 /* process the flashing buffer. No need to erase as GDB
1703 * always issues a vFlashErase first. */
1704 if ((result
= flash_write(gdb_service
->target
, gdb_connection
->vflash_image
, &written
, &error_str
, NULL
, 0)) != ERROR_OK
)
1706 if (result
== ERROR_FLASH_DST_OUT_OF_BANK
)
1707 gdb_put_packet(connection
, "E.memtype", 9);
1709 gdb_send_error(connection
, EIO
);
1713 ERROR("flash writing failed: %s", error_str
);
1719 DEBUG("wrote %u bytes from vFlash image to flash", written
);
1720 gdb_put_packet(connection
, "OK", 2);
1723 image_close(gdb_connection
->vflash_image
);
1724 free(gdb_connection
->vflash_image
);
1725 gdb_connection
->vflash_image
= NULL
;
1727 /* reenable gdb output */
1728 gdb_connection
->output_disable
= 0;
1733 gdb_put_packet(connection
, "", 0);
1737 int gdb_detach(connection_t
*connection
, target_t
*target
)
1739 switch( detach_mode
)
1741 case GDB_DETACH_RESUME
:
1742 target
->type
->resume(target
, 1, 0, 1, 0);
1745 case GDB_DETACH_RESET
:
1746 target_process_reset(connection
->cmd_ctx
);
1749 case GDB_DETACH_HALT
:
1750 target
->type
->halt(target
);
1753 case GDB_DETACH_NOTHING
:
1757 gdb_put_packet(connection
, "OK", 2);
1762 int gdb_input(connection_t
*connection
)
1764 gdb_service_t
*gdb_service
= connection
->service
->priv
;
1765 target_t
*target
= gdb_service
->target
;
1766 char packet
[GDB_BUFFER_SIZE
];
1769 gdb_connection_t
*gdb_con
= connection
->priv
;
1770 static int extended_protocol
= 0;
1772 /* drain input buffer */
1775 packet_size
= GDB_BUFFER_SIZE
-1;
1776 if ((retval
= gdb_get_packet(connection
, packet
, &packet_size
)) != ERROR_OK
)
1780 case ERROR_GDB_BUFFER_TOO_SMALL
:
1781 ERROR("BUG: buffer supplied for gdb packet was too small");
1783 case ERROR_SERVER_REMOTE_CLOSED
:
1784 return ERROR_SERVER_REMOTE_CLOSED
;
1786 ERROR("BUG: unexpected error");
1791 /* terminate with zero */
1792 packet
[packet_size
] = 0;
1794 DEBUG("received packet: '%s'", packet
);
1796 if (packet_size
> 0)
1802 /* Hct... -- set thread
1803 * we don't have threads, send empty reply */
1804 gdb_put_packet(connection
, NULL
, 0);
1807 retval
= gdb_query_packet(connection
, target
, packet
, packet_size
);
1810 retval
= gdb_get_registers_packet(connection
, target
, packet
, packet_size
);
1813 retval
= gdb_set_registers_packet(connection
, target
, packet
, packet_size
);
1816 retval
= gdb_get_register_packet(connection
, target
, packet
, packet_size
);
1819 retval
= gdb_set_register_packet(connection
, target
, packet
, packet_size
);
1822 retval
= gdb_read_memory_packet(connection
, target
, packet
, packet_size
);
1825 retval
= gdb_write_memory_packet(connection
, target
, packet
, packet_size
);
1829 retval
= gdb_breakpoint_watchpoint_packet(connection
, target
, packet
, packet_size
);
1832 gdb_last_signal_packet(connection
, target
, packet
, packet_size
);
1836 gdb_step_continue_packet(connection
, target
, packet
, packet_size
);
1839 retval
= gdb_v_packet(connection
, target
, packet
, packet_size
);
1842 retval
= gdb_detach(connection
, target
);
1843 extended_protocol
= 0;
1846 if ((retval
= gdb_write_memory_binary_packet(connection
, target
, packet
, packet_size
)) != ERROR_OK
)
1850 if (extended_protocol
!= 0)
1852 gdb_put_packet(connection
, "OK", 2);
1853 return ERROR_SERVER_REMOTE_CLOSED
;
1855 /* handle extended remote protocol */
1856 extended_protocol
= 1;
1857 gdb_put_packet(connection
, "OK", 2);
1860 /* handle extended restart packet */
1861 target_process_reset(connection
->cmd_ctx
);
1864 /* ignore unkown packets */
1865 DEBUG("ignoring 0x%2.2x packet", packet
[0]);
1866 gdb_put_packet(connection
, NULL
, 0);
1870 /* if a packet handler returned an error, exit input loop */
1871 if (retval
!= ERROR_OK
)
1875 if (gdb_con
->ctrl_c
)
1877 if (target
->state
== TARGET_RUNNING
)
1879 target
->type
->halt(target
);
1880 gdb_con
->ctrl_c
= 0;
1884 } while (gdb_con
->buf_cnt
> 0);
1891 gdb_service_t
*gdb_service
;
1892 target_t
*target
= targets
;
1897 WARNING("no gdb ports allocated as no target has been specified");
1903 WARNING("no gdb port specified, using default port 3333");
1909 char service_name
[8];
1911 snprintf(service_name
, 8, "gdb-%2.2i", i
);
1913 gdb_service
= malloc(sizeof(gdb_service_t
));
1914 gdb_service
->target
= target
;
1916 add_service("gdb", CONNECTION_GDB
, gdb_port
+ i
, 1, gdb_new_connection
, gdb_input
, gdb_connection_closed
, gdb_service
);
1918 DEBUG("gdb service for target %s at port %i", target
->type
->name
, gdb_port
+ i
);
1921 target
= target
->next
;
1927 /* daemon configuration command gdb_port */
1928 int handle_gdb_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1933 /* only if the port wasn't overwritten by cmdline */
1935 gdb_port
= strtoul(args
[0], NULL
, 0);
1940 int handle_gdb_detach_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1944 if (strcmp(args
[0], "resume") == 0)
1946 detach_mode
= GDB_DETACH_RESUME
;
1949 else if (strcmp(args
[0], "reset") == 0)
1951 detach_mode
= GDB_DETACH_RESET
;
1954 else if (strcmp(args
[0], "halt") == 0)
1956 detach_mode
= GDB_DETACH_HALT
;
1959 else if (strcmp(args
[0], "nothing") == 0)
1961 detach_mode
= GDB_DETACH_NOTHING
;
1966 WARNING("invalid gdb_detach configuration directive: %s", args
[0]);
1970 int handle_gdb_memory_map_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1974 if (strcmp(args
[0], "enable") == 0)
1976 gdb_use_memory_map
= 1;
1979 else if (strcmp(args
[0], "disable") == 0)
1981 gdb_use_memory_map
= 0;
1986 WARNING("invalid gdb_memory_map configuration directive: %s", args
[0]);
1990 int handle_gdb_flash_program_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1994 if (strcmp(args
[0], "enable") == 0)
1996 gdb_flash_program
= 1;
1999 else if (strcmp(args
[0], "disable") == 0)
2001 gdb_flash_program
= 0;
2006 WARNING("invalid gdb_memory_map configuration directive: %s", args
[0]);
2010 int gdb_register_commands(command_context_t
*command_context
)
2012 register_command(command_context
, NULL
, "gdb_port", handle_gdb_port_command
,
2013 COMMAND_CONFIG
, "");
2014 register_command(command_context
, NULL
, "gdb_detach", handle_gdb_detach_command
,
2015 COMMAND_CONFIG
, "");
2016 register_command(command_context
, NULL
, "gdb_memory_map", handle_gdb_memory_map_command
,
2017 COMMAND_CONFIG
, "");
2018 register_command(command_context
, NULL
, "gdb_flash_program", handle_gdb_flash_program_command
,
2019 COMMAND_CONFIG
, "");
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)