1 /***************************************************************************
2 * Copyright (C) 2011 by Broadcom Corporation *
3 * Evan Hunter - ehunter@broadcom.com *
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 ***************************************************************************/
27 #include "target/target.h"
28 #include "helper/log.h"
29 #include "server/gdb_server.h"
32 static int64_t current_threadid
= -1;
34 static void hex_to_str( char* dst
, char * hex_src
);
35 static int str_to_hex( char* hex_dst
, char* src
);
39 extern struct rtos_type FreeRTOS_rtos
;
40 extern struct rtos_type ThreadX_rtos
;
41 extern struct rtos_type eCos_rtos
;
43 static struct rtos_type
*rtos_types
[] =
52 int rtos_create(Jim_GetOptInfo
*goi
, struct target
* target
)
57 if (! goi
->isconfigure
) {
60 Jim_WrongNumArgs(goi
->interp
,
66 Jim_SetResultString(goi
->interp
,
67 target_type_name(target
), -1);
72 free((void *)(target
->rtos
));
74 // e = Jim_GetOpt_String(goi, &cp, NULL);
75 // target->rtos = strdup(cp);
77 Jim_GetOpt_String(goi
, &cp
, NULL
);
78 /* now does target type exist */
80 if ( 0 == strcmp( cp
, "auto") )
82 // auto detection of RTOS
83 target
->rtos_auto_detect
= true;
89 for (x
= 0 ; rtos_types
[x
] ; x
++) {
90 if (0 == strcmp(cp
, rtos_types
[x
]->name
)) {
95 if (rtos_types
[x
] == NULL
) {
96 Jim_SetResultFormatted(goi
->interp
, "Unknown rtos type %s, try one of ", cp
);
97 for (x
= 0 ; rtos_types
[x
] ; x
++) {
98 if (rtos_types
[x
+ 1]) {
99 Jim_AppendStrings(goi
->interp
,
100 Jim_GetResult(goi
->interp
),
104 Jim_AppendStrings(goi
->interp
,
105 Jim_GetResult(goi
->interp
),
107 rtos_types
[x
]->name
,NULL
);
114 target
->rtos
= calloc(1,sizeof(struct rtos
));
115 target
->rtos
->type
= rtos_types
[x
];
116 target
->rtos
->current_thread
= 0;
117 target
->rtos
->symbols
= NULL
;
118 target
->rtos
->target
= target
;
120 if ( 0 != strcmp( cp
, "auto") )
122 target
->rtos
->type
->create( target
);
131 int gdb_thread_packet(struct connection
*connection
, struct target
*target
, char *packet
, int packet_size
)
133 if (strstr(packet
, "qP"))
135 #define TAG_THREADID 1 /* Echo the thread identifier */
136 #define TAG_EXISTS 2 /* Is this process defined enough to
137 fetch registers and its stack */
138 #define TAG_DISPLAY 4 /* A short thing maybe to put on a window */
139 #define TAG_THREADNAME 8 /* string, maps 1-to-1 with a thread is */
140 #define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about */
142 // TODO: need to scanf the mode variable (or it with the tags), and the threadid
145 threadid_t threadid
= 0;
146 struct thread_detail
* detail
;
147 sscanf(packet
, "qP%8lx%16" SCNx64
, &mode
, &threadid
);
152 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
155 for (thread_num
= 0; thread_num
156 < target
->rtos
->thread_count
; thread_num
++) {
157 if (target
->rtos
->thread_details
[thread_num
].threadid
159 if (target
->rtos
->thread_details
[thread_num
].exists
) {
166 gdb_put_packet(connection
, "E01", 3); // thread not found
170 detail
= &target
->rtos
->thread_details
[found
];
172 if ( detail
->display_str
!= NULL
)
176 if ( detail
->thread_name_str
!= NULL
)
178 mode
&= TAG_THREADNAME
;
180 if ( detail
->extra_info_str
!= NULL
)
182 mode
&= TAG_MOREDISPLAY
;
186 mode
&= TAG_THREADID
| TAG_EXISTS
;
188 char thread_str
[1000];
190 sprintf(thread_str
, "%08lx", mode
);
191 sprintf(thread_str
, "%016" PRIx64
, threadid
);
194 if (mode
& TAG_THREADID
) {
195 sprintf(thread_str
, "%08" PRIx32
"10%016" PRIx64
, TAG_THREADID
, threadid
);
197 if (mode
& TAG_EXISTS
) {
198 sprintf(thread_str
, "%08" PRIx32
"08%08" PRIx32
, TAG_EXISTS
, (detail
->exists
==true)?1:0);
200 if (mode
& TAG_DISPLAY
) {
201 sprintf(thread_str
, "%08" PRIx32
"%02x%s", TAG_DISPLAY
, (unsigned char)strlen(detail
->display_str
), detail
->display_str
);
203 if (mode
& TAG_MOREDISPLAY
) {
204 sprintf(thread_str
, "%08" PRIx32
"%02x%s", TAG_MOREDISPLAY
, (unsigned char)strlen(detail
->extra_info_str
), detail
->extra_info_str
);
206 if (mode
& TAG_THREADNAME
) {
207 sprintf(thread_str
, "%08" PRIx32
"%02x%s", TAG_THREADNAME
, (unsigned char)strlen(detail
->thread_name_str
), detail
->thread_name_str
);
210 //gdb_put_packet(connection, tmpstr, sizeof(tmpstr)-1);
211 gdb_put_packet(connection
, thread_str
, strlen(thread_str
));
213 // gdb_put_packet(connection, "", 0);
214 // gdb_put_packet(connection, "OK", 2); // all threads alive
217 else if (strstr(packet
, "qThreadExtraInfo,"))
219 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
!= NULL
) && (target
->rtos
->thread_count
!= 0))
221 threadid_t threadid
= 0;
223 sscanf(packet
, "qThreadExtraInfo,%" SCNx64
, &threadid
);
225 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
228 for (thread_num
= 0; thread_num
229 < target
->rtos
->thread_count
; thread_num
++) {
230 if (target
->rtos
->thread_details
[thread_num
].threadid
232 if (target
->rtos
->thread_details
[thread_num
].exists
) {
239 gdb_put_packet(connection
, "E01", 3); // thread not found
243 struct thread_detail
* detail
= &target
->rtos
->thread_details
[found
];
246 if ( detail
->display_str
!= NULL
)
248 str_size
+= strlen(detail
->display_str
);
250 if ( detail
->thread_name_str
!= NULL
)
252 str_size
+= strlen(detail
->thread_name_str
);
254 if ( detail
->extra_info_str
!= NULL
)
256 str_size
+= strlen(detail
->extra_info_str
);
259 char * tmp_str
= (char*) malloc( str_size
+ 7 );
260 char* tmp_str_ptr
= tmp_str
;
262 if ( detail
->display_str
!= NULL
)
264 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%s", detail
->display_str
);
266 if ( detail
->thread_name_str
!= NULL
)
268 if ( tmp_str_ptr
!= tmp_str
)
270 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : " );
272 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%s", detail
->thread_name_str
);
274 if ( detail
->extra_info_str
!= NULL
)
276 if ( tmp_str_ptr
!= tmp_str
)
278 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : " );
280 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : %s", detail
->extra_info_str
);
283 char * hex_str
= (char*) malloc( strlen(tmp_str
)*2 +1 );
284 str_to_hex( hex_str
, tmp_str
);
286 gdb_put_packet(connection
, hex_str
, strlen(hex_str
));
292 gdb_put_packet(connection
, "", 0);
295 else if (strstr(packet
, "qSymbol"))
297 if ( target
->rtos
!= NULL
)
299 int next_symbol_num
= -1;
300 if (target
->rtos
->symbols
== NULL
)
302 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
304 if (0 == strcmp( "qSymbol::", packet
) )
312 char * hex_name_str
= malloc( strlen(packet
));
316 char* found
= strstr( packet
, "qSymbol::" );
319 sscanf(packet
, "qSymbol:%" SCNx64
":%s", &value
, hex_name_str
);
323 // No value returned by GDB - symbol was not found
324 sscanf(packet
, "qSymbol::%s", hex_name_str
);
326 name_str
= (char*) malloc( 1+ strlen(hex_name_str
) / 2 );
328 hex_to_str( name_str
, hex_name_str
);
332 while ( ( target
->rtos
->symbols
[ symbol_num
].symbol_name
!= NULL
) && ( 0 != strcmp( target
->rtos
->symbols
[ symbol_num
].symbol_name
, name_str
) ) )
338 if ( target
->rtos
->symbols
[ symbol_num
].symbol_name
== NULL
)
340 LOG_OUTPUT("ERROR: unknown symbol\r\n");
341 gdb_put_packet(connection
, "OK", 2);
345 target
->rtos
->symbols
[ symbol_num
].address
= value
;
347 next_symbol_num
= symbol_num
+1;
348 free( hex_name_str
);
353 int symbols_done
= 0;
354 if ( target
->rtos
->symbols
[ next_symbol_num
].symbol_name
== NULL
)
356 if ( ( target
->rtos_auto_detect
== false ) ||
357 ( 1 == target
->rtos
->type
->detect_rtos( target
) ) )
359 // Found correct RTOS or not autodetecting
360 if ( target
->rtos_auto_detect
== true )
362 LOG_OUTPUT( "Auto-detected RTOS: %s\r\n",target
->rtos
->type
->name
);
368 // Auto detecting RTOS and currently not found
369 if( 1 != rtos_try_next( target
) )
371 // No more RTOS's to try
377 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
384 if ( symbols_done
== 1 )
386 target
->rtos_auto_detect
= false;
387 target
->rtos
->type
->create( target
);
388 target
->rtos
->type
->update_threads(target
->rtos
);
389 // No more symbols needed
390 gdb_put_packet(connection
, "OK", 2);
396 char* symname
= target
->rtos
->symbols
[ next_symbol_num
].symbol_name
;
397 char qsymstr
[] = "qSymbol:";
398 char * opstring
= (char*)malloc(sizeof(qsymstr
)+strlen(symname
)*2+1);
399 char * posptr
= opstring
;
400 posptr
+= sprintf( posptr
, "%s", qsymstr
);
401 str_to_hex( posptr
, symname
);
402 gdb_put_packet(connection
, opstring
, strlen(opstring
));
408 gdb_put_packet(connection
, "OK", 2);
411 else if (strstr(packet
, "qfThreadInfo"))
414 if ( ( target
->rtos
!= NULL
) && ( target
->rtos
->thread_count
!= 0 ) )
417 char* out_str
= (char*) malloc(17 * target
->rtos
->thread_count
+ 5);
418 char* tmp_str
= out_str
;
419 tmp_str
+= sprintf(tmp_str
, "m");
420 for (i
= 0; i
< target
->rtos
->thread_count
; i
++) {
422 tmp_str
+= sprintf(tmp_str
, ",");
424 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
,
425 target
->rtos
->thread_details
[i
].threadid
);
428 gdb_put_packet(connection
, out_str
, strlen(out_str
));
432 gdb_put_packet(connection
, "", 0);
437 else if (strstr(packet
, "qsThreadInfo"))
439 gdb_put_packet(connection
, "l", 1);
442 else if (strstr(packet
, "qAttached"))
444 gdb_put_packet(connection
, "1", 1);
447 else if (strstr(packet
, "qOffsets"))
449 char offsets
[] = "Text=0;Data=0;Bss=0";
450 gdb_put_packet(connection
, offsets
, sizeof(offsets
)-1);
453 else if (strstr(packet
, "qC"))
455 if( target
->rtos
!=NULL
)
459 size
= snprintf(buffer
, 15, "QC%08X", (int)target
->rtos
->current_thread
);
460 gdb_put_packet(connection
, buffer
, size
);
464 gdb_put_packet(connection
, "QC0", 3);
468 else if ( packet
[0] == 'T' ) // Is thread alive?
472 sscanf(packet
, "T%" SCNx64
, &threadid
);
473 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
476 for (thread_num
= 0; thread_num
477 < target
->rtos
->thread_count
; thread_num
++) {
478 if (target
->rtos
->thread_details
[thread_num
].threadid
480 if (target
->rtos
->thread_details
[thread_num
].exists
) {
487 gdb_put_packet(connection
, "OK", 2); // thread alive
489 gdb_put_packet(connection
, "E01", 3); // thread not found
492 else if ( packet
[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations )
494 if (packet
[1] == 'g')
496 sscanf(packet
, "Hg%16" SCNx64
, ¤t_threadid
);
498 gdb_put_packet(connection
, "OK", 2);
501 return GDB_THREAD_PACKET_NOT_CONSUMED
;
504 int rtos_get_gdb_reg_list(struct connection
*connection
, struct target
*target
, struct reg
**reg_list
[], int *reg_list_size
)
506 if ( ( target
->rtos
!= NULL
) &&
507 ( current_threadid
!= -1 ) &&
508 ( current_threadid
!= 0 ) &&
509 ( current_threadid
!= target
->rtos
->current_thread
) )
512 target
->rtos
->type
->get_thread_reg_list( target
->rtos
, current_threadid
, &hex_reg_list
);
514 if ( hex_reg_list
!= NULL
)
516 gdb_put_packet(connection
, hex_reg_list
, strlen(hex_reg_list
));
526 int rtos_generic_stack_read( struct target
* target
, const struct rtos_register_stacking
* stacking
, int64_t stack_ptr
, char ** hex_reg_list
)
530 int64_t new_stack_ptr
;
536 LOG_OUTPUT("Error: null stack pointer in thread\r\n");
540 uint8_t * stack_data
= (uint8_t*) malloc( stacking
->stack_registers_size
);
541 uint32_t address
= stack_ptr
;
543 if ( stacking
->stack_growth_direction
== 1 )
545 address
-= stacking
->stack_registers_size
;
547 retval
= target_read_buffer( target
, address
, stacking
->stack_registers_size
, stack_data
);
548 if ( retval
!= ERROR_OK
)
550 LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
554 LOG_OUTPUT("Stack Data :");
555 for(i = 0; i < stacking->stack_registers_size; i++ )
557 LOG_OUTPUT("%02X",stack_data[i]);
561 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
563 list_size
+= stacking
->register_offsets
[i
].width_bits
/8;
565 *hex_reg_list
= (char*)malloc( list_size
*2 +1 );
566 tmp_str_ptr
= *hex_reg_list
;
567 new_stack_ptr
= stack_ptr
- stacking
->stack_growth_direction
* stacking
->stack_registers_size
;
568 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
571 for ( j
= 0; j
< stacking
->register_offsets
[i
].width_bits
/8; j
++ )
573 if ( stacking
->register_offsets
[i
].offset
== -1 )
575 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", 0 );
577 else if ( stacking
->register_offsets
[i
].offset
== -2 )
579 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", ((uint8_t*)&new_stack_ptr
)[j
] );
583 tmp_str_ptr
+= sprintf( tmp_str_ptr
,"%02x", stack_data
[ stacking
->register_offsets
[i
].offset
+ j
] );
587 // LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list);
591 int rtos_try_next( struct target
* target
)
595 if ( target
->rtos
== NULL
)
600 for (x
= 0 ; rtos_types
[x
] ; x
++) {
601 if (target
->rtos
->type
== rtos_types
[x
] ) {
603 if ( rtos_types
[x
+1] != NULL
)
605 target
->rtos
->type
= rtos_types
[x
+1];
606 if ( target
->rtos
->symbols
!= NULL
)
608 free( target
->rtos
->symbols
);
614 // No more rtos types
624 static void hex_to_str( char* dst
, char * hex_src
)
629 while ( hex_src
[src_pos
] != '\x00' )
631 char hex_char
= hex_src
[src_pos
];
632 char hex_digit_val
= (hex_char
>='a')?hex_char
-'a'+10:(hex_char
>='A')?hex_char
-'A'+10:hex_char
-'0';
633 if ( 0 == (src_pos
& 0x01) )
635 dst
[dst_pos
] = hex_digit_val
;
640 ((unsigned char*)dst
)[dst_pos
] <<= 4;
641 ((unsigned char*)dst
)[dst_pos
] += hex_digit_val
;
649 static int str_to_hex( char* hex_dst
, char* src
)
651 char * posptr
= hex_dst
;
653 for( i
= 0; i
< strlen(src
); i
++)
655 posptr
+= sprintf( posptr
, "%02x", (unsigned char)src
[i
] );
657 return (posptr
-hex_dst
);
661 int rtos_update_threads( struct target
* target
)
663 if ((target
->rtos
!= NULL
) && (target
->rtos
->type
!= NULL
))
665 target
->rtos
->type
->update_threads(target
->rtos
);
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)