commit
87ecfac438
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue