66 #define ECOS_MAX_THREAD_COUNT (4095)
159 .thread_stack_offset = 0x0c,
160 .thread_name_offset = 0x9c,
161 .thread_state_offset = 0x3c,
162 .thread_next_offset = 0xa0,
163 .thread_uniqueid_offset = 0x4c,
165 .stacking_info =
NULL
172 .thread_stack_offset = 0,
173 .thread_name_offset = 0,
174 .thread_state_offset = 0,
175 .thread_next_offset = 0,
176 .thread_uniqueid_offset = 0,
178 .stacking_info =
NULL
182 #define ECOS_NUM_PARAMS ARRAY_SIZE(ecos_params_list)
229 #define ECOS_CORTEXM_BASE_NUMREGS (ARMV7M_NUM_CORE_REGS)
294 .stack_growth_direction = -1,
295 .num_output_registers = 0,
296 .calculate_process_stack =
NULL,
297 .register_offsets =
NULL
374 #define ECOSSYM(_n, _o, _t) { .name = _n, .optional = (_o), .target_names = _t }
382 ECOSSYM(
"Cyg_Scheduler_Base::current_thread",
false,
NULL),
387 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.list_next",
true,
NULL),
388 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.list_next",
true,
NULL),
389 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.state",
true,
NULL),
390 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.state",
true,
NULL),
391 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.sleep_reason",
true,
NULL),
392 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.sleep_reason",
true,
NULL),
393 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.wake_reason",
true,
NULL),
394 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.wake_reason",
true,
NULL),
395 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.unique_id",
true,
NULL),
396 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.unique_id",
true,
NULL),
397 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.name",
true,
NULL),
398 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.name",
true,
NULL),
399 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.priority",
true,
NULL),
400 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.priority",
true,
NULL),
401 ECOSSYM(
"__ecospro_syminfo.off.cyg_thread.stack_ptr",
true,
NULL),
402 ECOSSYM(
"__ecospro_syminfo.size.cyg_thread.stack_ptr",
true,
NULL),
472 LOG_ERROR(
"eCos: Invalid symbol index %u", idx);
476 #define XMLENTRY(_c, _s) { .xc = (_c), .rs = (_s), .rlen = (sizeof(_s) - 1) }
478 static const struct {
493 static const char *tokens =
"<&>\'\"";
494 bool escaped =
false;
499 (void)memset(out,
'\0', limit);
501 while (raw && *raw && limit) {
502 size_t lok = strcspn(raw, tokens);
505 tocopy = ((limit < lok) ? limit : lok);
506 (void)memcpy(out, raw, tocopy);
513 char *fidx = strchr(tokens, *raw);
517 LOG_ERROR(
"eCos: Unexpected XML char %c", *raw);
521 uint32_t cidx = (fidx - tokens);
522 size_t tocopy =
xmlchars[cidx].rlen;
544 LOG_DEBUG(
"eCos: %s 0x%016" PRIX64
" %s",
554 if (thread_next_size != 0) {
565 if (param->
uid_width !=
sizeof(uint16_t)) {
569 param->
uid_width = (
unsigned char)
sizeof(uint16_t);
708 int thread_list_size = 0;
736 LOG_ERROR(
"Don't have the thread list head");
742 uint32_t thread_index;
746 (uint8_t *) &thread_index);
747 uint32_t first_thread = thread_index;
767 thread_list_size = 0;
773 (uint8_t *)&thread_index);
776 }
while (thread_index != first_thread);
782 uint32_t current_thread_addr;
786 (uint8_t *)¤t_thread_addr);
788 LOG_ERROR(
"Reading active thread address");
792 if (current_thread_addr) {
799 LOG_ERROR(
"Could not read eCos current thread from target");
809 static const char tmp_str[] =
"Current Execution";
823 if (thread_list_size == 1) {
834 thread_index = first_thread;
836 #define ECOS_THREAD_NAME_STR_SIZE (200)
838 uint32_t name_ptr = 0;
839 uint32_t prev_thread_ptr;
844 uint16_t thread_id = 0;
848 (uint8_t *)&thread_id);
850 LOG_ERROR(
"Could not read eCos thread id from target");
859 (uint8_t *)&name_ptr);
861 LOG_ERROR(
"Could not read eCos thread name pointer from target");
870 (uint8_t *)&tmp_str);
872 LOG_ERROR(
"Error reading thread name from eCos target");
884 if (tmp_str[0] ==
'\x00') {
895 strcpy(tmp_str, esc_str);
899 malloc(strlen(tmp_str)+1);
903 int64_t thread_status = 0;
907 (uint8_t *)&thread_status);
909 LOG_ERROR(
"Error reading thread state from eCos target");
917 strcpy(state_desc,
"suspended+");
919 state_desc[0] =
'\0';
923 if (thread_index == current_thread_addr)
924 strcat(state_desc,
"running");
926 state_desc[9] =
'\0';
928 strcat(state_desc,
"ready");
931 strcat(state_desc,
"sleeping");
935 strcat(state_desc,
"counted sleep");
938 strcpy(state_desc,
"creating");
941 strcpy(state_desc,
"exited");
944 strcpy(state_desc,
"unknown state");
951 int64_t sleep_reason = 0;
953 if (thread_index != current_thread_addr &&
958 (uint8_t *)&sleep_reason);
960 LOG_ERROR(
"Error reading thread sleep reason from eCos target");
963 if (sleep_reason < 0 ||
971 const char *reason_desc =
NULL;
975 tr_extra = 2 + strlen(reason_desc) + 1;
978 int64_t priority = 0;
979 size_t pri_extra = 0;
984 (uint8_t *)&priority);
986 LOG_ERROR(
"Error reading thread priority from eCos target");
989 pri_extra = (12 + 20);
992 size_t eilen = (8 + strlen(state_desc) + tr_extra + pri_extra);
993 char *eistr = malloc(eilen);
999 LOG_ERROR(
"OOM allocating extra information buffer");
1003 int soff = snprintf(eistr, eilen,
"State: %s", state_desc);
1004 if (tr_extra && reason_desc)
1005 soff += snprintf(&eistr[soff], (eilen - soff),
" (%s)", reason_desc);
1007 (void)snprintf(&eistr[soff], (eilen - soff),
", Priority: %" PRId64
"", priority);
1013 prev_thread_ptr = thread_index;
1020 (uint8_t *) &thread_index);
1022 LOG_ERROR(
"Error reading next thread pointer in eCos thread list");
1025 }
while (thread_index != first_thread);
1032 struct rtos_reg **reg_list,
int *num_regs)
1066 uint32_t thread_index;
1068 (uint8_t *)&thread_index);
1076 LOG_ERROR(
"Error reading unique id from eCos thread 0x%08" PRIX32
"", thread_index);
1080 if (
id == thread_id) {
1087 (uint8_t *) &thread_index);
1092 int64_t stack_ptr = 0;
1096 (uint8_t *)&stack_ptr);
1098 LOG_ERROR(
"Error reading stack frame from eCos thread");
1103 LOG_ERROR(
"NULL stack pointer in thread %" PRIu64, thread_id);
1111 LOG_ERROR(
"Error reading stack layout for eCos thread");
1135 *symbol_list = calloc(
1166 const char *packet,
int packet_size)
1168 int64_t current_threadid;
1170 if (packet[0] ==
'H' && packet[1] ==
'g') {
1171 int numscan = sscanf(packet,
"Hg%16" SCNx64, ¤t_threadid);
1172 if (numscan == 1 && current_threadid == 0) {
1222 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 const struct @54 xmlchars[]
static struct rtos_register_stacking rtos_ecos_stacking
#define ECOS_THREAD_NAME_STR_SIZE
const struct rtos_type ecos_rtos
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
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
const char * target_type_name(const struct target *target)
Get the target type name.
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.