657338ea7405e395639a207a8a5e7fb71743a1f8
[openocd.git] / src / server / gdb_server.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "replacements.h"
25
26 #include "gdb_server.h"
27
28 #include "server.h"
29 #include "log.h"
30 #include "binarybuffer.h"
31 #include "breakpoints.h"
32 #include "flash.h"
33 #include "target_request.h"
34
35 #define __USE_GNU
36 #include <string.h>
37 #include <errno.h>
38 #include <unistd.h>
39 #include <stdlib.h>
40
41 #if 0
42 #define _DEBUG_GDB_IO_
43 #endif
44
45 static unsigned short gdb_port;
46
47 enum gdb_detach_mode
48 {
49 GDB_DETACH_RESUME,
50 GDB_DETACH_RESET,
51 GDB_DETACH_HALT,
52 GDB_DETACH_NOTHING
53 };
54
55 enum gdb_detach_mode detach_mode = GDB_DETACH_RESUME;
56
57 int gdb_last_signal(target_t *target)
58 {
59 switch (target->debug_reason)
60 {
61 case DBG_REASON_DBGRQ:
62 return 0x2; /* SIGINT */
63 case DBG_REASON_BREAKPOINT:
64 case DBG_REASON_WATCHPOINT:
65 case DBG_REASON_WPTANDBKPT:
66 return 0x05; /* SIGTRAP */
67 case DBG_REASON_SINGLESTEP:
68 return 0x05; /* SIGTRAP */
69 case DBG_REASON_NOTHALTED:
70 return 0x0; /* no signal... shouldn't happen */
71 default:
72 ERROR("BUG: undefined debug reason");
73 exit(-1);
74 }
75 }
76
77 int gdb_get_char(connection_t *connection, int* next_char)
78 {
79 gdb_connection_t *gdb_con = connection->priv;
80 char *debug_buffer;
81
82 if (gdb_con->buf_cnt-- > 0)
83 {
84 *next_char = *(gdb_con->buf_p++);
85 if (gdb_con->buf_cnt > 0)
86 connection->input_pending = 1;
87 else
88 connection->input_pending = 0;
89
90 #ifdef _DEBUG_GDB_IO_
91 DEBUG("returned char '%c' (0x%2.2x)", *next_char, *next_char);
92 #endif
93
94 return ERROR_OK;
95 }
96
97 while ((gdb_con->buf_cnt = read_socket(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE)) <= 0)
98 {
99 if (gdb_con->buf_cnt == 0)
100 return ERROR_SERVER_REMOTE_CLOSED;
101
102 #ifdef _WIN32
103 errno = WSAGetLastError();
104
105 switch(errno)
106 {
107 case WSAEWOULDBLOCK:
108 usleep(1000);
109 break;
110 case WSAECONNABORTED:
111 return ERROR_SERVER_REMOTE_CLOSED;
112 default:
113 ERROR("read: %d", errno);
114 exit(-1);
115 }
116 #else
117 switch(errno)
118 {
119 case EAGAIN:
120 usleep(1000);
121 break;
122 case ECONNABORTED:
123 return ERROR_SERVER_REMOTE_CLOSED;
124 case ECONNRESET:
125 return ERROR_SERVER_REMOTE_CLOSED;
126 default:
127 ERROR("read: %s", strerror(errno));
128 exit(-1);
129 }
130 #endif
131 }
132
133 debug_buffer = malloc(gdb_con->buf_cnt + 1);
134 memcpy(debug_buffer, gdb_con->buffer, gdb_con->buf_cnt);
135 debug_buffer[gdb_con->buf_cnt] = 0;
136 DEBUG("received '%s'", debug_buffer);
137 free(debug_buffer);
138
139 gdb_con->buf_p = gdb_con->buffer;
140 gdb_con->buf_cnt--;
141 *next_char = *(gdb_con->buf_p++);
142 if (gdb_con->buf_cnt > 0)
143 connection->input_pending = 1;
144 else
145 connection->input_pending = 0;
146 #ifdef _DEBUG_GDB_IO_
147 DEBUG("returned char '%c' (0x%2.2x)", *next_char, *next_char);
148 #endif
149
150 return ERROR_OK;
151 }
152
153 int gdb_putback_char(connection_t *connection, int last_char)
154 {
155 gdb_connection_t *gdb_con = connection->priv;
156
157 if (gdb_con->buf_p > gdb_con->buffer)
158 {
159 *(--gdb_con->buf_p) = last_char;
160 gdb_con->buf_cnt++;
161 }
162 else
163 {
164 ERROR("BUG: couldn't put character back");
165 }
166
167 return ERROR_OK;
168 }
169
170 int gdb_put_packet(connection_t *connection, char *buffer, int len)
171 {
172 int i;
173 unsigned char my_checksum = 0;
174 char checksum[3];
175 char *debug_buffer;
176 int reply;
177 int retval;
178 gdb_connection_t *gdb_con = connection->priv;
179
180 for (i = 0; i < len; i++)
181 my_checksum += buffer[i];
182
183 while (1)
184 {
185 debug_buffer = malloc(len + 1);
186 memcpy(debug_buffer, buffer, len);
187 debug_buffer[len] = 0;
188 DEBUG("sending packet '$%s#%2.2x'", debug_buffer, my_checksum);
189 free(debug_buffer);
190
191 write_socket(connection->fd, "$", 1);
192 if (len > 0)
193 write_socket(connection->fd, buffer, len);
194 write_socket(connection->fd, "#", 1);
195
196 snprintf(checksum, 3, "%2.2x", my_checksum);
197
198 write_socket(connection->fd, checksum, 2);
199
200 if ((retval = gdb_get_char(connection, &reply)) != ERROR_OK)
201 return retval;
202
203 if (reply == '+')
204 break;
205 else if (reply == '-')
206 WARNING("negative reply, retrying");
207 else if (reply == 0x3)
208 {
209 gdb_con->ctrl_c = 1;
210 if ((retval = gdb_get_char(connection, &reply)) != ERROR_OK)
211 return retval;
212 if (reply == '+')
213 break;
214 else if (reply == '-')
215 WARNING("negative reply, retrying");
216 else
217 {
218 ERROR("unknown character 0x%2.2x in reply, dropping connection", reply);
219 return ERROR_SERVER_REMOTE_CLOSED;
220 }
221 }
222 else
223 {
224 ERROR("unknown character 0x%2.2x in reply, dropping connection", reply);
225 return ERROR_SERVER_REMOTE_CLOSED;
226 }
227 }
228
229 return ERROR_OK;
230 }
231
232 int gdb_get_packet(connection_t *connection, char *buffer, int *len)
233 {
234 int character;
235 int count = 0;
236 int retval;
237 char checksum[3];
238 unsigned char my_checksum = 0;
239 gdb_connection_t *gdb_con = connection->priv;
240
241 while (1)
242 {
243 do
244 {
245 if ((retval = gdb_get_char(connection, &character)) != ERROR_OK)
246 return retval;
247
248 DEBUG("character: '%c'", character);
249
250 switch (character)
251 {
252 case '$':
253 break;
254 case '+':
255 WARNING("acknowledgment received, but no packet pending");
256 break;
257 case '-':
258 WARNING("negative acknowledgment, but no packet pending");
259 break;
260 case 0x3:
261 gdb_con->ctrl_c = 1;
262 *len = 0;
263 return ERROR_OK;
264 default:
265 WARNING("ignoring character 0x%x", character);
266 break;
267 }
268 } while (character != '$');
269
270 my_checksum = 0;
271
272 do
273 {
274 if ((retval = gdb_get_char(connection, &character)) != ERROR_OK)
275 return retval;
276
277 if (character == '#') break;
278
279 if (character == '}')
280 {
281 /* data transmitted in binary mode (X packet)
282 * uses 0x7d as escape character */
283 my_checksum += character & 0xff;
284 if ((retval = gdb_get_char(connection, &character)) != ERROR_OK)
285 return retval;
286 my_checksum += character & 0xff;
287 buffer[count++] = (character ^ 0x20) & 0xff;
288 }
289 else
290 {
291 my_checksum += character & 0xff;
292 buffer[count++] = character & 0xff;
293 }
294
295 if (count > *len)
296 {
297 ERROR("packet buffer too small");
298 return ERROR_GDB_BUFFER_TOO_SMALL;
299 }
300 } while (1);
301
302 *len = count;
303
304 if ((retval = gdb_get_char(connection, &character)) != ERROR_OK)
305 return retval;
306 checksum[0] = character;
307 if ((retval = gdb_get_char(connection, &character)) != ERROR_OK)
308 return retval;
309 checksum[1] = character;
310 checksum[2] = 0;
311
312 if (my_checksum == strtoul(checksum, NULL, 16))
313 {
314 write_socket(connection->fd, "+", 1);
315 break;
316 }
317
318 WARNING("checksum error, requesting retransmission");
319 write_socket(connection->fd, "-", 1);
320 }
321
322 return ERROR_OK;
323 }
324
325 int gdb_output(struct command_context_s *context, char* line)
326 {
327 connection_t *connection = context->output_handler_priv;
328 char *hex_buffer;
329 int i, bin_size;
330
331 bin_size = strlen(line);
332
333 hex_buffer = malloc(bin_size*2 + 4);
334
335 hex_buffer[0] = 'O';
336 for (i=0; i<bin_size; i++)
337 snprintf(hex_buffer + 1 + i*2, 3, "%2.2x", line[i]);
338 hex_buffer[bin_size*2+1] = '0';
339 hex_buffer[bin_size*2+2] = 'a';
340 hex_buffer[bin_size*2+3] = 0x0;
341
342 gdb_put_packet(connection, hex_buffer, bin_size*2 + 3);
343
344 free(hex_buffer);
345 return ERROR_OK;
346 }
347
348 int gdb_target_callback_event_handler(struct target_s *target, enum target_event event, void *priv)
349 {
350 connection_t *connection = priv;
351 gdb_connection_t *gdb_connection = connection->priv;
352 char sig_reply[4];
353 int signal;
354
355 switch (event)
356 {
357 case TARGET_EVENT_HALTED:
358 if (gdb_connection->frontend_state == TARGET_RUNNING)
359 {
360 if (gdb_connection->ctrl_c)
361 {
362 signal = 0x2;
363 gdb_connection->ctrl_c = 0;
364 }
365 else
366 {
367 signal = gdb_last_signal(target);
368 }
369
370 snprintf(sig_reply, 4, "T%2.2x", signal);
371 gdb_put_packet(connection, sig_reply, 3);
372 gdb_connection->frontend_state = TARGET_HALTED;
373 }
374 break;
375 case TARGET_EVENT_RESUMED:
376 if (gdb_connection->frontend_state == TARGET_HALTED)
377 {
378 gdb_connection->frontend_state = TARGET_RUNNING;
379 }
380 break;
381 default:
382 break;
383 }
384
385 return ERROR_OK;
386 }
387
388 int gdb_new_connection(connection_t *connection)
389 {
390 gdb_connection_t *gdb_connection = malloc(sizeof(gdb_connection_t));
391 gdb_service_t *gdb_service = connection->service->priv;
392 int retval;
393 int initial_ack;
394
395 connection->priv = gdb_connection;
396
397 /* initialize gdb connection information */
398 gdb_connection->buf_p = gdb_connection->buffer;
399 gdb_connection->buf_cnt = 0;
400 gdb_connection->ctrl_c = 0;
401 gdb_connection->frontend_state = TARGET_HALTED;
402 gdb_connection->vflash_image = NULL;
403
404 /* output goes through gdb connection */
405 command_set_output_handler(connection->cmd_ctx, gdb_output, connection);
406
407 /* register callback to be informed about target events */
408 target_register_event_callback(gdb_target_callback_event_handler, connection);
409
410 /* a gdb session just attached, put the target in halt mode */
411 if (((retval = gdb_service->target->type->halt(gdb_service->target)) != ERROR_OK) &&
412 (retval != ERROR_TARGET_ALREADY_HALTED))
413 {
414 ERROR("error when trying to halt target");
415 exit(-1);
416 }
417
418 while (gdb_service->target->state != TARGET_HALTED)
419 {
420 gdb_service->target->type->poll(gdb_service->target);
421 }
422
423 /* remove the initial ACK from the incoming buffer */
424 if ((retval = gdb_get_char(connection, &initial_ack)) != ERROR_OK)
425 return retval;
426
427 if (initial_ack != '+')
428 gdb_putback_char(connection, initial_ack);
429
430 return ERROR_OK;
431 }
432
433 int gdb_connection_closed(connection_t *connection)
434 {
435 gdb_service_t *gdb_service = connection->service->priv;
436 gdb_connection_t *gdb_connection = connection->priv;
437
438 /* see if an image built with vFlash commands is left */
439 if (gdb_connection->vflash_image)
440 {
441 image_close(gdb_connection->vflash_image);
442 free(gdb_connection->vflash_image);
443 gdb_connection->vflash_image = NULL;
444 }
445
446 /* if this connection registered a debug-message receiver delete it */
447 delete_debug_msg_receiver(connection->cmd_ctx, gdb_service->target);
448
449 if (connection->priv)
450 free(connection->priv);
451 else
452 ERROR("BUG: connection->priv == NULL");
453
454 target_unregister_event_callback(gdb_target_callback_event_handler, connection);
455
456 return ERROR_OK;
457 }
458
459 void gdb_send_error(connection_t *connection, u8 the_error)
460 {
461 char err[4];
462 snprintf(err, 4, "E%2.2X", the_error );
463 gdb_put_packet(connection, err, 3);
464 }
465
466 int gdb_last_signal_packet(connection_t *connection, target_t *target, char* packet, int packet_size)
467 {
468 char sig_reply[4];
469 int signal;
470
471 signal = gdb_last_signal(target);
472
473 snprintf(sig_reply, 4, "S%2.2x", signal);
474 gdb_put_packet(connection, sig_reply, 3);
475
476 return ERROR_OK;
477 }
478
479 void gdb_str_to_target(target_t *target, char *str, char *tstr)
480 {
481 int str_len = strlen(str);
482 int i;
483
484 if (str_len % 2)
485 {
486 ERROR("BUG: gdb value with uneven number of characters encountered: %s", str);
487 exit(-1);
488 }
489
490 if (target->endianness == TARGET_LITTLE_ENDIAN)
491 {
492 for (i = 0; i < str_len; i+=2)
493 {
494 tstr[str_len - i - 1] = str[i + 1];
495 tstr[str_len - i - 2] = str[i];
496 }
497 }
498 else
499 {
500 for (i = 0; i < str_len; i++)
501 {
502 tstr[i] = str[i];
503 }
504 }
505 }
506
507 void gdb_target_to_str(target_t *target, char *tstr, char *str)
508 {
509 int str_len = strlen(tstr);
510 int i;
511
512 if (str_len % 2)
513 {
514 ERROR("BUG: gdb value with uneven number of characters encountered");
515 exit(-1);
516 }
517
518 if (target->endianness == TARGET_LITTLE_ENDIAN)
519 {
520 for (i = 0; i < str_len; i+=2)
521 {
522 str[str_len - i - 1] = tstr[i + 1];
523 str[str_len - i - 2] = tstr[i];
524 }
525 }
526 else
527 {
528 for (i = 0; i < str_len; i++)
529 {
530 str[i] = tstr[i];
531 }
532 }
533 }
534
535 int gdb_get_registers_packet(connection_t *connection, target_t *target, char* packet, int packet_size)
536 {
537 reg_t **reg_list;
538 int reg_list_size;
539 int retval;
540 int reg_packet_size = 0;
541 char *reg_packet;
542 char *reg_packet_p;
543 int i;
544
545 DEBUG("-");
546
547 if ((retval = target->type->get_gdb_reg_list(target, &reg_list, &reg_list_size)) != ERROR_OK)
548 {
549 switch (retval)
550 {
551 case ERROR_TARGET_NOT_HALTED:
552 ERROR("gdb requested registers but we're not halted, dropping connection");
553 return ERROR_SERVER_REMOTE_CLOSED;
554 default:
555 /* this is a bug condition - get_gdb_reg_list() may not return any other error */
556 ERROR("BUG: unexpected error returned by get_gdb_reg_list()");
557 exit(-1);
558 }
559 }
560
561 for (i = 0; i < reg_list_size; i++)
562 {
563 reg_packet_size += reg_list[i]->size;
564 }
565
566 reg_packet = malloc(CEIL(reg_packet_size, 8) * 2);
567 reg_packet_p = reg_packet;
568
569 for (i = 0; i < reg_list_size; i++)
570 {
571 char *hex_buf = buf_to_str(reg_list[i]->value, reg_list[i]->size, 16);
572 DEBUG("hex_buf: %s", hex_buf);
573 gdb_str_to_target(target, hex_buf, reg_packet_p);
574 reg_packet_p += CEIL(reg_list[i]->size, 8) * 2;
575 free(hex_buf);
576 }
577
578 reg_packet_p = strndup(reg_packet, CEIL(reg_packet_size, 8) * 2);
579 DEBUG("reg_packet: %s", reg_packet_p);
580 free(reg_packet_p);
581
582 gdb_put_packet(connection, reg_packet, CEIL(reg_packet_size, 8) * 2);
583 free(reg_packet);
584
585 free(reg_list);
586
587 return ERROR_OK;
588 }
589
590 int gdb_set_registers_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
591 {
592 int i;
593 reg_t **reg_list;
594 int reg_list_size;
595 int retval;
596 char *packet_p;
597
598 DEBUG("-");
599
600 /* skip command character */
601 packet++;
602 packet_size--;
603
604 if (packet_size % 2)
605 {
606 WARNING("GDB set_registers packet with uneven characters received, dropping connection");
607 return ERROR_SERVER_REMOTE_CLOSED;
608 }
609
610 if ((retval = target->type->get_gdb_reg_list(target, &reg_list, &reg_list_size)) != ERROR_OK)
611 {
612 switch (retval)
613 {
614 case ERROR_TARGET_NOT_HALTED:
615 ERROR("gdb tried to registers but we're not halted, dropping connection");
616 return ERROR_SERVER_REMOTE_CLOSED;
617 default:
618 /* this is a bug condition - get_gdb_reg_list() may not return any other error */
619 ERROR("BUG: unexpected error returned by get_gdb_reg_list()");
620 exit(-1);
621 }
622 }
623
624 packet_p = packet;
625 for (i = 0; i < reg_list_size; i++)
626 {
627 u8 *bin_buf;
628 char *hex_buf;
629 reg_arch_type_t *arch_type;
630
631 /* convert from GDB-string (target-endian) to hex-string (big-endian) */
632 hex_buf = malloc(CEIL(reg_list[i]->size, 8) * 2);
633 gdb_target_to_str(target, packet_p, hex_buf);
634
635 /* convert hex-string to binary buffer */
636 bin_buf = malloc(CEIL(reg_list[i]->size, 8));
637 str_to_buf(hex_buf, CEIL(reg_list[i]->size, 8) * 2, bin_buf, reg_list[i]->size, 16);
638
639 /* get register arch_type, and call set method */
640 arch_type = register_get_arch_type(reg_list[i]->arch_type);
641 if (arch_type == NULL)
642 {
643 ERROR("BUG: encountered unregistered arch type");
644 exit(-1);
645 }
646 arch_type->set(reg_list[i], bin_buf);
647
648 /* advance packet pointer */
649 packet_p += (CEIL(reg_list[i]->size, 8) * 2);
650
651 free(bin_buf);
652 free(hex_buf);
653 }
654
655 /* free reg_t *reg_list[] array allocated by get_gdb_reg_list */
656 free(reg_list);
657
658 gdb_put_packet(connection, "OK", 2);
659
660 return ERROR_OK;
661 }
662
663 int gdb_get_register_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
664 {
665 char *reg_packet;
666 int reg_num = strtoul(packet + 1, NULL, 16);
667 reg_t **reg_list;
668 int reg_list_size;
669 int retval;
670 char *hex_buf;
671
672 DEBUG("-");
673
674 if ((retval = target->type->get_gdb_reg_list(target, &reg_list, &reg_list_size)) != ERROR_OK)
675 {
676 switch (retval)
677 {
678 case ERROR_TARGET_NOT_HALTED:
679 ERROR("gdb requested registers but we're not halted, dropping connection");
680 return ERROR_SERVER_REMOTE_CLOSED;
681 default:
682 /* this is a bug condition - get_gdb_reg_list() may not return any other error */
683 ERROR("BUG: unexpected error returned by get_gdb_reg_list()");
684 exit(-1);
685 }
686 }
687
688 if (reg_list_size <= reg_num)
689 {
690 ERROR("gdb requested a non-existing register");
691 exit(-1);
692 }
693
694 reg_packet = malloc(CEIL(reg_list[reg_num]->size, 8) * 2);
695
696 hex_buf = buf_to_str(reg_list[reg_num]->value, reg_list[reg_num]->size, 16);
697
698 gdb_str_to_target(target, hex_buf, reg_packet);
699
700 gdb_put_packet(connection, reg_packet, CEIL(reg_list[reg_num]->size, 8) * 2);
701
702 free(reg_list);
703 free(reg_packet);
704 free(hex_buf);
705
706 return ERROR_OK;
707 }
708
709 int gdb_set_register_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
710 {
711 char *separator;
712 char *hex_buf;
713 u8 *bin_buf;
714 int reg_num = strtoul(packet + 1, &separator, 16);
715 reg_t **reg_list;
716 int reg_list_size;
717 int retval;
718 reg_arch_type_t *arch_type;
719
720 DEBUG("-");
721
722 if ((retval = target->type->get_gdb_reg_list(target, &reg_list, &reg_list_size)) != ERROR_OK)
723 {
724 switch (retval)
725 {
726 case ERROR_TARGET_NOT_HALTED:
727 ERROR("gdb tried to set a register but we're not halted, dropping connection");
728 return ERROR_SERVER_REMOTE_CLOSED;
729 default:
730 /* this is a bug condition - get_gdb_reg_list() may not return any other error */
731 ERROR("BUG: unexpected error returned by get_gdb_reg_list()");
732 exit(-1);
733 }
734 }
735
736 if (reg_list_size < reg_num)
737 {
738 ERROR("gdb requested a non-existing register");
739 return ERROR_SERVER_REMOTE_CLOSED;
740 }
741
742 if (*separator != '=')
743 {
744 ERROR("GDB 'set register packet', but no '=' following the register number");
745 return ERROR_SERVER_REMOTE_CLOSED;
746 }
747
748 /* convert from GDB-string (target-endian) to hex-string (big-endian) */
749 hex_buf = malloc(CEIL(reg_list[reg_num]->size, 8) * 2);
750 gdb_target_to_str(target, separator + 1, hex_buf);
751
752 /* convert hex-string to binary buffer */
753 bin_buf = malloc(CEIL(reg_list[reg_num]->size, 8));
754 str_to_buf(hex_buf, CEIL(reg_list[reg_num]->size, 8) * 2, bin_buf, reg_list[reg_num]->size, 16);
755
756 /* get register arch_type, and call set method */
757 arch_type = register_get_arch_type(reg_list[reg_num]->arch_type);
758 if (arch_type == NULL)
759 {
760 ERROR("BUG: encountered unregistered arch type");
761 exit(-1);
762 }
763 arch_type->set(reg_list[reg_num], bin_buf);
764
765 gdb_put_packet(connection, "OK", 2);
766
767 free(bin_buf);
768 free(hex_buf);
769 free(reg_list);
770
771 return ERROR_OK;
772 }
773
774 int gdb_memory_packet_error(connection_t *connection, int retval)
775 {
776 switch (retval)
777 {
778 case ERROR_TARGET_NOT_HALTED:
779 ERROR("gdb tried to read memory but we're not halted, dropping connection");
780 return ERROR_SERVER_REMOTE_CLOSED;
781 break;
782 case ERROR_TARGET_DATA_ABORT:
783 gdb_send_error(connection, EIO);
784 break;
785 case ERROR_TARGET_TRANSLATION_FAULT:
786 gdb_send_error(connection, EFAULT);
787 break;
788 case ERROR_TARGET_UNALIGNED_ACCESS:
789 gdb_send_error(connection, EFAULT);
790 break;
791 default:
792 ERROR("BUG: unexpected error %i", retval);
793 exit(-1);
794 }
795
796 return ERROR_OK;
797 }
798
799 int gdb_read_memory_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
800 {
801 char *separator;
802 u32 addr = 0;
803 u32 len = 0;
804
805 u8 *buffer;
806 char *hex_buffer;
807
808 int i;
809 int retval;
810
811 /* skip command character */
812 packet++;
813
814 addr = strtoul(packet, &separator, 16);
815
816 if (*separator != ',')
817 {
818 ERROR("incomplete read memory packet received, dropping connection");
819 return ERROR_SERVER_REMOTE_CLOSED;
820 }
821
822 len = strtoul(separator+1, NULL, 16);
823
824 buffer = malloc(len);
825
826 DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr, len);
827
828 switch (len)
829 {
830 case 4:
831 if ((addr % 4) == 0)
832 retval = target->type->read_memory(target, addr, 4, 1, buffer);
833 else
834 retval = target->type->read_memory(target, addr, 1, len, buffer);
835 break;
836 case 2:
837 if ((addr % 2) == 0)
838 retval = target->type->read_memory(target, addr, 2, 1, buffer);
839 else
840 retval = target->type->read_memory(target, addr, 1, len, buffer);
841 break;
842 default:
843 if (((addr % 4) == 0) && ((len % 4) == 0))
844 retval = target->type->read_memory(target, addr, 4, len / 4, buffer);
845 else
846 retval = target->type->read_memory(target, addr, 1, len, buffer);
847 }
848
849 if (retval == ERROR_OK)
850 {
851 hex_buffer = malloc(len * 2 + 1);
852
853 for (i=0; i<len; i++)
854 snprintf(hex_buffer + 2*i, 3, "%2.2x", buffer[i]);
855
856 gdb_put_packet(connection, hex_buffer, len * 2);
857
858 free(hex_buffer);
859 }
860 else
861 {
862 if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK)
863 return retval;
864 }
865
866 free(buffer);
867
868 return ERROR_OK;
869 }
870
871 int gdb_write_memory_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
872 {
873 char *separator;
874 u32 addr = 0;
875 u32 len = 0;
876
877 u8 *buffer;
878
879 int i;
880 int retval;
881
882 /* skip command character */
883 packet++;
884
885 addr = strtoul(packet, &separator, 16);
886
887 if (*separator != ',')
888 {
889 ERROR("incomplete write memory packet received, dropping connection");
890 return ERROR_SERVER_REMOTE_CLOSED;
891 }
892
893 len = strtoul(separator+1, &separator, 16);
894
895 if (*(separator++) != ':')
896 {
897 ERROR("incomplete write memory packet received, dropping connection");
898 return ERROR_SERVER_REMOTE_CLOSED;
899 }
900
901 buffer = malloc(len);
902
903 DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr, len);
904
905 for (i=0; i<len; i++)
906 {
907 u32 tmp;
908 sscanf(separator + 2*i, "%2x", &tmp);
909 buffer[i] = tmp;
910 }
911
912 retval = ERROR_OK;
913 switch (len)
914 {
915 /* handle sized writes */
916 case 4:
917 if ((addr % 4) == 0)
918 retval = target->type->write_memory(target, addr, 4, 1, buffer);
919 else
920 retval = target->type->write_memory(target, addr, 1, len, buffer);
921 break;
922 case 2:
923 if ((addr % 2) == 0)
924 retval = target->type->write_memory(target, addr, 2, 1, buffer);
925 else
926 retval = target->type->write_memory(target, addr, 1, len, buffer);
927 break;
928 case 3:
929 case 1:
930 retval = target->type->write_memory(target, addr, 1, len, buffer);
931 break;
932 /* handle bulk writes */
933 default:
934 retval = target_write_buffer(target, addr, len, buffer);
935 break;
936 }
937
938 if (retval == ERROR_OK)
939 {
940 gdb_put_packet(connection, "OK", 2);
941 }
942 else
943 {
944 if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK)
945 return retval;
946 }
947
948 free(buffer);
949
950 return ERROR_OK;
951 }
952
953 int gdb_write_memory_binary_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
954 {
955 char *separator;
956 u32 addr = 0;
957 u32 len = 0;
958
959 u8 *buffer;
960 int retval;
961
962 /* skip command character */
963 packet++;
964
965 addr = strtoul(packet, &separator, 16);
966
967 if (*separator != ',')
968 {
969 ERROR("incomplete write memory binary packet received, dropping connection");
970 return ERROR_SERVER_REMOTE_CLOSED;
971 }
972
973 len = strtoul(separator+1, &separator, 16);
974
975 if (*(separator++) != ':')
976 {
977 ERROR("incomplete write memory binary packet received, dropping connection");
978 return ERROR_SERVER_REMOTE_CLOSED;
979 }
980
981 retval = ERROR_OK;
982 if( len ) {
983
984 buffer = malloc(len);
985
986 DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr, len);
987
988 memcpy( buffer, separator, len );
989
990 switch (len)
991 {
992 case 4:
993 if ((addr % 4) == 0)
994 retval = target->type->write_memory(target, addr, 4, 1, buffer);
995 else
996 retval = target->type->write_memory(target, addr, 1, len, buffer);
997 break;
998 case 2:
999 if ((addr % 2) == 0)
1000 retval = target->type->write_memory(target, addr, 2, 1, buffer);
1001 else
1002 retval = target->type->write_memory(target, addr, 1, len, buffer);
1003 break;
1004 case 3:
1005 case 1:
1006 retval = target->type->write_memory(target, addr, 1, len, buffer);
1007 break;
1008 default:
1009 retval = target_write_buffer(target, addr, len, buffer);
1010 break;
1011 }
1012
1013 free(buffer);
1014 }
1015
1016 if (retval == ERROR_OK)
1017 {
1018 gdb_put_packet(connection, "OK", 2);
1019 }
1020 else
1021 {
1022 if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK)
1023 return retval;
1024 }
1025
1026 return ERROR_OK;
1027 }
1028
1029 void gdb_step_continue_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
1030 {
1031 int current = 0;
1032 u32 address = 0x0;
1033
1034 DEBUG("-");
1035
1036 if (packet_size > 1)
1037 {
1038 packet[packet_size] = 0;
1039 address = strtoul(packet + 1, NULL, 16);
1040 }
1041 else
1042 {
1043 current = 1;
1044 }
1045
1046 if (packet[0] == 'c')
1047 {
1048 DEBUG("continue");
1049 target->type->resume(target, current, address, 0, 0); /* resume at current address, don't handle breakpoints, not debugging */
1050 }
1051 else if (packet[0] == 's')
1052 {
1053 DEBUG("step");
1054 target->type->step(target, current, address, 0); /* step at current or address, don't handle breakpoints */
1055 }
1056 }
1057
1058 int gdb_bp_wp_packet_error(connection_t *connection, int retval)
1059 {
1060 switch (retval)
1061 {
1062 case ERROR_TARGET_NOT_HALTED:
1063 ERROR("gdb tried to set a breakpoint but we're not halted, dropping connection");
1064 return ERROR_SERVER_REMOTE_CLOSED;
1065 break;
1066 case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
1067 gdb_send_error(connection, EBUSY);
1068 break;
1069 default:
1070 ERROR("BUG: unexpected error %i", retval);
1071 exit(-1);
1072 }
1073
1074 return ERROR_OK;
1075 }
1076
1077 int gdb_breakpoint_watchpoint_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
1078 {
1079 int type;
1080 enum breakpoint_type bp_type = BKPT_SOFT /* dummy init to avoid warning */;
1081 enum watchpoint_rw wp_type;
1082 u32 address;
1083 u32 size;
1084 char *separator;
1085 int retval;
1086
1087 DEBUG("-");
1088
1089 type = strtoul(packet + 1, &separator, 16);
1090
1091 if (type == 0) /* memory breakpoint */
1092 bp_type = BKPT_SOFT;
1093 else if (type == 1) /* hardware breakpoint */
1094 bp_type = BKPT_HARD;
1095 else if (type == 2) /* write watchpoint */
1096 wp_type = WPT_WRITE;
1097 else if (type == 3) /* read watchpoint */
1098 wp_type = WPT_READ;
1099 else if (type == 4) /* access watchpoint */
1100 wp_type = WPT_ACCESS;
1101
1102 if (*separator != ',')
1103 {
1104 ERROR("incomplete breakpoint/watchpoint packet received, dropping connection");
1105 return ERROR_SERVER_REMOTE_CLOSED;
1106 }
1107
1108 address = strtoul(separator+1, &separator, 16);
1109
1110 if (*separator != ',')
1111 {
1112 ERROR("incomplete breakpoint/watchpoint packet received, dropping connection");
1113 return ERROR_SERVER_REMOTE_CLOSED;
1114 }
1115
1116 size = strtoul(separator+1, &separator, 16);
1117
1118 switch (type)
1119 {
1120 case 0:
1121 case 1:
1122 if (packet[0] == 'Z')
1123 {
1124 if ((retval = breakpoint_add(target, address, size, bp_type)) != ERROR_OK)
1125 {
1126 if ((retval = gdb_bp_wp_packet_error(connection, retval)) != ERROR_OK)
1127 return retval;
1128 }
1129 else
1130 {
1131 gdb_put_packet(connection, "OK", 2);
1132 }
1133 }
1134 else
1135 {
1136 breakpoint_remove(target, address);
1137 gdb_put_packet(connection, "OK", 2);
1138 }
1139 break;
1140 case 2:
1141 case 3:
1142 case 4:
1143 {
1144 if (packet[0] == 'Z')
1145 {
1146 if ((retval = watchpoint_add(target, address, size, type-2, 0, 0xffffffffu)) != ERROR_OK)
1147 {
1148 if ((retval = gdb_bp_wp_packet_error(connection, retval)) != ERROR_OK)
1149 return retval;
1150 }
1151 else
1152 {
1153 gdb_put_packet(connection, "OK", 2);
1154 }
1155 }
1156 else
1157 {
1158 watchpoint_remove(target, address);
1159 gdb_put_packet(connection, "OK", 2);
1160 }
1161 break;
1162 }
1163 default:
1164 break;
1165 }
1166
1167 return ERROR_OK;
1168 }
1169
1170 int gdb_query_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
1171 {
1172 command_context_t *cmd_ctx = connection->cmd_ctx;
1173
1174 if (strstr(packet, "qRcmd,"))
1175 {
1176 if (packet_size > 6)
1177 {
1178 char *cmd;
1179 int i;
1180 cmd = malloc((packet_size - 6)/2 + 1);
1181 for (i=0; i < (packet_size - 6)/2; i++)
1182 {
1183 u32 tmp;
1184 sscanf(packet + 6 + 2*i, "%2x", &tmp);
1185 cmd[i] = tmp;
1186 }
1187 cmd[(packet_size - 6)/2] = 0x0;
1188 command_run_line(cmd_ctx, cmd);
1189 free(cmd);
1190 }
1191 gdb_put_packet(connection, "OK", 2);
1192 return ERROR_OK;
1193 }
1194
1195 if (strstr(packet, "qCRC:"))
1196 {
1197 if (packet_size > 5)
1198 {
1199 int retval;
1200 u8 gdb_reply[9];
1201 char *separator;
1202 u32 checksum;
1203 u32 addr = 0;
1204 u32 len = 0;
1205
1206 /* skip command character */
1207 packet += 5;
1208
1209 addr = strtoul(packet, &separator, 16);
1210
1211 if (*separator != ',')
1212 {
1213 ERROR("incomplete read memory packet received, dropping connection");
1214 return ERROR_SERVER_REMOTE_CLOSED;
1215 }
1216
1217 len = strtoul(separator+1, NULL, 16);
1218
1219 retval = target_checksum_memory(target, addr, len, &checksum);
1220
1221 if (retval == ERROR_OK)
1222 {
1223 snprintf(gdb_reply, 9, "C%2.2x", checksum);
1224 gdb_put_packet(connection, gdb_reply, 9);
1225 }
1226 else
1227 {
1228 if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK)
1229 return retval;
1230 }
1231
1232 return ERROR_OK;
1233 }
1234 }
1235
1236 gdb_put_packet(connection, "", 0);
1237 return ERROR_OK;
1238 }
1239
1240 int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
1241 {
1242 gdb_connection_t *gdb_connection = connection->priv;
1243 gdb_service_t *gdb_service = connection->service->priv;
1244 int result;
1245
1246 if (strstr(packet, "vFlashErase:"))
1247 {
1248 unsigned long addr;
1249 unsigned long length;
1250 char *parse = packet + 12;
1251 if (*parse == '\0')
1252 {
1253 ERROR("incomplete vFlashErase packet received, dropping connection");
1254 return ERROR_SERVER_REMOTE_CLOSED;
1255 }
1256
1257 addr = strtoul(parse, &parse, 16);
1258
1259 if (*(parse++) != ',' || *parse == '\0')
1260 {
1261 ERROR("incomplete vFlashErase packet received, dropping connection");
1262 return ERROR_SERVER_REMOTE_CLOSED;
1263 }
1264
1265 length = strtoul(parse, &parse, 16);
1266
1267 if (*parse != '\0')
1268 {
1269 ERROR("incomplete vFlashErase packet received, dropping connection");
1270 return ERROR_SERVER_REMOTE_CLOSED;
1271 }
1272
1273 /* perform erase */
1274 if ((result = flash_erase(gdb_service->target, addr, length)) != ERROR_OK)
1275 {
1276 /* GDB doesn't evaluate the actual error number returned,
1277 * treat a failed erase as an I/O error
1278 */
1279 gdb_send_error(connection, EIO);
1280 ERROR("flash_erase returned %i", result);
1281 }
1282 else
1283 gdb_put_packet(connection, "OK", 2);
1284
1285 return ERROR_OK;
1286 }
1287
1288 if (strstr(packet, "vFlashWrite:"))
1289 {
1290 unsigned long addr;
1291 unsigned long length;
1292 char *parse = packet + 12;
1293
1294 if (*parse == '\0')
1295 {
1296 ERROR("incomplete vFlashErase packet received, dropping connection");
1297 return ERROR_SERVER_REMOTE_CLOSED;
1298 }
1299 addr = strtoul(parse, &parse, 16);
1300 if (*(parse++) != ':')
1301 {
1302 ERROR("incomplete vFlashErase packet received, dropping connection");
1303 return ERROR_SERVER_REMOTE_CLOSED;
1304 }
1305 length = packet_size - (parse - packet);
1306
1307 /* create a new image if there isn't already one */
1308 if (gdb_connection->vflash_image == NULL)
1309 {
1310 gdb_connection->vflash_image = malloc(sizeof(image_t));
1311 image_open(gdb_connection->vflash_image, "", "build");
1312 }
1313
1314 /* create new section with content from packet buffer */
1315 image_add_section(gdb_connection->vflash_image, addr, length, 0x0, (u8*)parse);
1316
1317 gdb_put_packet(connection, "OK", 2);
1318
1319 return ERROR_OK;
1320 }
1321
1322 if (!strcmp(packet, "vFlashDone"))
1323 {
1324 u32 written;
1325 char *error_str;
1326
1327 /* process the flashing buffer */
1328 if ((result = flash_write(gdb_service->target, gdb_connection->vflash_image, &written, &error_str, NULL, 0)) != ERROR_OK)
1329 {
1330 if (result == ERROR_FLASH_DST_OUT_OF_BANK)
1331 gdb_put_packet(connection, "E.memtype", 9);
1332 else
1333 gdb_send_error(connection, EIO);
1334
1335 if (error_str)
1336 {
1337 ERROR("flash writing failed: %s", error_str);
1338 free(error_str);
1339 }
1340 }
1341 else
1342 {
1343 DEBUG("wrote %u bytes from vFlash image to flash", written);
1344 gdb_put_packet(connection, "OK", 2);
1345 }
1346
1347 image_close(gdb_connection->vflash_image);
1348 free(gdb_connection->vflash_image);
1349 gdb_connection->vflash_image = NULL;
1350
1351 return ERROR_OK;
1352 }
1353
1354 gdb_put_packet(connection, "", 0);
1355 return ERROR_OK;
1356 }
1357
1358 int gdb_detach(connection_t *connection, target_t *target)
1359 {
1360 switch( detach_mode )
1361 {
1362 case GDB_DETACH_RESUME:
1363 target->type->resume(target, 1, 0, 1, 0);
1364 break;
1365
1366 case GDB_DETACH_RESET:
1367 target_process_reset(connection->cmd_ctx);
1368 break;
1369
1370 case GDB_DETACH_HALT:
1371 target->type->halt(target);
1372 break;
1373
1374 case GDB_DETACH_NOTHING:
1375 break;
1376 }
1377
1378 gdb_put_packet(connection, "OK", 2);
1379
1380 return ERROR_OK;
1381 }
1382
1383 int gdb_input(connection_t *connection)
1384 {
1385 gdb_service_t *gdb_service = connection->service->priv;
1386 target_t *target = gdb_service->target;
1387 char packet[GDB_BUFFER_SIZE];
1388 int packet_size;
1389 int retval;
1390 gdb_connection_t *gdb_con = connection->priv;
1391
1392 /* drain input buffer */
1393 do
1394 {
1395 packet_size = GDB_BUFFER_SIZE-1;
1396 if ((retval = gdb_get_packet(connection, packet, &packet_size)) != ERROR_OK)
1397 {
1398 switch (retval)
1399 {
1400 case ERROR_GDB_BUFFER_TOO_SMALL:
1401 ERROR("BUG: buffer supplied for gdb packet was too small");
1402 exit(-1);
1403 case ERROR_SERVER_REMOTE_CLOSED:
1404 return ERROR_SERVER_REMOTE_CLOSED;
1405 default:
1406 ERROR("BUG: unexpected error");
1407 exit(-1);
1408 }
1409 }
1410
1411 /* terminate with zero */
1412 packet[packet_size] = 0;
1413
1414 DEBUG("received packet: '%s'", packet);
1415
1416 if (packet_size > 0)
1417 {
1418 retval = ERROR_OK;
1419 switch (packet[0])
1420 {
1421 case 'H':
1422 /* Hct... -- set thread
1423 * we don't have threads, send empty reply */
1424 gdb_put_packet(connection, NULL, 0);
1425 break;
1426 case 'q':
1427 retval = gdb_query_packet(connection, target, packet, packet_size);
1428 break;
1429 case 'g':
1430 retval = gdb_get_registers_packet(connection, target, packet, packet_size);
1431 break;
1432 case 'G':
1433 retval = gdb_set_registers_packet(connection, target, packet, packet_size);
1434 break;
1435 case 'p':
1436 retval = gdb_get_register_packet(connection, target, packet, packet_size);
1437 break;
1438 case 'P':
1439 retval = gdb_set_register_packet(connection, target, packet, packet_size);
1440 break;
1441 case 'm':
1442 retval = gdb_read_memory_packet(connection, target, packet, packet_size);
1443 break;
1444 case 'M':
1445 retval = gdb_write_memory_packet(connection, target, packet, packet_size);
1446 break;
1447 case 'z':
1448 case 'Z':
1449 retval = gdb_breakpoint_watchpoint_packet(connection, target, packet, packet_size);
1450 break;
1451 case '?':
1452 gdb_last_signal_packet(connection, target, packet, packet_size);
1453 break;
1454 case 'c':
1455 case 's':
1456 gdb_step_continue_packet(connection, target, packet, packet_size);
1457 break;
1458 case 'v':
1459 retval = gdb_v_packet(connection, target, packet, packet_size);
1460 break;
1461 case 'D':
1462 retval = gdb_detach(connection, target);
1463 break;
1464 case 'X':
1465 if ((retval = gdb_write_memory_binary_packet(connection, target, packet, packet_size)) != ERROR_OK)
1466 return retval;
1467 break;
1468 case 'k':
1469 gdb_put_packet(connection, "OK", 2);
1470 return ERROR_SERVER_REMOTE_CLOSED;
1471 default:
1472 /* ignore unkown packets */
1473 DEBUG("ignoring 0x%2.2x packet", packet[0]);
1474 gdb_put_packet(connection, NULL, 0);
1475 break;
1476 }
1477
1478 /* if a packet handler returned an error, exit input loop */
1479 if (retval != ERROR_OK)
1480 return retval;
1481 }
1482
1483 if (gdb_con->ctrl_c)
1484 {
1485 if (target->state == TARGET_RUNNING)
1486 {
1487 target->type->halt(target);
1488 gdb_con->ctrl_c = 0;
1489 }
1490 }
1491
1492 } while (gdb_con->buf_cnt > 0);
1493
1494 return ERROR_OK;
1495 }
1496
1497 int gdb_init()
1498 {
1499 gdb_service_t *gdb_service;
1500 target_t *target = targets;
1501 int i = 0;
1502
1503 if (!target)
1504 {
1505 WARNING("no gdb ports allocated as no target has been specified");
1506 return ERROR_OK;
1507 }
1508
1509 if (gdb_port == 0)
1510 {
1511 WARNING("no gdb port specified, using default port 3333");
1512 gdb_port = 3333;
1513 }
1514
1515 while (target)
1516 {
1517 char service_name[8];
1518
1519 snprintf(service_name, 8, "gdb-%2.2i", i);
1520
1521 gdb_service = malloc(sizeof(gdb_service_t));
1522 gdb_service->target = target;
1523
1524 add_service("gdb", CONNECTION_GDB, gdb_port + i, 1, gdb_new_connection, gdb_input, gdb_connection_closed, gdb_service);
1525
1526 DEBUG("gdb service for target %s at port %i", target->type->name, gdb_port + i);
1527
1528 i++;
1529 target = target->next;
1530 }
1531
1532 return ERROR_OK;
1533 }
1534
1535 /* daemon configuration command gdb_port */
1536 int handle_gdb_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1537 {
1538 if (argc == 0)
1539 return ERROR_OK;
1540
1541 /* only if the port wasn't overwritten by cmdline */
1542 if (gdb_port == 0)
1543 gdb_port = strtoul(args[0], NULL, 0);
1544
1545 return ERROR_OK;
1546 }
1547
1548 int handle_gdb_detach_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1549 {
1550 if (argc == 1)
1551 {
1552 if (strcmp(args[0], "resume") == 0)
1553 {
1554 detach_mode = GDB_DETACH_RESUME;
1555 return ERROR_OK;
1556 }
1557 else if (strcmp(args[0], "reset") == 0)
1558 {
1559 detach_mode = GDB_DETACH_RESET;
1560 return ERROR_OK;
1561 }
1562 else if (strcmp(args[0], "halt") == 0)
1563 {
1564 detach_mode = GDB_DETACH_HALT;
1565 return ERROR_OK;
1566 }
1567 else if (strcmp(args[0], "nothing") == 0)
1568 {
1569 detach_mode = GDB_DETACH_NOTHING;
1570 return ERROR_OK;
1571 }
1572 }
1573
1574 WARNING("invalid gdb_detach configuration directive: %s", args[0]);
1575 return ERROR_OK;
1576 }
1577
1578 int gdb_register_commands(command_context_t *command_context)
1579 {
1580 register_command(command_context, NULL, "gdb_port", handle_gdb_port_command,
1581 COMMAND_CONFIG, "");
1582 register_command(command_context, NULL, "gdb_detach", handle_gdb_detach_command,
1583 COMMAND_CONFIG, "");
1584
1585 return ERROR_OK;
1586 }

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)