2954 lines · 70.3 KB · C
RawDownload
/* * Kernel Debugger Architecture Independent Main Code * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved. * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com> * Xscale (R) modifications copyright (C) 2003 Intel Corporation. * Copyright (c) 2009 Wind River Systems, Inc.  All Rights Reserved. */ #include <linux/ctype.h>#include <linux/types.h>#include <linux/string.h>#include <linux/kernel.h>#include <linux/kmsg_dump.h>#include <linux/reboot.h>#include <linux/sched.h>#include <linux/sysrq.h>#include <linux/smp.h>#include <linux/utsname.h>#include <linux/vmalloc.h>#include <linux/atomic.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/mm.h>#include <linux/init.h>#include <linux/kallsyms.h>#include <linux/kgdb.h>#include <linux/kdb.h>#include <linux/notifier.h>#include <linux/interrupt.h>#include <linux/delay.h>#include <linux/nmi.h>#include <linux/time.h>#include <linux/ptrace.h>#include <linux/sysctl.h>#include <linux/cpu.h>#include <linux/kdebug.h>#include <linux/proc_fs.h>#include <linux/uaccess.h>#include <linux/slab.h>#include "kdb_private.h" #undef	MODULE_PARAM_PREFIX#define	MODULE_PARAM_PREFIX "kdb." static int kdb_cmd_enabled = CONFIG_KDB_DEFAULT_ENABLE;module_param_named(cmd_enable, kdb_cmd_enabled, int, 0600); #define GREP_LEN 256char kdb_grep_string[GREP_LEN];int kdb_grepping_flag;EXPORT_SYMBOL(kdb_grepping_flag);int kdb_grep_leading;int kdb_grep_trailing; /* * Kernel debugger state flags */int kdb_flags;atomic_t kdb_event; /* * kdb_lock protects updates to kdb_initial_cpu.  Used to * single thread processors through the kernel debugger. */int kdb_initial_cpu = -1;	/* cpu number that owns kdb */int kdb_nextline = 1;int kdb_state;			/* General KDB state */ struct task_struct *kdb_current_task;EXPORT_SYMBOL(kdb_current_task);struct pt_regs *kdb_current_regs; const char *kdb_diemsg;static int kdb_go_count;#ifdef CONFIG_KDB_CONTINUE_CATASTROPHICstatic unsigned int kdb_continue_catastrophic =	CONFIG_KDB_CONTINUE_CATASTROPHIC;#elsestatic unsigned int kdb_continue_catastrophic;#endif /* kdb_commands describes the available commands. */static kdbtab_t *kdb_commands;#define KDB_BASE_CMD_MAX 50static 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++) typedef struct _kdbmsg {	int	km_diag;	/* kdb diagnostic */	char	*km_msg;	/* Corresponding message text */} kdbmsg_t; #define KDBMSG(msgnum, text) \	{ KDB_##msgnum, text } static kdbmsg_t kdbmsgs[] = {	KDBMSG(NOTFOUND, "Command Not Found"),	KDBMSG(ARGCOUNT, "Improper argument count, see usage."),	KDBMSG(BADWIDTH, "Illegal value for BYTESPERWORD use 1, 2, 4 or 8, "	       "8 is only allowed on 64 bit systems"),	KDBMSG(BADRADIX, "Illegal value for RADIX use 8, 10 or 16"),	KDBMSG(NOTENV, "Cannot find environment variable"),	KDBMSG(NOENVVALUE, "Environment variable should have value"),	KDBMSG(NOTIMP, "Command not implemented"),	KDBMSG(ENVFULL, "Environment full"),	KDBMSG(ENVBUFFULL, "Environment buffer full"),	KDBMSG(TOOMANYBPT, "Too many breakpoints defined"),#ifdef CONFIG_CPU_XSCALE	KDBMSG(TOOMANYDBREGS, "More breakpoints than ibcr registers defined"),#else	KDBMSG(TOOMANYDBREGS, "More breakpoints than db registers defined"),#endif	KDBMSG(DUPBPT, "Duplicate breakpoint address"),	KDBMSG(BPTNOTFOUND, "Breakpoint not found"),	KDBMSG(BADMODE, "Invalid IDMODE"),	KDBMSG(BADINT, "Illegal numeric value"),	KDBMSG(INVADDRFMT, "Invalid symbolic address format"),	KDBMSG(BADREG, "Invalid register name"),	KDBMSG(BADCPUNUM, "Invalid cpu number"),	KDBMSG(BADLENGTH, "Invalid length field"),	KDBMSG(NOBP, "No Breakpoint exists"),	KDBMSG(BADADDR, "Invalid address"),	KDBMSG(NOPERM, "Permission denied"),};#undef KDBMSG static const int __nkdb_err = ARRAY_SIZE(kdbmsgs);  /* * Initial environment.   This is all kept static and local to * this file.   We don't want to rely on the memory allocation * mechanisms in the kernel, so we use a very limited allocate-only * heap for new and altered environment variables.  The entire * environment is limited to a fixed number of entries (add more * to __env[] if required) and a fixed amount of heap (add more to * KDB_ENVBUFSIZE if required). */ static char *__env[] = {#if defined(CONFIG_SMP) "PROMPT=[%d]kdb> ",#else "PROMPT=kdb> ",#endif "MOREPROMPT=more> ", "RADIX=16", "MDCOUNT=8",			/* lines of md output */ KDB_PLATFORM_ENV, "DTABCOUNT=30", "NOSECT=1", (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0,}; static const int __nenv = ARRAY_SIZE(__env); struct task_struct *kdb_curr_task(int cpu){	struct task_struct *p = curr_task(cpu);#ifdef	_TIF_MCA_INIT	if ((task_thread_info(p)->flags & _TIF_MCA_INIT) && KDB_TSK(cpu))		p = krp->p;#endif	return p;} /* * Check whether the flags of the current command and the permissions * of the kdb console has allow a command to be run. */static inline bool kdb_check_flags(kdb_cmdflags_t flags, int permissions,				   bool no_args){	/* permissions comes from userspace so needs massaging slightly */	permissions &= KDB_ENABLE_MASK;	permissions |= KDB_ENABLE_ALWAYS_SAFE; 	/* some commands change group when launched with no arguments */	if (no_args)		permissions |= permissions << KDB_ENABLE_NO_ARGS_SHIFT; 	flags |= KDB_ENABLE_ALL; 	return permissions & flags;} /* * kdbgetenv - This function will return the character string value of *	an environment variable. * Parameters: *	match	A character string representing an environment variable. * Returns: *	NULL	No environment variable matches 'match' *	char*	Pointer to string value of environment variable. */char *kdbgetenv(const char *match){	char **ep = __env;	int matchlen = strlen(match);	int i; 	for (i = 0; i < __nenv; i++) {		char *e = *ep++; 		if (!e)			continue; 		if ((strncmp(match, e, matchlen) == 0)		 && ((e[matchlen] == '\0')		   || (e[matchlen] == '='))) {			char *cp = strchr(e, '=');			return cp ? ++cp : "";		}	}	return NULL;} /* * kdballocenv - This function is used to allocate bytes for *	environment entries. * Parameters: *	match	A character string representing a numeric value * Outputs: *	*value  the unsigned long representation of the env variable 'match' * Returns: *	Zero on success, a kdb diagnostic on failure. * Remarks: *	We use a static environment buffer (envbuffer) to hold the values *	of dynamically generated environment variables (see kdb_set).  Buffer *	space once allocated is never free'd, so over time, the amount of space *	(currently 512 bytes) will be exhausted if env variables are changed *	frequently. */static char *kdballocenv(size_t bytes){#define	KDB_ENVBUFSIZE	512	static char envbuffer[KDB_ENVBUFSIZE];	static int envbufsize;	char *ep = NULL; 	if ((KDB_ENVBUFSIZE - envbufsize) >= bytes) {		ep = &envbuffer[envbufsize];		envbufsize += bytes;	}	return ep;} /* * kdbgetulenv - This function will return the value of an unsigned *	long-valued environment variable. * Parameters: *	match	A character string representing a numeric value * Outputs: *	*value  the unsigned long represntation of the env variable 'match' * Returns: *	Zero on success, a kdb diagnostic on failure. */static int kdbgetulenv(const char *match, unsigned long *value){	char *ep; 	ep = kdbgetenv(match);	if (!ep)		return KDB_NOTENV;	if (strlen(ep) == 0)		return KDB_NOENVVALUE; 	*value = simple_strtoul(ep, NULL, 0); 	return 0;} /* * kdbgetintenv - This function will return the value of an *	integer-valued environment variable. * Parameters: *	match	A character string representing an integer-valued env variable * Outputs: *	*value  the integer representation of the environment variable 'match' * Returns: *	Zero on success, a kdb diagnostic on failure. */int kdbgetintenv(const char *match, int *value){	unsigned long val;	int diag; 	diag = kdbgetulenv(match, &val);	if (!diag)		*value = (int) val;	return diag;} /* * kdbgetularg - This function will convert a numeric string into an *	unsigned long value. * Parameters: *	arg	A character string representing a numeric value * Outputs: *	*value  the unsigned long represntation of arg. * Returns: *	Zero on success, a kdb diagnostic on failure. */int kdbgetularg(const char *arg, unsigned long *value){	char *endp;	unsigned long val; 	val = simple_strtoul(arg, &endp, 0); 	if (endp == arg) {		/*		 * Also try base 16, for us folks too lazy to type the		 * leading 0x...		 */		val = simple_strtoul(arg, &endp, 16);		if (endp == arg)			return KDB_BADINT;	} 	*value = val; 	return 0;} int kdbgetu64arg(const char *arg, u64 *value){	char *endp;	u64 val; 	val = simple_strtoull(arg, &endp, 0); 	if (endp == arg) { 		val = simple_strtoull(arg, &endp, 16);		if (endp == arg)			return KDB_BADINT;	} 	*value = val; 	return 0;} /* * kdb_set - This function implements the 'set' command.  Alter an *	existing environment variable or create a new one. */int kdb_set(int argc, const char **argv){	int i;	char *ep;	size_t varlen, vallen; 	/*	 * we can be invoked two ways:	 *   set var=value    argv[1]="var", argv[2]="value"	 *   set var = value  argv[1]="var", argv[2]="=", argv[3]="value"	 * - if the latter, shift 'em down.	 */	if (argc == 3) {		argv[2] = argv[3];		argc--;	} 	if (argc != 2)		return KDB_ARGCOUNT; 	/*	 * Check for internal variables	 */	if (strcmp(argv[1], "KDBDEBUG") == 0) {		unsigned int debugflags;		char *cp; 		debugflags = simple_strtoul(argv[2], &cp, 0);		if (cp == argv[2] || debugflags & ~KDB_DEBUG_FLAG_MASK) {			kdb_printf("kdb: illegal debug flags '%s'\n",				    argv[2]);			return 0;		}		kdb_flags = (kdb_flags &			     ~(KDB_DEBUG_FLAG_MASK << KDB_DEBUG_FLAG_SHIFT))			| (debugflags << KDB_DEBUG_FLAG_SHIFT); 		return 0;	} 	/*	 * Tokenizer squashed the '=' sign.  argv[1] is variable	 * name, argv[2] = value.	 */	varlen = strlen(argv[1]);	vallen = strlen(argv[2]);	ep = kdballocenv(varlen + vallen + 2);	if (ep == (char *)0)		return KDB_ENVBUFFULL; 	sprintf(ep, "%s=%s", argv[1], argv[2]); 	ep[varlen+vallen+1] = '\0'; 	for (i = 0; i < __nenv; i++) {		if (__env[i]		 && ((strncmp(__env[i], argv[1], varlen) == 0)		   && ((__env[i][varlen] == '\0')		    || (__env[i][varlen] == '=')))) {			__env[i] = ep;			return 0;		}	} 	/*	 * Wasn't existing variable.  Fit into slot.	 */	for (i = 0; i < __nenv-1; i++) {		if (__env[i] == (char *)0) {			__env[i] = ep;			return 0;		}	} 	return KDB_ENVFULL;} static int kdb_check_regs(void){	if (!kdb_current_regs) {		kdb_printf("No current kdb registers."			   "  You may need to select another task\n");		return KDB_BADREG;	}	return 0;} /* * kdbgetaddrarg - This function is responsible for parsing an *	address-expression and returning the value of the expression, *	symbol name, and offset to the caller. * *	The argument may consist of a numeric value (decimal or *	hexidecimal), a symbol name, a register name (preceded by the *	percent sign), an environment variable with a numeric value *	(preceded by a dollar sign) or a simple arithmetic expression *	consisting of a symbol name, +/-, and a numeric constant value *	(offset). * Parameters: *	argc	- count of arguments in argv *	argv	- argument vector *	*nextarg - index to next unparsed argument in argv[] *	regs	- Register state at time of KDB entry * Outputs: *	*value	- receives the value of the address-expression *	*offset - receives the offset specified, if any *	*name   - receives the symbol name, if any *	*nextarg - index to next unparsed argument in argv[] * Returns: *	zero is returned on success, a kdb diagnostic code is *      returned on error. */int kdbgetaddrarg(int argc, const char **argv, int *nextarg,		  unsigned long *value,  long *offset,		  char **name){	unsigned long addr;	unsigned long off = 0;	int positive;	int diag;

Lines 1–500 of 2954.