Beispiel #1
0
static int hwthread_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
					struct rtos_reg **rtos_reg_list, int *num_regs)
{
	struct target_list *head;
	struct target *target;
	struct target *curr;
	struct reg **reg_list;
	int retval;

	if (rtos == NULL)
		return ERROR_FAIL;

	target = rtos->target;

	/* Find the thread with that thread_id */
	if (target->smp) {
		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;

	}

	if (!target_was_examined(curr))
		return ERROR_FAIL;

	retval = target_get_gdb_reg_list(curr, &reg_list, num_regs,
			REG_CLASS_GENERAL);
	if (retval != ERROR_OK)
		return retval;

	*rtos_reg_list = calloc(*num_regs, sizeof(struct rtos_reg));
	if (*rtos_reg_list == NULL) {
		free(reg_list);
		return ERROR_FAIL;
	}

	for (int i = 0; i < *num_regs; i++) {
		(*rtos_reg_list)[i].number = (*reg_list)[i].number;
		(*rtos_reg_list)[i].size = (*reg_list)[i].size;
		memcpy((*rtos_reg_list)[i].value, (*reg_list)[i].value,
		       ((*reg_list)[i].size + 7) / 8);
	}

	free(reg_list);

	return ERROR_OK;

}
Beispiel #2
0
int get_current(struct target *target, int create)
{
    struct target_list *head;
    head = target->head;
    uint8_t *buf;
    uint32_t val;
    uint32_t ti_addr;
    uint8_t *buffer = calloc(1, 4);
    struct linux_os *linux_os = (struct linux_os *)
                                target->rtos->rtos_specific_params;
    struct current_thread *ctt = linux_os->current_threads;

    /*  invalid current threads content */
    while (ctt != NULL) {
        ctt->threadid = -1;
        ctt->TS = 0xdeadbeef;
        ctt = ctt->next;
    }

    while (head != (struct target_list *)NULL) {
        struct reg **reg_list;
        int reg_list_size;
        int retval;

        if (target_get_gdb_reg_list(head->target, &reg_list,
                                    &reg_list_size) != ERROR_OK) {
            free(buffer);
            return ERROR_TARGET_FAILURE;
        }

        if (!reg_list[13]->valid)
            reg_list[13]->type->get(reg_list[13]);

        buf = reg_list[13]->value;
        val = get_buffer(target, buf);
        ti_addr = (val & 0xffffe000);
        uint32_t TS_addr = ti_addr + 0xc;
        retval = fill_buffer(target, TS_addr, buffer);

        if (retval == ERROR_OK) {
            uint32_t TS = get_buffer(target, buffer);
            uint32_t cpu, on_cpu = TS + ONCPU;
            retval = fill_buffer(target, on_cpu, buffer);

            if (retval == ERROR_OK) {
                /*uint32_t cpu = get_buffer(target, buffer);*/
                struct current_thread *ct =
                        linux_os->current_threads;
                cpu = head->target->coreid;

                while ((ct != NULL) && (ct->core_id != (int32_t) cpu))
                    ct = ct->next;

                if ((ct != NULL) && (ct->TS == 0xdeadbeef))
                    ct->TS = TS;
                else
                    LOG_ERROR
                    ("error in linux current thread update");

                if (create) {
                    struct threads *t;
                    t = calloc(1, sizeof(struct threads));
                    t->base_addr = ct->TS;
                    fill_task(target, t);
                    get_name(target, t);
                    t->oncpu = cpu;
                    insert_into_threadlist(target, t);
                    t->status = 3;
                    t->thread_info_addr = 0xdeadbeef;
                    ct->threadid = t->threadid;
                    linux_os->thread_count++;
#ifdef PID_CHECK
                    ct->pid = t->pid;
#endif
                    /*LOG_INFO("Creation of current thread %s",t->name);*/
                }
            }
        }

        free(reg_list);
        head = head->next;
    }

    free(buffer);

    return ERROR_OK;
}
Beispiel #3
0
static int linux_os_thread_reg_list(struct rtos *rtos,
                                    int64_t thread_id, char **hex_reg_list)
{
    struct target *target = rtos->target;
    struct linux_os *linux_os = (struct linux_os *)
                                target->rtos->rtos_specific_params;
    int i = 0;
    struct current_thread *tmp = linux_os->current_threads;
    struct current_thread *next;
    char *hex_string;
    int found = 0;
    int retval;
    /*  check if a current thread is requested  */
    next = tmp;

    do {
        if (next->threadid == thread_id)
            found = 1;
        else
            next = next->next;
    } while ((found == 0) && (next != tmp) && (next != NULL));

    if (found == 1) {
        /*  search target to perfom the access  */
        struct reg **reg_list;
        int reg_list_size, reg_packet_size = 0;
        struct target_list *head;
        head = target->head;
        found = 0;
        do {
            if (head->target->coreid == next->core_id) {

                target = head->target;
                found = 1;
            } else
                head = head->next;

        } while ((head != (struct target_list *)NULL) && (found == 0));

        if (found == 0) {
            LOG_ERROR
            (
                "current thread %" PRIx64 ": no target to perform access of core id %x",
                thread_id,
                next->core_id);
            return ERROR_FAIL;
        }

        /*LOG_INFO("thread %lx current on core %x",thread_id,
         * target->coreid);*/
        retval =
            target_get_gdb_reg_list(target, &reg_list, &reg_list_size);

        if (retval != ERROR_OK)
            return retval;

        for (i = 0; i < reg_list_size; i++)
            reg_packet_size += reg_list[i]->size;

        *hex_reg_list = malloc(DIV_ROUND_UP(reg_packet_size, 8) * 2);

        hex_string = *hex_reg_list;

        for (i = 0; i < reg_list_size; i++) {
            if (!reg_list[i]->valid)
                reg_list[i]->type->get(reg_list[i]);

            hex_string = reg_converter(hex_string,
                                       reg_list[i]->value,
                                       (reg_list[i]->size) / 8);
        }

        free(reg_list);

    } else {
        struct threads *temp = linux_os->thread_list;
        *hex_reg_list = (char *)calloc(1, 500 * sizeof(char));
        hex_string = *hex_reg_list;

        for (i = 0; i < 16; i++)
            hex_string += sprintf(hex_string, "%02x", 0);

        while ((temp != NULL) &&
                (temp->threadid != target->rtos->current_threadid))
            temp = temp->next;

        if (temp != NULL) {
            if (temp->context == NULL)
                temp->context = cpu_context_read(target,
                                                 temp->
                                                 base_addr,
                                                 &temp->
                                                 thread_info_addr);

            hex_string =
                reg_converter(hex_string, &temp->context->R4, 4);
            hex_string =
                reg_converter(hex_string, &temp->context->R5, 4);
            hex_string =
                reg_converter(hex_string, &temp->context->R6, 4);
            hex_string =
                reg_converter(hex_string, &temp->context->R7, 4);
            hex_string =
                reg_converter(hex_string, &temp->context->R8, 4);
            hex_string =
                reg_converter(hex_string, &temp->context->R9, 4);

            for (i = 0; i < 4; i++)	/*R10 = 0x0 */
                hex_string += sprintf(hex_string, "%02x", 0);

            hex_string =
                reg_converter(hex_string, &temp->context->FP, 4);
            hex_string =
                reg_converter(hex_string, &temp->context->IP, 4);
            hex_string =
                reg_converter(hex_string, &temp->context->SP, 4);

            for (i = 0; i < 4; i++)
                hex_string += sprintf(hex_string, "%02x", 0);

            hex_string =
                reg_converter(hex_string, &temp->context->PC, 4);

            for (i = 0; i < 100; i++)	/*100 */
                hex_string += sprintf(hex_string, "%02x", 0);

            uint32_t cpsr = 0x00000000;
            reg_converter(hex_string, &cpsr, 4);
        }
    }
    return ERROR_OK;
}