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 long long 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
;
42 static struct rtos_type
*rtos_types
[] =
50 int rtos_create(Jim_GetOptInfo
*goi
, struct target
* target
)
55 if (! goi
->isconfigure
) {
58 Jim_WrongNumArgs(goi
->interp
,
64 Jim_SetResultString(goi
->interp
,
65 target_type_name(target
), -1);
70 free((void *)(target
->rtos
));
72 // e = Jim_GetOpt_String(goi, &cp, NULL);
73 // target->rtos = strdup(cp);
75 Jim_GetOpt_String(goi
, &cp
, NULL
);
76 /* now does target type exist */
78 if ( 0 == strcmp( cp
, "auto") )
80 // auto detection of RTOS
81 target
->rtos_auto_detect
= true;
87 for (x
= 0 ; rtos_types
[x
] ; x
++) {
88 if (0 == strcmp(cp
, rtos_types
[x
]->name
)) {
93 if (rtos_types
[x
] == NULL
) {
94 Jim_SetResultFormatted(goi
->interp
, "Unknown rtos type %s, try one of ", cp
);
95 for (x
= 0 ; rtos_types
[x
] ; x
++) {
96 if (rtos_types
[x
+ 1]) {
97 Jim_AppendStrings(goi
->interp
,
98 Jim_GetResult(goi
->interp
),
102 Jim_AppendStrings(goi
->interp
,
103 Jim_GetResult(goi
->interp
),
105 rtos_types
[x
]->name
,NULL
);
112 target
->rtos
= calloc(1,sizeof(struct rtos
));
113 target
->rtos
->type
= rtos_types
[x
];
114 target
->rtos
->current_thread
= 0;
115 target
->rtos
->symbols
= NULL
;
116 target
->rtos
->target
= target
;
118 if ( 0 != strcmp( cp
, "auto") )
120 target
->rtos
->type
->create( target
);
129 int gdb_thread_packet(struct connection
*connection
, struct target
*target
, char *packet
, int packet_size
)
131 if (strstr(packet
, "qP"))
133 #define TAG_THREADID 1 /* Echo the thread identifier */
134 #define TAG_EXISTS 2 /* Is this process defined enough to
135 fetch registers and its stack */
136 #define TAG_DISPLAY 4 /* A short thing maybe to put on a window */
137 #define TAG_THREADNAME 8 /* string, maps 1-to-1 with a thread is */
138 #define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about */
140 // TODO: need to scanf the mode variable (or it with the tags), and the threadid
143 threadid_t threadid
= 0;
144 struct thread_detail
* detail
;
145 sscanf(packet
, "qP%8lx%16" SCNx64
, &mode
, &threadid
);
150 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
153 for (thread_num
= 0; thread_num
154 < target
->rtos
->thread_count
; thread_num
++) {
155 if (target
->rtos
->thread_details
[thread_num
].threadid
157 if (target
->rtos
->thread_details
[thread_num
].exists
) {
164 gdb_put_packet(connection
, "E01", 3); // thread not found
168 detail
= &target
->rtos
->thread_details
[found
];
170 if ( detail
->display_str
!= NULL
)
174 if ( detail
->thread_name_str
!= NULL
)
176 mode
&= TAG_THREADNAME
;
178 if ( detail
->extra_info_str
!= NULL
)
180 mode
&= TAG_MOREDISPLAY
;
184 mode
&= TAG_THREADID
| TAG_EXISTS
;
186 char thread_str
[1000];
188 sprintf(thread_str
, "%08lx", mode
);
189 sprintf(thread_str
, "%016" PRIx64
, threadid
);
192 if (mode
& TAG_THREADID
) {
193 sprintf(thread_str
, "%08" PRIx32
"10%016" PRIx64
, TAG_THREADID
, threadid
);
195 if (mode
& TAG_EXISTS
) {
196 sprintf(thread_str
, "%08" PRIx32
"08%08" PRIx32
, TAG_EXISTS
, (detail
->exists
==true)?1:0);
198 if (mode
& TAG_DISPLAY
) {
199 sprintf(thread_str
, "%08" PRIx32
"%02x%s", TAG_DISPLAY
, (unsigned char)strlen(detail
->display_str
), detail
->display_str
);
201 if (mode
& TAG_MOREDISPLAY
) {
202 sprintf(thread_str
, "%08" PRIx32
"%02x%s", TAG_MOREDISPLAY
, (unsigned char)strlen(detail
->extra_info_str
), detail
->extra_info_str
);
204 if (mode
& TAG_THREADNAME
) {
205 sprintf(thread_str
, "%08" PRIx32
"%02x%s", TAG_THREADNAME
, (unsigned char)strlen(detail
->thread_name_str
), detail
->thread_name_str
);
208 //gdb_put_packet(connection, tmpstr, sizeof(tmpstr)-1);
209 gdb_put_packet(connection
, thread_str
, strlen(thread_str
));
211 // gdb_put_packet(connection, "", 0);
212 // gdb_put_packet(connection, "OK", 2); // all threads alive
215 else if (strstr(packet
, "qThreadExtraInfo,"))
217 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
!= NULL
) && (target
->rtos
->thread_count
!= 0))
219 threadid_t threadid
= 0;
221 sscanf(packet
, "qThreadExtraInfo,%" SCNx64
, &threadid
);
223 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
226 for (thread_num
= 0; thread_num
227 < target
->rtos
->thread_count
; thread_num
++) {
228 if (target
->rtos
->thread_details
[thread_num
].threadid
230 if (target
->rtos
->thread_details
[thread_num
].exists
) {
237 gdb_put_packet(connection
, "E01", 3); // thread not found
241 struct thread_detail
* detail
= &target
->rtos
->thread_details
[found
];
244 if ( detail
->display_str
!= NULL
)
246 str_size
+= strlen(detail
->display_str
);
248 if ( detail
->thread_name_str
!= NULL
)
250 str_size
+= strlen(detail
->thread_name_str
);
252 if ( detail
->extra_info_str
!= NULL
)
254 str_size
+= strlen(detail
->extra_info_str
);
257 char * tmp_str
= (char*) malloc( str_size
+ 7 );
258 char* tmp_str_ptr
= tmp_str
;
260 if ( detail
->display_str
!= NULL
)
262 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%s", detail
->display_str
);
264 if ( detail
->thread_name_str
!= NULL
)
266 if ( tmp_str_ptr
!= tmp_str
)
268 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : " );
270 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%s", detail
->thread_name_str
);
272 if ( detail
->extra_info_str
!= NULL
)
274 if ( tmp_str_ptr
!= tmp_str
)
276 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : " );
278 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : %s", detail
->extra_info_str
);
281 char * hex_str
= (char*) malloc( strlen(tmp_str
)*2 +1 );
282 str_to_hex( hex_str
, tmp_str
);
284 gdb_put_packet(connection
, hex_str
, strlen(hex_str
));
290 gdb_put_packet(connection
, "", 0);
293 else if (strstr(packet
, "qSymbol"))
295 if ( target
->rtos
!= NULL
)
297 int next_symbol_num
= -1;
298 if (target
->rtos
->symbols
== NULL
)
300 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
302 if (0 == strcmp( "qSymbol::", packet
) )
310 char * hex_name_str
= malloc( strlen(packet
));
314 char* found
= strstr( packet
, "qSymbol::" );
318 numconv
=sscanf(packet
, "qSymbol:%" SCNx64
":%s", &value
, hex_name_str
);
322 // No value returned by GDB - symbol was not found
323 numconv
=sscanf(packet
, "qSymbol::%s", hex_name_str
);
325 name_str
= (char*) malloc( 1+ strlen(hex_name_str
) / 2 );
327 hex_to_str( name_str
, hex_name_str
);
331 while ( ( target
->rtos
->symbols
[ symbol_num
].symbol_name
!= NULL
) && ( 0 != strcmp( target
->rtos
->symbols
[ symbol_num
].symbol_name
, name_str
) ) )
337 if ( target
->rtos
->symbols
[ symbol_num
].symbol_name
== NULL
)
339 LOG_OUTPUT("ERROR: unknown symbol\r\n");
340 gdb_put_packet(connection
, "OK", 2);
344 target
->rtos
->symbols
[ symbol_num
].address
= value
;
346 next_symbol_num
= symbol_num
+1;
347 free( hex_name_str
);
352 int symbols_done
= 0;
353 if ( target
->rtos
->symbols
[ next_symbol_num
].symbol_name
== NULL
)
355 if ( ( target
->rtos_auto_detect
== false ) ||
356 ( 1 == target
->rtos
->type
->detect_rtos( target
) ) )
358 // Found correct RTOS or not autodetecting
359 if ( target
->rtos_auto_detect
== true )
361 LOG_OUTPUT( "Auto-detected RTOS: %s\r\n",target
->rtos
->type
->name
);
367 // Auto detecting RTOS and currently not found
368 if( 1 != rtos_try_next( target
) )
370 // No more RTOS's to try
376 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
383 if ( symbols_done
== 1 )
385 target
->rtos_auto_detect
= false;
386 target
->rtos
->type
->create( target
);
387 target
->rtos
->type
->update_threads(target
->rtos
);
388 // No more symbols needed
389 gdb_put_packet(connection
, "OK", 2);
395 char* symname
= target
->rtos
->symbols
[ next_symbol_num
].symbol_name
;
396 char qsymstr
[] = "qSymbol:";
397 char * opstring
= (char*)malloc(sizeof(qsymstr
)+strlen(symname
)*2+1);
398 char * posptr
= opstring
;
399 posptr
+= sprintf( posptr
, "%s", qsymstr
);
400 str_to_hex( posptr
, symname
);
401 gdb_put_packet(connection
, opstring
, strlen(opstring
));
407 gdb_put_packet(connection
, "OK", 2);
410 else if (strstr(packet
, "qfThreadInfo"))
413 if ( ( target
->rtos
!= NULL
) && ( target
->rtos
->thread_count
!= 0 ) )
416 char* out_str
= (char*) malloc(17 * target
->rtos
->thread_count
+ 5);
417 char* tmp_str
= out_str
;
418 tmp_str
+= sprintf(tmp_str
, "m");
419 for (i
= 0; i
< target
->rtos
->thread_count
; i
++) {
421 tmp_str
+= sprintf(tmp_str
, ",");
423 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
,
424 target
->rtos
->thread_details
[i
].threadid
);
427 gdb_put_packet(connection
, out_str
, strlen(out_str
));
431 gdb_put_packet(connection
, "", 0);
436 else if (strstr(packet
, "qsThreadInfo"))
438 gdb_put_packet(connection
, "l", 1);
441 else if (strstr(packet
, "qAttached"))
443 gdb_put_packet(connection
, "1", 1);
446 else if (strstr(packet
, "qOffsets"))
448 char offsets
[] = "Text=0;Data=0;Bss=0";
449 gdb_put_packet(connection
, offsets
, sizeof(offsets
)-1);
452 else if (strstr(packet
, "qC"))
454 gdb_put_packet(connection
, "QC0", 3);
457 else if ( packet
[0] == 'T' ) // Is thread alive?
461 sscanf(packet
, "T%" SCNx64
, &threadid
);
462 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
465 for (thread_num
= 0; thread_num
466 < target
->rtos
->thread_count
; thread_num
++) {
467 if (target
->rtos
->thread_details
[thread_num
].threadid
469 if (target
->rtos
->thread_details
[thread_num
].exists
) {
476 gdb_put_packet(connection
, "OK", 2); // thread alive
478 gdb_put_packet(connection
, "E01", 3); // thread not found
481 else if ( packet
[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations )
483 if (packet
[1] == 'g')
485 sscanf(packet
, "Hg%16" SCNx64
, ¤t_threadid
);
487 gdb_put_packet(connection
, "OK", 2);
490 return GDB_THREAD_PACKET_NOT_CONSUMED
;
493 int rtos_get_gdb_reg_list(struct connection
*connection
, struct target
*target
, struct reg
**reg_list
[], int *reg_list_size
)
495 if ( ( target
->rtos
!= NULL
) &&
496 ( current_threadid
!= 1 ) &&
497 ( current_threadid
!= 0 ) &&
498 ( current_threadid
!= target
->rtos
->current_thread
) )
501 target
->rtos
->type
->get_thread_reg_list( target
->rtos
, current_threadid
, &hex_reg_list
);
503 if ( hex_reg_list
!= NULL
)
505 gdb_put_packet(connection
, hex_reg_list
, strlen(hex_reg_list
));
515 int rtos_generic_stack_read( struct target
* target
, const struct rtos_register_stacking
* stacking
, long long stack_ptr
, char ** hex_reg_list
)
519 long long new_stack_ptr
;
525 LOG_OUTPUT("Error: null stack pointer in thread\r\n");
529 uint8_t * stack_data
= (uint8_t*) malloc( stacking
->stack_registers_size
);
530 uint32_t address
= stack_ptr
;
532 if ( stacking
->stack_growth_direction
== 1 )
534 address
-= stacking
->stack_registers_size
;
536 retval
= target_read_buffer( target
, stack_ptr
, stacking
->stack_registers_size
, stack_data
);
537 if ( retval
!= ERROR_OK
)
539 LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
543 LOG_OUTPUT("Stack Data :");
544 for(i = 0; i < stacking->stack_registers_size; i++ )
546 LOG_OUTPUT("%02X",stack_data[i]);
550 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
552 list_size
+= stacking
->register_offsets
[i
].width_bits
/8;
554 *hex_reg_list
= (char*)malloc( list_size
*2 +1 );
555 tmp_str_ptr
= *hex_reg_list
;
556 new_stack_ptr
= stack_ptr
+ stacking
->stack_growth_direction
* stacking
->stack_registers_size
;
557 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
560 for ( j
= 0; j
< stacking
->register_offsets
[i
].width_bits
/8; j
++ )
562 if ( stacking
->register_offsets
[i
].offset
== -1 )
564 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", 0 );
566 else if ( stacking
->register_offsets
[i
].offset
== -2 )
568 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", ((uint8_t*)&new_stack_ptr
)[j
] );
572 tmp_str_ptr
+= sprintf( tmp_str_ptr
,"%02x", stack_data
[ stacking
->register_offsets
[i
].offset
+ j
] );
576 // LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list);
580 int rtos_try_next( struct target
* target
)
584 if ( target
->rtos
== NULL
)
589 for (x
= 0 ; rtos_types
[x
] ; x
++) {
590 if (target
->rtos
->type
== rtos_types
[x
] ) {
592 if ( rtos_types
[x
+1] != NULL
)
594 target
->rtos
->type
= rtos_types
[x
+1];
595 if ( target
->rtos
->symbols
!= NULL
)
597 free( target
->rtos
->symbols
);
603 // No more rtos types
613 static void hex_to_str( char* dst
, char * hex_src
)
618 while ( hex_src
[src_pos
] != '\x00' )
620 char hex_char
= hex_src
[src_pos
];
621 char hex_digit_val
= (hex_char
>='a')?hex_char
-'a'+10:(hex_char
>='A')?hex_char
-'A'+10:hex_char
-'0';
622 if ( 0 == (src_pos
& 0x01) )
624 dst
[dst_pos
] = hex_digit_val
;
629 ((unsigned char*)dst
)[dst_pos
] <<= 4;
630 ((unsigned char*)dst
)[dst_pos
] += hex_digit_val
;
638 static int str_to_hex( char* hex_dst
, char* src
)
640 char * posptr
= hex_dst
;
642 for( i
= 0; i
< strlen(src
); i
++)
644 posptr
+= sprintf( posptr
, "%02x", (unsigned char)src
[i
] );
646 return (posptr
-hex_dst
);
650 int rtos_update_threads( struct target
* target
)
652 if ((target
->rtos
!= NULL
) && (target
->rtos
->type
!= NULL
))
654 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)