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"
33 static void hex_to_str( char* dst
, char * hex_src
);
34 static int str_to_hex( char* hex_dst
, char* src
);
38 extern struct rtos_type FreeRTOS_rtos
;
39 extern struct rtos_type ThreadX_rtos
;
40 extern struct rtos_type eCos_rtos
;
42 static struct rtos_type
*rtos_types
[] =
50 int rtos_thread_packet(struct connection
*connection
, char *packet
, int packet_size
);
52 int rtos_smp_init(struct target
*target
)
54 if (target
->rtos
->type
->smp_init
)
55 return target
->rtos
->type
->smp_init(target
);
56 return ERROR_TARGET_INIT_FAILED
;
60 int rtos_create(Jim_GetOptInfo
*goi
, struct target
* target
)
64 if (! goi
->isconfigure
) {
67 Jim_WrongNumArgs(goi
->interp
,
73 Jim_SetResultString(goi
->interp
,
74 target_type_name(target
), -1);
79 free((void *)(target
->rtos
));
81 // e = Jim_GetOpt_String(goi, &cp, NULL);
82 // target->rtos = strdup(cp);
84 Jim_GetOpt_String(goi
, &cp
, NULL
);
85 /* now does target type exist */
87 if ( 0 == strcmp( cp
, "auto") )
89 // auto detection of RTOS
90 target
->rtos_auto_detect
= true;
96 for (x
= 0 ; rtos_types
[x
] ; x
++) {
97 if (0 == strcmp(cp
, rtos_types
[x
]->name
)) {
102 if (rtos_types
[x
] == NULL
) {
103 Jim_SetResultFormatted(goi
->interp
, "Unknown rtos type %s, try one of ", cp
);
104 for (x
= 0 ; rtos_types
[x
] ; x
++) {
105 if (rtos_types
[x
+ 1]) {
106 Jim_AppendStrings(goi
->interp
,
107 Jim_GetResult(goi
->interp
),
111 Jim_AppendStrings(goi
->interp
,
112 Jim_GetResult(goi
->interp
),
114 rtos_types
[x
]->name
,NULL
);
121 target
->rtos
= calloc(1,sizeof(struct rtos
));
122 target
->rtos
->type
= rtos_types
[x
];
123 target
->rtos
->current_threadid
= -1;
124 target
->rtos
->current_thread
= 0;
125 target
->rtos
->symbols
= NULL
;
126 target
->rtos
->target
= target
;
127 /* put default thread handler in linux usecase it is overloaded*/
128 target
->rtos
->gdb_thread_packet
= rtos_thread_packet
;
130 if ( 0 != strcmp( cp
, "auto") )
132 target
->rtos
->type
->create( target
);
138 int gdb_thread_packet(struct connection
*connection
, char *packet
, int packet_size
)
140 struct target
*target
= get_target_from_connection(connection
);
141 if (target
->rtos
== NULL
)
142 return rtos_thread_packet(connection
, packet
, packet_size
); /* thread not found*/
143 return target
->rtos
->gdb_thread_packet(connection
, packet
, packet_size
);
149 int rtos_thread_packet(struct connection
*connection
, char *packet
, int packet_size
)
151 struct target
*target
= get_target_from_connection(connection
);
153 if (strstr(packet
, "qThreadExtraInfo,"))
155 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
!= NULL
) && (target
->rtos
->thread_count
!= 0))
157 threadid_t threadid
= 0;
159 sscanf(packet
, "qThreadExtraInfo,%" SCNx64
, &threadid
);
161 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
164 for (thread_num
= 0; thread_num
165 < target
->rtos
->thread_count
; thread_num
++) {
166 if (target
->rtos
->thread_details
[thread_num
].threadid
168 if (target
->rtos
->thread_details
[thread_num
].exists
) {
175 gdb_put_packet(connection
, "E01", 3); // thread not found
179 struct thread_detail
* detail
= &target
->rtos
->thread_details
[found
];
182 if ( detail
->display_str
!= NULL
)
184 str_size
+= strlen(detail
->display_str
);
186 if ( detail
->thread_name_str
!= NULL
)
188 str_size
+= strlen(detail
->thread_name_str
);
190 if ( detail
->extra_info_str
!= NULL
)
192 str_size
+= strlen(detail
->extra_info_str
);
195 char * tmp_str
= (char*) malloc( str_size
+ 7 );
196 char* tmp_str_ptr
= tmp_str
;
198 if ( detail
->display_str
!= NULL
)
200 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%s", detail
->display_str
);
202 if ( detail
->thread_name_str
!= NULL
)
204 if ( tmp_str_ptr
!= tmp_str
)
206 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : " );
208 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%s", detail
->thread_name_str
);
210 if ( detail
->extra_info_str
!= NULL
)
212 if ( tmp_str_ptr
!= tmp_str
)
214 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : " );
216 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : %s", detail
->extra_info_str
);
219 assert(strlen(tmp_str
) ==
220 (size_t) (tmp_str_ptr
- tmp_str
));
222 char * hex_str
= (char*) malloc( strlen(tmp_str
)*2 +1 );
223 str_to_hex( hex_str
, tmp_str
);
225 gdb_put_packet(connection
, hex_str
, strlen(hex_str
));
231 gdb_put_packet(connection
, "", 0);
234 else if (strstr(packet
, "qSymbol"))
236 if ( target
->rtos
!= NULL
)
238 int next_symbol_num
= -1;
239 if (target
->rtos
->symbols
== NULL
)
241 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
243 if (0 == strcmp( "qSymbol::", packet
) )
251 char * hex_name_str
= malloc( strlen(packet
));
255 char* found
= strstr( packet
, "qSymbol::" );
258 sscanf(packet
, "qSymbol:%" SCNx64
":%s", &value
, hex_name_str
);
262 // No value returned by GDB - symbol was not found
263 sscanf(packet
, "qSymbol::%s", hex_name_str
);
265 name_str
= (char*) malloc( 1+ strlen(hex_name_str
) / 2 );
267 hex_to_str( name_str
, hex_name_str
);
271 while ( ( target
->rtos
->symbols
[ symbol_num
].symbol_name
!= NULL
) && ( 0 != strcmp( target
->rtos
->symbols
[ symbol_num
].symbol_name
, name_str
) ) )
277 if ( target
->rtos
->symbols
[ symbol_num
].symbol_name
== NULL
)
279 LOG_OUTPUT("ERROR: unknown symbol\r\n");
280 gdb_put_packet(connection
, "OK", 2);
284 target
->rtos
->symbols
[ symbol_num
].address
= value
;
286 next_symbol_num
= symbol_num
+1;
287 free( hex_name_str
);
292 int symbols_done
= 0;
293 if ( target
->rtos
->symbols
[ next_symbol_num
].symbol_name
== NULL
)
295 if ( ( target
->rtos_auto_detect
== false ) ||
296 ( 1 == target
->rtos
->type
->detect_rtos( target
) ) )
298 // Found correct RTOS or not autodetecting
299 if ( target
->rtos_auto_detect
== true )
301 LOG_OUTPUT( "Auto-detected RTOS: %s\r\n",target
->rtos
->type
->name
);
307 // Auto detecting RTOS and currently not found
308 if( 1 != rtos_try_next( target
) )
310 // No more RTOS's to try
316 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
323 if ( symbols_done
== 1 )
325 target
->rtos_auto_detect
= false;
326 target
->rtos
->type
->create( target
);
327 target
->rtos
->type
->update_threads(target
->rtos
);
328 // No more symbols needed
329 gdb_put_packet(connection
, "OK", 2);
335 char* symname
= target
->rtos
->symbols
[ next_symbol_num
].symbol_name
;
336 char qsymstr
[] = "qSymbol:";
337 char * opstring
= (char*)malloc(sizeof(qsymstr
)+strlen(symname
)*2+1);
338 char * posptr
= opstring
;
339 posptr
+= sprintf( posptr
, "%s", qsymstr
);
340 str_to_hex( posptr
, symname
);
341 gdb_put_packet(connection
, opstring
, strlen(opstring
));
347 gdb_put_packet(connection
, "OK", 2);
350 else if (strstr(packet
, "qfThreadInfo"))
353 if ( ( target
->rtos
!= NULL
) && ( target
->rtos
->thread_count
!= 0 ) )
356 char* out_str
= (char*) malloc(17 * target
->rtos
->thread_count
+ 5);
357 char* tmp_str
= out_str
;
358 tmp_str
+= sprintf(tmp_str
, "m");
359 for (i
= 0; i
< target
->rtos
->thread_count
; i
++) {
361 tmp_str
+= sprintf(tmp_str
, ",");
363 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
,
364 target
->rtos
->thread_details
[i
].threadid
);
367 gdb_put_packet(connection
, out_str
, strlen(out_str
));
371 gdb_put_packet(connection
, "", 0);
376 else if (strstr(packet
, "qsThreadInfo"))
378 gdb_put_packet(connection
, "l", 1);
381 else if (strstr(packet
, "qAttached"))
383 gdb_put_packet(connection
, "1", 1);
386 else if (strstr(packet
, "qOffsets"))
388 char offsets
[] = "Text=0;Data=0;Bss=0";
389 gdb_put_packet(connection
, offsets
, sizeof(offsets
)-1);
392 else if (strstr(packet
, "qC"))
394 if( target
->rtos
!=NULL
)
398 size
= snprintf(buffer
, 15, "QC%08X", (int)target
->rtos
->current_thread
);
399 gdb_put_packet(connection
, buffer
, size
);
403 gdb_put_packet(connection
, "QC0", 3);
407 else if ( packet
[0] == 'T' ) // Is thread alive?
411 sscanf(packet
, "T%" SCNx64
, &threadid
);
412 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
415 for (thread_num
= 0; thread_num
416 < target
->rtos
->thread_count
; thread_num
++) {
417 if (target
->rtos
->thread_details
[thread_num
].threadid
419 if (target
->rtos
->thread_details
[thread_num
].exists
) {
426 gdb_put_packet(connection
, "OK", 2); // thread alive
428 gdb_put_packet(connection
, "E01", 3); // thread not found
432 else if ( packet
[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations )
434 if ((packet
[1] == 'g') && (target
->rtos
!= NULL
))
435 sscanf(packet
, "Hg%16" SCNx64
, &target
->rtos
->current_threadid
);
436 gdb_put_packet(connection
, "OK", 2);
440 return GDB_THREAD_PACKET_NOT_CONSUMED
;
443 int rtos_get_gdb_reg_list(struct connection
*connection
)
445 struct target
*target
= get_target_from_connection(connection
);
446 int64_t current_threadid
= target
->rtos
->current_threadid
;
447 if ((target
->rtos
!= NULL
) &&
448 (current_threadid
!= -1) &&
449 (current_threadid
!= 0) &&
450 ((current_threadid
!= target
->rtos
->current_thread
) ||
451 (target
->smp
))) /* in smp several current thread are possible */
454 target
->rtos
->type
->get_thread_reg_list( target
->rtos
, current_threadid
, &hex_reg_list
);
456 if ( hex_reg_list
!= NULL
)
458 gdb_put_packet(connection
, hex_reg_list
, strlen(hex_reg_list
));
468 int rtos_generic_stack_read( struct target
* target
, const struct rtos_register_stacking
* stacking
, int64_t stack_ptr
, char ** hex_reg_list
)
472 int64_t new_stack_ptr
;
478 LOG_OUTPUT("Error: null stack pointer in thread\r\n");
482 uint8_t * stack_data
= (uint8_t*) malloc( stacking
->stack_registers_size
);
483 uint32_t address
= stack_ptr
;
485 if ( stacking
->stack_growth_direction
== 1 )
487 address
-= stacking
->stack_registers_size
;
489 retval
= target_read_buffer( target
, address
, stacking
->stack_registers_size
, stack_data
);
490 if ( retval
!= ERROR_OK
)
492 LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
496 LOG_OUTPUT("Stack Data :");
497 for(i = 0; i < stacking->stack_registers_size; i++ )
499 LOG_OUTPUT("%02X",stack_data[i]);
503 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
505 list_size
+= stacking
->register_offsets
[i
].width_bits
/8;
507 *hex_reg_list
= (char*)malloc( list_size
*2 +1 );
508 tmp_str_ptr
= *hex_reg_list
;
509 new_stack_ptr
= stack_ptr
- stacking
->stack_growth_direction
* stacking
->stack_registers_size
;
510 if (stacking
->stack_alignment
!= 0) {
511 /* Align new stack pointer to x byte boundary */
513 (new_stack_ptr
& (~((int64_t) stacking
->stack_alignment
- 1))) +
514 ((stacking
->stack_growth_direction
== -1) ? stacking
->stack_alignment
: 0);
516 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
519 for ( j
= 0; j
< stacking
->register_offsets
[i
].width_bits
/8; j
++ )
521 if ( stacking
->register_offsets
[i
].offset
== -1 )
523 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", 0 );
525 else if ( stacking
->register_offsets
[i
].offset
== -2 )
527 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", ((uint8_t*)&new_stack_ptr
)[j
] );
531 tmp_str_ptr
+= sprintf( tmp_str_ptr
,"%02x", stack_data
[ stacking
->register_offsets
[i
].offset
+ j
] );
535 // LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list);
539 int rtos_try_next( struct target
* target
)
543 if ( target
->rtos
== NULL
)
548 for (x
= 0 ; rtos_types
[x
] ; x
++) {
549 if (target
->rtos
->type
== rtos_types
[x
] ) {
551 if ( rtos_types
[x
+1] != NULL
)
553 target
->rtos
->type
= rtos_types
[x
+1];
554 if ( target
->rtos
->symbols
!= NULL
)
556 free( target
->rtos
->symbols
);
562 // No more rtos types
572 static void hex_to_str( char* dst
, char * hex_src
)
577 while ( hex_src
[src_pos
] != '\x00' )
579 char hex_char
= hex_src
[src_pos
];
580 char hex_digit_val
= (hex_char
>='a')?hex_char
-'a'+10:(hex_char
>='A')?hex_char
-'A'+10:hex_char
-'0';
581 if ( 0 == (src_pos
& 0x01) )
583 dst
[dst_pos
] = hex_digit_val
;
588 ((unsigned char*)dst
)[dst_pos
] <<= 4;
589 ((unsigned char*)dst
)[dst_pos
] += hex_digit_val
;
597 static int str_to_hex( char* hex_dst
, char* src
)
599 char * posptr
= hex_dst
;
601 for( i
= 0; i
< strlen(src
); i
++)
603 posptr
+= sprintf( posptr
, "%02x", (unsigned char)src
[i
] );
605 return (posptr
-hex_dst
);
609 int rtos_update_threads( struct target
* target
)
611 if ((target
->rtos
!= NULL
) && (target
->rtos
->type
!= NULL
))
613 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)