Beispiel #1
0
static int hwthread_thread_packet(struct connection *connection, const char *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);

	struct target *curr = NULL;
	int64_t current_threadid;

	if (packet[0] == 'H' && packet[1] == 'g') {
		sscanf(packet, "Hg%16" SCNx64, &current_threadid);

		if (current_threadid > 0) {
			if (hwthread_target_for_threadid(connection, current_threadid, &curr) != ERROR_OK) {
				LOG_ERROR("hwthread: cannot find thread id %"PRId64, current_threadid);
				gdb_put_packet(connection, "E01", 3);
				return ERROR_FAIL;
			}
			target->rtos->current_thread = current_threadid;
		} else
		if (current_threadid == 0 || current_threadid == -1)
			target->rtos->current_thread = threadid_from_target(target);

		target->rtos->current_threadid = current_threadid;

		gdb_put_packet(connection, "OK", 2);
		return ERROR_OK;
	}

	return rtos_thread_packet(connection, packet, packet_size);
}
Beispiel #2
0
int rtos_get_gdb_reg_list(struct connection *connection)
{
	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;

		LOG_DEBUG("RTOS: getting register list for thread 0x%" PRIx64
				  ", target->rtos->current_thread=0x%" PRIx64 "\r\n",
										current_threadid,
										target->rtos->current_thread);

		target->rtos->type->get_thread_reg_list(target->rtos,
			current_threadid,
			&hex_reg_list);

		if (hex_reg_list != NULL) {
			gdb_put_packet(connection, hex_reg_list, strlen(hex_reg_list));
			free(hex_reg_list);
			return ERROR_OK;
		}
	}
	return ERROR_FAIL;
}
Beispiel #3
0
static int hwthread_target_for_threadid(struct connection *connection, int64_t thread_id, struct target **p_target)
{
	struct target *target = get_target_from_connection(connection);
	struct target_list *head;
	struct target *curr;

	if (target->smp) {
		/* Find the thread with that thread_id */
		curr = NULL;
		for (head = target->head; head != NULL; head = head->next) {
			curr = head->target;

			if (thread_id == threadid_from_target(curr))
				break;
		}

		if (head == NULL)
			return ERROR_FAIL;
	} else {
		curr = target;
		if (thread_id != threadid_from_target(curr))
			return ERROR_FAIL;
	}

	*p_target = curr;

	return ERROR_OK;
}
Beispiel #4
0
/* packet j :smp status request */
int gdb_read_smp_packet(struct connection *connection,
		char *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);
	uint32_t len = sizeof(int32_t);
	uint8_t *buffer;
	char *hex_buffer;
	int retval = ERROR_OK;
	if (target->smp)
	{
		if (strstr(packet, "jc"))
		{
			hex_buffer = malloc(len * 2 + 1);
			buffer = (uint8_t *)&target->gdb_service->core[0];
			uint32_t i;
			for (i = 0; i < 4; i++)
			{
				uint8_t t = buffer[i];
				hex_buffer[2 * i] = DIGITS[(t >> 4) & 0xf];
				hex_buffer[2 * i + 1] = DIGITS[t & 0xf];
			}

			retval = gdb_put_packet(connection, hex_buffer, len * 2);

			free(hex_buffer);
		}
	}
Beispiel #5
0
int gdb_thread_packet(struct connection *connection, char const *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);
}
Beispiel #6
0
/* packet j :smp status request */
int gdb_read_smp_packet(struct connection *connection,
		char const *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);
	int retval = ERROR_OK;
	if (target->smp) {
		if (strncmp(packet, "jc", 2) == 0) {
			const uint32_t len = sizeof(target->gdb_service->core[0]);
			char hex_buffer[len * 2 + 1];
			char buffer[len];
			buf_set_u32(buffer, 0, len * 8, target->gdb_service->core[0]);
			int pkt_len = hexify(hex_buffer, buffer, sizeof(buffer), sizeof(hex_buffer));

			retval = gdb_put_packet(connection, hex_buffer, pkt_len);
		}
	} else
		retval = gdb_put_packet(connection, "E01", 3);
	return retval;
}
Beispiel #7
0
/* J :  smp set request */
int gdb_write_smp_packet(struct connection *connection,
		char const *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);
	char *separator;
	int coreid = 0;
	int retval = ERROR_OK;

	/* skip command character */
	if (target->smp) {
		if (strncmp(packet, "Jc", 2) == 0) {
			packet += 2;
			coreid = strtoul(packet, &separator, 16);
			target->gdb_service->core[1] = coreid;
			retval = gdb_put_packet(connection, "OK", 2);
		}
	} else
		retval = gdb_put_packet(connection, "E01", 3);

	return retval;
}
Beispiel #8
0
int rtos_get_gdb_reg_list(struct connection *connection, struct reg **reg_list[], int *reg_list_size)
{
	struct target *target = get_target_from_connection(connection);

	if ( ( target->rtos != NULL ) &&
		 ( current_threadid != -1 ) &&
		 ( current_threadid != 0 ) &&
		 ( current_threadid != target->rtos->current_thread ) )
	{
		char * hex_reg_list;
		target->rtos->type->get_thread_reg_list( target->rtos, current_threadid, &hex_reg_list );

		if ( hex_reg_list != NULL )
		{
			gdb_put_packet(connection, hex_reg_list, strlen(hex_reg_list));
			free(hex_reg_list);
			return ERROR_OK;
		}
	}
	return ERROR_FAIL;
}
Beispiel #9
0
/* packet j :smp status request */
int gdb_read_smp_packet(struct connection *connection,
		char *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);
	uint32_t len = sizeof(int32_t);
	uint8_t *buffer;
	char *hex_buffer;
	int retval = ERROR_OK;
	if (target->smp) {
		if (strncmp(packet, "jc", 2) == 0) {
			hex_buffer = malloc(len * 2 + 1);
			buffer = (uint8_t *)&target->gdb_service->core[0];
			int pkt_len = hexify(hex_buffer, (char *)buffer, len, len * 2 + 1);

			retval = gdb_put_packet(connection, hex_buffer, pkt_len);
			free(hex_buffer);
		}
	} else
		retval = gdb_put_packet(connection, "E01", 3);
	return retval;
}
Beispiel #10
0
int rtos_thread_packet(struct connection *connection, char const *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);

	if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) {
		if ((target->rtos != NULL) && (target->rtos->thread_details != NULL) &&
				(target->rtos->thread_count != 0)) {
			threadid_t threadid = 0;
			int found = -1;
			sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid);

			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;
					}
				}
			}
			if (found == -1) {
				gdb_put_packet(connection, "E01", 3);	/* thread not found */
				return ERROR_OK;
			}

			struct thread_detail *detail = &target->rtos->thread_details[found];

			int str_size = 0;
			if (detail->display_str != NULL)
				str_size += strlen(detail->display_str);
			if (detail->thread_name_str != NULL)
				str_size += strlen(detail->thread_name_str);
			if (detail->extra_info_str != NULL)
				str_size += strlen(detail->extra_info_str);

			char *tmp_str = calloc(str_size + 7, sizeof(char));
			char *tmp_str_ptr = tmp_str;

			if (detail->display_str != NULL)
				tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->display_str);
			if (detail->thread_name_str != NULL) {
				if (tmp_str_ptr != tmp_str)
					tmp_str_ptr += sprintf(tmp_str_ptr, " : ");
				tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->thread_name_str);
			}
			if (detail->extra_info_str != NULL) {
				if (tmp_str_ptr != tmp_str)
					tmp_str_ptr += sprintf(tmp_str_ptr, " : ");
				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 = malloc(strlen(tmp_str) * 2 + 1);
			int pkt_len = hexify(hex_str, tmp_str, 0, strlen(tmp_str) * 2 + 1);

			gdb_put_packet(connection, hex_str, pkt_len);
			free(hex_str);
			free(tmp_str);
			return ERROR_OK;

		}
		gdb_put_packet(connection, "", 0);
		return ERROR_OK;
	} else if (strncmp(packet, "qSymbol", 7) == 0) {
		if (rtos_qsymbol(connection, packet, packet_size) == 1) {
			target->rtos_auto_detect = false;
			target->rtos->type->create(target);
			target->rtos->type->update_threads(target->rtos);
		}
		return ERROR_OK;
	} else if (strncmp(packet, "qfThreadInfo", 12) == 0) {
		int i;
		if (target->rtos != NULL) {
			if (target->rtos->thread_count == 0) {
				gdb_put_packet(connection, "l", 1);
			} else {
				/*thread id are 16 char +1 for ',' */
				char *out_str = malloc(17 * target->rtos->thread_count + 1);
				char *tmp_str = out_str;
				for (i = 0; i < target->rtos->thread_count; i++) {
					tmp_str += sprintf(tmp_str, "%c%016" PRIx64, i == 0 ? 'm' : ',',
										target->rtos->thread_details[i].threadid);
				}
				gdb_put_packet(connection, out_str, strlen(out_str));
				free(out_str);
			}
		} else
			gdb_put_packet(connection, "l", 1);

		return ERROR_OK;
	} else if (strncmp(packet, "qsThreadInfo", 12) == 0) {
		gdb_put_packet(connection, "l", 1);
		return ERROR_OK;
	} else if (strncmp(packet, "qAttached", 9) == 0) {
		gdb_put_packet(connection, "1", 1);
		return ERROR_OK;
	} else if (strncmp(packet, "qOffsets", 8) == 0) {
		char offsets[] = "Text=0;Data=0;Bss=0";
		gdb_put_packet(connection, offsets, sizeof(offsets)-1);
		return ERROR_OK;
	} else if (strncmp(packet, "qCRC:", 5) == 0) {
		/* make sure we check this before "qC" packet below
		 * otherwise it gets incorrectly handled */
		return GDB_THREAD_PACKET_NOT_CONSUMED;
	} else if (strncmp(packet, "qC", 2) == 0) {
		if (target->rtos != NULL) {
			char buffer[19];
			int size;
			size = snprintf(buffer, 19, "QC%016" PRIx64, target->rtos->current_thread);
			gdb_put_packet(connection, buffer, size);
		} else
			gdb_put_packet(connection, "QC0", 3);
		return ERROR_OK;
	} else if (packet[0] == 'T') {	/* Is thread alive? */
		threadid_t threadid;
		int found = -1;
		sscanf(packet, "T%" SCNx64, &threadid);
		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;
				}
			}
		}
		if (found != -1)
			gdb_put_packet(connection, "OK", 2);	/* thread alive */
		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') && (target->rtos != NULL)) {
			sscanf(packet, "Hg%16" SCNx64, &target->rtos->current_threadid);
			LOG_DEBUG("RTOS: GDB requested to set current thread to 0x%" PRIx64 "\r\n",
										target->rtos->current_threadid);
		}
		gdb_put_packet(connection, "OK", 2);
		return ERROR_OK;
	}

	return GDB_THREAD_PACKET_NOT_CONSUMED;
}
Beispiel #11
0
/* rtos_qsymbol() processes and replies to all qSymbol packets from GDB.
 *
 * GDB sends a qSymbol:: packet (empty address, empty name) to notify
 * that it can now answer qSymbol::hexcodedname queries, to look up symbols.
 *
 * If the qSymbol packet has no address that means GDB did not find the
 * symbol, in which case auto-detect will move on to try the next RTOS.
 *
 * rtos_qsymbol() then calls the next_symbol() helper function, which
 * iterates over symbol names for the current RTOS until it finds the
 * symbol in the received GDB packet, and then returns the next entry
 * in the list of symbols.
 *
 * If GDB replied about the last symbol for the RTOS and the RTOS was
 * specified explicitly, then no further symbol lookup is done. When
 * auto-detecting, the RTOS driver _detect() function must return success.
 *
 * rtos_qsymbol() returns 1 if an RTOS has been detected, or 0 otherwise.
 */
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
{
	int rtos_detected = 0;
	uint64_t addr = 0;
	size_t reply_len;
	char reply[GDB_BUFFER_SIZE], cur_sym[GDB_BUFFER_SIZE / 2] = "";
	symbol_table_elem_t *next_sym = NULL;
	struct target *target = get_target_from_connection(connection);
	struct rtos *os = target->rtos;

	reply_len = sprintf(reply, "OK");

	if (!os)
		goto done;

	/* Decode any symbol name in the packet*/
	int len = unhexify(cur_sym, strchr(packet + 8, ':') + 1, strlen(strchr(packet + 8, ':') + 1));
	cur_sym[len] = 0;

	if ((strcmp(packet, "qSymbol::") != 0) &&               /* GDB is not offering symbol lookup for the first time */
	    (!sscanf(packet, "qSymbol:%" SCNx64 ":", &addr)) && /* GDB did not find an address for a symbol */
	    is_symbol_mandatory(os, cur_sym)) {					/* the symbol is mandatory for this RTOS */

		/* GDB could not find an address for the previous symbol */
		if (!target->rtos_auto_detect) {
			LOG_WARNING("RTOS %s not detected. (GDB could not find symbol \'%s\')", os->type->name, cur_sym);
			goto done;
		} else {
			/* Autodetecting RTOS - try next RTOS */
			if (!rtos_try_next(target)) {
				LOG_WARNING("No RTOS could be auto-detected!");
				goto done;
			}

			/* Next RTOS selected - invalidate current symbol */
			cur_sym[0] = '\x00';
		}
	}
	next_sym = next_symbol(os, cur_sym, addr);

	if (!next_sym->symbol_name) {
		/* No more symbols need looking up */

		if (!target->rtos_auto_detect) {
			rtos_detected = 1;
			goto done;
		}

		if (os->type->detect_rtos(target)) {
			LOG_INFO("Auto-detected RTOS: %s", os->type->name);
			rtos_detected = 1;
			goto done;
		} else {
			LOG_WARNING("No RTOS could be auto-detected!");
			goto done;
		}
	}

	if (8 + (strlen(next_sym->symbol_name) * 2) + 1 > sizeof(reply)) {
		LOG_ERROR("ERROR: RTOS symbol '%s' name is too long for GDB!", next_sym->symbol_name);
		goto done;
	}

	reply_len = snprintf(reply, sizeof(reply), "qSymbol:");
	reply_len += hexify(reply + reply_len, next_sym->symbol_name, 0, sizeof(reply) - reply_len);

done:
	gdb_put_packet(connection, reply, reply_len);
	return rtos_detected;
}
Beispiel #12
0
static int linux_thread_packet(struct connection *connection, char *packet,
                               int packet_size)
{
    int retval = ERROR_OK;
    struct current_thread *ct;
    struct target *target = get_target_from_connection(connection);
    struct linux_os *linux_os = (struct linux_os *)
                                target->rtos->rtos_specific_params;

    switch (packet[0]) {
    case 'T':		/* Is thread alive?*/

        linux_gdb_T_packet(connection, target, packet, packet_size);
        break;
    case 'H':		/* Set current thread */
        /*  ( 'c' for step and continue, 'g' for all other operations )*/
        /*LOG_INFO(" H packet received '%s'", packet);*/
        linux_gdb_h_packet(connection, target, packet, packet_size);
        break;
    case 'q':

        if (strncmp(packet, "qSymbol", 7) == 0) {
            if (rtos_qsymbol(connection, packet, packet_size) == 1) {
                linux_compute_virt2phys(target,
                                        target->rtos->
                                        symbols[INIT_TASK].
                                        address);
            }

            break;
        } else if (strncmp(packet, "qfThreadInfo", 12) == 0) {
            if (linux_os->thread_list == NULL) {
                retval = linux_gdb_thread_packet(target,
                                                 connection,
                                                 packet,
                                                 packet_size);
                break;
            } else {
                retval = linux_gdb_thread_update(target,
                                                 connection,
                                                 packet,
                                                 packet_size);
                break;
            }
        } else if (strncmp(packet, "qsThreadInfo", 12) == 0) {
            gdb_put_packet(connection, "l", 1);
            break;
        } else if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) {
            linux_thread_extra_info(target, connection, packet,
                                    packet_size);
            break;
        } else {
            retval = GDB_THREAD_PACKET_NOT_CONSUMED;
            break;
        }

    case 'Q':
        /* previously response was : thread not found
         * gdb_put_packet(connection, "E01", 3); */
        retval = GDB_THREAD_PACKET_NOT_CONSUMED;
        break;
    case 'c':
    case 's': {
        if (linux_os->threads_lookup == 1) {
            ct = linux_os->current_threads;

            while ((ct != NULL) && (ct->core_id) != target->coreid)
                ct = ct->next;

            if ((ct != NULL) && (ct->threadid == -1)) {
                ct = linux_os->current_threads;

                while ((ct != NULL) && (ct->threadid == -1))
                    ct = ct->next;
            }

            if ((ct != NULL) && (ct->threadid !=
                                 target->rtos->
                                 current_threadid)
                    && (target->rtos->current_threadid != -1))
                LOG_WARNING("WARNING! current GDB thread do not match" \
                            "current thread running." \
                            "Switch thread in GDB to threadid %d",
                            (int)ct->threadid);

            LOG_INFO("threads_needs_update = 1");
            linux_os->threads_needs_update = 1;
        }
    }

        /* if a packet handler returned an error, exit input loop */
    if (retval != ERROR_OK)
        return retval;
    }

    return retval;
}
Beispiel #13
0
int gdb_thread_packet(struct connection *connection, char *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);

	if (strstr(packet, "qThreadExtraInfo,"))
	{
		if ((target->rtos != NULL) && (target->rtos->thread_details != NULL) && (target->rtos->thread_count != 0))
		{
			threadid_t threadid = 0;
			int found = -1;
			sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid );

			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;
						}
					}
				}
			}
			if (found == -1) {
				gdb_put_packet(connection, "E01", 3); // thread not found
				return ERROR_OK;
			}

			struct thread_detail* detail = &target->rtos->thread_details[found];

			int str_size = 0;
			if ( detail->display_str != NULL )
			{
				str_size += strlen(detail->display_str);
			}
			if ( detail->thread_name_str != NULL )
			{
				str_size += strlen(detail->thread_name_str);
			}
			if ( detail->extra_info_str != NULL )
			{
				str_size += strlen(detail->extra_info_str);
			}

			char * tmp_str = (char*) malloc( str_size + 7 );
			char*  tmp_str_ptr = tmp_str;

			if ( detail->display_str != NULL )
			{
				tmp_str_ptr += sprintf( tmp_str_ptr, "%s", detail->display_str );
			}
			if ( detail->thread_name_str != NULL )
			{
				if ( tmp_str_ptr != tmp_str )
				{
					tmp_str_ptr += sprintf( tmp_str_ptr, " : " );
				}
				tmp_str_ptr += sprintf( tmp_str_ptr, "%s", detail->thread_name_str );
			}
			if ( detail->extra_info_str != NULL )
			{
				if ( tmp_str_ptr != tmp_str )
				{
					tmp_str_ptr += sprintf( tmp_str_ptr, " : " );
				}
				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 );

			gdb_put_packet(connection, hex_str, strlen(hex_str));
			free(hex_str);
			free(tmp_str);
			return ERROR_OK;

		}
		gdb_put_packet(connection, "", 0);
		return ERROR_OK;
	}
	else if (strstr(packet, "qSymbol"))
	{
		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 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;
			}

		}
		gdb_put_packet(connection, "OK", 2);
		return ERROR_OK;
	}
	else if (strstr(packet, "qfThreadInfo"))
	{
		int i;
		if ( ( target->rtos != NULL ) && ( target->rtos->thread_count != 0 ) )
		{

			char* out_str = (char*) malloc(17 * target->rtos->thread_count + 5);
			char* tmp_str = out_str;
			tmp_str += sprintf(tmp_str, "m");
			for (i = 0; i < target->rtos->thread_count; i++) {
				if (i != 0) {
					tmp_str += sprintf(tmp_str, ",");
				}
				tmp_str += sprintf(tmp_str, "%016" PRIx64,
						target->rtos->thread_details[i].threadid);
			}
			tmp_str[0] = 0;
			gdb_put_packet(connection, out_str, strlen(out_str));
		}
		else
		{
			gdb_put_packet(connection, "", 0);
		}

		return ERROR_OK;
	}
	else if (strstr(packet, "qsThreadInfo"))
	{
		gdb_put_packet(connection, "l", 1);
		return ERROR_OK;
	}
	else if (strstr(packet, "qAttached"))
	{
		gdb_put_packet(connection, "1", 1);
		return ERROR_OK;
	}
	else if (strstr(packet, "qOffsets"))
	{
		char offsets[] = "Text=0;Data=0;Bss=0";
		gdb_put_packet(connection, offsets, sizeof(offsets)-1);
		return ERROR_OK;
	}
	else if (strstr(packet, "qC"))
	{
		if( target->rtos!=NULL )
		{
			char buffer[15];
			int size;
			size = snprintf(buffer, 15, "QC%08X", (int)target->rtos->current_thread);
			gdb_put_packet(connection, buffer, size);
		}
		else
		{
			gdb_put_packet(connection, "QC0", 3);
		}
		return ERROR_OK;
	}
	else if ( packet[0] == 'T' ) // Is thread alive?
	{
		threadid_t threadid;
		int found = -1;
		sscanf(packet, "T%" SCNx64, &threadid);
		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;
					}
				}
			}
		}
		if (found != -1) {
			gdb_put_packet(connection, "OK", 2); // thread alive
		} 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, &current_threadid);
		}
		gdb_put_packet(connection, "OK", 2);
		return ERROR_OK;
	}

	return GDB_THREAD_PACKET_NOT_CONSUMED;
}