25 #define LINUX_USER_KERNEL_BORDER 0xc0000000
28 #define MAX_THREADS 200
105 LOG_ERROR(
"Cannot compute linux virt2phys translation");
127 LOG_ERROR(
"linux awareness : address in user space");
149 int64_t thread_id,
struct rtos_reg **reg_list,
int *num_regs)
162 if (next->threadid == thread_id)
166 }
while ((found == 0) && (next != tmp) && (next));
169 LOG_ERROR(
"could not find thread: %" PRIx64, thread_id);
174 struct reg **gdb_reg_list;
188 "current thread %" PRIx64
": no target to perform access of core id %" PRIx32,
199 *reg_list = calloc(*num_regs,
sizeof(
struct rtos_reg));
201 for (
int i = 0; i < *num_regs; ++i) {
202 if (!gdb_reg_list[i]->valid)
203 gdb_reg_list[i]->
type->
get(gdb_reg_list[i]);
205 (*reg_list)[i].number = gdb_reg_list[i]->
number;
206 (*reg_list)[i].size = gdb_reg_list[i]->
size;
208 buf_cpy(gdb_reg_list[i]->value, (*reg_list)[i].value, (*reg_list)[i].
size);
269 LOG_ERROR(
"fill_task_pid: unable to read memory");
281 uint8_t *
buffer = calloc(1, 4);
288 LOG_ERROR(
"fill_task: unable to read memory");
296 LOG_ERROR(
"fill task: unable to read memory");
304 LOG_ERROR(
"fill task: unable to read memory");
312 uint32_t asid_addr = val +
MM_CTX;
320 (
"fill task: unable to read memory -- ASID");
324 LOG_ERROR(
"fill task: unable to read memory");
338 for (i = 0; i < 17; i++)
344 LOG_ERROR(
"get_name: unable to read memory\n");
351 t->
name[3] = raw_name >> 24;
352 t->
name[2] = raw_name >> 16;
353 t->
name[1] = raw_name >> 8;
354 t->
name[0] = raw_name;
357 t->
name[7] = raw_name >> 24;
358 t->
name[6] = raw_name >> 16;
359 t->
name[5] = raw_name >> 8;
360 t->
name[4] = raw_name;
363 t->
name[11] = raw_name >> 24;
364 t->
name[10] = raw_name >> 16;
365 t->
name[9] = raw_name >> 8;
366 t->
name[8] = raw_name;
369 t->
name[15] = raw_name >> 24;
370 t->
name[14] = raw_name >> 16;
371 t->
name[13] = raw_name >> 8;
372 t->
name[12] = raw_name;
383 uint8_t *
buffer = calloc(1, 4);
391 ctt->TS = 0xdeadbeef;
396 struct reg **reg_list;
406 if (!reg_list[13]->
valid)
407 reg_list[13]->
type->
get(reg_list[13]);
409 buf = reg_list[13]->
value;
411 ti_addr = (val & 0xffffe000);
412 uint32_t ts_addr = ti_addr + 0xc;
417 uint32_t cpu, on_cpu = TS +
ONCPU;
426 while ((ct) && (ct->
core_id != (int32_t) cpu))
429 if ((ct) && (ct->
TS == 0xdeadbeef))
433 (
"error in linux current thread update");
437 t = calloc(1,
sizeof(
struct threads));
464 uint32_t *thread_info_addr_old)
467 uint32_t preempt_count_addr = 0;
468 uint32_t registers[10];
469 uint8_t *
buffer = calloc(1, 4);
470 uint32_t stack = base_addr +
QAT;
471 uint32_t thread_info_addr = 0;
472 uint32_t thread_info_addr_update = 0;
474 context->
R4 = 0xdeadbeef;
475 context->
R5 = 0xdeadbeef;
476 context->
R6 = 0xdeadbeef;
477 context->
R7 = 0xdeadbeef;
478 context->
R8 = 0xdeadbeef;
479 context->
R9 = 0xdeadbeef;
480 context->
IP = 0xdeadbeef;
481 context->
FP = 0xdeadbeef;
482 context->
SP = 0xdeadbeef;
483 context->
PC = 0xdeadbeef;
486 if (*thread_info_addr_old == 0xdeadbeef) {
492 LOG_ERROR(
"cpu_context: unable to read memory");
494 thread_info_addr_update = thread_info_addr;
496 thread_info_addr = *thread_info_addr_old;
498 preempt_count_addr = thread_info_addr +
PREEMPT;
504 if (*thread_info_addr_old != 0xdeadbeef) {
506 (
"cpu_context: cannot read at thread_info_addr");
510 (
"cpu_context : thread_info_addr in userspace!!!");
512 *thread_info_addr_old = 0xdeadbeef;
516 LOG_ERROR(
"cpu_context: unable to read memory");
522 (uint8_t *) registers);
526 LOG_ERROR(
"cpu_context: unable to read memory\n");
551 if (*thread_info_addr_old == 0xdeadbeef)
552 *thread_info_addr_old = thread_info_addr_update;
561 uint8_t *
buffer = calloc(1, 4);
571 LOG_ERROR(
"next task: unable to read memory");
600 LOG_INFO(
"del task %" PRId64, (*t)->threadid);
604 task_list = (*t)->
next;
610 *t = prev ? prev : task_list;
624 struct threads *temp = task_list;
649 while ((ct) && (ct->pid != pid))
651 while ((ct) && (ct->
TS != base_addr))
655 if ((ct) && (ct->pid == pid))
657 if ((ct) && (ct->
TS == base_addr))
733 t = calloc(1,
sizeof(
struct threads));
742 LOG_INFO(
"complete time %" PRId64
", thread mean %" PRId64
"\n",
776 os_linux->
name =
"linux";
818 if (ct->threadid == -1) {
822 t = calloc(1,
sizeof(
struct threads));
830 (
"linux identify_current_threads: unable to read pid");
868 LOG_INFO(
"current thread core %x identified %s",
869 ct->core_id, t->
name);
871 LOG_INFO(
"current thread core %x, reused %s",
872 ct->core_id, t->
name);
880 LOG_INFO(
"current thread core %x , already identified %s !!!",
881 ct->core_id, tmp.
name);
924 uint32_t previous = 0xdeadbeef;
931 (t->
base_addr != previous)) || (loop == 0)) {
938 retval = fill_task_pid(
target, t);
948 while (thread_list) {
950 if (t->
pid == thread_list->pid) {
952 if (t->
base_addr == thread_list->base_addr) {
954 if (!thread_list->status) {
956 if (t->
base_addr != thread_list->base_addr)
957 LOG_INFO(
"thread base_addr has changed !!");
961 thread_list->status = 1;
970 thread_list->context =
972 thread_list->base_addr,
973 &thread_list->thread_info_addr);
983 thread_list = thread_list->next;
1000 t = calloc(1,
sizeof(
struct threads));
1007 LOG_INFO(
"update thread done %" PRId64
", mean%" PRId64
"\n",
1024 LOG_INFO(
"received thread request without init task address");
1039 char *tmp_str = out_str;
1040 tmp_str += sprintf(tmp_str,
"m");
1044 tmp_str += sprintf(tmp_str,
"%016" PRIx64, temp->
threadid);
1047 tmp_str += sprintf(tmp_str,
",");
1075 char *out_strr = calloc(
MAX_THREADS * 17 + 10, 1);
1076 char *tmp_strr = out_strr;
1077 tmp_strr += sprintf(tmp_strr,
"m");
1079 tmp_strr += sprintf(tmp_strr,
"%016" PRIx64, temp->threadid);
1085 tmp_strr += sprintf(tmp_strr,
",");
1087 sprintf(tmp_strr,
"%016" PRIx64, temp->threadid);
1106 int64_t threadid = 0;
1109 sscanf(packet,
"qThreadExtraInfo,%" SCNx64, &threadid);
1115 char *tmp_str =
alloc_printf(
"%cPID: %" PRIu32
", Name: %s",
1116 temp->
status == 3 ?
'*' :
' ',
1122 char *hex_str = calloc(1, strlen(tmp_str) * 2 + 1);
1123 size_t pkt_len =
hexify(hex_str, (
const uint8_t *)tmp_str,
1124 strlen(tmp_str), strlen(tmp_str) * 2 + 1);
1139 struct target *
target,
char const *packet,
int packet_size)
1145 sscanf(packet,
"T%" SCNx64, &threadid);
1172 LOG_INFO(
"gdb requested status on non existing thread");
1199 struct target *
target,
char const *packet,
int packet_size)
1209 int64_t current_gdb_thread_rq;
1212 if ((ct) && (ct->threadid == -1)) {
1215 while ((ct) && (ct->threadid == -1))
1222 LOG_INFO(
"no current thread identified");
1228 while ((ct) && (ct->threadid == -1)) {
1231 LOG_INFO(
"name of unidentified thread %s",
1240 if (packet[1] ==
'g') {
1241 sscanf(packet,
"Hg%16" SCNx64, ¤t_gdb_thread_rq);
1243 if (current_gdb_thread_rq == 0) {
1248 current_gdb_thread_rq;
1251 }
else if (packet[1] ==
'c') {
1252 sscanf(packet,
"Hc%16" SCNx64, ¤t_gdb_thread_rq);
1254 if ((current_gdb_thread_rq == 0) ||
1255 (current_gdb_thread_rq == ct->threadid)) {
1276 switch (packet[0]) {
1288 if (!strncmp(packet,
"qSymbol", 7)) {
1293 }
else if (!strncmp(packet,
"qfThreadInfo", 12)) {
1305 }
else if (!strncmp(packet,
"qsThreadInfo", 12)) {
1307 }
else if (!strncmp(packet,
"qThreadExtraInfo,", 17)) {
1329 if ((ct) && (ct->
threadid == -1)) {
1332 while ((ct) && (ct->
threadid == -1))
1339 LOG_WARNING(
"WARNING! current GDB thread do not match "
1340 "current thread running. "
1341 "Switch thread in GDB to threadid %d",
1344 LOG_INFO(
"threads_needs_update = 1");
1372 ct->TS = 0xdeadbeef;
1390 os_linux->
name =
"linux";
1402 ct->
TS = 0xdeadbeef;
1430 LOG_INFO(
"allocation for %d threads line",
1438 tmp += sprintf(tmp,
"PID\t\tCPU\t\tASID\t\tNAME\n");
1439 tmp += sprintf(tmp,
"---\t\t---\t\t----\t\t----\n");
1446 "%" PRIu32
"\t\t%" PRIu32
"\t\t%" PRIx32
"\t\t%s\n",
1452 "%" PRIu32
"\t\t%" PRIu32
"\t\t%" PRIx32
"\t\t%s\n",
1464 display = calloc(40, 1);
1465 sprintf(display,
"linux_ps_command failed\n");
void * buf_cpy(const void *from, void *_to, unsigned int size)
Copies size bits out of from and into to.
size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t length)
Convert binary data into a string of hexadecimal pairs.
uint64_t buffer
Pointer to data buffer to send over SPI.
uint32_t size
Size of dw_spi_transaction::buffer.
uint32_t address
Starting address. Sector aligned.
int gdb_put_packet(struct connection *connection, const char *buffer, int len)
static struct target * get_target_from_connection(struct connection *connection)
The JTAG interface can be implemented with a software or hardware fifo.
static struct current_thread * add_current_thread(struct current_thread *currents, struct current_thread *ct)
static int fill_task(struct target *target, struct threads *t)
static int clean_threadlist(struct target *target)
static int linux_os_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs)
static int current_base_addr(struct linux_os *linux_os, uint32_t base_addr)
static int linux_thread_extra_info(struct target *target, struct connection *connection, char const *packet, int packet_size)
static void linux_identify_current_threads(struct target *target)
static char * linux_ps_command(struct target *target)
static int linux_os_smp_init(struct target *target)
static uint32_t next_task(struct target *target, struct threads *t)
static int linux_gdb_thread_update(struct target *target, struct connection *connection, char const *packet, int packet_size)
static int linux_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])
static int insert_into_threadlist(struct target *target, struct threads *t)
static int get_current(struct target *target, int create)
static int linux_gdb_h_packet(struct connection *connection, struct target *target, char const *packet, int packet_size)
static struct threads * liste_add_task(struct threads *task_list, struct threads *t, struct threads **last)
static int linux_compute_virt2phys(struct target *target, target_addr_t address)
static int linux_os_clean(struct target *target)
static int fill_buffer(struct target *target, uint32_t addr, uint8_t *buffer)
static const char *const linux_symbol_list[]
static bool linux_os_detect(struct target *target)
#define LINUX_USER_KERNEL_BORDER
static int linux_get_tasks(struct target *target, int context)
static struct cpu_context * cpu_context_read(struct target *target, uint32_t base_addr, uint32_t *info_addr)
static int linux_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
static int get_name(struct target *target, struct threads *t)
const struct rtos_type linux_rtos
static int linux_gdb_thread_packet(struct target *target, struct connection *connection, char const *packet, int packet_size)
static int linux_os_dummy_update(struct rtos *rtos)
static int linux_task_update(struct target *target, int context)
static int linux_os_create(struct target *target)
static int linux_thread_packet(struct connection *connection, char const *packet, int packet_size)
static int linux_gdb_t_packet(struct connection *connection, struct target *target, char const *packet, int packet_size)
static struct threads * liste_del_task(struct threads *task_list, struct threads **t, struct threads *prev)
char * alloc_printf(const char *format,...)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
#define GDB_THREAD_PACKET_NOT_CONSUMED
target_addr_t addr
Start address to search for the control block.
#define foreach_smp_target(pos, head)
struct current_thread * next
struct threads * thread_list
struct current_thread * current_threads
int preupdtate_threadid_count
int(* get)(struct reg *reg)
const struct reg_arch_type * type
int(* create)(struct target *target)
int(* gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size)
struct symbol_table_elem * symbols
void * rtos_specific_params
Table should be terminated by an element with NULL in symbol_name.
int(* virt2phys)(struct target *target, target_addr_t address, target_addr_t *physical)
struct list_head * smp_targets
struct target_type * type
struct cpu_context * context
uint32_t thread_info_addr
int target_read_phys_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
int target_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class)
Obtain the registers for GDB.
int target_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Read count items of size bytes from the memory of target at the address given.
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
#define ERROR_TARGET_FAILURE
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.