diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-01 13:39:40 -1000 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-01 13:39:40 -1000 | 
| commit | 72f9adfd20e3be8a33ff3ef96cec787ed97b9ba9 (patch) | |
| tree | 2e59de0152634f577ba996a1a3f35eceb9c5ebee | |
| parent | 5f66d2b58ca879e70740c82422354144845d6dd3 (diff) | |
| parent | 37f86b469d73fc2f2a925536fb99b8f513f641b7 (diff) | |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb:
  kdb,kgdb: Allow arbitrary kgdb magic knock sequences
  kdb: Remove all references to DOING_KGDB2
  kdb,kgdb: Implement switch and pass buffer from kdb -> gdb
  kdb: cleanup unused variables missed in the original kdb merge
| -rw-r--r-- | kernel/debug/gdbstub.c | 22 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_bt.c | 5 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_cmds | 4 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_debugger.c | 21 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_io.c | 36 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_main.c | 4 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_private.h | 3 | 
7 files changed, 53 insertions, 42 deletions
diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c index a11db956dd62..34872482315e 100644 --- a/kernel/debug/gdbstub.c +++ b/kernel/debug/gdbstub.c @@ -42,6 +42,8 @@  /* Our I/O buffers. */  static char			remcom_in_buffer[BUFMAX];  static char			remcom_out_buffer[BUFMAX]; +static int			gdbstub_use_prev_in_buf; +static int			gdbstub_prev_in_buf_pos;  /* Storage for the registers, in GDB format. */  static unsigned long		gdb_regs[(NUMREGBYTES + @@ -58,6 +60,13 @@ static int gdbstub_read_wait(void)  	int ret = -1;  	int i; +	if (unlikely(gdbstub_use_prev_in_buf)) { +		if (gdbstub_prev_in_buf_pos < gdbstub_use_prev_in_buf) +			return remcom_in_buffer[gdbstub_prev_in_buf_pos++]; +		else +			gdbstub_use_prev_in_buf = 0; +	} +  	/* poll any additional I/O interfaces that are defined */  	while (ret < 0)  		for (i = 0; kdb_poll_funcs[i] != NULL; i++) { @@ -109,7 +118,6 @@ static void get_packet(char *buffer)  			buffer[count] = ch;  			count = count + 1;  		} -		buffer[count] = 0;  		if (ch == '#') {  			xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4; @@ -124,6 +132,7 @@ static void get_packet(char *buffer)  			if (dbg_io_ops->flush)  				dbg_io_ops->flush();  		} +		buffer[count] = 0;  	} while (checksum != xmitcsum);  } @@ -1082,12 +1091,11 @@ int gdbstub_state(struct kgdb_state *ks, char *cmd)  	case 'c':  		strcpy(remcom_in_buffer, cmd);  		return 0; -	case '?': -		gdb_cmd_status(ks); -		break; -	case '\0': -		strcpy(remcom_out_buffer, ""); -		break; +	case '$': +		strcpy(remcom_in_buffer, cmd); +		gdbstub_use_prev_in_buf = strlen(remcom_in_buffer); +		gdbstub_prev_in_buf_pos = 0; +		return 0;  	}  	dbg_io_ops->write_char('+');  	put_packet(remcom_out_buffer); diff --git a/kernel/debug/kdb/kdb_bt.c b/kernel/debug/kdb/kdb_bt.c index 2f62fe85f16a..7179eac7b41c 100644 --- a/kernel/debug/kdb/kdb_bt.c +++ b/kernel/debug/kdb/kdb_bt.c @@ -112,9 +112,8 @@ kdb_bt(int argc, const char **argv)  	unsigned long addr;  	long offset; -	kdbgetintenv("BTARGS", &argcount);	/* Arguments to print */ -	kdbgetintenv("BTAPROMPT", &btaprompt);	/* Prompt after each -						 * proc in bta */ +	/* Prompt after each proc in bta */ +	kdbgetintenv("BTAPROMPT", &btaprompt);  	if (strcmp(argv[0], "bta") == 0) {  		struct task_struct *g, *p; diff --git a/kernel/debug/kdb/kdb_cmds b/kernel/debug/kdb/kdb_cmds index 56c88e4db309..9834ad303ab6 100644 --- a/kernel/debug/kdb/kdb_cmds +++ b/kernel/debug/kdb/kdb_cmds @@ -18,16 +18,12 @@ defcmd dumpcommon "" "Common kdb debugging"  endefcmd  defcmd dumpall "" "First line debugging" -  set BTSYMARG 1 -  set BTARGS 9    pid R    -dumpcommon    -bta  endefcmd  defcmd dumpcpu "" "Same as dumpall but only tasks on cpus" -  set BTSYMARG 1 -  set BTARGS 9    pid R    -dumpcommon    -btc diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c index dd0b1b7dd02c..d9ca9aa481ec 100644 --- a/kernel/debug/kdb/kdb_debugger.c +++ b/kernel/debug/kdb/kdb_debugger.c @@ -30,6 +30,8 @@ EXPORT_SYMBOL_GPL(kdb_poll_funcs);  int kdb_poll_idx = 1;  EXPORT_SYMBOL_GPL(kdb_poll_idx); +static struct kgdb_state *kdb_ks; +  int kdb_stub(struct kgdb_state *ks)  {  	int error = 0; @@ -39,6 +41,7 @@ int kdb_stub(struct kgdb_state *ks)  	kdb_dbtrap_t db_result = KDB_DB_NOBPT;  	int i; +	kdb_ks = ks;  	if (KDB_STATE(REENTRY)) {  		reason = KDB_REASON_SWITCH;  		KDB_STATE_CLEAR(REENTRY); @@ -123,20 +126,8 @@ int kdb_stub(struct kgdb_state *ks)  	KDB_STATE_CLEAR(PAGER);  	kdbnearsym_cleanup();  	if (error == KDB_CMD_KGDB) { -		if (KDB_STATE(DOING_KGDB) || KDB_STATE(DOING_KGDB2)) { -	/* -	 * This inteface glue which allows kdb to transition in into -	 * the gdb stub.  In order to do this the '?' or '' gdb serial -	 * packet response is processed here.  And then control is -	 * passed to the gdbstub. -	 */ -			if (KDB_STATE(DOING_KGDB)) -				gdbstub_state(ks, "?"); -			else -				gdbstub_state(ks, ""); +		if (KDB_STATE(DOING_KGDB))  			KDB_STATE_CLEAR(DOING_KGDB); -			KDB_STATE_CLEAR(DOING_KGDB2); -		}  		return DBG_PASS_EVENT;  	}  	kdb_bp_install(ks->linux_regs); @@ -166,3 +157,7 @@ int kdb_stub(struct kgdb_state *ks)  	return kgdb_info[ks->cpu].ret_state;  } +void kdb_gdb_state_pass(char *buf) +{ +	gdbstub_state(kdb_ks, buf); +} diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 96fdaac46a80..4802eb5840e1 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c @@ -31,15 +31,21 @@ char kdb_prompt_str[CMD_BUFLEN];  int kdb_trap_printk; -static void kgdb_transition_check(char *buffer) +static int kgdb_transition_check(char *buffer)  { -	int slen = strlen(buffer); -	if (strncmp(buffer, "$?#3f", slen) != 0 && -	    strncmp(buffer, "$qSupported#37", slen) != 0 && -	    strncmp(buffer, "+$qSupported#37", slen) != 0) { +	if (buffer[0] != '+' && buffer[0] != '$') {  		KDB_STATE_SET(KGDB_TRANS);  		kdb_printf("%s", buffer); +	} else { +		int slen = strlen(buffer); +		if (slen > 3 && buffer[slen - 3] == '#') { +			kdb_gdb_state_pass(buffer); +			strcpy(buffer, "kgdb"); +			KDB_STATE_SET(DOING_KGDB); +			return 1; +		}  	} +	return 0;  }  static int kdb_read_get_key(char *buffer, size_t bufsize) @@ -251,6 +257,10 @@ poll_again:  	case 13: /* enter */  		*lastchar++ = '\n';  		*lastchar++ = '\0'; +		if (!KDB_STATE(KGDB_TRANS)) { +			KDB_STATE_SET(KGDB_TRANS); +			kdb_printf("%s", buffer); +		}  		kdb_printf("\n");  		return buffer;  	case 4: /* Del */ @@ -382,22 +392,26 @@ poll_again:  				 * printed characters if we think that  				 * kgdb is connecting, until the check  				 * fails */ -				if (!KDB_STATE(KGDB_TRANS)) -					kgdb_transition_check(buffer); -				else +				if (!KDB_STATE(KGDB_TRANS)) { +					if (kgdb_transition_check(buffer)) +						return buffer; +				} else {  					kdb_printf("%c", key); +				}  			}  			/* Special escape to kgdb */  			if (lastchar - buffer >= 5 &&  			    strcmp(lastchar - 5, "$?#3f") == 0) { +				kdb_gdb_state_pass(lastchar - 5);  				strcpy(buffer, "kgdb");  				KDB_STATE_SET(DOING_KGDB);  				return buffer;  			} -			if (lastchar - buffer >= 14 && -			    strcmp(lastchar - 14, "$qSupported#37") == 0) { +			if (lastchar - buffer >= 11 && +			    strcmp(lastchar - 11, "$qSupported") == 0) { +				kdb_gdb_state_pass(lastchar - 11);  				strcpy(buffer, "kgdb"); -				KDB_STATE_SET(DOING_KGDB2); +				KDB_STATE_SET(DOING_KGDB);  				return buffer;  			}  		} diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index be14779bcef6..63786e71a3cd 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -145,7 +145,6 @@ static char *__env[] = {  #endif   "RADIX=16",   "MDCOUNT=8",			/* lines of md output */ - "BTARGS=9",			/* 9 possible args in bt */   KDB_PLATFORM_ENV,   "DTABCOUNT=30",   "NOSECT=1", @@ -172,6 +171,7 @@ static char *__env[] = {   (char *)0,   (char *)0,   (char *)0, + (char *)0,  };  static const int __nenv = (sizeof(__env) / sizeof(char *)); @@ -1386,7 +1386,7 @@ int kdb_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,  		}  		if (result == KDB_CMD_KGDB) { -			if (!(KDB_STATE(DOING_KGDB) || KDB_STATE(DOING_KGDB2))) +			if (!KDB_STATE(DOING_KGDB))  				kdb_printf("Entering please attach debugger "  					   "or use $D#44+ or $3#33\n");  			break; diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 35d69ed1dfb5..e381d105b40b 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h @@ -21,7 +21,6 @@  #define KDB_CMD_SS	(-1003)  #define KDB_CMD_SSB	(-1004)  #define KDB_CMD_KGDB (-1005) -#define KDB_CMD_KGDB2 (-1006)  /* Internal debug flags */  #define KDB_DEBUG_FLAG_BP	0x0002	/* Breakpoint subsystem debug */ @@ -146,7 +145,6 @@ extern int kdb_state;  						 * keyboard on this cpu */  #define KDB_STATE_KEXEC		0x00040000	/* kexec issued */  #define KDB_STATE_DOING_KGDB	0x00080000	/* kgdb enter now issued */ -#define KDB_STATE_DOING_KGDB2	0x00100000	/* kgdb enter now issued */  #define KDB_STATE_KGDB_TRANS	0x00200000	/* Transition to kgdb */  #define KDB_STATE_ARCH		0xff000000	/* Reserved for arch  						 * specific use */ @@ -218,6 +216,7 @@ extern void kdb_print_nameval(const char *name, unsigned long val);  extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info);  extern void kdb_meminfo_proc_show(void);  extern char *kdb_getstr(char *, size_t, char *); +extern void kdb_gdb_state_pass(char *buf);  /* Defines for kdb_symbol_print */  #define KDB_SP_SPACEB	0x0001		/* Space before string */  | 
