#define pr_fmt(fmt) …
#include <linux/spinlock.h>
#include <linux/hardirq.h>
#include <linux/uaccess.h>
#include <linux/ftrace.h>
#include <linux/percpu.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/memory.h>
#include <linux/vmalloc.h>
#include <linux/set_memory.h>
#include <linux/execmem.h>
#include <trace/syscall.h>
#include <asm/kprobes.h>
#include <asm/ftrace.h>
#include <asm/nops.h>
#include <asm/text-patching.h>
#ifdef CONFIG_DYNAMIC_FTRACE
static int ftrace_poke_late = …;
void ftrace_arch_code_modify_prepare(void)
__acquires(&text_mutex)
{ … }
void ftrace_arch_code_modify_post_process(void)
__releases(&text_mutex)
{ … }
static const char *ftrace_nop_replace(void)
{ … }
static const char *ftrace_call_replace(unsigned long ip, unsigned long addr)
{ … }
static int ftrace_verify_code(unsigned long ip, const char *old_code)
{ … }
static int __ref
ftrace_modify_code_direct(unsigned long ip, const char *old_code,
const char *new_code)
{ … }
int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr)
{ … }
int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{ … }
int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
unsigned long addr)
{ … }
int ftrace_update_ftrace_func(ftrace_func_t func)
{ … }
void ftrace_replace_code(int enable)
{ … }
void arch_ftrace_update_code(int command)
{ … }
#ifdef CONFIG_X86_64
static inline void *alloc_tramp(unsigned long size)
{ … }
static inline void tramp_free(void *tramp)
{ … }
extern void ftrace_regs_caller_end(void);
extern void ftrace_caller_end(void);
extern void ftrace_caller_op_ptr(void);
extern void ftrace_regs_caller_op_ptr(void);
extern void ftrace_regs_caller_jmp(void);
#define OP_REF_SIZE …
ftrace_op_code_union;
#define RET_SIZE …
static unsigned long
create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
{ … }
void set_ftrace_ops_ro(void)
{ … }
static unsigned long calc_trampoline_call_offset(bool save_regs)
{ … }
void arch_ftrace_update_trampoline(struct ftrace_ops *ops)
{ … }
static void *addr_from_call(void *ptr)
{ … }
static void *static_tramp_func(struct ftrace_ops *ops, struct dyn_ftrace *rec)
{ … }
void *arch_ftrace_trampoline_func(struct ftrace_ops *ops, struct dyn_ftrace *rec)
{ … }
void arch_ftrace_trampoline_free(struct ftrace_ops *ops)
{ … }
#endif
#endif
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#if defined(CONFIG_DYNAMIC_FTRACE) && !defined(CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS)
extern void ftrace_graph_call(void);
static const char *ftrace_jmp_replace(unsigned long ip, unsigned long addr)
{
return text_gen_insn(JMP32_INSN_OPCODE, (void *)ip, (void *)addr);
}
static int ftrace_mod_jmp(unsigned long ip, void *func)
{
const char *new;
new = ftrace_jmp_replace(ip, (unsigned long)func);
text_poke_bp((void *)ip, new, MCOUNT_INSN_SIZE, NULL);
return 0;
}
int ftrace_enable_ftrace_graph_caller(void)
{
unsigned long ip = (unsigned long)(&ftrace_graph_call);
return ftrace_mod_jmp(ip, &ftrace_graph_caller);
}
int ftrace_disable_ftrace_graph_caller(void)
{
unsigned long ip = (unsigned long)(&ftrace_graph_call);
return ftrace_mod_jmp(ip, &ftrace_stub);
}
#endif
void prepare_ftrace_return(unsigned long ip, unsigned long *parent,
unsigned long frame_pointer)
{ … }
#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *op, struct ftrace_regs *fregs)
{ … }
#endif
#endif