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::" );
320 numconv
=sscanf(packet
, "qSymbol:%" SCNx64
":%s", &value
, hex_name_str
);
324 // No value returned by GDB - symbol was not found
325 numconv
=sscanf(packet
, "qSymbol::%s", hex_name_str
);
327 name_str
= (char*) malloc( 1+ strlen(hex_name_str
) / 2 );
329 hex_to_str( name_str
, hex_name_str
);
333 while ( ( target
->rtos
->symbols
[ symbol_num
].symbol_name
!= NULL
) && ( 0 != strcmp( target
->rtos
->symbols
[ symbol_num
].symbol_name
, name_str
) ) )
339 if ( target
->rtos
->symbols
[ symbol_num
].symbol_name
== NULL
)
341 LOG_OUTPUT("ERROR: unknown symbol\r\n");
342 gdb_put_packet(connection
, "OK", 2);
346 target
->rtos
->symbols
[ symbol_num
].address
= value
;
348 next_symbol_num
= symbol_num
+1;
349 free( hex_name_str
);
354 int symbols_done
= 0;
355 if ( target
->rtos
->symbols
[ next_symbol_num
].symbol_name
== NULL
)
357 if ( ( target
->rtos_auto_detect
== false ) ||
358 ( 1 == target
->rtos
->type
->detect_rtos( target
) ) )
360 // Found correct RTOS or not autodetecting
361 if ( target
->rtos_auto_detect
== true )
363 LOG_OUTPUT( "Auto-detected RTOS: %s\r\n",target
->rtos
->type
->name
);
369 // Auto detecting RTOS and currently not found
370 if( 1 != rtos_try_next( target
) )
372 // No more RTOS's to try
378 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
385 if ( symbols_done
== 1 )
387 target
->rtos_auto_detect
= false;
388 target
->rtos
->type
->create( target
);
389 target
->rtos
->type
->update_threads(target
->rtos
);
390 // No more symbols needed
391 gdb_put_packet(connection
, "OK", 2);
397 char* symname
= target
->rtos
->symbols
[ next_symbol_num
].symbol_name
;
398 char qsymstr
[] = "qSymbol:";
399 char * opstring
= (char*)malloc(sizeof(qsymstr
)+strlen(symname
)*2+1);
400 char * posptr
= opstring
;
401 posptr
+= sprintf( posptr
, "%s", qsymstr
);
402 str_to_hex( posptr
, symname
);
403 gdb_put_packet(connection
, opstring
, strlen(opstring
));
409 gdb_put_packet(connection
, "OK", 2);
412 else if (strstr(packet
, "qfThreadInfo"))
415 if ( ( target
->rtos
!= NULL
) && ( target
->rtos
->thread_count
!= 0 ) )
418 char* out_str
= (char*) malloc(17 * target
->rtos
->thread_count
+ 5);
419 char* tmp_str
= out_str
;
420 tmp_str
+= sprintf(tmp_str
, "m");
421 for (i
= 0; i
< target
->rtos
->thread_count
; i
++) {
423 tmp_str
+= sprintf(tmp_str
, ",");
425 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
,
426 target
->rtos
->thread_details
[i
].threadid
);
429 gdb_put_packet(connection
, out_str
, strlen(out_str
));
433 gdb_put_packet(connection
, "", 0);
438 else if (strstr(packet
, "qsThreadInfo"))
440 gdb_put_packet(connection
, "l", 1);
443 else if (strstr(packet
, "qAttached"))
445 gdb_put_packet(connection
, "1", 1);
448 else if (strstr(packet
, "qOffsets"))
450 char offsets
[] = "Text=0;Data=0;Bss=0";
451 gdb_put_packet(connection
, offsets
, sizeof(offsets
)-1);
454 else if (strstr(packet
, "qC"))
456 gdb_put_packet(connection
, "QC0", 3);
459 else if ( packet
[0] == 'T' ) // Is thread alive?
463 sscanf(packet
, "T%" SCNx64
, &threadid
);
464 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
467 for (thread_num
= 0; thread_num
468 < target
->rtos
->thread_count
; thread_num
++) {
469 if (target
->rtos
->thread_details
[thread_num
].threadid
471 if (target
->rtos
->thread_details
[thread_num
].exists
) {
478 gdb_put_packet(connection
, "OK", 2); // thread alive
480 gdb_put_packet(connection
, "E01", 3); // thread not found
483 else if ( packet
[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations )
485 if (packet
[1] == 'g')
487 sscanf(packet
, "Hg%16" SCNx64
, ¤t_threadid
);
489 gdb_put_packet(connection
, "OK", 2);
492 return GDB_THREAD_PACKET_NOT_CONSUMED
;
495 int rtos_get_gdb_reg_list(struct connection
*connection
, struct target
*target
, struct reg
**reg_list
[], int *reg_list_size
)
497 if ( ( target
->rtos
!= NULL
) &&
498 ( current_threadid
!= -1 ) &&
499 ( current_threadid
!= 0 ) &&
500 ( current_threadid
!= target
->rtos
->current_thread
) )
503 target
->rtos
->type
->get_thread_reg_list( target
->rtos
, current_threadid
, &hex_reg_list
);
505 if ( hex_reg_list
!= NULL
)
507 gdb_put_packet(connection
, hex_reg_list
, strlen(hex_reg_list
));
517 int rtos_generic_stack_read( struct target
* target
, const struct rtos_register_stacking
* stacking
, int64_t stack_ptr
, char ** hex_reg_list
)
521 int64_t new_stack_ptr
;
527 LOG_OUTPUT("Error: null stack pointer in thread\r\n");
531 uint8_t * stack_data
= (uint8_t*) malloc( stacking
->stack_registers_size
);
532 uint32_t address
= stack_ptr
;
534 if ( stacking
->stack_growth_direction
== 1 )
536 address
-= stacking
->stack_registers_size
;
538 retval
= target_read_buffer( target
, address
, stacking
->stack_registers_size
, stack_data
);
539 if ( retval
!= ERROR_OK
)
541 LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
545 LOG_OUTPUT("Stack Data :");
546 for(i = 0; i < stacking->stack_registers_size; i++ )
548 LOG_OUTPUT("%02X",stack_data[i]);
552 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
554 list_size
+= stacking
->register_offsets
[i
].width_bits
/8;
556 *hex_reg_list
= (char*)malloc( list_size
*2 +1 );
557 tmp_str_ptr
= *hex_reg_list
;
558 new_stack_ptr
= stack_ptr
- stacking
->stack_growth_direction
* stacking
->stack_registers_size
;
559 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
562 for ( j
= 0; j
< stacking
->register_offsets
[i
].width_bits
/8; j
++ )
564 if ( stacking
->register_offsets
[i
].offset
== -1 )
566 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", 0 );
568 else if ( stacking
->register_offsets
[i
].offset
== -2 )
570 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", ((uint8_t*)&new_stack_ptr
)[j
] );
574 tmp_str_ptr
+= sprintf( tmp_str_ptr
,"%02x", stack_data
[ stacking
->register_offsets
[i
].offset
+ j
] );
578 // LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list);
582 int rtos_try_next( struct target
* target
)
586 if ( target
->rtos
== NULL
)
591 for (x
= 0 ; rtos_types
[x
] ; x
++) {
592 if (target
->rtos
->type
== rtos_types
[x
] ) {
594 if ( rtos_types
[x
+1] != NULL
)
596 target
->rtos
->type
= rtos_types
[x
+1];
597 if ( target
->rtos
->symbols
!= NULL
)
599 free( target
->rtos
->symbols
);
605 // No more rtos types
615 static void hex_to_str( char* dst
, char * hex_src
)
620 while ( hex_src
[src_pos
] != '\x00' )
622 char hex_char
= hex_src
[src_pos
];
623 char hex_digit_val
= (hex_char
>='a')?hex_char
-'a'+10:(hex_char
>='A')?hex_char
-'A'+10:hex_char
-'0';
624 if ( 0 == (src_pos
& 0x01) )
626 dst
[dst_pos
] = hex_digit_val
;
631 ((unsigned char*)dst
)[dst_pos
] <<= 4;
632 ((unsigned char*)dst
)[dst_pos
] += hex_digit_val
;
640 static int str_to_hex( char* hex_dst
, char* src
)
642 char * posptr
= hex_dst
;
644 for( i
= 0; i
< strlen(src
); i
++)
646 posptr
+= sprintf( posptr
, "%02x", (unsigned char)src
[i
] );
648 return (posptr
-hex_dst
);
652 int rtos_update_threads( struct target
* target
)
654 if ((target
->rtos
!= NULL
) && (target
->rtos
->type
!= NULL
))
656 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)