OpenOCD
rtos.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2011 by Broadcom Corporation *
5  * Evan Hunter - ehunter@broadcom.com *
6  ***************************************************************************/
7 
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11 
12 #include "rtos.h"
13 #include "target/target.h"
14 #include "target/smp.h"
15 #include "helper/log.h"
16 #include "helper/binarybuffer.h"
17 #include "helper/types.h"
18 #include "server/gdb_server.h"
19 
20 static const struct rtos_type *rtos_types[] = {
21  // Keep in alphabetic order this list of rtos, except hwthread
22  &chibios_rtos,
24  &ecos_rtos,
27  &linux_rtos,
28  &mqx_rtos,
29  &nuttx_rtos,
30  &riot_rtos,
32  &threadx_rtos,
34  &zephyr_rtos,
35 
36  // keep this as last, as it always matches with rtos auto
38 };
39 
41 {
42  if (target->rtos->type->smp_init)
43  return target->rtos->type->smp_init(target);
45 }
46 
47 static int rtos_target_for_threadid(struct connection *connection, int64_t threadid, struct target **t)
48 {
50  if (t)
51  *t = curr;
52 
53  return ERROR_OK;
54 }
55 
56 static int os_alloc(struct target *target, const struct rtos_type *ostype)
57 {
58  struct rtos *os = target->rtos = calloc(1, sizeof(struct rtos));
59 
60  if (!os)
61  return ERROR_FAIL;
62 
63  os->type = ostype;
64  os->current_threadid = -1;
65  os->current_thread = 0;
66  os->symbols = NULL;
67  os->target = target;
68 
69  /* RTOS drivers can override the packet handler in _create(). */
72 
73  return ERROR_OK;
74 }
75 
76 static void os_free(struct target *target)
77 {
78  if (!target->rtos)
79  return;
80 
81  free(target->rtos->symbols);
83  free(target->rtos);
84  target->rtos = NULL;
85 }
86 
87 static int os_alloc_create(struct target *target, const struct rtos_type *ostype)
88 {
89  int ret = os_alloc(target, ostype);
90  if (ret != ERROR_OK)
91  return ret;
92 
93  ret = target->rtos->type->create(target);
94  if (ret != ERROR_OK)
95  os_free(target);
96 
97  return ret;
98 }
99 
101  const char *rtos_name)
102 {
103  os_free(target);
104  target->rtos_auto_detect = false;
105 
106  if (strcmp(rtos_name, "none") == 0)
107  return ERROR_OK;
108 
109  if (strcmp(rtos_name, "auto") == 0) {
110  /* Auto detect tries to look up all symbols for each RTOS,
111  * and runs the RTOS driver's _detect() function when GDB
112  * finds all symbols for any RTOS. See rtos_qsymbol(). */
113  target->rtos_auto_detect = true;
114 
115  /* rtos_qsymbol() will iterate over all RTOSes. Allocate
116  * target->rtos here, and set it to the first RTOS type. */
117  return os_alloc(target, rtos_types[0]);
118  }
119 
120  for (size_t x = 0; x < ARRAY_SIZE(rtos_types); x++)
121  if (strcmp(rtos_name, rtos_types[x]->name) == 0)
122  return os_alloc_create(target, rtos_types[x]);
123 
124  char *all = NULL;
125  for (size_t x = 0; x < ARRAY_SIZE(rtos_types); x++) {
126  char *prev = all;
127  if (all)
128  all = alloc_printf("%s, %s", all, rtos_types[x]->name);
129  else
130  all = alloc_printf("%s", rtos_types[x]->name);
131  free(prev);
132  if (!all) {
133  LOG_ERROR("Out of memory");
134  return ERROR_FAIL;
135  }
136  }
137 
138  command_print(cmd, "Unknown RTOS type %s, try one of: %s, auto or none",
139  rtos_name, all);
140  free(all);
141 
143 }
144 
146 {
147  os_free(target);
148 }
149 
150 int gdb_thread_packet(struct connection *connection, char const *packet, int packet_size)
151 {
153  if (!target->rtos)
154  return rtos_thread_packet(connection, packet, packet_size); /* thread not
155  *found*/
156  return target->rtos->gdb_thread_packet(connection, packet, packet_size);
157 }
158 
159 static bool rtos_try_next(struct target *target)
160 {
161  struct rtos *os = target->rtos;
162 
163  if (!os)
164  return false;
165 
166  for (size_t x = 0; x < ARRAY_SIZE(rtos_types) - 1; x++) {
167  if (os->type == rtos_types[x]) {
168  // Use next RTOS in the list
169  os->type = rtos_types[x + 1];
170 
171  free(os->symbols);
172  os->symbols = NULL;
173 
174  return true;
175  }
176  }
177 
178  // No next RTOS to try
179  return false;
180 }
181 
182 static struct symbol_table_elem *find_symbol(const struct rtos *os, const char *symbol)
183 {
184  struct symbol_table_elem *s;
185 
186  for (s = os->symbols; s->symbol_name; s++)
187  if (!strcmp(s->symbol_name, symbol))
188  return s;
189 
190  return NULL;
191 }
192 
193 static struct symbol_table_elem *next_symbol(struct rtos *os, char *cur_symbol, uint64_t cur_addr)
194 {
195  if (!os->symbols)
197 
198  if (!cur_symbol[0])
199  return &os->symbols[0];
200 
201  struct symbol_table_elem *s = find_symbol(os, cur_symbol);
202  if (!s)
203  return NULL;
204 
205  s->address = cur_addr;
206  s++;
207  return s;
208 }
209 
210 /* rtos_qsymbol() processes and replies to all qSymbol packets from GDB.
211  *
212  * GDB sends a qSymbol:: packet (empty address, empty name) to notify
213  * that it can now answer qSymbol::hexcodedname queries, to look up symbols.
214  *
215  * If the qSymbol packet has no address that means GDB did not find the
216  * symbol, in which case auto-detect will move on to try the next RTOS.
217  *
218  * rtos_qsymbol() then calls the next_symbol() helper function, which
219  * iterates over symbol names for the current RTOS until it finds the
220  * symbol in the received GDB packet, and then returns the next entry
221  * in the list of symbols.
222  *
223  * If GDB replied about the last symbol for the RTOS and the RTOS was
224  * specified explicitly, then no further symbol lookup is done. When
225  * auto-detecting, the RTOS driver _detect() function must return success.
226  *
227  * The symbol is tried twice to handle the -flto case with gcc. The first
228  * attempt uses the symbol as-is, and the second attempt tries the symbol
229  * with ".lto_priv.0" appended to it. We only consider the first static
230  * symbol here from the -flto case. (Each subsequent static symbol with
231  * the same name is exported as .lto_priv.1, .lto_priv.2, etc.)
232  *
233  * rtos_qsymbol() returns 1 if an RTOS has been detected, or 0 otherwise.
234  */
235 int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
236 {
237  int rtos_detected = 0;
238  uint64_t addr = 0;
239  size_t reply_len;
240  char reply[GDB_BUFFER_SIZE + 1], cur_sym[GDB_BUFFER_SIZE / 2 + 1] = ""; /* Extra byte for null-termination */
241  struct symbol_table_elem *next_sym = NULL;
243  struct rtos *os = target->rtos;
244 
245  reply_len = sprintf(reply, "OK");
246 
247  if (!os)
248  goto done;
249 
250  /* Decode any symbol name in the packet*/
251  size_t len = unhexify((uint8_t *)cur_sym, strchr(packet + 8, ':') + 1, strlen(strchr(packet + 8, ':') + 1));
252  cur_sym[len] = 0;
253 
254  const char no_suffix[] = "";
255  const char lto_suffix[] = ".lto_priv.0";
256  const size_t lto_suffix_len = strlen(lto_suffix);
257 
258  const char *cur_suffix;
259  const char *next_suffix;
260 
261  /* Detect what suffix was used during the previous symbol lookup attempt, and
262  * speculatively determine the next suffix (only used for the unknown address case) */
263  if (len > lto_suffix_len && !strcmp(cur_sym + len - lto_suffix_len, lto_suffix)) {
264  /* Trim the suffix from cur_sym for comparison purposes below */
265  cur_sym[len - lto_suffix_len] = '\0';
266  cur_suffix = lto_suffix;
267  next_suffix = NULL;
268  } else {
269  cur_suffix = no_suffix;
270  next_suffix = lto_suffix;
271  }
272 
273  if ((strcmp(packet, "qSymbol::") != 0) && /* GDB is not offering symbol lookup for the first time */
274  (!sscanf(packet, "qSymbol:%" SCNx64 ":", &addr))) { /* GDB did not find an address for a symbol */
275 
276  /* GDB could not find an address for the previous symbol */
277  struct symbol_table_elem *sym = find_symbol(os, cur_sym);
278 
279  if (next_suffix) {
280  next_sym = sym;
281  } else if (sym && !sym->optional) { /* the symbol is mandatory for this RTOS */
282  if (!target->rtos_auto_detect) {
283  LOG_WARNING("RTOS %s not detected. (GDB could not find symbol \'%s\')", os->type->name, cur_sym);
284  goto done;
285  } else {
286  /* Autodetecting RTOS - try next RTOS */
287  if (!rtos_try_next(target)) {
288  LOG_WARNING("No RTOS could be auto-detected!");
289  goto done;
290  }
291 
292  /* Next RTOS selected - invalidate current symbol */
293  cur_sym[0] = '\x00';
294  }
295  }
296  }
297 
298  LOG_DEBUG("RTOS: Address of symbol '%s%s' is 0x%" PRIx64, cur_sym, cur_suffix, addr);
299 
300  if (!next_sym) {
301  next_sym = next_symbol(os, cur_sym, addr);
302  next_suffix = no_suffix;
303  }
304 
305  /* Should never happen unless the debugger misbehaves */
306  if (!next_sym) {
307  LOG_WARNING("RTOS: Debugger sent us qSymbol with '%s%s' that we did not ask for", cur_sym, cur_suffix);
308  goto done;
309  }
310 
311  if (!next_sym->symbol_name) {
312  /* No more symbols need looking up */
313 
314  if (!target->rtos_auto_detect) {
315  rtos_detected = 1;
316  goto done;
317  }
318 
319  if (os->type->detect_rtos(target)) {
320  LOG_INFO("Auto-detected RTOS: %s", os->type->name);
321  rtos_detected = 1;
322  goto done;
323  } else {
324  LOG_WARNING("No RTOS could be auto-detected!");
325  goto done;
326  }
327  }
328 
329  assert(next_suffix);
330 
331  reply_len = 8; /* snprintf(..., "qSymbol:") */
332  reply_len += 2 * strlen(next_sym->symbol_name); /* hexify(..., next_sym->symbol_name, ...) */
333  reply_len += 2 * strlen(next_suffix); /* hexify(..., next_suffix, ...) */
334  reply_len += 1; /* Terminating NUL */
335  if (reply_len > sizeof(reply)) {
336  LOG_ERROR("RTOS symbol '%s%s' name is too long for GDB", next_sym->symbol_name, next_suffix);
337  goto done;
338  }
339 
340  LOG_DEBUG("RTOS: Requesting symbol lookup of '%s%s' from the debugger", next_sym->symbol_name, next_suffix);
341 
342  reply_len = snprintf(reply, sizeof(reply), "qSymbol:");
343  reply_len += hexify(reply + reply_len,
344  (const uint8_t *)next_sym->symbol_name, strlen(next_sym->symbol_name),
345  sizeof(reply) - reply_len);
346  reply_len += hexify(reply + reply_len,
347  (const uint8_t *)next_suffix, strlen(next_suffix),
348  sizeof(reply) - reply_len);
349 
350 done:
351  gdb_put_packet(connection, reply, reply_len);
352  return rtos_detected;
353 }
354 
355 int rtos_thread_packet(struct connection *connection, char const *packet, int packet_size)
356 {
358 
359  if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) {
360  if ((target->rtos) && (target->rtos->thread_details) &&
361  (target->rtos->thread_count != 0)) {
362  threadid_t threadid = 0;
363  int found = -1;
364  sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid);
365 
366  if ((target->rtos) && (target->rtos->thread_details)) {
367  int thread_num;
368  for (thread_num = 0; thread_num < target->rtos->thread_count; thread_num++) {
369  if (target->rtos->thread_details[thread_num].threadid == threadid) {
370  if (target->rtos->thread_details[thread_num].exists)
371  found = thread_num;
372  }
373  }
374  }
375  if (found == -1) {
376  gdb_put_packet(connection, "E01", 3); /* thread not found */
377  return ERROR_OK;
378  }
379 
380  struct thread_detail *detail = &target->rtos->thread_details[found];
381 
382  int str_size = 0;
383  if (detail->thread_name_str)
384  str_size += strlen(detail->thread_name_str);
385  if (detail->extra_info_str)
386  str_size += strlen(detail->extra_info_str);
387 
388  char *tmp_str = calloc(str_size + 9, sizeof(char));
389  if (!tmp_str) {
390  LOG_ERROR("Out of memory");
391  return ERROR_FAIL;
392  }
393  char *tmp_str_ptr = tmp_str;
394 
395  if (detail->thread_name_str)
396  tmp_str_ptr += sprintf(tmp_str_ptr, "Name: %s", detail->thread_name_str);
397  if (detail->extra_info_str) {
398  if (tmp_str_ptr != tmp_str)
399  tmp_str_ptr += sprintf(tmp_str_ptr, ", ");
400  tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->extra_info_str);
401  }
402 
403  assert(strlen(tmp_str) ==
404  (size_t) (tmp_str_ptr - tmp_str));
405 
406  char *hex_str = malloc(strlen(tmp_str) * 2 + 1);
407  size_t pkt_len = hexify(hex_str, (const uint8_t *)tmp_str,
408  strlen(tmp_str), strlen(tmp_str) * 2 + 1);
409 
410  gdb_put_packet(connection, hex_str, pkt_len);
411  free(hex_str);
412  free(tmp_str);
413  return ERROR_OK;
414 
415  }
416  gdb_put_packet(connection, "", 0);
417  return ERROR_OK;
418  } else if (strncmp(packet, "qSymbol", 7) == 0) {
419  if (rtos_qsymbol(connection, packet, packet_size) == 1) {
420  if (target->rtos_auto_detect) {
421  target->rtos_auto_detect = false;
423  }
425  }
426  return ERROR_OK;
427  } else if (strncmp(packet, "qfThreadInfo", 12) == 0) {
428  int i;
429  if (target->rtos) {
430  if (target->rtos->thread_count == 0) {
431  gdb_put_packet(connection, "l", 1);
432  } else {
433  /*thread id are 16 char +1 for ',' */
434  char *out_str = malloc(17 * target->rtos->thread_count + 1);
435  char *tmp_str = out_str;
436  for (i = 0; i < target->rtos->thread_count; i++) {
437  tmp_str += sprintf(tmp_str, "%c%016" PRIx64, i == 0 ? 'm' : ',',
439  }
440  gdb_put_packet(connection, out_str, strlen(out_str));
441  free(out_str);
442  }
443  } else
444  gdb_put_packet(connection, "l", 1);
445 
446  return ERROR_OK;
447  } else if (strncmp(packet, "qsThreadInfo", 12) == 0) {
448  gdb_put_packet(connection, "l", 1);
449  return ERROR_OK;
450  } else if (strncmp(packet, "qAttached", 9) == 0) {
451  gdb_put_packet(connection, "1", 1);
452  return ERROR_OK;
453  } else if (strncmp(packet, "qOffsets", 8) == 0) {
454  char offsets[] = "Text=0;Data=0;Bss=0";
455  gdb_put_packet(connection, offsets, sizeof(offsets)-1);
456  return ERROR_OK;
457  } else if (strncmp(packet, "qCRC:", 5) == 0) {
458  /* make sure we check this before "qC" packet below
459  * otherwise it gets incorrectly handled */
461  } else if (strncmp(packet, "qC", 2) == 0) {
462  if (target->rtos) {
463  char buffer[19];
464  int size;
465  size = snprintf(buffer, 19, "QC%016" PRIx64, target->rtos->current_thread);
467  } else
468  gdb_put_packet(connection, "QC0", 3);
469  return ERROR_OK;
470  } else if (packet[0] == 'T') { /* Is thread alive? */
472  int found = -1;
473  sscanf(packet, "T%" SCNx64, &threadid);
474  if ((target->rtos) && (target->rtos->thread_details)) {
475  int thread_num;
476  for (thread_num = 0; thread_num < target->rtos->thread_count; thread_num++) {
477  if (target->rtos->thread_details[thread_num].threadid == threadid) {
478  if (target->rtos->thread_details[thread_num].exists)
479  found = thread_num;
480  }
481  }
482  }
483  if (found != -1)
484  gdb_put_packet(connection, "OK", 2); /* thread alive */
485  else
486  gdb_put_packet(connection, "E01", 3); /* thread not found */
487  return ERROR_OK;
488  } else if (packet[0] == 'H') { /* Set current thread ( 'c' for step and continue, 'g' for
489  * all other operations ) */
490  if ((packet[1] == 'g') && (target->rtos)) {
492  sscanf(packet, "Hg%16" SCNx64, &threadid);
493  LOG_DEBUG("RTOS: GDB requested to set current thread to 0x%" PRIx64, threadid);
494  /* threadid of 0 indicates target should choose */
495  if (threadid == 0)
497  else
499  }
500  gdb_put_packet(connection, "OK", 2);
501  return ERROR_OK;
502  }
503 
505 }
506 
508  uint8_t *reg_value, unsigned int reg_size)
509 {
510  unsigned int reg_bytes = DIV_ROUND_UP(reg_size, 8);
511  unsigned int num_bytes = reg_bytes * 2 + 1; // for '\0'
512 
513  char *hex = malloc(num_bytes);
514  if (!hex) {
515  LOG_ERROR("Out of memory");
516  return ERROR_FAIL;
517  }
518 
519  size_t len = hexify(hex, reg_value, reg_bytes, num_bytes);
520 
521  gdb_put_packet(connection, hex, len);
522  free(hex);
523 
524  return ERROR_OK;
525 }
526 
528  struct rtos_reg *reg_list, int num_regs)
529 {
530  size_t num_bytes = 1; /* NUL */
531  for (int i = 0; i < num_regs; ++i)
532  num_bytes += DIV_ROUND_UP(reg_list[i].size, 8) * 2;
533 
534  char *hex = malloc(num_bytes);
535  char *hex_p = hex;
536 
537  for (int i = 0; i < num_regs; ++i) {
538  size_t count = DIV_ROUND_UP(reg_list[i].size, 8);
539  size_t n = hexify(hex_p, reg_list[i].value, count, num_bytes);
540  hex_p += n;
541  num_bytes -= n;
542  }
543 
544  gdb_put_packet(connection, hex, strlen(hex));
545  free(hex);
546 
547  return ERROR_OK;
548 }
549 
551 int rtos_get_gdb_reg(struct connection *connection, int reg_num)
552 {
554  int64_t current_threadid = target->rtos->current_threadid;
555  if ((target->rtos) && (current_threadid != -1) &&
556  (current_threadid != 0) &&
557  ((current_threadid != target->rtos->current_thread) ||
558  (target->smp))) { /* in smp several current thread are possible */
559  struct rtos_reg *reg_list;
560  int num_regs;
561 
562  LOG_DEBUG("getting register %d for thread 0x%" PRIx64
563  ", target->rtos->current_thread=0x%" PRIx64,
564  reg_num,
565  current_threadid,
567 
568  int retval;
570  uint32_t reg_size;
571  uint8_t *reg_value;
573  current_threadid, reg_num, &reg_size, &reg_value);
574  if (retval != ERROR_OK) {
575  LOG_ERROR("RTOS: failed to get register %d", reg_num);
576  return retval;
577  }
578 
579  retval = rtos_put_gdb_reg(connection, reg_value, reg_size);
580 
581  free(reg_value);
582  return retval;
583  }
584 
586  current_threadid,
587  &reg_list,
588  &num_regs);
589  if (retval != ERROR_OK) {
590  LOG_ERROR("RTOS: failed to get register list");
591  return retval;
592  }
593 
594  for (int i = 0; i < num_regs; ++i) {
595  if (reg_list[i].number == (uint32_t)reg_num) {
596  rtos_put_gdb_reg_list(connection, reg_list + i, 1);
597  free(reg_list);
598  return ERROR_OK;
599  }
600  }
601 
602  free(reg_list);
603  }
604  return ERROR_NOT_IMPLEMENTED;
605 }
606 
609 {
611  int64_t current_threadid = target->rtos->current_threadid;
612  if ((target->rtos) && (current_threadid != -1) &&
613  (current_threadid != 0) &&
614  ((current_threadid != target->rtos->current_thread) ||
615  (target->smp))) { /* in smp several current thread are possible */
616  struct rtos_reg *reg_list;
617  int num_regs;
618 
619  LOG_DEBUG("RTOS: getting register list for thread 0x%" PRIx64
620  ", target->rtos->current_thread=0x%" PRIx64 "\r\n",
621  current_threadid,
623 
624  int retval = target->rtos->type->get_thread_reg_list(target->rtos,
625  current_threadid,
626  &reg_list,
627  &num_regs);
628  if (retval != ERROR_OK) {
629  LOG_ERROR("RTOS: failed to get register list");
630  return retval;
631  }
632 
633  rtos_put_gdb_reg_list(connection, reg_list, num_regs);
634  free(reg_list);
635 
636  return ERROR_OK;
637  }
638  return ERROR_FAIL;
639 }
640 
641 int rtos_set_reg(struct connection *connection, int reg_num,
642  uint8_t *reg_value)
643 {
645  int64_t current_threadid = target->rtos->current_threadid;
646  if ((target->rtos) &&
647  (target->rtos->type->set_reg) &&
648  (current_threadid != -1) &&
649  (current_threadid != 0)) {
650  return target->rtos->type->set_reg(target->rtos, reg_num, reg_value);
651  }
652  return ERROR_FAIL;
653 }
654 
656  const struct rtos_register_stacking *stacking,
657  int64_t stack_ptr,
658  struct rtos_reg **reg_list,
659  int *num_regs)
660 {
661  int retval;
662 
663  if (stack_ptr == 0) {
664  LOG_ERROR("null stack pointer in thread");
665  return -5;
666  }
667  /* Read the stack */
668  uint8_t *stack_data = malloc(stacking->stack_registers_size);
669  uint32_t address = stack_ptr;
670 
671  if (stacking->stack_growth_direction == 1)
672  address -= stacking->stack_registers_size;
673  if (stacking->read_stack)
674  retval = stacking->read_stack(target, address, stacking, stack_data);
675  else
676  retval = target_read_buffer(target, address, stacking->stack_registers_size, stack_data);
677  if (retval != ERROR_OK) {
678  free(stack_data);
679  LOG_ERROR("Error reading stack frame from thread");
680  return retval;
681  }
682  LOG_DEBUG("RTOS: Read stack frame at 0x%" PRIx32, address);
683 
684 #if 0
685  LOG_OUTPUT("Stack Data :");
686  for (i = 0; i < stacking->stack_registers_size; i++)
687  LOG_OUTPUT("%02X", stack_data[i]);
688  LOG_OUTPUT("\r\n");
689 #endif
690 
691  target_addr_t new_stack_ptr;
692  if (stacking->calculate_process_stack) {
693  new_stack_ptr = stacking->calculate_process_stack(target,
694  stack_data, stacking, stack_ptr);
695  } else {
696  new_stack_ptr = stack_ptr - stacking->stack_growth_direction *
697  stacking->stack_registers_size;
698  }
699 
700  *reg_list = calloc(stacking->num_output_registers, sizeof(struct rtos_reg));
701  *num_regs = stacking->num_output_registers;
702 
703  for (int i = 0; i < stacking->num_output_registers; ++i) {
704  (*reg_list)[i].number = stacking->register_offsets[i].number;
705  (*reg_list)[i].size = stacking->register_offsets[i].width_bits;
706 
707  int offset = stacking->register_offsets[i].offset;
708  if (offset == -2)
709  buf_cpy(&new_stack_ptr, (*reg_list)[i].value, (*reg_list)[i].size);
710  else if (offset != -1)
711  buf_cpy(stack_data + offset, (*reg_list)[i].value, (*reg_list)[i].size);
712  }
713 
714  free(stack_data);
715 /* LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list); */
716  return ERROR_OK;
717 }
718 
720 {
721  if (target->rtos && target->rtos->type)
722  return target->rtos;
723 
724  struct target_list *pos;
726  if (pos->target->rtos && pos->target->rtos->type)
727  return pos->target->rtos;
728 
729  return NULL;
730 }
731 
733 {
734  struct rtos *rtos = rtos_from_target(target);
735  if (rtos)
737  return ERROR_OK;
738 }
739 
741 {
742  if (rtos->thread_details) {
743  int j;
744 
745  for (j = 0; j < rtos->thread_count; j++) {
747  free(current_thread->thread_name_str);
748  free(current_thread->extra_info_str);
749  }
750  free(rtos->thread_details);
752  rtos->thread_count = 0;
753  rtos->current_threadid = -1;
754  rtos->current_thread = 0;
755  }
756 }
757 
759  uint32_t size, uint8_t *buffer)
760 {
761  if (target->rtos->type->read_buffer)
763  return ERROR_NOT_IMPLEMENTED;
764 }
765 
767  uint32_t size, const uint8_t *buffer)
768 {
769  if (target->rtos->type->write_buffer)
771  return ERROR_NOT_IMPLEMENTED;
772 }
773 
774 bool rtos_needs_fake_step(struct target *target, int64_t thread_id)
775 {
777  return target->rtos->type->needs_fake_step(target, thread_id);
778  return target->rtos->current_thread != thread_id;
779 }
780 
782  uint32_t length, enum breakpoint_type type)
783 {
784  if (target->rtos->type->swbp_target)
786  return target;
787 }
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
size_t unhexify(uint8_t *bin, const char *hex, size_t count)
Convert a string of hexadecimal pairs into its binary representation.
Definition: binarybuffer.c:342
Support functions to access arbitrary bits in a byte array.
breakpoint_type
Definition: breakpoints.h:17
const struct rtos_type chibios_rtos
Definition: chibios.c:99
const struct rtos_type chromium_ec_rtos
Definition: chromium-ec.c:383
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:371
#define ERROR_COMMAND_ARGUMENT_INVALID
Definition: command.h:402
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
const struct rtos_type ecos_rtos
Definition: ecos.c:455
const struct rtos_type embkernel_rtos
Definition: embkernel.c:29
enum esirisc_reg_num number
Definition: esirisc.c:87
uint8_t type
Definition: esp_usb_jtag.c:0
uint8_t length
Definition: esp_usb_jtag.c:1
const struct rtos_type freertos_rtos
Definition: freertos.c:82
int gdb_put_packet(struct connection *connection, const char *buffer, int len)
Definition: gdb_server.c:554
#define GDB_BUFFER_SIZE
Definition: gdb_server.h:25
static struct target * get_target_from_connection(struct connection *connection)
Definition: gdb_server.h:35
const struct rtos_type hwthread_rtos
Definition: hwthread.c:53
const struct rtos_type linux_rtos
Definition: linux.c:250
char * alloc_printf(const char *format,...)
Definition: log.c:378
#define ERROR_NOT_IMPLEMENTED
Definition: log.h:179
#define LOG_OUTPUT(expr ...)
Definition: log.h:143
#define LOG_WARNING(expr ...)
Definition: log.h:131
#define ERROR_FAIL
Definition: log.h:175
#define LOG_ERROR(expr ...)
Definition: log.h:134
#define LOG_INFO(expr ...)
Definition: log.h:128
#define LOG_DEBUG(expr ...)
Definition: log.h:111
#define ERROR_OK
Definition: log.h:169
const struct rtos_type mqx_rtos
Definition: mqx.c:499
const struct rtos_type nuttx_rtos
Definition: nuttx.c:396
const struct rtos_type riot_rtos
Definition: riot.c:97
const struct rtos_type rtkernel_rtos
Definition: rtkernel.c:375
static int rtos_target_for_threadid(struct connection *connection, int64_t threadid, struct target **t)
Definition: rtos.c:47
int rtos_generic_stack_read(struct target *target, const struct rtos_register_stacking *stacking, int64_t stack_ptr, struct rtos_reg **reg_list, int *num_regs)
Definition: rtos.c:655
struct target * rtos_swbp_target(struct target *target, target_addr_t address, uint32_t length, enum breakpoint_type type)
Definition: rtos.c:781
static const struct rtos_type * rtos_types[]
Definition: rtos.c:20
static int os_alloc_create(struct target *target, const struct rtos_type *ostype)
Definition: rtos.c:87
int rtos_thread_packet(struct connection *connection, char const *packet, int packet_size)
Definition: rtos.c:355
int gdb_thread_packet(struct connection *connection, char const *packet, int packet_size)
Definition: rtos.c:150
static struct symbol_table_elem * find_symbol(const struct rtos *os, const char *symbol)
Definition: rtos.c:182
static int os_alloc(struct target *target, const struct rtos_type *ostype)
Definition: rtos.c:56
int rtos_create(struct command_invocation *cmd, struct target *target, const char *rtos_name)
Definition: rtos.c:100
static void os_free(struct target *target)
Definition: rtos.c:76
int rtos_set_reg(struct connection *connection, int reg_num, uint8_t *reg_value)
Definition: rtos.c:641
int rtos_get_gdb_reg_list(struct connection *connection)
Return a list of general registers.
Definition: rtos.c:608
void rtos_destroy(struct target *target)
Definition: rtos.c:145
static int rtos_put_gdb_reg(struct connection *connection, uint8_t *reg_value, unsigned int reg_size)
Definition: rtos.c:507
static int rtos_put_gdb_reg_list(struct connection *connection, struct rtos_reg *reg_list, int num_regs)
Definition: rtos.c:527
static bool rtos_try_next(struct target *target)
Definition: rtos.c:159
int rtos_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: rtos.c:766
static struct symbol_table_elem * next_symbol(struct rtos *os, char *cur_symbol, uint64_t cur_addr)
Definition: rtos.c:193
int rtos_update_threads(struct target *target)
Definition: rtos.c:732
int rtos_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
Definition: rtos.c:758
int rtos_smp_init(struct target *target)
Definition: rtos.c:40
bool rtos_needs_fake_step(struct target *target, int64_t thread_id)
Definition: rtos.c:774
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
Definition: rtos.c:235
void rtos_free_threadlist(struct rtos *rtos)
Definition: rtos.c:740
struct rtos * rtos_from_target(struct target *target)
Get the RTOS from the target itself, or from one of the targets in the same SMP node,...
Definition: rtos.c:719
int rtos_get_gdb_reg(struct connection *connection, int reg_num)
Look through all registers to find this register.
Definition: rtos.c:551
#define GDB_THREAD_PACKET_NOT_CONSUMED
Definition: rtos.h:129
const struct rtos_type zephyr_rtos
Definition: zephyr.c:788
const struct rtos_type threadx_rtos
Definition: threadx.c:193
int64_t threadid_t
Definition: rtos.h:15
const struct rtos_type ucos_iii_rtos
Definition: ucos_iii.c:501
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
struct target * target
Definition: rtt/rtt.c:26
#define foreach_smp_target(pos, head)
Definition: smp.h:15
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
Definition: rtos.h:53
const struct stack_register_offset * register_offsets
Definition: rtos.h:119
unsigned char num_output_registers
Definition: rtos.h:109
target_addr_t(* calculate_process_stack)(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr)
Definition: rtos.h:115
unsigned char stack_registers_size
Definition: rtos.h:107
int(* read_stack)(struct target *target, int64_t stack_ptr, const struct rtos_register_stacking *stacking, uint8_t *stack_data)
Definition: rtos.h:123
signed char stack_growth_direction
Definition: rtos.h:108
Definition: rtos.h:59
int(* create)(struct target *target)
Definition: rtos.h:62
bool(* needs_fake_step)(struct target *target, int64_t thread_id)
Possibly work around an annoying gdb behaviour: when the current thread is changed in gdb,...
Definition: rtos.h:89
int(* get_thread_reg_value)(struct rtos *rtos, threadid_t thread_id, uint32_t reg_num, uint32_t *size, uint8_t **value)
Return the size and value of the specified reg_num.
Definition: rtos.h:70
int(* smp_init)(struct target *target)
Definition: rtos.h:63
int(* update_threads)(struct rtos *rtos)
Definition: rtos.h:64
int(* get_symbol_list_to_lookup)(struct symbol_table_elem *symbol_list[])
Definition: rtos.h:72
struct target *(* swbp_target)(struct rtos *rtos, target_addr_t address, uint32_t length, enum breakpoint_type type)
Definition: rtos.h:94
const char * name
Definition: rtos.h:60
int(* write_buffer)(struct rtos *rtos, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: rtos.h:81
int(* read_buffer)(struct rtos *rtos, target_addr_t address, uint32_t size, uint8_t *buffer)
Definition: rtos.h:79
bool(* detect_rtos)(struct target *target)
Definition: rtos.h:61
int(* get_thread_reg_list)(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs)
Return a list of general registers, with their values filled out.
Definition: rtos.h:66
int(* set_reg)(struct rtos *rtos, uint32_t reg_num, uint8_t *reg_value)
Definition: rtos.h:75
Definition: rtos.h:36
const struct rtos_type * type
Definition: rtos.h:37
int thread_count
Definition: rtos.h:47
int(* gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size)
Definition: rtos.h:48
struct thread_detail * thread_details
Definition: rtos.h:46
struct symbol_table_elem * symbols
Definition: rtos.h:39
struct target * target
Definition: rtos.h:40
int(* gdb_target_for_threadid)(struct connection *connection, int64_t thread_id, struct target **p_target)
Definition: rtos.h:49
threadid_t current_thread
Definition: rtos.h:45
int64_t current_threadid
Definition: rtos.h:43
unsigned short width_bits
Definition: rtos.h:103
unsigned short number
Definition: rtos.h:99
signed short offset
Definition: rtos.h:100
Table should be terminated by an element with NULL in symbol_name.
Definition: rtos.h:23
symbol_address_t address
Definition: rtos.h:25
bool optional
Definition: rtos.h:26
const char * symbol_name
Definition: rtos.h:24
struct target * target
Definition: target.h:217
Definition: target.h:119
struct list_head * smp_targets
Definition: target.h:191
struct rtos * rtos
Definition: target.h:186
bool rtos_auto_detect
Definition: target.h:187
unsigned int smp
Definition: target.h:190
char * extra_info_str
Definition: rtos.h:33
char * thread_name_str
Definition: rtos.h:32
bool exists
Definition: rtos.h:31
threadid_t threadid
Definition: rtos.h:30
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
Definition: target.c:2416
#define ERROR_TARGET_INIT_FAILED
Definition: target.h:784
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
#define DIV_ROUND_UP(m, n)
Rounds m up to the nearest multiple of n using division.
Definition: types.h:79
uint64_t target_addr_t
Definition: types.h:279
#define NULL
Definition: usb.h:16
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22