100 const char *rtos_name)
105 if (strcmp(rtos_name,
"none") == 0)
108 if (strcmp(rtos_name,
"auto") == 0) {
236 int rtos_detected = 0;
244 reply_len = sprintf(reply,
"OK");
250 size_t len =
unhexify((uint8_t *)cur_sym, strchr(packet + 8,
':') + 1, strlen(strchr(packet + 8,
':') + 1));
253 const char no_suffix[] =
"";
254 const char lto_suffix[] =
".lto_priv.0";
255 const size_t lto_suffix_len = strlen(lto_suffix);
257 const char *cur_suffix;
258 const char *next_suffix;
262 if (len > lto_suffix_len && !strcmp(cur_sym + len - lto_suffix_len, lto_suffix)) {
264 cur_sym[len - lto_suffix_len] =
'\0';
265 cur_suffix = lto_suffix;
268 cur_suffix = no_suffix;
269 next_suffix = lto_suffix;
272 if ((strcmp(packet,
"qSymbol::") != 0) &&
273 (!sscanf(packet,
"qSymbol:%" SCNx64
":", &
addr))) {
282 LOG_WARNING(
"RTOS %s not detected. (GDB could not find symbol \'%s\')", os->
type->
name, cur_sym);
297 LOG_DEBUG(
"RTOS: Address of symbol '%s%s' is 0x%" PRIx64, cur_sym, cur_suffix,
addr);
301 next_suffix = no_suffix;
306 LOG_WARNING(
"RTOS: Debugger sent us qSymbol with '%s%s' that we did not ask for", cur_sym, cur_suffix);
332 reply_len += 2 * strlen(next_suffix);
334 if (reply_len >
sizeof(reply)) {
339 LOG_DEBUG(
"RTOS: Requesting symbol lookup of '%s%s' from the debugger", next_sym->
symbol_name, next_suffix);
341 reply_len = snprintf(reply,
sizeof(reply),
"qSymbol:");
342 reply_len +=
hexify(reply + reply_len,
344 sizeof(reply) - reply_len);
345 reply_len +=
hexify(reply + reply_len,
346 (
const uint8_t *)next_suffix, strlen(next_suffix),
347 sizeof(reply) - reply_len);
351 return rtos_detected;
358 if (strncmp(packet,
"qThreadExtraInfo,", 17) == 0) {
363 sscanf(packet,
"qThreadExtraInfo,%" SCNx64, &threadid);
387 char *tmp_str = calloc(str_size + 9,
sizeof(
char));
392 char *tmp_str_ptr = tmp_str;
395 tmp_str_ptr += sprintf(tmp_str_ptr,
"Name: %s", detail->
thread_name_str);
397 if (tmp_str_ptr != tmp_str)
398 tmp_str_ptr += sprintf(tmp_str_ptr,
", ");
399 tmp_str_ptr += sprintf(tmp_str_ptr,
"%s", detail->
extra_info_str);
402 assert(strlen(tmp_str) ==
403 (
size_t) (tmp_str_ptr - tmp_str));
405 char *hex_str = malloc(strlen(tmp_str) * 2 + 1);
406 size_t pkt_len =
hexify(hex_str, (
const uint8_t *)tmp_str,
407 strlen(tmp_str), strlen(tmp_str) * 2 + 1);
417 }
else if (strncmp(packet,
"qSymbol", 7) == 0) {
426 }
else if (strncmp(packet,
"qfThreadInfo", 12) == 0) {
434 char *tmp_str = out_str;
436 tmp_str += sprintf(tmp_str,
"%c%016" PRIx64, i == 0 ?
'm' :
',',
446 }
else if (strncmp(packet,
"qsThreadInfo", 12) == 0) {
449 }
else if (strncmp(packet,
"qAttached", 9) == 0) {
452 }
else if (strncmp(packet,
"qOffsets", 8) == 0) {
453 char offsets[] =
"Text=0;Data=0;Bss=0";
456 }
else if (strncmp(packet,
"qCRC:", 5) == 0) {
460 }
else if (strncmp(packet,
"qC", 2) == 0) {
469 }
else if (packet[0] ==
'T') {
472 sscanf(packet,
"T%" SCNx64, &
threadid);
487 }
else if (packet[0] ==
'H') {
491 sscanf(packet,
"Hg%16" SCNx64, &
threadid);
507 struct rtos_reg *reg_list,
int num_regs)
509 size_t num_bytes = 1;
510 for (
int i = 0; i < num_regs; ++i)
513 char *hex = malloc(num_bytes);
516 for (
int i = 0; i < num_regs; ++i) {
518 size_t n =
hexify(hex_p, reg_list[i].value,
count, num_bytes);
534 if ((
target->
rtos) && (current_threadid != -1) &&
535 (current_threadid != 0) &&
541 LOG_DEBUG(
"getting register %d for thread 0x%" PRIx64
542 ", target->rtos->current_thread=0x%" PRIx64,
549 reg_list = calloc(1,
sizeof(*reg_list));
552 current_threadid, reg_num, ®_list[0]);
554 LOG_ERROR(
"RTOS: failed to get register %d", reg_num);
563 LOG_ERROR(
"RTOS: failed to get register list");
568 for (
int i = 0; i < num_regs; ++i) {
569 if (reg_list[i].
number == (uint32_t)reg_num) {
586 if ((
target->
rtos) && (current_threadid != -1) &&
587 (current_threadid != 0) &&
593 LOG_DEBUG(
"RTOS: getting register list for thread 0x%" PRIx64
594 ", target->rtos->current_thread=0x%" PRIx64
"\r\n",
603 LOG_ERROR(
"RTOS: failed to get register list");
622 (current_threadid != -1) &&
623 (current_threadid != 0)) {
637 if (stack_ptr == 0) {
638 LOG_ERROR(
"null stack pointer in thread");
653 LOG_ERROR(
"Error reading stack frame from thread");
668 stack_data, stacking, stack_ptr);
683 buf_cpy(&new_stack_ptr, (*reg_list)[i].value, (*reg_list)[i].
size);
void * buf_cpy(const void *from, void *_to, unsigned int size)
Copies size bits out of from and into to.
size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t length)
Convert binary data into a string of hexadecimal pairs.
size_t unhexify(uint8_t *bin, const char *hex, size_t count)
Convert a string of hexadecimal pairs into its binary representation.
Support functions to access arbitrary bits in a byte array.
const struct rtos_type chibios_rtos
const struct rtos_type chromium_ec_rtos
void command_print(struct command_invocation *cmd, const char *format,...)
#define ERROR_COMMAND_ARGUMENT_INVALID
uint64_t buffer
Pointer to data buffer to send over SPI.
uint32_t size
Size of dw_spi_transaction::buffer.
uint32_t address
Starting address. Sector aligned.
const struct rtos_type ecos_rtos
const struct rtos_type embkernel_rtos
enum esirisc_reg_num number
const struct rtos_type freertos_rtos
int gdb_put_packet(struct connection *connection, const char *buffer, int len)
static struct target * get_target_from_connection(struct connection *connection)
const struct rtos_type hwthread_rtos
const struct rtos_type linux_rtos
char * alloc_printf(const char *format,...)
#define ERROR_NOT_IMPLEMENTED
#define LOG_OUTPUT(expr ...)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
const struct rtos_type mqx_rtos
const struct rtos_type nuttx_rtos
const struct rtos_type riot_rtos
const struct rtos_type rtkernel_rtos
static int rtos_target_for_threadid(struct connection *connection, int64_t threadid, struct target **t)
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)
static const struct rtos_type * rtos_types[]
static int os_alloc_create(struct target *target, const struct rtos_type *ostype)
int rtos_thread_packet(struct connection *connection, char const *packet, int packet_size)
int gdb_thread_packet(struct connection *connection, char const *packet, int packet_size)
static struct symbol_table_elem * find_symbol(const struct rtos *os, const char *symbol)
static int os_alloc(struct target *target, const struct rtos_type *ostype)
int rtos_create(struct command_invocation *cmd, struct target *target, const char *rtos_name)
static void os_free(struct target *target)
int rtos_set_reg(struct connection *connection, int reg_num, uint8_t *reg_value)
int rtos_get_gdb_reg_list(struct connection *connection)
Return a list of general registers.
void rtos_destroy(struct target *target)
static int rtos_put_gdb_reg_list(struct connection *connection, struct rtos_reg *reg_list, int num_regs)
static bool rtos_try_next(struct target *target)
int rtos_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
static struct symbol_table_elem * next_symbol(struct rtos *os, char *cur_symbol, uint64_t cur_addr)
int rtos_update_threads(struct target *target)
int rtos_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
int rtos_smp_init(struct target *target)
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
void rtos_free_threadlist(struct rtos *rtos)
int rtos_get_gdb_reg(struct connection *connection, int reg_num)
Look through all registers to find this register.
#define GDB_THREAD_PACKET_NOT_CONSUMED
const struct rtos_type zephyr_rtos
const struct rtos_type threadx_rtos
const struct rtos_type ucos_iii_rtos
target_addr_t addr
Start address to search for the control block.
When run_command is called, a new instance will be created on the stack, filled with the proper value...
const struct stack_register_offset * register_offsets
unsigned char num_output_registers
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)
unsigned char stack_registers_size
int(* read_stack)(struct target *target, int64_t stack_ptr, const struct rtos_register_stacking *stacking, uint8_t *stack_data)
signed char stack_growth_direction
int(* create)(struct target *target)
int(* smp_init)(struct target *target)
int(* update_threads)(struct rtos *rtos)
int(* get_thread_reg)(struct rtos *rtos, int64_t thread_id, uint32_t reg_num, struct rtos_reg *reg)
int(* get_symbol_list_to_lookup)(struct symbol_table_elem *symbol_list[])
int(* write_buffer)(struct rtos *rtos, target_addr_t address, uint32_t size, const uint8_t *buffer)
int(* read_buffer)(struct rtos *rtos, target_addr_t address, uint32_t size, uint8_t *buffer)
bool(* detect_rtos)(struct target *target)
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.
int(* set_reg)(struct rtos *rtos, uint32_t reg_num, uint8_t *reg_value)
const struct rtos_type * type
int(* gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size)
struct thread_detail * thread_details
struct symbol_table_elem * symbols
int(* gdb_target_for_threadid)(struct connection *connection, int64_t thread_id, struct target **p_target)
threadid_t current_thread
unsigned short width_bits
Table should be terminated by an element with NULL in symbol_name.
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
#define ERROR_TARGET_INIT_FAILED
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
#define DIV_ROUND_UP(m, n)
Rounds m up to the nearest multiple of n using division.