[BACK]Return to kgdb_stub.c CVS log [TXT][DIR] Up to [local] / sys / kern

Annotation of sys/kern/kgdb_stub.c, Revision 1.1.1.1

1.1       nbrk        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: }

CVSweb