OpenOCD
linux.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2011 by STEricsson *
5  * Heythem Bouhaja heythem.bouhaja@stericsson.com : creation *
6  * Michel JAOUEN michel.jaouen@stericsson.com : adaptation to rtos *
7  ***************************************************************************/
8 
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12 
13 #include <helper/time_support.h>
14 #include <jtag/jtag.h>
15 #include "target/target.h"
16 #include "target/target_type.h"
17 #include "helper/log.h"
18 #include "helper/types.h"
19 #include "rtos.h"
21 #include <target/register.h>
22 #include <target/smp.h>
23 #include "server/gdb_server.h"
24 
25 #define LINUX_USER_KERNEL_BORDER 0xc0000000
26 #include "linux_header.h"
27 #define PHYS
28 #define MAX_THREADS 200
29 /* specific task */
30 struct linux_os {
31  const char *name;
32  uint32_t init_task_addr;
36  int nr_cpus;
41  /* virt2phys parameter */
42  uint32_t phys_mask;
43  uint32_t phys_base;
44 };
45 
47  int64_t threadid;
48  int32_t core_id;
49 #ifdef PID_CHECK
50  uint32_t pid;
51 #endif
52  uint32_t TS;
54 };
55 
56 struct threads {
57  char name[17];
58  uint32_t base_addr; /* address to read magic */
59  uint32_t state; /* magic value : filled only at creation */
60  uint32_t pid; /* linux pid : id for identifying a thread */
61  uint32_t oncpu; /* content cpu number in current thread */
62  uint32_t asid; /* filled only at creation */
63  int64_t threadid;
64  int status; /* dead = 1 alive = 2 current = 3 alive and current */
65  /* value that should not change during the live of a thread ? */
66  uint32_t thread_info_addr; /* contain latest thread_info_addr computed */
67  /* retrieve from thread_info */
69  struct threads *next;
70 };
71 
72 struct cpu_context {
73  uint32_t R4;
74  uint32_t R5;
75  uint32_t R6;
76  uint32_t R7;
77  uint32_t R8;
78  uint32_t R9;
79  uint32_t IP;
80  uint32_t FP;
81  uint32_t SP;
82  uint32_t PC;
83  uint32_t preempt_count;
84 };
85 static struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr,
86  uint32_t *info_addr);
87 static int insert_into_threadlist(struct target *target, struct threads *t);
88 
89 static int linux_os_create(struct target *target);
90 
91 static int linux_os_dummy_update(struct rtos *rtos)
92 {
93  /* update is done only when thread request come
94  * too many thread to do it on each stop */
95  return 0;
96 }
97 
98 static int linux_compute_virt2phys(struct target *target, target_addr_t address)
99 {
100  struct linux_os *linux_os = (struct linux_os *)
102  target_addr_t pa = 0;
103  int retval = target->type->virt2phys(target, address, &pa);
104  if (retval != ERROR_OK) {
105  LOG_ERROR("Cannot compute linux virt2phys translation");
106  /* fixes default address */
107  linux_os->phys_base = 0;
108  return ERROR_FAIL;
109  }
110 
111  linux_os->init_task_addr = address;
112  address = address & linux_os->phys_mask;
113  linux_os->phys_base = pa - address;
114  return ERROR_OK;
115 }
116 
117 static int linux_read_memory(struct target *target,
118  uint32_t address, uint32_t size, uint32_t count,
119  uint8_t *buffer)
120 {
121 #ifdef PHYS
122  struct linux_os *linux_os = (struct linux_os *)
124  uint32_t pa = (address & linux_os->phys_mask) + linux_os->phys_base;
125 #endif
126  if (address < 0xc0000000) {
127  LOG_ERROR("linux awareness : address in user space");
128  return ERROR_FAIL;
129  }
130 #ifdef PHYS
132 #endif
134  return ERROR_OK;
135 }
136 
137 static int fill_buffer(struct target *target, uint32_t addr, uint8_t *buffer)
138 {
139 
140  if ((addr & 0xfffffffc) != addr)
141  LOG_INFO("unaligned address %" PRIx32 "!!", addr);
142 
143  int retval = linux_read_memory(target, addr, 4, 1, buffer);
144  return retval;
145 
146 }
147 
148 static uint32_t get_buffer(struct target *target, const uint8_t *buffer)
149 {
150  uint32_t value = 0;
151  const uint8_t *value_ptr = buffer;
152  value = target_buffer_get_u32(target, value_ptr);
153  return value;
154 }
155 
156 static int linux_os_thread_reg_list(struct rtos *rtos,
157  int64_t thread_id, struct rtos_reg **reg_list, int *num_regs)
158 {
159  struct target *target = rtos->target;
160  struct linux_os *linux_os = (struct linux_os *)
162  struct current_thread *tmp = linux_os->current_threads;
163  struct current_thread *next;
164  int found = 0;
165  int retval;
166  /* check if a current thread is requested */
167  next = tmp;
168 
169  do {
170  if (next->threadid == thread_id)
171  found = 1;
172  else
173  next = next->next;
174  } while ((found == 0) && (next != tmp) && (next));
175 
176  if (found == 0) {
177  LOG_ERROR("could not find thread: %" PRIx64, thread_id);
178  return ERROR_FAIL;
179  }
180 
181  /* search target to perform the access */
182  struct reg **gdb_reg_list;
183  struct target_list *head;
184  found = 0;
186  if (head->target->coreid == next->core_id) {
187  target = head->target;
188  found = 1;
189  break;
190  }
191  }
192 
193  if (found == 0) {
194  LOG_ERROR
195  (
196  "current thread %" PRIx64 ": no target to perform access of core id %" PRIx32,
197  thread_id,
198  next->core_id);
199  return ERROR_FAIL;
200  }
201 
202  /*LOG_INFO("thread %lx current on core %x",thread_id, target->coreid);*/
203  retval = target_get_gdb_reg_list(target, &gdb_reg_list, num_regs, REG_CLASS_GENERAL);
204  if (retval != ERROR_OK)
205  return retval;
206 
207  *reg_list = calloc(*num_regs, sizeof(struct rtos_reg));
208 
209  for (int i = 0; i < *num_regs; ++i) {
210  if (!gdb_reg_list[i]->valid)
211  gdb_reg_list[i]->type->get(gdb_reg_list[i]);
212 
213  (*reg_list)[i].number = gdb_reg_list[i]->number;
214  (*reg_list)[i].size = gdb_reg_list[i]->size;
215 
216  buf_cpy(gdb_reg_list[i]->value, (*reg_list)[i].value, (*reg_list)[i].size);
217  }
218 
219  return ERROR_OK;
220 }
221 
222 static bool linux_os_detect(struct target *target)
223 {
224  LOG_INFO("should no be called");
225  return false;
226 }
227 
228 static int linux_os_smp_init(struct target *target);
229 static int linux_os_clean(struct target *target);
230 #define INIT_TASK 0
231 static const char * const linux_symbol_list[] = {
232  "init_task",
233  NULL
234 };
235 
236 static int linux_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])
237 {
238  unsigned int i;
239  *symbol_list = (struct symbol_table_elem *)
240  calloc(ARRAY_SIZE(linux_symbol_list), sizeof(struct symbol_table_elem));
241 
242  for (i = 0; i < ARRAY_SIZE(linux_symbol_list); i++)
243  (*symbol_list)[i].symbol_name = linux_symbol_list[i];
244 
245  return 0;
246 }
247 
248 static char *linux_ps_command(struct target *target);
249 
250 const struct rtos_type linux_rtos = {
251  .name = "linux",
252  .detect_rtos = linux_os_detect,
253  .create = linux_os_create,
254  .smp_init = linux_os_smp_init,
255  .update_threads = linux_os_dummy_update,
256  .get_thread_reg_list = linux_os_thread_reg_list,
257  .get_symbol_list_to_lookup = linux_get_symbol_list_to_lookup,
258  .clean = linux_os_clean,
259  .ps_command = linux_ps_command,
260 };
261 
262 static int linux_thread_packet(struct connection *connection, char const *packet,
263  int packet_size);
264 static void linux_identify_current_threads(struct target *target);
265 
266 #ifdef PID_CHECK
267 int fill_task_pid(struct target *target, struct threads *t)
268 {
269  uint32_t pid_addr = t->base_addr + PID;
270  uint8_t buffer[4];
271  int retval = fill_buffer(target, pid_addr, buffer);
272 
273  if (retval == ERROR_OK) {
274  uint32_t val = get_buffer(target, buffer);
275  t->pid = val;
276  } else
277  LOG_ERROR("fill_task_pid: unable to read memory");
278 
279  return retval;
280 }
281 #endif
282 
283 static int fill_task(struct target *target, struct threads *t)
284 {
285  int retval;
286  uint32_t pid_addr = t->base_addr + PID;
287  uint32_t mem_addr = t->base_addr + MEM;
288  uint32_t on_cpu = t->base_addr + ONCPU;
289  uint8_t *buffer = calloc(1, 4);
290  retval = fill_buffer(target, t->base_addr, buffer);
291 
292  if (retval == ERROR_OK) {
293  uint32_t val = get_buffer(target, buffer);
294  t->state = val;
295  } else
296  LOG_ERROR("fill_task: unable to read memory");
297 
298  retval = fill_buffer(target, pid_addr, buffer);
299 
300  if (retval == ERROR_OK) {
301  uint32_t val = get_buffer(target, buffer);
302  t->pid = val;
303  } else
304  LOG_ERROR("fill task: unable to read memory");
305 
306  retval = fill_buffer(target, on_cpu, buffer);
307 
308  if (retval == ERROR_OK) {
309  uint32_t val = get_buffer(target, buffer);
310  t->oncpu = val;
311  } else
312  LOG_ERROR("fill task: unable to read memory");
313 
314  retval = fill_buffer(target, mem_addr, buffer);
315 
316  if (retval == ERROR_OK) {
317  uint32_t val = get_buffer(target, buffer);
318 
319  if (val != 0) {
320  uint32_t asid_addr = val + MM_CTX;
321  retval = fill_buffer(target, asid_addr, buffer);
322 
323  if (retval == ERROR_OK) {
324  val = get_buffer(target, buffer);
325  t->asid = val;
326  } else
327  LOG_ERROR
328  ("fill task: unable to read memory -- ASID");
329  } else
330  t->asid = 0;
331  } else
332  LOG_ERROR("fill task: unable to read memory");
333 
334  free(buffer);
335 
336  return retval;
337 }
338 
339 static int get_name(struct target *target, struct threads *t)
340 {
341  int retval;
342  uint32_t full_name[4];
343  uint32_t comm = t->base_addr + COMM;
344  int i;
345 
346  for (i = 0; i < 17; i++)
347  t->name[i] = 0;
348 
349  retval = linux_read_memory(target, comm, 4, 4, (uint8_t *) full_name);
350 
351  if (retval != ERROR_OK) {
352  LOG_ERROR("get_name: unable to read memory\n");
353  return ERROR_FAIL;
354  }
355 
356  uint32_t raw_name = target_buffer_get_u32(target,
357  (const uint8_t *)
358  &full_name[0]);
359  t->name[3] = raw_name >> 24;
360  t->name[2] = raw_name >> 16;
361  t->name[1] = raw_name >> 8;
362  t->name[0] = raw_name;
363  raw_name =
364  target_buffer_get_u32(target, (const uint8_t *)&full_name[1]);
365  t->name[7] = raw_name >> 24;
366  t->name[6] = raw_name >> 16;
367  t->name[5] = raw_name >> 8;
368  t->name[4] = raw_name;
369  raw_name =
370  target_buffer_get_u32(target, (const uint8_t *)&full_name[2]);
371  t->name[11] = raw_name >> 24;
372  t->name[10] = raw_name >> 16;
373  t->name[9] = raw_name >> 8;
374  t->name[8] = raw_name;
375  raw_name =
376  target_buffer_get_u32(target, (const uint8_t *)&full_name[3]);
377  t->name[15] = raw_name >> 24;
378  t->name[14] = raw_name >> 16;
379  t->name[13] = raw_name >> 8;
380  t->name[12] = raw_name;
381  return ERROR_OK;
382 
383 }
384 
385 static int get_current(struct target *target, int create)
386 {
387  struct target_list *head;
388  uint8_t *buf;
389  uint32_t val;
390  uint32_t ti_addr;
391  uint8_t *buffer = calloc(1, 4);
392  struct linux_os *linux_os = (struct linux_os *)
394  struct current_thread *ctt = linux_os->current_threads;
395 
396  /* invalid current threads content */
397  while (ctt) {
398  ctt->threadid = -1;
399  ctt->TS = 0xdeadbeef;
400  ctt = ctt->next;
401  }
402 
404  struct reg **reg_list;
405  int reg_list_size;
406  int retval;
407 
408  if (target_get_gdb_reg_list(head->target, &reg_list,
409  &reg_list_size, REG_CLASS_GENERAL) != ERROR_OK) {
410  free(buffer);
411  return ERROR_TARGET_FAILURE;
412  }
413 
414  if (!reg_list[13]->valid)
415  reg_list[13]->type->get(reg_list[13]);
416 
417  buf = reg_list[13]->value;
418  val = get_buffer(target, buf);
419  ti_addr = (val & 0xffffe000);
420  uint32_t ts_addr = ti_addr + 0xc;
421  retval = fill_buffer(target, ts_addr, buffer);
422 
423  if (retval == ERROR_OK) {
424  uint32_t TS = get_buffer(target, buffer);
425  uint32_t cpu, on_cpu = TS + ONCPU;
426  retval = fill_buffer(target, on_cpu, buffer);
427 
428  if (retval == ERROR_OK) {
429  /*uint32_t cpu = get_buffer(target, buffer);*/
430  struct current_thread *ct =
432  cpu = head->target->coreid;
433 
434  while ((ct) && (ct->core_id != (int32_t) cpu))
435  ct = ct->next;
436 
437  if ((ct) && (ct->TS == 0xdeadbeef))
438  ct->TS = TS;
439  else
440  LOG_ERROR
441  ("error in linux current thread update");
442 
443  if (create && ct) {
444  struct threads *t;
445  t = calloc(1, sizeof(struct threads));
446  t->base_addr = ct->TS;
447  fill_task(target, t);
448  get_name(target, t);
449  t->oncpu = cpu;
451  t->status = 3;
452  t->thread_info_addr = 0xdeadbeef;
453  ct->threadid = t->threadid;
455 #ifdef PID_CHECK
456  ct->pid = t->pid;
457 #endif
458  /*LOG_INFO("Creation of current thread %s",t->name);*/
459  }
460  }
461  }
462 
463  free(reg_list);
464  }
465 
466  free(buffer);
467 
468  return ERROR_OK;
469 }
470 
471 static struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr,
472  uint32_t *thread_info_addr_old)
473 {
474  struct cpu_context *context = calloc(1, sizeof(struct cpu_context));
475  uint32_t preempt_count_addr = 0;
476  uint32_t registers[10];
477  uint8_t *buffer = calloc(1, 4);
478  uint32_t stack = base_addr + QAT;
479  uint32_t thread_info_addr = 0;
480  uint32_t thread_info_addr_update = 0;
481  int retval = ERROR_FAIL;
482  context->R4 = 0xdeadbeef;
483  context->R5 = 0xdeadbeef;
484  context->R6 = 0xdeadbeef;
485  context->R7 = 0xdeadbeef;
486  context->R8 = 0xdeadbeef;
487  context->R9 = 0xdeadbeef;
488  context->IP = 0xdeadbeef;
489  context->FP = 0xdeadbeef;
490  context->SP = 0xdeadbeef;
491  context->PC = 0xdeadbeef;
492 retry:
493 
494  if (*thread_info_addr_old == 0xdeadbeef) {
495  retval = fill_buffer(target, stack, buffer);
496 
497  if (retval == ERROR_OK)
498  thread_info_addr = get_buffer(target, buffer);
499  else
500  LOG_ERROR("cpu_context: unable to read memory");
501 
502  thread_info_addr_update = thread_info_addr;
503  } else
504  thread_info_addr = *thread_info_addr_old;
505 
506  preempt_count_addr = thread_info_addr + PREEMPT;
507  retval = fill_buffer(target, preempt_count_addr, buffer);
508 
509  if (retval == ERROR_OK)
510  context->preempt_count = get_buffer(target, buffer);
511  else {
512  if (*thread_info_addr_old != 0xdeadbeef) {
513  LOG_ERROR
514  ("cpu_context: cannot read at thread_info_addr");
515 
516  if (*thread_info_addr_old < LINUX_USER_KERNEL_BORDER)
517  LOG_INFO
518  ("cpu_context : thread_info_addr in userspace!!!");
519 
520  *thread_info_addr_old = 0xdeadbeef;
521  goto retry;
522  }
523 
524  LOG_ERROR("cpu_context: unable to read memory");
525  }
526 
527  thread_info_addr += CPU_CONT;
528 
529  retval = linux_read_memory(target, thread_info_addr, 4, 10,
530  (uint8_t *) registers);
531 
532  if (retval != ERROR_OK) {
533  free(buffer);
534  LOG_ERROR("cpu_context: unable to read memory\n");
535  return context;
536  }
537 
538  context->R4 =
539  target_buffer_get_u32(target, (const uint8_t *)&registers[0]);
540  context->R5 =
541  target_buffer_get_u32(target, (const uint8_t *)&registers[1]);
542  context->R6 =
543  target_buffer_get_u32(target, (const uint8_t *)&registers[2]);
544  context->R7 =
545  target_buffer_get_u32(target, (const uint8_t *)&registers[3]);
546  context->R8 =
547  target_buffer_get_u32(target, (const uint8_t *)&registers[4]);
548  context->R9 =
549  target_buffer_get_u32(target, (const uint8_t *)&registers[5]);
550  context->IP =
551  target_buffer_get_u32(target, (const uint8_t *)&registers[6]);
552  context->FP =
553  target_buffer_get_u32(target, (const uint8_t *)&registers[7]);
554  context->SP =
555  target_buffer_get_u32(target, (const uint8_t *)&registers[8]);
556  context->PC =
557  target_buffer_get_u32(target, (const uint8_t *)&registers[9]);
558 
559  if (*thread_info_addr_old == 0xdeadbeef)
560  *thread_info_addr_old = thread_info_addr_update;
561 
562  free(buffer);
563 
564  return context;
565 }
566 
567 static uint32_t next_task(struct target *target, struct threads *t)
568 {
569  uint8_t *buffer = calloc(1, 4);
570  uint32_t next_addr = t->base_addr + NEXT;
571  int retval = fill_buffer(target, next_addr, buffer);
572 
573  if (retval == ERROR_OK) {
574  uint32_t val = get_buffer(target, buffer);
575  val = val - NEXT;
576  free(buffer);
577  return val;
578  } else
579  LOG_ERROR("next task: unable to read memory");
580 
581  free(buffer);
582 
583  return 0;
584 }
585 
586 static struct current_thread *add_current_thread(struct current_thread *currents,
587  struct current_thread *ct)
588 {
589  ct->next = NULL;
590 
591  if (!currents) {
592  currents = ct;
593  return currents;
594  } else {
595  struct current_thread *temp = currents;
596 
597  while (temp->next)
598  temp = temp->next;
599 
600  temp->next = ct;
601  return currents;
602  }
603 }
604 
605 static struct threads *liste_del_task(struct threads *task_list, struct threads **t,
606  struct threads *prev)
607 {
608  LOG_INFO("del task %" PRId64, (*t)->threadid);
609  if (prev)
610  prev->next = (*t)->next;
611  else
612  task_list = (*t)->next;
613 
614  /* free content of threads */
615  free((*t)->context);
616 
617  free(*t);
618  *t = prev ? prev : task_list;
619  return task_list;
620 }
621 
622 static struct threads *liste_add_task(struct threads *task_list, struct threads *t,
623  struct threads **last)
624 {
625  t->next = NULL;
626 
627  if (!*last)
628  if (!task_list) {
629  task_list = t;
630  return task_list;
631  } else {
632  struct threads *temp = task_list;
633 
634  while (temp->next)
635  temp = temp->next;
636 
637  temp->next = t;
638  *last = t;
639  return task_list;
640  } else {
641  (*last)->next = t;
642  *last = t;
643  return task_list;
644  }
645 }
646 
647 #ifdef PID_CHECK
648 static int current_pid(struct linux_os *linux_os, uint32_t pid)
649 #else
650 static int current_base_addr(struct linux_os *linux_os, uint32_t base_addr)
651 #endif
652 {
654 #ifdef PID_CHECK
655 
656  while ((ct) && (ct->pid != pid))
657 #else
658  while ((ct) && (ct->TS != base_addr))
659 #endif
660  ct = ct->next;
661 #ifdef PID_CHECK
662  if ((ct) && (ct->pid == pid))
663 #else
664  if ((ct) && (ct->TS == base_addr))
665 #endif
666  return 1;
667 
668  return 0;
669 }
670 
671 static int linux_get_tasks(struct target *target, int context)
672 {
673  int loop = 0;
674  int retval = 0;
675  struct linux_os *linux_os = (struct linux_os *)
678  linux_os->thread_count = 0;
679 
680  if (linux_os->init_task_addr == 0xdeadbeef) {
681  LOG_INFO("no init symbol\n");
682  return ERROR_FAIL;
683  }
684 
685  int64_t start = timeval_ms();
686 
687  struct threads *t = calloc(1, sizeof(struct threads));
688  struct threads *last = NULL;
690  /* retrieve the thread id , currently running in the different smp core */
691  get_current(target, 1);
692 
693  while (((t->base_addr != linux_os->init_task_addr) &&
694  (t->base_addr != 0)) || (loop == 0)) {
695  loop++;
696  fill_task(target, t);
697  retval = get_name(target, t);
698 
699  if (loop > MAX_THREADS) {
700  free(t);
701  LOG_INFO("more than %d threads !!", MAX_THREADS);
702  return ERROR_FAIL;
703  }
704 
705  if (retval != ERROR_OK) {
706  free(t);
707  return ERROR_FAIL;
708  }
709 
710  /* check that this thread is not one the current threads already
711  * created */
712  uint32_t base_addr;
713 #ifdef PID_CHECK
714 
715  if (!current_pid(linux_os, t->pid)) {
716 #else
718 #endif
720  t->status = 1;
722 
724  liste_add_task(linux_os->thread_list, t, &last);
725  /* no interest to fill the context if it is a current thread. */
727  t->thread_info_addr = 0xdeadbeef;
728 
729  if (context)
730  t->context =
732  &t->thread_info_addr);
733  base_addr = next_task(target, t);
734  } else {
735  /*LOG_INFO("thread %s is a current thread already created",t->name); */
736  base_addr = next_task(target, t);
737  free(t);
738  }
739 
740  t = calloc(1, sizeof(struct threads));
741  t->base_addr = base_addr;
742  }
743 
747  /* check that all current threads have been identified */
748 
749  LOG_INFO("complete time %" PRId64 ", thread mean %" PRId64 "\n",
750  (timeval_ms() - start),
752 
753  LOG_INFO("threadid count %d", linux_os->threadid_count);
754  free(t);
755 
756  return ERROR_OK;
757 }
758 
759 static int clean_threadlist(struct target *target)
760 {
761  struct linux_os *linux_os = (struct linux_os *)
763  struct threads *old, *temp = linux_os->thread_list;
764 
765  while (temp) {
766  old = temp;
767 
768  free(temp->context);
769 
770  temp = temp->next;
771  free(old);
772  }
773 
774  return ERROR_OK;
775 }
776 
777 static int linux_os_clean(struct target *target)
778 {
779  struct linux_os *os_linux = (struct linux_os *)
782  os_linux->init_task_addr = 0xdeadbeef;
783  os_linux->name = "linux";
784  os_linux->thread_list = NULL;
785  os_linux->thread_count = 0;
786  os_linux->nr_cpus = 0;
787  os_linux->threads_lookup = 0;
788  os_linux->threads_needs_update = 0;
789  os_linux->threadid_count = 1;
790  return ERROR_OK;
791 }
792 
793 static int insert_into_threadlist(struct target *target, struct threads *t)
794 {
795  struct linux_os *linux_os = (struct linux_os *)
797  struct threads *temp = linux_os->thread_list;
800  t->status = 1;
801  t->next = NULL;
802 
803  if (!temp)
804  linux_os->thread_list = t;
805  else {
806  while (temp->next)
807  temp = temp->next;
808 
809  t->next = NULL;
810  temp->next = t;
811  }
812 
813  return ERROR_OK;
814 }
815 
817 {
818  struct linux_os *linux_os = (struct linux_os *)
822  struct threads *t = NULL;
823 
824  while ((ct)) {
825  if (ct->threadid == -1) {
826 
827  /* un-identified thread */
828  int found = 0;
829  t = calloc(1, sizeof(struct threads));
830  t->base_addr = ct->TS;
831 #ifdef PID_CHECK
832 
833  if (fill_task_pid(target, t) != ERROR_OK) {
834 error_handling:
835  free(t);
836  LOG_ERROR
837  ("linux identify_current_threads: unable to read pid");
838  return;
839  }
840 #endif
841 
842  /* search in the list of threads if pid
843  already present */
844  while ((thread_list) && (found == 0)) {
845 #ifdef PID_CHECK
846  if (thread_list->pid == t->pid) {
847 #else
848  if (thread_list->base_addr == t->base_addr) {
849 #endif
850  free(t);
851  t = thread_list;
852  found = 1;
853  }
855  }
856 
857  if (!found) {
858  /* it is a new thread */
859  if (fill_task(target, t) != ERROR_OK)
860  goto error_handling;
861 
862  get_name(target, t);
864  t->thread_info_addr = 0xdeadbeef;
865  }
866 
867  t->status = 3;
868  ct->threadid = t->threadid;
869 #ifdef PID_CHECK
870  ct->pid = t->pid;
871 #endif
873 #if 0
874  if (found == 0)
875  LOG_INFO("current thread core %x identified %s",
876  ct->core_id, t->name);
877  else
878  LOG_INFO("current thread core %x, reused %s",
879  ct->core_id, t->name);
880 #endif
881  }
882 #if 0
883  else {
884  struct threads tmp;
885  tmp.base_addr = ct->TS;
886  get_name(target, &tmp);
887  LOG_INFO("current thread core %x , already identified %s !!!",
888  ct->core_id, tmp.name);
889  }
890 #endif
891  ct = ct->next;
892  }
893 
894  return;
895 #ifndef PID_CHECK
896 error_handling:
897  free(t);
898  LOG_ERROR("unable to read pid");
899  return;
900 
901 #endif
902 }
903 
904 static int linux_task_update(struct target *target, int context)
905 {
906  struct linux_os *linux_os = (struct linux_os *)
909  int retval;
910  int loop = 0;
911  linux_os->thread_count = 0;
912 
913  /*thread_list = thread_list->next; skip init_task*/
914  while (thread_list) {
915  thread_list->status = 0; /*setting all tasks to dead state*/
916 
917  free(thread_list->context);
919 
921  }
922 
923  int found = 0;
924 
925  if (linux_os->init_task_addr == 0xdeadbeef) {
926  LOG_INFO("no init symbol\n");
927  return ERROR_FAIL;
928  }
929  int64_t start = timeval_ms();
930  struct threads *t = calloc(1, sizeof(struct threads));
931  uint32_t previous = 0xdeadbeef;
933  retval = get_current(target, 0);
934  /*check that all current threads have been identified */
936 
937  while (((t->base_addr != linux_os->init_task_addr) &&
938  (t->base_addr != previous)) || (loop == 0)) {
939  /* for avoiding any permanent loop for any reason possibly due to
940  * target */
941  loop++;
942  previous = t->base_addr;
943  /* read only pid */
944 #ifdef PID_CHECK
945  retval = fill_task_pid(target, t);
946 #endif
947 
948  if (retval != ERROR_OK) {
949  free(t);
950  return ERROR_FAIL;
951  }
952 
953  thread_list = linux_os->thread_list;
954 
955  while (thread_list) {
956 #ifdef PID_CHECK
957  if (t->pid == thread_list->pid) {
958 #else
959  if (t->base_addr == thread_list->base_addr) {
960 #endif
961  if (!thread_list->status) {
962 #ifdef PID_CHECK
963  if (t->base_addr != thread_list->base_addr)
964  LOG_INFO("thread base_addr has changed !!");
965 #endif
966  /* this is not a current thread */
967  thread_list->base_addr = t->base_addr;
968  thread_list->status = 1;
969 
970  /* we don 't update this field any more */
971 
972  /*thread_list->state = t->state;
973  thread_list->oncpu = t->oncpu;
974  thread_list->asid = t->asid;
975  */
976  if (context)
977  thread_list->context =
979  thread_list->base_addr,
980  &thread_list->thread_info_addr);
981  } else {
982  /* it is a current thread no need to read context */
983  }
984 
986  found = 1;
987  break;
988  } else {
989  found = 0;
990  thread_list = thread_list->next;
991  }
992  }
993 
994  if (found == 0) {
995  uint32_t base_addr;
996  fill_task(target, t);
997  get_name(target, t);
998  retval = insert_into_threadlist(target, t);
999  t->thread_info_addr = 0xdeadbeef;
1000 
1001  if (context)
1002  t->context =
1004  &t->thread_info_addr);
1005 
1006  base_addr = next_task(target, t);
1007  t = calloc(1, sizeof(struct threads));
1008  t->base_addr = base_addr;
1010  } else
1011  t->base_addr = next_task(target, t);
1012  }
1013 
1014  LOG_INFO("update thread done %" PRId64 ", mean%" PRId64 "\n",
1015  (timeval_ms() - start), (timeval_ms() - start) / loop);
1016  free(t);
1018  return ERROR_OK;
1019 }
1020 
1022  struct connection *connection, char const *packet,
1023  int packet_size)
1024 {
1025  int retval;
1026  struct linux_os *linux_os =
1028 
1029  if (linux_os->init_task_addr == 0xdeadbeef) {
1030  /* it has not been initialized */
1031  LOG_INFO("received thread request without init task address");
1032  gdb_put_packet(connection, "l", 1);
1033  return ERROR_OK;
1034  }
1035 
1036  retval = linux_get_tasks(target, 1);
1037 
1038  if (retval != ERROR_OK)
1039  return ERROR_TARGET_FAILURE;
1040 
1041  char *out_str = calloc(MAX_THREADS * 17 + 10, 1);
1042  char *tmp_str = out_str;
1043  tmp_str += sprintf(tmp_str, "m");
1044  struct threads *temp = linux_os->thread_list;
1045 
1046  while (temp) {
1047  tmp_str += sprintf(tmp_str, "%016" PRIx64, temp->threadid);
1048  temp = temp->next;
1049  if (temp)
1050  tmp_str += sprintf(tmp_str, ",");
1051  }
1052 
1053  gdb_put_packet(connection, out_str, strlen(out_str));
1054  free(out_str);
1055  return ERROR_OK;
1056 }
1057 
1059  struct connection *connection, char const *packet,
1060  int packet_size)
1061 {
1062  int found = 0;
1063  struct linux_os *linux_os = (struct linux_os *)
1065  struct threads *temp = linux_os->thread_list;
1066 
1067  while (temp) {
1068  if (temp->threadid == linux_os->preupdtate_threadid_count + 1) {
1069  /*LOG_INFO("FOUND");*/
1070  found = 1;
1071  break;
1072  } else
1073  temp = temp->next;
1074  }
1075 
1076  if (found == 1) {
1077  /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/
1078  char *out_strr = calloc(MAX_THREADS * 17 + 10, 1);
1079  char *tmp_strr = out_strr;
1080  tmp_strr += sprintf(tmp_strr, "m");
1081  /*LOG_INFO("CHAR MALLOC & M DONE");*/
1082  tmp_strr += sprintf(tmp_strr, "%016" PRIx64, temp->threadid);
1083 
1084  temp = temp->next;
1085 
1086  while (temp) {
1087  /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/
1088  tmp_strr += sprintf(tmp_strr, ",");
1089  tmp_strr +=
1090  sprintf(tmp_strr, "%016" PRIx64, temp->threadid);
1091  temp = temp->next;
1092  }
1093 
1094  /*tmp_str[0] = 0;*/
1095  gdb_put_packet(connection, out_strr, strlen(out_strr));
1097  linux_os->threadid_count - 1;
1098  free(out_strr);
1099  } else
1100  gdb_put_packet(connection, "l", 1);
1101 
1102  return ERROR_OK;
1103 }
1104 
1106  struct connection *connection, char const *packet,
1107  int packet_size)
1108 {
1109  int64_t threadid = 0;
1110  struct linux_os *linux_os = (struct linux_os *)
1112  sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid);
1113  /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/
1114  struct threads *temp = linux_os->thread_list;
1115 
1116  while (temp) {
1117  if (temp->threadid == threadid) {
1118  char *pid = " PID: ";
1119  char *pid_current = "*PID: ";
1120  char *name = "Name: ";
1121  int str_size = strlen(pid) + strlen(name);
1122  char *tmp_str = calloc(1, str_size + 50);
1123  char *tmp_str_ptr = tmp_str;
1124 
1125  /* discriminate current task */
1126  if (temp->status == 3)
1127  tmp_str_ptr += sprintf(tmp_str_ptr, "%s",
1128  pid_current);
1129  else
1130  tmp_str_ptr += sprintf(tmp_str_ptr, "%s", pid);
1131 
1132  tmp_str_ptr += sprintf(tmp_str_ptr, "%d, ", (int)temp->pid);
1133  sprintf(tmp_str_ptr, "%s", name);
1134  sprintf(tmp_str_ptr, "%s", temp->name);
1135  char *hex_str = calloc(1, strlen(tmp_str) * 2 + 1);
1136  size_t pkt_len = hexify(hex_str, (const uint8_t *)tmp_str,
1137  strlen(tmp_str), strlen(tmp_str) * 2 + 1);
1138  gdb_put_packet(connection, hex_str, pkt_len);
1139  free(hex_str);
1140  free(tmp_str);
1141  return ERROR_OK;
1142  }
1143 
1144  temp = temp->next;
1145  }
1146 
1147  LOG_INFO("thread not found");
1148  return ERROR_OK;
1149 }
1150 
1152  struct target *target, char const *packet, int packet_size)
1153 {
1154  int64_t threadid;
1155  struct linux_os *linux_os = (struct linux_os *)
1157  int retval = ERROR_OK;
1158  sscanf(packet, "T%" SCNx64, &threadid);
1159 
1160  if (linux_os->threads_needs_update == 0) {
1161  struct threads *temp = linux_os->thread_list;
1162  struct threads *prev = NULL;
1163 
1164  while (temp) {
1165  if (temp->threadid == threadid) {
1166  if (temp->status != 0) {
1167  gdb_put_packet(connection, "OK", 2);
1168  return ERROR_OK;
1169  } else {
1170  /* delete item in the list */
1173  &temp, prev);
1175  gdb_put_packet(connection, "E01", 3);
1176  return ERROR_OK;
1177  }
1178  }
1179 
1180  /* for deletion */
1181  prev = temp;
1182  temp = temp->next;
1183  }
1184 
1185  LOG_INFO("gdb requested status on non existing thread");
1186  gdb_put_packet(connection, "E01", 3);
1187  return ERROR_OK;
1188 
1189  } else {
1190  retval = linux_task_update(target, 1);
1191  struct threads *temp = linux_os->thread_list;
1192 
1193  while (temp) {
1194  if (temp->threadid == threadid) {
1195  if (temp->status == 1) {
1196  gdb_put_packet(connection, "OK", 2);
1197  return ERROR_OK;
1198  } else {
1199  gdb_put_packet(connection, "E01", 3);
1200  return ERROR_OK;
1201  }
1202  }
1203 
1204  temp = temp->next;
1205  }
1206  }
1207 
1208  return retval;
1209 }
1210 
1212  struct target *target, char const *packet, int packet_size)
1213 {
1214  struct linux_os *linux_os = (struct linux_os *)
1216  struct current_thread *ct = linux_os->current_threads;
1217 
1218  /* select to display the current thread of the selected target */
1219  while ((ct) && (ct->core_id != target->coreid))
1220  ct = ct->next;
1221 
1222  int64_t current_gdb_thread_rq;
1223 
1224  if (linux_os->threads_lookup == 1) {
1225  if ((ct) && (ct->threadid == -1)) {
1226  ct = linux_os->current_threads;
1227 
1228  while ((ct) && (ct->threadid == -1))
1229  ct = ct->next;
1230  }
1231 
1232  if (!ct) {
1233  /* no current thread can be identified
1234  * any way with smp */
1235  LOG_INFO("no current thread identified");
1236  /* attempt to display the name of the 2 threads identified with
1237  * get_current */
1238  struct threads t;
1239  ct = linux_os->current_threads;
1240 
1241  while ((ct) && (ct->threadid == -1)) {
1242  t.base_addr = ct->TS;
1243  get_name(target, &t);
1244  LOG_INFO("name of unidentified thread %s",
1245  t.name);
1246  ct = ct->next;
1247  }
1248 
1249  gdb_put_packet(connection, "OK", 2);
1250  return ERROR_OK;
1251  }
1252 
1253  if (packet[1] == 'g') {
1254  sscanf(packet, "Hg%16" SCNx64, &current_gdb_thread_rq);
1255 
1256  if (current_gdb_thread_rq == 0) {
1257  target->rtos->current_threadid = ct->threadid;
1258  gdb_put_packet(connection, "OK", 2);
1259  } else {
1261  current_gdb_thread_rq;
1262  gdb_put_packet(connection, "OK", 2);
1263  }
1264  } else if (packet[1] == 'c') {
1265  sscanf(packet, "Hc%16" SCNx64, &current_gdb_thread_rq);
1266 
1267  if ((current_gdb_thread_rq == 0) ||
1268  (current_gdb_thread_rq == ct->threadid)) {
1269  target->rtos->current_threadid = ct->threadid;
1270  gdb_put_packet(connection, "OK", 2);
1271  } else
1272  gdb_put_packet(connection, "E01", 3);
1273  }
1274  } else
1275  gdb_put_packet(connection, "OK", 2);
1276 
1277  return ERROR_OK;
1278 }
1279 
1280 static int linux_thread_packet(struct connection *connection, char const *packet,
1281  int packet_size)
1282 {
1283  int retval = ERROR_OK;
1284  struct current_thread *ct;
1286  struct linux_os *linux_os = (struct linux_os *)
1288 
1289  switch (packet[0]) {
1290  case 'T': /* Is thread alive?*/
1291 
1292  linux_gdb_t_packet(connection, target, packet, packet_size);
1293  break;
1294  case 'H': /* Set current thread */
1295  /* ( 'c' for step and continue, 'g' for all other operations )*/
1296  /*LOG_INFO(" H packet received '%s'", packet);*/
1297  linux_gdb_h_packet(connection, target, packet, packet_size);
1298  break;
1299  case 'q':
1300 
1301  if (strncmp(packet, "qSymbol", 7) == 0) {
1302  if (rtos_qsymbol(connection, packet, packet_size) == 1) {
1305  }
1306 
1307  break;
1308  } else if (strncmp(packet, "qfThreadInfo", 12) == 0) {
1309  if (!linux_os->thread_list) {
1311  connection,
1312  packet,
1313  packet_size);
1314  break;
1315  } else {
1317  connection,
1318  packet,
1319  packet_size);
1320  break;
1321  }
1322  } else if (strncmp(packet, "qsThreadInfo", 12) == 0) {
1323  gdb_put_packet(connection, "l", 1);
1324  break;
1325  } else if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) {
1327  packet_size);
1328  break;
1329  } else {
1331  break;
1332  }
1333 
1334  case 'Q':
1335  /* previously response was : thread not found
1336  * gdb_put_packet(connection, "E01", 3); */
1338  break;
1339  case 'c':
1340  case 's': {
1341  if (linux_os->threads_lookup == 1) {
1342  ct = linux_os->current_threads;
1343 
1344  while ((ct) && (ct->core_id) != target->coreid)
1345  ct = ct->next;
1346 
1347  if ((ct) && (ct->threadid == -1)) {
1348  ct = linux_os->current_threads;
1349 
1350  while ((ct) && (ct->threadid == -1))
1351  ct = ct->next;
1352  }
1353 
1354  if ((ct) && (ct->threadid !=
1356  && (target->rtos->current_threadid != -1))
1357  LOG_WARNING("WARNING! current GDB thread do not match "
1358  "current thread running. "
1359  "Switch thread in GDB to threadid %d",
1360  (int)ct->threadid);
1361 
1362  LOG_INFO("threads_needs_update = 1");
1364  }
1365  }
1366 
1367  /* if a packet handler returned an error, exit input loop */
1368  if (retval != ERROR_OK)
1369  return retval;
1370  }
1371 
1372  return retval;
1373 }
1374 
1375 static int linux_os_smp_init(struct target *target)
1376 {
1377  struct target_list *head;
1378  /* keep only target->rtos */
1379  struct rtos *rtos = target->rtos;
1380  struct linux_os *os_linux =
1381  (struct linux_os *)rtos->rtos_specific_params;
1382  struct current_thread *ct;
1383 
1385  if (head->target->rtos != rtos) {
1386  struct linux_os *smp_os_linux =
1387  (struct linux_os *)head->target->rtos->rtos_specific_params;
1388  /* remap smp target on rtos */
1389  free(head->target->rtos);
1390  head->target->rtos = rtos;
1391  /* reuse allocated ct */
1392  ct = smp_os_linux->current_threads;
1393  ct->threadid = -1;
1394  ct->TS = 0xdeadbeef;
1395  ct->core_id = head->target->coreid;
1396  os_linux->current_threads =
1397  add_current_thread(os_linux->current_threads, ct);
1398  os_linux->nr_cpus++;
1399  free(smp_os_linux);
1400  }
1401  }
1402 
1403  return ERROR_OK;
1404 }
1405 
1406 static int linux_os_create(struct target *target)
1407 {
1408  struct linux_os *os_linux = calloc(1, sizeof(struct linux_os));
1409  struct current_thread *ct = calloc(1, sizeof(struct current_thread));
1410  LOG_INFO("linux os creation\n");
1411  os_linux->init_task_addr = 0xdeadbeef;
1412  os_linux->name = "linux";
1413  os_linux->thread_list = NULL;
1414  os_linux->thread_count = 0;
1415  target->rtos->current_threadid = -1;
1416  os_linux->nr_cpus = 1;
1417  os_linux->threads_lookup = 0;
1418  os_linux->threads_needs_update = 0;
1419  os_linux->threadid_count = 1;
1420  os_linux->current_threads = NULL;
1421  target->rtos->rtos_specific_params = os_linux;
1422  ct->core_id = target->coreid;
1423  ct->threadid = -1;
1424  ct->TS = 0xdeadbeef;
1425  os_linux->current_threads =
1426  add_current_thread(os_linux->current_threads, ct);
1427  /* overload rtos thread default handler */
1429  /* initialize a default virt 2 phys translation */
1430  os_linux->phys_mask = ~0xc0000000;
1431  os_linux->phys_base = 0x0;
1432  return JIM_OK;
1433 }
1434 
1435 static char *linux_ps_command(struct target *target)
1436 {
1437  struct linux_os *linux_os = (struct linux_os *)
1439  int retval = ERROR_OK;
1440  char *display;
1441 
1442  if (linux_os->threads_lookup == 0)
1443  retval = linux_get_tasks(target, 1);
1444  else {
1445  if (linux_os->threads_needs_update != 0)
1446  retval = linux_task_update(target, 0);
1447  }
1448 
1449  if (retval == ERROR_OK) {
1450  struct threads *temp = linux_os->thread_list;
1451  char *tmp;
1452  LOG_INFO("allocation for %d threads line",
1454  display = calloc((linux_os->thread_count + 2) * 80, 1);
1455 
1456  if (!display)
1457  goto error;
1458 
1459  tmp = display;
1460  tmp += sprintf(tmp, "PID\t\tCPU\t\tASID\t\tNAME\n");
1461  tmp += sprintf(tmp, "---\t\t---\t\t----\t\t----\n");
1462 
1463  while (temp) {
1464  if (temp->status) {
1465  if (temp->context)
1466  tmp +=
1467  sprintf(tmp,
1468  "%" PRIu32 "\t\t%" PRIu32 "\t\t%" PRIx32 "\t\t%s\n",
1469  temp->pid, temp->oncpu,
1470  temp->asid, temp->name);
1471  else
1472  tmp +=
1473  sprintf(tmp,
1474  "%" PRIu32 "\t\t%" PRIu32 "\t\t%" PRIx32 "\t\t%s\n",
1475  temp->pid, temp->oncpu,
1476  temp->asid, temp->name);
1477  }
1478 
1479  temp = temp->next;
1480  }
1481 
1482  return display;
1483  }
1484 
1485 error:
1486  display = calloc(40, 1);
1487  sprintf(display, "linux_ps_command failed\n");
1488  return display;
1489 }
const char * name
Definition: armv4_5.c:76
void * buf_cpy(const void *from, void *_to, unsigned int size)
Copies size bits out of from and into to.
Definition: binarybuffer.c:43
size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t length)
Convert binary data into a string of hexadecimal pairs.
Definition: binarybuffer.c:380
int gdb_put_packet(struct connection *connection, const char *buffer, int len)
Definition: gdb_server.c:525
static struct target * get_target_from_connection(struct connection *connection)
Definition: gdb_server.h:35
The JTAG interface can be implemented with a software or hardware fifo.
#define PID
Definition: kitprog.c:38
static struct current_thread * add_current_thread(struct current_thread *currents, struct current_thread *ct)
Definition: linux.c:586
static int fill_task(struct target *target, struct threads *t)
Definition: linux.c:283
#define INIT_TASK
Definition: linux.c:230
static int clean_threadlist(struct target *target)
Definition: linux.c:759
static int linux_os_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs)
Definition: linux.c:156
static int current_base_addr(struct linux_os *linux_os, uint32_t base_addr)
Definition: linux.c:650
static int linux_thread_extra_info(struct target *target, struct connection *connection, char const *packet, int packet_size)
Definition: linux.c:1105
static void linux_identify_current_threads(struct target *target)
Definition: linux.c:816
static char * linux_ps_command(struct target *target)
Definition: linux.c:1435
static int linux_os_smp_init(struct target *target)
Definition: linux.c:1375
static uint32_t next_task(struct target *target, struct threads *t)
Definition: linux.c:567
static int linux_gdb_thread_update(struct target *target, struct connection *connection, char const *packet, int packet_size)
Definition: linux.c:1058
static int linux_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])
Definition: linux.c:236
static int insert_into_threadlist(struct target *target, struct threads *t)
Definition: linux.c:793
static int get_current(struct target *target, int create)
Definition: linux.c:385
static int linux_gdb_h_packet(struct connection *connection, struct target *target, char const *packet, int packet_size)
Definition: linux.c:1211
static struct threads * liste_add_task(struct threads *task_list, struct threads *t, struct threads **last)
Definition: linux.c:622
static int linux_compute_virt2phys(struct target *target, target_addr_t address)
Definition: linux.c:98
static int linux_os_clean(struct target *target)
Definition: linux.c:777
static int fill_buffer(struct target *target, uint32_t addr, uint8_t *buffer)
Definition: linux.c:137
static const char *const linux_symbol_list[]
Definition: linux.c:231
static bool linux_os_detect(struct target *target)
Definition: linux.c:222
#define LINUX_USER_KERNEL_BORDER
Definition: linux.c:25
static int linux_get_tasks(struct target *target, int context)
Definition: linux.c:671
static struct cpu_context * cpu_context_read(struct target *target, uint32_t base_addr, uint32_t *info_addr)
Definition: linux.c:471
#define MAX_THREADS
Definition: linux.c:28
static int linux_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Definition: linux.c:117
static int get_name(struct target *target, struct threads *t)
Definition: linux.c:339
const struct rtos_type linux_rtos
Definition: linux.c:250
static int linux_gdb_thread_packet(struct target *target, struct connection *connection, char const *packet, int packet_size)
Definition: linux.c:1021
static int linux_os_dummy_update(struct rtos *rtos)
Definition: linux.c:91
static int linux_task_update(struct target *target, int context)
Definition: linux.c:904
static uint32_t get_buffer(struct target *target, const uint8_t *buffer)
Definition: linux.c:148
static int linux_os_create(struct target *target)
Definition: linux.c:1406
static int linux_thread_packet(struct connection *connection, char const *packet, int packet_size)
Definition: linux.c:1280
static int linux_gdb_t_packet(struct connection *connection, struct target *target, char const *packet, int packet_size)
Definition: linux.c:1151
static struct threads * liste_del_task(struct threads *task_list, struct threads **t, struct threads *prev)
Definition: linux.c:605
#define CPU_CONT
Definition: linux_header.h:35
#define MEM
Definition: linux_header.h:32
#define NEXT
Definition: linux_header.h:30
#define COMM
Definition: linux_header.h:31
#define ONCPU
Definition: linux_header.h:33
#define MM_CTX
Definition: linux_header.h:37
#define PREEMPT
Definition: linux_header.h:36
#define QAT
Definition: linux_header.h:29
static int64_t start
Definition: log.c:42
#define LOG_WARNING(expr ...)
Definition: log.h:129
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define ERROR_OK
Definition: log.h:164
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
Definition: rtos.c:211
#define GDB_THREAD_PACKET_NOT_CONSUMED
Definition: rtos.h:114
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
#define foreach_smp_target(pos, head)
Definition: smp.h:15
uint32_t R6
Definition: linux.c:75
uint32_t IP
Definition: linux.c:79
uint32_t preempt_count
Definition: linux.c:83
uint32_t SP
Definition: linux.c:81
uint32_t R8
Definition: linux.c:77
uint32_t R7
Definition: linux.c:76
uint32_t R4
Definition: linux.c:73
uint32_t FP
Definition: linux.c:80
uint32_t R9
Definition: linux.c:78
uint32_t R5
Definition: linux.c:74
uint32_t PC
Definition: linux.c:82
uint32_t TS
Definition: linux.c:52
int32_t core_id
Definition: linux.c:48
struct current_thread * next
Definition: linux.c:53
int64_t threadid
Definition: linux.c:47
Definition: linux.c:30
uint32_t phys_mask
Definition: linux.c:42
struct threads * thread_list
Definition: linux.c:40
uint32_t phys_base
Definition: linux.c:43
int threads_needs_update
Definition: linux.c:38
int nr_cpus
Definition: linux.c:36
int threadid_count
Definition: linux.c:34
struct current_thread * current_threads
Definition: linux.c:39
uint32_t init_task_addr
Definition: linux.c:32
int threads_lookup
Definition: linux.c:37
const char * name
Definition: linux.c:31
int thread_count
Definition: linux.c:33
int preupdtate_threadid_count
Definition: linux.c:35
int(* get)(struct reg *reg)
Definition: register.h:152
Definition: register.h:111
bool valid
Definition: register.h:126
uint32_t size
Definition: register.h:132
uint8_t * value
Definition: register.h:122
uint32_t number
Definition: register.h:115
const struct reg_arch_type * type
Definition: register.h:141
Definition: rtos.h:53
Definition: rtos.h:59
int(* create)(struct target *target)
Definition: rtos.h:62
const char * name
Definition: rtos.h:60
Definition: rtos.h:36
int(* gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size)
Definition: rtos.h:48
struct symbol_table_elem * symbols
Definition: rtos.h:39
struct target * target
Definition: rtos.h:40
void * rtos_specific_params
Definition: rtos.h:50
int64_t current_threadid
Definition: rtos.h:43
Table should be terminated by an element with NULL in symbol_name.
Definition: rtos.h:23
symbol_address_t address
Definition: rtos.h:25
const char * symbol_name
Definition: rtos.h:24
struct target * target
Definition: target.h:214
int(* virt2phys)(struct target *target, target_addr_t address, target_addr_t *physical)
Definition: target_type.h:252
Definition: target.h:116
int32_t coreid
Definition: target.h:120
struct list_head * smp_targets
Definition: target.h:188
struct rtos * rtos
Definition: target.h:183
struct target_type * type
Definition: target.h:117
Definition: linux.c:56
uint32_t oncpu
Definition: linux.c:61
uint32_t pid
Definition: linux.c:60
uint32_t asid
Definition: linux.c:62
uint32_t state
Definition: linux.c:59
int64_t threadid
Definition: linux.c:63
uint32_t base_addr
Definition: linux.c:58
int status
Definition: linux.c:64
char name[17]
Definition: linux.c:57
struct threads * next
Definition: linux.c:69
struct cpu_context * context
Definition: linux.c:68
uint32_t thread_info_addr
Definition: linux.c:66
int target_read_phys_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Definition: target.c:1251
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.
Definition: target.c:1368
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.
Definition: target.c:1237
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
Definition: target.c:316
@ REG_CLASS_GENERAL
Definition: target.h:112
#define ERROR_TARGET_FAILURE
Definition: target.h:791
int64_t timeval_ms(void)
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
uint64_t target_addr_t
Definition: types.h:335
#define NULL
Definition: usb.h:16
uint8_t count[4]
Definition: vdebug.c:22