98 const char *rtos_name)
103 if (strcmp(rtos_name,
"none") == 0)
106 if (strcmp(rtos_name,
"auto") == 0) {
234 int rtos_detected = 0;
242 reply_len = sprintf(reply,
"OK");
248 size_t len =
unhexify((uint8_t *)cur_sym, strchr(packet + 8,
':') + 1, strlen(strchr(packet + 8,
':') + 1));
251 const char no_suffix[] =
"";
252 const char lto_suffix[] =
".lto_priv.0";
253 const size_t lto_suffix_len = strlen(lto_suffix);
255 const char *cur_suffix;
256 const char *next_suffix;
260 if (len > lto_suffix_len && !strcmp(cur_sym + len - lto_suffix_len, lto_suffix)) {
262 cur_sym[len - lto_suffix_len] =
'\0';
263 cur_suffix = lto_suffix;
266 cur_suffix = no_suffix;
267 next_suffix = lto_suffix;
270 if ((strcmp(packet,
"qSymbol::") != 0) &&
271 (!sscanf(packet,
"qSymbol:%" SCNx64
":", &
addr))) {
280 LOG_WARNING(
"RTOS %s not detected. (GDB could not find symbol \'%s\')", os->
type->
name, cur_sym);
295 LOG_DEBUG(
"RTOS: Address of symbol '%s%s' is 0x%" PRIx64, cur_sym, cur_suffix,
addr);
299 next_suffix = no_suffix;
304 LOG_WARNING(
"RTOS: Debugger sent us qSymbol with '%s%s' that we did not ask for", cur_sym, cur_suffix);
330 reply_len += 2 * strlen(next_suffix);
332 if (reply_len >
sizeof(reply)) {
337 LOG_DEBUG(
"RTOS: Requesting symbol lookup of '%s%s' from the debugger", next_sym->
symbol_name, next_suffix);
339 reply_len = snprintf(reply,
sizeof(reply),
"qSymbol:");
340 reply_len +=
hexify(reply + reply_len,
342 sizeof(reply) - reply_len);
343 reply_len +=
hexify(reply + reply_len,
344 (
const uint8_t *)next_suffix, strlen(next_suffix),
345 sizeof(reply) - reply_len);
349 return rtos_detected;
356 if (strncmp(packet,
"qThreadExtraInfo,", 17) == 0) {
361 sscanf(packet,
"qThreadExtraInfo,%" SCNx64, &threadid);
385 char *tmp_str = calloc(str_size + 9,
sizeof(
char));
390 char *tmp_str_ptr = tmp_str;
393 tmp_str_ptr += sprintf(tmp_str_ptr,
"Name: %s", detail->
thread_name_str);
395 if (tmp_str_ptr != tmp_str)
396 tmp_str_ptr += sprintf(tmp_str_ptr,
", ");
397 tmp_str_ptr += sprintf(tmp_str_ptr,
"%s", detail->
extra_info_str);
400 assert(strlen(tmp_str) ==
401 (
size_t) (tmp_str_ptr - tmp_str));
403 char *hex_str = malloc(strlen(tmp_str) * 2 + 1);
404 size_t pkt_len =
hexify(hex_str, (
const uint8_t *)tmp_str,
405 strlen(tmp_str), strlen(tmp_str) * 2 + 1);
415 }
else if (strncmp(packet,
"qSymbol", 7) == 0) {
424 }
else if (strncmp(packet,
"qfThreadInfo", 12) == 0) {
432 char *tmp_str = out_str;
434 tmp_str += sprintf(tmp_str,
"%c%016" PRIx64, i == 0 ?
'm' :
',',
444 }
else if (strncmp(packet,
"qsThreadInfo", 12) == 0) {
447 }
else if (strncmp(packet,
"qAttached", 9) == 0) {
450 }
else if (strncmp(packet,
"qOffsets", 8) == 0) {
451 char offsets[] =
"Text=0;Data=0;Bss=0";
454 }
else if (strncmp(packet,
"qCRC:", 5) == 0) {
458 }
else if (strncmp(packet,
"qC", 2) == 0) {
467 }
else if (packet[0] ==
'T') {
470 sscanf(packet,
"T%" SCNx64, &
threadid);
485 }
else if (packet[0] ==
'H') {
489 sscanf(packet,
"Hg%16" SCNx64, &
threadid);
505 struct rtos_reg *reg_list,
int num_regs)
507 size_t num_bytes = 1;
508 for (
int i = 0; i < num_regs; ++i)
511 char *hex = malloc(num_bytes);
514 for (
int i = 0; i < num_regs; ++i) {
516 size_t n =
hexify(hex_p, reg_list[i].value,
count, num_bytes);
532 if ((
target->
rtos) && (current_threadid != -1) &&
533 (current_threadid != 0) &&
539 LOG_DEBUG(
"getting register %d for thread 0x%" PRIx64
540 ", target->rtos->current_thread=0x%" PRIx64,
547 reg_list = calloc(1,
sizeof(*reg_list));
550 current_threadid, reg_num, ®_list[0]);
552 LOG_ERROR(
"RTOS: failed to get register %d", reg_num);
561 LOG_ERROR(
"RTOS: failed to get register list");
566 for (
int i = 0; i < num_regs; ++i) {
567 if (reg_list[i].
number == (uint32_t)reg_num) {
584 if ((
target->
rtos) && (current_threadid != -1) &&
585 (current_threadid != 0) &&
591 LOG_DEBUG(
"RTOS: getting register list for thread 0x%" PRIx64
592 ", target->rtos->current_thread=0x%" PRIx64
"\r\n",
601 LOG_ERROR(
"RTOS: failed to get register list");
620 (current_threadid != -1) &&
621 (current_threadid != 0)) {
635 if (stack_ptr == 0) {
636 LOG_ERROR(
"null stack pointer in thread");
651 LOG_ERROR(
"Error reading stack frame from thread");
666 stack_data, stacking, stack_ptr);
681 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.