kgdb_stub.c revision 1.23.6.1 1 /* $NetBSD: kgdb_stub.c,v 1.23.6.1 2011/04/21 01:42:09 rmind Exp $ */
2
3 /*
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
10 *
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratories.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
41 */
42
43 /*
44 * "Stub" to allow remote CPU to debug over a serial line using gdb.
45 */
46
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD: kgdb_stub.c,v 1.23.6.1 2011/04/21 01:42:09 rmind Exp $");
49
50 #include "opt_kgdb.h"
51
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/kgdb.h>
55
56 #undef DEBUG_KGDB
57
58 #ifdef DEBUG_KGDB
59 #define DPRINTF(x) printf x
60 #else
61 #define DPRINTF(x)
62 #endif
63
64 /* XXX: Maybe these should be in the MD files? */
65 #ifndef KGDB_DEV
66 #define KGDB_DEV NODEV
67 #endif
68 #ifndef KGDB_DEVRATE
69 #define KGDB_DEVRATE 19200
70 #endif
71
72 dev_t kgdb_dev = KGDB_DEV; /* remote debugging device (NODEV if none) */
73 int kgdb_rate = KGDB_DEVRATE; /* remote debugging baud rate */
74 int kgdb_active = 0; /* remote debugging active if != 0 */
75 int kgdb_debug_init = 0; /* != 0 waits for remote at system init */
76 int kgdb_debug_panic = 0; /* != 0 waits for remote on panic */
77 label_t *kgdb_recover = 0;
78
79 static int (*kgdb_getc)(void *);
80 static void (*kgdb_putc)(void *, int);
81 static void *kgdb_ioarg;
82
83 /* KGDB_BUFLEN must be at least (2*KGDB_NUMREGS*sizeof(kgdb_reg_t)+1) */
84 static u_char buffer[KGDB_BUFLEN];
85 static kgdb_reg_t gdb_regs[KGDB_NUMREGS];
86
87 #define GETC() ((*kgdb_getc)(kgdb_ioarg))
88 #define PUTC(c) ((*kgdb_putc)(kgdb_ioarg, c))
89
90 /*
91 * db_trap_callback can be hooked by MD port code to handle special
92 * cases such as disabling hardware watchdogs while in kgdb. Name
93 * is shared with DDB.
94 */
95 void (*db_trap_callback)(int);
96
97 void kgdb_voidop(void);
98
99 __weak_alias(kgdb_entry_notice, kgdb_voidop);
100
101 void
102 kgdb_voidop(void)
103 {
104 return;
105 }
106
107 /*
108 * This little routine exists simply so that bcopy() can be debugged.
109 */
110 static void
111 kgdb_copy(void *vsrc, void *vdst, int len)
112 {
113 char *src = vsrc;
114 char *dst = vdst;
115
116 while (--len >= 0)
117 *dst++ = *src++;
118 }
119
120 #if 0
121 /* ditto for bzero */
122 static void
123 kgdb_zero(void *vptr, int len)
124 {
125 char *ptr = vptr;
126
127 while (--len >= 0)
128 *ptr++ = (char) 0;
129 }
130 #endif
131
132 /*
133 * Convert a hex digit into an integer.
134 * This returns -1 if the argument passed is no
135 * valid hex digit.
136 */
137 static int
138 digit2i(u_char c)
139 {
140 if (c >= '0' && c <= '9')
141 return (c - '0');
142 else if (c >= 'a' && c <= 'f')
143 return (c - 'a' + 10);
144 else if (c >= 'A' && c <= 'F')
145
146 return (c - 'A' + 10);
147 else
148 return (-1);
149 }
150
151 /*
152 * Convert the low 4 bits of an integer into
153 * an hex digit.
154 */
155 static u_char
156 i2digit(int n)
157 {
158 return (hexdigits[n & 0x0f]);
159 }
160
161 /*
162 * Convert a byte array into an hex string.
163 */
164 static void
165 mem2hex(void *vdst, void *vsrc, int len)
166 {
167 u_char *dst = vdst;
168 u_char *src = vsrc;
169
170 while (len--) {
171 *dst++ = i2digit(*src >> 4);
172 *dst++ = i2digit(*src++);
173 }
174 *dst = '\0';
175 }
176
177 /*
178 * Convert an hex string into a byte array.
179 * This returns a pointer to the character following
180 * the last valid hex digit. If the string ends in
181 * the middle of a byte, NULL is returned.
182 */
183 static u_char *
184 hex2mem(void *vdst, u_char *src, int maxlen)
185 {
186 u_char *dst = vdst;
187 int msb, lsb;
188
189 while (*src && maxlen--) {
190 msb = digit2i(*src++);
191 if (msb < 0)
192 return (src - 1);
193 lsb = digit2i(*src++);
194 if (lsb < 0)
195 return (NULL);
196 *dst++ = (msb << 4) | lsb;
197 }
198 return (src);
199 }
200
201 /*
202 * Convert an hex string into an integer.
203 * This returns a pointer to the character following
204 * the last valid hex digit.
205 */
206 static vaddr_t
207 hex2i(u_char **srcp)
208 {
209 char *src = *srcp;
210 vaddr_t r = 0;
211 int nibble;
212
213 while ((nibble = digit2i(*src)) >= 0) {
214 r *= 16;
215 r += nibble;
216 src++;
217 }
218 *srcp = src;
219 return (r);
220 }
221
222 /*
223 * Send a packet.
224 */
225 static void
226 kgdb_send(const u_char *bp)
227 {
228 const u_char *p;
229 u_char csum, c;
230
231 DPRINTF(("kgdb_send: %s\n", bp));
232 do {
233 p = bp;
234 PUTC(KGDB_START);
235 for (csum = 0; (c = *p); p++) {
236 PUTC(c);
237 csum += c;
238 }
239 PUTC(KGDB_END);
240 PUTC(i2digit(csum >> 4));
241 PUTC(i2digit(csum));
242 } while ((c = GETC() & 0x7f) == KGDB_BADP);
243 }
244
245 /*
246 * Receive a packet.
247 */
248 static int
249 kgdb_recv(u_char *bp, int maxlen)
250 {
251 u_char *p;
252 int c, csum, tmpcsum;
253 int len;
254
255 DPRINTF(("kgdb_recv: "));
256 do {
257 p = bp;
258 csum = len = 0;
259 while ((c = GETC()) != KGDB_START)
260 DPRINTF(("%c",c));
261 DPRINTF(("%c Start ",c));
262
263 while ((c = GETC()) != KGDB_END && len < maxlen) {
264 DPRINTF(("%c",c));
265 c &= 0x7f;
266 csum += c;
267 *p++ = c;
268 len++;
269 }
270 csum &= 0xff;
271 *p = '\0';
272 DPRINTF(("%c End ", c));
273
274 if (len >= maxlen) {
275 DPRINTF(("Long- "));
276 PUTC(KGDB_BADP);
277 continue;
278 }
279 tmpcsum = csum;
280
281 c = GETC();
282 DPRINTF(("%c",c));
283 csum -= digit2i(c) * 16;
284 c = GETC();
285 DPRINTF(("%c",c));
286 csum -= digit2i(c);
287
288 if (csum == 0) {
289 DPRINTF(("Good+ "));
290 PUTC(KGDB_GOODP);
291 /* Sequence present? */
292 if (bp[2] == ':') {
293 DPRINTF(("Seq %c%c ", bp[0], bp[1]));
294 PUTC(bp[0]);
295 PUTC(bp[1]);
296 len -= 3;
297 kgdb_copy(bp + 3, bp, len);
298 }
299 break;
300 }
301 DPRINTF((" Bad(wanted %x, off by %d)- ", tmpcsum, csum));
302 PUTC(KGDB_BADP);
303 } while (1);
304 DPRINTF(("kgdb_recv: %s\n", bp));
305 return (len);
306 }
307
308 /*
309 * This is called by the appropriate tty driver.
310 */
311 void
312 kgdb_attach(int (*getfn)(void *), void (*putfn)(void *, int), void *ioarg)
313 {
314 kgdb_getc = getfn;
315 kgdb_putc = putfn;
316 kgdb_ioarg = ioarg;
317 }
318
319 /*
320 * This function does all command processing for interfacing to
321 * a remote gdb. Note that the error codes are ignored by gdb
322 * at present, but might eventually become meaningful. (XXX)
323 * It might makes sense to use POSIX errno values, because
324 * that is what the gdb/remote.c functions want to return.
325 */
326 int
327 kgdb_trap(int type, db_regs_t *regs)
328 {
329 label_t jmpbuf;
330 vaddr_t addr;
331 size_t len;
332 u_char *p;
333
334 kgdb_entry_notice(type, regs);
335
336 if (kgdb_dev == NODEV || kgdb_getc == NULL) {
337 /* not debugging */
338 return (0);
339 }
340
341 db_clear_single_step(regs);
342
343 if (db_trap_callback) db_trap_callback(1);
344
345 /* Detect and recover from unexpected traps. */
346 if (kgdb_recover != 0) {
347 printf("kgdb: caught trap 0x%x at %p\n",
348 type, (void*)PC_REGS(regs));
349 kgdb_send("E0E"); /* 14==EFAULT */
350 longjmp(kgdb_recover);
351 }
352
353 /*
354 * The first entry to this function is normally through
355 * a breakpoint trap in kgdb_connect(), in which case we
356 * must advance past the breakpoint because gdb will not.
357 *
358 * Machines vary as to where they leave the PC after a
359 * breakpoint trap. Those that leave the PC set to the
360 * address of the trap instruction (i.e. pc532) will not
361 * define FIXUP_PC_AFTER_BREAK(), and therefore will just
362 * advance the PC. On machines that leave the PC set to
363 * the instruction after the trap, FIXUP_PC_AFTER_BREAK
364 * will be defined to back-up the PC, so that after the
365 * "first-time" part of the if statement below has run,
366 * the PC will be the same as it was on entry.
367 *
368 * On the first entry here, we expect that gdb is not yet
369 * listening to us, so just enter the interaction loop.
370 * After the debugger is "active" (connected) it will be
371 * waiting for a "signaled" message from us.
372 */
373 if (kgdb_active == 0) {
374 if (!IS_BREAKPOINT_TRAP(type, 0)) {
375 /* No debugger active -- let trap handle this. */
376 if (db_trap_callback) db_trap_callback(0);
377 return (0);
378 }
379 /* Make the PC point at the breakpoint... */
380 #ifdef FIXUP_PC_AFTER_BREAK
381 FIXUP_PC_AFTER_BREAK(regs);
382 #endif
383 /* ... and then advance past it. */
384 #ifdef PC_ADVANCE
385 PC_ADVANCE(regs);
386 #else
387 PC_REGS(regs) += BKPT_SIZE;
388 #endif
389 kgdb_active = 1;
390 } else {
391 /* Tell remote host that an exception has occurred. */
392 snprintf(buffer, sizeof(buffer), "S%02x", kgdb_signal(type));
393 kgdb_send(buffer);
394 }
395
396 /* Stick frame regs into our reg cache. */
397 kgdb_getregs(regs, gdb_regs);
398
399 /*
400 * Interact with gdb until it lets us go.
401 * If we cause a trap, resume here.
402 */
403 (void)setjmp((kgdb_recover = &jmpbuf));
404 for (;;) {
405 kgdb_recv(buffer, sizeof(buffer));
406 switch (buffer[0]) {
407
408 default:
409 /* Unknown command. */
410 kgdb_send("");
411 continue;
412
413 case KGDB_SIGNAL:
414 /*
415 * if this command came from a running gdb,
416 * answer it -- the other guy has no way of
417 * knowing if we're in or out of this loop
418 * when he issues a "remote-signal".
419 */
420 snprintf(buffer, sizeof(buffer), "S%02x",
421 kgdb_signal(type));
422 kgdb_send(buffer);
423 continue;
424
425 case KGDB_REG_R:
426 mem2hex(buffer, gdb_regs, sizeof(gdb_regs));
427 kgdb_send(buffer);
428 continue;
429
430 case KGDB_REG_W:
431 p = hex2mem(gdb_regs, buffer + 1, sizeof(gdb_regs));
432 if (p == NULL || *p != '\0')
433 kgdb_send("E01");
434 else {
435 kgdb_setregs(regs, gdb_regs);
436 kgdb_send("OK");
437 }
438 continue;
439
440 case KGDB_MEM_R:
441 p = buffer + 1;
442 addr = hex2i(&p);
443 if (*p++ != ',') {
444 kgdb_send("E02");
445 continue;
446 }
447 len = hex2i(&p);
448 if (*p != '\0') {
449 kgdb_send("E03");
450 continue;
451 }
452 if (len > sizeof(buffer) / 2) {
453 kgdb_send("E04");
454 continue;
455 }
456 if (kgdb_acc(addr, len) == 0) {
457 kgdb_send("E05");
458 continue;
459 }
460 db_read_bytes(addr, (size_t)len,
461 (char *)buffer + sizeof(buffer) / 2);
462 mem2hex(buffer, buffer + sizeof(buffer) / 2, len);
463 kgdb_send(buffer);
464 continue;
465
466 case KGDB_MEM_W:
467 p = buffer + 1;
468 addr = hex2i(&p);
469 if (*p++ != ',') {
470 kgdb_send("E06");
471 continue;
472 }
473 len = hex2i(&p);
474 if (*p++ != ':') {
475 kgdb_send("E07");
476 continue;
477 }
478 if (len > (sizeof(buffer) - (p - buffer))) {
479 kgdb_send("E08");
480 continue;
481 }
482 p = hex2mem(buffer, p, sizeof(buffer));
483 if (p == NULL) {
484 kgdb_send("E09");
485 continue;
486 }
487 if (kgdb_acc(addr, len) == 0) {
488 kgdb_send("E0A");
489 continue;
490 }
491 db_write_bytes(addr, (size_t)len, (char *)buffer);
492 kgdb_send("OK");
493 continue;
494
495 case KGDB_DETACH:
496 case KGDB_KILL:
497 kgdb_active = 0;
498 printf("kgdb detached\n");
499 db_clear_single_step(regs);
500 kgdb_send("OK");
501 goto out;
502
503 case KGDB_CONT:
504 if (buffer[1]) {
505 p = buffer + 1;
506 addr = hex2i(&p);
507 if (*p) {
508 kgdb_send("E0B");
509 continue;
510 }
511 PC_REGS(regs) = addr;
512 DPRINTF(("kgdb: continuing at %08lx\n", addr));
513
514 } else {
515 DPRINTF((
516 "kgdb: continuing at old address %08lx\n",
517 (vaddr_t)PC_REGS(regs)));
518 }
519
520 db_clear_single_step(regs);
521 goto out;
522
523 case KGDB_STEP:
524 if (buffer[1]) {
525 p = buffer + 1;
526 addr = hex2i(&p);
527 if (*p) {
528 kgdb_send("E0B");
529 continue;
530 }
531 PC_REGS(regs) = addr;
532 }
533 db_set_single_step(regs);
534 goto out;
535 }
536 }
537 out:
538 if (db_trap_callback) db_trap_callback(0);
539 kgdb_recover = 0;
540 return (1);
541 }
542
543 int
544 kgdb_disconnected(void)
545 {
546 return 1;
547 }
548