Commit 0ea2dc7c authored by Guo Ren's avatar Guo Ren
Browse files

csky: stacktrace supported.



The gcc option "-mbacktrace" will push fp(r8),lr into stack and we could
unwind the stack with:
	fp = *fp
	lr = (unsigned int *)fp[1]

Signed-off-by: default avatarGuo Ren <ren_guo@c-sky.com>
parent 859e5f45
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -94,6 +94,9 @@ config MMU
config RWSEM_GENERIC_SPINLOCK
	def_bool y

config STACKTRACE_SUPPORT
	def_bool y

config TIME_LOW_RES
	def_bool y

+4 −0
Original line number Diff line number Diff line
@@ -47,6 +47,10 @@ ifeq ($(CSKYABI),abiv2)
KBUILD_CFLAGS += -mno-stack-size
endif

ifdef CONFIG_STACKTRACE
KBUILD_CFLAGS += -mbacktrace
endif

abidirs := $(patsubst %,arch/csky/%/,$(CSKYABI))
KBUILD_CFLAGS += $(patsubst %,-I$(srctree)/%inc,$(abidirs))

+4 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include <asm/types.h>
#include <asm/page.h>
#include <asm/processor.h>
#include <abi/switch_context.h>

struct thread_info {
	struct task_struct	*task;
@@ -36,6 +37,9 @@ struct thread_info {

#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT)

#define thread_saved_fp(tsk) \
	((unsigned long)(((struct switch_stack *)(tsk->thread.ksp))->r8))

static inline struct thread_info *current_thread_info(void)
{
	unsigned long sp;
+1 −0
Original line number Diff line number Diff line
@@ -6,3 +6,4 @@ obj-y += process.o cpu-probe.o ptrace.o dumpstack.o

obj-$(CONFIG_MODULES)			+= module.o
obj-$(CONFIG_SMP)			+= smp.o
obj-$(CONFIG_STACKTRACE)		+= stacktrace.o
+17 −12
Original line number Diff line number Diff line
@@ -93,26 +93,31 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *pr_regs)

unsigned long get_wchan(struct task_struct *p)
{
	unsigned long esp, pc;
	unsigned long stack_page;
	unsigned long lr;
	unsigned long *fp, *stack_start, *stack_end;
	int count = 0;

	if (!p || p == current || p->state == TASK_RUNNING)
		return 0;

	stack_page = (unsigned long)p;
	esp = p->thread.esp0;
	stack_start = (unsigned long *)end_of_stack(p);
	stack_end = (unsigned long *)(task_stack_page(p) + THREAD_SIZE);

	fp = (unsigned long *) thread_saved_fp(p);
	do {
		if (esp < stack_page+sizeof(struct task_struct) ||
		    esp >= 8184+stack_page)
		if (fp < stack_start || fp > stack_end)
			return 0;
		/*FIXME: There's may be error here!*/
		pc = ((unsigned long *)esp)[1];
		/* FIXME: This depends on the order of these functions. */
		if (!in_sched_functions(pc))
			return pc;
		esp = *(unsigned long *) esp;
#ifdef CONFIG_STACKTRACE
		lr = fp[1];
		fp = (unsigned long *)fp[0];
#else
		lr = *fp++;
#endif
		if (!in_sched_functions(lr) &&
		    __kernel_text_address(lr))
			return lr;
	} while (count++ < 16);

	return 0;
}
EXPORT_SYMBOL(get_wchan);
Loading