diff options
Diffstat (limited to 'driver/gator_backtrace.c')
-rw-r--r-- | driver/gator_backtrace.c | 48 |
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 | ||
33 | static 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 | |||
33 | static void arm_backtrace_eabi(int cpu, struct pt_regs *const regs, unsigned int depth) | 45 | static 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 |
138 | MODULE_PARM_DESC(kernel_stack_unwinding, "Allow kernel stack unwinding."); | 150 | MODULE_PARM_DESC(kernel_stack_unwinding, "Allow kernel stack unwinding."); |
139 | bool kernel_stack_unwinding = 0; | 151 | static bool kernel_stack_unwinding = 0; |
140 | module_param(kernel_stack_unwinding, bool, 0644); | 152 | module_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 | |||
182 | static 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 | } | ||