67 #define ECOS_MAX_THREAD_COUNT (4095)
160 .thread_stack_offset = 0x0c,
161 .thread_name_offset = 0x9c,
162 .thread_state_offset = 0x3c,
163 .thread_next_offset = 0xa0,
164 .thread_uniqueid_offset = 0x4c,
166 .stacking_info =
NULL
173 .thread_stack_offset = 0,
174 .thread_name_offset = 0,
175 .thread_state_offset = 0,
176 .thread_next_offset = 0,
177 .thread_uniqueid_offset = 0,
179 .stacking_info =
NULL
183 #define ECOS_NUM_PARAMS ARRAY_SIZE(ecos_params_list)
230 #define ECOS_CORTEXM_BASE_NUMREGS (ARMV7M_NUM_CORE_REGS)
295 .stack_growth_direction = -1,
296 .num_output_registers = 0,
297 .calculate_process_stack =
NULL,
298 .register_offsets =
NULL
375 #define ECOSSYM(_n, _o, _t) { .name = _n, .optional = (_o), .target_names = _t }
383 ECOSSYM(
"Cyg_Scheduler_Base::current_thread",
false,
NULL),
388 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.list_next",
true,
NULL),
389 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.list_next",
true,
NULL),
390 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.state",
true,
NULL),
391 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.state",
true,
NULL),
392 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.sleep_reason",
true,
NULL),
393 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.sleep_reason",
true,
NULL),
394 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.wake_reason",
true,
NULL),
395 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.wake_reason",
true,
NULL),
396 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.unique_id",
true,
NULL),
397 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.unique_id",
true,
NULL),
398 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.name",
true,
NULL),
399 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.name",
true,
NULL),
400 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.priority",
true,
NULL),
401 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.priority",
true,
NULL),
402 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.stack_ptr",
true,
NULL),
403 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.stack_ptr",
true,
NULL),
473 LOG_ERROR(
"eCos: Invalid symbol index %u", idx);
477 #define XMLENTRY(_c, _s) { .xc = (_c), .rs = (_s), .rlen = (sizeof(_s) - 1) }
479 static const struct {
494 static const char *tokens =
"<&>\'\"";
495 bool escaped =
false;
500 (void)memset(out,
'\0', limit);
502 while (raw && *raw && limit) {
503 size_t lok = strcspn(raw, tokens);
506 tocopy = ((limit < lok) ? limit : lok);
507 (void)memcpy(out, raw, tocopy);
514 char *fidx = strchr(tokens, *raw);
518 LOG_ERROR(
"eCos: Unexpected XML char %c", *raw);
522 uint32_t cidx = (fidx - tokens);
523 size_t tocopy =
xmlchars[cidx].rlen;
545 LOG_DEBUG(
"eCos: %s 0x%016" PRIX64
" %s",
555 if (thread_next_size != 0) {
566 if (param->
uid_width !=
sizeof(uint16_t)) {
570 param->
uid_width = (
unsigned char)
sizeof(uint16_t);
709 int thread_list_size = 0;
737 LOG_ERROR(
"Don't have the thread list head");
743 uint32_t thread_index;
747 (uint8_t *) &thread_index);
748 uint32_t first_thread = thread_index;
768 thread_list_size = 0;
774 (uint8_t *)&thread_index);
777 }
while (thread_index != first_thread);
783 uint32_t current_thread_addr;
787 (uint8_t *)¤t_thread_addr);
789 LOG_ERROR(
"Reading active thread address");
793 if (current_thread_addr) {
800 LOG_ERROR(
"Could not read eCos current thread from target");
810 static const char tmp_str[] =
"Current Execution";
824 if (thread_list_size == 1) {
835 thread_index = first_thread;
837 #define ECOS_THREAD_NAME_STR_SIZE (200)
839 uint32_t name_ptr = 0;
840 uint32_t prev_thread_ptr;
845 uint16_t thread_id = 0;
849 (uint8_t *)&thread_id);
851 LOG_ERROR(
"Could not read eCos thread id from target");
860 (uint8_t *)&name_ptr);
862 LOG_ERROR(
"Could not read eCos thread name pointer from target");
871 (uint8_t *)&tmp_str);
873 LOG_ERROR(
"Error reading thread name from eCos target");
885 if (tmp_str[0] ==
'\x00') {
896 strcpy(tmp_str, esc_str);
900 malloc(strlen(tmp_str)+1);
904 int64_t thread_status = 0;
908 (uint8_t *)&thread_status);
910 LOG_ERROR(
"Error reading thread state from eCos target");
918 strcpy(state_desc,
"suspended+");
920 state_desc[0] =
'\0';
924 if (thread_index == current_thread_addr)
925 strcat(state_desc,
"running");
927 state_desc[9] =
'\0';
929 strcat(state_desc,
"ready");
932 strcat(state_desc,
"sleeping");
936 strcat(state_desc,
"counted sleep");
939 strcpy(state_desc,
"creating");
942 strcpy(state_desc,
"exited");
945 strcpy(state_desc,
"unknown state");
952 int64_t sleep_reason = 0;
954 if (thread_index != current_thread_addr &&
959 (uint8_t *)&sleep_reason);
961 LOG_ERROR(
"Error reading thread sleep reason from eCos target");
964 if (sleep_reason < 0 ||
972 const char *reason_desc =
NULL;
976 tr_extra = 2 + strlen(reason_desc) + 1;
979 int64_t priority = 0;
980 size_t pri_extra = 0;
985 (uint8_t *)&priority);
987 LOG_ERROR(
"Error reading thread priority from eCos target");
990 pri_extra = (12 + 20);
993 size_t eilen = (8 + strlen(state_desc) + tr_extra + pri_extra);
994 char *eistr = malloc(eilen);
1000 LOG_ERROR(
"OOM allocating extra information buffer");
1004 int soff = snprintf(eistr, eilen,
"State: %s", state_desc);
1005 if (tr_extra && reason_desc)
1006 soff += snprintf(&eistr[soff], (eilen - soff),
" (%s)", reason_desc);
1008 (void)snprintf(&eistr[soff], (eilen - soff),
", Priority: %" PRId64
"", priority);
1014 prev_thread_ptr = thread_index;
1021 (uint8_t *) &thread_index);
1023 LOG_ERROR(
"Error reading next thread pointer in eCos thread list");
1026 }
while (thread_index != first_thread);
1033 struct rtos_reg **reg_list,
int *num_regs)
1067 uint32_t thread_index;
1069 (uint8_t *)&thread_index);
1077 LOG_ERROR(
"Error reading unique id from eCos thread 0x%08" PRIX32
"", thread_index);
1081 if (
id == thread_id) {
1088 (uint8_t *) &thread_index);
1093 int64_t stack_ptr = 0;
1097 (uint8_t *)&stack_ptr);
1099 LOG_ERROR(
"Error reading stack frame from eCos thread");
1104 LOG_ERROR(
"NULL stack pointer in thread %" PRIu64, thread_id);
1112 LOG_ERROR(
"Error reading stack layout for eCos thread");
1136 *symbol_list = calloc(
1167 const char *packet,
int packet_size)
1169 int64_t current_threadid;
1171 if (packet[0] ==
'H' && packet[1] ==
'g') {
1172 int numscan = sscanf(packet,
"Hg%16" SCNx64, ¤t_threadid);
1173 if (numscan == 1 && current_threadid == 0) {
1223 LOG_ERROR(
"Could not find target in eCos compatibility list");
static const char *const target_cortex_m[]
@ ECOS_VAL_CORTEXM_CTX_S_OFF
@ ECOS_VAL_CORTEXM_CTX_TYPE_OFF
@ ECOS_VAL_ARM_CTX_R2_OFF
@ ECOS_VAL_COMMON_THREAD_ID_SIZE
@ ECOS_VAL_COMMON_THREAD_SLEEP_SIZE
@ ECOS_VAL_COMMON_THREAD_NEXT_SIZE
@ ECOS_VAL_ARM_CTX_R6_OFF
@ ECOS_VAL_CORTEXM_CTX_REG_OFF
@ ECOS_VAL_CORTEXM_THREAD_SAVED
@ ECOS_VAL_ARM_CTX_LR_OFF
@ ECOS_VAL_ARM_CTX_R4_OFF
@ ECOS_VAL_ARM_CTX_R5_OFF
@ ECOS_VAL_ARM_CTX_VFPVEC_OFF
@ ECOS_VAL_COMMON_THREAD_STATE_SIZE
@ ECOS_VAL_CORTEXM_VAL_THREAD
@ ECOS_VAL_ARM_CTX_R10_OFF
@ ECOS_VAL_COMMON_THREAD_WAKE_OFF
@ ECOS_VAL_COMMON_THREAD_ID_OFF
@ ECOS_VAL_CORTEXM_CTX_S_SIZE
@ ECOS_VAL_ARM_CTX_R3_OFF
@ ECOS_VAL_CORTEXM_CTX_SP_SIZE
@ ECOS_VAL_ARM_CTX_IP_OFF
@ ECOS_VAL_CORTEXM_VAL_INTERRUPT
@ ECOS_VAL_ARM_CTX_FPSCR_OFF
@ ECOS_VAL_CORTEXM_CTX_FPSCR_OFF
@ ECOS_VAL_ARM_CTX_SP_OFF
@ ECOS_VAL_CORTEXM_CTX_THREAD_SIZE
@ ECOS_VAL_ARM_CTX_R8_OFF
@ ECOS_VAL_COMMON_THREAD_STACK_SIZE
@ ECOS_VAL_ARM_CTX_R0_OFF
@ ECOS_VAL_CORTEXM_VAL_EXCEPTION
@ ECOS_VAL_COMMON_THREAD_STACK_OFF
@ ECOS_VAL_COMMON_THREAD_PRI_OFF
@ ECOS_VAL_ARM_CTX_R1_OFF
@ ECOS_VAL_ARM_CTX_R9_OFF
@ ECOS_VAL_ARM_CTX_R7_OFF
@ ECOS_VAL_COMMON_THREAD_SLEEP_OFF
@ ECOS_VAL_CORTEXM_CTX_FPSCR_SIZE
@ ECOS_VAL_CORTEXM_CTX_REG_SIZE
@ ECOS_VAL_COMMON_THREAD_PRI_SIZE
@ ECOS_VAL_CORTEXM_CTX_SP_OFF
@ ECOS_VAL_CORTEXM_CTX_PC_OFF
@ ECOS_VAL_ARM_CTX_SVEC_OFF
@ ECOS_VAL_ARM_CTX_FP_OFF
@ ECOS_VAL_CORTEXM_CTX_TYPE_SIZE
@ ECOS_VAL_CURRENT_THREAD_PTR
@ ECOS_VAL_CORTEXM_CTX_PC_SIZE
@ ECOS_VAL_COMMON_THREAD_NEXT_OFF
@ ECOS_VAL_CORTEXM_CTX_BASEPRI_OFF
@ ECOS_VAL_ARM_CTX_CPSR_OFF
@ ECOS_VAL_COMMON_THREAD_NAME_SIZE
@ ECOS_VAL_ARM_CTX_PC_OFF
@ ECOS_VAL_CORTEXM_CTX_BASEPRI_SIZE
@ ECOS_VAL_COMMON_THREAD_NAME_OFF
@ ECOS_VAL_CORTEXM_VAL_FPU
@ ECOS_VAL_COMMON_THREAD_WAKE_SIZE
@ ECOS_VAL_COMMON_THREAD_STATE_OFF
static bool ecos_escape_string(const char *raw, char *out, size_t limit)
Escape any XML reserved characters in a string.
static int ecos_stack_layout_cortexm(struct rtos *rtos, struct ecos_params *param, int64_t stack_ptr, const struct rtos_register_stacking **si)
#define ECOSSYM(_n, _o, _t)
static symbol_address_t ecos_value(struct rtos *rtos, unsigned int idx)
static struct stack_register_offset rtos_ecos_regoff_cortexm[]
static bool ecos_detect_rtos(struct target *target)
static int ecos_update_threads(struct rtos *rtos)
static struct rtos_register_stacking rtos_ecos_stacking
#define ECOS_THREAD_NAME_STR_SIZE
const struct rtos_type ecos_rtos
static const struct @53 xmlchars[]
static int ecos_check_app_info(struct rtos *rtos, struct ecos_params *param)
#define ECOS_CORTEXM_BASE_NUMREGS
#define ECOS_MAX_THREAD_COUNT
static const struct ecos_thread_state ecos_thread_reasons[]
static struct stack_register_offset rtos_ecos_regoff_arm[]
static int ecos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])
static int ecos_create(struct target *target)
static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs)
static struct ecos_params ecos_params_list[]
static int ecos_packet_hook(struct connection *connection, const char *packet, int packet_size)
static const struct symbols ecos_symbol_list[]
static int ecos_stack_layout_arm(struct rtos *rtos, struct ecos_params *param, int64_t stack_ptr, const struct rtos_register_stacking **si)
static const char *const target_arm[]
static struct target * get_target_from_connection(struct connection *connection)
The JTAG interface can be implemented with a software or hardware fifo.
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_DEBUG(expr ...)
static const struct rtos_register_stacking * stacking_info
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)
int rtos_thread_packet(struct connection *connection, char const *packet, int packet_size)
void rtos_free_threadlist(struct rtos *rtos)
const struct rtos_register_stacking rtos_ecos_cortex_m3_stacking
target_addr_t rtos_generic_stack_align8(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr)
unsigned char state_width
unsigned int thread_stack_offset
unsigned int thread_next_offset
int(* target_stack_layout)(struct rtos *rtos, struct ecos_params *param, int64_t stack_ptr, const struct rtos_register_stacking **si)
unsigned int thread_name_offset
const char *const * target_names
const struct rtos_register_stacking * stacking_info
unsigned char pointer_width
unsigned int thread_state_offset
unsigned int thread_uniqueid_offset
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(* gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size)
struct thread_detail * thread_details
struct symbol_table_elem * symbols
void * rtos_specific_params
threadid_t current_thread
Table should be terminated by an element with NULL in symbol_name.
const char *const * target_names
const char * name
Name of this type of target.
struct target_type * type
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.