X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Frtos%2Frtos.c;h=a0bbc82b5ec03871b9d4f49baa519711558f914b;hb=433ca26f1abe59f39844eeac0dafef6cb7fdd520;hp=3c029f5a053f89508c169abc6bd0d70bc96422c2;hpb=b01e13604587837e20bd4a3a1e78e650c1ce3b77;p=openocd.git diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index 3c029f5a05..a0bbc82b5e 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -29,10 +29,8 @@ #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 */ @@ -48,12 +46,20 @@ static struct rtos_type *rtos_types[] = 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) { @@ -113,9 +119,12 @@ int rtos_create(Jim_GetOptInfo *goi, struct target * target) /* 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") ) { @@ -125,10 +134,97 @@ int rtos_create(Jim_GetOptInfo *goi, struct target * target) 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); @@ -215,118 +311,14 @@ int gdb_thread_packet(struct connection *connection, char *packet, int packet_si } 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")) @@ -413,10 +405,8 @@ int gdb_thread_packet(struct connection *connection, char *packet, int packet_si } 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; } @@ -424,14 +414,15 @@ int gdb_thread_packet(struct connection *connection, char *packet, int packet_si 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 ); @@ -490,6 +481,12 @@ int rtos_generic_stack_read( struct target * target, const struct rtos_register_ *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; @@ -571,7 +568,7 @@ static void hex_to_str( char* dst, char * hex_src ) } -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;