src/rtos/rtos_nuttx_stackings.c: Fix stack alignment for cortex-m targets
Backtraces performed by GDB on any thread other than the current thread would fail if hardware 8 byte ISR stack alignment was enabled on cortex_m targets. Stack reads now adjust the stored SP to account for a potential offset introduced by hardware. Fixed incorrect register offsets for cortex_m Nuttx frames by reading the TCB info symbols to determine correct offsets. Fixed offsets can no longer be used since the offsets have changed multiple times for different Nuttx versions. Tested on nuttx-12.1.0. Tested using custom stm32h7 board and custom s32k148 board variants. Built with CONFIG_ARCH_FPU enabled and disabled to test FPU and non FPU frame logic. Change-Id: Ifcbeefb0ddcfbcb528daa9d1d95732ca9584c9ef Signed-off-by: daniellizewski <daniellizewski@geotab.com> Reviewed-on: https://review.openocd.org/c/openocd/+/8180 Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Tested-by: jenkins
This commit is contained in:
committed by
Antonio Borneo
parent
b14f63e004
commit
5159c59915
@@ -32,7 +32,6 @@
|
||||
struct nuttx_params {
|
||||
const char *target_name;
|
||||
const struct rtos_register_stacking *stacking;
|
||||
const struct rtos_register_stacking *(*select_stackinfo)(struct target *target);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -56,19 +55,12 @@ struct symbols {
|
||||
bool optional;
|
||||
};
|
||||
|
||||
/* Used to index the list of retrieved symbols. See nuttx_symbol_list for the order. */
|
||||
enum nuttx_symbol_vals {
|
||||
NX_SYM_READYTORUN = 0,
|
||||
NX_SYM_PIDHASH,
|
||||
NX_SYM_NPIDHASH,
|
||||
NX_SYM_TCB_INFO,
|
||||
};
|
||||
|
||||
static const struct symbols nuttx_symbol_list[] = {
|
||||
{ "g_readytorun", false },
|
||||
{ "g_pidhash", false },
|
||||
{ "g_npidhash", false },
|
||||
{ "g_tcbinfo", false },
|
||||
{ "g_reg_offs", false},
|
||||
{ NULL, false }
|
||||
};
|
||||
|
||||
@@ -86,18 +78,14 @@ static char *task_state_str[] = {
|
||||
"STOPPED",
|
||||
};
|
||||
|
||||
static const struct rtos_register_stacking *cortexm_select_stackinfo(struct target *target);
|
||||
|
||||
static const struct nuttx_params nuttx_params_list[] = {
|
||||
{
|
||||
.target_name = "cortex_m",
|
||||
.stacking = NULL,
|
||||
.select_stackinfo = cortexm_select_stackinfo,
|
||||
.stacking = &nuttx_stacking_cortex_m,
|
||||
},
|
||||
{
|
||||
.target_name = "hla_target",
|
||||
.stacking = NULL,
|
||||
.select_stackinfo = cortexm_select_stackinfo,
|
||||
.stacking = &nuttx_stacking_cortex_m,
|
||||
},
|
||||
{
|
||||
.target_name = "esp32",
|
||||
@@ -117,28 +105,6 @@ static const struct nuttx_params nuttx_params_list[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static bool cortexm_hasfpu(struct target *target)
|
||||
{
|
||||
uint32_t cpacr;
|
||||
struct armv7m_common *armv7m_target = target_to_armv7m(target);
|
||||
|
||||
if (!is_armv7m(armv7m_target) || armv7m_target->fp_feature == FP_NONE)
|
||||
return false;
|
||||
|
||||
int retval = target_read_u32(target, FPU_CPACR, &cpacr);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("Could not read CPACR register to check FPU state");
|
||||
return false;
|
||||
}
|
||||
|
||||
return cpacr & 0x00F00000;
|
||||
}
|
||||
|
||||
static const struct rtos_register_stacking *cortexm_select_stackinfo(struct target *target)
|
||||
{
|
||||
return cortexm_hasfpu(target) ? &nuttx_stacking_cortex_m_fpu : &nuttx_stacking_cortex_m;
|
||||
}
|
||||
|
||||
static bool nuttx_detect_rtos(struct target *target)
|
||||
{
|
||||
if (target->rtos->symbols &&
|
||||
@@ -371,29 +337,25 @@ static int nuttx_getreg_current_thread(struct rtos *rtos,
|
||||
static int nuttx_getregs_fromstack(struct rtos *rtos, int64_t thread_id,
|
||||
struct rtos_reg **reg_list, int *num_regs)
|
||||
{
|
||||
uint16_t xcpreg_off;
|
||||
uint16_t regs_off;
|
||||
uint32_t regsaddr;
|
||||
const struct nuttx_params *priv = rtos->rtos_specific_params;
|
||||
const struct rtos_register_stacking *stacking = priv->stacking;
|
||||
|
||||
if (!stacking) {
|
||||
if (priv->select_stackinfo) {
|
||||
stacking = priv->select_stackinfo(rtos->target);
|
||||
} else {
|
||||
LOG_ERROR("Can't find a way to get stacking info");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
LOG_ERROR("Can't find a way to get stacking info");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
int ret = target_read_u16(rtos->target,
|
||||
rtos->symbols[NX_SYM_TCB_INFO].address + offsetof(struct tcbinfo, regs_off),
|
||||
&xcpreg_off);
|
||||
®s_off);
|
||||
if (ret != ERROR_OK) {
|
||||
LOG_ERROR("Failed to read registers' offset: ret = %d", ret);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
ret = target_read_u32(rtos->target, thread_id + xcpreg_off, ®saddr);
|
||||
ret = target_read_u32(rtos->target, thread_id + regs_off, ®saddr);
|
||||
if (ret != ERROR_OK) {
|
||||
LOG_ERROR("Failed to read registers' address: ret = %d", ret);
|
||||
return ERROR_FAIL;
|
||||
|
||||
Reference in New Issue
Block a user