#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, struct target *target, char *packet, int packet_size)
+int gdb_thread_packet(struct connection *connection, char *packet, int packet_size)
{
- if (strstr(packet, "qP"))
- {
- #define TAG_THREADID 1 /* Echo the thread identifier */
- #define TAG_EXISTS 2 /* Is this process defined enough to
- fetch registers and its stack */
- #define TAG_DISPLAY 4 /* A short thing maybe to put on a window */
- #define TAG_THREADNAME 8 /* string, maps 1-to-1 with a thread is */
- #define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about */
-
- // TODO: need to scanf the mode variable (or it with the tags), and the threadid
-
- unsigned long mode;
- threadid_t threadid = 0;
- struct thread_detail* detail;
- sscanf(packet, "qP%8lx%16" SCNx64, &mode, &threadid);
+ 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;
- int found = -1;
+ next_symbol_num = symbol_num+1;
+ free(hex_name_str);
+ free(name_str);
+ }
- if ((target->rtos != NULL) && (target->rtos->thread_details
- != NULL)) {
- int thread_num;
- for (thread_num = 0; thread_num
- < target->rtos->thread_count; thread_num++) {
- if (target->rtos->thread_details[thread_num].threadid
- == threadid) {
- if (target->rtos->thread_details[thread_num].exists) {
- found = thread_num;
- }
+ 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 (found == -1) {
- gdb_put_packet(connection, "E01", 3); // thread not found
- return ERROR_OK;
- }
-
- detail = &target->rtos->thread_details[found];
-
- if ( detail->display_str != NULL )
- {
- mode &= TAG_DISPLAY;
- }
- if ( detail->thread_name_str != NULL )
- {
- mode &= TAG_THREADNAME;
+ 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;
}
- if ( detail->extra_info_str != NULL )
- {
- mode &= TAG_MOREDISPLAY;
- }
-
-
- mode &= TAG_THREADID | TAG_EXISTS;
-
- char thread_str[1000];
-
- sprintf(thread_str, "%08lx", mode);
- sprintf(thread_str, "%016" PRIx64, threadid);
+ }
+ gdb_put_packet(connection, "OK", 2);
+ return -1;
+}
- if (mode & TAG_THREADID) {
- sprintf(thread_str, "%08" PRIx32 "10%016" PRIx64, TAG_THREADID, threadid);
- }
- if (mode & TAG_EXISTS) {
- sprintf(thread_str, "%08" PRIx32 "08%08" PRIx32, TAG_EXISTS, (detail->exists==true)?1:0);
- }
- if (mode & TAG_DISPLAY) {
- sprintf(thread_str, "%08" PRIx32 "%02x%s", TAG_DISPLAY, (unsigned char)strlen(detail->display_str), detail->display_str );
- }
- if (mode & TAG_MOREDISPLAY) {
- sprintf(thread_str, "%08" PRIx32 "%02x%s", TAG_MOREDISPLAY, (unsigned char)strlen(detail->extra_info_str), detail->extra_info_str );
- }
- if (mode & TAG_THREADNAME) {
- sprintf(thread_str, "%08" PRIx32 "%02x%s", TAG_THREADNAME, (unsigned char)strlen(detail->thread_name_str), detail->thread_name_str );
- }
-
- //gdb_put_packet(connection, tmpstr, sizeof(tmpstr)-1);
- gdb_put_packet(connection, thread_str, strlen(thread_str));
+int rtos_thread_packet(struct connection *connection, char *packet, int packet_size)
+{
+ struct target *target = get_target_from_connection(connection);
- // gdb_put_packet(connection, "", 0);
- // gdb_put_packet(connection, "OK", 2); // all threads alive
- return ERROR_OK;
- }
- else if (strstr(packet, "qThreadExtraInfo,"))
+ if (strstr(packet, "qThreadExtraInfo,"))
{
if ((target->rtos != NULL) && (target->rtos->thread_details != NULL) && (target->rtos->thread_count != 0))
{
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 {
gdb_put_packet(connection, "E01", 3); // thread not found
}
+ return ERROR_OK;
}
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 target *target, struct reg **reg_list[], int *reg_list_size)
+int rtos_get_gdb_reg_list(struct connection *connection)
{
- if ( ( target->rtos != NULL ) &&
- ( current_threadid != -1 ) &&
- ( current_threadid != 0 ) &&
- ( current_threadid != target->rtos->current_thread ) )
+ struct target *target = get_target_from_connection(connection);
+ 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;