linux/kernel/trace/trace_printk.c

// SPDX-License-Identifier: GPL-2.0
/*
 * trace binary printk
 *
 * Copyright (C) 2008 Lai Jiangshan <[email protected]>
 *
 */
#include <linux/seq_file.h>
#include <linux/security.h>
#include <linux/uaccess.h>
#include <linux/kernel.h>
#include <linux/ftrace.h>
#include <linux/string.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/ctype.h>
#include <linux/list.h>
#include <linux/slab.h>

#include "trace.h"

#ifdef CONFIG_MODULES

/*
 * modules trace_printk()'s formats are autosaved in struct trace_bprintk_fmt
 * which are queued on trace_bprintk_fmt_list.
 */
static LIST_HEAD(trace_bprintk_fmt_list);

/* serialize accesses to trace_bprintk_fmt_list */
static DEFINE_MUTEX(btrace_mutex);

struct trace_bprintk_fmt {};

static inline struct trace_bprintk_fmt *lookup_format(const char *fmt)
{}

static
void hold_module_trace_bprintk_format(const char **start, const char **end)
{}

static int module_trace_bprintk_format_notify(struct notifier_block *self,
		unsigned long val, void *data)
{}

/*
 * The debugfs/tracing/printk_formats file maps the addresses with
 * the ASCII formats that are used in the bprintk events in the
 * buffer. For userspace tools to be able to decode the events from
 * the buffer, they need to be able to map the address with the format.
 *
 * The addresses of the bprintk formats are in their own section
 * __trace_printk_fmt. But for modules we copy them into a link list.
 * The code to print the formats and their addresses passes around the
 * address of the fmt string. If the fmt address passed into the seq
 * functions is within the kernel core __trace_printk_fmt section, then
 * it simply uses the next pointer in the list.
 *
 * When the fmt pointer is outside the kernel core __trace_printk_fmt
 * section, then we need to read the link list pointers. The trick is
 * we pass the address of the string to the seq function just like
 * we do for the kernel core formats. To get back the structure that
 * holds the format, we simply use container_of() and then go to the
 * next format in the list.
 */
static const char **
find_next_mod_format(int start_index, void *v, const char **fmt, loff_t *pos)
{}

static void format_mod_start(void)
{}

static void format_mod_stop(void)
{}

#else /* !CONFIG_MODULES */
__init static int
module_trace_bprintk_format_notify(struct notifier_block *self,
		unsigned long val, void *data)
{
	return NOTIFY_OK;
}
static inline const char **
find_next_mod_format(int start_index, void *v, const char **fmt, loff_t *pos)
{
	return NULL;
}
static inline void format_mod_start(void) { }
static inline void format_mod_stop(void) { }
#endif /* CONFIG_MODULES */

static bool __read_mostly trace_printk_enabled =;

void trace_printk_control(bool enabled)
{}

__initdata_or_module static
struct notifier_block module_trace_bprintk_format_nb =;

int __trace_bprintk(unsigned long ip, const char *fmt, ...)
{}
EXPORT_SYMBOL_GPL();

int __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap)
{}
EXPORT_SYMBOL_GPL();

int __trace_printk(unsigned long ip, const char *fmt, ...)
{}
EXPORT_SYMBOL_GPL();

int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap)
{}
EXPORT_SYMBOL_GPL();

bool trace_is_tracepoint_string(const char *str)
{}

static const char **find_next(void *v, loff_t *pos)
{}

static void *
t_start(struct seq_file *m, loff_t *pos)
{}

static void *t_next(struct seq_file *m, void * v, loff_t *pos)
{}

static int t_show(struct seq_file *m, void *v)
{}

static void t_stop(struct seq_file *m, void *p)
{}

static const struct seq_operations show_format_seq_ops =;

static int
ftrace_formats_open(struct inode *inode, struct file *file)
{}

static const struct file_operations ftrace_formats_fops =;

static __init int init_trace_printk_function_export(void)
{}

fs_initcall(init_trace_printk_function_export);

static __init int init_trace_printk(void)
{}

early_initcall(init_trace_printk);