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 ***************************************************************************/
22 #include "gdb_server.h"
26 #include "binarybuffer.h"
27 #include "breakpoints.h"
37 char* strndup(const char *s
, size_t n
)
39 size_t len
= strnlen (s
, n
);
40 char *new = (char *) malloc (len
+ 1);
46 return (char *) memcpy (new, s
, len
);
51 #define _DEBUG_GDB_IO_
54 static unsigned short gdb_port
;
56 int gdb_last_signal(target_t
*target
)
58 switch (target
->debug_reason
)
60 case DBG_REASON_DBGRQ
:
61 return 0x2; /* SIGINT */
62 case DBG_REASON_BREAKPOINT
:
63 case DBG_REASON_WATCHPOINT
:
64 case DBG_REASON_WPTANDBKPT
:
65 return 0x05; /* SIGTRAP */
66 case DBG_REASON_SINGLESTEP
:
67 return 0x05; /* SIGTRAP */
68 case DBG_REASON_NOTHALTED
:
69 return 0x0; /* no signal... shouldn't happen */
71 ERROR("BUG: undefined debug reason");
76 int gdb_get_char(connection_t
*connection
, int* next_char
)
78 gdb_connection_t
*gdb_con
= connection
->priv
;
81 if (gdb_con
->buf_cnt
-- > 0)
83 *next_char
= *(gdb_con
->buf_p
++);
84 if (gdb_con
->buf_cnt
> 0)
85 connection
->input_pending
= 1;
87 connection
->input_pending
= 0;
90 DEBUG("returned char '%c' (0x%2.2x)", *next_char
, *next_char
);
96 while ((gdb_con
->buf_cnt
= read(connection
->fd
, gdb_con
->buffer
, GDB_BUFFER_SIZE
)) <= 0)
98 if (gdb_con
->buf_cnt
== 0)
99 return ERROR_SERVER_REMOTE_CLOSED
;
107 return ERROR_SERVER_REMOTE_CLOSED
;
109 return ERROR_SERVER_REMOTE_CLOSED
;
111 ERROR("read: %s", strerror(errno
));
116 debug_buffer
= malloc(gdb_con
->buf_cnt
+ 1);
117 memcpy(debug_buffer
, gdb_con
->buffer
, gdb_con
->buf_cnt
);
118 debug_buffer
[gdb_con
->buf_cnt
] = 0;
119 DEBUG("received '%s'", debug_buffer
);
122 gdb_con
->buf_p
= gdb_con
->buffer
;
124 *next_char
= *(gdb_con
->buf_p
++);
125 if (gdb_con
->buf_cnt
> 0)
126 connection
->input_pending
= 1;
128 connection
->input_pending
= 0;
129 #ifdef _DEBUG_GDB_IO_
130 DEBUG("returned char '%c' (0x%2.2x)", *next_char
, *next_char
);
136 int gdb_put_packet(connection_t
*connection
, char *buffer
, int len
)
139 unsigned char my_checksum
= 0;
144 gdb_connection_t
*gdb_con
= connection
->priv
;
146 for (i
= 0; i
< len
; i
++)
147 my_checksum
+= buffer
[i
];
152 debug_buffer
= malloc(len
+ 1);
153 memcpy(debug_buffer
, buffer
, len
);
154 debug_buffer
[len
] = 0;
155 DEBUG("sending packet '$%s#%2.2x'", debug_buffer
, my_checksum
);
158 write(connection
->fd
, "$", 1);
160 write(connection
->fd
, buffer
, len
);
161 write(connection
->fd
, "#", 1);
163 snprintf(checksum
, 3, "%2.2x", my_checksum
);
165 write(connection
->fd
, checksum
, 2);
167 if ((retval
= gdb_get_char(connection
, &reply
)) != ERROR_OK
)
172 else if (reply
== '-')
173 WARNING("negative reply, retrying");
174 else if (reply
== 0x3)
177 if ((retval
= gdb_get_char(connection
, &reply
)) != ERROR_OK
)
181 else if (reply
== '-')
182 WARNING("negative reply, retrying");
185 ERROR("unknown character 0x%2.2x in reply, dropping connection", reply
);
186 return ERROR_SERVER_REMOTE_CLOSED
;
191 ERROR("unknown character 0x%2.2x in reply, dropping connection", reply
);
192 return ERROR_SERVER_REMOTE_CLOSED
;
199 int gdb_get_packet(connection_t
*connection
, char *buffer
, int *len
)
207 unsigned char my_checksum
= 0;
208 gdb_connection_t
*gdb_con
= connection
->priv
;
214 if ((retval
= gdb_get_char(connection
, &character
)) != ERROR_OK
)
222 WARNING("acknowledgment received, but no packet pending");
225 WARNING("negative acknowledgment, but no packet pending");
232 WARNING("ignoring character 0x%x", character
);
235 } while (character
!= '$');
241 if ((retval
= gdb_get_char(connection
, &character
)) != ERROR_OK
)
245 packet_type
= character
;
249 if( packet_type
== 'X' )
256 /* data transmitted in binary mode (X packet)
257 * uses 0x7d as escape character */
258 my_checksum
+= character
& 0xff;
259 gdb_get_char(connection
, &character
);
260 my_checksum
+= character
& 0xff;
261 buffer
[count
++] = (character
^ 0x20) & 0xff;
264 ERROR("packet buffer too small");
265 return ERROR_GDB_BUFFER_TOO_SMALL
;
269 buffer
[count
++] = character
& 0xff;
270 my_checksum
+= character
& 0xff;
273 ERROR("packet buffer too small");
274 return ERROR_GDB_BUFFER_TOO_SMALL
;
289 buffer
[count
++] = character
& 0xff;
290 my_checksum
+= character
& 0xff;
293 ERROR("packet buffer too small");
294 return ERROR_GDB_BUFFER_TOO_SMALL
;
299 } while (character
!= '#');
303 if ((retval
= gdb_get_char(connection
, &character
)) != ERROR_OK
)
305 checksum
[0] = character
;
306 if ((retval
= gdb_get_char(connection
, &character
)) != ERROR_OK
)
308 checksum
[1] = character
;
311 if (my_checksum
== strtoul(checksum
, NULL
, 16))
313 write (connection
->fd
, "+", 1);
317 WARNING("checksum error, requesting retransmission");
318 write(connection
->fd
, "-", 1);
324 int gdb_output(struct command_context_s
*context
, char* line
)
326 connection_t
*connection
= context
->output_handler_priv
;
330 bin_size
= strlen(line
);
332 hex_buffer
= malloc(bin_size
*2 + 4);
335 for (i
=0; i
<bin_size
; i
++)
336 snprintf(hex_buffer
+ 1 + i
*2, 3, "%2.2x", line
[i
]);
337 hex_buffer
[bin_size
*2+1] = '0';
338 hex_buffer
[bin_size
*2+2] = 'a';
339 hex_buffer
[bin_size
*2+3] = 0x0;
341 gdb_put_packet(connection
, hex_buffer
, bin_size
*2 + 3);
347 int gdb_target_callback_event_handler(struct target_s
*target
, enum target_event event
, void *priv
)
349 connection_t
*connection
= priv
;
350 gdb_connection_t
*gdb_connection
= connection
->priv
;
356 case TARGET_EVENT_HALTED
:
357 if (gdb_connection
->frontend_state
== TARGET_RUNNING
)
359 if (gdb_connection
->ctrl_c
)
362 gdb_connection
->ctrl_c
= 0;
366 signal
= gdb_last_signal(target
);
369 snprintf(sig_reply
, 4, "T%2.2x", signal
);
370 gdb_put_packet(connection
, sig_reply
, 3);
371 gdb_connection
->frontend_state
= TARGET_HALTED
;
374 case TARGET_EVENT_RESUMED
:
375 if (gdb_connection
->frontend_state
== TARGET_HALTED
)
377 gdb_connection
->frontend_state
= TARGET_RUNNING
;
387 int gdb_new_connection(connection_t
*connection
)
389 gdb_connection_t
*gdb_connection
= malloc(sizeof(gdb_connection_t
));
390 gdb_service_t
*gdb_service
= connection
->service
->priv
;
394 connection
->priv
= gdb_connection
;
396 /* initialize gdb connection information */
397 gdb_connection
->buf_p
= gdb_connection
->buffer
;
398 gdb_connection
->buf_cnt
= 0;
399 gdb_connection
->ctrl_c
= 0;
400 gdb_connection
->frontend_state
= TARGET_HALTED
;
402 /* output goes through gdb connection */
403 command_set_output_handler(connection
->cmd_ctx
, gdb_output
, connection
);
405 /* register callback to be informed about target events */
406 target_register_event_callback(gdb_target_callback_event_handler
, connection
);
408 /* a gdb session just attached, put the target in halt mode */
409 if (((retval
= gdb_service
->target
->type
->halt(gdb_service
->target
)) != ERROR_OK
) &&
410 (retval
!= ERROR_TARGET_ALREADY_HALTED
))
412 ERROR("error when trying to halt target");
416 while (gdb_service
->target
->state
!= TARGET_HALTED
)
418 gdb_service
->target
->type
->poll(gdb_service
->target
);
421 /* remove the initial ACK from the incoming buffer */
422 if ((retval
= gdb_get_char(connection
, &initial_ack
)) != ERROR_OK
)
428 int gdb_connection_closed(connection_t
*connection
)
430 if (connection
->priv
)
431 free(connection
->priv
);
433 ERROR("BUG: connection->priv == NULL");
435 target_unregister_event_callback(gdb_target_callback_event_handler
, connection
);
440 int gdb_last_signal_packet(connection_t
*connection
, target_t
*target
, char* packet
, int packet_size
)
445 signal
= gdb_last_signal(target
);
447 snprintf(sig_reply
, 4, "S%2.2x", signal
);
448 gdb_put_packet(connection
, sig_reply
, 3);
453 void gdb_get_registers_packet(connection_t
*connection
, target_t
*target
, char* packet
, int packet_size
)
458 int reg_packet_size
= 0;
465 if ((retval
= target
->type
->get_gdb_reg_list(target
, ®_list
, ®_list_size
)) != ERROR_OK
)
469 case ERROR_TARGET_NOT_HALTED
:
470 ERROR("gdb requested registers, but we're not halted");
473 ERROR("BUG: unexpected error returned by get_gdb_reg_list()");
478 for (i
= 0; i
< reg_list_size
; i
++)
480 reg_packet_size
+= reg_list
[i
]->size
;
483 reg_packet
= malloc(CEIL(reg_packet_size
, 8) * 2);
484 reg_packet_p
= reg_packet
;
486 for (i
= 0; i
< reg_list_size
; i
++)
489 char *hex_buf
= buf_to_char(reg_list
[i
]->value
, reg_list
[i
]->size
);
490 DEBUG("hex_buf: %s", hex_buf
);
491 for (j
= CEIL(reg_list
[i
]->size
, 8) * 2; j
> 0; j
-= 2)
493 *reg_packet_p
++ = hex_buf
[j
- 2];
494 *reg_packet_p
++ = hex_buf
[j
- 1];
499 reg_packet_p
= strndup(reg_packet
, CEIL(reg_packet_size
, 8) * 2);
500 DEBUG("reg_packet: %s", reg_packet_p
);
503 gdb_put_packet(connection
, reg_packet
, CEIL(reg_packet_size
, 8) * 2);
508 void gdb_set_registers_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
518 /* skip command character */
524 WARNING("GDB set_registers packet with uneven characters received");
528 if ((retval
= target
->type
->get_gdb_reg_list(target
, ®_list
, ®_list_size
)) != ERROR_OK
)
532 case ERROR_TARGET_NOT_HALTED
:
533 ERROR("gdb requested registers, but we're not halted");
536 ERROR("BUG: unexpected error returned by get_gdb_reg_list()");
542 for (i
= 0; i
< reg_list_size
; i
++)
544 char_to_buf(packet
, CEIL(reg_list
[i
]->size
, 8) * 2, reg_list
[i
]->value
, reg_list
[i
]->size
);
545 reg_list
[i
]->dirty
= 1;
548 gdb_put_packet(connection
, "OK", 2);
551 void gdb_get_register_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
556 int reg_num
= strtoul(packet
+ 1, NULL
, 16);
564 if ((retval
= target
->type
->get_gdb_reg_list(target
, ®_list
, ®_list_size
)) != ERROR_OK
)
568 case ERROR_TARGET_NOT_HALTED
:
569 ERROR("gdb requested registers, but we're not halted");
572 ERROR("BUG: unexpected error returned by get_gdb_reg_list()");
577 if (reg_list_size
<= reg_num
)
579 ERROR("gdb requested a non-existing register");
583 hex_buf
= buf_to_char(reg_list
[reg_num
]->value
, reg_list
[reg_num
]->size
);
584 reg_packet
= reg_packet_p
= malloc(CEIL(reg_list
[reg_num
]->size
, 8) * 2);
586 for (i
= CEIL(reg_list
[reg_num
]->size
, 8) * 2; i
> 0; i
-= 2)
588 *reg_packet_p
++ = hex_buf
[i
- 2];
589 *reg_packet_p
++ = hex_buf
[i
- 1];
592 gdb_put_packet(connection
, reg_packet
, CEIL(reg_list
[reg_num
]->size
, 8) * 2);
599 void gdb_set_register_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
602 int reg_num
= strtoul(packet
+ 1, &separator
, 16);
609 if ((retval
= target
->type
->get_gdb_reg_list(target
, ®_list
, ®_list_size
)) != ERROR_OK
)
613 case ERROR_TARGET_NOT_HALTED
:
614 ERROR("gdb requested registers, but we're not halted");
617 ERROR("BUG: unexpected error returned by get_gdb_reg_list()");
622 if (reg_list_size
< reg_num
)
624 ERROR("gdb requested a non-existing register");
628 if (*separator
!= '=')
630 ERROR("GDB set register packet, but no '=' following the register number");
634 char_to_buf(separator
+ 1, CEIL(reg_list
[reg_num
]->size
, 8) * 2, reg_list
[reg_num
]->value
, reg_list
[reg_num
]->size
);
635 reg_list
[reg_num
]->dirty
= 1;
637 gdb_put_packet(connection
, "OK", 2);
641 void gdb_read_memory_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
652 /* skip command character */
655 addr
= strtoul(packet
, &separator
, 16);
657 if (*separator
!= ',')
660 len
= strtoul(separator
+1, NULL
, 16);
662 buffer
= malloc(len
);
664 DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr
, len
);
670 target
->type
->read_memory(target
, addr
, 4, 1, buffer
);
672 target
->type
->read_memory(target
, addr
, 1, len
, buffer
);
676 target
->type
->read_memory(target
, addr
, 2, 1, buffer
);
678 target
->type
->read_memory(target
, addr
, 1, len
, buffer
);
681 if (((addr
% 4) == 0) && ((len
% 4) == 0))
682 target
->type
->read_memory(target
, addr
, 4, len
/ 4, buffer
);
684 target
->type
->read_memory(target
, addr
, 1, len
, buffer
);
687 hex_buffer
= malloc(len
* 2 + 1);
689 for (i
=0; i
<len
; i
++)
690 snprintf(hex_buffer
+ 2*i
, 3, "%2.2x", buffer
[i
]);
692 gdb_put_packet(connection
, hex_buffer
, len
* 2);
698 void gdb_write_memory_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
708 /* skip command character */
711 addr
= strtoul(packet
, &separator
, 16);
713 if (*separator
!= ',')
716 len
= strtoul(separator
+1, &separator
, 16);
718 if (*(separator
++) != ':')
721 buffer
= malloc(len
);
723 DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr
, len
);
725 for (i
=0; i
<len
; i
++)
728 sscanf(separator
+ 2*i
, "%2x", &tmp
);
734 /* handle sized writes */
737 target
->type
->write_memory(target
, addr
, 4, 1, buffer
);
739 target
->type
->write_memory(target
, addr
, 1, len
, buffer
);
743 target
->type
->write_memory(target
, addr
, 2, 1, buffer
);
745 target
->type
->write_memory(target
, addr
, 1, len
, buffer
);
749 target
->type
->write_memory(target
, addr
, 1, len
, buffer
);
751 /* handle bulk writes */
753 target_write_buffer(target
, addr
, len
, buffer
);
757 gdb_put_packet(connection
, "OK", 2);
762 void gdb_write_memory_binary_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
770 /* skip command character */
773 addr
= strtoul(packet
, &separator
, 16);
775 if (*separator
!= ',')
778 len
= strtoul(separator
+1, &separator
, 16);
780 if (*(separator
++) != ':')
785 buffer
= malloc(len
);
787 DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr
, len
);
789 memcpy( buffer
, separator
, len
);
795 target
->type
->write_memory(target
, addr
, 4, 1, buffer
);
797 target
->type
->write_memory(target
, addr
, 1, len
, buffer
);
801 target
->type
->write_memory(target
, addr
, 2, 1, buffer
);
803 target
->type
->write_memory(target
, addr
, 1, len
, buffer
);
807 target
->type
->write_memory(target
, addr
, 1, len
, buffer
);
810 target_write_buffer(target
, addr
, len
, buffer
);
817 gdb_put_packet(connection
, "OK", 2);
820 void gdb_step_continue_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
830 packet
[packet_size
] = 0;
831 address
= strtoul(packet
+ 1, NULL
, 16);
838 if (packet
[0] == 'c')
841 target
->type
->resume(target
, current
, address
, 0, 0); /* resume at current address, don't handle breakpoints, not debugging */
843 else if (packet
[0] == 's')
846 target
->type
->step(target
, current
, address
, 0); /* step at current or address, don't handle breakpoints */
850 void gdb_breakpoint_watchpoint_packet(connection_t
*connection
, target_t
*target
, char *packet
, int packet_size
)
853 enum breakpoint_type bp_type
;
854 enum watchpoint_rw wp_type
;
862 type
= strtoul(packet
+ 1, &separator
, 16);
864 if (type
== 0) /* memory breakpoint */
866 else if (type
== 1) /* hardware breakpoint */
868 else if (type
== 2) /* write watchpoint */
870 else if (type
== 3) /* read watchpoint */
872 else if (type
== 4) /* access watchpoint */
873 wp_type
= WPT_ACCESS
;
875 if (*separator
!= ',')
878 address
= strtoul(separator
+1, &separator
, 16);
880 if (*separator
!= ',')
883 size
= strtoul(separator
+1, &separator
, 16);
889 if (packet
[0] == 'Z')
891 if ((retval
= breakpoint_add(target
, address
, size
, bp_type
)) != ERROR_OK
)
893 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
895 gdb_put_packet(connection
, "E00", 3);
902 breakpoint_remove(target
, address
);
904 gdb_put_packet(connection
, "OK", 2);
910 if (packet
[0] == 'Z')
911 watchpoint_add(target
, address
, size
, type
-2, 0, 0xffffffffu
);
913 watchpoint_remove(target
, address
);
914 gdb_put_packet(connection
, "OK", 2);
923 void gdb_query_packet(connection_t
*connection
, char *packet
, int packet_size
)
925 command_context_t
*cmd_ctx
= connection
->cmd_ctx
;
926 gdb_service_t
*gdb_service
= connection
->service
->priv
;
927 target_t
*target
= gdb_service
->target
;
929 if (strstr(packet
, "qRcmd,"))
935 cmd
= malloc((packet_size
- 6)/2 + 1);
936 for (i
=0; i
< (packet_size
- 6)/2; i
++)
939 sscanf(packet
+ 6 + 2*i
, "%2x", &tmp
);
942 cmd
[(packet_size
- 6)/2] = 0x0;
943 command_run_line(cmd_ctx
, cmd
);
946 gdb_put_packet(connection
, "OK", 2);
950 gdb_put_packet(connection
, "", 0);
953 int gdb_input(connection_t
*connection
)
955 gdb_service_t
*gdb_service
= connection
->service
->priv
;
956 target_t
*target
= gdb_service
->target
;
957 char packet
[GDB_BUFFER_SIZE
];
960 gdb_connection_t
*gdb_con
= connection
->priv
;
962 /* drain input buffer */
965 packet_size
= GDB_BUFFER_SIZE
-1;
966 if ((retval
= gdb_get_packet(connection
, packet
, &packet_size
)) != ERROR_OK
)
970 case ERROR_GDB_BUFFER_TOO_SMALL
:
971 ERROR("BUG: buffer supplied for gdb packet was too small");
973 case ERROR_SERVER_REMOTE_CLOSED
:
974 return ERROR_SERVER_REMOTE_CLOSED
;
976 ERROR("unexpected error");
981 /* terminate with zero */
982 packet
[packet_size
] = 0;
984 DEBUG("recevied packet: '%s'", packet
);
991 /* Hct... -- set thread
992 * we don't have threads, send empty reply */
993 gdb_put_packet(connection
, NULL
, 0);
996 gdb_query_packet(connection
, packet
, packet_size
);
999 gdb_get_registers_packet(connection
, target
, packet
, packet_size
);
1002 gdb_set_registers_packet(connection
, target
, packet
, packet_size
);
1005 gdb_get_register_packet(connection
, target
, packet
, packet_size
);
1008 gdb_set_register_packet(connection
, target
, packet
, packet_size
);
1011 gdb_read_memory_packet(connection
, target
, packet
, packet_size
);
1014 gdb_write_memory_packet(connection
, target
, packet
, packet_size
);
1018 gdb_breakpoint_watchpoint_packet(connection
, target
, packet
, packet_size
);
1021 gdb_last_signal_packet(connection
, target
, packet
, packet_size
);
1025 gdb_step_continue_packet(connection
, target
, packet
, packet_size
);
1028 target
->type
->resume(target
, 1, 0, 1, 0);
1029 gdb_put_packet(connection
, "OK", 2);
1032 gdb_write_memory_binary_packet(connection
, target
, packet
, packet_size
);
1035 gdb_put_packet(connection
, "OK", 2);
1036 return ERROR_SERVER_REMOTE_CLOSED
;
1038 /* ignore unkown packets */
1039 DEBUG("ignoring 0x%2.2x packet", packet
[0]);
1040 gdb_put_packet(connection
, NULL
, 0);
1045 if (gdb_con
->ctrl_c
)
1047 if (target
->state
== TARGET_RUNNING
)
1049 target
->type
->halt(target
);
1050 gdb_con
->ctrl_c
= 0;
1054 } while (gdb_con
->buf_cnt
> 0);
1061 gdb_service_t
*gdb_service
;
1062 target_t
*target
= targets
;
1067 WARNING("no gdb ports allocated as no target has been specified");
1073 WARNING("no gdb port specified, using default port 3333");
1079 char service_name
[8];
1081 snprintf(service_name
, 8, "gdb-%2.2i", i
);
1083 gdb_service
= malloc(sizeof(gdb_service_t
));
1084 gdb_service
->target
= target
;
1086 add_service("gdb", CONNECTION_GDB
, gdb_port
+ i
, 1, gdb_new_connection
, gdb_input
, gdb_connection_closed
, gdb_service
);
1088 DEBUG("gdb service for target %s at port %i", target
->type
->name
, gdb_port
+ i
);
1090 target
= target
->next
;
1096 /* daemon configuration command gdb_port */
1097 int handle_gdb_port_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1102 /* only if the port wasn't overwritten by cmdline */
1104 gdb_port
= strtoul(args
[0], NULL
, 0);
1109 int gdb_register_commands(command_context_t
*command_context
)
1111 register_command(command_context
, NULL
, "gdb_port", handle_gdb_port_command
,
1112 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)