Commit 72f9adfd20e3be8a33ff3ef96cec787ed97b9ba9
Exists in
master
and in
38 other branches
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
Showing 7 changed files Side-by-side Diff
kernel/debug/gdbstub.c
... | ... | @@ -42,6 +42,8 @@ |
42 | 42 | /* Our I/O buffers. */ |
43 | 43 | static char remcom_in_buffer[BUFMAX]; |
44 | 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 | 48 | /* Storage for the registers, in GDB format. */ |
47 | 49 | static unsigned long gdb_regs[(NUMREGBYTES + |
... | ... | @@ -58,6 +60,13 @@ |
58 | 60 | int ret = -1; |
59 | 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 | 70 | /* poll any additional I/O interfaces that are defined */ |
62 | 71 | while (ret < 0) |
63 | 72 | for (i = 0; kdb_poll_funcs[i] != NULL; i++) { |
... | ... | @@ -109,7 +118,6 @@ |
109 | 118 | buffer[count] = ch; |
110 | 119 | count = count + 1; |
111 | 120 | } |
112 | - buffer[count] = 0; | |
113 | 121 | |
114 | 122 | if (ch == '#') { |
115 | 123 | xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4; |
... | ... | @@ -124,6 +132,7 @@ |
124 | 132 | if (dbg_io_ops->flush) |
125 | 133 | dbg_io_ops->flush(); |
126 | 134 | } |
135 | + buffer[count] = 0; | |
127 | 136 | } while (checksum != xmitcsum); |
128 | 137 | } |
129 | 138 | |
... | ... | @@ -1082,12 +1091,11 @@ |
1082 | 1091 | case 'c': |
1083 | 1092 | strcpy(remcom_in_buffer, cmd); |
1084 | 1093 | return 0; |
1085 | - case '?': | |
1086 | - gdb_cmd_status(ks); | |
1087 | - break; | |
1088 | - case '\0': | |
1089 | - strcpy(remcom_out_buffer, ""); | |
1090 | - break; | |
1094 | + case '$': | |
1095 | + strcpy(remcom_in_buffer, cmd); | |
1096 | + gdbstub_use_prev_in_buf = strlen(remcom_in_buffer); | |
1097 | + gdbstub_prev_in_buf_pos = 0; | |
1098 | + return 0; | |
1091 | 1099 | } |
1092 | 1100 | dbg_io_ops->write_char('+'); |
1093 | 1101 | put_packet(remcom_out_buffer); |
kernel/debug/kdb/kdb_bt.c
... | ... | @@ -112,9 +112,8 @@ |
112 | 112 | unsigned long addr; |
113 | 113 | long offset; |
114 | 114 | |
115 | - kdbgetintenv("BTARGS", &argcount); /* Arguments to print */ | |
116 | - kdbgetintenv("BTAPROMPT", &btaprompt); /* Prompt after each | |
117 | - * proc in bta */ | |
115 | + /* Prompt after each proc in bta */ | |
116 | + kdbgetintenv("BTAPROMPT", &btaprompt); | |
118 | 117 | |
119 | 118 | if (strcmp(argv[0], "bta") == 0) { |
120 | 119 | struct task_struct *g, *p; |
kernel/debug/kdb/kdb_cmds
... | ... | @@ -18,16 +18,12 @@ |
18 | 18 | endefcmd |
19 | 19 | |
20 | 20 | defcmd dumpall "" "First line debugging" |
21 | - set BTSYMARG 1 | |
22 | - set BTARGS 9 | |
23 | 21 | pid R |
24 | 22 | -dumpcommon |
25 | 23 | -bta |
26 | 24 | endefcmd |
27 | 25 | |
28 | 26 | defcmd dumpcpu "" "Same as dumpall but only tasks on cpus" |
29 | - set BTSYMARG 1 | |
30 | - set BTARGS 9 | |
31 | 27 | pid R |
32 | 28 | -dumpcommon |
33 | 29 | -btc |
kernel/debug/kdb/kdb_debugger.c
... | ... | @@ -30,6 +30,8 @@ |
30 | 30 | int kdb_poll_idx = 1; |
31 | 31 | EXPORT_SYMBOL_GPL(kdb_poll_idx); |
32 | 32 | |
33 | +static struct kgdb_state *kdb_ks; | |
34 | + | |
33 | 35 | int kdb_stub(struct kgdb_state *ks) |
34 | 36 | { |
35 | 37 | int error = 0; |
... | ... | @@ -39,6 +41,7 @@ |
39 | 41 | kdb_dbtrap_t db_result = KDB_DB_NOBPT; |
40 | 42 | int i; |
41 | 43 | |
44 | + kdb_ks = ks; | |
42 | 45 | if (KDB_STATE(REENTRY)) { |
43 | 46 | reason = KDB_REASON_SWITCH; |
44 | 47 | KDB_STATE_CLEAR(REENTRY); |
45 | 48 | |
... | ... | @@ -123,20 +126,8 @@ |
123 | 126 | KDB_STATE_CLEAR(PAGER); |
124 | 127 | kdbnearsym_cleanup(); |
125 | 128 | if (error == KDB_CMD_KGDB) { |
126 | - 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, ""); | |
129 | + if (KDB_STATE(DOING_KGDB)) | |
137 | 130 | KDB_STATE_CLEAR(DOING_KGDB); |
138 | - KDB_STATE_CLEAR(DOING_KGDB2); | |
139 | - } | |
140 | 131 | return DBG_PASS_EVENT; |
141 | 132 | } |
142 | 133 | kdb_bp_install(ks->linux_regs); |
... | ... | @@ -164,5 +155,10 @@ |
164 | 155 | return DBG_SWITCH_CPU_EVENT; |
165 | 156 | } |
166 | 157 | return kgdb_info[ks->cpu].ret_state; |
158 | +} | |
159 | + | |
160 | +void kdb_gdb_state_pass(char *buf) | |
161 | +{ | |
162 | + gdbstub_state(kdb_ks, buf); | |
167 | 163 | } |
kernel/debug/kdb/kdb_io.c
... | ... | @@ -31,15 +31,21 @@ |
31 | 31 | |
32 | 32 | int kdb_trap_printk; |
33 | 33 | |
34 | -static void kgdb_transition_check(char *buffer) | |
34 | +static int kgdb_transition_check(char *buffer) | |
35 | 35 | { |
36 | - int slen = strlen(buffer); | |
37 | - if (strncmp(buffer, "$?#3f", slen) != 0 && | |
38 | - strncmp(buffer, "$qSupported#37", slen) != 0 && | |
39 | - strncmp(buffer, "+$qSupported#37", slen) != 0) { | |
36 | + if (buffer[0] != '+' && buffer[0] != '$') { | |
40 | 37 | KDB_STATE_SET(KGDB_TRANS); |
41 | 38 | kdb_printf("%s", buffer); |
39 | + } else { | |
40 | + int slen = strlen(buffer); | |
41 | + if (slen > 3 && buffer[slen - 3] == '#') { | |
42 | + kdb_gdb_state_pass(buffer); | |
43 | + strcpy(buffer, "kgdb"); | |
44 | + KDB_STATE_SET(DOING_KGDB); | |
45 | + return 1; | |
46 | + } | |
42 | 47 | } |
48 | + return 0; | |
43 | 49 | } |
44 | 50 | |
45 | 51 | static int kdb_read_get_key(char *buffer, size_t bufsize) |
... | ... | @@ -251,6 +257,10 @@ |
251 | 257 | case 13: /* enter */ |
252 | 258 | *lastchar++ = '\n'; |
253 | 259 | *lastchar++ = '\0'; |
260 | + if (!KDB_STATE(KGDB_TRANS)) { | |
261 | + KDB_STATE_SET(KGDB_TRANS); | |
262 | + kdb_printf("%s", buffer); | |
263 | + } | |
254 | 264 | kdb_printf("\n"); |
255 | 265 | return buffer; |
256 | 266 | case 4: /* Del */ |
257 | 267 | |
258 | 268 | |
259 | 269 | |
260 | 270 | |
... | ... | @@ -382,22 +392,26 @@ |
382 | 392 | * printed characters if we think that |
383 | 393 | * kgdb is connecting, until the check |
384 | 394 | * fails */ |
385 | - if (!KDB_STATE(KGDB_TRANS)) | |
386 | - kgdb_transition_check(buffer); | |
387 | - else | |
395 | + if (!KDB_STATE(KGDB_TRANS)) { | |
396 | + if (kgdb_transition_check(buffer)) | |
397 | + return buffer; | |
398 | + } else { | |
388 | 399 | kdb_printf("%c", key); |
400 | + } | |
389 | 401 | } |
390 | 402 | /* Special escape to kgdb */ |
391 | 403 | if (lastchar - buffer >= 5 && |
392 | 404 | strcmp(lastchar - 5, "$?#3f") == 0) { |
405 | + kdb_gdb_state_pass(lastchar - 5); | |
393 | 406 | strcpy(buffer, "kgdb"); |
394 | 407 | KDB_STATE_SET(DOING_KGDB); |
395 | 408 | return buffer; |
396 | 409 | } |
397 | - if (lastchar - buffer >= 14 && | |
398 | - strcmp(lastchar - 14, "$qSupported#37") == 0) { | |
410 | + if (lastchar - buffer >= 11 && | |
411 | + strcmp(lastchar - 11, "$qSupported") == 0) { | |
412 | + kdb_gdb_state_pass(lastchar - 11); | |
399 | 413 | strcpy(buffer, "kgdb"); |
400 | - KDB_STATE_SET(DOING_KGDB2); | |
414 | + KDB_STATE_SET(DOING_KGDB); | |
401 | 415 | return buffer; |
402 | 416 | } |
403 | 417 | } |
kernel/debug/kdb/kdb_main.c
... | ... | @@ -145,7 +145,6 @@ |
145 | 145 | #endif |
146 | 146 | "RADIX=16", |
147 | 147 | "MDCOUNT=8", /* lines of md output */ |
148 | - "BTARGS=9", /* 9 possible args in bt */ | |
149 | 148 | KDB_PLATFORM_ENV, |
150 | 149 | "DTABCOUNT=30", |
151 | 150 | "NOSECT=1", |
... | ... | @@ -172,6 +171,7 @@ |
172 | 171 | (char *)0, |
173 | 172 | (char *)0, |
174 | 173 | (char *)0, |
174 | + (char *)0, | |
175 | 175 | }; |
176 | 176 | |
177 | 177 | static const int __nenv = (sizeof(__env) / sizeof(char *)); |
... | ... | @@ -1386,7 +1386,7 @@ |
1386 | 1386 | } |
1387 | 1387 | |
1388 | 1388 | if (result == KDB_CMD_KGDB) { |
1389 | - if (!(KDB_STATE(DOING_KGDB) || KDB_STATE(DOING_KGDB2))) | |
1389 | + if (!KDB_STATE(DOING_KGDB)) | |
1390 | 1390 | kdb_printf("Entering please attach debugger " |
1391 | 1391 | "or use $D#44+ or $3#33\n"); |
1392 | 1392 | break; |
kernel/debug/kdb/kdb_private.h
... | ... | @@ -21,7 +21,6 @@ |
21 | 21 | #define KDB_CMD_SS (-1003) |
22 | 22 | #define KDB_CMD_SSB (-1004) |
23 | 23 | #define KDB_CMD_KGDB (-1005) |
24 | -#define KDB_CMD_KGDB2 (-1006) | |
25 | 24 | |
26 | 25 | /* Internal debug flags */ |
27 | 26 | #define KDB_DEBUG_FLAG_BP 0x0002 /* Breakpoint subsystem debug */ |
... | ... | @@ -146,7 +145,6 @@ |
146 | 145 | * keyboard on this cpu */ |
147 | 146 | #define KDB_STATE_KEXEC 0x00040000 /* kexec issued */ |
148 | 147 | #define KDB_STATE_DOING_KGDB 0x00080000 /* kgdb enter now issued */ |
149 | -#define KDB_STATE_DOING_KGDB2 0x00100000 /* kgdb enter now issued */ | |
150 | 148 | #define KDB_STATE_KGDB_TRANS 0x00200000 /* Transition to kgdb */ |
151 | 149 | #define KDB_STATE_ARCH 0xff000000 /* Reserved for arch |
152 | 150 | * specific use */ |
... | ... | @@ -218,6 +216,7 @@ |
218 | 216 | extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); |
219 | 217 | extern void kdb_meminfo_proc_show(void); |
220 | 218 | extern char *kdb_getstr(char *, size_t, char *); |
219 | +extern void kdb_gdb_state_pass(char *buf); | |
221 | 220 | |
222 | 221 | /* Defines for kdb_symbol_print */ |
223 | 222 | #define KDB_SP_SPACEB 0x0001 /* Space before string */ |