Annotation of coherent/d/bin/db/i8086/i8086a.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * A debugger.
                      3:  * Intel 8086.
                      4:  */
                      5: #include <stdio.h>
                      6: #include <sys/const.h>
                      7: #include <l.out.h>
                      8: #include <signal.h>
                      9: #include <sys/uproc.h>
                     10: #include "trace.h"
                     11: #include "i8086.h"
                     12: 
                     13: /*
                     14:  * Given an l.out header, set up segmentation for an l.out.
                     15:  */
                     16: setaseg(ldhp)
                     17: register struct ldheader *ldhp;
                     18: {
                     19:        register long fbase;
                     20:        register long si;
                     21:        register long pi;
                     22:        register long bi;
                     23:        register long sd;
                     24:        register long pd;
                     25:        register long rs;
                     26: 
                     27:        fbase = sizeof(*ldhp);
                     28:        si = ldhp->l_ssize[L_SHRI];
                     29:        pi = ldhp->l_ssize[L_PRVI];
                     30:        bi = ldhp->l_ssize[L_BSSI];
                     31:        sd = ldhp->l_ssize[L_SHRD];
                     32:        pd = ldhp->l_ssize[L_PRVD];
                     33:        switch (ldhp->l_flag & (LF_SEP|LF_SHR)) {
                     34:        case 0:
                     35:                endpure = NULL;
                     36:                DSPACE = setsmap(NULL, (long)0, si+pi, fbase,
                     37:                                getf, putf, 0);
                     38:                DSPACE = setsmap(DSPACE, si+pi+bi, sd+pd, fbase+si+pi,
                     39:                                getf, putf, 0);
                     40:                ISPACE = DSPACE;
                     41:                break;
                     42: 
                     43:        case LF_SHR:
                     44:                endpure = NULL;
                     45:                rs = (si+sd+0xF) & ~0xF;
                     46:                DSPACE = setsmap(NULL, (long)0, si, fbase, getf, putf, 0);
                     47:                DSPACE = setsmap(DSPACE, si, sd, fbase+si+pi, getf, putf, 0);
                     48:                DSPACE = setsmap(DSPACE, rs, pi, fbase+si, getf, putf, 0);
                     49:                DSPACE = setsmap(DSPACE, rs+pi, pd, fbase+si+pi+sd,
                     50:                                getf, putf, 0);
                     51:                ISPACE = DSPACE;
                     52:                break;
                     53: 
                     54:        case LF_SEP:
                     55:                endpure = NULL;
                     56:                ISPACE = setsmap(NULL, (long)0, si+pi, fbase, getf, putf, 0);
                     57:                DSPACE = setsmap(NULL, (long)0, sd+pd, fbase+si+pi,
                     58:                                getf, putf, 0);
                     59:                break;
                     60: 
                     61:        case LF_SEP|LF_SHR:
                     62:                endpure = NULL; /* No pure data */
                     63:                rs  = (sd+0xF) & ~0xF;
                     64:                ISPACE = setsmap(NULL, (long)0, si+pi, fbase, getf, putf, 0);
                     65:                DSPACE = setsmap(NULL, (long)0, sd, fbase+si+pi, getf, putf, 0);
                     66:                DSPACE = setsmap(DSPACE, rs, pd, fbase+si+pi+sd, getf, putf, 0);
                     67:                break;
                     68:        }
                     69: }
                     70: 
                     71: /*
                     72:  * Set up segmentation for kernel memory.
                     73:  */
                     74: setkmem(np)
                     75: char *np;
                     76: {
                     77:        register fsize_t l;
                     78:        unsigned n;
                     79:        struct ldsym lds;
                     80: 
                     81:        cfp = openfil(np, rflag);
                     82:        USPACE = setsmap(NULL, (fsize_t)0, (fsize_t)LI, (fsize_t)0,
                     83:                getf, putf, 1);
                     84:        add = 2;
                     85:        if (getb(2, &n, sizeof(n)) == 0)
                     86:                panic("Bad memory file");
                     87:        l = (fsize_t)n << 4;
                     88:        ISPACE = setsmap(NULL, (fsize_t)0, (fsize_t)LI, (fsize_t)l,
                     89:                getf, putf, 1);
                     90:        strncpy(lds.ls_id, "etext_", NCPLN);
                     91:        if (nameval(&lds) == 0)
                     92:                DSPACE = ISPACE;
                     93:        else {
                     94:                n = (lds.ls_addr+0xF) & ~0xF;
                     95:                DSPACE = setsmap(NULL, (fsize_t)0, (fsize_t)LI, (fsize_t)l+n,
                     96:                        getf, putf, 1);
                     97:        }
                     98: }
                     99: 
                    100: /*
                    101:  * Set up segmentation for a system dump.
                    102:  */
                    103: setdump(np)
                    104: char *np;
                    105: {
                    106:        setkmem(np);
                    107: }
                    108: 
                    109: /*
                    110:  * Update register structure in memory.
                    111:  */
                    112: setregs()
                    113: {
                    114:        struct ureg ureg;
                    115: 
                    116:        regflag = 0;
                    117:        add = UREGOFF;
                    118:        if (getb(2, (char *)&ureg, sizeof(ureg)) == 0) {
                    119:                printr("Cannot read registers");
                    120:                return (0);
                    121:        }
                    122:        copyreg(&ureg);
                    123:        regflag = 1;
                    124:        return (1);
                    125: }
                    126: 
                    127: /*
                    128:  * Copy registers from the User area structure to the register
                    129:  * structure.
                    130:  */
                    131: copyreg(up)
                    132: register struct ureg *up;
                    133: {
                    134:        reg.r_ax = up->ur_ax;
                    135:        reg.r_bx = up->ur_bx;
                    136:        reg.r_cx = up->ur_cx;
                    137:        reg.r_dx = up->ur_dx;
                    138:        reg.r_sp = up->ur_sp;
                    139:        reg.r_bp = up->ur_bp;
                    140:        reg.r_si = up->ur_si;
                    141:        reg.r_di = up->ur_di;
                    142:        reg.r_cs = up->ur_cs;
                    143:        reg.r_ds = up->ur_ds;
                    144:        reg.r_ss = up->ur_ss;
                    145:        reg.r_es = up->ur_es;
                    146:        reg.r_ip = up->ur_ip;
                    147:        reg.r_fw = up->ur_fw;
                    148: }
                    149: 
                    150: /*
                    151:  * If the given name matches a register, set up `ldp' with the address
                    152:  * of a registers in the user area.
                    153:  */
                    154: regaddr(ldp)
                    155: struct ldsym *ldp;
                    156: {
                    157:        register char *cp;
                    158:        register int c0;
                    159:        register int c1;
                    160:        register int a;
                    161: 
                    162:        a = UPASIZE - sizeof(struct ureg);
                    163:        cp = ldp->ls_id;
                    164:        if ((c0=*cp++) == '\0')
                    165:                return (0);
                    166:        if ((c1=*cp++) == '\0')
                    167:                return (0);
                    168:        if (*cp != '\0')
                    169:                return (0);
                    170:        switch (c1) {
                    171:        case 'h':
                    172:                a++;
                    173:        case 'l':
                    174:                c1 = 'x';
                    175:        }
                    176:        cp = regitab;
                    177:        do {
                    178:                if (cp[0]==c0 && cp[1]==c1) {
                    179:                        ldp->ls_addr = a;
                    180:                        ldp->ls_type = L_REG;
                    181:                        return (1);
                    182:                }
                    183:                a += 2;
                    184:                cp += 2;
                    185:        } while (*cp != '\0');
                    186:        return (0);
                    187: }
                    188: 
                    189: /*
                    190:  * Return the programme counter.
                    191:  */
                    192: vaddr_t
                    193: getpc()
                    194: {
                    195:        return (reg.r_ip);
                    196: }
                    197: 
                    198: /*
                    199:  * Set the programme counter.
                    200:  */
                    201: setpc(ip)
                    202: vaddr_t ip;
                    203: {
                    204:        reg.r_ip = ip;
                    205:        add = UREGOFF + offset(ureg, ur_ip);
                    206:        putb(2, (char *)&reg.r_ip, sizeof(reg.r_ip));
                    207: }
                    208: 
                    209: /*
                    210:  * Return the frame pointer.
                    211:  */
                    212: vaddr_t
                    213: getfp()
                    214: {
                    215:        return (reg.r_bp);
                    216: }
                    217: 
                    218: /*
                    219:  * Display registers.
                    220:  */
                    221: dispreg()
                    222: {
                    223:        if (testint())
                    224:                return;
                    225:        printf("ip=%04x fw=%04x\n", reg.r_ip, reg.r_fw);
                    226: 
                    227:        if (testint())
                    228:                return;
                    229:        printf("ax=%04x bx=%04x cx=%04x dx=%04x\n",
                    230:                reg.r_ax, reg.r_bx, reg.r_cx, reg.r_dx);
                    231: 
                    232:        if (testint())
                    233:                return;
                    234:        printf("sp=%04x bp=%04x si=%04x di=%04x\n",
                    235:                reg.r_sp, reg.r_bp, reg.r_si, reg.r_di);
                    236: 
                    237:        if (testint())
                    238:                return;
                    239:        printf("cs=%04x ds=%04x ss=%04x es=%04x\n",
                    240:                reg.r_cs, reg.r_ds, reg.r_ss, reg.r_es);
                    241: }
                    242: 
                    243: /*
                    244:  * Stack traceback.
                    245:  */
                    246: dispsbt(l)
                    247: {
                    248:        int     sdbase = dbase;
                    249:        register int argc;
                    250:        register int iflag;
                    251:        register int sflag;
                    252:        register int qflag;
                    253:        unsigned amain;
                    254:        unsigned rpc;
                    255:        unsigned pc;
                    256:        unsigned fp;
                    257:        unsigned n;
                    258:        unsigned char e[1];
                    259:        unsigned char b[3];
                    260:        struct ldsym ldsym;
                    261: 
                    262:        dbase = 16;
                    263:        amain = 1;
                    264:        strcpy(ldsym.ls_id, "main_");
                    265:        if (nameval(&ldsym) != 0)
                    266:                amain = ldsym.ls_addr;
                    267:        add = reg.r_ip;
                    268:        if (getb(1, b, 1) == 0) {
                    269:                printe("Illegal ip");
                    270:                goto done;
                    271:        }
                    272:        sflag = 0;
                    273:        fp = reg.r_bp;
                    274:        e[0] = 0x56;                            /* push si */
                    275:        if (valname(1, (vaddr_t)reg.r_ip, &ldsym) != 0) {
                    276:                add = (long)ldsym.ls_addr;
                    277:                getb(1, (char *)e, 1);
                    278:        }
                    279:        if (b[0]==0x56 || e[0]!=0x56) {         /* push si */
                    280:                sflag = 1;
                    281:                fp = reg.r_sp - 6;
                    282:        }
                    283:        pc = reg.r_ip;
                    284:        qflag = 0;
                    285:        for (;;) {
                    286:                add = fp + 6;
                    287:                if (getb(0, &rpc, 2) == 0)
                    288:                        break;
                    289:                argc = 0;
                    290:                add = rpc;
                    291:                if (getb(1, b, 3) != 0) {
                    292:                        if (b[0]==0x83 && b[1]==0xC4)   /* add sp,$? */
                    293:                                argc = b[2]/2;
                    294:                }
                    295:                add = rpc - 3;
                    296:                if (getb(1, b, 1) == 0)
                    297:                        break;
                    298:                if (getb(1, &n, sizeof(n)) == 0)
                    299:                        break;
                    300:                printx(DAFMT, (long)fp);
                    301:                printx("  ");
                    302:                printx(DAFMT, (long)pc);
                    303:                printx("  ");
                    304:                if (b[0] == 0xE8) {                     /* call ? */
                    305:                        n += rpc;
                    306:                        putaddr(1, (long)n, I);
                    307:                        if (n == amain) {
                    308:                                qflag = 1;
                    309:                                argc = 3;
                    310:                        }
                    311:                } else {
                    312:                        if (valname(1, (vaddr_t)pc, &ldsym) == 0)
                    313:                                printx("*");
                    314:                        else {
                    315:                                printx("%.*s", NCPLN, ldsym.ls_id);
                    316:                                if (strcmp(ldsym.ls_id, "main_") == 0) {
                    317:                                        qflag = 1;
                    318:                                        argc = 3;
                    319:                                }
                    320:                        }
                    321:                }
                    322:                putx('(');
                    323:                iflag = 0;
                    324:                add = fp + 8;
                    325:                while (argc--) {
                    326:                        if (getb(0, &n, 2) == 0)
                    327:                                break;
                    328:                        if (iflag++ != 0)
                    329:                                printx(", ");
                    330:                        putaddr(1, (long)n, -1);
                    331:                }
                    332:                printx(")\n");
                    333:                if (testint())
                    334:                        goto done;
                    335:                if (qflag)
                    336:                        break;
                    337:                if (sflag) {
                    338:                        sflag = 0;
                    339:                        fp = reg.r_bp;
                    340:                } else {
                    341:                        add = fp;
                    342:                        if (getb(0, &fp, sizeof(fp)) == 0)
                    343:                                break;
                    344:                }
                    345:                if (--l == 0)
                    346:                        goto done;
                    347:                pc = rpc;
                    348:        }
                    349: done:  dbase = sdbase;
                    350: }
                    351: 
                    352: /*
                    353:  * Get the return pc and frame pointer to set a return breakpoint.
                    354:  */
                    355: setretf(pcp, fpp)
                    356: register vaddr_t *pcp;
                    357: register vaddr_t *fpp;
                    358: {
                    359:        char b[1];
                    360: 
                    361:        add = reg.r_ip;
                    362:        if (getb(0, b, sizeof(b)) == 0)
                    363:                return (0);
                    364:        if (b[0] == 0x56) {                     /* push si */
                    365:                *fpp = reg.r_bp;
                    366:                add = reg.r_sp;
                    367:        } else {
                    368:                add = reg.r_bp;
                    369:                if (getb(0, (char *)fpp, sizeof(*fpp)) == 0)
                    370:                        return (0);
                    371:                add = reg.r_bp + 6;
                    372:        }
                    373:        if (getb(0, (char *)pcp, sizeof(*pcp)) == 0)
                    374:                return (0);
                    375: }
                    376: 
                    377: /*
                    378:  * Initialise after getting a trap.
                    379:  */
                    380: trapint()
                    381: {
                    382:        vaddr_t pc;
                    383:        vaddr_t fw;
                    384: 
                    385:        cacsegn = -1;
                    386:        add = UREGOFF + offset(ureg, ur_fw);
                    387:        if (getb(2, (char *)&fw, sizeof(fw)) == 0) {
                    388:                printr("Cannot get fw");
                    389:                return (0);
                    390:        }
                    391:        fw &= ~TBIT;
                    392:        add = UREGOFF + offset(ureg, ur_fw);
                    393:        if (putb(2, (char *)&fw, sizeof(fw)) == 0) {
                    394:                printr("Cannot set fw");
                    395:                return (0);
                    396:        }
                    397:        if (sysflag) {
                    398:                add = UREGOFF + offset(ureg, ur_ip);
                    399:                if (getb(2, (char *)&pc, sizeof(pc)) == 0) {
                    400:                        printr("Cannot get pc");
                    401:                        return (0);
                    402:                }
                    403:                pc -= 2;
                    404:                add = UREGOFF + offset(ureg, ur_ip);
                    405:                if (putb(2, (char *)&pc, sizeof(pc)) == 0) {
                    406:                        printr("Cannot set pc");
                    407:                        return (0);
                    408:                }
                    409:                add = (long)pc;
                    410:                if (putb(1, (char *)sin, sizeof(sin)) == 0) {
                    411:                        printr("Cannot set sin");
                    412:                        return (0);
                    413:                }
                    414:                bitflag = 1;
                    415:        }
                    416:        return (1);
                    417: }
                    418: 
                    419: /*
                    420:  * Set up before returning from a trap.  Single stepping over a system
                    421:  * call is handled here.
                    422:  */
                    423: restret()
                    424: {
                    425:        char w[1];
                    426: 
                    427:        sysflag = 0;
                    428:        if (bitflag == 0)
                    429:                return (1);
                    430:        add = reg.r_ip;
                    431:        if (getb(1, (char *)w, sizeof(w)) == 0)
                    432:                return (1);
                    433:        if (w[0] != 0xCD)               /* Interrupt (system call) */
                    434:                return (1);
                    435:        add = reg.r_ip + 2;
                    436:        if (getb(1, (char *)sin, sizeof(sin)) == 0) {
                    437:                printr("Cannot get breakpoint");
                    438:                return (0);
                    439:        }
                    440:        add -= sizeof(sin);
                    441:        if (putb(1, (char *)bin, sizeof(bin)) == 0) {
                    442:                printr("Cannot set breakpoint");
                    443:                return (0);
                    444:        }
                    445:        bitflag = 0;
                    446:        sysflag = 1;
                    447:        return (1);
                    448: }
                    449: 
                    450: /*
                    451:  * Set up breakpoint for single step continue.
                    452:  */
                    453: setcont()
                    454: {
                    455:        char w[2];
                    456: 
                    457:        add = reg.r_ip;
                    458:        if (getb(1, (char *)w, sizeof(w)) == 0)
                    459:                return;
                    460:        if (w[0] == 0xE8)                       /* Direct call */
                    461:                sinmode = SCSET;
                    462:        if (w[0]==0xFF && (w[1]&0x38)==0x10)    /* Indirect call */
                    463:                sinmode = SCSET;
                    464: }
                    465: 
                    466: /*
                    467:  * Continue after initial break in single step continue.
                    468:  */
                    469: intcont()
                    470: {
                    471:        unsigned a;
                    472: 
                    473:        add = reg.r_sp;
                    474:        if (getb(0, (char *)&a, sizeof(a)))
                    475:                setibpt(BSIN, a, reg.r_bp, NULL);
                    476: }
                    477: 
                    478: /*
                    479:  * See if the given instruction is a breakpoint.
                    480:  */
                    481: testbpt(pc)
                    482: {
                    483:        char w[1];
                    484: 
                    485:        add = pc;
                    486:        return (getb(1, (char *)w, sizeof(w))!=0 && w==0xCC);
                    487: }
                    488: 
                    489: /*
                    490:  * Read `n' characters into the buffer `bp' starting at address `a'
                    491:  * from the traced process.
                    492:  */
                    493: getp(f, la, bp, n)
                    494: long la;
                    495: register char *bp;
                    496: register int n;
                    497: {
                    498:        register unsigned a;
                    499: 
                    500:        a = la;
                    501:        if (a != la)
                    502:                return (0);
                    503:        while (n--) {
                    504:                if (getq(f, a++, bp++) == 0)
                    505:                        return (0);
                    506:        }
                    507:        return (1);
                    508: }
                    509: 
                    510: /*
                    511:  * Write `n' characters from the buffer `bp' starting at address `a' in
                    512:  * the traced process.
                    513:  */
                    514: putp(f, la, bp, n)
                    515: long la;
                    516: register char *bp;
                    517: register int n;
                    518: {
                    519:        extern int errno;
                    520:        int d;
                    521:        register unsigned a;
                    522: 
                    523:        a = la;
                    524:        if (a != la)
                    525:                return (0);
                    526:        cacsegn = -1;
                    527:        if (n!=0 && (a&1)!=0) {
                    528:                if (getq(f, --a, (char *)&d) == 0)
                    529:                        return (0);
                    530:                ((char *)&d)[1] = *bp++;
                    531:                ptrace(4+f, pid, (int *) a, d);
                    532:                if (errno)
                    533:                        return (0);
                    534:                a += 2;
                    535:                --n;
                    536:        }
                    537:        while (n > 1) {
                    538:                ((char *)&d)[0] = *bp++;
                    539:                ((char *)&d)[1] = *bp++;
                    540:                ptrace(4+f, pid, (int *) a, d);
                    541:                if (errno)
                    542:                        return (0);
                    543:                a += 2;
                    544:                n -= 2;
                    545:        }
                    546:        if (n) {
                    547:                ((char *)&d)[0] = *bp++;
                    548:                if (getq(f, a+1, &((char *)&d)[1]) == 0)
                    549:                        return (0);
                    550:                ptrace(4+f, pid, (int *)a, d);
                    551:                if (errno)
                    552:                        return (0);
                    553:        }
                    554:        return (1);
                    555: }
                    556: 
                    557: /*
                    558:  * Return the byte at address `a' in segment `f' indirectly through
                    559:  * the byte pointer `bp'.
                    560:  */
                    561: getq(f, a, bp)
                    562: register int a;
                    563: register char *bp;
                    564: {
                    565:        extern int errno;
                    566:        register int w;
                    567: 
                    568:        if ((w=(a&~1))!=cacaddr || f!=cacsegn) {
                    569:                errno = 0;
                    570:                cacdata = ptrace(1+f, pid, (int *) w, 0);
                    571:                if (errno) {
                    572:                        cacsegn = -1;
                    573:                        return (0);
                    574:                }
                    575:                cacsegn = f;
                    576:                cacaddr = w;
                    577:        }
                    578:        *bp = ((char *)&cacdata)[a&1];
                    579:        return (1);
                    580: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.