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
)
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 if (stacking
->stack_alignment
!= 0) {
494 /* Align new stack pointer to x byte boundary */
496 (new_stack_ptr
& (~((int64_t) stacking
->stack_alignment
- 1))) +
497 ((stacking
->stack_growth_direction
== -1) ? stacking
->stack_alignment
: 0);
499 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
502 for ( j
= 0; j
< stacking
->register_offsets
[i
].width_bits
/8; j
++ )
504 if ( stacking
->register_offsets
[i
].offset
== -1 )
506 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", 0 );
508 else if ( stacking
->register_offsets
[i
].offset
== -2 )
510 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", ((uint8_t*)&new_stack_ptr
)[j
] );
514 tmp_str_ptr
+= sprintf( tmp_str_ptr
,"%02x", stack_data
[ stacking
->register_offsets
[i
].offset
+ j
] );
518 // LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list);
522 int rtos_try_next( struct target
* target
)
526 if ( target
->rtos
== NULL
)
531 for (x
= 0 ; rtos_types
[x
] ; x
++) {
532 if (target
->rtos
->type
== rtos_types
[x
] ) {
534 if ( rtos_types
[x
+1] != NULL
)
536 target
->rtos
->type
= rtos_types
[x
+1];
537 if ( target
->rtos
->symbols
!= NULL
)
539 free( target
->rtos
->symbols
);
545 // No more rtos types
555 static void hex_to_str( char* dst
, char * hex_src
)
560 while ( hex_src
[src_pos
] != '\x00' )
562 char hex_char
= hex_src
[src_pos
];
563 char hex_digit_val
= (hex_char
>='a')?hex_char
-'a'+10:(hex_char
>='A')?hex_char
-'A'+10:hex_char
-'0';
564 if ( 0 == (src_pos
& 0x01) )
566 dst
[dst_pos
] = hex_digit_val
;
571 ((unsigned char*)dst
)[dst_pos
] <<= 4;
572 ((unsigned char*)dst
)[dst_pos
] += hex_digit_val
;
580 static int str_to_hex( char* hex_dst
, char* src
)
582 char * posptr
= hex_dst
;
584 for( i
= 0; i
< strlen(src
); i
++)
586 posptr
+= sprintf( posptr
, "%02x", (unsigned char)src
[i
] );
588 return (posptr
-hex_dst
);
592 int rtos_update_threads( struct target
* target
)
594 if ((target
->rtos
!= NULL
) && (target
->rtos
->type
!= NULL
))
596 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)