#define pr_fmt(fmt) …
#include <linux/bpf-cgroup.h>
#include <linux/security.h>
#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/uprobes.h>
#include <linux/namei.h>
#include <linux/string.h>
#include <linux/rculist.h>
#include <linux/filter.h>
#include "trace_dynevent.h"
#include "trace_probe.h"
#include "trace_probe_tmpl.h"
#define UPROBE_EVENT_SYSTEM …
struct uprobe_trace_entry_head { … };
#define SIZEOF_TRACE_ENTRY(is_return) …
#define DATAOF_TRACE_ENTRY(entry, is_return) …
static int trace_uprobe_create(const char *raw_command);
static int trace_uprobe_show(struct seq_file *m, struct dyn_event *ev);
static int trace_uprobe_release(struct dyn_event *ev);
static bool trace_uprobe_is_busy(struct dyn_event *ev);
static bool trace_uprobe_match(const char *system, const char *event,
int argc, const char **argv, struct dyn_event *ev);
static struct dyn_event_operations trace_uprobe_ops = …;
struct trace_uprobe { … };
static bool is_trace_uprobe(struct dyn_event *ev)
{ … }
static struct trace_uprobe *to_trace_uprobe(struct dyn_event *ev)
{ … }
#define for_each_trace_uprobe(pos, dpos) …
static int register_uprobe_event(struct trace_uprobe *tu);
static int unregister_uprobe_event(struct trace_uprobe *tu);
static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs);
static int uretprobe_dispatcher(struct uprobe_consumer *con,
unsigned long func, struct pt_regs *regs);
#ifdef CONFIG_STACK_GROWSUP
static unsigned long adjust_stack_addr(unsigned long addr, unsigned int n)
{
return addr - (n * sizeof(long));
}
#else
static unsigned long adjust_stack_addr(unsigned long addr, unsigned int n)
{ … }
#endif
static unsigned long get_user_stack_nth(struct pt_regs *regs, unsigned int n)
{ … }
static nokprobe_inline int
probe_mem_read(void *dest, void *src, size_t size)
{ … }
static nokprobe_inline int
probe_mem_read_user(void *dest, void *src, size_t size)
{ … }
static nokprobe_inline int
fetch_store_string(unsigned long addr, void *dest, void *base)
{ … }
static nokprobe_inline int
fetch_store_string_user(unsigned long addr, void *dest, void *base)
{ … }
static nokprobe_inline int
fetch_store_strlen(unsigned long addr)
{ … }
static nokprobe_inline int
fetch_store_strlen_user(unsigned long addr)
{ … }
static unsigned long translate_user_vaddr(unsigned long file_offset)
{ … }
static int
process_fetch_insn(struct fetch_insn *code, void *rec, void *edata,
void *dest, void *base)
{ … }
NOKPROBE_SYMBOL(…)
static inline void init_trace_uprobe_filter(struct trace_uprobe_filter *filter)
{ … }
static inline bool uprobe_filter_is_empty(struct trace_uprobe_filter *filter)
{ … }
static inline bool is_ret_probe(struct trace_uprobe *tu)
{ … }
static bool trace_uprobe_is_busy(struct dyn_event *ev)
{ … }
static bool trace_uprobe_match_command_head(struct trace_uprobe *tu,
int argc, const char **argv)
{ … }
static bool trace_uprobe_match(const char *system, const char *event,
int argc, const char **argv, struct dyn_event *ev)
{ … }
static nokprobe_inline struct trace_uprobe *
trace_uprobe_primary_from_call(struct trace_event_call *call)
{ … }
static struct trace_uprobe *
alloc_trace_uprobe(const char *group, const char *event, int nargs, bool is_ret)
{ … }
static void free_trace_uprobe(struct trace_uprobe *tu)
{ … }
static struct trace_uprobe *find_probe_event(const char *event, const char *group)
{ … }
static int unregister_trace_uprobe(struct trace_uprobe *tu)
{ … }
static bool trace_uprobe_has_same_uprobe(struct trace_uprobe *orig,
struct trace_uprobe *comp)
{ … }
static int append_trace_uprobe(struct trace_uprobe *tu, struct trace_uprobe *to)
{ … }
static int validate_ref_ctr_offset(struct trace_uprobe *new)
{ … }
static int register_trace_uprobe(struct trace_uprobe *tu)
{ … }
static int __trace_uprobe_create(int argc, const char **argv)
{ … }
int trace_uprobe_create(const char *raw_command)
{ … }
static int create_or_delete_trace_uprobe(const char *raw_command)
{ … }
static int trace_uprobe_release(struct dyn_event *ev)
{ … }
static int trace_uprobe_show(struct seq_file *m, struct dyn_event *ev)
{ … }
static int probes_seq_show(struct seq_file *m, void *v)
{ … }
static const struct seq_operations probes_seq_op = …;
static int probes_open(struct inode *inode, struct file *file)
{ … }
static ssize_t probes_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations uprobe_events_ops = …;
static int probes_profile_seq_show(struct seq_file *m, void *v)
{ … }
static const struct seq_operations profile_seq_op = …;
static int profile_open(struct inode *inode, struct file *file)
{ … }
static const struct file_operations uprobe_profile_ops = …;
struct uprobe_cpu_buffer { … };
static struct uprobe_cpu_buffer __percpu *uprobe_cpu_buffer;
static int uprobe_buffer_refcnt;
static int uprobe_buffer_init(void)
{ … }
static int uprobe_buffer_enable(void)
{ … }
static void uprobe_buffer_disable(void)
{ … }
static struct uprobe_cpu_buffer *uprobe_buffer_get(void)
{ … }
static void uprobe_buffer_put(struct uprobe_cpu_buffer *ucb)
{ … }
static struct uprobe_cpu_buffer *prepare_uprobe_buffer(struct trace_uprobe *tu,
struct pt_regs *regs,
struct uprobe_cpu_buffer **ucbp)
{ … }
static void __uprobe_trace_func(struct trace_uprobe *tu,
unsigned long func, struct pt_regs *regs,
struct uprobe_cpu_buffer *ucb,
struct trace_event_file *trace_file)
{ … }
static int uprobe_trace_func(struct trace_uprobe *tu, struct pt_regs *regs,
struct uprobe_cpu_buffer **ucbp)
{ … }
static void uretprobe_trace_func(struct trace_uprobe *tu, unsigned long func,
struct pt_regs *regs,
struct uprobe_cpu_buffer **ucbp)
{ … }
static enum print_line_t
print_uprobe_event(struct trace_iterator *iter, int flags, struct trace_event *event)
{ … }
filter_func_t;
static int trace_uprobe_enable(struct trace_uprobe *tu, filter_func_t filter)
{ … }
static void __probe_event_disable(struct trace_probe *tp)
{ … }
static int probe_event_enable(struct trace_event_call *call,
struct trace_event_file *file, filter_func_t filter)
{ … }
static void probe_event_disable(struct trace_event_call *call,
struct trace_event_file *file)
{ … }
static int uprobe_event_define_fields(struct trace_event_call *event_call)
{ … }
#ifdef CONFIG_PERF_EVENTS
static bool
__uprobe_perf_filter(struct trace_uprobe_filter *filter, struct mm_struct *mm)
{ … }
static inline bool
trace_uprobe_filter_event(struct trace_uprobe_filter *filter,
struct perf_event *event)
{ … }
static bool trace_uprobe_filter_remove(struct trace_uprobe_filter *filter,
struct perf_event *event)
{ … }
static bool trace_uprobe_filter_add(struct trace_uprobe_filter *filter,
struct perf_event *event)
{ … }
static int uprobe_perf_close(struct trace_event_call *call,
struct perf_event *event)
{ … }
static int uprobe_perf_open(struct trace_event_call *call,
struct perf_event *event)
{ … }
static bool uprobe_perf_filter(struct uprobe_consumer *uc,
enum uprobe_filter_ctx ctx, struct mm_struct *mm)
{ … }
static void __uprobe_perf_func(struct trace_uprobe *tu,
unsigned long func, struct pt_regs *regs,
struct uprobe_cpu_buffer **ucbp)
{ … }
static int uprobe_perf_func(struct trace_uprobe *tu, struct pt_regs *regs,
struct uprobe_cpu_buffer **ucbp)
{ … }
static void uretprobe_perf_func(struct trace_uprobe *tu, unsigned long func,
struct pt_regs *regs,
struct uprobe_cpu_buffer **ucbp)
{ … }
int bpf_get_uprobe_info(const struct perf_event *event, u32 *fd_type,
const char **filename, u64 *probe_offset,
u64 *probe_addr, bool perf_type_tracepoint)
{ … }
#endif
static int
trace_uprobe_register(struct trace_event_call *event, enum trace_reg type,
void *data)
{ … }
static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs)
{ … }
static int uretprobe_dispatcher(struct uprobe_consumer *con,
unsigned long func, struct pt_regs *regs)
{ … }
static struct trace_event_functions uprobe_funcs = …;
static struct trace_event_fields uprobe_fields_array[] = …;
static inline void init_trace_event_call(struct trace_uprobe *tu)
{ … }
static int register_uprobe_event(struct trace_uprobe *tu)
{ … }
static int unregister_uprobe_event(struct trace_uprobe *tu)
{ … }
#ifdef CONFIG_PERF_EVENTS
struct trace_event_call *
create_local_trace_uprobe(char *name, unsigned long offs,
unsigned long ref_ctr_offset, bool is_return)
{ … }
void destroy_local_trace_uprobe(struct trace_event_call *event_call)
{ … }
#endif
static __init int init_uprobe_trace(void)
{ … }
fs_initcall(init_uprobe_trace);