1 /* $NetBSD: kgdb_stub.c,v 1.24 2011/04/03 22:29:28 dyoung 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.24 2011/04/03 22:29:28 dyoung 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