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 
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 
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 int linux_os_thread_reg_list(struct rtos *rtos,
149  int64_t thread_id, struct rtos_reg **reg_list, int *num_regs)
150 {
151  struct target *target = rtos->target;
152  struct linux_os *linux_os = (struct linux_os *)
154  struct current_thread *tmp = linux_os->current_threads;
155  struct current_thread *next;
156  int found = 0;
157  int retval;
158  /* check if a current thread is requested */
159  next = tmp;
160 
161  do {
162  if (next->threadid == thread_id)
163  found = 1;
164  else
165  next = next->next;
166  } while ((found == 0) && (next != tmp) && (next));
167 
168  if (found == 0) {
169  LOG_ERROR("could not find thread: %" PRIx64, thread_id);
170  return ERROR_FAIL;
171  }
172 
173  /* search target to perform the access */
174  struct reg **gdb_reg_list;
175  struct target_list *head;
176  found = 0;
178  if (head->target->coreid == next->core_id) {
179  target = head->target;
180  found = 1;
181  break;
182  }
183  }
184 
185  if (found == 0) {
186  LOG_ERROR
187  (
188  "current thread %" PRIx64 ": no target to perform access of core id %" PRIx32,
189  thread_id,
190  next->core_id);
191  return ERROR_FAIL;
192  }
193 
194  /*LOG_INFO("thread %lx current on core %x",thread_id, target->coreid);*/
195  retval = target_get_gdb_reg_list(target, &gdb_reg_list, num_regs, REG_CLASS_GENERAL);
196  if (retval != ERROR_OK)
197  return retval;
198 
199  *reg_list = calloc(*num_regs, sizeof(struct rtos_reg));
200 
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]);
204 
205  (*reg_list)[i].number = gdb_reg_list[i]->number;
206  (*reg_list)[i].size = gdb_reg_list[i]->size;
207 
208  buf_cpy(gdb_reg_list[i]->value, (*reg_list)[i].value, (*reg_list)[i].size);
209  }
210 
211  return ERROR_OK;
212 }
213 
214 static bool linux_os_detect(struct target *target)
215 {
216  LOG_INFO("should no be called");
217  return false;
218 }
219 
220 static int linux_os_smp_init(struct target *target);
221 static int linux_os_clean(struct target *target);
222 #define INIT_TASK 0
223 static const char * const linux_symbol_list[] = {
224  "init_task",
225  NULL
226 };
227 
228 static int linux_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])
229 {
230  unsigned int i;
231  *symbol_list = (struct symbol_table_elem *)
232  calloc(ARRAY_SIZE(linux_symbol_list), sizeof(struct symbol_table_elem));
233 
234  for (i = 0; i < ARRAY_SIZE(linux_symbol_list); i++)
235  (*symbol_list)[i].symbol_name = linux_symbol_list[i];
236 
237  return 0;
238 }
239 
240 static char *linux_ps_command(struct target *target);
241 
242 const struct rtos_type linux_rtos = {
243  .name = "linux",
244  .detect_rtos = linux_os_detect,
245  .create = linux_os_create,
246  .smp_init = linux_os_smp_init,
247  .update_threads = linux_os_dummy_update,
248  .get_thread_reg_list = linux_os_thread_reg_list,
249  .get_symbol_list_to_lookup = linux_get_symbol_list_to_lookup,
250  .clean = linux_os_clean,
251  .ps_command = linux_ps_command,
252 };
253 
254 static int linux_thread_packet(struct connection *connection, char const *packet,
255  int packet_size);
256 static void linux_identify_current_threads(struct target *target);
257 
258 #ifdef PID_CHECK
259 int fill_task_pid(struct target *target, struct threads *t)
260 {
261  uint32_t pid_addr = t->base_addr + PID;
262  uint8_t buffer[4];
263  int retval = fill_buffer(target, pid_addr, buffer);
264 
265  if (retval == ERROR_OK) {
266  uint32_t val = target_buffer_get_u32(target, buffer);
267  t->pid = val;
268  } else
269  LOG_ERROR("fill_task_pid: unable to read memory");
270 
271  return retval;
272 }
273 #endif
274 
275 static int fill_task(struct target *target, struct threads *t)
276 {
277  int retval;
278  uint32_t pid_addr = t->base_addr + PID;
279  uint32_t mem_addr = t->base_addr + MEM;
280  uint32_t on_cpu = t->base_addr + ONCPU;
281  uint8_t *buffer = calloc(1, 4);
282  retval = fill_buffer(target, t->base_addr, buffer);
283 
284  if (retval == ERROR_OK) {
285  uint32_t val = target_buffer_get_u32(target, buffer);
286  t->state = val;
287  } else
288  LOG_ERROR("fill_task: unable to read memory");
289 
290  retval = fill_buffer(target, pid_addr, buffer);
291 
292  if (retval == ERROR_OK) {
293  uint32_t val = target_buffer_get_u32(target, buffer);
294  t->pid = val;
295  } else
296  LOG_ERROR("fill task: unable to read memory");
297 
298  retval = fill_buffer(target, on_cpu, buffer);
299 
300  if (retval == ERROR_OK) {
301  uint32_t val = target_buffer_get_u32(target, buffer);
302  t->oncpu = val;
303  } else
304  LOG_ERROR("fill task: unable to read memory");
305 
306  retval = fill_buffer(target, mem_addr, buffer);
307 
308  if (retval == ERROR_OK) {
309  uint32_t val = target_buffer_get_u32(target, buffer);
310 
311  if (val != 0) {
312  uint32_t asid_addr = val + MM_CTX;
313  retval = fill_buffer(target, asid_addr, buffer);
314 
315  if (retval == ERROR_OK) {
317  t->asid = val;
318  } else
319  LOG_ERROR
320  ("fill task: unable to read memory -- ASID");
321  } else
322  t->asid = 0;
323  } else
324  LOG_ERROR("fill task: unable to read memory");
325 
326  free(buffer);
327 
328  return retval;
329 }
330 
331 static int get_name(struct target *target, struct threads *t)
332 {
333  int retval;
334  uint32_t full_name[4];
335  uint32_t comm = t->base_addr + COMM;
336  int i;
337 
338  for (i = 0; i < 17; i++)
339  t->name[i] = 0;
340 
341  retval = linux_read_memory(target, comm, 4, 4, (uint8_t *) full_name);
342 
343  if (retval != ERROR_OK) {
344  LOG_ERROR("get_name: unable to read memory\n");
345  return ERROR_FAIL;
346  }
347 
348  uint32_t raw_name = target_buffer_get_u32(target,
349  (const uint8_t *)
350  &full_name[0]);
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;
355  raw_name =
356  target_buffer_get_u32(target, (const uint8_t *)&full_name[1]);
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;
361  raw_name =
362  target_buffer_get_u32(target, (const uint8_t *)&full_name[2]);
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;
367  raw_name =
368  target_buffer_get_u32(target, (const uint8_t *)&full_name[3]);
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;
373  return ERROR_OK;
374 
375 }
376 
377 static int get_current(struct target *target, int create)
378 {
379  struct target_list *head;
380  uint8_t *buf;
381  uint32_t val;
382  uint32_t ti_addr;
383  uint8_t *buffer = calloc(1, 4);
384  struct linux_os *linux_os = (struct linux_os *)
386  struct current_thread *ctt = linux_os->current_threads;
387 
388  /* invalid current threads content */
389  while (ctt) {
390  ctt->threadid = -1;
391  ctt->TS = 0xdeadbeef;
392  ctt = ctt->next;
393  }
394 
396  struct reg **reg_list;
397  int reg_list_size;
398  int retval;
399 
400  if (target_get_gdb_reg_list(head->target, &reg_list,
401  &reg_list_size, REG_CLASS_GENERAL) != ERROR_OK) {
402  free(buffer);
403  return ERROR_TARGET_FAILURE;
404  }
405 
406  if (!reg_list[13]->valid)
407  reg_list[13]->type->get(reg_list[13]);
408 
409  buf = reg_list[13]->value;
410  val = target_buffer_get_u32(target, buf);
411  ti_addr = (val & 0xffffe000);
412  uint32_t ts_addr = ti_addr + 0xc;
413  retval = fill_buffer(target, ts_addr, buffer);
414 
415  if (retval == ERROR_OK) {
416  uint32_t TS = target_buffer_get_u32(target, buffer);
417  uint32_t cpu, on_cpu = TS + ONCPU;
418  retval = fill_buffer(target, on_cpu, buffer);
419 
420  if (retval == ERROR_OK) {
421  /*uint32_t cpu = target_buffer_get_u32(target, buffer);*/
422  struct current_thread *ct =
424  cpu = head->target->coreid;
425 
426  while ((ct) && (ct->core_id != (int32_t) cpu))
427  ct = ct->next;
428 
429  if ((ct) && (ct->TS == 0xdeadbeef))
430  ct->TS = TS;
431  else
432  LOG_ERROR
433  ("error in linux current thread update");
434 
435  if (create && ct) {
436  struct threads *t;
437  t = calloc(1, sizeof(struct threads));
438  t->base_addr = ct->TS;
439  fill_task(target, t);
440  get_name(target, t);
441  t->oncpu = cpu;
443  t->status = 3;
444  t->thread_info_addr = 0xdeadbeef;
445  ct->threadid = t->threadid;
447 #ifdef PID_CHECK
448  ct->pid = t->pid;
449 #endif
450  /*LOG_INFO("Creation of current thread %s",t->name);*/
451  }
452  }
453  }
454 
455  free(reg_list);
456  }
457 
458  free(buffer);
459 
460  return ERROR_OK;
461 }
462 
463 static struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr,
464  uint32_t *thread_info_addr_old)
465 {
466  struct cpu_context *context = calloc(1, sizeof(struct cpu_context));
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;
473  int retval = ERROR_FAIL;
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;
484 retry:
485 
486  if (*thread_info_addr_old == 0xdeadbeef) {
487  retval = fill_buffer(target, stack, buffer);
488 
489  if (retval == ERROR_OK)
490  thread_info_addr = target_buffer_get_u32(target, buffer);
491  else
492  LOG_ERROR("cpu_context: unable to read memory");
493 
494  thread_info_addr_update = thread_info_addr;
495  } else
496  thread_info_addr = *thread_info_addr_old;
497 
498  preempt_count_addr = thread_info_addr + PREEMPT;
499  retval = fill_buffer(target, preempt_count_addr, buffer);
500 
501  if (retval == ERROR_OK)
503  else {
504  if (*thread_info_addr_old != 0xdeadbeef) {
505  LOG_ERROR
506  ("cpu_context: cannot read at thread_info_addr");
507 
508  if (*thread_info_addr_old < LINUX_USER_KERNEL_BORDER)
509  LOG_INFO
510  ("cpu_context : thread_info_addr in userspace!!!");
511 
512  *thread_info_addr_old = 0xdeadbeef;
513  goto retry;
514  }
515 
516  LOG_ERROR("cpu_context: unable to read memory");
517  }
518 
519  thread_info_addr += CPU_CONT;
520 
521  retval = linux_read_memory(target, thread_info_addr, 4, 10,
522  (uint8_t *) registers);
523 
524  if (retval != ERROR_OK) {
525  free(buffer);
526  LOG_ERROR("cpu_context: unable to read memory\n");
527  return context;
528  }
529 
530  context->R4 =
531  target_buffer_get_u32(target, (const uint8_t *)&registers[0]);
532  context->R5 =
533  target_buffer_get_u32(target, (const uint8_t *)&registers[1]);
534  context->R6 =
535  target_buffer_get_u32(target, (const uint8_t *)&registers[2]);
536  context->R7 =
537  target_buffer_get_u32(target, (const uint8_t *)&registers[3]);
538  context->R8 =
539  target_buffer_get_u32(target, (const uint8_t *)&registers[4]);
540  context->R9 =
541  target_buffer_get_u32(target, (const uint8_t *)&registers[5]);
542  context->IP =
543  target_buffer_get_u32(target, (const uint8_t *)&registers[6]);
544  context->FP =
545  target_buffer_get_u32(target, (const uint8_t *)&registers[7]);
546  context->SP =
547  target_buffer_get_u32(target, (const uint8_t *)&registers[8]);
548  context->PC =
549  target_buffer_get_u32(target, (const uint8_t *)&registers[9]);
550 
551  if (*thread_info_addr_old == 0xdeadbeef)
552  *thread_info_addr_old = thread_info_addr_update;
553 
554  free(buffer);
555 
556  return context;
557 }
558 
559 static uint32_t next_task(struct target *target, struct threads *t)
560 {
561  uint8_t *buffer = calloc(1, 4);
562  uint32_t next_addr = t->base_addr + NEXT;
563  int retval = fill_buffer(target, next_addr, buffer);
564 
565  if (retval == ERROR_OK) {
566  uint32_t val = target_buffer_get_u32(target, buffer);
567  val = val - NEXT;
568  free(buffer);
569  return val;
570  } else
571  LOG_ERROR("next task: unable to read memory");
572 
573  free(buffer);
574 
575  return 0;
576 }
577 
578 static struct current_thread *add_current_thread(struct current_thread *currents,
579  struct current_thread *ct)
580 {
581  ct->next = NULL;
582 
583  if (!currents) {
584  currents = ct;
585  return currents;
586  } else {
587  struct current_thread *temp = currents;
588 
589  while (temp->next)
590  temp = temp->next;
591 
592  temp->next = ct;
593  return currents;
594  }
595 }
596 
597 static struct threads *liste_del_task(struct threads *task_list, struct threads **t,
598  struct threads *prev)
599 {
600  LOG_INFO("del task %" PRId64, (*t)->threadid);
601  if (prev)
602  prev->next = (*t)->next;
603  else
604  task_list = (*t)->next;
605 
606  /* free content of threads */
607  free((*t)->context);
608 
609  free(*t);
610  *t = prev ? prev : task_list;
611  return task_list;
612 }
613 
614 static struct threads *liste_add_task(struct threads *task_list, struct threads *t,
615  struct threads **last)
616 {
617  t->next = NULL;
618 
619  if (!*last) {
620  if (!task_list) {
621  task_list = t;
622  return task_list;
623  } else {
624  struct threads *temp = task_list;
625 
626  while (temp->next)
627  temp = temp->next;
628 
629  temp->next = t;
630  *last = t;
631  return task_list;
632  }
633  } else {
634  (*last)->next = t;
635  *last = t;
636  return task_list;
637  }
638 }
639 
640 #ifdef PID_CHECK
641 static int current_pid(struct linux_os *linux_os, uint32_t pid)
642 #else
643 static int current_base_addr(struct linux_os *linux_os, uint32_t base_addr)
644 #endif
645 {
647 #ifdef PID_CHECK
648 
649  while ((ct) && (ct->pid != pid))
650 #else
651  while ((ct) && (ct->TS != base_addr))
652 #endif
653  ct = ct->next;
654 #ifdef PID_CHECK
655  if ((ct) && (ct->pid == pid))
656 #else
657  if ((ct) && (ct->TS == base_addr))
658 #endif
659  return 1;
660 
661  return 0;
662 }
663 
664 static int linux_get_tasks(struct target *target, int context)
665 {
666  int loop = 0;
667  int retval = 0;
668  struct linux_os *linux_os = (struct linux_os *)
671  linux_os->thread_count = 0;
672 
673  if (linux_os->init_task_addr == 0xdeadbeef) {
674  LOG_INFO("no init symbol\n");
675  return ERROR_FAIL;
676  }
677 
678  int64_t start = timeval_ms();
679 
680  struct threads *t = calloc(1, sizeof(struct threads));
681  struct threads *last = NULL;
683  /* retrieve the thread id , currently running in the different smp core */
684  get_current(target, 1);
685 
686  while (((t->base_addr != linux_os->init_task_addr) &&
687  (t->base_addr != 0)) || (loop == 0)) {
688  loop++;
689  fill_task(target, t);
690  retval = get_name(target, t);
691 
692  if (loop > MAX_THREADS) {
693  free(t);
694  LOG_INFO("more than %d threads !!", MAX_THREADS);
695  return ERROR_FAIL;
696  }
697 
698  if (retval != ERROR_OK) {
699  free(t);
700  return ERROR_FAIL;
701  }
702 
703  /* check that this thread is not one the current threads already
704  * created */
705  uint32_t base_addr;
706 #ifdef PID_CHECK
707 
708  if (!current_pid(linux_os, t->pid)) {
709 #else
711 #endif
713  t->status = 1;
715 
717  liste_add_task(linux_os->thread_list, t, &last);
718  /* no interest to fill the context if it is a current thread. */
720  t->thread_info_addr = 0xdeadbeef;
721 
722  if (context)
723  t->context =
725  &t->thread_info_addr);
726  base_addr = next_task(target, t);
727  } else {
728  /*LOG_INFO("thread %s is a current thread already created",t->name); */
729  base_addr = next_task(target, t);
730  free(t);
731  }
732 
733  t = calloc(1, sizeof(struct threads));
734  t->base_addr = base_addr;
735  }
736 
740  /* check that all current threads have been identified */
741 
742  LOG_INFO("complete time %" PRId64 ", thread mean %" PRId64 "\n",
743  (timeval_ms() - start),
745 
746  LOG_INFO("threadid count %d", linux_os->threadid_count);
747  free(t);
748 
749  return ERROR_OK;
750 }
751 
752 static int clean_threadlist(struct target *target)
753 {
754  struct linux_os *linux_os = (struct linux_os *)
756  struct threads *old, *temp = linux_os->thread_list;
757 
758  while (temp) {
759  old = temp;
760 
761  free(temp->context);
762 
763  temp = temp->next;
764  free(old);
765  }
766 
767  return ERROR_OK;
768 }
769 
770 static int linux_os_clean(struct target *target)
771 {
772  struct linux_os *os_linux = (struct linux_os *)
775  os_linux->init_task_addr = 0xdeadbeef;
776  os_linux->name = "linux";
777  os_linux->thread_list = NULL;
778  os_linux->thread_count = 0;
779  os_linux->nr_cpus = 0;
780  os_linux->threads_lookup = 0;
781  os_linux->threads_needs_update = 0;
782  os_linux->threadid_count = 1;
783  return ERROR_OK;
784 }
785 
786 static int insert_into_threadlist(struct target *target, struct threads *t)
787 {
788  struct linux_os *linux_os = (struct linux_os *)
790  struct threads *temp = linux_os->thread_list;
793  t->status = 1;
794  t->next = NULL;
795 
796  if (!temp)
797  linux_os->thread_list = t;
798  else {
799  while (temp->next)
800  temp = temp->next;
801 
802  t->next = NULL;
803  temp->next = t;
804  }
805 
806  return ERROR_OK;
807 }
808 
810 {
811  struct linux_os *linux_os = (struct linux_os *)
815  struct threads *t = NULL;
816 
817  while ((ct)) {
818  if (ct->threadid == -1) {
819 
820  /* un-identified thread */
821  int found = 0;
822  t = calloc(1, sizeof(struct threads));
823  t->base_addr = ct->TS;
824 #ifdef PID_CHECK
825 
826  if (fill_task_pid(target, t) != ERROR_OK) {
827 error_handling:
828  free(t);
829  LOG_ERROR
830  ("linux identify_current_threads: unable to read pid");
831  return;
832  }
833 #endif
834 
835  /* search in the list of threads if pid
836  already present */
837  while ((thread_list) && (found == 0)) {
838 #ifdef PID_CHECK
839  if (thread_list->pid == t->pid) {
840 #else
841  if (thread_list->base_addr == t->base_addr) {
842 #endif
843  free(t);
844  t = thread_list;
845  found = 1;
846  }
848  }
849 
850  if (!found) {
851  /* it is a new thread */
852  if (fill_task(target, t) != ERROR_OK)
853  goto error_handling;
854 
855  get_name(target, t);
857  t->thread_info_addr = 0xdeadbeef;
858  }
859 
860  t->status = 3;
861  ct->threadid = t->threadid;
862 #ifdef PID_CHECK
863  ct->pid = t->pid;
864 #endif
866 #if 0
867  if (found == 0)
868  LOG_INFO("current thread core %x identified %s",
869  ct->core_id, t->name);
870  else
871  LOG_INFO("current thread core %x, reused %s",
872  ct->core_id, t->name);
873 #endif
874  }
875 #if 0
876  else {
877  struct threads tmp;
878  tmp.base_addr = ct->TS;
879  get_name(target, &tmp);
880  LOG_INFO("current thread core %x , already identified %s !!!",
881  ct->core_id, tmp.name);
882  }
883 #endif
884  ct = ct->next;
885  }
886 
887  return;
888 #ifndef PID_CHECK
889 error_handling:
890  free(t);
891  LOG_ERROR("unable to read pid");
892  return;
893 
894 #endif
895 }
896 
897 static int linux_task_update(struct target *target, int context)
898 {
899  struct linux_os *linux_os = (struct linux_os *)
902  int retval;
903  int loop = 0;
904  linux_os->thread_count = 0;
905 
906  /*thread_list = thread_list->next; skip init_task*/
907  while (thread_list) {
908  thread_list->status = 0; /*setting all tasks to dead state*/
909 
910  free(thread_list->context);
912 
914  }
915 
916  int found = 0;
917 
918  if (linux_os->init_task_addr == 0xdeadbeef) {
919  LOG_INFO("no init symbol\n");
920  return ERROR_FAIL;
921  }
922  int64_t start = timeval_ms();
923  struct threads *t = calloc(1, sizeof(struct threads));
924  uint32_t previous = 0xdeadbeef;
926  retval = get_current(target, 0);
927  /*check that all current threads have been identified */
929 
930  while (((t->base_addr != linux_os->init_task_addr) &&
931  (t->base_addr != previous)) || (loop == 0)) {
932  /* for avoiding any permanent loop for any reason possibly due to
933  * target */
934  loop++;
935  previous = t->base_addr;
936  /* read only pid */
937 #ifdef PID_CHECK
938  retval = fill_task_pid(target, t);
939 #endif
940 
941  if (retval != ERROR_OK) {
942  free(t);
943  return ERROR_FAIL;
944  }
945 
946  thread_list = linux_os->thread_list;
947 
948  while (thread_list) {
949 #ifdef PID_CHECK
950  if (t->pid == thread_list->pid) {
951 #else
952  if (t->base_addr == thread_list->base_addr) {
953 #endif
954  if (!thread_list->status) {
955 #ifdef PID_CHECK
956  if (t->base_addr != thread_list->base_addr)
957  LOG_INFO("thread base_addr has changed !!");
958 #endif
959  /* this is not a current thread */
960  thread_list->base_addr = t->base_addr;
961  thread_list->status = 1;
962 
963  /* we don 't update this field any more */
964 
965  /*thread_list->state = t->state;
966  thread_list->oncpu = t->oncpu;
967  thread_list->asid = t->asid;
968  */
969  if (context)
970  thread_list->context =
972  thread_list->base_addr,
973  &thread_list->thread_info_addr);
974  } else {
975  /* it is a current thread no need to read context */
976  }
977 
979  found = 1;
980  break;
981  } else {
982  found = 0;
983  thread_list = thread_list->next;
984  }
985  }
986 
987  if (found == 0) {
988  uint32_t base_addr;
989  fill_task(target, t);
990  get_name(target, t);
991  retval = insert_into_threadlist(target, t);
992  t->thread_info_addr = 0xdeadbeef;
993 
994  if (context)
995  t->context =
997  &t->thread_info_addr);
998 
999  base_addr = next_task(target, t);
1000  t = calloc(1, sizeof(struct threads));
1001  t->base_addr = base_addr;
1003  } else
1004  t->base_addr = next_task(target, t);
1005  }
1006 
1007  LOG_INFO("update thread done %" PRId64 ", mean%" PRId64 "\n",
1008  (timeval_ms() - start), (timeval_ms() - start) / loop);
1009  free(t);
1011  return ERROR_OK;
1012 }
1013 
1015  struct connection *connection, char const *packet,
1016  int packet_size)
1017 {
1018  int retval;
1019  struct linux_os *linux_os =
1021 
1022  if (linux_os->init_task_addr == 0xdeadbeef) {
1023  /* it has not been initialized */
1024  LOG_INFO("received thread request without init task address");
1025  gdb_put_packet(connection, "l", 1);
1026  return ERROR_OK;
1027  }
1028 
1029  retval = linux_get_tasks(target, 1);
1030 
1031  if (retval != ERROR_OK)
1032  return ERROR_TARGET_FAILURE;
1033 
1034  char *out_str = calloc(MAX_THREADS * 17 + 10, 1);
1035  if (!out_str) {
1036  LOG_ERROR("Out of memory");
1037  return ERROR_FAIL;
1038  }
1039  char *tmp_str = out_str;
1040  tmp_str += sprintf(tmp_str, "m");
1041  struct threads *temp = linux_os->thread_list;
1042 
1043  while (temp) {
1044  tmp_str += sprintf(tmp_str, "%016" PRIx64, temp->threadid);
1045  temp = temp->next;
1046  if (temp)
1047  tmp_str += sprintf(tmp_str, ",");
1048  }
1049 
1050  gdb_put_packet(connection, out_str, strlen(out_str));
1051  free(out_str);
1052  return ERROR_OK;
1053 }
1054 
1056  struct connection *connection, char const *packet,
1057  int packet_size)
1058 {
1059  int found = 0;
1060  struct linux_os *linux_os = (struct linux_os *)
1062  struct threads *temp = linux_os->thread_list;
1063 
1064  while (temp) {
1065  if (temp->threadid == linux_os->preupdtate_threadid_count + 1) {
1066  /*LOG_INFO("FOUND");*/
1067  found = 1;
1068  break;
1069  } else
1070  temp = temp->next;
1071  }
1072 
1073  if (found == 1) {
1074  /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/
1075  char *out_strr = calloc(MAX_THREADS * 17 + 10, 1);
1076  char *tmp_strr = out_strr;
1077  tmp_strr += sprintf(tmp_strr, "m");
1078  /*LOG_INFO("CHAR MALLOC & M DONE");*/
1079  tmp_strr += sprintf(tmp_strr, "%016" PRIx64, temp->threadid);
1080 
1081  temp = temp->next;
1082 
1083  while (temp) {
1084  /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/
1085  tmp_strr += sprintf(tmp_strr, ",");
1086  tmp_strr +=
1087  sprintf(tmp_strr, "%016" PRIx64, temp->threadid);
1088  temp = temp->next;
1089  }
1090 
1091  /*tmp_str[0] = 0;*/
1092  gdb_put_packet(connection, out_strr, strlen(out_strr));
1094  linux_os->threadid_count - 1;
1095  free(out_strr);
1096  } else
1097  gdb_put_packet(connection, "l", 1);
1098 
1099  return ERROR_OK;
1100 }
1101 
1103  struct connection *connection, char const *packet,
1104  int packet_size)
1105 {
1106  int64_t threadid = 0;
1107  struct linux_os *linux_os = (struct linux_os *)
1109  sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid);
1110  /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/
1111  struct threads *temp = linux_os->thread_list;
1112 
1113  while (temp) {
1114  if (temp->threadid == threadid) {
1115  char *tmp_str = alloc_printf("%cPID: %" PRIu32 ", Name: %s",
1116  temp->status == 3 ? '*' : ' ',
1117  temp->pid, temp->name);
1118  if (!tmp_str) {
1119  LOG_ERROR("Out of memory");
1120  return ERROR_FAIL;
1121  }
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);
1125  gdb_put_packet(connection, hex_str, pkt_len);
1126  free(hex_str);
1127  free(tmp_str);
1128  return ERROR_OK;
1129  }
1130 
1131  temp = temp->next;
1132  }
1133 
1134  LOG_INFO("thread not found");
1135  return ERROR_OK;
1136 }
1137 
1139  struct target *target, char const *packet, int packet_size)
1140 {
1141  int64_t threadid;
1142  struct linux_os *linux_os = (struct linux_os *)
1144  int retval = ERROR_OK;
1145  sscanf(packet, "T%" SCNx64, &threadid);
1146 
1147  if (linux_os->threads_needs_update == 0) {
1148  struct threads *temp = linux_os->thread_list;
1149  struct threads *prev = NULL;
1150 
1151  while (temp) {
1152  if (temp->threadid == threadid) {
1153  if (temp->status != 0) {
1154  gdb_put_packet(connection, "OK", 2);
1155  return ERROR_OK;
1156  } else {
1157  /* delete item in the list */
1160  &temp, prev);
1162  gdb_put_packet(connection, "E01", 3);
1163  return ERROR_OK;
1164  }
1165  }
1166 
1167  /* for deletion */
1168  prev = temp;
1169  temp = temp->next;
1170  }
1171 
1172  LOG_INFO("gdb requested status on non existing thread");
1173  gdb_put_packet(connection, "E01", 3);
1174  return ERROR_OK;
1175 
1176  } else {
1177  retval = linux_task_update(target, 1);
1178  struct threads *temp = linux_os->thread_list;
1179 
1180  while (temp) {
1181  if (temp->threadid == threadid) {
1182  if (temp->status == 1) {
1183  gdb_put_packet(connection, "OK", 2);
1184  return ERROR_OK;
1185  } else {
1186  gdb_put_packet(connection, "E01", 3);
1187  return ERROR_OK;
1188  }
1189  }
1190 
1191  temp = temp->next;
1192  }
1193  }
1194 
1195  return retval;
1196 }
1197 
1199  struct target *target, char const *packet, int packet_size)
1200 {
1201  struct linux_os *linux_os = (struct linux_os *)
1203  struct current_thread *ct = linux_os->current_threads;
1204 
1205  /* select to display the current thread of the selected target */
1206  while ((ct) && (ct->core_id != target->coreid))
1207  ct = ct->next;
1208 
1209  int64_t current_gdb_thread_rq;
1210 
1211  if (linux_os->threads_lookup == 1) {
1212  if ((ct) && (ct->threadid == -1)) {
1213  ct = linux_os->current_threads;
1214 
1215  while ((ct) && (ct->threadid == -1))
1216  ct = ct->next;
1217  }
1218 
1219  if (!ct) {
1220  /* no current thread can be identified
1221  * any way with smp */
1222  LOG_INFO("no current thread identified");
1223  /* attempt to display the name of the 2 threads identified with
1224  * get_current */
1225  struct threads t;
1226  ct = linux_os->current_threads;
1227 
1228  while ((ct) && (ct->threadid == -1)) {
1229  t.base_addr = ct->TS;
1230  get_name(target, &t);
1231  LOG_INFO("name of unidentified thread %s",
1232  t.name);
1233  ct = ct->next;
1234  }
1235 
1236  gdb_put_packet(connection, "OK", 2);
1237  return ERROR_OK;
1238  }
1239 
1240  if (packet[1] == 'g') {
1241  sscanf(packet, "Hg%16" SCNx64, &current_gdb_thread_rq);
1242 
1243  if (current_gdb_thread_rq == 0) {
1244  target->rtos->current_threadid = ct->threadid;
1245  gdb_put_packet(connection, "OK", 2);
1246  } else {
1248  current_gdb_thread_rq;
1249  gdb_put_packet(connection, "OK", 2);
1250  }
1251  } else if (packet[1] == 'c') {
1252  sscanf(packet, "Hc%16" SCNx64, &current_gdb_thread_rq);
1253 
1254  if ((current_gdb_thread_rq == 0) ||
1255  (current_gdb_thread_rq == ct->threadid)) {
1256  target->rtos->current_threadid = ct->threadid;
1257  gdb_put_packet(connection, "OK", 2);
1258  } else
1259  gdb_put_packet(connection, "E01", 3);
1260  }
1261  } else
1262  gdb_put_packet(connection, "OK", 2);
1263 
1264  return ERROR_OK;
1265 }
1266 
1267 static int linux_thread_packet(struct connection *connection, char const *packet,
1268  int packet_size)
1269 {
1270  int retval = ERROR_OK;
1271  struct current_thread *ct;
1273  struct linux_os *linux_os = (struct linux_os *)
1275 
1276  switch (packet[0]) {
1277  case 'T': /* Is thread alive?*/
1278  linux_gdb_t_packet(connection, target, packet, packet_size);
1279  break;
1280 
1281  case 'H': /* Set current thread */
1282  /* ( 'c' for step and continue, 'g' for all other operations )*/
1283  /*LOG_INFO(" H packet received '%s'", packet);*/
1284  linux_gdb_h_packet(connection, target, packet, packet_size);
1285  break;
1286 
1287  case 'q':
1288  if (!strncmp(packet, "qSymbol", 7)) {
1289  if (rtos_qsymbol(connection, packet, packet_size) == 1) {
1292  }
1293  } else if (!strncmp(packet, "qfThreadInfo", 12)) {
1294  if (!linux_os->thread_list) {
1296  connection,
1297  packet,
1298  packet_size);
1299  } else {
1301  connection,
1302  packet,
1303  packet_size);
1304  }
1305  } else if (!strncmp(packet, "qsThreadInfo", 12)) {
1306  gdb_put_packet(connection, "l", 1);
1307  } else if (!strncmp(packet, "qThreadExtraInfo,", 17)) {
1309  packet_size);
1310  } else {
1312  }
1313  break;
1314 
1315  case 'Q':
1316  /* previously response was : thread not found
1317  * gdb_put_packet(connection, "E01", 3); */
1319  break;
1320 
1321  case 'c':
1322  case 's':
1323  if (linux_os->threads_lookup == 1) {
1324  ct = linux_os->current_threads;
1325 
1326  while ((ct) && (ct->core_id) != target->coreid)
1327  ct = ct->next;
1328 
1329  if ((ct) && (ct->threadid == -1)) {
1330  ct = linux_os->current_threads;
1331 
1332  while ((ct) && (ct->threadid == -1))
1333  ct = ct->next;
1334  }
1335 
1336  if ((ct) && (ct->threadid !=
1338  && (target->rtos->current_threadid != -1))
1339  LOG_WARNING("WARNING! current GDB thread do not match "
1340  "current thread running. "
1341  "Switch thread in GDB to threadid %d",
1342  (int)ct->threadid);
1343 
1344  LOG_INFO("threads_needs_update = 1");
1346  }
1347  break;
1348  }
1349 
1350  return retval;
1351 }
1352 
1353 static int linux_os_smp_init(struct target *target)
1354 {
1355  struct target_list *head;
1356  /* keep only target->rtos */
1357  struct rtos *rtos = target->rtos;
1358  struct linux_os *os_linux =
1359  (struct linux_os *)rtos->rtos_specific_params;
1360  struct current_thread *ct;
1361 
1363  if (head->target->rtos != rtos) {
1364  struct linux_os *smp_os_linux =
1365  (struct linux_os *)head->target->rtos->rtos_specific_params;
1366  /* remap smp target on rtos */
1367  free(head->target->rtos);
1368  head->target->rtos = rtos;
1369  /* reuse allocated ct */
1370  ct = smp_os_linux->current_threads;
1371  ct->threadid = -1;
1372  ct->TS = 0xdeadbeef;
1373  ct->core_id = head->target->coreid;
1374  os_linux->current_threads =
1375  add_current_thread(os_linux->current_threads, ct);
1376  os_linux->nr_cpus++;
1377  free(smp_os_linux);
1378  }
1379  }
1380 
1381  return ERROR_OK;
1382 }
1383 
1384 static int linux_os_create(struct target *target)
1385 {
1386  struct linux_os *os_linux = calloc(1, sizeof(struct linux_os));
1387  struct current_thread *ct = calloc(1, sizeof(struct current_thread));
1388  LOG_INFO("linux os creation\n");
1389  os_linux->init_task_addr = 0xdeadbeef;
1390  os_linux->name = "linux";
1391  os_linux->thread_list = NULL;
1392  os_linux->thread_count = 0;
1393  target->rtos->current_threadid = -1;
1394  os_linux->nr_cpus = 1;
1395  os_linux->threads_lookup = 0;
1396  os_linux->threads_needs_update = 0;
1397  os_linux->threadid_count = 1;
1398  os_linux->current_threads = NULL;
1399  target->rtos->rtos_specific_params = os_linux;
1400  ct->core_id = target->coreid;
1401  ct->threadid = -1;
1402  ct->TS = 0xdeadbeef;
1403  os_linux->current_threads =
1404  add_current_thread(os_linux->current_threads, ct);
1405  /* overload rtos thread default handler */
1407  /* initialize a default virt 2 phys translation */
1408  os_linux->phys_mask = ~0xc0000000;
1409  os_linux->phys_base = 0x0;
1410  return ERROR_OK;
1411 }
1412 
1413 static char *linux_ps_command(struct target *target)
1414 {
1415  struct linux_os *linux_os = (struct linux_os *)
1417  int retval = ERROR_OK;
1418  char *display;
1419 
1420  if (linux_os->threads_lookup == 0)
1421  retval = linux_get_tasks(target, 1);
1422  else {
1423  if (linux_os->threads_needs_update != 0)
1424  retval = linux_task_update(target, 0);
1425  }
1426 
1427  if (retval == ERROR_OK) {
1428  struct threads *temp = linux_os->thread_list;
1429  char *tmp;
1430  LOG_INFO("allocation for %d threads line",
1432  display = calloc((linux_os->thread_count + 2) * 80, 1);
1433 
1434  if (!display)
1435  goto error;
1436 
1437  tmp = display;
1438  tmp += sprintf(tmp, "PID\t\tCPU\t\tASID\t\tNAME\n");
1439  tmp += sprintf(tmp, "---\t\t---\t\t----\t\t----\n");
1440 
1441  while (temp) {
1442  if (temp->status) {
1443  if (temp->context)
1444  tmp +=
1445  sprintf(tmp,
1446  "%" PRIu32 "\t\t%" PRIu32 "\t\t%" PRIx32 "\t\t%s\n",
1447  temp->pid, temp->oncpu,
1448  temp->asid, temp->name);
1449  else
1450  tmp +=
1451  sprintf(tmp,
1452  "%" PRIu32 "\t\t%" PRIu32 "\t\t%" PRIx32 "\t\t%s\n",
1453  temp->pid, temp->oncpu,
1454  temp->asid, temp->name);
1455  }
1456 
1457  temp = temp->next;
1458  }
1459 
1460  return display;
1461  }
1462 
1463 error:
1464  display = calloc(40, 1);
1465  sprintf(display, "linux_ps_command failed\n");
1466  return display;
1467 }
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
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:0
uint32_t size
Size of dw_spi_transaction::buffer.
Definition: dw-spi-helper.h:4
uint32_t address
Starting address. Sector aligned.
Definition: dw-spi-helper.h:0
int gdb_put_packet(struct connection *connection, const char *buffer, int len)
Definition: gdb_server.c:554
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:578
static int fill_task(struct target *target, struct threads *t)
Definition: linux.c:275
#define INIT_TASK
Definition: linux.c:222
static int clean_threadlist(struct target *target)
Definition: linux.c:752
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:148
static int current_base_addr(struct linux_os *linux_os, uint32_t base_addr)
Definition: linux.c:643
static int linux_thread_extra_info(struct target *target, struct connection *connection, char const *packet, int packet_size)
Definition: linux.c:1102
static void linux_identify_current_threads(struct target *target)
Definition: linux.c:809
static char * linux_ps_command(struct target *target)
Definition: linux.c:1413
static int linux_os_smp_init(struct target *target)
Definition: linux.c:1353
static uint32_t next_task(struct target *target, struct threads *t)
Definition: linux.c:559
static int linux_gdb_thread_update(struct target *target, struct connection *connection, char const *packet, int packet_size)
Definition: linux.c:1055
static int linux_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])
Definition: linux.c:228
static int insert_into_threadlist(struct target *target, struct threads *t)
Definition: linux.c:786
static int get_current(struct target *target, int create)
Definition: linux.c:377
static int linux_gdb_h_packet(struct connection *connection, struct target *target, char const *packet, int packet_size)
Definition: linux.c:1198
static struct threads * liste_add_task(struct threads *task_list, struct threads *t, struct threads **last)
Definition: linux.c:614
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:770
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:223
static bool linux_os_detect(struct target *target)
Definition: linux.c:214
#define LINUX_USER_KERNEL_BORDER
Definition: linux.c:25
static int linux_get_tasks(struct target *target, int context)
Definition: linux.c:664
static struct cpu_context * cpu_context_read(struct target *target, uint32_t base_addr, uint32_t *info_addr)
Definition: linux.c:463
#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:331
const struct rtos_type linux_rtos
Definition: linux.c:242
static int linux_gdb_thread_packet(struct target *target, struct connection *connection, char const *packet, int packet_size)
Definition: linux.c:1014
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:897
static int linux_os_create(struct target *target)
Definition: linux.c:1384
static int linux_thread_packet(struct connection *connection, char const *packet, int packet_size)
Definition: linux.c:1267
static int linux_gdb_t_packet(struct connection *connection, struct target *target, char const *packet, int packet_size)
Definition: linux.c:1138
static struct threads * liste_del_task(struct threads *task_list, struct threads **t, struct threads *prev)
Definition: linux.c:597
#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:38
char * alloc_printf(const char *format,...)
Definition: log.c:386
#define LOG_WARNING(expr ...)
Definition: log.h:144
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_INFO(expr ...)
Definition: log.h:141
#define ERROR_OK
Definition: log.h:182
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
Definition: rtos.c:235
#define GDB_THREAD_PACKET_NOT_CONSUMED
Definition: rtos.h:129
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
#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:227
int(* virt2phys)(struct target *target, target_addr_t address, target_addr_t *physical)
Definition: target_type.h:254
Definition: target.h:119
int32_t coreid
Definition: target.h:123
struct list_head * smp_targets
Definition: target.h:201
struct rtos * rtos
Definition: target.h:193
struct target_type * type
Definition: target.h:120
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:1274
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:1391
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:1260
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
Definition: target.c:326
@ REG_CLASS_GENERAL
Definition: target.h:115
#define ERROR_TARGET_FAILURE
Definition: target.h:818
int64_t timeval_ms(void)
const char * full_name
Definition: transport.c:52
#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:279
#define NULL
Definition: usb.h:16
uint8_t count[4]
Definition: vdebug.c:22