forked from mirrors/linux
		
	kdb: Simplify kdb commands registration
Simplify kdb commands registration via using linked list instead of static array for commands storage. Signed-off-by: Sumit Garg <sumit.garg@linaro.org> Link: https://lore.kernel.org/r/20210224070827.408771-1-sumit.garg@linaro.org Reviewed-by: Douglas Anderson <dianders@chromium.org> [daniel.thompson@linaro.org: Removed a bunch of .cmd_minline = 0 initializers] Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
This commit is contained in:
		
							parent
							
								
									d027fdc4fa
								
							
						
					
					
						commit
						e4f291b3f7
					
				
					 3 changed files with 314 additions and 216 deletions
				
			
		| 
						 | 
				
			
			@ -522,6 +522,54 @@ static int kdb_ss(int argc, const char **argv)
 | 
			
		|||
	return KDB_CMD_SS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static kdbtab_t bptab[] = {
 | 
			
		||||
	{	.cmd_name = "bp",
 | 
			
		||||
		.cmd_func = kdb_bp,
 | 
			
		||||
		.cmd_usage = "[<vaddr>]",
 | 
			
		||||
		.cmd_help = "Set/Display breakpoints",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "bl",
 | 
			
		||||
		.cmd_func = kdb_bp,
 | 
			
		||||
		.cmd_usage = "[<vaddr>]",
 | 
			
		||||
		.cmd_help = "Display breakpoints",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "bc",
 | 
			
		||||
		.cmd_func = kdb_bc,
 | 
			
		||||
		.cmd_usage = "<bpnum>",
 | 
			
		||||
		.cmd_help = "Clear Breakpoint",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_FLOW_CTRL,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "be",
 | 
			
		||||
		.cmd_func = kdb_bc,
 | 
			
		||||
		.cmd_usage = "<bpnum>",
 | 
			
		||||
		.cmd_help = "Enable Breakpoint",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_FLOW_CTRL,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "bd",
 | 
			
		||||
		.cmd_func = kdb_bc,
 | 
			
		||||
		.cmd_usage = "<bpnum>",
 | 
			
		||||
		.cmd_help = "Disable Breakpoint",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_FLOW_CTRL,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "ss",
 | 
			
		||||
		.cmd_func = kdb_ss,
 | 
			
		||||
		.cmd_usage = "",
 | 
			
		||||
		.cmd_help = "Single Step",
 | 
			
		||||
		.cmd_minlen = 1,
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static kdbtab_t bphcmd = {
 | 
			
		||||
	.cmd_name = "bph",
 | 
			
		||||
	.cmd_func = kdb_bp,
 | 
			
		||||
	.cmd_usage = "[<vaddr>]",
 | 
			
		||||
	.cmd_help = "[datar [length]|dataw [length]]   Set hw brk",
 | 
			
		||||
	.cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Initialize the breakpoint table and register	breakpoint commands. */
 | 
			
		||||
 | 
			
		||||
void __init kdb_initbptab(void)
 | 
			
		||||
| 
						 | 
				
			
			@ -537,30 +585,7 @@ void __init kdb_initbptab(void)
 | 
			
		|||
	for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++)
 | 
			
		||||
		bp->bp_free = 1;
 | 
			
		||||
 | 
			
		||||
	kdb_register_flags("bp", kdb_bp, "[<vaddr>]",
 | 
			
		||||
		"Set/Display breakpoints", 0,
 | 
			
		||||
		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
 | 
			
		||||
	kdb_register_flags("bl", kdb_bp, "[<vaddr>]",
 | 
			
		||||
		"Display breakpoints", 0,
 | 
			
		||||
		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
 | 
			
		||||
	kdb_register_table(bptab, ARRAY_SIZE(bptab));
 | 
			
		||||
	if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT)
 | 
			
		||||
		kdb_register_flags("bph", kdb_bp, "[<vaddr>]",
 | 
			
		||||
		"[datar [length]|dataw [length]]   Set hw brk", 0,
 | 
			
		||||
		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
 | 
			
		||||
	kdb_register_flags("bc", kdb_bc, "<bpnum>",
 | 
			
		||||
		"Clear Breakpoint", 0,
 | 
			
		||||
		KDB_ENABLE_FLOW_CTRL);
 | 
			
		||||
	kdb_register_flags("be", kdb_bc, "<bpnum>",
 | 
			
		||||
		"Enable Breakpoint", 0,
 | 
			
		||||
		KDB_ENABLE_FLOW_CTRL);
 | 
			
		||||
	kdb_register_flags("bd", kdb_bc, "<bpnum>",
 | 
			
		||||
		"Disable Breakpoint", 0,
 | 
			
		||||
		KDB_ENABLE_FLOW_CTRL);
 | 
			
		||||
 | 
			
		||||
	kdb_register_flags("ss", kdb_ss, "",
 | 
			
		||||
		"Single Step", 1,
 | 
			
		||||
		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
 | 
			
		||||
	/*
 | 
			
		||||
	 * Architecture dependent initialization.
 | 
			
		||||
	 */
 | 
			
		||||
		kdb_register_table(&bphcmd, 1);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,7 @@
 | 
			
		|||
#include <linux/kallsyms.h>
 | 
			
		||||
#include <linux/kgdb.h>
 | 
			
		||||
#include <linux/kdb.h>
 | 
			
		||||
#include <linux/list.h>
 | 
			
		||||
#include <linux/notifier.h>
 | 
			
		||||
#include <linux/interrupt.h>
 | 
			
		||||
#include <linux/delay.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -84,15 +85,8 @@ static unsigned int kdb_continue_catastrophic =
 | 
			
		|||
static unsigned int kdb_continue_catastrophic;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* kdb_commands describes the available commands. */
 | 
			
		||||
static kdbtab_t *kdb_commands;
 | 
			
		||||
#define KDB_BASE_CMD_MAX 50
 | 
			
		||||
static int kdb_max_commands = KDB_BASE_CMD_MAX;
 | 
			
		||||
static kdbtab_t kdb_base_commands[KDB_BASE_CMD_MAX];
 | 
			
		||||
#define for_each_kdbcmd(cmd, num)					\
 | 
			
		||||
	for ((cmd) = kdb_base_commands, (num) = 0;			\
 | 
			
		||||
	     num < kdb_max_commands;					\
 | 
			
		||||
	     num++, num == KDB_BASE_CMD_MAX ? cmd = kdb_commands : cmd++)
 | 
			
		||||
/* kdb_cmds_head describes the available commands. */
 | 
			
		||||
static LIST_HEAD(kdb_cmds_head);
 | 
			
		||||
 | 
			
		||||
typedef struct _kdbmsg {
 | 
			
		||||
	int	km_diag;	/* kdb diagnostic */
 | 
			
		||||
| 
						 | 
				
			
			@ -921,7 +915,7 @@ int kdb_parse(const char *cmdstr)
 | 
			
		|||
	char *cp;
 | 
			
		||||
	char *cpp, quoted;
 | 
			
		||||
	kdbtab_t *tp;
 | 
			
		||||
	int i, escaped, ignore_errors = 0, check_grep = 0;
 | 
			
		||||
	int escaped, ignore_errors = 0, check_grep = 0;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * First tokenize the command string.
 | 
			
		||||
| 
						 | 
				
			
			@ -1011,45 +1005,33 @@ int kdb_parse(const char *cmdstr)
 | 
			
		|||
		++argv[0];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for_each_kdbcmd(tp, i) {
 | 
			
		||||
		if (tp->cmd_name) {
 | 
			
		||||
	list_for_each_entry(tp, &kdb_cmds_head, list_node) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * If this command is allowed to be abbreviated,
 | 
			
		||||
		 * check to see if this is it.
 | 
			
		||||
		 */
 | 
			
		||||
 | 
			
		||||
			if (tp->cmd_minlen
 | 
			
		||||
			 && (strlen(argv[0]) <= tp->cmd_minlen)) {
 | 
			
		||||
				if (strncmp(argv[0],
 | 
			
		||||
					    tp->cmd_name,
 | 
			
		||||
					    tp->cmd_minlen) == 0) {
 | 
			
		||||
		if (tp->cmd_minlen && (strlen(argv[0]) <= tp->cmd_minlen) &&
 | 
			
		||||
		    (strncmp(argv[0], tp->cmd_name, tp->cmd_minlen) == 0))
 | 
			
		||||
			break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		if (strcmp(argv[0], tp->cmd_name) == 0)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If we don't find a command by this name, see if the first
 | 
			
		||||
	 * few characters of this match any of the known commands.
 | 
			
		||||
	 * e.g., md1c20 should match md.
 | 
			
		||||
	 */
 | 
			
		||||
	if (i == kdb_max_commands) {
 | 
			
		||||
		for_each_kdbcmd(tp, i) {
 | 
			
		||||
			if (tp->cmd_name) {
 | 
			
		||||
				if (strncmp(argv[0],
 | 
			
		||||
					    tp->cmd_name,
 | 
			
		||||
					    strlen(tp->cmd_name)) == 0) {
 | 
			
		||||
	if (list_entry_is_head(tp, &kdb_cmds_head, list_node)) {
 | 
			
		||||
		list_for_each_entry(tp, &kdb_cmds_head, list_node) {
 | 
			
		||||
			if (strncmp(argv[0], tp->cmd_name,
 | 
			
		||||
				    strlen(tp->cmd_name)) == 0)
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (i < kdb_max_commands) {
 | 
			
		||||
	if (!list_entry_is_head(tp, &kdb_cmds_head, list_node)) {
 | 
			
		||||
		int result;
 | 
			
		||||
 | 
			
		||||
		if (!kdb_check_flags(tp->cmd_flags, kdb_cmd_enabled, argc <= 1))
 | 
			
		||||
| 
						 | 
				
			
			@ -2428,17 +2410,14 @@ static int kdb_kgdb(int argc, const char **argv)
 | 
			
		|||
static int kdb_help(int argc, const char **argv)
 | 
			
		||||
{
 | 
			
		||||
	kdbtab_t *kt;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	kdb_printf("%-15.15s %-20.20s %s\n", "Command", "Usage", "Description");
 | 
			
		||||
	kdb_printf("-----------------------------"
 | 
			
		||||
		   "-----------------------------\n");
 | 
			
		||||
	for_each_kdbcmd(kt, i) {
 | 
			
		||||
	list_for_each_entry(kt, &kdb_cmds_head, list_node) {
 | 
			
		||||
		char *space = "";
 | 
			
		||||
		if (KDB_FLAG(CMD_INTERRUPT))
 | 
			
		||||
			return 0;
 | 
			
		||||
		if (!kt->cmd_name)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!kdb_check_flags(kt->cmd_flags, kdb_cmd_enabled, true))
 | 
			
		||||
			continue;
 | 
			
		||||
		if (strlen(kt->cmd_usage) > 20)
 | 
			
		||||
| 
						 | 
				
			
			@ -2659,7 +2638,6 @@ static int kdb_grep_help(int argc, const char **argv)
 | 
			
		|||
 * Returns:
 | 
			
		||||
 *	zero for success, one if a duplicate command.
 | 
			
		||||
 */
 | 
			
		||||
#define kdb_command_extend 50	/* arbitrary */
 | 
			
		||||
int kdb_register_flags(char *cmd,
 | 
			
		||||
		       kdb_func_t func,
 | 
			
		||||
		       char *usage,
 | 
			
		||||
| 
						 | 
				
			
			@ -2667,50 +2645,21 @@ int kdb_register_flags(char *cmd,
 | 
			
		|||
		       short minlen,
 | 
			
		||||
		       kdb_cmdflags_t flags)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	kdbtab_t *kp;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 *  Brute force method to determine duplicates
 | 
			
		||||
	 */
 | 
			
		||||
	for_each_kdbcmd(kp, i) {
 | 
			
		||||
		if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) {
 | 
			
		||||
	list_for_each_entry(kp, &kdb_cmds_head, list_node) {
 | 
			
		||||
		if (strcmp(kp->cmd_name, cmd) == 0) {
 | 
			
		||||
			kdb_printf("Duplicate kdb command registered: "
 | 
			
		||||
				"%s, func %px help %s\n", cmd, func, help);
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Insert command into first available location in table
 | 
			
		||||
	 */
 | 
			
		||||
	for_each_kdbcmd(kp, i) {
 | 
			
		||||
		if (kp->cmd_name == NULL)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (i >= kdb_max_commands) {
 | 
			
		||||
		kdbtab_t *new = kmalloc_array(kdb_max_commands -
 | 
			
		||||
						KDB_BASE_CMD_MAX +
 | 
			
		||||
						kdb_command_extend,
 | 
			
		||||
					      sizeof(*new),
 | 
			
		||||
					      GFP_KDB);
 | 
			
		||||
		if (!new) {
 | 
			
		||||
			kdb_printf("Could not allocate new kdb_command "
 | 
			
		||||
				   "table\n");
 | 
			
		||||
	kp = kmalloc(sizeof(*kp), GFP_KDB);
 | 
			
		||||
	if (!kp) {
 | 
			
		||||
		kdb_printf("Could not allocate new kdb_command table\n");
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
		if (kdb_commands) {
 | 
			
		||||
			memcpy(new, kdb_commands,
 | 
			
		||||
			  (kdb_max_commands - KDB_BASE_CMD_MAX) * sizeof(*new));
 | 
			
		||||
			kfree(kdb_commands);
 | 
			
		||||
		}
 | 
			
		||||
		memset(new + kdb_max_commands - KDB_BASE_CMD_MAX, 0,
 | 
			
		||||
		       kdb_command_extend * sizeof(*new));
 | 
			
		||||
		kdb_commands = new;
 | 
			
		||||
		kp = kdb_commands + kdb_max_commands - KDB_BASE_CMD_MAX;
 | 
			
		||||
		kdb_max_commands += kdb_command_extend;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	kp->cmd_name   = cmd;
 | 
			
		||||
	kp->cmd_func   = func;
 | 
			
		||||
| 
						 | 
				
			
			@ -2718,11 +2667,27 @@ int kdb_register_flags(char *cmd,
 | 
			
		|||
	kp->cmd_help   = help;
 | 
			
		||||
	kp->cmd_minlen = minlen;
 | 
			
		||||
	kp->cmd_flags  = flags;
 | 
			
		||||
	kp->is_dynamic = true;
 | 
			
		||||
 | 
			
		||||
	list_add_tail(&kp->list_node, &kdb_cmds_head);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(kdb_register_flags);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * kdb_register_table() - This function is used to register a kdb command
 | 
			
		||||
 *                        table.
 | 
			
		||||
 * @kp: pointer to kdb command table
 | 
			
		||||
 * @len: length of kdb command table
 | 
			
		||||
 */
 | 
			
		||||
void kdb_register_table(kdbtab_t *kp, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	while (len--) {
 | 
			
		||||
		list_add_tail(&kp->list_node, &kdb_cmds_head);
 | 
			
		||||
		kp++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * kdb_register - Compatibility register function for commands that do
 | 
			
		||||
| 
						 | 
				
			
			@ -2757,15 +2722,16 @@ EXPORT_SYMBOL_GPL(kdb_register);
 | 
			
		|||
 */
 | 
			
		||||
int kdb_unregister(char *cmd)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	kdbtab_t *kp;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 *  find the command.
 | 
			
		||||
	 */
 | 
			
		||||
	for_each_kdbcmd(kp, i) {
 | 
			
		||||
		if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) {
 | 
			
		||||
			kp->cmd_name = NULL;
 | 
			
		||||
	list_for_each_entry(kp, &kdb_cmds_head, list_node) {
 | 
			
		||||
		if (strcmp(kp->cmd_name, cmd) == 0) {
 | 
			
		||||
			list_del(&kp->list_node);
 | 
			
		||||
			if (kp->is_dynamic)
 | 
			
		||||
				kfree(kp);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -2775,118 +2741,222 @@ int kdb_unregister(char *cmd)
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(kdb_unregister);
 | 
			
		||||
 | 
			
		||||
static kdbtab_t maintab[] = {
 | 
			
		||||
	{	.cmd_name = "md",
 | 
			
		||||
		.cmd_func = kdb_md,
 | 
			
		||||
		.cmd_usage = "<vaddr>",
 | 
			
		||||
		.cmd_help = "Display Memory Contents, also mdWcN, e.g. md8c1",
 | 
			
		||||
		.cmd_minlen = 1,
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "mdr",
 | 
			
		||||
		.cmd_func = kdb_md,
 | 
			
		||||
		.cmd_usage = "<vaddr> <bytes>",
 | 
			
		||||
		.cmd_help = "Display Raw Memory",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "mdp",
 | 
			
		||||
		.cmd_func = kdb_md,
 | 
			
		||||
		.cmd_usage = "<paddr> <bytes>",
 | 
			
		||||
		.cmd_help = "Display Physical Memory",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "mds",
 | 
			
		||||
		.cmd_func = kdb_md,
 | 
			
		||||
		.cmd_usage = "<vaddr>",
 | 
			
		||||
		.cmd_help = "Display Memory Symbolically",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "mm",
 | 
			
		||||
		.cmd_func = kdb_mm,
 | 
			
		||||
		.cmd_usage = "<vaddr> <contents>",
 | 
			
		||||
		.cmd_help = "Modify Memory Contents",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_MEM_WRITE | KDB_REPEAT_NO_ARGS,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "go",
 | 
			
		||||
		.cmd_func = kdb_go,
 | 
			
		||||
		.cmd_usage = "[<vaddr>]",
 | 
			
		||||
		.cmd_help = "Continue Execution",
 | 
			
		||||
		.cmd_minlen = 1,
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_REG_WRITE |
 | 
			
		||||
			     KDB_ENABLE_ALWAYS_SAFE_NO_ARGS,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "rd",
 | 
			
		||||
		.cmd_func = kdb_rd,
 | 
			
		||||
		.cmd_usage = "",
 | 
			
		||||
		.cmd_help = "Display Registers",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_REG_READ,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "rm",
 | 
			
		||||
		.cmd_func = kdb_rm,
 | 
			
		||||
		.cmd_usage = "<reg> <contents>",
 | 
			
		||||
		.cmd_help = "Modify Registers",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_REG_WRITE,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "ef",
 | 
			
		||||
		.cmd_func = kdb_ef,
 | 
			
		||||
		.cmd_usage = "<vaddr>",
 | 
			
		||||
		.cmd_help = "Display exception frame",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_MEM_READ,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "bt",
 | 
			
		||||
		.cmd_func = kdb_bt,
 | 
			
		||||
		.cmd_usage = "[<vaddr>]",
 | 
			
		||||
		.cmd_help = "Stack traceback",
 | 
			
		||||
		.cmd_minlen = 1,
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "btp",
 | 
			
		||||
		.cmd_func = kdb_bt,
 | 
			
		||||
		.cmd_usage = "<pid>",
 | 
			
		||||
		.cmd_help = "Display stack for process <pid>",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_INSPECT,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "bta",
 | 
			
		||||
		.cmd_func = kdb_bt,
 | 
			
		||||
		.cmd_usage = "[D|R|S|T|C|Z|E|U|I|M|A]",
 | 
			
		||||
		.cmd_help = "Backtrace all processes matching state flag",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_INSPECT,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "btc",
 | 
			
		||||
		.cmd_func = kdb_bt,
 | 
			
		||||
		.cmd_usage = "",
 | 
			
		||||
		.cmd_help = "Backtrace current process on each cpu",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_INSPECT,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "btt",
 | 
			
		||||
		.cmd_func = kdb_bt,
 | 
			
		||||
		.cmd_usage = "<vaddr>",
 | 
			
		||||
		.cmd_help = "Backtrace process given its struct task address",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "env",
 | 
			
		||||
		.cmd_func = kdb_env,
 | 
			
		||||
		.cmd_usage = "",
 | 
			
		||||
		.cmd_help = "Show environment variables",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_ALWAYS_SAFE,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "set",
 | 
			
		||||
		.cmd_func = kdb_set,
 | 
			
		||||
		.cmd_usage = "",
 | 
			
		||||
		.cmd_help = "Set environment variables",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_ALWAYS_SAFE,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "help",
 | 
			
		||||
		.cmd_func = kdb_help,
 | 
			
		||||
		.cmd_usage = "",
 | 
			
		||||
		.cmd_help = "Display Help Message",
 | 
			
		||||
		.cmd_minlen = 1,
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_ALWAYS_SAFE,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "?",
 | 
			
		||||
		.cmd_func = kdb_help,
 | 
			
		||||
		.cmd_usage = "",
 | 
			
		||||
		.cmd_help = "Display Help Message",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_ALWAYS_SAFE,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "cpu",
 | 
			
		||||
		.cmd_func = kdb_cpu,
 | 
			
		||||
		.cmd_usage = "<cpunum>",
 | 
			
		||||
		.cmd_help = "Switch to new cpu",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_ALWAYS_SAFE_NO_ARGS,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "kgdb",
 | 
			
		||||
		.cmd_func = kdb_kgdb,
 | 
			
		||||
		.cmd_usage = "",
 | 
			
		||||
		.cmd_help = "Enter kgdb mode",
 | 
			
		||||
		.cmd_flags = 0,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "ps",
 | 
			
		||||
		.cmd_func = kdb_ps,
 | 
			
		||||
		.cmd_usage = "[<flags>|A]",
 | 
			
		||||
		.cmd_help = "Display active task list",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_INSPECT,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "pid",
 | 
			
		||||
		.cmd_func = kdb_pid,
 | 
			
		||||
		.cmd_usage = "<pidnum>",
 | 
			
		||||
		.cmd_help = "Switch to another task",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_INSPECT,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "reboot",
 | 
			
		||||
		.cmd_func = kdb_reboot,
 | 
			
		||||
		.cmd_usage = "",
 | 
			
		||||
		.cmd_help = "Reboot the machine immediately",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_REBOOT,
 | 
			
		||||
	},
 | 
			
		||||
#if defined(CONFIG_MODULES)
 | 
			
		||||
	{	.cmd_name = "lsmod",
 | 
			
		||||
		.cmd_func = kdb_lsmod,
 | 
			
		||||
		.cmd_usage = "",
 | 
			
		||||
		.cmd_help = "List loaded kernel modules",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_INSPECT,
 | 
			
		||||
	},
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(CONFIG_MAGIC_SYSRQ)
 | 
			
		||||
	{	.cmd_name = "sr",
 | 
			
		||||
		.cmd_func = kdb_sr,
 | 
			
		||||
		.cmd_usage = "<key>",
 | 
			
		||||
		.cmd_help = "Magic SysRq key",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_ALWAYS_SAFE,
 | 
			
		||||
	},
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(CONFIG_PRINTK)
 | 
			
		||||
	{	.cmd_name = "dmesg",
 | 
			
		||||
		.cmd_func = kdb_dmesg,
 | 
			
		||||
		.cmd_usage = "[lines]",
 | 
			
		||||
		.cmd_help = "Display syslog buffer",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_ALWAYS_SAFE,
 | 
			
		||||
	},
 | 
			
		||||
#endif
 | 
			
		||||
	{	.cmd_name = "defcmd",
 | 
			
		||||
		.cmd_func = kdb_defcmd,
 | 
			
		||||
		.cmd_usage = "name \"usage\" \"help\"",
 | 
			
		||||
		.cmd_help = "Define a set of commands, down to endefcmd",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_ALWAYS_SAFE,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "kill",
 | 
			
		||||
		.cmd_func = kdb_kill,
 | 
			
		||||
		.cmd_usage = "<-signal> <pid>",
 | 
			
		||||
		.cmd_help = "Send a signal to a process",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_SIGNAL,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "summary",
 | 
			
		||||
		.cmd_func = kdb_summary,
 | 
			
		||||
		.cmd_usage = "",
 | 
			
		||||
		.cmd_help = "Summarize the system",
 | 
			
		||||
		.cmd_minlen = 4,
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_ALWAYS_SAFE,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "per_cpu",
 | 
			
		||||
		.cmd_func = kdb_per_cpu,
 | 
			
		||||
		.cmd_usage = "<sym> [<bytes>] [<cpu>]",
 | 
			
		||||
		.cmd_help = "Display per_cpu variables",
 | 
			
		||||
		.cmd_minlen = 3,
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_MEM_READ,
 | 
			
		||||
	},
 | 
			
		||||
	{	.cmd_name = "grephelp",
 | 
			
		||||
		.cmd_func = kdb_grep_help,
 | 
			
		||||
		.cmd_usage = "",
 | 
			
		||||
		.cmd_help = "Display help on | grep",
 | 
			
		||||
		.cmd_flags = KDB_ENABLE_ALWAYS_SAFE,
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static kdbtab_t nmicmd = {
 | 
			
		||||
	.cmd_name = "disable_nmi",
 | 
			
		||||
	.cmd_func = kdb_disable_nmi,
 | 
			
		||||
	.cmd_usage = "",
 | 
			
		||||
	.cmd_help = "Disable NMI entry to KDB",
 | 
			
		||||
	.cmd_flags = KDB_ENABLE_ALWAYS_SAFE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Initialize the kdb command table. */
 | 
			
		||||
static void __init kdb_inittab(void)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	kdbtab_t *kp;
 | 
			
		||||
 | 
			
		||||
	for_each_kdbcmd(kp, i)
 | 
			
		||||
		kp->cmd_name = NULL;
 | 
			
		||||
 | 
			
		||||
	kdb_register_flags("md", kdb_md, "<vaddr>",
 | 
			
		||||
	  "Display Memory Contents, also mdWcN, e.g. md8c1", 1,
 | 
			
		||||
	  KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS);
 | 
			
		||||
	kdb_register_flags("mdr", kdb_md, "<vaddr> <bytes>",
 | 
			
		||||
	  "Display Raw Memory", 0,
 | 
			
		||||
	  KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS);
 | 
			
		||||
	kdb_register_flags("mdp", kdb_md, "<paddr> <bytes>",
 | 
			
		||||
	  "Display Physical Memory", 0,
 | 
			
		||||
	  KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS);
 | 
			
		||||
	kdb_register_flags("mds", kdb_md, "<vaddr>",
 | 
			
		||||
	  "Display Memory Symbolically", 0,
 | 
			
		||||
	  KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS);
 | 
			
		||||
	kdb_register_flags("mm", kdb_mm, "<vaddr> <contents>",
 | 
			
		||||
	  "Modify Memory Contents", 0,
 | 
			
		||||
	  KDB_ENABLE_MEM_WRITE | KDB_REPEAT_NO_ARGS);
 | 
			
		||||
	kdb_register_flags("go", kdb_go, "[<vaddr>]",
 | 
			
		||||
	  "Continue Execution", 1,
 | 
			
		||||
	  KDB_ENABLE_REG_WRITE | KDB_ENABLE_ALWAYS_SAFE_NO_ARGS);
 | 
			
		||||
	kdb_register_flags("rd", kdb_rd, "",
 | 
			
		||||
	  "Display Registers", 0,
 | 
			
		||||
	  KDB_ENABLE_REG_READ);
 | 
			
		||||
	kdb_register_flags("rm", kdb_rm, "<reg> <contents>",
 | 
			
		||||
	  "Modify Registers", 0,
 | 
			
		||||
	  KDB_ENABLE_REG_WRITE);
 | 
			
		||||
	kdb_register_flags("ef", kdb_ef, "<vaddr>",
 | 
			
		||||
	  "Display exception frame", 0,
 | 
			
		||||
	  KDB_ENABLE_MEM_READ);
 | 
			
		||||
	kdb_register_flags("bt", kdb_bt, "[<vaddr>]",
 | 
			
		||||
	  "Stack traceback", 1,
 | 
			
		||||
	  KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS);
 | 
			
		||||
	kdb_register_flags("btp", kdb_bt, "<pid>",
 | 
			
		||||
	  "Display stack for process <pid>", 0,
 | 
			
		||||
	  KDB_ENABLE_INSPECT);
 | 
			
		||||
	kdb_register_flags("bta", kdb_bt, "[D|R|S|T|C|Z|E|U|I|M|A]",
 | 
			
		||||
	  "Backtrace all processes matching state flag", 0,
 | 
			
		||||
	  KDB_ENABLE_INSPECT);
 | 
			
		||||
	kdb_register_flags("btc", kdb_bt, "",
 | 
			
		||||
	  "Backtrace current process on each cpu", 0,
 | 
			
		||||
	  KDB_ENABLE_INSPECT);
 | 
			
		||||
	kdb_register_flags("btt", kdb_bt, "<vaddr>",
 | 
			
		||||
	  "Backtrace process given its struct task address", 0,
 | 
			
		||||
	  KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS);
 | 
			
		||||
	kdb_register_flags("env", kdb_env, "",
 | 
			
		||||
	  "Show environment variables", 0,
 | 
			
		||||
	  KDB_ENABLE_ALWAYS_SAFE);
 | 
			
		||||
	kdb_register_flags("set", kdb_set, "",
 | 
			
		||||
	  "Set environment variables", 0,
 | 
			
		||||
	  KDB_ENABLE_ALWAYS_SAFE);
 | 
			
		||||
	kdb_register_flags("help", kdb_help, "",
 | 
			
		||||
	  "Display Help Message", 1,
 | 
			
		||||
	  KDB_ENABLE_ALWAYS_SAFE);
 | 
			
		||||
	kdb_register_flags("?", kdb_help, "",
 | 
			
		||||
	  "Display Help Message", 0,
 | 
			
		||||
	  KDB_ENABLE_ALWAYS_SAFE);
 | 
			
		||||
	kdb_register_flags("cpu", kdb_cpu, "<cpunum>",
 | 
			
		||||
	  "Switch to new cpu", 0,
 | 
			
		||||
	  KDB_ENABLE_ALWAYS_SAFE_NO_ARGS);
 | 
			
		||||
	kdb_register_flags("kgdb", kdb_kgdb, "",
 | 
			
		||||
	  "Enter kgdb mode", 0, 0);
 | 
			
		||||
	kdb_register_flags("ps", kdb_ps, "[<flags>|A]",
 | 
			
		||||
	  "Display active task list", 0,
 | 
			
		||||
	  KDB_ENABLE_INSPECT);
 | 
			
		||||
	kdb_register_flags("pid", kdb_pid, "<pidnum>",
 | 
			
		||||
	  "Switch to another task", 0,
 | 
			
		||||
	  KDB_ENABLE_INSPECT);
 | 
			
		||||
	kdb_register_flags("reboot", kdb_reboot, "",
 | 
			
		||||
	  "Reboot the machine immediately", 0,
 | 
			
		||||
	  KDB_ENABLE_REBOOT);
 | 
			
		||||
#if defined(CONFIG_MODULES)
 | 
			
		||||
	kdb_register_flags("lsmod", kdb_lsmod, "",
 | 
			
		||||
	  "List loaded kernel modules", 0,
 | 
			
		||||
	  KDB_ENABLE_INSPECT);
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(CONFIG_MAGIC_SYSRQ)
 | 
			
		||||
	kdb_register_flags("sr", kdb_sr, "<key>",
 | 
			
		||||
	  "Magic SysRq key", 0,
 | 
			
		||||
	  KDB_ENABLE_ALWAYS_SAFE);
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(CONFIG_PRINTK)
 | 
			
		||||
	kdb_register_flags("dmesg", kdb_dmesg, "[lines]",
 | 
			
		||||
	  "Display syslog buffer", 0,
 | 
			
		||||
	  KDB_ENABLE_ALWAYS_SAFE);
 | 
			
		||||
#endif
 | 
			
		||||
	if (arch_kgdb_ops.enable_nmi) {
 | 
			
		||||
		kdb_register_flags("disable_nmi", kdb_disable_nmi, "",
 | 
			
		||||
		  "Disable NMI entry to KDB", 0,
 | 
			
		||||
		  KDB_ENABLE_ALWAYS_SAFE);
 | 
			
		||||
	}
 | 
			
		||||
	kdb_register_flags("defcmd", kdb_defcmd, "name \"usage\" \"help\"",
 | 
			
		||||
	  "Define a set of commands, down to endefcmd", 0,
 | 
			
		||||
	  KDB_ENABLE_ALWAYS_SAFE);
 | 
			
		||||
	kdb_register_flags("kill", kdb_kill, "<-signal> <pid>",
 | 
			
		||||
	  "Send a signal to a process", 0,
 | 
			
		||||
	  KDB_ENABLE_SIGNAL);
 | 
			
		||||
	kdb_register_flags("summary", kdb_summary, "",
 | 
			
		||||
	  "Summarize the system", 4,
 | 
			
		||||
	  KDB_ENABLE_ALWAYS_SAFE);
 | 
			
		||||
	kdb_register_flags("per_cpu", kdb_per_cpu, "<sym> [<bytes>] [<cpu>]",
 | 
			
		||||
	  "Display per_cpu variables", 3,
 | 
			
		||||
	  KDB_ENABLE_MEM_READ);
 | 
			
		||||
	kdb_register_flags("grephelp", kdb_grep_help, "",
 | 
			
		||||
	  "Display help on | grep", 0,
 | 
			
		||||
	  KDB_ENABLE_ALWAYS_SAFE);
 | 
			
		||||
	kdb_register_table(maintab, ARRAY_SIZE(maintab));
 | 
			
		||||
	if (arch_kgdb_ops.enable_nmi)
 | 
			
		||||
		kdb_register_table(&nmicmd, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Execute any commands defined in kdb_cmds.  */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -174,8 +174,11 @@ typedef struct _kdbtab {
 | 
			
		|||
	short    cmd_minlen;		/* Minimum legal # command
 | 
			
		||||
					 * chars required */
 | 
			
		||||
	kdb_cmdflags_t cmd_flags;	/* Command behaviour flags */
 | 
			
		||||
	struct list_head list_node;	/* Command list */
 | 
			
		||||
	bool    is_dynamic;		/* Command table allocation type */
 | 
			
		||||
} kdbtab_t;
 | 
			
		||||
 | 
			
		||||
extern void kdb_register_table(kdbtab_t *kp, size_t len);
 | 
			
		||||
extern int kdb_bt(int, const char **);	/* KDB display back trace */
 | 
			
		||||
 | 
			
		||||
/* KDB breakpoint management functions */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue