X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Frtos%2Flinux.c;h=e692ada8274edd417b303fd41751869cd920fafd;hp=e249ff49e96217f53816de3ea73a0ff32ae188ce;hb=e1d2abc9ca53d983716ac9dcc481b8130d8e5ca2;hpb=7b032df3aa63905c16c63f1ba4414a04687f3777 diff --git a/src/rtos/linux.c b/src/rtos/linux.c index e249ff49e9..e692ada827 100644 --- a/src/rtos/linux.c +++ b/src/rtos/linux.c @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -28,8 +28,8 @@ #include "target/target.h" #include "target/target_type.h" #include "helper/log.h" +#include "helper/types.h" #include "rtos.h" -#include "helper/log.h" #include "rtos_standard_stackings.h" #include #include "server/gdb_server.h" @@ -140,9 +140,9 @@ static int linux_read_memory(struct target *target, return ERROR_FAIL; } #ifdef PHYS - target->type->read_phys_memory(target, pa, size, count, buffer); + target_read_phys_memory(target, pa, size, count, buffer); #endif - target->type->read_memory(target, address, size, count, buffer); + target_read_memory(target, address, size, count, buffer); return ERROR_OK; } @@ -226,7 +226,8 @@ static int linux_os_thread_reg_list(struct rtos *rtos, /*LOG_INFO("thread %lx current on core %x",thread_id, * target->coreid);*/ retval = - target_get_gdb_reg_list(target, ®_list, ®_list_size); + target_get_gdb_reg_list(target, ®_list, ®_list_size, + REG_CLASS_GENERAL); if (retval != ERROR_OK) return retval; @@ -234,6 +235,8 @@ static int linux_os_thread_reg_list(struct rtos *rtos, for (i = 0; i < reg_list_size; i++) reg_packet_size += reg_list[i]->size; + assert(reg_packet_size > 0); + *hex_reg_list = malloc(DIV_ROUND_UP(reg_packet_size, 8) * 2); hex_string = *hex_reg_list; @@ -302,7 +305,7 @@ static int linux_os_thread_reg_list(struct rtos *rtos, hex_string += sprintf(hex_string, "%02x", 0); uint32_t cpsr = 0x00000000; - hex_string = reg_converter(hex_string, &cpsr, 4); + reg_converter(hex_string, &cpsr, 4); } } return ERROR_OK; @@ -326,9 +329,9 @@ static int linux_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) { unsigned int i; *symbol_list = (symbol_table_elem_t *) - malloc(sizeof(symbol_table_elem_t) / sizeof(char *)); + malloc(sizeof(symbol_table_elem_t) * ARRAY_SIZE(linux_symbol_list)); - for (i = 0; i < sizeof(linux_symbol_list) / sizeof(char *); i++) + for (i = 0; i < ARRAY_SIZE(linux_symbol_list); i++) (*symbol_list)[i].symbol_name = linux_symbol_list[i]; return 0; @@ -420,6 +423,8 @@ int fill_task(struct target *target, struct threads *t) } else LOG_ERROR("fill task: unable to read memory"); + free(buffer); + return retval; } @@ -494,8 +499,10 @@ int get_current(struct target *target, int create) int retval; if (target_get_gdb_reg_list(head->target, ®_list, - ®_list_size) != ERROR_OK) + ®_list_size, REG_CLASS_GENERAL) != ERROR_OK) { + free(buffer); return ERROR_TARGET_FAILURE; + } if (!reg_list[13]->valid) reg_list[13]->type->get(reg_list[13]); @@ -526,7 +533,7 @@ int get_current(struct target *target, int create) LOG_ERROR ("error in linux current thread update"); - if (create) { + if (create && ct) { struct threads *t; t = calloc(1, sizeof(struct threads)); t->base_addr = ct->TS; @@ -550,6 +557,8 @@ int get_current(struct target *target, int create) head = head->next; } + free(buffer); + return ERROR_OK; } @@ -615,6 +624,7 @@ retry: (uint8_t *) registers); if (retval != ERROR_OK) { + free(buffer); LOG_ERROR("cpu_context: unable to read memory\n"); return context; } @@ -643,6 +653,8 @@ retry: if (*thread_info_addr_old == 0xdeadbeef) *thread_info_addr_old = thread_info_addr_update; + free(buffer); + return context; } @@ -655,11 +667,13 @@ uint32_t next_task(struct target *target, struct threads *t) if (retval == ERROR_OK) { uint32_t val = get_buffer(target, buffer); val = val - NEXT; - return val; free(buffer); + return val; } else LOG_ERROR("next task: unable to read memory"); + free(buffer); + return 0; } @@ -769,15 +783,16 @@ int linux_get_tasks(struct target *target, int context) struct threads *last = NULL; t->base_addr = linux_os->init_task_addr; /* retrieve the thread id , currently running in the different smp core */ - retval = get_current(target, 1); + get_current(target, 1); while (((t->base_addr != linux_os->init_task_addr) && (t->base_addr != 0)) || (loop == 0)) { loop++; - retval = fill_task(target, t); + fill_task(target, t); retval = get_name(target, t); if (loop > MAX_THREADS) { + free(t); LOG_INFO("more than %d threads !!", MAX_THREADS); return ERROR_FAIL; } @@ -829,6 +844,7 @@ int linux_get_tasks(struct target *target, int context) (timeval_ms() - start) / linux_os->threadid_count); LOG_INFO("threadid count %d", linux_os->threadid_count); + free(t); return ERROR_OK; } @@ -973,7 +989,7 @@ error_handling: #ifndef PID_CHECK error_handling: free(t); - LOG_ERROR("unable toread pid"); + LOG_ERROR("unable to read pid"); return; #endif @@ -1124,13 +1140,12 @@ int linux_gdb_thread_packet(struct target *target, char *tmp_str = out_str; tmp_str += sprintf(tmp_str, "m"); struct threads *temp = linux_os->thread_list; - tmp_str += sprintf(tmp_str, "%016" PRIx64, temp->threadid); - temp = temp->next; while (temp != NULL) { - tmp_str += sprintf(tmp_str, ","); tmp_str += sprintf(tmp_str, "%016" PRIx64, temp->threadid); temp = temp->next; + if (temp) + tmp_str += sprintf(tmp_str, ","); } gdb_put_packet(connection, out_str, strlen(out_str)); @@ -1204,7 +1219,7 @@ int linux_thread_extra_info(struct target *target, char *tmp_str = (char *)calloc(1, str_size + 50); char *tmp_str_ptr = tmp_str; - /* discriminate cuurent task */ + /* discriminate current task */ if (temp->status == 3) tmp_str_ptr += sprintf(tmp_str_ptr, "%s", pid_current); @@ -1214,12 +1229,11 @@ int linux_thread_extra_info(struct target *target, tmp_str_ptr += sprintf(tmp_str_ptr, "%d", (int)temp->pid); tmp_str_ptr += sprintf(tmp_str_ptr, "%s", " | "); - tmp_str_ptr += sprintf(tmp_str_ptr, "%s", name); - tmp_str_ptr += sprintf(tmp_str_ptr, "%s", temp->name); - char *hex_str = - (char *)calloc(1, strlen(tmp_str) * 2 + 1); - str_to_hex(hex_str, tmp_str); - gdb_put_packet(connection, hex_str, strlen(hex_str)); + sprintf(tmp_str_ptr, "%s", name); + sprintf(tmp_str_ptr, "%s", temp->name); + char *hex_str = (char *)calloc(1, 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; @@ -1383,10 +1397,8 @@ static int linux_thread_packet(struct connection *connection, char *packet, break; case 'q': - if ((strstr(packet, "qSymbol"))) { + if (strncmp(packet, "qSymbol", 7) == 0) { if (rtos_qsymbol(connection, packet, packet_size) == 1) { - gdb_put_packet(connection, "OK", 2); - linux_compute_virt2phys(target, target->rtos-> symbols[INIT_TASK]. @@ -1394,7 +1406,7 @@ static int linux_thread_packet(struct connection *connection, char *packet, } break; - } else if (strstr(packet, "qfThreadInfo")) { + } else if (strncmp(packet, "qfThreadInfo", 12) == 0) { if (linux_os->thread_list == NULL) { retval = linux_gdb_thread_packet(target, connection, @@ -1408,10 +1420,10 @@ static int linux_thread_packet(struct connection *connection, char *packet, packet_size); break; } - } else if (strstr(packet, "qsThreadInfo")) { + } else if (strncmp(packet, "qsThreadInfo", 12) == 0) { gdb_put_packet(connection, "l", 1); break; - } else if (strstr(packet, "qThreadExtraInfo,")) { + } else if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) { linux_thread_extra_info(target, connection, packet, packet_size); break; @@ -1454,7 +1466,7 @@ static int linux_thread_packet(struct connection *connection, char *packet, } } - /* if a packet handler returned an error, exit input loop */ + /* if a packet handler returned an error, exit input loop */ if (retval != ERROR_OK) return retval; }