diff options
Diffstat (limited to 'driver/gator_backtrace.c')
-rw-r--r-- | driver/gator_backtrace.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/driver/gator_backtrace.c b/driver/gator_backtrace.c index 2173d8a..e6125b3 100644 --- a/driver/gator_backtrace.c +++ b/driver/gator_backtrace.c @@ -11,20 +11,28 @@ * EABI backtrace stores {fp,lr} on the stack. */ struct frame_tail_eabi { - unsigned long fp; // points to prev_lr + unsigned long fp; // points to prev_lr unsigned long lr; }; -static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned int depth) +static void arm_backtrace_eabi(int cpu, struct pt_regs *const regs, unsigned int depth) { -#if defined(__arm__) +#if defined(__arm__) || defined(__aarch64__) struct frame_tail_eabi *tail; struct frame_tail_eabi *next; struct frame_tail_eabi *ptrtail; struct frame_tail_eabi buftail; +#if defined(__arm__) unsigned long fp = regs->ARM_fp; unsigned long sp = regs->ARM_sp; unsigned long lr = regs->ARM_lr; + const int frame_offset = 4; +#else + unsigned long fp = regs->regs[29]; + unsigned long sp = regs->sp; + unsigned long lr = regs->regs[30]; + const int frame_offset = 0; +#endif int is_user_mode = user_mode(regs); if (!is_user_mode) { @@ -39,9 +47,9 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in return; } - tail = (struct frame_tail_eabi *)(fp - 4); + tail = (struct frame_tail_eabi *)(fp - frame_offset); - while (depth-- && tail && !((unsigned long) tail & 3)) { + while (depth-- && tail && !((unsigned long)tail & 3)) { /* Also check accessibility of one struct frame_tail beyond */ if (!access_ok(VERIFY_READ, tail, sizeof(struct frame_tail_eabi))) return; @@ -53,10 +61,10 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in gator_add_trace(cpu, lr); /* frame pointers should progress back up the stack, towards higher addresses */ - next = (struct frame_tail_eabi *)(lr - 4); + next = (struct frame_tail_eabi *)(lr - frame_offset); if (tail >= next || lr == 0) { fp = ptrtail[0].fp; - next = (struct frame_tail_eabi *)(fp - 4); + next = (struct frame_tail_eabi *)(fp - frame_offset); /* check tail is valid */ if (tail >= next || fp == 0) { return; @@ -68,7 +76,7 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in #endif } -#if defined(__arm__) +#if defined(__arm__) || defined(__aarch64__) static int report_trace(struct stackframe *frame, void *d) { struct module *mod; @@ -78,7 +86,7 @@ static int report_trace(struct stackframe *frame, void *d) if (*depth) { mod = __module_address(addr); if (mod) { - cookie = get_cookie(cpu, current, NULL, mod, true); + cookie = get_cookie(cpu, current, mod->name, false); addr = addr - (unsigned long)mod->module_core; } marshal_backtrace(addr & ~1, cookie); @@ -91,9 +99,9 @@ static int report_trace(struct stackframe *frame, void *d) // Uncomment the following line to enable kernel stack unwinding within gator, note it can also be defined from the Makefile // #define GATOR_KERNEL_STACK_UNWINDING -static void kernel_backtrace(int cpu, struct pt_regs * const regs) +static void kernel_backtrace(int cpu, struct pt_regs *const regs) { -#if defined(__arm__) +#if defined(__arm__) || defined(__aarch64__) #ifdef GATOR_KERNEL_STACK_UNWINDING int depth = gator_backtrace_depth; #else @@ -102,10 +110,16 @@ static void kernel_backtrace(int cpu, struct pt_regs * const regs) struct stackframe frame; if (depth == 0) depth = 1; +#if defined(__arm__) frame.fp = regs->ARM_fp; frame.sp = regs->ARM_sp; frame.lr = regs->ARM_lr; frame.pc = regs->ARM_pc; +#else + frame.fp = regs->regs[29]; + frame.sp = regs->sp; + frame.pc = regs->pc; +#endif walk_stackframe(&frame, report_trace, &depth); #else marshal_backtrace(PC_REG & ~1, NO_COOKIE); |