#include "server/gdb_server.h"
-static int64_t current_threadid = -1;
static void hex_to_str( char* dst, char * hex_src );
-static int str_to_hex( char* hex_dst, char* src );
/* RTOSs */
NULL
};
+int rtos_thread_packet(struct connection *connection, char *packet, int packet_size);
+
+int rtos_smp_init(struct target *target)
+{
+ if (target->rtos->type->smp_init)
+ return target->rtos->type->smp_init(target);
+ return ERROR_TARGET_INIT_FAILED;
+}
+
int rtos_create(Jim_GetOptInfo *goi, struct target * target)
{
int x;
char *cp;
-
if (! goi->isconfigure) {
if (goi->argc != 0) {
if (goi->argc != 0) {
/* Create it */
target->rtos = calloc(1,sizeof(struct rtos));
target->rtos->type = rtos_types[x];
+ target->rtos->current_threadid = -1;
target->rtos->current_thread = 0;
target->rtos->symbols = NULL;
target->rtos->target = target;
+ /* put default thread handler in linux usecase it is overloaded*/
+ target->rtos->gdb_thread_packet = rtos_thread_packet;
if ( 0 != strcmp( cp, "auto") )
{
return JIM_OK;
}
+int gdb_thread_packet(struct connection *connection, char *packet, int packet_size)
+{
+ struct target *target = get_target_from_connection(connection);
+ if (target->rtos == NULL)
+ return rtos_thread_packet(connection, packet, packet_size); /* thread not found*/
+ return target->rtos->gdb_thread_packet(connection, packet, packet_size);
+}
+/* return -1 if no rtos defined, 0 if rtos and symbol to be asked, 1 if all
+ * symbol have been asked*/
+int rtos_qsymbol(struct connection *connection, char *packet, int packet_size)
+{
+ struct target *target = get_target_from_connection(connection);
+ if (target->rtos != NULL) {
+ int next_symbol_num = -1;
+ if (target->rtos->symbols == NULL)
+ target->rtos->type->get_symbol_list_to_lookup(&target->rtos->symbols);
+ if (0 == strcmp("qSymbol::", packet))
+ /* first query - */
+ next_symbol_num = 0;
+ else {
+ int64_t value = 0;
+ char *hex_name_str = malloc(strlen(packet));
+ char *name_str;
+ int symbol_num;
+
+ char *found = strstr(packet, "qSymbol::");
+ if (0 == found)
+ sscanf(packet, "qSymbol:%" SCNx64 ":%s", &value, hex_name_str);
+ else
+ /* No value returned by GDB - symbol was not found*/
+ sscanf(packet, "qSymbol::%s", hex_name_str);
+ name_str = (char *) malloc(1 + strlen(hex_name_str) / 2);
+
+ hex_to_str(name_str, hex_name_str);
+ symbol_num = 0;
+ while ((target->rtos->symbols[symbol_num].symbol_name != NULL)
+ && (0 != strcmp(target->rtos->symbols[symbol_num].symbol_name, name_str)))
+ symbol_num++;
+
+ if (target->rtos->symbols[symbol_num].symbol_name == NULL) {
+ LOG_OUTPUT("ERROR: unknown symbol\r\n");
+ gdb_put_packet(connection, "OK", 2);
+ return ERROR_OK;
+ }
+ target->rtos->symbols[symbol_num].address = value;
+ next_symbol_num = symbol_num+1;
+ free(hex_name_str);
+ free(name_str);
+ }
-int gdb_thread_packet(struct connection *connection, char *packet, int packet_size)
+ int symbols_done = 0;
+ if (target->rtos->symbols[next_symbol_num].symbol_name == NULL) {
+ if ((target->rtos_auto_detect == false) ||
+ (1 == target->rtos->type->detect_rtos(target))) {
+ /* Found correct RTOS or not autodetecting */
+ if (target->rtos_auto_detect == true)
+ LOG_OUTPUT("Auto-detected RTOS: %s\r\n", target->rtos->type->name);
+ symbols_done = 1;
+ } else {
+ /* Auto detecting RTOS and currently not found */
+ if (1 != rtos_try_next(target))
+ /* No more RTOS's to try */
+ symbols_done = 1;
+ else {
+ next_symbol_num = 0;
+ target->rtos->type->get_symbol_list_to_lookup(&target->rtos->symbols);
+ }
+ }
+ }
+ if (symbols_done == 1)
+ return symbols_done;
+ else {
+ char *symname = target->rtos->symbols[next_symbol_num].symbol_name;
+ char qsymstr[] = "qSymbol:";
+ char *opstring = (char *)malloc(sizeof(qsymstr)+strlen(symname)*2+1);
+ char *posptr = opstring;
+ posptr += sprintf(posptr, "%s", qsymstr);
+ str_to_hex(posptr, symname);
+ gdb_put_packet(connection, opstring, strlen(opstring));
+ free(opstring);
+ return symbols_done;
+ }
+ }
+ gdb_put_packet(connection, "OK", 2);
+ return -1;
+}
+
+
+int rtos_thread_packet(struct connection *connection, char *packet, int packet_size)
{
struct target *target = get_target_from_connection(connection);
tmp_str_ptr += sprintf( tmp_str_ptr, " : %s", detail->extra_info_str );
}
+ assert(strlen(tmp_str) ==
+ (size_t) (tmp_str_ptr - tmp_str));
+
char * hex_str = (char*) malloc( strlen(tmp_str)*2 +1 );
str_to_hex( hex_str, tmp_str );
}
else if (strstr(packet, "qSymbol"))
{
- if ( target->rtos != NULL )
+ if (rtos_qsymbol(connection, packet, packet_size) == 1)
{
- int next_symbol_num = -1;
- if (target->rtos->symbols == NULL)
- {
- target->rtos->type->get_symbol_list_to_lookup( &target->rtos->symbols );
- }
- if (0 == strcmp( "qSymbol::", packet ) )
- {
- // first query -
- next_symbol_num = 0;
- }
- else
- {
- int64_t value = 0;
- char * hex_name_str = malloc( strlen(packet));
- char * name_str;
- int symbol_num;
-
- char* found = strstr( packet, "qSymbol::" );
- if (0 == found )
- {
- sscanf(packet, "qSymbol:%" SCNx64 ":%s", &value, hex_name_str);
- }
- else
- {
- // No value returned by GDB - symbol was not found
- sscanf(packet, "qSymbol::%s", hex_name_str);
- }
- name_str = (char*) malloc( 1+ strlen(hex_name_str) / 2 );
-
- hex_to_str( name_str, hex_name_str );
-
-
- symbol_num = 0;
- while ( ( target->rtos->symbols[ symbol_num ].symbol_name != NULL ) && ( 0 != strcmp( target->rtos->symbols[ symbol_num ].symbol_name, name_str ) ) )
- {
- symbol_num++;
- }
-
-
- if ( target->rtos->symbols[ symbol_num ].symbol_name == NULL )
- {
- LOG_OUTPUT("ERROR: unknown symbol\r\n");
- gdb_put_packet(connection, "OK", 2);
- return ERROR_OK;
- }
-
- target->rtos->symbols[ symbol_num ].address = value;
-
- next_symbol_num = symbol_num+1;
- free( hex_name_str );
- free( name_str );
-
- }
-
- int symbols_done = 0;
- if ( target->rtos->symbols[ next_symbol_num ].symbol_name == NULL )
- {
- if ( ( target->rtos_auto_detect == false ) ||
- ( 1 == target->rtos->type->detect_rtos( target ) ) )
- {
- // Found correct RTOS or not autodetecting
- if ( target->rtos_auto_detect == true )
- {
- LOG_OUTPUT( "Auto-detected RTOS: %s\r\n",target->rtos->type->name );
- }
- symbols_done = 1;
- }
- else
- {
- // Auto detecting RTOS and currently not found
- if( 1 != rtos_try_next( target ) )
- {
- // No more RTOS's to try
- symbols_done = 1;
- }
- else
- {
- next_symbol_num = 0;
- target->rtos->type->get_symbol_list_to_lookup( &target->rtos->symbols );
- }
-
- }
- }
-
-
- if ( symbols_done == 1 )
- {
- target->rtos_auto_detect = false;
- target->rtos->type->create( target );
- target->rtos->type->update_threads(target->rtos);
- // No more symbols needed
- gdb_put_packet(connection, "OK", 2);
- return ERROR_OK;
-
- }
- else
- {
- char* symname = target->rtos->symbols[ next_symbol_num ].symbol_name;
- char qsymstr[] = "qSymbol:";
- char * opstring = (char*)malloc(sizeof(qsymstr)+strlen(symname)*2+1);
- char * posptr = opstring;
- posptr += sprintf( posptr, "%s", qsymstr );
- str_to_hex( posptr, symname );
- gdb_put_packet(connection, opstring, strlen(opstring));
- free(opstring);
- return ERROR_OK;
- }
-
+ target->rtos_auto_detect = false;
+ target->rtos->type->create(target);
+ target->rtos->type->update_threads(target->rtos);
+ /* No more symbols needed */
+ gdb_put_packet(connection, "OK", 2);
}
- gdb_put_packet(connection, "OK", 2);
return ERROR_OK;
}
else if (strstr(packet, "qfThreadInfo"))
}
else if ( packet[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations )
{
- if (packet[1] == 'g')
- {
- sscanf(packet, "Hg%16" SCNx64, ¤t_threadid);
- }
+ if ((packet[1] == 'g') && (target->rtos != NULL))
+ sscanf(packet, "Hg%16" SCNx64, &target->rtos->current_threadid);
gdb_put_packet(connection, "OK", 2);
return ERROR_OK;
}
return GDB_THREAD_PACKET_NOT_CONSUMED;
}
-int rtos_get_gdb_reg_list(struct connection *connection, struct reg **reg_list[], int *reg_list_size)
+int rtos_get_gdb_reg_list(struct connection *connection)
{
struct target *target = get_target_from_connection(connection);
-
- if ( ( target->rtos != NULL ) &&
- ( current_threadid != -1 ) &&
- ( current_threadid != 0 ) &&
- ( current_threadid != target->rtos->current_thread ) )
+ int64_t current_threadid = target->rtos->current_threadid;
+ if ((target->rtos != NULL) &&
+ (current_threadid != -1) &&
+ (current_threadid != 0) &&
+ ((current_threadid != target->rtos->current_thread) ||
+ (target->smp))) /* in smp several current thread are possible */
{
char * hex_reg_list;
target->rtos->type->get_thread_reg_list( target->rtos, current_threadid, &hex_reg_list );
*hex_reg_list = (char*)malloc( list_size*2 +1 );
tmp_str_ptr = *hex_reg_list;
new_stack_ptr = stack_ptr - stacking->stack_growth_direction * stacking->stack_registers_size;
+ if (stacking->stack_alignment != 0) {
+ /* Align new stack pointer to x byte boundary */
+ new_stack_ptr =
+ (new_stack_ptr & (~((int64_t) stacking->stack_alignment - 1))) +
+ ((stacking->stack_growth_direction == -1) ? stacking->stack_alignment : 0);
+ }
for( i = 0; i < stacking->num_output_registers; i++ )
{
int j;
}
-static int str_to_hex( char* hex_dst, char* src )
+int str_to_hex(char *hex_dst, char *src)
{
char * posptr = hex_dst;
unsigned i;