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
, char *packet
, int packet_size
)
133 struct target
*target
= get_target_from_connection(connection
);
135 if (strstr(packet
, "qP"))
137 #define TAG_THREADID 1 /* Echo the thread identifier */
138 #define TAG_EXISTS 2 /* Is this process defined enough to
139 fetch registers and its stack */
140 #define TAG_DISPLAY 4 /* A short thing maybe to put on a window */
141 #define TAG_THREADNAME 8 /* string, maps 1-to-1 with a thread is */
142 #define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about */
144 // TODO: need to scanf the mode variable (or it with the tags), and the threadid
147 threadid_t threadid
= 0;
148 struct thread_detail
* detail
;
149 sscanf(packet
, "qP%8lx%16" SCNx64
, &mode
, &threadid
);
154 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
157 for (thread_num
= 0; thread_num
158 < target
->rtos
->thread_count
; thread_num
++) {
159 if (target
->rtos
->thread_details
[thread_num
].threadid
161 if (target
->rtos
->thread_details
[thread_num
].exists
) {
168 gdb_put_packet(connection
, "E01", 3); // thread not found
172 detail
= &target
->rtos
->thread_details
[found
];
174 if ( detail
->display_str
!= NULL
)
178 if ( detail
->thread_name_str
!= NULL
)
180 mode
&= TAG_THREADNAME
;
182 if ( detail
->extra_info_str
!= NULL
)
184 mode
&= TAG_MOREDISPLAY
;
188 mode
&= TAG_THREADID
| TAG_EXISTS
;
190 char thread_str
[1000];
192 sprintf(thread_str
, "%08lx", mode
);
193 sprintf(thread_str
, "%016" PRIx64
, threadid
);
196 if (mode
& TAG_THREADID
) {
197 sprintf(thread_str
, "%08" PRIx32
"10%016" PRIx64
, TAG_THREADID
, threadid
);
199 if (mode
& TAG_EXISTS
) {
200 sprintf(thread_str
, "%08" PRIx32
"08%08" PRIx32
, TAG_EXISTS
, (detail
->exists
==true)?1:0);
202 if (mode
& TAG_DISPLAY
) {
203 sprintf(thread_str
, "%08" PRIx32
"%02x%s", TAG_DISPLAY
, (unsigned char)strlen(detail
->display_str
), detail
->display_str
);
205 if (mode
& TAG_MOREDISPLAY
) {
206 sprintf(thread_str
, "%08" PRIx32
"%02x%s", TAG_MOREDISPLAY
, (unsigned char)strlen(detail
->extra_info_str
), detail
->extra_info_str
);
208 if (mode
& TAG_THREADNAME
) {
209 sprintf(thread_str
, "%08" PRIx32
"%02x%s", TAG_THREADNAME
, (unsigned char)strlen(detail
->thread_name_str
), detail
->thread_name_str
);
212 //gdb_put_packet(connection, tmpstr, sizeof(tmpstr)-1);
213 gdb_put_packet(connection
, thread_str
, strlen(thread_str
));
215 // gdb_put_packet(connection, "", 0);
216 // gdb_put_packet(connection, "OK", 2); // all threads alive
219 else if (strstr(packet
, "qThreadExtraInfo,"))
221 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
!= NULL
) && (target
->rtos
->thread_count
!= 0))
223 threadid_t threadid
= 0;
225 sscanf(packet
, "qThreadExtraInfo,%" SCNx64
, &threadid
);
227 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
230 for (thread_num
= 0; thread_num
231 < target
->rtos
->thread_count
; thread_num
++) {
232 if (target
->rtos
->thread_details
[thread_num
].threadid
234 if (target
->rtos
->thread_details
[thread_num
].exists
) {
241 gdb_put_packet(connection
, "E01", 3); // thread not found
245 struct thread_detail
* detail
= &target
->rtos
->thread_details
[found
];
248 if ( detail
->display_str
!= NULL
)
250 str_size
+= strlen(detail
->display_str
);
252 if ( detail
->thread_name_str
!= NULL
)
254 str_size
+= strlen(detail
->thread_name_str
);
256 if ( detail
->extra_info_str
!= NULL
)
258 str_size
+= strlen(detail
->extra_info_str
);
261 char * tmp_str
= (char*) malloc( str_size
+ 7 );
262 char* tmp_str_ptr
= tmp_str
;
264 if ( detail
->display_str
!= NULL
)
266 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%s", detail
->display_str
);
268 if ( detail
->thread_name_str
!= NULL
)
270 if ( tmp_str_ptr
!= tmp_str
)
272 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : " );
274 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%s", detail
->thread_name_str
);
276 if ( detail
->extra_info_str
!= NULL
)
278 if ( tmp_str_ptr
!= tmp_str
)
280 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : " );
282 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : %s", detail
->extra_info_str
);
285 char * hex_str
= (char*) malloc( strlen(tmp_str
)*2 +1 );
286 str_to_hex( hex_str
, tmp_str
);
288 gdb_put_packet(connection
, hex_str
, strlen(hex_str
));
294 gdb_put_packet(connection
, "", 0);
297 else if (strstr(packet
, "qSymbol"))
299 if ( target
->rtos
!= NULL
)
301 int next_symbol_num
= -1;
302 if (target
->rtos
->symbols
== NULL
)
304 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
306 if (0 == strcmp( "qSymbol::", packet
) )
314 char * hex_name_str
= malloc( strlen(packet
));
318 char* found
= strstr( packet
, "qSymbol::" );
321 sscanf(packet
, "qSymbol:%" SCNx64
":%s", &value
, hex_name_str
);
325 // No value returned by GDB - symbol was not found
326 sscanf(packet
, "qSymbol::%s", hex_name_str
);
328 name_str
= (char*) malloc( 1+ strlen(hex_name_str
) / 2 );
330 hex_to_str( name_str
, hex_name_str
);
334 while ( ( target
->rtos
->symbols
[ symbol_num
].symbol_name
!= NULL
) && ( 0 != strcmp( target
->rtos
->symbols
[ symbol_num
].symbol_name
, name_str
) ) )
340 if ( target
->rtos
->symbols
[ symbol_num
].symbol_name
== NULL
)
342 LOG_OUTPUT("ERROR: unknown symbol\r\n");
343 gdb_put_packet(connection
, "OK", 2);
347 target
->rtos
->symbols
[ symbol_num
].address
= value
;
349 next_symbol_num
= symbol_num
+1;
350 free( hex_name_str
);
355 int symbols_done
= 0;
356 if ( target
->rtos
->symbols
[ next_symbol_num
].symbol_name
== NULL
)
358 if ( ( target
->rtos_auto_detect
== false ) ||
359 ( 1 == target
->rtos
->type
->detect_rtos( target
) ) )
361 // Found correct RTOS or not autodetecting
362 if ( target
->rtos_auto_detect
== true )
364 LOG_OUTPUT( "Auto-detected RTOS: %s\r\n",target
->rtos
->type
->name
);
370 // Auto detecting RTOS and currently not found
371 if( 1 != rtos_try_next( target
) )
373 // No more RTOS's to try
379 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
386 if ( symbols_done
== 1 )
388 target
->rtos_auto_detect
= false;
389 target
->rtos
->type
->create( target
);
390 target
->rtos
->type
->update_threads(target
->rtos
);
391 // No more symbols needed
392 gdb_put_packet(connection
, "OK", 2);
398 char* symname
= target
->rtos
->symbols
[ next_symbol_num
].symbol_name
;
399 char qsymstr
[] = "qSymbol:";
400 char * opstring
= (char*)malloc(sizeof(qsymstr
)+strlen(symname
)*2+1);
401 char * posptr
= opstring
;
402 posptr
+= sprintf( posptr
, "%s", qsymstr
);
403 str_to_hex( posptr
, symname
);
404 gdb_put_packet(connection
, opstring
, strlen(opstring
));
410 gdb_put_packet(connection
, "OK", 2);
413 else if (strstr(packet
, "qfThreadInfo"))
416 if ( ( target
->rtos
!= NULL
) && ( target
->rtos
->thread_count
!= 0 ) )
419 char* out_str
= (char*) malloc(17 * target
->rtos
->thread_count
+ 5);
420 char* tmp_str
= out_str
;
421 tmp_str
+= sprintf(tmp_str
, "m");
422 for (i
= 0; i
< target
->rtos
->thread_count
; i
++) {
424 tmp_str
+= sprintf(tmp_str
, ",");
426 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
,
427 target
->rtos
->thread_details
[i
].threadid
);
430 gdb_put_packet(connection
, out_str
, strlen(out_str
));
434 gdb_put_packet(connection
, "", 0);
439 else if (strstr(packet
, "qsThreadInfo"))
441 gdb_put_packet(connection
, "l", 1);
444 else if (strstr(packet
, "qAttached"))
446 gdb_put_packet(connection
, "1", 1);
449 else if (strstr(packet
, "qOffsets"))
451 char offsets
[] = "Text=0;Data=0;Bss=0";
452 gdb_put_packet(connection
, offsets
, sizeof(offsets
)-1);
455 else if (strstr(packet
, "qC"))
457 if( target
->rtos
!=NULL
)
461 size
= snprintf(buffer
, 15, "QC%08X", (int)target
->rtos
->current_thread
);
462 gdb_put_packet(connection
, buffer
, size
);
466 gdb_put_packet(connection
, "QC0", 3);
470 else if ( packet
[0] == 'T' ) // Is thread alive?
474 sscanf(packet
, "T%" SCNx64
, &threadid
);
475 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
478 for (thread_num
= 0; thread_num
479 < target
->rtos
->thread_count
; thread_num
++) {
480 if (target
->rtos
->thread_details
[thread_num
].threadid
482 if (target
->rtos
->thread_details
[thread_num
].exists
) {
489 gdb_put_packet(connection
, "OK", 2); // thread alive
491 gdb_put_packet(connection
, "E01", 3); // thread not found
495 else if ( packet
[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations )
497 if (packet
[1] == 'g')
499 sscanf(packet
, "Hg%16" SCNx64
, ¤t_threadid
);
501 gdb_put_packet(connection
, "OK", 2);
505 return GDB_THREAD_PACKET_NOT_CONSUMED
;
508 int rtos_get_gdb_reg_list(struct connection
*connection
, struct reg
**reg_list
[], int *reg_list_size
)
510 struct target
*target
= get_target_from_connection(connection
);
512 if ( ( target
->rtos
!= NULL
) &&
513 ( current_threadid
!= -1 ) &&
514 ( current_threadid
!= 0 ) &&
515 ( current_threadid
!= target
->rtos
->current_thread
) )
518 target
->rtos
->type
->get_thread_reg_list( target
->rtos
, current_threadid
, &hex_reg_list
);
520 if ( hex_reg_list
!= NULL
)
522 gdb_put_packet(connection
, hex_reg_list
, strlen(hex_reg_list
));
532 int rtos_generic_stack_read( struct target
* target
, const struct rtos_register_stacking
* stacking
, int64_t stack_ptr
, char ** hex_reg_list
)
536 int64_t new_stack_ptr
;
542 LOG_OUTPUT("Error: null stack pointer in thread\r\n");
546 uint8_t * stack_data
= (uint8_t*) malloc( stacking
->stack_registers_size
);
547 uint32_t address
= stack_ptr
;
549 if ( stacking
->stack_growth_direction
== 1 )
551 address
-= stacking
->stack_registers_size
;
553 retval
= target_read_buffer( target
, address
, stacking
->stack_registers_size
, stack_data
);
554 if ( retval
!= ERROR_OK
)
556 LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
560 LOG_OUTPUT("Stack Data :");
561 for(i = 0; i < stacking->stack_registers_size; i++ )
563 LOG_OUTPUT("%02X",stack_data[i]);
567 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
569 list_size
+= stacking
->register_offsets
[i
].width_bits
/8;
571 *hex_reg_list
= (char*)malloc( list_size
*2 +1 );
572 tmp_str_ptr
= *hex_reg_list
;
573 new_stack_ptr
= stack_ptr
- stacking
->stack_growth_direction
* stacking
->stack_registers_size
;
574 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
577 for ( j
= 0; j
< stacking
->register_offsets
[i
].width_bits
/8; j
++ )
579 if ( stacking
->register_offsets
[i
].offset
== -1 )
581 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", 0 );
583 else if ( stacking
->register_offsets
[i
].offset
== -2 )
585 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", ((uint8_t*)&new_stack_ptr
)[j
] );
589 tmp_str_ptr
+= sprintf( tmp_str_ptr
,"%02x", stack_data
[ stacking
->register_offsets
[i
].offset
+ j
] );
593 // LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list);
597 int rtos_try_next( struct target
* target
)
601 if ( target
->rtos
== NULL
)
606 for (x
= 0 ; rtos_types
[x
] ; x
++) {
607 if (target
->rtos
->type
== rtos_types
[x
] ) {
609 if ( rtos_types
[x
+1] != NULL
)
611 target
->rtos
->type
= rtos_types
[x
+1];
612 if ( target
->rtos
->symbols
!= NULL
)
614 free( target
->rtos
->symbols
);
620 // No more rtos types
630 static void hex_to_str( char* dst
, char * hex_src
)
635 while ( hex_src
[src_pos
] != '\x00' )
637 char hex_char
= hex_src
[src_pos
];
638 char hex_digit_val
= (hex_char
>='a')?hex_char
-'a'+10:(hex_char
>='A')?hex_char
-'A'+10:hex_char
-'0';
639 if ( 0 == (src_pos
& 0x01) )
641 dst
[dst_pos
] = hex_digit_val
;
646 ((unsigned char*)dst
)[dst_pos
] <<= 4;
647 ((unsigned char*)dst
)[dst_pos
] += hex_digit_val
;
655 static int str_to_hex( char* hex_dst
, char* src
)
657 char * posptr
= hex_dst
;
659 for( i
= 0; i
< strlen(src
); i
++)
661 posptr
+= sprintf( posptr
, "%02x", (unsigned char)src
[i
] );
663 return (posptr
-hex_dst
);
667 int rtos_update_threads( struct target
* target
)
669 if ((target
->rtos
!= NULL
) && (target
->rtos
->type
!= NULL
))
671 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)