// SPDX-License-Identifier: GPL-2.0
/*
 * Userspace indexing of printk formats
 */

#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/slab.h>
#include <linux/string_helpers.h>

#include "internal.h"

extern struct pi_entry *__start_printk_index[];
extern struct pi_entry *__stop_printk_index[];

/* The base dir for module formats, typically debugfs/printk/index/ */
static struct dentry *dfs_index;

static struct pi_entry *pi_get_entry(const struct module *mod, loff_t pos)
{
	struct pi_entry **entries;
	unsigned int nr_entries;

#ifdef CONFIG_MODULES
	if (mod) {
		entries = mod->printk_index_start;
		nr_entries = mod->printk_index_size;
	}
#endif

	if (!mod) {
		/* vmlinux, comes from linker symbols */
		entries = __start_printk_index;
		nr_entries = __stop_printk_index - __start_printk_index;
	}

	if (pos >= nr_entries)
		return NULL;

	return entries[pos];
}

static void *pi_next(struct seq_file *s, void *v, loff_t *pos)
{
	const struct module *mod = s->file->f_inode->i_private;
	struct pi_entry *entry = pi_get_entry(mod, *pos);

	(*pos)++;

	return entry;
}

static void *pi_start(struct seq_file *s, loff_t *pos)
{
	/*
	 * Make show() print the header line. Do not update *pos because
	 * pi_next() still has to return the entry at index 0 later.
	 */
	if (*pos == 0)
		return SEQ_START_TOKEN;

	return pi_next(s, NULL, pos);
}

/*
 * We need both ESCAPE_ANY and explicit characters from ESCAPE_SPECIAL in @only
 * because otherwise ESCAPE_NAP will cause double quotes and backslashes to be
 * ignored for quoting.
 */
#define seq_escape_printf_format(s, src) \
	seq_escape_str(s, src, ESCAPE_ANY | ESCAPE_NAP | ESCAPE_APPEND, "\"\\")

static int pi_show(struct seq_file *s, void *v)
{
	const struct pi_entry *entry = v;
	int level = LOGLEVEL_DEFAULT;
	enum printk_info_flags flags = 0;
	u16 prefix_len = 0;

	if (v == SEQ_START_TOKEN) {
		seq_puts(s, "# <level/flags> filename:line function \"format\"\n");
		return 0;
	}

	if (!entry->fmt)
		return 0;

	if (entry->level)
		printk_parse_prefix(entry->level, &level, &flags);
	else
		prefix_len = printk_parse_prefix(entry->fmt, &level, &flags);


	if (flags & LOG_CONT) {
		/*
		 * LOGLEVEL_DEFAULT here means "use the same level as the
		 * message we're continuing from", not the default message
		 * loglevel, so don't display it as such.
		 */
		if (level == LOGLEVEL_DEFAULT)
			seq_puts(s, "<c>");
		else
			seq_printf(s, "<%d,c>", level);
	} else
		seq_printf(s, "<%d>", level);

	seq_printf(s, " %s:%d %s \"", entry->file, entry->line, entry->func);
	if (entry->subsys_fmt_prefix)
		seq_escape_printf_format(s, entry->subsys_fmt_prefix);
	seq_escape_printf_format(s, entry->fmt + prefix_len);
	seq_puts(s, "\"\n");

	return 0;
}

static void pi_stop(struct seq_file *p, void *v) { }

static const struct seq_operations dfs_index_sops = {
	.start = pi_start,
	.next  = pi_next,
	.show  = pi_show,
	.stop  = pi_stop,
};

DEFINE_SEQ_ATTRIBUTE(dfs_index);

#ifdef CONFIG_MODULES
static const char *pi_get_module_name(struct module *mod)
{
	return mod ? mod->name : "vmlinux";
}
#else
static const char *pi_get_module_name(struct module *mod)
{
	return "vmlinux";
}
#endif

static void pi_create_file(struct module *mod)
{
	debugfs_create_file(pi_get_module_name(mod), 0444, dfs_index,
				       mod, &dfs_index_fops);
}

#ifdef CONFIG_MODULES
static void pi_remove_file(struct module *mod)
{
	debugfs_remove(debugfs_lookup(pi_get_module_name(mod), dfs_index));
}

static int pi_module_notify(struct notifier_block *nb, unsigned long op,
			    void *data)
{
	struct module *mod = data;

	switch (op) {
	case MODULE_STATE_COMING:
		pi_create_file(mod);
		break;
	case MODULE_STATE_GOING:
		pi_remove_file(mod);
		break;
	default: /* we don't care about other module states */
		break;
	}

	return NOTIFY_OK;
}

static struct notifier_block module_printk_fmts_nb = {
	.notifier_call = pi_module_notify,
};

static void __init pi_setup_module_notifier(void)
{
	register_module_notifier(&module_printk_fmts_nb);
}
#else
static inline void __init pi_setup_module_notifier(void) { }
#endif

static int __init pi_init(void)
{
	struct dentry *dfs_root = debugfs_create_dir("printk", NULL);

	dfs_index = debugfs_create_dir("index", dfs_root);
	pi_setup_module_notifier();
	pi_create_file(NULL);

	return 0;
}

/* debugfs comes up on core and must be initialised first */
postcore_initcall(pi_init);
