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