microblaze: Add stack unwinder
Implement intelligent backtracing by searching for stack frame creation, and emitting only return addresses. Use print_hex_dump() to display the entire binary kernel stack. Limitation: MMU kernels are not currently able to trace beyond a system trap (interrupt, syscall, etc.). It is the intent of this patch to provide infrastructure that can be extended to add this capability later. Changes from V1: * Removed checks in find_frame_creation() that prevented location of the frame creation instruction in heavily optimized code * Various formatting/commenting/file location tweaks per review comments * Dropped Kconfig option to enable STACKTRACE as something logically separate Signed-off-by: Steven J. Magnani <steve@digidescorp.com>
This commit is contained in:
committed by
Michal Simek
parent
ba9c4f88d7
commit
ce3266c047
@@ -14,52 +14,18 @@
|
||||
#include <linux/thread_info.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/unwind.h>
|
||||
|
||||
/* FIXME initial support */
|
||||
void save_stack_trace(struct stack_trace *trace)
|
||||
{
|
||||
unsigned long *sp;
|
||||
unsigned long addr;
|
||||
asm("addik %0, r1, 0" : "=r" (sp));
|
||||
|
||||
while (!kstack_end(sp)) {
|
||||
addr = *sp++;
|
||||
if (__kernel_text_address(addr)) {
|
||||
if (trace->skip > 0)
|
||||
trace->skip--;
|
||||
else
|
||||
trace->entries[trace->nr_entries++] = addr;
|
||||
|
||||
if (trace->nr_entries >= trace->max_entries)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Exclude our helper functions from the trace*/
|
||||
trace->skip += 2;
|
||||
microblaze_unwind(NULL, trace);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace);
|
||||
|
||||
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
|
||||
{
|
||||
unsigned int *sp;
|
||||
unsigned long addr;
|
||||
|
||||
struct thread_info *ti = task_thread_info(tsk);
|
||||
|
||||
if (tsk == current)
|
||||
asm("addik %0, r1, 0" : "=r" (sp));
|
||||
else
|
||||
sp = (unsigned int *)ti->cpu_context.r1;
|
||||
|
||||
while (!kstack_end(sp)) {
|
||||
addr = *sp++;
|
||||
if (__kernel_text_address(addr)) {
|
||||
if (trace->skip > 0)
|
||||
trace->skip--;
|
||||
else
|
||||
trace->entries[trace->nr_entries++] = addr;
|
||||
|
||||
if (trace->nr_entries >= trace->max_entries)
|
||||
break;
|
||||
}
|
||||
}
|
||||
microblaze_unwind(tsk, trace);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
|
||||
|
||||
Reference in New Issue
Block a user