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
);
53 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_threadid
= -1;
117 target
->rtos
->current_thread
= 0;
118 target
->rtos
->symbols
= NULL
;
119 target
->rtos
->target
= target
;
120 /* put default thread handler in linux usecase it is overloaded*/
121 target
->rtos
->gdb_thread_packet
= rtos_thread_packet
;
123 if ( 0 != strcmp( cp
, "auto") )
125 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
);
134 if (target
->rtos
== NULL
)
135 return rtos_thread_packet(connection
, packet
, packet_size
); /* thread not found*/
136 return target
->rtos
->gdb_thread_packet(connection
, packet
, packet_size
);
142 int rtos_thread_packet(struct connection
*connection
, char *packet
, int packet_size
)
144 struct target
*target
= get_target_from_connection(connection
);
146 if (strstr(packet
, "qThreadExtraInfo,"))
148 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
!= NULL
) && (target
->rtos
->thread_count
!= 0))
150 threadid_t threadid
= 0;
152 sscanf(packet
, "qThreadExtraInfo,%" SCNx64
, &threadid
);
154 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
157 for (thread_num
= 0; thread_num
158 < target
->rtos
->thread_count
; thread_num
++) {
159 if (target
->rtos
->thread_details
[thread_num
].threadid
161 if (target
->rtos
->thread_details
[thread_num
].exists
) {
168 gdb_put_packet(connection
, "E01", 3); // thread not found
172 struct thread_detail
* detail
= &target
->rtos
->thread_details
[found
];
175 if ( detail
->display_str
!= NULL
)
177 str_size
+= strlen(detail
->display_str
);
179 if ( detail
->thread_name_str
!= NULL
)
181 str_size
+= strlen(detail
->thread_name_str
);
183 if ( detail
->extra_info_str
!= NULL
)
185 str_size
+= strlen(detail
->extra_info_str
);
188 char * tmp_str
= (char*) malloc( str_size
+ 7 );
189 char* tmp_str_ptr
= tmp_str
;
191 if ( detail
->display_str
!= NULL
)
193 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%s", detail
->display_str
);
195 if ( detail
->thread_name_str
!= NULL
)
197 if ( tmp_str_ptr
!= tmp_str
)
199 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : " );
201 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%s", detail
->thread_name_str
);
203 if ( detail
->extra_info_str
!= NULL
)
205 if ( tmp_str_ptr
!= tmp_str
)
207 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : " );
209 tmp_str_ptr
+= sprintf( tmp_str_ptr
, " : %s", detail
->extra_info_str
);
212 assert(strlen(tmp_str
) ==
213 (size_t) (tmp_str_ptr
- tmp_str
));
215 char * hex_str
= (char*) malloc( strlen(tmp_str
)*2 +1 );
216 str_to_hex( hex_str
, tmp_str
);
218 gdb_put_packet(connection
, hex_str
, strlen(hex_str
));
224 gdb_put_packet(connection
, "", 0);
227 else if (strstr(packet
, "qSymbol"))
229 if ( target
->rtos
!= NULL
)
231 int next_symbol_num
= -1;
232 if (target
->rtos
->symbols
== NULL
)
234 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
236 if (0 == strcmp( "qSymbol::", packet
) )
244 char * hex_name_str
= malloc( strlen(packet
));
248 char* found
= strstr( packet
, "qSymbol::" );
251 sscanf(packet
, "qSymbol:%" SCNx64
":%s", &value
, hex_name_str
);
255 // No value returned by GDB - symbol was not found
256 sscanf(packet
, "qSymbol::%s", hex_name_str
);
258 name_str
= (char*) malloc( 1+ strlen(hex_name_str
) / 2 );
260 hex_to_str( name_str
, hex_name_str
);
264 while ( ( target
->rtos
->symbols
[ symbol_num
].symbol_name
!= NULL
) && ( 0 != strcmp( target
->rtos
->symbols
[ symbol_num
].symbol_name
, name_str
) ) )
270 if ( target
->rtos
->symbols
[ symbol_num
].symbol_name
== NULL
)
272 LOG_OUTPUT("ERROR: unknown symbol\r\n");
273 gdb_put_packet(connection
, "OK", 2);
277 target
->rtos
->symbols
[ symbol_num
].address
= value
;
279 next_symbol_num
= symbol_num
+1;
280 free( hex_name_str
);
285 int symbols_done
= 0;
286 if ( target
->rtos
->symbols
[ next_symbol_num
].symbol_name
== NULL
)
288 if ( ( target
->rtos_auto_detect
== false ) ||
289 ( 1 == target
->rtos
->type
->detect_rtos( target
) ) )
291 // Found correct RTOS or not autodetecting
292 if ( target
->rtos_auto_detect
== true )
294 LOG_OUTPUT( "Auto-detected RTOS: %s\r\n",target
->rtos
->type
->name
);
300 // Auto detecting RTOS and currently not found
301 if( 1 != rtos_try_next( target
) )
303 // No more RTOS's to try
309 target
->rtos
->type
->get_symbol_list_to_lookup( &target
->rtos
->symbols
);
316 if ( symbols_done
== 1 )
318 target
->rtos_auto_detect
= false;
319 target
->rtos
->type
->create( target
);
320 target
->rtos
->type
->update_threads(target
->rtos
);
321 // No more symbols needed
322 gdb_put_packet(connection
, "OK", 2);
328 char* symname
= target
->rtos
->symbols
[ next_symbol_num
].symbol_name
;
329 char qsymstr
[] = "qSymbol:";
330 char * opstring
= (char*)malloc(sizeof(qsymstr
)+strlen(symname
)*2+1);
331 char * posptr
= opstring
;
332 posptr
+= sprintf( posptr
, "%s", qsymstr
);
333 str_to_hex( posptr
, symname
);
334 gdb_put_packet(connection
, opstring
, strlen(opstring
));
340 gdb_put_packet(connection
, "OK", 2);
343 else if (strstr(packet
, "qfThreadInfo"))
346 if ( ( target
->rtos
!= NULL
) && ( target
->rtos
->thread_count
!= 0 ) )
349 char* out_str
= (char*) malloc(17 * target
->rtos
->thread_count
+ 5);
350 char* tmp_str
= out_str
;
351 tmp_str
+= sprintf(tmp_str
, "m");
352 for (i
= 0; i
< target
->rtos
->thread_count
; i
++) {
354 tmp_str
+= sprintf(tmp_str
, ",");
356 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
,
357 target
->rtos
->thread_details
[i
].threadid
);
360 gdb_put_packet(connection
, out_str
, strlen(out_str
));
364 gdb_put_packet(connection
, "", 0);
369 else if (strstr(packet
, "qsThreadInfo"))
371 gdb_put_packet(connection
, "l", 1);
374 else if (strstr(packet
, "qAttached"))
376 gdb_put_packet(connection
, "1", 1);
379 else if (strstr(packet
, "qOffsets"))
381 char offsets
[] = "Text=0;Data=0;Bss=0";
382 gdb_put_packet(connection
, offsets
, sizeof(offsets
)-1);
385 else if (strstr(packet
, "qC"))
387 if( target
->rtos
!=NULL
)
391 size
= snprintf(buffer
, 15, "QC%08X", (int)target
->rtos
->current_thread
);
392 gdb_put_packet(connection
, buffer
, size
);
396 gdb_put_packet(connection
, "QC0", 3);
400 else if ( packet
[0] == 'T' ) // Is thread alive?
404 sscanf(packet
, "T%" SCNx64
, &threadid
);
405 if ((target
->rtos
!= NULL
) && (target
->rtos
->thread_details
408 for (thread_num
= 0; thread_num
409 < target
->rtos
->thread_count
; thread_num
++) {
410 if (target
->rtos
->thread_details
[thread_num
].threadid
412 if (target
->rtos
->thread_details
[thread_num
].exists
) {
419 gdb_put_packet(connection
, "OK", 2); // thread alive
421 gdb_put_packet(connection
, "E01", 3); // thread not found
425 else if ( packet
[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations )
427 if ((packet
[1] == 'g') && (target
->rtos
!= NULL
))
428 sscanf(packet
, "Hg%16" SCNx64
, &target
->rtos
->current_threadid
);
429 gdb_put_packet(connection
, "OK", 2);
433 return GDB_THREAD_PACKET_NOT_CONSUMED
;
436 int rtos_get_gdb_reg_list(struct connection
*connection
)
438 struct target
*target
= get_target_from_connection(connection
);
439 int64_t current_threadid
= target
->rtos
->current_threadid
;
440 if ( ( target
->rtos
!= NULL
) &&
441 ( current_threadid
!= -1 ) &&
442 ( current_threadid
!= 0 ) &&
443 ( current_threadid
!= target
->rtos
->current_thread
) )
446 target
->rtos
->type
->get_thread_reg_list( target
->rtos
, current_threadid
, &hex_reg_list
);
448 if ( hex_reg_list
!= NULL
)
450 gdb_put_packet(connection
, hex_reg_list
, strlen(hex_reg_list
));
460 int rtos_generic_stack_read( struct target
* target
, const struct rtos_register_stacking
* stacking
, int64_t stack_ptr
, char ** hex_reg_list
)
464 int64_t new_stack_ptr
;
470 LOG_OUTPUT("Error: null stack pointer in thread\r\n");
474 uint8_t * stack_data
= (uint8_t*) malloc( stacking
->stack_registers_size
);
475 uint32_t address
= stack_ptr
;
477 if ( stacking
->stack_growth_direction
== 1 )
479 address
-= stacking
->stack_registers_size
;
481 retval
= target_read_buffer( target
, address
, stacking
->stack_registers_size
, stack_data
);
482 if ( retval
!= ERROR_OK
)
484 LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
488 LOG_OUTPUT("Stack Data :");
489 for(i = 0; i < stacking->stack_registers_size; i++ )
491 LOG_OUTPUT("%02X",stack_data[i]);
495 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
497 list_size
+= stacking
->register_offsets
[i
].width_bits
/8;
499 *hex_reg_list
= (char*)malloc( list_size
*2 +1 );
500 tmp_str_ptr
= *hex_reg_list
;
501 new_stack_ptr
= stack_ptr
- stacking
->stack_growth_direction
* stacking
->stack_registers_size
;
502 if (stacking
->stack_alignment
!= 0) {
503 /* Align new stack pointer to x byte boundary */
505 (new_stack_ptr
& (~((int64_t) stacking
->stack_alignment
- 1))) +
506 ((stacking
->stack_growth_direction
== -1) ? stacking
->stack_alignment
: 0);
508 for( i
= 0; i
< stacking
->num_output_registers
; i
++ )
511 for ( j
= 0; j
< stacking
->register_offsets
[i
].width_bits
/8; j
++ )
513 if ( stacking
->register_offsets
[i
].offset
== -1 )
515 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", 0 );
517 else if ( stacking
->register_offsets
[i
].offset
== -2 )
519 tmp_str_ptr
+= sprintf( tmp_str_ptr
, "%02x", ((uint8_t*)&new_stack_ptr
)[j
] );
523 tmp_str_ptr
+= sprintf( tmp_str_ptr
,"%02x", stack_data
[ stacking
->register_offsets
[i
].offset
+ j
] );
527 // LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list);
531 int rtos_try_next( struct target
* target
)
535 if ( target
->rtos
== NULL
)
540 for (x
= 0 ; rtos_types
[x
] ; x
++) {
541 if (target
->rtos
->type
== rtos_types
[x
] ) {
543 if ( rtos_types
[x
+1] != NULL
)
545 target
->rtos
->type
= rtos_types
[x
+1];
546 if ( target
->rtos
->symbols
!= NULL
)
548 free( target
->rtos
->symbols
);
554 // No more rtos types
564 static void hex_to_str( char* dst
, char * hex_src
)
569 while ( hex_src
[src_pos
] != '\x00' )
571 char hex_char
= hex_src
[src_pos
];
572 char hex_digit_val
= (hex_char
>='a')?hex_char
-'a'+10:(hex_char
>='A')?hex_char
-'A'+10:hex_char
-'0';
573 if ( 0 == (src_pos
& 0x01) )
575 dst
[dst_pos
] = hex_digit_val
;
580 ((unsigned char*)dst
)[dst_pos
] <<= 4;
581 ((unsigned char*)dst
)[dst_pos
] += hex_digit_val
;
589 static int str_to_hex( char* hex_dst
, char* src
)
591 char * posptr
= hex_dst
;
593 for( i
= 0; i
< strlen(src
); i
++)
595 posptr
+= sprintf( posptr
, "%02x", (unsigned char)src
[i
] );
597 return (posptr
-hex_dst
);
601 int rtos_update_threads( struct target
* target
)
603 if ((target
->rtos
!= NULL
) && (target
->rtos
->type
!= NULL
))
605 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)