Пример #1
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;
}
Пример #2
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;
}