Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e377ae9 authored by Zong Li's avatar Zong Li Committed by Greentime Hu
Browse files

nds32/stack: Get real return address by using ftrace_graph_ret_addr



Function graph tracer has modified the return address to
'return_to_handler' on stack, and provide the 'ftrace_graph_ret_addr' to
get the real return address.

Signed-off-by: default avatarZong Li <zong@andestech.com>
Acked-by: default avatarGreentime Hu <greentime@andestech.com>
Signed-off-by: default avatarGreentime Hu <greentime@andestech.com>
parent 95cd2f7b
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -4,6 +4,7 @@
#include <linux/sched/debug.h>
#include <linux/sched/debug.h>
#include <linux/sched/task_stack.h>
#include <linux/sched/task_stack.h>
#include <linux/stacktrace.h>
#include <linux/stacktrace.h>
#include <linux/ftrace.h>


void save_stack_trace(struct stack_trace *trace)
void save_stack_trace(struct stack_trace *trace)
{
{
@@ -16,6 +17,7 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
	unsigned long *fpn;
	unsigned long *fpn;
	int skip = trace->skip;
	int skip = trace->skip;
	int savesched;
	int savesched;
	int graph_idx = 0;


	if (tsk == current) {
	if (tsk == current) {
		__asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn));
		__asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn));
@@ -33,6 +35,8 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
		fpp = fpn[FP_OFFSET];
		fpp = fpn[FP_OFFSET];
		if (!__kernel_text_address(lpp))
		if (!__kernel_text_address(lpp))
			break;
			break;
		else
			lpp = ftrace_graph_ret_addr(tsk, &graph_idx, lpp, NULL);


		if (savesched || !in_sched_functions(lpp)) {
		if (savesched || !in_sched_functions(lpp)) {
			if (skip) {
			if (skip) {
+6 −24
Original line number Original line Diff line number Diff line
@@ -8,6 +8,7 @@
#include <linux/kdebug.h>
#include <linux/kdebug.h>
#include <linux/sched/task_stack.h>
#include <linux/sched/task_stack.h>
#include <linux/uaccess.h>
#include <linux/uaccess.h>
#include <linux/ftrace.h>


#include <asm/proc-fns.h>
#include <asm/proc-fns.h>
#include <asm/unistd.h>
#include <asm/unistd.h>
@@ -94,28 +95,6 @@ static void dump_instr(struct pt_regs *regs)
	set_fs(fs);
	set_fs(fs);
}
}


#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#include <linux/ftrace.h>
static void
get_real_ret_addr(unsigned long *addr, struct task_struct *tsk, int *graph)
{
	if (*addr == (unsigned long)return_to_handler) {
		int index = tsk->curr_ret_stack;

		if (tsk->ret_stack && index >= *graph) {
			index -= *graph;
			*addr = tsk->ret_stack[index].ret;
			(*graph)++;
		}
	}
}
#else
static inline void
get_real_ret_addr(unsigned long *addr, struct task_struct *tsk, int *graph)
{
}
#endif

#define LOOP_TIMES (100)
#define LOOP_TIMES (100)
static void __dump(struct task_struct *tsk, unsigned long *base_reg)
static void __dump(struct task_struct *tsk, unsigned long *base_reg)
{
{
@@ -126,7 +105,8 @@ static void __dump(struct task_struct *tsk, unsigned long *base_reg)
		while (!kstack_end(base_reg)) {
		while (!kstack_end(base_reg)) {
			ret_addr = *base_reg++;
			ret_addr = *base_reg++;
			if (__kernel_text_address(ret_addr)) {
			if (__kernel_text_address(ret_addr)) {
				get_real_ret_addr(&ret_addr, tsk, &graph);
				ret_addr = ftrace_graph_ret_addr(
						tsk, &graph, ret_addr, NULL);
				print_ip_sym(ret_addr);
				print_ip_sym(ret_addr);
			}
			}
			if (--cnt < 0)
			if (--cnt < 0)
@@ -145,7 +125,9 @@ static void __dump(struct task_struct *tsk, unsigned long *base_reg)
			next_fp = base_reg[FP_OFFSET];
			next_fp = base_reg[FP_OFFSET];
#endif
#endif
			if (__kernel_text_address(ret_addr)) {
			if (__kernel_text_address(ret_addr)) {
				get_real_ret_addr(&ret_addr, tsk, &graph);

				ret_addr = ftrace_graph_ret_addr(
						tsk, &graph, ret_addr, NULL);
				print_ip_sym(ret_addr);
				print_ip_sym(ret_addr);
			}
			}
			if (--cnt < 0)
			if (--cnt < 0)