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 if( target
->rtos
!=NULL
)
460 size
= snprintf(buffer
, 15, "QC%08X", (int)target
->rtos
->current_thread
);
461 gdb_put_packet(connection
, buffer
, size
);
465 gdb_put_packet(connection
, "QC0", 3);
469 else if ( packet
[0] == 'T' ) // Is thread alive?
473 sscanf(packet
, "T%" SCNx64
, &threadid
);
474 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
477 for (thread_num
= 0; thread_num
478 < target
->rtos
->thread_count
; thread_num
++) {
479 if (target
->rtos
->thread_details
[thread_num
].threadid
481 if (target
->rtos
->thread_details
[thread_num
].exists
) {
488 gdb_put_packet(connection
, "OK", 2); // thread alive
490 gdb_put_packet(connection
, "E01", 3); // thread not found
493 else if ( packet
[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations )
495 if (packet
[1] == 'g')
497 sscanf(packet
, "Hg%16" SCNx64
, ¤t_threadid
);
499 gdb_put_packet(connection
, "OK", 2);
502 return GDB_THREAD_PACKET_NOT_CONSUMED
;
505 int rtos_get_gdb_reg_list(struct connection
*connection
, struct target
*target
, struct reg
**reg_list
[], int *reg_list_size
)
507 if ( ( target
->rtos
!= NULL
) &&
508 ( current_threadid
!= -1 ) &&
509 ( current_threadid
!= 0 ) &&
510 ( current_threadid
!= target
->rtos
->current_thread
) )
513 target
->rtos
->type
->get_thread_reg_list( target
->rtos
, current_threadid
, &hex_reg_list
);
515 if ( hex_reg_list
!= NULL
)
517 gdb_put_packet(connection
, hex_reg_list
, strlen(hex_reg_list
));
527 int rtos_generic_stack_read( struct target
* target
, const struct rtos_register_stacking
* stacking
, int64_t stack_ptr
, char ** hex_reg_list
)
531 int64_t new_stack_ptr
;
537 LOG_OUTPUT("Error: null stack pointer in thread\r\n");
541 uint8_t * stack_data
= (uint8_t*) malloc( stacking
->stack_registers_size
);
542 uint32_t address
= stack_ptr
;
544 if ( stacking
->stack_growth_direction
== 1 )
546 address
-= stacking
->stack_registers_size
;
548 retval
= target_read_buffer( target
, address
, stacking
->stack_registers_size
, stack_data
);
549 if ( retval
!= ERROR_OK
)
551 LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
555 LOG_OUTPUT("Stack Data :");
556 for(i = 0; i < stacking->stack_registers_size; i++ )
558 LOG_OUTPUT("%02X",stack_data[i]);
562 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
564 list_size
+= stacking
->register_offsets
[i
].width_bits
/8;
566 *hex_reg_list
= (char*)malloc( list_size
*2 +1 );
567 tmp_str_ptr
= *hex_reg_list
;
568 new_stack_ptr
= stack_ptr
- stacking
->stack_growth_direction
* stacking
->stack_registers_size
;
569 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
572 for ( j
= 0; j
< stacking
->register_offsets
[i
].width_bits
/8; j
++ )
574 if ( stacking
->register_offsets
[i
].offset
== -1 )
576 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", 0 );
578 else if ( stacking
->register_offsets
[i
].offset
== -2 )
580 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", ((uint8_t*)&new_stack_ptr
)[j
] );
584 tmp_str_ptr
+= sprintf( tmp_str_ptr
,"%02x", stack_data
[ stacking
->register_offsets
[i
].offset
+ j
] );
588 // LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list);
592 int rtos_try_next( struct target
* target
)
596 if ( target
->rtos
== NULL
)
601 for (x
= 0 ; rtos_types
[x
] ; x
++) {
602 if (target
->rtos
->type
== rtos_types
[x
] ) {
604 if ( rtos_types
[x
+1] != NULL
)
606 target
->rtos
->type
= rtos_types
[x
+1];
607 if ( target
->rtos
->symbols
!= NULL
)
609 free( target
->rtos
->symbols
);
615 // No more rtos types
625 static void hex_to_str( char* dst
, char * hex_src
)
630 while ( hex_src
[src_pos
] != '\x00' )
632 char hex_char
= hex_src
[src_pos
];
633 char hex_digit_val
= (hex_char
>='a')?hex_char
-'a'+10:(hex_char
>='A')?hex_char
-'A'+10:hex_char
-'0';
634 if ( 0 == (src_pos
& 0x01) )
636 dst
[dst_pos
] = hex_digit_val
;
641 ((unsigned char*)dst
)[dst_pos
] <<= 4;
642 ((unsigned char*)dst
)[dst_pos
] += hex_digit_val
;
650 static int str_to_hex( char* hex_dst
, char* src
)
652 char * posptr
= hex_dst
;
654 for( i
= 0; i
< strlen(src
); i
++)
656 posptr
+= sprintf( posptr
, "%02x", (unsigned char)src
[i
] );
658 return (posptr
-hex_dst
);
662 int rtos_update_threads( struct target
* target
)
664 if ((target
->rtos
!= NULL
) && (target
->rtos
->type
!= NULL
))
666 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)