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
, "qThreadExtraInfo,"))
137 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
!= NULL
) && (target
->rtos
->thread_count
!= 0))
139 threadid_t threadid
= 0;
141 sscanf(packet
, "qThreadExtraInfo,%" SCNx64
, &threadid
);
143 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
146 for (thread_num
= 0; thread_num
147 < target
->rtos
->thread_count
; thread_num
++) {
148 if (target
->rtos
->thread_details
[thread_num
].threadid
150 if (target
->rtos
->thread_details
[thread_num
].exists
) {
157 gdb_put_packet(connection
, "E01", 3); // thread not found
161 struct thread_detail
* detail
= &target
->rtos
->thread_details
[found
];
164 if ( detail
->display_str
!= NULL
)
166 str_size
+= strlen(detail
->display_str
);
168 if ( detail
->thread_name_str
!= NULL
)
170 str_size
+= strlen(detail
->thread_name_str
);
172 if ( detail
->extra_info_str
!= NULL
)
174 str_size
+= strlen(detail
->extra_info_str
);
177 char * tmp_str
= (char*) malloc( str_size
+ 7 );
178 char* tmp_str_ptr
= tmp_str
;
180 if ( detail
->display_str
!= NULL
)
182 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%s", detail
->display_str
);
184 if ( detail
->thread_name_str
!= NULL
)
186 if ( tmp_str_ptr
!= tmp_str
)
188 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : " );
190 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%s", detail
->thread_name_str
);
192 if ( detail
->extra_info_str
!= NULL
)
194 if ( tmp_str_ptr
!= tmp_str
)
196 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : " );
198 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : %s", detail
->extra_info_str
);
201 assert(strlen(tmp_str
) ==
202 (size_t) (tmp_str_ptr
- tmp_str
));
204 char * hex_str
= (char*) malloc( strlen(tmp_str
)*2 +1 );
205 str_to_hex( hex_str
, tmp_str
);
207 gdb_put_packet(connection
, hex_str
, strlen(hex_str
));
213 gdb_put_packet(connection
, "", 0);
216 else if (strstr(packet
, "qSymbol"))
218 if ( target
->rtos
!= NULL
)
220 int next_symbol_num
= -1;
221 if (target
->rtos
->symbols
== NULL
)
223 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
225 if (0 == strcmp( "qSymbol::", packet
) )
233 char * hex_name_str
= malloc( strlen(packet
));
237 char* found
= strstr( packet
, "qSymbol::" );
240 sscanf(packet
, "qSymbol:%" SCNx64
":%s", &value
, hex_name_str
);
244 // No value returned by GDB - symbol was not found
245 sscanf(packet
, "qSymbol::%s", hex_name_str
);
247 name_str
= (char*) malloc( 1+ strlen(hex_name_str
) / 2 );
249 hex_to_str( name_str
, hex_name_str
);
253 while ( ( target
->rtos
->symbols
[ symbol_num
].symbol_name
!= NULL
) && ( 0 != strcmp( target
->rtos
->symbols
[ symbol_num
].symbol_name
, name_str
) ) )
259 if ( target
->rtos
->symbols
[ symbol_num
].symbol_name
== NULL
)
261 LOG_OUTPUT("ERROR: unknown symbol\r\n");
262 gdb_put_packet(connection
, "OK", 2);
266 target
->rtos
->symbols
[ symbol_num
].address
= value
;
268 next_symbol_num
= symbol_num
+1;
269 free( hex_name_str
);
274 int symbols_done
= 0;
275 if ( target
->rtos
->symbols
[ next_symbol_num
].symbol_name
== NULL
)
277 if ( ( target
->rtos_auto_detect
== false ) ||
278 ( 1 == target
->rtos
->type
->detect_rtos( target
) ) )
280 // Found correct RTOS or not autodetecting
281 if ( target
->rtos_auto_detect
== true )
283 LOG_OUTPUT( "Auto-detected RTOS: %s\r\n",target
->rtos
->type
->name
);
289 // Auto detecting RTOS and currently not found
290 if( 1 != rtos_try_next( target
) )
292 // No more RTOS's to try
298 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
305 if ( symbols_done
== 1 )
307 target
->rtos_auto_detect
= false;
308 target
->rtos
->type
->create( target
);
309 target
->rtos
->type
->update_threads(target
->rtos
);
310 // No more symbols needed
311 gdb_put_packet(connection
, "OK", 2);
317 char* symname
= target
->rtos
->symbols
[ next_symbol_num
].symbol_name
;
318 char qsymstr
[] = "qSymbol:";
319 char * opstring
= (char*)malloc(sizeof(qsymstr
)+strlen(symname
)*2+1);
320 char * posptr
= opstring
;
321 posptr
+= sprintf( posptr
, "%s", qsymstr
);
322 str_to_hex( posptr
, symname
);
323 gdb_put_packet(connection
, opstring
, strlen(opstring
));
329 gdb_put_packet(connection
, "OK", 2);
332 else if (strstr(packet
, "qfThreadInfo"))
335 if ( ( target
->rtos
!= NULL
) && ( target
->rtos
->thread_count
!= 0 ) )
338 char* out_str
= (char*) malloc(17 * target
->rtos
->thread_count
+ 5);
339 char* tmp_str
= out_str
;
340 tmp_str
+= sprintf(tmp_str
, "m");
341 for (i
= 0; i
< target
->rtos
->thread_count
; i
++) {
343 tmp_str
+= sprintf(tmp_str
, ",");
345 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
,
346 target
->rtos
->thread_details
[i
].threadid
);
349 gdb_put_packet(connection
, out_str
, strlen(out_str
));
353 gdb_put_packet(connection
, "", 0);
358 else if (strstr(packet
, "qsThreadInfo"))
360 gdb_put_packet(connection
, "l", 1);
363 else if (strstr(packet
, "qAttached"))
365 gdb_put_packet(connection
, "1", 1);
368 else if (strstr(packet
, "qOffsets"))
370 char offsets
[] = "Text=0;Data=0;Bss=0";
371 gdb_put_packet(connection
, offsets
, sizeof(offsets
)-1);
374 else if (strstr(packet
, "qC"))
376 if( target
->rtos
!=NULL
)
380 size
= snprintf(buffer
, 15, "QC%08X", (int)target
->rtos
->current_thread
);
381 gdb_put_packet(connection
, buffer
, size
);
385 gdb_put_packet(connection
, "QC0", 3);
389 else if ( packet
[0] == 'T' ) // Is thread alive?
393 sscanf(packet
, "T%" SCNx64
, &threadid
);
394 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
397 for (thread_num
= 0; thread_num
398 < target
->rtos
->thread_count
; thread_num
++) {
399 if (target
->rtos
->thread_details
[thread_num
].threadid
401 if (target
->rtos
->thread_details
[thread_num
].exists
) {
408 gdb_put_packet(connection
, "OK", 2); // thread alive
410 gdb_put_packet(connection
, "E01", 3); // thread not found
414 else if ( packet
[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations )
416 if (packet
[1] == 'g')
418 sscanf(packet
, "Hg%16" SCNx64
, ¤t_threadid
);
420 gdb_put_packet(connection
, "OK", 2);
424 return GDB_THREAD_PACKET_NOT_CONSUMED
;
427 int rtos_get_gdb_reg_list(struct connection
*connection
, struct reg
**reg_list
[], int *reg_list_size
)
429 struct target
*target
= get_target_from_connection(connection
);
431 if ( ( target
->rtos
!= NULL
) &&
432 ( current_threadid
!= -1 ) &&
433 ( current_threadid
!= 0 ) &&
434 ( current_threadid
!= target
->rtos
->current_thread
) )
437 target
->rtos
->type
->get_thread_reg_list( target
->rtos
, current_threadid
, &hex_reg_list
);
439 if ( hex_reg_list
!= NULL
)
441 gdb_put_packet(connection
, hex_reg_list
, strlen(hex_reg_list
));
451 int rtos_generic_stack_read( struct target
* target
, const struct rtos_register_stacking
* stacking
, int64_t stack_ptr
, char ** hex_reg_list
)
455 int64_t new_stack_ptr
;
461 LOG_OUTPUT("Error: null stack pointer in thread\r\n");
465 uint8_t * stack_data
= (uint8_t*) malloc( stacking
->stack_registers_size
);
466 uint32_t address
= stack_ptr
;
468 if ( stacking
->stack_growth_direction
== 1 )
470 address
-= stacking
->stack_registers_size
;
472 retval
= target_read_buffer( target
, address
, stacking
->stack_registers_size
, stack_data
);
473 if ( retval
!= ERROR_OK
)
475 LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
479 LOG_OUTPUT("Stack Data :");
480 for(i = 0; i < stacking->stack_registers_size; i++ )
482 LOG_OUTPUT("%02X",stack_data[i]);
486 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
488 list_size
+= stacking
->register_offsets
[i
].width_bits
/8;
490 *hex_reg_list
= (char*)malloc( list_size
*2 +1 );
491 tmp_str_ptr
= *hex_reg_list
;
492 new_stack_ptr
= stack_ptr
- stacking
->stack_growth_direction
* stacking
->stack_registers_size
;
493 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
496 for ( j
= 0; j
< stacking
->register_offsets
[i
].width_bits
/8; j
++ )
498 if ( stacking
->register_offsets
[i
].offset
== -1 )
500 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", 0 );
502 else if ( stacking
->register_offsets
[i
].offset
== -2 )
504 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", ((uint8_t*)&new_stack_ptr
)[j
] );
508 tmp_str_ptr
+= sprintf( tmp_str_ptr
,"%02x", stack_data
[ stacking
->register_offsets
[i
].offset
+ j
] );
512 // LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list);
516 int rtos_try_next( struct target
* target
)
520 if ( target
->rtos
== NULL
)
525 for (x
= 0 ; rtos_types
[x
] ; x
++) {
526 if (target
->rtos
->type
== rtos_types
[x
] ) {
528 if ( rtos_types
[x
+1] != NULL
)
530 target
->rtos
->type
= rtos_types
[x
+1];
531 if ( target
->rtos
->symbols
!= NULL
)
533 free( target
->rtos
->symbols
);
539 // No more rtos types
549 static void hex_to_str( char* dst
, char * hex_src
)
554 while ( hex_src
[src_pos
] != '\x00' )
556 char hex_char
= hex_src
[src_pos
];
557 char hex_digit_val
= (hex_char
>='a')?hex_char
-'a'+10:(hex_char
>='A')?hex_char
-'A'+10:hex_char
-'0';
558 if ( 0 == (src_pos
& 0x01) )
560 dst
[dst_pos
] = hex_digit_val
;
565 ((unsigned char*)dst
)[dst_pos
] <<= 4;
566 ((unsigned char*)dst
)[dst_pos
] += hex_digit_val
;
574 static int str_to_hex( char* hex_dst
, char* src
)
576 char * posptr
= hex_dst
;
578 for( i
= 0; i
< strlen(src
); i
++)
580 posptr
+= sprintf( posptr
, "%02x", (unsigned char)src
[i
] );
582 return (posptr
-hex_dst
);
586 int rtos_update_threads( struct target
* target
)
588 if ((target
->rtos
!= NULL
) && (target
->rtos
->type
!= NULL
))
590 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)