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