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 @@ | |||
11 | * EABI backtrace stores {fp,lr} on the stack. | 11 | * EABI backtrace stores {fp,lr} on the stack. |
12 | */ | 12 | */ |
13 | struct frame_tail_eabi { | 13 | struct frame_tail_eabi { |
14 | unsigned long fp; // points to prev_lr | 14 | unsigned long fp; // points to prev_lr |
15 | unsigned long lr; | 15 | unsigned long lr; |
16 | }; | 16 | }; |
17 | 17 | ||
18 | static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned int depth) | 18 | static void arm_backtrace_eabi(int cpu, struct pt_regs *const regs, unsigned int depth) |
19 | { | 19 | { |
20 | #if defined(__arm__) | 20 | #if defined(__arm__) || defined(__aarch64__) |
21 | struct frame_tail_eabi *tail; | 21 | struct frame_tail_eabi *tail; |
22 | struct frame_tail_eabi *next; | 22 | struct frame_tail_eabi *next; |
23 | struct frame_tail_eabi *ptrtail; | 23 | struct frame_tail_eabi *ptrtail; |
24 | struct frame_tail_eabi buftail; | 24 | struct frame_tail_eabi buftail; |
25 | #if defined(__arm__) | ||
25 | unsigned long fp = regs->ARM_fp; | 26 | unsigned long fp = regs->ARM_fp; |
26 | unsigned long sp = regs->ARM_sp; | 27 | unsigned long sp = regs->ARM_sp; |
27 | unsigned long lr = regs->ARM_lr; | 28 | unsigned long lr = regs->ARM_lr; |
29 | const int frame_offset = 4; | ||
30 | #else | ||
31 | unsigned long fp = regs->regs[29]; | ||
32 | unsigned long sp = regs->sp; | ||
33 | unsigned long lr = regs->regs[30]; | ||
34 | const int frame_offset = 0; | ||
35 | #endif | ||
28 | int is_user_mode = user_mode(regs); | 36 | int is_user_mode = user_mode(regs); |
29 | 37 | ||
30 | if (!is_user_mode) { | 38 | if (!is_user_mode) { |
@@ -39,9 +47,9 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in | |||
39 | return; | 47 | return; |
40 | } | 48 | } |
41 | 49 | ||
42 | tail = (struct frame_tail_eabi *)(fp - 4); | 50 | tail = (struct frame_tail_eabi *)(fp - frame_offset); |
43 | 51 | ||
44 | while (depth-- && tail && !((unsigned long) tail & 3)) { | 52 | while (depth-- && tail && !((unsigned long)tail & 3)) { |
45 | /* Also check accessibility of one struct frame_tail beyond */ | 53 | /* Also check accessibility of one struct frame_tail beyond */ |
46 | if (!access_ok(VERIFY_READ, tail, sizeof(struct frame_tail_eabi))) | 54 | if (!access_ok(VERIFY_READ, tail, sizeof(struct frame_tail_eabi))) |
47 | return; | 55 | return; |
@@ -53,10 +61,10 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in | |||
53 | gator_add_trace(cpu, lr); | 61 | gator_add_trace(cpu, lr); |
54 | 62 | ||
55 | /* frame pointers should progress back up the stack, towards higher addresses */ | 63 | /* frame pointers should progress back up the stack, towards higher addresses */ |
56 | next = (struct frame_tail_eabi *)(lr - 4); | 64 | next = (struct frame_tail_eabi *)(lr - frame_offset); |
57 | if (tail >= next || lr == 0) { | 65 | if (tail >= next || lr == 0) { |
58 | fp = ptrtail[0].fp; | 66 | fp = ptrtail[0].fp; |
59 | next = (struct frame_tail_eabi *)(fp - 4); | 67 | next = (struct frame_tail_eabi *)(fp - frame_offset); |
60 | /* check tail is valid */ | 68 | /* check tail is valid */ |
61 | if (tail >= next || fp == 0) { | 69 | if (tail >= next || fp == 0) { |
62 | return; | 70 | return; |
@@ -68,7 +76,7 @@ static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned in | |||
68 | #endif | 76 | #endif |
69 | } | 77 | } |
70 | 78 | ||
71 | #if defined(__arm__) | 79 | #if defined(__arm__) || defined(__aarch64__) |
72 | static int report_trace(struct stackframe *frame, void *d) | 80 | static int report_trace(struct stackframe *frame, void *d) |
73 | { | 81 | { |
74 | struct module *mod; | 82 | struct module *mod; |
@@ -78,7 +86,7 @@ static int report_trace(struct stackframe *frame, void *d) | |||
78 | if (*depth) { | 86 | if (*depth) { |
79 | mod = __module_address(addr); | 87 | mod = __module_address(addr); |
80 | if (mod) { | 88 | if (mod) { |
81 | cookie = get_cookie(cpu, current, NULL, mod, true); | 89 | cookie = get_cookie(cpu, current, mod->name, false); |
82 | addr = addr - (unsigned long)mod->module_core; | 90 | addr = addr - (unsigned long)mod->module_core; |
83 | } | 91 | } |
84 | marshal_backtrace(addr & ~1, cookie); | 92 | marshal_backtrace(addr & ~1, cookie); |
@@ -91,9 +99,9 @@ static int report_trace(struct stackframe *frame, void *d) | |||
91 | 99 | ||
92 | // Uncomment the following line to enable kernel stack unwinding within gator, note it can also be defined from the Makefile | 100 | // Uncomment the following line to enable kernel stack unwinding within gator, note it can also be defined from the Makefile |
93 | // #define GATOR_KERNEL_STACK_UNWINDING | 101 | // #define GATOR_KERNEL_STACK_UNWINDING |
94 | static void kernel_backtrace(int cpu, struct pt_regs * const regs) | 102 | static void kernel_backtrace(int cpu, struct pt_regs *const regs) |
95 | { | 103 | { |
96 | #if defined(__arm__) | 104 | #if defined(__arm__) || defined(__aarch64__) |
97 | #ifdef GATOR_KERNEL_STACK_UNWINDING | 105 | #ifdef GATOR_KERNEL_STACK_UNWINDING |
98 | int depth = gator_backtrace_depth; | 106 | int depth = gator_backtrace_depth; |
99 | #else | 107 | #else |
@@ -102,10 +110,16 @@ static void kernel_backtrace(int cpu, struct pt_regs * const regs) | |||
102 | struct stackframe frame; | 110 | struct stackframe frame; |
103 | if (depth == 0) | 111 | if (depth == 0) |
104 | depth = 1; | 112 | depth = 1; |
113 | #if defined(__arm__) | ||
105 | frame.fp = regs->ARM_fp; | 114 | frame.fp = regs->ARM_fp; |
106 | frame.sp = regs->ARM_sp; | 115 | frame.sp = regs->ARM_sp; |
107 | frame.lr = regs->ARM_lr; | 116 | frame.lr = regs->ARM_lr; |
108 | frame.pc = regs->ARM_pc; | 117 | frame.pc = regs->ARM_pc; |
118 | #else | ||
119 | frame.fp = regs->regs[29]; | ||
120 | frame.sp = regs->sp; | ||
121 | frame.pc = regs->pc; | ||
122 | #endif | ||
109 | walk_stackframe(&frame, report_trace, &depth); | 123 | walk_stackframe(&frame, report_trace, &depth); |
110 | #else | 124 | #else |
111 | marshal_backtrace(PC_REG & ~1, NO_COOKIE); | 125 | marshal_backtrace(PC_REG & ~1, NO_COOKIE); |