Commit 72f9adfd authored by Linus Torvalds's avatar Linus Torvalds

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
parents 5f66d2b5 37f86b46
...@@ -42,6 +42,8 @@ ...@@ -42,6 +42,8 @@
/* Our I/O buffers. */ /* Our I/O buffers. */
static char remcom_in_buffer[BUFMAX]; static char remcom_in_buffer[BUFMAX];
static char remcom_out_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. */ /* Storage for the registers, in GDB format. */
static unsigned long gdb_regs[(NUMREGBYTES + static unsigned long gdb_regs[(NUMREGBYTES +
...@@ -58,6 +60,13 @@ static int gdbstub_read_wait(void) ...@@ -58,6 +60,13 @@ static int gdbstub_read_wait(void)
int ret = -1; int ret = -1;
int i; 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 */ /* poll any additional I/O interfaces that are defined */
while (ret < 0) while (ret < 0)
for (i = 0; kdb_poll_funcs[i] != NULL; i++) { for (i = 0; kdb_poll_funcs[i] != NULL; i++) {
...@@ -109,7 +118,6 @@ static void get_packet(char *buffer) ...@@ -109,7 +118,6 @@ static void get_packet(char *buffer)
buffer[count] = ch; buffer[count] = ch;
count = count + 1; count = count + 1;
} }
buffer[count] = 0;
if (ch == '#') { if (ch == '#') {
xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4; xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4;
...@@ -124,6 +132,7 @@ static void get_packet(char *buffer) ...@@ -124,6 +132,7 @@ static void get_packet(char *buffer)
if (dbg_io_ops->flush) if (dbg_io_ops->flush)
dbg_io_ops->flush(); dbg_io_ops->flush();
} }
buffer[count] = 0;
} while (checksum != xmitcsum); } while (checksum != xmitcsum);
} }
...@@ -1082,12 +1091,11 @@ int gdbstub_state(struct kgdb_state *ks, char *cmd) ...@@ -1082,12 +1091,11 @@ int gdbstub_state(struct kgdb_state *ks, char *cmd)
case 'c': case 'c':
strcpy(remcom_in_buffer, cmd); strcpy(remcom_in_buffer, cmd);
return 0; return 0;
case '?': case '$':
gdb_cmd_status(ks); strcpy(remcom_in_buffer, cmd);
break; gdbstub_use_prev_in_buf = strlen(remcom_in_buffer);
case '\0': gdbstub_prev_in_buf_pos = 0;
strcpy(remcom_out_buffer, ""); return 0;
break;
} }
dbg_io_ops->write_char('+'); dbg_io_ops->write_char('+');
put_packet(remcom_out_buffer); put_packet(remcom_out_buffer);
......
...@@ -112,9 +112,8 @@ kdb_bt(int argc, const char **argv) ...@@ -112,9 +112,8 @@ kdb_bt(int argc, const char **argv)
unsigned long addr; unsigned long addr;
long offset; long offset;
kdbgetintenv("BTARGS", &argcount); /* Arguments to print */ /* Prompt after each proc in bta */
kdbgetintenv("BTAPROMPT", &btaprompt); /* Prompt after each kdbgetintenv("BTAPROMPT", &btaprompt);
* proc in bta */
if (strcmp(argv[0], "bta") == 0) { if (strcmp(argv[0], "bta") == 0) {
struct task_struct *g, *p; struct task_struct *g, *p;
......
...@@ -18,16 +18,12 @@ defcmd dumpcommon "" "Common kdb debugging" ...@@ -18,16 +18,12 @@ defcmd dumpcommon "" "Common kdb debugging"
endefcmd endefcmd
defcmd dumpall "" "First line debugging" defcmd dumpall "" "First line debugging"
set BTSYMARG 1
set BTARGS 9
pid R pid R
-dumpcommon -dumpcommon
-bta -bta
endefcmd endefcmd
defcmd dumpcpu "" "Same as dumpall but only tasks on cpus" defcmd dumpcpu "" "Same as dumpall but only tasks on cpus"
set BTSYMARG 1
set BTARGS 9
pid R pid R
-dumpcommon -dumpcommon
-btc -btc
......
...@@ -30,6 +30,8 @@ EXPORT_SYMBOL_GPL(kdb_poll_funcs); ...@@ -30,6 +30,8 @@ EXPORT_SYMBOL_GPL(kdb_poll_funcs);
int kdb_poll_idx = 1; int kdb_poll_idx = 1;
EXPORT_SYMBOL_GPL(kdb_poll_idx); EXPORT_SYMBOL_GPL(kdb_poll_idx);
static struct kgdb_state *kdb_ks;
int kdb_stub(struct kgdb_state *ks) int kdb_stub(struct kgdb_state *ks)
{ {
int error = 0; int error = 0;
...@@ -39,6 +41,7 @@ int kdb_stub(struct kgdb_state *ks) ...@@ -39,6 +41,7 @@ int kdb_stub(struct kgdb_state *ks)
kdb_dbtrap_t db_result = KDB_DB_NOBPT; kdb_dbtrap_t db_result = KDB_DB_NOBPT;
int i; int i;
kdb_ks = ks;
if (KDB_STATE(REENTRY)) { if (KDB_STATE(REENTRY)) {
reason = KDB_REASON_SWITCH; reason = KDB_REASON_SWITCH;
KDB_STATE_CLEAR(REENTRY); KDB_STATE_CLEAR(REENTRY);
...@@ -123,20 +126,8 @@ int kdb_stub(struct kgdb_state *ks) ...@@ -123,20 +126,8 @@ int kdb_stub(struct kgdb_state *ks)
KDB_STATE_CLEAR(PAGER); KDB_STATE_CLEAR(PAGER);
kdbnearsym_cleanup(); kdbnearsym_cleanup();
if (error == KDB_CMD_KGDB) { if (error == KDB_CMD_KGDB) {
if (KDB_STATE(DOING_KGDB) || KDB_STATE(DOING_KGDB2)) { if (KDB_STATE(DOING_KGDB))
/*
* 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, "");
KDB_STATE_CLEAR(DOING_KGDB); KDB_STATE_CLEAR(DOING_KGDB);
KDB_STATE_CLEAR(DOING_KGDB2);
}
return DBG_PASS_EVENT; return DBG_PASS_EVENT;
} }
kdb_bp_install(ks->linux_regs); kdb_bp_install(ks->linux_regs);
...@@ -166,3 +157,7 @@ int kdb_stub(struct kgdb_state *ks) ...@@ -166,3 +157,7 @@ int kdb_stub(struct kgdb_state *ks)
return kgdb_info[ks->cpu].ret_state; return kgdb_info[ks->cpu].ret_state;
} }
void kdb_gdb_state_pass(char *buf)
{
gdbstub_state(kdb_ks, buf);
}
...@@ -31,15 +31,21 @@ char kdb_prompt_str[CMD_BUFLEN]; ...@@ -31,15 +31,21 @@ char kdb_prompt_str[CMD_BUFLEN];
int kdb_trap_printk; int kdb_trap_printk;
static void kgdb_transition_check(char *buffer) static int kgdb_transition_check(char *buffer)
{ {
int slen = strlen(buffer); if (buffer[0] != '+' && buffer[0] != '$') {
if (strncmp(buffer, "$?#3f", slen) != 0 &&
strncmp(buffer, "$qSupported#37", slen) != 0 &&
strncmp(buffer, "+$qSupported#37", slen) != 0) {
KDB_STATE_SET(KGDB_TRANS); KDB_STATE_SET(KGDB_TRANS);
kdb_printf("%s", buffer); 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) static int kdb_read_get_key(char *buffer, size_t bufsize)
...@@ -251,6 +257,10 @@ static char *kdb_read(char *buffer, size_t bufsize) ...@@ -251,6 +257,10 @@ static char *kdb_read(char *buffer, size_t bufsize)
case 13: /* enter */ case 13: /* enter */
*lastchar++ = '\n'; *lastchar++ = '\n';
*lastchar++ = '\0'; *lastchar++ = '\0';
if (!KDB_STATE(KGDB_TRANS)) {
KDB_STATE_SET(KGDB_TRANS);
kdb_printf("%s", buffer);
}
kdb_printf("\n"); kdb_printf("\n");
return buffer; return buffer;
case 4: /* Del */ case 4: /* Del */
...@@ -382,22 +392,26 @@ static char *kdb_read(char *buffer, size_t bufsize) ...@@ -382,22 +392,26 @@ static char *kdb_read(char *buffer, size_t bufsize)
* printed characters if we think that * printed characters if we think that
* kgdb is connecting, until the check * kgdb is connecting, until the check
* fails */ * fails */
if (!KDB_STATE(KGDB_TRANS)) if (!KDB_STATE(KGDB_TRANS)) {
kgdb_transition_check(buffer); if (kgdb_transition_check(buffer))
else return buffer;
} else {
kdb_printf("%c", key); kdb_printf("%c", key);
}
} }
/* Special escape to kgdb */ /* Special escape to kgdb */
if (lastchar - buffer >= 5 && if (lastchar - buffer >= 5 &&
strcmp(lastchar - 5, "$?#3f") == 0) { strcmp(lastchar - 5, "$?#3f") == 0) {
kdb_gdb_state_pass(lastchar - 5);
strcpy(buffer, "kgdb"); strcpy(buffer, "kgdb");
KDB_STATE_SET(DOING_KGDB); KDB_STATE_SET(DOING_KGDB);
return buffer; return buffer;
} }
if (lastchar - buffer >= 14 && if (lastchar - buffer >= 11 &&
strcmp(lastchar - 14, "$qSupported#37") == 0) { strcmp(lastchar - 11, "$qSupported") == 0) {
kdb_gdb_state_pass(lastchar - 11);
strcpy(buffer, "kgdb"); strcpy(buffer, "kgdb");
KDB_STATE_SET(DOING_KGDB2); KDB_STATE_SET(DOING_KGDB);
return buffer; return buffer;
} }
} }
......
...@@ -145,7 +145,6 @@ static char *__env[] = { ...@@ -145,7 +145,6 @@ static char *__env[] = {
#endif #endif
"RADIX=16", "RADIX=16",
"MDCOUNT=8", /* lines of md output */ "MDCOUNT=8", /* lines of md output */
"BTARGS=9", /* 9 possible args in bt */
KDB_PLATFORM_ENV, KDB_PLATFORM_ENV,
"DTABCOUNT=30", "DTABCOUNT=30",
"NOSECT=1", "NOSECT=1",
...@@ -172,6 +171,7 @@ static char *__env[] = { ...@@ -172,6 +171,7 @@ static char *__env[] = {
(char *)0, (char *)0,
(char *)0, (char *)0,
(char *)0, (char *)0,
(char *)0,
}; };
static const int __nenv = (sizeof(__env) / sizeof(char *)); 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, ...@@ -1386,7 +1386,7 @@ int kdb_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,
} }
if (result == KDB_CMD_KGDB) { 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 " kdb_printf("Entering please attach debugger "
"or use $D#44+ or $3#33\n"); "or use $D#44+ or $3#33\n");
break; break;
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#define KDB_CMD_SS (-1003) #define KDB_CMD_SS (-1003)
#define KDB_CMD_SSB (-1004) #define KDB_CMD_SSB (-1004)
#define KDB_CMD_KGDB (-1005) #define KDB_CMD_KGDB (-1005)
#define KDB_CMD_KGDB2 (-1006)
/* Internal debug flags */ /* Internal debug flags */
#define KDB_DEBUG_FLAG_BP 0x0002 /* Breakpoint subsystem debug */ #define KDB_DEBUG_FLAG_BP 0x0002 /* Breakpoint subsystem debug */
...@@ -146,7 +145,6 @@ extern int kdb_state; ...@@ -146,7 +145,6 @@ extern int kdb_state;
* keyboard on this cpu */ * keyboard on this cpu */
#define KDB_STATE_KEXEC 0x00040000 /* kexec issued */ #define KDB_STATE_KEXEC 0x00040000 /* kexec issued */
#define KDB_STATE_DOING_KGDB 0x00080000 /* kgdb enter now 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_KGDB_TRANS 0x00200000 /* Transition to kgdb */
#define KDB_STATE_ARCH 0xff000000 /* Reserved for arch #define KDB_STATE_ARCH 0xff000000 /* Reserved for arch
* specific use */ * specific use */
...@@ -218,6 +216,7 @@ extern void kdb_print_nameval(const char *name, unsigned long val); ...@@ -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_send_sig_info(struct task_struct *p, struct siginfo *info);
extern void kdb_meminfo_proc_show(void); extern void kdb_meminfo_proc_show(void);
extern char *kdb_getstr(char *, size_t, char *); extern char *kdb_getstr(char *, size_t, char *);
extern void kdb_gdb_state_pass(char *buf);
/* Defines for kdb_symbol_print */ /* Defines for kdb_symbol_print */
#define KDB_SP_SPACEB 0x0001 /* Space before string */ #define KDB_SP_SPACEB 0x0001 /* Space before string */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment