Skip to contentSkip to conversation

microblaze: add stack unwinder

PATCH New Steven J. Magnani 1 participant 1 message Apr 27, 2010 Microblaze architecture

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 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

---

arch/microblaze/include/asm/exceptions.h +5 -0
diff -uprN a/arch/microblaze/include/asm/exceptions.h b/arch/microblaze/include/asm/exceptions.h
@@ -14,6 +14,11 @@
 #define _ASM_MICROBLAZE_EXCEPTIONS_H
 
 #ifdef __KERNEL__
+
+#ifndef CONFIG_MMU
+#define EX_HANDLER_STACK_SIZ	(4*19)
+#endif
+
 #ifndef __ASSEMBLY__
 
 /* Macros to enable and disable HW exceptions in the MSR */
arch/microblaze/include/asm/system.h +0 -1
diff -uprN a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h
@@ -44,7 +44,6 @@ extern struct task_struct *_switch_to(st
 #define smp_rmb()		rmb()
 #define smp_wmb()		wmb()
 
-void show_trace(struct task_struct *task, unsigned long *stack);
 void __bad_xchg(volatile void *ptr, int size);
 
 static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
arch/microblaze/include/asm/unwind.h +29 -0
diff -uprN a/arch/microblaze/include/asm/unwind.h b/arch/microblaze/include/asm/unwind.h
@@ -0,0 +1,29 @@
+/*
+ * Backtrace support for Microblaze
+ *
+ * Copyright (C) 2010  Digital Design Corporation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __MICROBLAZE_UNWIND_H
+#define __MICROBLAZE_UNWIND_H
+
+struct stack_trace;
+
+struct trap_handler_info {
+	unsigned long start_addr;
+	unsigned long end_addr;
+	const char    *trap_name;
+};
+extern struct trap_handler_info microblaze_trap_handlers;
+
+extern const char _hw_exception_handler;
+extern const char ex_handler_unhandled;
+
+void microblaze_unwind(struct task_struct *task, struct stack_trace *trace);
+
+#endif	/* __MICROBLAZE_UNWIND_H */
+
arch/microblaze/kernel/entry-nommu.S +28 -0
diff -uprN a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
@@ -586,3 +586,31 @@ sys_rt_sigsuspend_wrapper:
 #include "syscall_table.S"
 
 syscall_table_size=(.-sys_call_table)
+
+type_SYSCALL:
+	.ascii "SYSCALL\0"
+type_IRQ:
+	.ascii "IRQ\0"
+type_IRQ_PREEMPT:
+	.ascii "IRQ (PREEMPTED)\0"
+type_SYSCALL_PREEMPT:
+	.ascii " SYSCALL (PREEMPTED)\0"
+
+	/*
+	 * Trap decoding for stack unwinder
+	 * Tuples are (start addr, end addr, string)
+	 * If return address lies on [start addr, end addr],
+	 * unwinder displays 'string'
+	 */
+
+	.align 4
+.global microblaze_trap_handlers
+microblaze_trap_handlers:
+	/* Exact matches come first */
+	.word ret_to_user  ; .word ret_to_user    ; .word type_SYSCALL
+	.word ret_from_intr; .word ret_from_intr  ; .word type_IRQ
+	/* Fuzzy matches go here */
+	.word ret_from_intr; .word no_intr_resched; .word type_IRQ_PREEMPT
+	.word work_pending ; .word no_work_pending; .word type_SYSCALL_PREEMPT
+	/* End of table */
+	.word 0             ; .word 0               ; .word 0
arch/microblaze/kernel/entry.S +27 -0
diff -uprN a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
@@ -1127,3 +1127,30 @@ ENTRY(_break)
 
 syscall_table_size=(.-sys_call_table)
 
+type_SYSCALL:
+	.ascii "SYSCALL\0"
+type_IRQ:
+	.ascii "IRQ\0"
+type_IRQ_PREEMPT:
+	.ascii "IRQ (PREEMPTED)\0"
+type_SYSCALL_PREEMPT:
+	.ascii " SYSCALL (PREEMPTED)\0"
+
+	/*
+	 * Trap decoding for stack unwinder
+	 * Tuples are (start addr, end addr, string)
+	 * If return address lies on [start addr, end addr],
+	 * unwinder displays 'string'
+	 */
+
+	.align 4
+.global microblaze_trap_handlers
+microblaze_trap_handlers:
+	/* Exact matches come first */
+	.word ret_from_trap; .word ret_from_trap   ; .word type_SYSCALL
+	.word ret_from_irq ; .word ret_from_irq    ; .word type_IRQ
+	/* Fuzzy matches go here */
+	.word ret_from_irq ; .word no_intr_resched ; .word type_IRQ_PREEMPT
+	.word ret_from_trap; .word TRAP_return     ; .word type_SYSCALL_PREEMPT
+	/* End of table */
+	.word 0               ; .word 0               ; .word 0
arch/microblaze/kernel/hw_exception_handler.S +1 -3
diff -uprN a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
@@ -78,9 +78,6 @@
 #include <asm/asm-offsets.h>
 
 /* Helpful Macros */
-#ifndef CONFIG_MMU
-#define EX_HANDLER_STACK_SIZ	(4*19)
-#endif
 #define NUM_TO_REG(num)		r ## num
 
 #ifdef CONFIG_MMU
@@ -988,6 +985,7 @@ ex_unaligned_fixup:
 .end _unaligned_data_exception
 #endif /* CONFIG_MMU */
 
+.global ex_handler_unhandled
 ex_handler_unhandled:
 /* FIXME add handle function for unhandled exception - dump register */
 	bri 0
arch/microblaze/kernel/Makefile +1 -1
diff -uprN a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
@@ -17,7 +17,7 @@ extra-y := head.o vmlinux.lds
 obj-y += dma.o exceptions.o \
 	hw_exception_handler.o init_task.o intc.o irq.o of_device.o \
 	of_platform.o process.o prom.o prom_parse.o ptrace.o \
-	setup.o signal.o sys_microblaze.o timer.o traps.o reset.o
+	reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o
 
 obj-y += cpu/
 
arch/microblaze/kernel/stacktrace.c +5 -39

57 lines not on this page · raw message

arch/microblaze/kernel/traps.c +39 -50

117 lines not on this page · raw message

arch/microblaze/kernel/unwind.c +318 -0

318 lines not on this page · raw message