// SPDX-License-Identifier: GPL-2.0 /* * fprobe - Simple ftrace probe wrapper for function entry. */ #define pr_fmt(fmt) … #include <linux/err.h> #include <linux/fprobe.h> #include <linux/kallsyms.h> #include <linux/kprobes.h> #include <linux/rethook.h> #include <linux/slab.h> #include <linux/sort.h> #include "trace.h" struct fprobe_rethook_node { … }; static inline void __fprobe_handler(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct ftrace_regs *fregs) { … } static void fprobe_handler(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct ftrace_regs *fregs) { … } NOKPROBE_SYMBOL(fprobe_handler); static void fprobe_kprobe_handler(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *ops, struct ftrace_regs *fregs) { … } static void fprobe_exit_handler(struct rethook_node *rh, void *data, unsigned long ret_ip, struct pt_regs *regs) { … } NOKPROBE_SYMBOL(fprobe_exit_handler); static int symbols_cmp(const void *a, const void *b) { … } /* Convert ftrace location address from symbols */ static unsigned long *get_ftrace_locations(const char **syms, int num) { … } static void fprobe_init(struct fprobe *fp) { … } static int fprobe_init_rethook(struct fprobe *fp, int num) { … } static void fprobe_fail_cleanup(struct fprobe *fp) { … } /** * register_fprobe() - Register fprobe to ftrace by pattern. * @fp: A fprobe data structure to be registered. * @filter: A wildcard pattern of probed symbols. * @notfilter: A wildcard pattern of NOT probed symbols. * * Register @fp to ftrace for enabling the probe on the symbols matched to @filter. * If @notfilter is not NULL, the symbols matched the @notfilter are not probed. * * Return 0 if @fp is registered successfully, -errno if not. */ int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter) { … } EXPORT_SYMBOL_GPL(…); /** * register_fprobe_ips() - Register fprobe to ftrace by address. * @fp: A fprobe data structure to be registered. * @addrs: An array of target ftrace location addresses. * @num: The number of entries of @addrs. * * Register @fp to ftrace for enabling the probe on the address given by @addrs. * The @addrs must be the addresses of ftrace location address, which may be * the symbol address + arch-dependent offset. * If you unsure what this mean, please use other registration functions. * * Return 0 if @fp is registered successfully, -errno if not. */ int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num) { … } EXPORT_SYMBOL_GPL(…); /** * register_fprobe_syms() - Register fprobe to ftrace by symbols. * @fp: A fprobe data structure to be registered. * @syms: An array of target symbols. * @num: The number of entries of @syms. * * Register @fp to the symbols given by @syms array. This will be useful if * you are sure the symbols exist in the kernel. * * Return 0 if @fp is registered successfully, -errno if not. */ int register_fprobe_syms(struct fprobe *fp, const char **syms, int num) { … } EXPORT_SYMBOL_GPL(…); bool fprobe_is_registered(struct fprobe *fp) { … } /** * unregister_fprobe() - Unregister fprobe from ftrace * @fp: A fprobe data structure to be unregistered. * * Unregister fprobe (and remove ftrace hooks from the function entries). * * Return 0 if @fp is unregistered successfully, -errno if not. */ int unregister_fprobe(struct fprobe *fp) { … } EXPORT_SYMBOL_GPL(…);