linux/kernel/trace/trace_syscalls.c

// SPDX-License-Identifier: GPL-2.0
#include <trace/syscall.h>
#include <trace/events/syscalls.h>
#include <linux/syscalls.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>	/* for MODULE_NAME_LEN via KSYM_SYMBOL_LEN */
#include <linux/ftrace.h>
#include <linux/perf_event.h>
#include <linux/xarray.h>
#include <asm/syscall.h>

#include "trace_output.h"
#include "trace.h"

static DEFINE_MUTEX(syscall_trace_lock);

static int syscall_enter_register(struct trace_event_call *event,
				 enum trace_reg type, void *data);
static int syscall_exit_register(struct trace_event_call *event,
				 enum trace_reg type, void *data);

static struct list_head *
syscall_get_enter_fields(struct trace_event_call *call)
{}

extern struct syscall_metadata *__start_syscalls_metadata[];
extern struct syscall_metadata *__stop_syscalls_metadata[];

static DEFINE_XARRAY(syscalls_metadata_sparse);
static struct syscall_metadata **syscalls_metadata;

#ifndef ARCH_HAS_SYSCALL_MATCH_SYM_NAME
static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
{
	/*
	 * Only compare after the "sys" prefix. Archs that use
	 * syscall wrappers may have syscalls symbols aliases prefixed
	 * with ".SyS" or ".sys" instead of "sys", leading to an unwanted
	 * mismatch.
	 */
	return !strcmp(sym + 3, name + 3);
}
#endif

#ifdef ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
/*
 * Some architectures that allow for 32bit applications
 * to run on a 64bit kernel, do not map the syscalls for
 * the 32bit tasks the same as they do for 64bit tasks.
 *
 *     *cough*x86*cough*
 *
 * In such a case, instead of reporting the wrong syscalls,
 * simply ignore them.
 *
 * For an arch to ignore the compat syscalls it needs to
 * define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS as well as
 * define the function arch_trace_is_compat_syscall() to let
 * the tracing system know that it should ignore it.
 */
static int
trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs)
{}
#else
static inline int
trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs)
{
	return syscall_get_nr(task, regs);
}
#endif /* ARCH_TRACE_IGNORE_COMPAT_SYSCALLS */

static __init struct syscall_metadata *
find_syscall_meta(unsigned long syscall)
{}

static struct syscall_metadata *syscall_nr_to_meta(int nr)
{}

const char *get_syscall_name(int syscall)
{}

static enum print_line_t
print_syscall_enter(struct trace_iterator *iter, int flags,
		    struct trace_event *event)
{}

static enum print_line_t
print_syscall_exit(struct trace_iterator *iter, int flags,
		   struct trace_event *event)
{}

#define SYSCALL_FIELD(_type, _name)

static int __init
__set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len)
{}

static int __init set_syscall_print_fmt(struct trace_event_call *call)
{}

static void __init free_syscall_print_fmt(struct trace_event_call *call)
{}

static int __init syscall_enter_define_fields(struct trace_event_call *call)
{}

static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
{}

static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
{}

static int reg_event_syscall_enter(struct trace_event_file *file,
				   struct trace_event_call *call)
{}

static void unreg_event_syscall_enter(struct trace_event_file *file,
				      struct trace_event_call *call)
{}

static int reg_event_syscall_exit(struct trace_event_file *file,
				  struct trace_event_call *call)
{}

static void unreg_event_syscall_exit(struct trace_event_file *file,
				     struct trace_event_call *call)
{}

static int __init init_syscall_trace(struct trace_event_call *call)
{}

static struct trace_event_fields __refdata syscall_enter_fields_array[] =;

struct trace_event_functions enter_syscall_print_funcs =;

struct trace_event_functions exit_syscall_print_funcs =;

struct trace_event_class __refdata event_class_syscall_enter =;

struct trace_event_class __refdata event_class_syscall_exit =;

unsigned long __init __weak arch_syscall_addr(int nr)
{}

void __init init_ftrace_syscalls(void)
{}

#ifdef CONFIG_PERF_EVENTS

static DECLARE_BITMAP(enabled_perf_enter_syscalls, NR_syscalls);
static DECLARE_BITMAP(enabled_perf_exit_syscalls, NR_syscalls);
static int sys_perf_refcount_enter;
static int sys_perf_refcount_exit;

static int perf_call_bpf_enter(struct trace_event_call *call, struct pt_regs *regs,
			       struct syscall_metadata *sys_data,
			       struct syscall_trace_enter *rec)
{}

static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
{}

static int perf_sysenter_enable(struct trace_event_call *call)
{}

static void perf_sysenter_disable(struct trace_event_call *call)
{}

static int perf_call_bpf_exit(struct trace_event_call *call, struct pt_regs *regs,
			      struct syscall_trace_exit *rec)
{}

static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
{}

static int perf_sysexit_enable(struct trace_event_call *call)
{}

static void perf_sysexit_disable(struct trace_event_call *call)
{}

#endif /* CONFIG_PERF_EVENTS */

static int syscall_enter_register(struct trace_event_call *event,
				 enum trace_reg type, void *data)
{}

static int syscall_exit_register(struct trace_event_call *event,
				 enum trace_reg type, void *data)
{}