feat: backtrace for arm9

arm9架构支持栈回溯功能

close #I4BMLG

Signed-off-by: Haryslee <lihao189@huawei.com>
Change-Id: Iba30a6853391c4cad3ed59ddfc05ef2530a4de89
This commit is contained in:
Haryslee 2021-09-24 11:09:17 +08:00
parent af8a6d5047
commit 03de7f3745
3 changed files with 116 additions and 2 deletions

View File

@ -45,7 +45,6 @@ WEAK BOOL OsStackDataIsCodeAddr(UINTPTR value)
return FALSE;
}
#if (LOSCFG_BACKTRACE_TYPE == 1)
#define OS_BACKTRACE_START 2
/* Thumb instruction, so the pc must be an odd number */
@ -587,6 +586,94 @@ VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
LR[index] = 0;
}
}
#elif (LOSCFG_BACKTRACE_TYPE == 6)
#define OS_BACKTRACE_START 1
#define STACK_OFFSET 4
#define THUMB_OFFSET 2
#define THUMB_BIT 16
#define ARM_ALIGN_CODE 4
#define THUMB_ALIGN_CODE 2
#define BL_CMD_OFFSET 4
#define ARM_BL_MASK 0xEB000000
#define THUMB_BL_MASK 0xF000F000
#define CLEAR_LOW_BIT_MASK 0xFFFFFFFE
STATIC INLINE BOOL IsAligned(UINT32 val, UINT32 align)
{
return ((val & (align - 1)) == 0);
}
STATIC INLINE UINTPTR OsSpGet(VOID)
{
UINTPTR SP;
__asm volatile("mov %0, sp" : "=r"(SP));
return SP;
}
STATIC INLINE BOOL IsArmValidLr(UINTPTR lr)
{
return ((*(UINT32 *)(lr - BL_CMD_OFFSET) & ARM_BL_MASK) == ARM_BL_MASK);
}
STATIC INLINE BOOL IsThumbValidLr(UINTPTR lr)
{
lr = (*(UINT16 *)(lr - BL_CMD_OFFSET) << THUMB_BIT) + *(UINT16 *)(lr - THUMB_OFFSET);
return ((lr & THUMB_BL_MASK) == THUMB_BL_MASK);
}
VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP)
{
UINT32 count = 0;
UINT32 index = 0;
LosTaskCB *taskCB = NULL;
UINT32 taskID;
UINT32 stackStart, stackEnd;
UINTPTR framePtr, tmpFramePtr, linkReg;
if (LR == NULL) {
return;
}
if (SP == 0) {
SP = OsSpGet();
}
if (LOS_TaskIsRunning()) {
taskID = LOS_CurTaskIDGet();
taskCB = OS_TCB_FROM_TID(taskID);
stackStart = taskCB->topOfStack;
stackEnd = stackStart + taskCB->stackSize;
} else {
stackStart = CSTACK_START_ADDR;
stackEnd = CSTACK_END_ADDR;
}
while ((SP > stackStart) && (SP < stackEnd)) {
linkReg = *(UINTPTR *)SP;
if (!OsStackDataIsCodeAddr(linkReg)) {
SP += STACK_OFFSET;
continue;
}
if (((!IsAligned(linkReg, ARM_ALIGN_CODE)) || !IsArmValidLr(linkReg)) &&
((!IsAligned(linkReg - 1, THUMB_ALIGN_CODE)) || !IsThumbValidLr(linkReg - 1))) {
SP += STACK_OFFSET;
continue;
}
if (index >= jumpCount) {
LR[count++] = linkReg & CLEAR_LOW_BIT_MASK;
if (count == LRSize) {
break;
}
}
++index;
SP += STACK_OFFSET;
}
/* if linkReg is not enough,clean up the last of the effective LR as the end. */
if (count < LRSize) {
LR[count] = 0;
}
}
#else
#error Unknown backtrace type.
#endif

View File

@ -183,6 +183,31 @@ extern CHAR *CSTACK_SECTION_END;
#define ALGIN_CODE 2
#define STACK_OFFSET 4
#elif (LOSCFG_BACKTRACE_TYPE == 6)
extern CHAR *__svc_stack;
extern CHAR *__svc_stack_top;
/* The default code section start address */
#define CODE_SECTION_START __text_start
/* The default code section end address */
#define CODE_SECTION_END __text_end
/* The default C stack section start address */
#define CSTACK_SECTION_START __svc_stack
/* The default C stack section end address */
#define CSTACK_SECTION_END __svc_stack_top
extern CHAR *CODE_SECTION_START;
extern CHAR *CODE_SECTION_END;
extern CHAR *CSTACK_SECTION_START;
extern CHAR *CSTACK_SECTION_END;
/* Default only one code section. In fact, there may be more than one.
You can define more than one and redefine the OsStackDataIsCodeAddr function
to support searching in multiple code sections */
#define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START)
#define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END)
#define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START)
#define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END)
#endif
/* This function is currently used to register the memory leak check hook,
@ -201,4 +226,5 @@ VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP);
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
#endif

View File

@ -741,6 +741,7 @@ extern UINT8 *m_aucSysMem0;
* 3: Call stack analysis for risc-v by scanning the stack.
* 4: Call stack analysis for xtensa by scanning the stack.
* 5: Call stack analysis for c-sky by scanning the stack.
* 6: Call stack analysis for arm9 by scanning the stack.
* others: Not currently supported.
*/
#ifndef LOSCFG_BACKTRACE_TYPE