diff options
| -rw-r--r-- | kernel/debug/gdbstub.c | 22 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_debugger.c | 17 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_io.c | 10 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_private.h | 1 |
4 files changed, 29 insertions, 21 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 @@ | |||
| 42 | /* Our I/O buffers. */ | 42 | /* Our I/O buffers. */ |
| 43 | static char remcom_in_buffer[BUFMAX]; | 43 | static char remcom_in_buffer[BUFMAX]; |
| 44 | static char remcom_out_buffer[BUFMAX]; | 44 | static char remcom_out_buffer[BUFMAX]; |
| 45 | static int gdbstub_use_prev_in_buf; | ||
| 46 | static int gdbstub_prev_in_buf_pos; | ||
| 45 | 47 | ||
| 46 | /* Storage for the registers, in GDB format. */ | 48 | /* Storage for the registers, in GDB format. */ |
| 47 | static unsigned long gdb_regs[(NUMREGBYTES + | 49 | static unsigned long gdb_regs[(NUMREGBYTES + |
| @@ -58,6 +60,13 @@ static int gdbstub_read_wait(void) | |||
| 58 | int ret = -1; | 60 | int ret = -1; |
| 59 | int i; | 61 | int i; |
| 60 | 62 | ||
| 63 | if (unlikely(gdbstub_use_prev_in_buf)) { | ||
| 64 | if (gdbstub_prev_in_buf_pos < gdbstub_use_prev_in_buf) | ||
| 65 | return remcom_in_buffer[gdbstub_prev_in_buf_pos++]; | ||
| 66 | else | ||
| 67 | gdbstub_use_prev_in_buf = 0; | ||
| 68 | } | ||
| 69 | |||
| 61 | /* poll any additional I/O interfaces that are defined */ | 70 | /* poll any additional I/O interfaces that are defined */ |
| 62 | while (ret < 0) | 71 | while (ret < 0) |
| 63 | for (i = 0; kdb_poll_funcs[i] != NULL; i++) { | 72 | for (i = 0; kdb_poll_funcs[i] != NULL; i++) { |
| @@ -109,7 +118,6 @@ static void get_packet(char *buffer) | |||
| 109 | buffer[count] = ch; | 118 | buffer[count] = ch; |
| 110 | count = count + 1; | 119 | count = count + 1; |
| 111 | } | 120 | } |
| 112 | buffer[count] = 0; | ||
| 113 | 121 | ||
| 114 | if (ch == '#') { | 122 | if (ch == '#') { |
| 115 | xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4; | 123 | xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4; |
| @@ -124,6 +132,7 @@ static void get_packet(char *buffer) | |||
| 124 | if (dbg_io_ops->flush) | 132 | if (dbg_io_ops->flush) |
| 125 | dbg_io_ops->flush(); | 133 | dbg_io_ops->flush(); |
| 126 | } | 134 | } |
| 135 | buffer[count] = 0; | ||
| 127 | } while (checksum != xmitcsum); | 136 | } while (checksum != xmitcsum); |
| 128 | } | 137 | } |
| 129 | 138 | ||
| @@ -1082,12 +1091,11 @@ int gdbstub_state(struct kgdb_state *ks, char *cmd) | |||
| 1082 | case 'c': | 1091 | case 'c': |
| 1083 | strcpy(remcom_in_buffer, cmd); | 1092 | strcpy(remcom_in_buffer, cmd); |
| 1084 | return 0; | 1093 | return 0; |
| 1085 | case '?': | 1094 | case '$': |
| 1086 | gdb_cmd_status(ks); | 1095 | strcpy(remcom_in_buffer, cmd); |
| 1087 | break; | 1096 | gdbstub_use_prev_in_buf = strlen(remcom_in_buffer); |
| 1088 | case '\0': | 1097 | gdbstub_prev_in_buf_pos = 0; |
| 1089 | strcpy(remcom_out_buffer, ""); | 1098 | return 0; |
| 1090 | break; | ||
| 1091 | } | 1099 | } |
| 1092 | dbg_io_ops->write_char('+'); | 1100 | dbg_io_ops->write_char('+'); |
| 1093 | put_packet(remcom_out_buffer); | 1101 | put_packet(remcom_out_buffer); |
diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c index dd0b1b7dd02c..fe422d275782 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); | |||
| 30 | int kdb_poll_idx = 1; | 30 | int kdb_poll_idx = 1; |
| 31 | EXPORT_SYMBOL_GPL(kdb_poll_idx); | 31 | EXPORT_SYMBOL_GPL(kdb_poll_idx); |
| 32 | 32 | ||
| 33 | static struct kgdb_state *kdb_ks; | ||
| 34 | |||
| 33 | int kdb_stub(struct kgdb_state *ks) | 35 | int kdb_stub(struct kgdb_state *ks) |
| 34 | { | 36 | { |
| 35 | int error = 0; | 37 | int error = 0; |
| @@ -39,6 +41,7 @@ int kdb_stub(struct kgdb_state *ks) | |||
| 39 | kdb_dbtrap_t db_result = KDB_DB_NOBPT; | 41 | kdb_dbtrap_t db_result = KDB_DB_NOBPT; |
| 40 | int i; | 42 | int i; |
| 41 | 43 | ||
| 44 | kdb_ks = ks; | ||
| 42 | if (KDB_STATE(REENTRY)) { | 45 | if (KDB_STATE(REENTRY)) { |
| 43 | reason = KDB_REASON_SWITCH; | 46 | reason = KDB_REASON_SWITCH; |
| 44 | KDB_STATE_CLEAR(REENTRY); | 47 | KDB_STATE_CLEAR(REENTRY); |
| @@ -124,16 +127,6 @@ int kdb_stub(struct kgdb_state *ks) | |||
| 124 | kdbnearsym_cleanup(); | 127 | kdbnearsym_cleanup(); |
| 125 | if (error == KDB_CMD_KGDB) { | 128 | if (error == KDB_CMD_KGDB) { |
| 126 | if (KDB_STATE(DOING_KGDB) || KDB_STATE(DOING_KGDB2)) { | 129 | if (KDB_STATE(DOING_KGDB) || KDB_STATE(DOING_KGDB2)) { |
| 127 | /* | ||
| 128 | * This inteface glue which allows kdb to transition in into | ||
| 129 | * the gdb stub. In order to do this the '?' or '' gdb serial | ||
| 130 | * packet response is processed here. And then control is | ||
| 131 | * passed to the gdbstub. | ||
| 132 | */ | ||
| 133 | if (KDB_STATE(DOING_KGDB)) | ||
| 134 | gdbstub_state(ks, "?"); | ||
| 135 | else | ||
| 136 | gdbstub_state(ks, ""); | ||
| 137 | KDB_STATE_CLEAR(DOING_KGDB); | 130 | KDB_STATE_CLEAR(DOING_KGDB); |
| 138 | KDB_STATE_CLEAR(DOING_KGDB2); | 131 | KDB_STATE_CLEAR(DOING_KGDB2); |
| 139 | } | 132 | } |
| @@ -166,3 +159,7 @@ int kdb_stub(struct kgdb_state *ks) | |||
| 166 | return kgdb_info[ks->cpu].ret_state; | 159 | return kgdb_info[ks->cpu].ret_state; |
| 167 | } | 160 | } |
| 168 | 161 | ||
| 162 | void kdb_gdb_state_pass(char *buf) | ||
| 163 | { | ||
| 164 | gdbstub_state(kdb_ks, buf); | ||
| 165 | } | ||
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 96fdaac46a80..bd233264b29f 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c | |||
| @@ -35,8 +35,8 @@ static void kgdb_transition_check(char *buffer) | |||
| 35 | { | 35 | { |
| 36 | int slen = strlen(buffer); | 36 | int slen = strlen(buffer); |
| 37 | if (strncmp(buffer, "$?#3f", slen) != 0 && | 37 | if (strncmp(buffer, "$?#3f", slen) != 0 && |
| 38 | strncmp(buffer, "$qSupported#37", slen) != 0 && | 38 | strncmp(buffer, "$qSupported", slen) != 0 && |
| 39 | strncmp(buffer, "+$qSupported#37", slen) != 0) { | 39 | strncmp(buffer, "+$qSupported", slen) != 0) { |
| 40 | KDB_STATE_SET(KGDB_TRANS); | 40 | KDB_STATE_SET(KGDB_TRANS); |
| 41 | kdb_printf("%s", buffer); | 41 | kdb_printf("%s", buffer); |
| 42 | } | 42 | } |
| @@ -390,12 +390,14 @@ poll_again: | |||
| 390 | /* Special escape to kgdb */ | 390 | /* Special escape to kgdb */ |
| 391 | if (lastchar - buffer >= 5 && | 391 | if (lastchar - buffer >= 5 && |
| 392 | strcmp(lastchar - 5, "$?#3f") == 0) { | 392 | strcmp(lastchar - 5, "$?#3f") == 0) { |
| 393 | kdb_gdb_state_pass(lastchar - 5); | ||
| 393 | strcpy(buffer, "kgdb"); | 394 | strcpy(buffer, "kgdb"); |
| 394 | KDB_STATE_SET(DOING_KGDB); | 395 | KDB_STATE_SET(DOING_KGDB); |
| 395 | return buffer; | 396 | return buffer; |
| 396 | } | 397 | } |
| 397 | if (lastchar - buffer >= 14 && | 398 | if (lastchar - buffer >= 11 && |
| 398 | strcmp(lastchar - 14, "$qSupported#37") == 0) { | 399 | strcmp(lastchar - 11, "$qSupported") == 0) { |
| 400 | kdb_gdb_state_pass(lastchar - 11); | ||
| 399 | strcpy(buffer, "kgdb"); | 401 | strcpy(buffer, "kgdb"); |
| 400 | KDB_STATE_SET(DOING_KGDB2); | 402 | KDB_STATE_SET(DOING_KGDB2); |
| 401 | return buffer; | 403 | return buffer; |
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 35d69ed1dfb5..03d332e63442 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h | |||
| @@ -218,6 +218,7 @@ extern void kdb_print_nameval(const char *name, unsigned long val); | |||
| 218 | extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); | 218 | extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); |
| 219 | extern void kdb_meminfo_proc_show(void); | 219 | extern void kdb_meminfo_proc_show(void); |
| 220 | extern char *kdb_getstr(char *, size_t, char *); | 220 | extern char *kdb_getstr(char *, size_t, char *); |
| 221 | extern void kdb_gdb_state_pass(char *buf); | ||
| 221 | 222 | ||
| 222 | /* Defines for kdb_symbol_print */ | 223 | /* Defines for kdb_symbol_print */ |
| 223 | #define KDB_SP_SPACEB 0x0001 /* Space before string */ | 224 | #define KDB_SP_SPACEB 0x0001 /* Space before string */ |
