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);
484 LOG_DEBUG(
"eCos: %s 0x%016" PRIX64
" %s",
494 if (thread_next_size != 0) {
505 if (param->
uid_width !=
sizeof(uint16_t)) {
509 param->
uid_width = (
unsigned char)
sizeof(uint16_t);
646 int thread_list_size = 0;
674 LOG_ERROR(
"Don't have the thread list head");
680 uint32_t thread_index;
684 (uint8_t *) &thread_index);
685 uint32_t first_thread = thread_index;
705 thread_list_size = 0;
711 (uint8_t *)&thread_index);
714 }
while (thread_index != first_thread);
720 uint32_t current_thread_addr;
724 (uint8_t *)¤t_thread_addr);
726 LOG_ERROR(
"Reading active thread address");
730 if (current_thread_addr) {
737 LOG_ERROR(
"Could not read eCos current thread from target");
747 static const char tmp_str[] =
"Current Execution";
761 if (thread_list_size == 1) {
772 thread_index = first_thread;
774 #define ECOS_THREAD_NAME_STR_SIZE (200)
776 uint32_t name_ptr = 0;
777 uint32_t prev_thread_ptr;
782 uint16_t thread_id = 0;
786 (uint8_t *)&thread_id);
788 LOG_ERROR(
"Could not read eCos thread id from target");
797 (uint8_t *)&name_ptr);
799 LOG_ERROR(
"Could not read eCos thread name pointer from target");
808 (uint8_t *)&tmp_str);
810 LOG_ERROR(
"Error reading thread name from eCos target");
815 if (tmp_str[0] ==
'\x00')
819 malloc(strlen(tmp_str)+1);
823 int64_t thread_status = 0;
827 (uint8_t *)&thread_status);
829 LOG_ERROR(
"Error reading thread state from eCos target");
837 strcpy(state_desc,
"suspended+");
839 state_desc[0] =
'\0';
843 if (thread_index == current_thread_addr)
844 strcat(state_desc,
"running");
846 state_desc[9] =
'\0';
848 strcat(state_desc,
"ready");
851 strcat(state_desc,
"sleeping");
855 strcat(state_desc,
"counted sleep");
858 strcpy(state_desc,
"creating");
861 strcpy(state_desc,
"exited");
864 strcpy(state_desc,
"unknown state");
871 int64_t sleep_reason = 0;
873 if (thread_index != current_thread_addr &&
878 (uint8_t *)&sleep_reason);
880 LOG_ERROR(
"Error reading thread sleep reason from eCos target");
883 if (sleep_reason < 0 ||
891 const char *reason_desc =
NULL;
895 tr_extra = 2 + strlen(reason_desc) + 1;
898 int64_t priority = 0;
899 size_t pri_extra = 0;
904 (uint8_t *)&priority);
906 LOG_ERROR(
"Error reading thread priority from eCos target");
909 pri_extra = (12 + 20);
912 size_t eilen = (8 + strlen(state_desc) + tr_extra + pri_extra);
913 char *eistr = malloc(eilen);
919 LOG_ERROR(
"OOM allocating extra information buffer");
923 int soff = snprintf(eistr, eilen,
"State: %s", state_desc);
924 if (tr_extra && reason_desc)
925 soff += snprintf(&eistr[soff], (eilen - soff),
" (%s)", reason_desc);
927 (void)snprintf(&eistr[soff], (eilen - soff),
", Priority: %" PRId64, priority);
933 prev_thread_ptr = thread_index;
940 (uint8_t *) &thread_index);
942 LOG_ERROR(
"Error reading next thread pointer in eCos thread list");
945 }
while (thread_index != first_thread);
952 struct rtos_reg **reg_list,
int *num_regs)
986 uint32_t thread_index;
988 (uint8_t *)&thread_index);
996 LOG_ERROR(
"Error reading unique id from eCos thread 0x%08" PRIX32, thread_index);
1000 if (
id == thread_id) {
1007 (uint8_t *) &thread_index);
1012 int64_t stack_ptr = 0;
1016 (uint8_t *)&stack_ptr);
1018 LOG_ERROR(
"Error reading stack frame from eCos thread");
1023 LOG_ERROR(
"NULL stack pointer in thread %" PRIu64, thread_id);
1031 LOG_ERROR(
"Error reading stack layout for eCos thread");
1055 *symbol_list = calloc(
1086 const char *packet,
int packet_size)
1088 int64_t current_threadid;
1090 if (packet[0] ==
'H' && packet[1] ==
'g') {
1091 int numscan = sscanf(packet,
"Hg%16" SCNx64, ¤t_threadid);
1092 if (numscan == 1 && current_threadid == 0) {
1142 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 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 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_LEVEL_IS(FOO)
#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.