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