1 /* $OpenBSD: kgdb_stub.c,v 1.6 2003/06/02 23:28:06 millert 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
kgdb_copy(vsrc,vdst,len)93 kgdb_copy(vsrc, vdst, len)
94 void *vsrc, *vdst;
95 int len;
96 {
97 char *src = vsrc;
98 char *dst = vdst;
99
100 while (--len >= 0)
101 *dst++ = *src++;
102 }
103
104 #if 0
105 /* ditto for bzero */
106 static void
107 kgdb_zero(vptr, len)
108 void *vptr;
109 int len;
110 {
111 char *ptr = vptr;
112
113 while (--len >= 0)
114 *ptr++ = (char) 0;
115 }
116 #endif
117
118 /*
119 * Convert a hex digit into an integer.
120 * This returns -1 if the argument passed is no
121 * valid hex digit.
122 */
123 static int
digit2i(c)124 digit2i(c)
125 u_char c;
126 {
127 if (c >= '0' && c <= '9')
128 return (c - '0');
129 else if (c >= 'a' && c <= 'f')
130 return (c - 'a' + 10);
131 else if (c >= 'A' && c <= 'F')
132
133 return (c - 'A' + 10);
134 else
135 return (-1);
136 }
137
138 /*
139 * Convert the low 4 bits of an integer into
140 * an hex digit.
141 */
142 static u_char
i2digit(n)143 i2digit(n)
144 int n;
145 {
146 return ("0123456789abcdef"[n & 0x0f]);
147 }
148
149 /*
150 * Convert a byte array into an hex string.
151 */
152 static void
mem2hex(vdst,vsrc,len)153 mem2hex(vdst, vsrc, len)
154 void *vdst, *vsrc;
155 int len;
156 {
157 u_char *dst = vdst;
158 u_char *src = vsrc;
159
160 while (len--) {
161 *dst++ = i2digit(*src >> 4);
162 *dst++ = i2digit(*src++);
163 }
164 *dst = '\0';
165 }
166
167 /*
168 * Convert an hex string into a byte array.
169 * This returns a pointer to the character following
170 * the last valid hex digit. If the string ends in
171 * the middle of a byte, NULL is returned.
172 */
173 static u_char *
hex2mem(vdst,src,maxlen)174 hex2mem(vdst, src, maxlen)
175 void *vdst;
176 u_char *src;
177 int maxlen;
178 {
179 u_char *dst = vdst;
180 int msb, lsb;
181
182 while (*src && maxlen--) {
183 msb = digit2i(*src++);
184 if (msb < 0)
185 return (src - 1);
186 lsb = digit2i(*src++);
187 if (lsb < 0)
188 return (NULL);
189 *dst++ = (msb << 4) | lsb;
190 }
191 return (src);
192 }
193
194 /*
195 * Convert an hex string into an integer.
196 * This returns a pointer to the character following
197 * the last valid hex digit.
198 */
199 static vaddr_t
hex2i(srcp)200 hex2i(srcp)
201 u_char **srcp;
202 {
203 char *src = *srcp;
204 vaddr_t r = 0;
205 int nibble;
206
207 while ((nibble = digit2i(*src)) >= 0) {
208 r *= 16;
209 r += nibble;
210 src++;
211 }
212 *srcp = src;
213 return (r);
214 }
215
216 /*
217 * Send a packet.
218 */
219 static void
kgdb_send(bp)220 kgdb_send(bp)
221 u_char *bp;
222 {
223 u_char *p;
224 u_char csum, c;
225
226 #ifdef DEBUG_KGDB
227 printf("kgdb_send: %s\n", bp);
228 #endif
229 do {
230 p = bp;
231 PUTC(KGDB_START);
232 for (csum = 0; (c = *p); p++) {
233 PUTC(c);
234 csum += c;
235 }
236 PUTC(KGDB_END);
237 PUTC(i2digit(csum >> 4));
238 PUTC(i2digit(csum));
239 } while ((c = GETC() & 0x7f) == KGDB_BADP);
240 }
241
242 /*
243 * Receive a packet.
244 */
245 static int
kgdb_recv(bp,maxlen)246 kgdb_recv(bp, maxlen)
247 u_char *bp;
248 int maxlen;
249 {
250 u_char *p;
251 int c, csum;
252 int len;
253
254 do {
255 p = bp;
256 csum = len = 0;
257 while ((c = GETC()) != KGDB_START)
258 ;
259
260 while ((c = GETC()) != KGDB_END && len < maxlen) {
261 c &= 0x7f;
262 csum += c;
263 *p++ = c;
264 len++;
265 }
266 csum &= 0xff;
267 *p = '\0';
268
269 if (len >= maxlen) {
270 PUTC(KGDB_BADP);
271 continue;
272 }
273
274 csum -= digit2i(GETC()) * 16;
275 csum -= digit2i(GETC());
276
277 if (csum == 0) {
278 PUTC(KGDB_GOODP);
279 /* Sequence present? */
280 if (bp[2] == ':') {
281 PUTC(bp[0]);
282 PUTC(bp[1]);
283 len -= 3;
284 kgdb_copy(bp + 3, bp, len);
285 }
286 break;
287 }
288 PUTC(KGDB_BADP);
289 } while (1);
290 #ifdef DEBUG_KGDB
291 printf("kgdb_recv: %s\n", bp);
292 #endif
293 return (len);
294 }
295
296 /*
297 * This is called by the appropriate tty driver.
298 */
299 void
300 kgdb_attach(getfn, putfn, ioarg)
301 int (*getfn)(void *);
302 void (*putfn)(void *, int);
303 void *ioarg;
304 {
305 kgdb_getc = getfn;
306 kgdb_putc = putfn;
307 kgdb_ioarg = ioarg;
308 }
309
310 /*
311 * This function does all command processing for interfacing to
312 * a remote gdb. Note that the error codes are ignored by gdb
313 * at present, but might eventually become meaningful. (XXX)
314 * It might makes sense to use POSIX errno values, because
315 * that is what the gdb/remote.c functions want to return.
316 */
317 int
kgdb_trap(type,regs)318 kgdb_trap(type, regs)
319 int type;
320 db_regs_t *regs;
321 {
322 label_t jmpbuf;
323 vaddr_t addr;
324 size_t len;
325 u_char *p;
326
327 if (kgdb_dev < 0 || kgdb_getc == NULL) {
328 /* not debugging */
329 return (0);
330 }
331
332 /* Detect and recover from unexpected traps. */
333 if (kgdb_recover != 0) {
334 printf("kgdb: caught trap 0x%x at %p\n",
335 type, (void *)PC_REGS(regs));
336 kgdb_send("E0E"); /* 14==EFAULT */
337 longjmp(kgdb_recover);
338 }
339
340 /*
341 * The first entry to this function is normally through
342 * a breakpoint trap in kgdb_connect(), in which case we
343 * must advance past the breakpoint because gdb will not.
344 *
345 * Machines vary as to where they leave the PC after a
346 * breakpoint trap. Those that leave the PC set to the
347 * address of the trap instruction (i.e. pc532) will not
348 * define FIXUP_PC_AFTER_BREAK(), and therefore will just
349 * advance the PC. On machines that leave the PC set to
350 * the instruction after the trap, FIXUP_PC_AFTER_BREAK
351 * will be defined to back-up the PC, so that after the
352 * "first-time" part of the if statement below has run,
353 * the PC will be the same as it was on entry.
354 *
355 * On the first entry here, we expect that gdb is not yet
356 * listening to us, so just enter the interaction loop.
357 * After the debugger is "active" (connected) it will be
358 * waiting for a "signaled" message from us.
359 */
360 if (kgdb_active == 0) {
361 if (!IS_BREAKPOINT_TRAP(type, 0)) {
362 /* No debugger active -- let trap handle this. */
363 return (0);
364 }
365 /* Make the PC point at the breakpoint... */
366 #ifdef FIXUP_PC_AFTER_BREAK
367 FIXUP_PC_AFTER_BREAK(regs);
368 #endif
369 /* ... and then advance past it. */
370 #ifdef PC_ADVANCE
371 PC_ADVANCE(regs);
372 #else
373 PC_REGS(regs) += BKPT_SIZE;
374 #endif
375 kgdb_active = 1;
376 } else {
377 /* Tell remote host that an exception has occurred. */
378 snprintf(buffer, sizeof buffer, "S%02x", kgdb_signal(type));
379 kgdb_send(buffer);
380 }
381
382 /* Stick frame regs into our reg cache. */
383 kgdb_getregs(regs, gdb_regs);
384
385 /*
386 * Interact with gdb until it lets us go.
387 * If we cause a trap, resume here.
388 */
389 (void)setjmp((kgdb_recover = &jmpbuf));
390 for (;;) {
391 kgdb_recv(buffer, sizeof(buffer));
392 switch (buffer[0]) {
393
394 default:
395 /* Unknown command. */
396 kgdb_send("");
397 continue;
398
399 case KGDB_SIGNAL:
400 /*
401 * if this command came from a running gdb,
402 * answer it -- the other guy has no way of
403 * knowing if we're in or out of this loop
404 * when he issues a "remote-signal".
405 */
406 snprintf(buffer, sizeof buffer, "S%02x", kgdb_signal(type));
407 kgdb_send(buffer);
408 continue;
409
410 case KGDB_REG_R:
411 mem2hex(buffer, gdb_regs, sizeof(gdb_regs));
412 kgdb_send(buffer);
413 continue;
414
415 case KGDB_REG_W:
416 p = hex2mem(gdb_regs, buffer + 1, sizeof(gdb_regs));
417 if (p == NULL || *p != '\0')
418 kgdb_send("E01");
419 else {
420 kgdb_setregs(regs, gdb_regs);
421 kgdb_send("OK");
422 }
423 continue;
424
425 case KGDB_MEM_R:
426 p = buffer + 1;
427 addr = hex2i(&p);
428 if (*p++ != ',') {
429 kgdb_send("E02");
430 continue;
431 }
432 len = hex2i(&p);
433 if (*p != '\0') {
434 kgdb_send("E03");
435 continue;
436 }
437 if (len > sizeof(buffer) / 2) {
438 kgdb_send("E04");
439 continue;
440 }
441 if (kgdb_acc(addr, len) == 0) {
442 kgdb_send("E05");
443 continue;
444 }
445 db_read_bytes(addr, (size_t)len,
446 (char *)buffer + sizeof(buffer) / 2);
447 mem2hex(buffer, buffer + sizeof(buffer) / 2, len);
448 kgdb_send(buffer);
449 continue;
450
451 case KGDB_MEM_W:
452 p = buffer + 1;
453 addr = hex2i(&p);
454 if (*p++ != ',') {
455 kgdb_send("E06");
456 continue;
457 }
458 len = hex2i(&p);
459 if (*p++ != ':') {
460 kgdb_send("E07");
461 continue;
462 }
463 if (len > (sizeof(buffer) - (p - buffer))) {
464 kgdb_send("E08");
465 continue;
466 }
467 p = hex2mem(buffer, p, sizeof(buffer));
468 if (p == NULL) {
469 kgdb_send("E09");
470 continue;
471 }
472 if (kgdb_acc(addr, len) == 0) {
473 kgdb_send("E0A");
474 continue;
475 }
476 db_write_bytes(addr, (size_t)len, (char *)buffer);
477 kgdb_send("OK");
478 continue;
479
480 case KGDB_DETACH:
481 kgdb_active = 0;
482 printf("kgdb detached\n");
483 db_clear_single_step(regs);
484 kgdb_send("OK");
485 goto out;
486
487 case KGDB_KILL:
488 kgdb_active = 0;
489 printf("kgdb detached\n");
490 db_clear_single_step(regs);
491 goto out;
492
493 case KGDB_CONT:
494 if (buffer[1]) {
495 p = buffer + 1;
496 addr = hex2i(&p);
497 if (*p) {
498 kgdb_send("E0B");
499 continue;
500 }
501 PC_REGS(regs) = addr;
502 }
503 db_clear_single_step(regs);
504 goto out;
505
506 case KGDB_STEP:
507 if (buffer[1]) {
508 p = buffer + 1;
509 addr = hex2i(&p);
510 if (*p) {
511 kgdb_send("E0B");
512 continue;
513 }
514 PC_REGS(regs) = addr;
515 }
516 db_set_single_step(regs);
517 goto out;
518 }
519 }
520 out:
521 kgdb_recover = 0;
522 return (1);
523 }
524