Commit b83b43ff authored by Steven Rostedt (VMware)'s avatar Steven Rostedt (VMware)
Browse files

fgraph: Fix function type mismatches of ftrace_graph_return using ftrace_stub

The C compiler is allowing more checks to make sure that function pointers
are assigned to the correct prototype function. Unfortunately, the function
graph tracer uses a special name with its assigned ftrace_graph_return
function pointer that maps to a stub function used by the function tracer
(ftrace_stub). The ftrace_graph_return variable is compared to the
ftrace_stub in some archs to know if the function graph tracer is enabled or
not. This means we can not just simply create a new function stub that
compares it without modifying all the archs.

Instead, have the linker script create a function_graph_stub that maps to
ftrace_stub, and this way we can define the prototype for it to match the
prototype of ftrace_graph_return, and make the compiler checks all happy!

Link: http://lkml.kernel.org/r/20191015090055.789a0aed@gandalf.local.home



Cc: linux-sh@vger.kernel.org
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc:  Rich Felker <dalias@libc.org>
Reported-by: default avatarSami Tolvanen <samitolvanen@google.com>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent 953ae45a
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -111,6 +111,11 @@ void __stack_chk_fail(void)
	error("stack-protector: Kernel stack is corrupted\n");
	error("stack-protector: Kernel stack is corrupted\n");
}
}


/* Needed because vmlinux.lds.h references this */
void ftrace_stub(void)
{
}

#ifdef CONFIG_SUPERH64
#ifdef CONFIG_SUPERH64
#define stackalign	8
#define stackalign	8
#else
#else
+14 −3
Original line number Original line Diff line number Diff line
@@ -111,19 +111,30 @@


#ifdef CONFIG_FTRACE_MCOUNT_RECORD
#ifdef CONFIG_FTRACE_MCOUNT_RECORD
#ifdef CC_USING_PATCHABLE_FUNCTION_ENTRY
#ifdef CC_USING_PATCHABLE_FUNCTION_ENTRY
/*
 * Need to also make ftrace_graph_stub point to ftrace_stub
 * so that the same stub location may have different protocols
 * and not mess up with C verifiers.
 */
#define MCOUNT_REC()	. = ALIGN(8);				\
#define MCOUNT_REC()	. = ALIGN(8);				\
			__start_mcount_loc = .;			\
			__start_mcount_loc = .;			\
			KEEP(*(__patchable_function_entries))	\
			KEEP(*(__patchable_function_entries))	\
			__stop_mcount_loc = .;
			__stop_mcount_loc = .;			\
			ftrace_graph_stub = ftrace_stub;
#else
#else
#define MCOUNT_REC()	. = ALIGN(8);				\
#define MCOUNT_REC()	. = ALIGN(8);				\
			__start_mcount_loc = .;			\
			__start_mcount_loc = .;			\
			KEEP(*(__mcount_loc))			\
			KEEP(*(__mcount_loc))			\
			__stop_mcount_loc = .;
			__stop_mcount_loc = .;			\
			ftrace_graph_stub = ftrace_stub;
#endif
#endif
#else
#else
# ifdef CONFIG_FUNCTION_TRACER
#  define MCOUNT_REC()	ftrace_graph_stub = ftrace_stub;
# else
#  define MCOUNT_REC()
#  define MCOUNT_REC()
# endif
# endif
#endif


#ifdef CONFIG_TRACE_BRANCH_PROFILING
#ifdef CONFIG_TRACE_BRANCH_PROFILING
#define LIKELY_PROFILE()	__start_annotated_branch_profile = .;	\
#define LIKELY_PROFILE()	__start_annotated_branch_profile = .;	\
+8 −3
Original line number Original line Diff line number Diff line
@@ -332,9 +332,14 @@ int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
	return 0;
	return 0;
}
}


/*
 * Simply points to ftrace_stub, but with the proper protocol.
 * Defined by the linker script in linux/vmlinux.lds.h
 */
extern void ftrace_graph_stub(struct ftrace_graph_ret *);

/* The callbacks that hook a function */
/* The callbacks that hook a function */
trace_func_graph_ret_t ftrace_graph_return =
trace_func_graph_ret_t ftrace_graph_return = ftrace_graph_stub;
			(trace_func_graph_ret_t)ftrace_stub;
trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub;
trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub;
static trace_func_graph_ent_t __ftrace_graph_entry = ftrace_graph_entry_stub;
static trace_func_graph_ent_t __ftrace_graph_entry = ftrace_graph_entry_stub;


@@ -614,7 +619,7 @@ void unregister_ftrace_graph(struct fgraph_ops *gops)
		goto out;
		goto out;


	ftrace_graph_active--;
	ftrace_graph_active--;
	ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
	ftrace_graph_return = ftrace_graph_stub;
	ftrace_graph_entry = ftrace_graph_entry_stub;
	ftrace_graph_entry = ftrace_graph_entry_stub;
	__ftrace_graph_entry = ftrace_graph_entry_stub;
	__ftrace_graph_entry = ftrace_graph_entry_stub;
	ftrace_shutdown(&graph_ops, FTRACE_STOP_FUNC_RET);
	ftrace_shutdown(&graph_ops, FTRACE_STOP_FUNC_RET);