X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Frtos%2Flinux.c;h=dbbf97b4467ae2a3de26c6345b7cb6783a97b288;hb=4e98d44fd1dc67f763f06eeecc0453d65b1290dc;hp=3b2a2b0c34b440fb72effcc1ab450213820dd434;hpb=dba9293a8907516bfec826464ac2896ffaba6da6;p=openocd.git diff --git a/src/rtos/linux.c b/src/rtos/linux.c index 3b2a2b0c34..dbbf97b446 100644 --- a/src/rtos/linux.c +++ b/src/rtos/linux.c @@ -144,16 +144,6 @@ static int linux_read_memory(struct target *target, return ERROR_OK; } -static char *reg_converter(char *buffer, void *reg, int size) -{ - int i; - - for (i = 0; i < size; i++) - buffer += sprintf(buffer, "%02x", ((uint8_t *) reg)[i]); - - return buffer; -} - int fill_buffer(struct target *target, uint32_t addr, uint8_t *buffer) { @@ -174,15 +164,13 @@ uint32_t get_buffer(struct target *target, const uint8_t *buffer) } static int linux_os_thread_reg_list(struct rtos *rtos, - int64_t thread_id, char **hex_reg_list) + int64_t thread_id, struct rtos_reg **reg_list, int *num_regs) { 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 */ @@ -195,117 +183,52 @@ static int linux_os_thread_reg_list(struct rtos *rtos, 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 %" PRIx32, - 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, ®_list, ®_list_size, - REG_CLASS_GENERAL); - - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < reg_list_size; i++) - reg_packet_size += reg_list[i]->size; - - assert(reg_packet_size > 0); + if (found == 0) { + LOG_ERROR("could not find thread: %" PRIx64, thread_id); + return ERROR_FAIL; + } - *hex_reg_list = malloc(DIV_ROUND_UP(reg_packet_size, 8) * 2); + /* search target to perform the access */ + struct reg **gdb_reg_list; + struct target_list *head; + head = target->head; + found = 0; + do { + if (head->target->coreid == next->core_id) { - hex_string = *hex_reg_list; + target = head->target; + found = 1; + } else + head = head->next; - for (i = 0; i < reg_list_size; i++) { - if (!reg_list[i]->valid) - reg_list[i]->type->get(reg_list[i]); + } while ((head != (struct target_list *)NULL) && (found == 0)); - hex_string = reg_converter(hex_string, - reg_list[i]->value, - (reg_list[i]->size) / 8); - } + if (found == 0) { + LOG_ERROR + ( + "current thread %" PRIx64 ": no target to perform access of core id %" PRIx32, + thread_id, + next->core_id); + return ERROR_FAIL; + } - free(reg_list); + /*LOG_INFO("thread %lx current on core %x",thread_id, target->coreid);*/ + retval = target_get_gdb_reg_list(target, &gdb_reg_list, num_regs, REG_CLASS_GENERAL); + if (retval != ERROR_OK) + return retval; - } else { - struct threads *temp = linux_os->thread_list; - *hex_reg_list = calloc(1, 500 * sizeof(char)); - hex_string = *hex_reg_list; + *reg_list = calloc(*num_regs, sizeof(struct rtos_reg)); - for (i = 0; i < 16; i++) - hex_string += sprintf(hex_string, "%02x", 0); + for (int i = 0; i < *num_regs; ++i) { + if (!gdb_reg_list[i]->valid) + gdb_reg_list[i]->type->get(gdb_reg_list[i]); - while ((temp != NULL) && - (temp->threadid != target->rtos->current_threadid)) - temp = temp->next; + (*reg_list)[i].number = gdb_reg_list[i]->number; + (*reg_list)[i].size = gdb_reg_list[i]->size; - 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); - } + buf_cpy(gdb_reg_list[i]->value, (*reg_list)[i].value, (*reg_list)[i].size); } + return ERROR_OK; } @@ -698,17 +621,16 @@ struct threads *liste_del_task(struct threads *task_list, struct threads **t, struct threads *prev) { LOG_INFO("del task %" PRId64, (*t)->threadid); - prev->next = (*t)->next; - - if (prev == task_list) - task_list = prev; + if (prev) + prev->next = (*t)->next; + else + task_list = (*t)->next; /* free content of threads */ - if ((*t)->context) - free((*t)->context); + free((*t)->context); free(*t); - *t = prev; + *t = prev ? prev : task_list; return task_list; } @@ -802,6 +724,7 @@ int linux_get_tasks(struct target *target, int context) /* check that this thread is not one the current threads already * created */ + uint32_t base_addr; #ifdef PID_CHECK if (!current_pid(linux_os, t->pid)) { @@ -822,12 +745,13 @@ int linux_get_tasks(struct target *target, int context) t->context = cpu_context_read(target, t->base_addr, &t->thread_info_addr); + base_addr = next_task(target, t); } else { /*LOG_INFO("thread %s is a current thread already created",t->name); */ + base_addr = next_task(target, t); free(t); } - uint32_t base_addr = next_task(target, t); t = calloc(1, sizeof(struct threads)); t->base_addr = base_addr; } @@ -856,8 +780,7 @@ static int clean_threadlist(struct target *target) while (temp != NULL) { old = temp; - if (temp->context) - free(temp->context); + free(temp->context); temp = temp->next; free(old); @@ -1006,10 +929,8 @@ static int linux_task_update(struct target *target, int context) while (thread_list != NULL) { thread_list->status = 0; /*setting all tasks to dead state*/ - if (thread_list->context) { - free(thread_list->context); - thread_list->context = NULL; - } + free(thread_list->context); + thread_list->context = NULL; thread_list = thread_list->next; } @@ -1070,10 +991,8 @@ static int linux_task_update(struct target *target, int context) if (context) thread_list->context = cpu_context_read(target, - thread_list-> - base_addr, - &thread_list-> - thread_info_addr); + thread_list->base_addr, + &thread_list->thread_info_addr); } else { /* it is a current thread no need to read context */ } @@ -1134,7 +1053,7 @@ int linux_gdb_thread_packet(struct target *target, if (retval != ERROR_OK) return ERROR_TARGET_FAILURE; - char *out_str = calloc(1, 350 * sizeof(int64_t)); + char *out_str = calloc(MAX_THREADS * 17 + 10, 1); char *tmp_str = out_str; tmp_str += sprintf(tmp_str, "m"); struct threads *temp = linux_os->thread_list; @@ -1171,7 +1090,7 @@ int linux_gdb_thread_update(struct target *target, if (found == 1) { /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/ - char *out_strr = calloc(1, 350 * sizeof(int64_t)); + char *out_strr = calloc(MAX_THREADS * 17 + 10, 1); char *tmp_strr = out_strr; tmp_strr += sprintf(tmp_strr, "m"); /*LOG_INFO("CHAR MALLOC & M DONE");*/ @@ -1255,7 +1174,7 @@ int linux_gdb_T_packet(struct connection *connection, if (linux_os->threads_needs_update == 0) { struct threads *temp = linux_os->thread_list; - struct threads *prev = linux_os->thread_list; + struct threads *prev = NULL; while (temp != NULL) { if (temp->threadid == threadid) { @@ -1265,9 +1184,8 @@ int linux_gdb_T_packet(struct connection *connection, } else { /* delete item in the list */ linux_os->thread_list = - liste_del_task(linux_os-> - thread_list, &temp, - prev); + liste_del_task(linux_os->thread_list, + &temp, prev); linux_os->thread_count--; gdb_put_packet(connection, "E01", 3); return ERROR_OK; @@ -1398,9 +1316,7 @@ static int linux_thread_packet(struct connection *connection, char const *packet if (strncmp(packet, "qSymbol", 7) == 0) { if (rtos_qsymbol(connection, packet, packet_size) == 1) { linux_compute_virt2phys(target, - target->rtos-> - symbols[INIT_TASK]. - address); + target->rtos->symbols[INIT_TASK].address); } break; @@ -1451,11 +1367,10 @@ static int linux_thread_packet(struct connection *connection, char const *packet } if ((ct != NULL) && (ct->threadid != - target->rtos-> - current_threadid) + target->rtos->current_threadid) && (target->rtos->current_threadid != -1)) - LOG_WARNING("WARNING! current GDB thread do not match" \ - "current thread running." \ + LOG_WARNING("WARNING! current GDB thread do not match " + "current thread running. " "Switch thread in GDB to threadid %d", (int)ct->threadid); @@ -1485,8 +1400,7 @@ static int linux_os_smp_init(struct target *target) while (head != (struct target_list *)NULL) { if (head->target->rtos != rtos) { struct linux_os *smp_os_linux = - (struct linux_os *)head->target->rtos-> - rtos_specific_params; + (struct linux_os *)head->target->rtos->rtos_specific_params; /* remap smp target on rtos */ free(head->target->rtos); head->target->rtos = rtos;