summaryrefslogtreecommitdiffstats
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 @@
11 * EABI backtrace stores {fp,lr} on the stack. 11 * EABI backtrace stores {fp,lr} on the stack.
12 */ 12 */
13struct frame_tail_eabi { 13struct 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
18static void arm_backtrace_eabi(int cpu, struct pt_regs * const regs, unsigned int depth) 18static 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__)
72static int report_trace(struct stackframe *frame, void *d) 80static 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
94static void kernel_backtrace(int cpu, struct pt_regs * const regs) 102static 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);