!135 添加backtrace for riscv在不打开frame-pointer的提前下
Merge pull request !135 from JerryH/backtrace
This commit is contained in:
commit
9781662cea
|
@ -112,15 +112,15 @@ STATIC INLINE UINT32 OsStackAddrGet(UINTPTR *stackStart, UINTPTR *stackEnd, UINT
|
||||||
{
|
{
|
||||||
if (SP != 0) {
|
if (SP != 0) {
|
||||||
*stackStart = SP;
|
*stackStart = SP;
|
||||||
if ((SP >= CODE_START_ADDR) && (SP < CSTACK_END_ADDR)) {
|
if ((SP >= CSTACK_START_ADDR) && (SP < CSTACK_END_ADDR)) {
|
||||||
*stackEnd = CSTACK_END_ADDR;
|
*stackEnd = CSTACK_END_ADDR;
|
||||||
} else {
|
} else {
|
||||||
UINT32 taskID = LOS_CurTaskIDGet();
|
UINT32 taskID = LOS_CurTaskIDGet();
|
||||||
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
|
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
|
||||||
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
|
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
|
||||||
if ((SP < (UINTPTR)taskCB->topOfStack) || (SP >= *stackEnd)) {
|
if ((SP < (UINTPTR)taskCB->topOfStack) || (SP >= *stackEnd)) {
|
||||||
PRINT_ERR("msp stack [0x%x, 0x%x], cur task stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
|
PRINT_ERR("msp statck [0x%x, 0x%x], cur task stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
|
||||||
CODE_START_ADDR, CSTACK_END_ADDR, (UINTPTR)taskCB->topOfStack, *stackEnd, SP);
|
CSTACK_START_ADDR, CSTACK_END_ADDR, (UINTPTR)taskCB->topOfStack, *stackEnd, SP);
|
||||||
return LOS_NOK;
|
return LOS_NOK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,9 +128,9 @@ STATIC INLINE UINT32 OsStackAddrGet(UINTPTR *stackStart, UINTPTR *stackEnd, UINT
|
||||||
if (HalSpGet() != HalPspGet()) {
|
if (HalSpGet() != HalPspGet()) {
|
||||||
*stackStart = HalMspGet();
|
*stackStart = HalMspGet();
|
||||||
*stackEnd = CSTACK_END_ADDR;
|
*stackEnd = CSTACK_END_ADDR;
|
||||||
if ((*stackStart < CODE_START_ADDR) || (*stackStart >= CSTACK_END_ADDR)) {
|
if ((*stackStart < CSTACK_START_ADDR) || (*stackStart >= CSTACK_END_ADDR)) {
|
||||||
PRINT_ERR("msp stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
|
PRINT_ERR("msp stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
|
||||||
CODE_START_ADDR, CSTACK_END_ADDR, *stackStart);
|
CSTACK_START_ADDR, CSTACK_END_ADDR, *stackStart);
|
||||||
return LOS_NOK;
|
return LOS_NOK;
|
||||||
}
|
}
|
||||||
PRINTK("msp, start = %x, end = %x\n", *stackStart, *stackEnd);
|
PRINTK("msp, start = %x, end = %x\n", *stackStart, *stackEnd);
|
||||||
|
@ -179,7 +179,172 @@ STATIC INLINE UINTPTR OsAddrIsValid(UINTPTR sp)
|
||||||
|
|
||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
|
#elif (LOSCFG_BACKTRACE_TYPE == 2)
|
||||||
|
STATIC INLINE BOOL OsBackTraceFpCheck(UINT32 value);
|
||||||
|
#define OS_BACKTRACE_START 1
|
||||||
|
#define OS_RA_OFFSET 4
|
||||||
|
#define OS_FP_OFFSET 8
|
||||||
|
#define OS_FP_ALIGN(value) (((UINT32)(value) & (UINT32)(LOSCFG_STACK_POINT_ALIGN_SIZE - 1)) == 0)
|
||||||
|
#define OS_FP_CHECK(value) (((UINT32)(value) != FP_INIT_VALUE) && OS_FP_ALIGN(value))
|
||||||
|
|
||||||
|
STATIC INLINE UINTPTR OsFpGet(VOID)
|
||||||
|
{
|
||||||
|
UINTPTR fp = 0;
|
||||||
|
__asm volatile("mv %0, s0" : "=r"(fp));
|
||||||
|
dsb();
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
|
||||||
|
{
|
||||||
|
UNUSED(SP);
|
||||||
|
UINT32 backFp = OsFpGet();
|
||||||
|
UINT32 tmpFp;
|
||||||
|
UINT32 backRa;
|
||||||
|
UINT32 count = 0;
|
||||||
|
UINT32 index = 0;
|
||||||
|
|
||||||
|
if (LR == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (OS_FP_CHECK(backFp)) {
|
||||||
|
tmpFp = backFp;
|
||||||
|
backRa = *((UINT32 *)(UINTPTR)(tmpFp - OS_RA_OFFSET));
|
||||||
|
backFp = *((UINT32 *)(UINTPTR)(tmpFp - OS_FP_OFFSET));
|
||||||
|
if (index++ < jumpCount) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LR[count] = backRa;
|
||||||
|
count++;
|
||||||
|
if ((count == LRSize) || (backFp == tmpFp) ||
|
||||||
|
(!OsStackDataIsCodeAddr(backRa))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < LRSize) {
|
||||||
|
LR[count] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif (LOSCFG_BACKTRACE_TYPE == 3)
|
||||||
|
#define OS_BACKTRACE_START 1
|
||||||
|
#define OS_JALX_INS_MASK 0x7F
|
||||||
|
#define OS_JAL_INS_LOW 0x6F
|
||||||
|
#define OS_JAL_16_INS_MASK 0x2001
|
||||||
|
#define OS_JALR_INS_LOW 0x67
|
||||||
|
#define OS_JALR_16_INS_MASK 0x9002
|
||||||
|
#define OS_JR_16_INS_MASK 0x8002
|
||||||
|
#define OS_J_16_INS_MASK 0xA001
|
||||||
|
|
||||||
|
STATIC INLINE BOOL OsInsIsJump(UINTPTR addr)
|
||||||
|
{
|
||||||
|
UINT16 ins1 = *((UINT16 *)addr);
|
||||||
|
UINT16 ins2 = *((UINT16 *)(addr + 2));
|
||||||
|
|
||||||
|
/* Jal ins */
|
||||||
|
if (((ins1 & OS_JALX_INS_MASK) == OS_JAL_INS_LOW) ||
|
||||||
|
((ins1 & OS_JAL_16_INS_MASK) == OS_JAL_16_INS_MASK) ||
|
||||||
|
((ins2 & OS_JAL_16_INS_MASK) == OS_JAL_16_INS_MASK)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Jalr ins */
|
||||||
|
if (((ins1 & OS_JALX_INS_MASK) == OS_JALR_INS_LOW) ||
|
||||||
|
((ins1 & OS_JALR_16_INS_MASK) == OS_JALR_16_INS_MASK) ||
|
||||||
|
((ins2 & OS_JALR_16_INS_MASK) == OS_JALR_16_INS_MASK)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Jr ins */
|
||||||
|
if (((ins1 & OS_JR_16_INS_MASK) == OS_JR_16_INS_MASK) ||
|
||||||
|
((ins2 & OS_JR_16_INS_MASK) == OS_JR_16_INS_MASK)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* J ins */
|
||||||
|
if (((ins1 & OS_J_16_INS_MASK) == OS_J_16_INS_MASK) ||
|
||||||
|
((ins2 & OS_J_16_INS_MASK) == OS_J_16_INS_MASK)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC INLINE UINTPTR OsSpGet(VOID)
|
||||||
|
{
|
||||||
|
UINTPTR sp = 0;
|
||||||
|
__asm volatile("mv %0, sp" : "=r"(sp));
|
||||||
|
dsb();
|
||||||
|
return sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC INLINE UINT32 OsStackAddrGet(UINTPTR *stackStart, UINTPTR *stackEnd, UINTPTR SP)
|
||||||
|
{
|
||||||
|
if (SP != 0) {
|
||||||
|
*stackStart = SP;
|
||||||
|
if ((SP >= CSTACK_START_ADDR) && (SP < CSTACK_END_ADDR)) {
|
||||||
|
*stackEnd = CSTACK_END_ADDR;
|
||||||
|
} else {
|
||||||
|
UINT32 taskID = LOS_CurTaskIDGet();
|
||||||
|
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
|
||||||
|
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
|
||||||
|
if ((SP < (UINTPTR)taskCB->topOfStack) || (SP >= *stackEnd)) {
|
||||||
|
PRINT_ERR("msp statck [0x%x, 0x%x], cur task stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
|
||||||
|
CSTACK_START_ADDR, CSTACK_END_ADDR, (UINTPTR)taskCB->topOfStack, *stackEnd, SP);
|
||||||
|
return LOS_NOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!LOS_TaskIsRunning()) {
|
||||||
|
*stackStart = OsSpGet();
|
||||||
|
*stackEnd = CSTACK_END_ADDR;
|
||||||
|
if ((*stackStart < CSTACK_START_ADDR) || (*stackStart >= CSTACK_END_ADDR)) {
|
||||||
|
PRINT_ERR("msp stack [0x%x, 0x%x], cur sp(0x%x) is overflow!\n",
|
||||||
|
CSTACK_START_ADDR, CSTACK_END_ADDR, *stackStart);
|
||||||
|
return LOS_NOK;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*stackStart = OsSpGet();
|
||||||
|
UINT32 taskID = LOS_CurTaskIDGet();
|
||||||
|
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
|
||||||
|
*stackEnd = (UINTPTR)taskCB->topOfStack + taskCB->stackSize;
|
||||||
|
if ((*stackStart < (UINTPTR)taskCB->topOfStack) || (*stackStart >= *stackEnd)) {
|
||||||
|
PRINT_ERR("psp stack [0x%x, 0x%x], cur sp(0x%x) is overflow, cur task id is %d!\n",
|
||||||
|
taskCB->topOfStack, *stackEnd, *stackStart, taskID);
|
||||||
|
return LOS_NOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC INLINE UINTPTR OsAddrIsValid(UINTPTR sp)
|
||||||
|
{
|
||||||
|
UINTPTR pc;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
pc = *((UINTPTR *)sp);
|
||||||
|
|
||||||
|
ret = OsStackDataIsCodeAddr(pc);
|
||||||
|
if (ret == FALSE) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = OsInsIsJump(pc - sizeof(UINTPTR));
|
||||||
|
if (ret == FALSE) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error Unknown backtrace type.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (LOSCFG_BACKTRACE_TYPE == 1) || (LOSCFG_BACKTRACE_TYPE == 3)
|
||||||
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
|
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
|
||||||
{
|
{
|
||||||
if (LR == NULL) {
|
if (LR == NULL) {
|
||||||
|
@ -218,57 +383,6 @@ VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
|
||||||
LR[count] = 0;
|
LR[count] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif (LOSCFG_BACKTRACE_TYPE == 2)
|
|
||||||
STATIC INLINE BOOL OsBackTraceFpCheck(UINT32 value);
|
|
||||||
#define OS_BACKTRACE_START 1
|
|
||||||
#define OS_RA_OFFSET 4
|
|
||||||
#define OS_FP_OFFSET 8
|
|
||||||
#define OS_FP_ALIGN(value) (((UINT32)(value) & (UINT32)(LOSCFG_STACK_POINT_ALIGN_SIZE - 1)) == 0)
|
|
||||||
#define OS_FP_CHECK(value) (((UINT32)(value) != FP_INIT_VALUE) && OS_FP_ALIGN(value))
|
|
||||||
|
|
||||||
STATIC INLINE UINTPTR OsFpGet(VOID)
|
|
||||||
{
|
|
||||||
UINTPTR fp = 0;
|
|
||||||
__asm volatile("mv %0, s0" : "=r"(fp));
|
|
||||||
dsb();
|
|
||||||
return fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
|
|
||||||
{
|
|
||||||
UNUSED(SP);
|
|
||||||
UINT32 backFp = OsFpGet();
|
|
||||||
UINT32 tmpFp;
|
|
||||||
UINT32 backRa;
|
|
||||||
UINT32 count = 0;
|
|
||||||
UINT32 index = 0;
|
|
||||||
|
|
||||||
if (LR == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (OS_FP_CHECK(backFp)) {
|
|
||||||
tmpFp = backFp;
|
|
||||||
backRa = *((UINT32 *)(UINTPTR)(tmpFp - OS_RA_OFFSET));
|
|
||||||
backFp = *((UINT32 *)(UINTPTR)(tmpFp - OS_FP_OFFSET));
|
|
||||||
if (index++ < jumpCount) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
LR[count] = backRa;
|
|
||||||
count++;
|
|
||||||
if ((count == LRSize) || (backFp == tmpFp) ||
|
|
||||||
(!OsStackDataIsCodeAddr(backRa))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count < LRSize) {
|
|
||||||
LR[count] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#error Unknown backtrace type.
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VOID LOS_BackTrace(VOID)
|
VOID LOS_BackTrace(VOID)
|
||||||
|
|
|
@ -115,18 +115,26 @@ extern CHAR *CSTACK_SECTION_END;
|
||||||
#else
|
#else
|
||||||
#error Unknown compiler.
|
#error Unknown compiler.
|
||||||
#endif
|
#endif
|
||||||
#elif (LOSCFG_BACKTRACE_TYPE == 2)
|
#elif (LOSCFG_BACKTRACE_TYPE == 2) || (LOSCFG_BACKTRACE_TYPE == 3)
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
/* The default code section start address */
|
/* The default code section start address */
|
||||||
#define CODE_SECTION_START __text_start
|
#define CODE_SECTION_START __text_start
|
||||||
/* The default code section end address */
|
/* The default code section end address */
|
||||||
#define CODE_SECTION_END __text_end
|
#define CODE_SECTION_END __text_end
|
||||||
|
/* The default C stack section start address */
|
||||||
|
#define CSTACK_SECTION_START __except_stack_top
|
||||||
|
/* The default C stack section end address */
|
||||||
|
#define CSTACK_SECTION_END __start_and_irq_stack_top
|
||||||
|
|
||||||
extern CHAR *CODE_SECTION_START;
|
extern CHAR *CODE_SECTION_START;
|
||||||
extern CHAR *CODE_SECTION_END;
|
extern CHAR *CODE_SECTION_END;
|
||||||
|
extern CHAR *CSTACK_SECTION_START;
|
||||||
|
extern CHAR *CSTACK_SECTION_END;
|
||||||
|
|
||||||
#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START)
|
#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START)
|
||||||
#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END)
|
#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END)
|
||||||
|
#define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START)
|
||||||
|
#define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END)
|
||||||
#else
|
#else
|
||||||
#error Unknown compiler.
|
#error Unknown compiler.
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -609,8 +609,9 @@ extern UINT8 *m_aucSysMem0;
|
||||||
* @ingroup los_config
|
* @ingroup los_config
|
||||||
* Configuration backtrace type
|
* Configuration backtrace type
|
||||||
* 0: Close stack analysis module.
|
* 0: Close stack analysis module.
|
||||||
* 1: Call stack analysis for cortex-m series.
|
* 1: Call stack analysis for cortex-m series by scanning the stack.
|
||||||
* 2: Call stack analysis for risc-v.
|
* 2: Call stack analysis for risc-v by using frame pointer.
|
||||||
|
* 3: Call stack analysis for risc-v by scanning the stack.
|
||||||
* others: Not currently supported.
|
* others: Not currently supported.
|
||||||
*/
|
*/
|
||||||
#ifndef LOSCFG_BACKTRACE_TYPE
|
#ifndef LOSCFG_BACKTRACE_TYPE
|
||||||
|
|
Loading…
Reference in New Issue