tlsr82/backtrace: tc32 backtrace bug fix

Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
This commit is contained in:
wangbowen6 2022-10-12 20:55:49 +08:00 committed by Alan Carvalho de Assis
parent 83764079a1
commit f925e17f18
2 changed files with 80 additions and 62 deletions

View File

@ -43,16 +43,16 @@
#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
#define IMASK_T_PUSH_LO 0xff00 /* push {reglist} (not LR) */
#define IMASK_T_PUSH_LO 0xff00 /* tpush {reglist} (not LR) */
#define IOP_T_PUSH_LO 0x6400
#define IMASK_T_PUSH 0xff00 /* push {reglist} (inc LR) */
#define IMASK_T_PUSH 0xff00 /* tpush {reglist} (inc LR) */
#define IOP_T_PUSH 0x6500
#define IMASK_T_SUB_SP_16 0xff80 /* sub sp, # */
#define IMASK_T_SUB_SP_16 0xff80 /* tsub sp, # */
#define IOP_T_SUB_SP_16 0x6080
#define IMASK_T_BL 0xf000 /* bl */
#define IMASK_T_BL 0xf000 /* tjl */
#define IOP_T_BL 0x9000
#define INSTR_LIMIT 0x2000
@ -63,6 +63,22 @@
static void **g_backtrace_code_regions;
/****************************************************************************
* Inline functions
****************************************************************************/
static inline uint32_t tc32_getsp(void)
{
uint32_t sp;
__asm__
(
"\ttmov %0, sp\n\t"
: "=r"(sp)
);
return sp;
}
/****************************************************************************
* Private Functions
****************************************************************************/
@ -168,7 +184,7 @@ static void *backtrace_push_internal(void **psp, void **ppc)
uint8_t *base;
uint8_t *lr;
uint16_t ins16;
int offset = 1;
int state = 0;
bool found;
int frame;
int i;
@ -185,25 +201,53 @@ static void *backtrace_push_internal(void **psp, void **ppc)
found = false;
/* Stack frame increase order:
* <function>:
* 1 tpush {rx, lr} (must , IOP_T_PUSH , case 2)
* 2 other instructions
* 3 tpush {rx} (not must, IOP_T_PUSH_LO , case 1)
* 4 tpush {rx} (not must, IOP_T_PUSH_LO , case 1)
* 5 ...
* 6 tpush {rx} (not must, IOP_T_PUSH_LO , case 1)
* 7 other instructions
* 8 tsub sp, #n (not must, IOP_T_SUB_SP_16, case 0)
*/
for (i = 0; i < INSTR_LIMIT; i += 2)
{
base = pc - i;
ins16 = *(uint16_t *)(base);
if (INSTR_IS(ins16, T_PUSH))
switch (state)
{
/* Bit 1 number in low byte indicates the number of pushed
* low register, +1 for LR is alao pushed into the stack.
*/
case 0:
if (INSTR_IS(ins16, T_SUB_SP_16))
{
/* Low 7 bit (imm7) is the number (4*imm7) sub to sp */
frame = __builtin_popcount(ins16 & 0xff) + 1;
ins16 = *(uint16_t *)(base - 2);
if (INSTR_IS(ins16, T_PUSH_LO))
{
offset += __builtin_popcount(ins16 & 0xff);
frame += offset - 1;
}
frame += (ins16 & 0x7f);
state = 1;
break;
}
found = true;
case 1:
if (INSTR_IS(ins16, T_PUSH_LO))
{
frame += __builtin_popcount(ins16 & 0xff);
state = 1;
break;
}
if (INSTR_IS(ins16, T_PUSH))
{
/* +1, because include the LR */
frame += __builtin_popcount(ins16 & 0xff) + 1;
found = true;
}
break;
default:
break;
}
if (found)
@ -229,48 +273,19 @@ static void *backtrace_push_internal(void **psp, void **ppc)
return NULL;
}
i = 0;
while (base + i < pc)
{
ins16 = *(uint16_t *)(base + i);
if (INSTR_IS(ins16, T_SUB_SP_16))
{
/* Low 7 bit indicates the number sub to sp */
frame += (ins16 & 0x7f);
break;
}
if (INSTR_IS(ins16, T_PUSH_LO))
{
/* Bit 1 number in low 8bit indicated the number of pushed
* low register.
*/
frame += __builtin_popcount(ins16 & 0xff);
}
/* 16bit instruction */
i += 2;
}
lr = (uint8_t *)*((uint32_t *)sp + frame - offset);
lr = (uint8_t *)*((uint32_t *)sp + frame - 1);
if (!in_code_region(lr))
{
return NULL;
}
offset = getlroffset(lr);
if (offset == 0)
if (getlroffset(lr) == 0)
{
return NULL;
}
*psp = (uint32_t *)sp + frame;
return lr - offset;
return lr - 4;
}
/****************************************************************************
@ -333,7 +348,6 @@ nosanitize_address
static int backtrace_branch(void *limit, void *sp,
void **buffer, int size, int *skip)
{
#if 1
uint16_t ins16;
uint32_t addr;
int i;
@ -371,13 +385,6 @@ static int backtrace_branch(void *limit, void *sp,
}
return i;
#else
/* Not implement backtrace branch method temporarily
* Wait for the instruction tjl encode document from telink.
*/
return 0;
#endif
}
/****************************************************************************
@ -461,7 +468,7 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int size, int skip)
if (tcb == rtcb)
{
sp = (void *)up_getsp();
sp = (void *)tc32_getsp();
if (up_interrupt_context())
{
@ -472,12 +479,12 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int size, int skip)
# else
g_intstacktop,
# endif /* CONFIG_SMP */
&sp, (void *)up_backtrace + 10,
&sp, (void *)up_backtrace + 16,
buffer, size, &skip);
#else
ret = backtrace_push(rtcb->stack_base_ptr +
rtcb->adj_stack_size,
&sp, (void *)up_backtrace + 10,
&sp, (void *)up_backtrace + 16,
buffer, size, &skip);
#endif
if (ret < size)
@ -493,7 +500,7 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int size, int skip)
{
ret = backtrace_push(rtcb->stack_base_ptr +
rtcb->adj_stack_size, &sp,
(void *)up_backtrace + 10,
(void *)up_backtrace + 16,
buffer, size, &skip);
}

View File

@ -19,6 +19,7 @@
# CONFIG_FS_PROCFS_EXCLUDE_VERSION is not set
# CONFIG_NSH_DISABLEBG is not set
# CONFIG_NSH_DISABLESCRIPT is not set
# CONFIG_NSH_DISABLE_CAT is not set
# CONFIG_NSH_DISABLE_CD is not set
# CONFIG_NSH_DISABLE_DF is not set
# CONFIG_NSH_DISABLE_ECHO is not set
@ -28,36 +29,42 @@
# CONFIG_NSH_DISABLE_ITEF is not set
# CONFIG_NSH_DISABLE_KILL is not set
# CONFIG_NSH_DISABLE_LOOPS is not set
# CONFIG_NSH_DISABLE_LS is not set
# CONFIG_NSH_DISABLE_PS is not set
# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set
# CONFIG_NSH_DISABLE_PWD is not set
# CONFIG_NSH_DISABLE_SEMICOLON is not set
# CONFIG_NSH_DISABLE_UNAME is not set
# CONFIG_NSH_DISABLE_XD is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="tlsr8278adk80d"
CONFIG_ARCH_BOARD_TLSR8278ADK80D=y
CONFIG_ARCH_CHIP="tlsr82"
CONFIG_ARCH_CHIP_TLSR8278=y
CONFIG_ARCH_CHIP_TLSR82=y
CONFIG_ARCH_INTERRUPTSTACK=384
CONFIG_ARCH_INTERRUPTSTACK=1024
CONFIG_ARCH_SETJMP_H=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=2000
CONFIG_BUILTIN=y
CONFIG_DEBUG_ASSERTIONS=y
CONFIG_DEBUG_CUSTOMOPT=y
CONFIG_DEBUG_ERROR=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_SMALL=y
CONFIG_DEV_GPIO=y
CONFIG_DRVR_MKRD=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_FS_PROCFS=y
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBM=y
CONFIG_MTD=y
CONFIG_MTD_PARTITION=y
CONFIG_NDEBUG=y
CONFIG_NSH_ARGCAT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_LINELEN=80
@ -69,9 +76,11 @@ CONFIG_RAM_SIZE=65536
CONFIG_RAM_START=0x00840000
CONFIG_RAW_BINARY=y
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_HPWORK=y
CONFIG_SIG_PREALLOC_IRQ_ACTIONS=8
CONFIG_STACK_COLORATION=y
CONFIG_SYSLOG_TIMESTAMP=y
CONFIG_SYSTEM_DUMPSTACK=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_OSTEST=y
CONFIG_TIMER=y
@ -84,4 +93,6 @@ CONFIG_TLSR82_TIMER1=y
CONFIG_TLSR82_TIMER=y
CONFIG_TLSR82_UART0=y
CONFIG_TLSR82_UART=y
CONFIG_TTY_FORCE_PANIC=y
CONFIG_TTY_SIGINT=y
CONFIG_USEC_PER_TICK=1000