summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'driver/gator_backtrace.c')
-rw-r--r--driver/gator_backtrace.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/driver/gator_backtrace.c b/driver/gator_backtrace.c
index ffacb49..9f305cf 100644
--- a/driver/gator_backtrace.c
+++ b/driver/gator_backtrace.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * Copyright (C) ARM Limited 2010-2013. All rights reserved. 2 * Copyright (C) ARM Limited 2010-2014. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
@@ -30,6 +30,18 @@ struct stack_frame_eabi {
30 }; 30 };
31}; 31};
32 32
33static void gator_add_trace(int cpu, unsigned long address)
34{
35 off_t offset = 0;
36 unsigned long cookie = get_address_cookie(cpu, current, address & ~1, &offset);
37
38 if (cookie == NO_COOKIE || cookie == UNRESOLVED_COOKIE) {
39 offset = address;
40 }
41
42 marshal_backtrace(offset & ~1, cookie, 0);
43}
44
33static void arm_backtrace_eabi(int cpu, struct pt_regs *const regs, unsigned int depth) 45static void arm_backtrace_eabi(int cpu, struct pt_regs *const regs, unsigned int depth)
34{ 46{
35#if defined(__arm__) || defined(__aarch64__) 47#if defined(__arm__) || defined(__aarch64__)
@@ -122,7 +134,7 @@ static int report_trace(struct stackframe *frame, void *d)
122 addr = addr - (unsigned long)mod->module_core; 134 addr = addr - (unsigned long)mod->module_core;
123 } 135 }
124#endif 136#endif
125 marshal_backtrace(addr & ~1, cookie); 137 marshal_backtrace(addr & ~1, cookie, 1);
126 (*depth)--; 138 (*depth)--;
127 } 139 }
128 140
@@ -136,7 +148,7 @@ static int report_trace(struct stackframe *frame, void *d)
136#if (defined(__arm__) || defined(__aarch64__)) && !defined(GATOR_KERNEL_STACK_UNWINDING) 148#if (defined(__arm__) || defined(__aarch64__)) && !defined(GATOR_KERNEL_STACK_UNWINDING)
137// Disabled by default 149// Disabled by default
138MODULE_PARM_DESC(kernel_stack_unwinding, "Allow kernel stack unwinding."); 150MODULE_PARM_DESC(kernel_stack_unwinding, "Allow kernel stack unwinding.");
139bool kernel_stack_unwinding = 0; 151static bool kernel_stack_unwinding = 0;
140module_param(kernel_stack_unwinding, bool, 0644); 152module_param(kernel_stack_unwinding, bool, 0644);
141#endif 153#endif
142 154
@@ -163,6 +175,34 @@ static void kernel_backtrace(int cpu, struct pt_regs *const regs)
163#endif 175#endif
164 walk_stackframe(&frame, report_trace, &depth); 176 walk_stackframe(&frame, report_trace, &depth);
165#else 177#else
166 marshal_backtrace(PC_REG & ~1, NO_COOKIE); 178 marshal_backtrace(PC_REG & ~1, NO_COOKIE, 1);
167#endif 179#endif
168} 180}
181
182static void gator_add_sample(int cpu, struct pt_regs *const regs, u64 time)
183{
184 bool in_kernel;
185 unsigned long exec_cookie;
186
187 if (!regs)
188 return;
189
190 in_kernel = !user_mode(regs);
191 exec_cookie = get_exec_cookie(cpu, current);
192
193 if (!marshal_backtrace_header(exec_cookie, current->tgid, current->pid, time))
194 return;
195
196 if (in_kernel) {
197 kernel_backtrace(cpu, regs);
198 } else {
199 // Cookie+PC
200 gator_add_trace(cpu, PC_REG);
201
202 // Backtrace
203 if (gator_backtrace_depth)
204 arm_backtrace_eabi(cpu, regs, gator_backtrace_depth);
205 }
206
207 marshal_backtrace_footer(time);
208}