aboutsummaryrefslogtreecommitdiff
path: root/driver/gator_backtrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/gator_backtrace.c')
-rw-r--r--driver/gator_backtrace.c36
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);