Annotation of 41BSD/cmd/analyze.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)analyze.c   4.1 (Berkeley) 10/1/80";
                      2: #include <stdio.h>
                      3: #include <sys/param.h>
                      4: #include <sys/dir.h>
                      5: #include <sys/pte.h>
                      6: #include <nlist.h>
                      7: #include <sys/map.h>
                      8: #include <sys/user.h>
                      9: #include <sys/proc.h>
                     10: #include <sys/text.h>
                     11: #include <sys/cmap.h>
                     12: #include <sys/vm.h>
                     13: 
                     14: /*
                     15:  * Analyze - analyze a core (and optional paging area) saved from
                     16:  * a virtual Unix system crash.
                     17:  */
                     18: 
                     19: int    Dflg;
                     20: int    dflg;
                     21: int    vflg;
                     22: int    mflg;
                     23: int    fflg;
                     24: int    sflg;
                     25: 
                     26: /* use vprintf with care; it plays havoc with ``else's'' */
                     27: #define        vprintf if (vflg) printf
                     28: 
                     29: #define        clear(x)        ((int)x & 0x7fffffff)
                     30: 
                     31: struct proc proc[NPROC];
                     32: struct text text[NTEXT];
                     33: struct map swapmap[SMAPSIZ];
                     34: struct cmap *cmap;
                     35: struct pte *usrpt;
                     36: struct pte *Usrptma;
                     37: int    firstfree;
                     38: int    maxfree;
                     39: int    freemem;
                     40: struct pte p0br[ctopt(MAXTSIZ+MAXDSIZ+MAXSSIZ)][NPTEPG];
                     41: int    pid;
                     42: 
                     43: struct paginfo {
                     44:        char    z_type;
                     45:        char    z_count;
                     46:        short   z_pid;
                     47:        struct  pte z_pte;
                     48: } *paginfo;
                     49: #define        ZLOST   0
                     50: #define        ZDATA   1
                     51: #define        ZSTACK  2
                     52: #define        ZUDOT   3
                     53: #define        ZPAGET  4
                     54: #define        ZTEXT   5
                     55: #define        ZFREE   6
                     56: #define        ZINTRAN 7
                     57: 
                     58: #define        NDBLKS  (2*SMAPSIZ)
                     59: struct dblks {
                     60:        short   d_first;
                     61:        short   d_size;
                     62:        char    d_type;
                     63:        char    d_index;
                     64: } dblks[NDBLKS];
                     65: int    ndblks;
                     66: 
                     67: #define        DFREE   0
                     68: #define        DDATA   1
                     69: #define        DSTACK  2
                     70: #define        DTEXT   3
                     71: #define        DUDOT   4
                     72: #define        DPAGET  5
                     73: 
                     74: union  {
                     75:        char buf[UPAGES][512];
                     76:        struct user U;
                     77: } u_area;
                     78: #define        u       u_area.U
                     79: 
                     80: int    fcore = -1;
                     81: int    fswap = -1;
                     82: 
                     83: struct nlist nl[] = {
                     84: #define        X_PROC 0
                     85:        { "_proc" },
                     86: #define        X_USRPT 1
                     87:        { "_usrpt" },
                     88: #define        X_PTMA  2
                     89:        { "_Usrptma" },
                     90: #define        X_FIRSTFREE 3
                     91:        { "_firstfr" },
                     92: #define        X_MAXFREE 4
                     93:        { "_maxfree" },
                     94: #define        X_TEXT 5
                     95:        { "_text" },
                     96: #define        X_FREEMEM 6
                     97:        { "_freemem" },
                     98: #define        X_CMAP 7
                     99:        { "_cmap" },
                    100: #define        X_ECMAP 8
                    101:        { "_ecmap" },
                    102: #define        X_SWAPMAP 9
                    103:        { "_swapmap" },
                    104:        { 0 }
                    105: };
                    106: 
                    107: main(argc, argv)
                    108:        int argc;
                    109:        char **argv;
                    110: {
                    111:        register struct nlist *np;
                    112:        register struct proc *p;
                    113:        register struct text *xp;
                    114:        register struct pte *pte;
                    115:        register int i;
                    116:        int w, a;
                    117: 
                    118:        argc--, argv++;
                    119:        while (argc > 0 && argv[0][0] == '-') {
                    120:                register char *cp = *argv++;
                    121:                argc--;
                    122:                while (*++cp) switch (*cp) {
                    123: 
                    124:                case 'm':
                    125:                        mflg++;
                    126:                        break;
                    127: 
                    128:                case 'v':
                    129:                        vflg++;
                    130:                        break;
                    131: 
                    132:                case 's':
                    133:                        if (argc < 2)
                    134:                                goto usage;
                    135:                        if ((fswap = open(argv[0], 0)) < 0) {
                    136:                                perror(argv[0]);
                    137:                                exit(1);
                    138:                        }
                    139:                        argc--,argv++;
                    140:                        sflg++;
                    141:                        break;
                    142: 
                    143:                case 'f':
                    144:                        fflg++;
                    145:                        break;
                    146: 
                    147:                case 'D':
                    148:                        Dflg++;
                    149:                        break;
                    150: 
                    151:                case 'd':
                    152:                        dflg++;
                    153:                        break;
                    154: 
                    155:                default:
                    156:                        goto usage;
                    157:                }
                    158:        }
                    159:        if (argc < 1) {
                    160: usage:
                    161:                fprintf(stderr, "usage: analyze [ -vmfd ] [ -s swapfile ] corefile [ system ]\n");
                    162:                exit(1);
                    163:        }
                    164:        close(0);
                    165:        if ((fcore = open(argv[0], 0)) < 0) {
                    166:                perror(argv[0]);
                    167:                exit(1);
                    168:        }
                    169:        nlist(argc > 1 ? argv[1] : "/vmunix", nl);
                    170:        if (nl[0].n_value == 0) {
                    171:                fprintf(stderr, "%s: bad namelist\n",
                    172:                    argc > 1 ? argv[1] : "/vmunix");
                    173:                exit(1);
                    174:        }
                    175:        for (np = nl; np->n_name[0]; np++)
                    176:                vprintf("%8.8s %x\n", np->n_name ,np->n_value );
                    177:        usrpt = (struct pte *)clear(nl[X_USRPT].n_value);
                    178:        Usrptma = (struct pte *)clear(nl[X_PTMA].n_value);
                    179:        firstfree = get(nl[X_FIRSTFREE].n_value);
                    180:        maxfree = get(nl[X_MAXFREE].n_value);
                    181:        freemem = get(nl[X_FREEMEM].n_value);
                    182:        paginfo = (struct paginfo *)calloc(maxfree, sizeof (struct paginfo));
                    183:        if (paginfo == NULL) {
                    184:                fprintf(stderr, "maxfree %x?... out of mem!\n", maxfree);
                    185:                exit(1);
                    186:        }
                    187:        vprintf("usrpt %x\nUsrptma %x\nfirstfree %x\nmaxfree %x\nfreemem %x\n",
                    188:                    usrpt, Usrptma, firstfree, maxfree, freemem);
                    189:        lseek(fcore, (long)clear(nl[X_PROC].n_value), 0);
                    190:        if (read(fcore, (char *)proc, sizeof proc) != sizeof proc) {
                    191:                perror("proc read");
                    192:                exit(1);
                    193:        }
                    194:        lseek(fcore, (long)clear(nl[X_TEXT].n_value), 0);
                    195:        if (read(fcore, (char *)text, sizeof text) != sizeof text) {
                    196:                perror("text read");
                    197:                exit(1);
                    198:        }
                    199:        i = (get(nl[X_ECMAP].n_value) - get(nl[X_CMAP].n_value));
                    200:        cmap = (struct cmap *)calloc(i, 1);
                    201:        if (cmap == NULL) {
                    202:                fprintf(stderr, "not enough mem for %x bytes of cmap\n", i);
                    203:                exit(1);
                    204:        }
                    205:        lseek(fcore, (long)clear(get(nl[X_CMAP].n_value)), 0);
                    206:        if (read(fcore, (char *)cmap, i) != i) {
                    207:                perror("cmap read");
                    208:                exit(1);
                    209:        }
                    210:        lseek(fcore, (long)clear(nl[X_SWAPMAP].n_value), 0);
                    211:        if (read(fcore, (char *)swapmap, sizeof swapmap) != sizeof swapmap) {
                    212:                perror("swapmap read");
                    213:                exit(1);
                    214:        }
                    215:        for (p = &proc[1]; p < &proc[NPROC]; p++) {
                    216:                p->p_p0br = (struct pte *)clear(p->p_p0br);
                    217:                p->p_addr = (struct pte *)clear(p->p_addr);
                    218:                if (p->p_stat == 0)
                    219:                        continue;
                    220:                printf("proc %d ", p->p_pid);
                    221:                if (p->p_stat == SZOMB) {
                    222:                        printf("zombie\n");
                    223:                        continue;
                    224:                }
                    225:                if (p->p_flag & SLOAD) {
                    226:                        printf("loaded, p0br %x, ", p->p_p0br);
                    227:                        printf("%d pages of page tables:", p->p_szpt);
                    228:                        a = btokmx(p->p_p0br);
                    229:                        for (i = 0; i < p->p_szpt; i++) {
                    230:                                w = get(&Usrptma[a + i]);
                    231:                                printf(" %x", w & PG_PFNUM);
                    232:                        }
                    233:                        printf("\n");
                    234:                        for(i = 0; i < p->p_szpt; i++) {
                    235:                                w = get(&Usrptma[a + i]);
                    236:                                if (getpt(w, i))
                    237:                                        count(p, (struct pte *)&w, ZPAGET);
                    238:                        }
                    239:                } else {
                    240:                        /* i = ctopt(btoc(u.u_exdata.ux_dsize)); */
                    241:                        i = clrnd(ctopt(p->p_tsize + p->p_dsize + p->p_ssize));
                    242:                        printf("swapped, swaddr %x\n", p->p_swaddr);
                    243:                        duse(p->p_swaddr, clrnd(ctod(UPAGES)), DUDOT, p - proc);
                    244:                        duse(p->p_swaddr + ctod(UPAGES),
                    245:                            clrnd(i - p->p_tsize / NPTEPG), DPAGET, p - proc); 
                    246:                            /* i, DPAGET, p - proc); */
                    247:                }
                    248:                p->p_p0br = (struct pte *)p0br;
                    249:                p->p_addr = uaddr(p);
                    250:                p->p_textp = &text[p->p_textp - (struct text *)nl[X_TEXT].n_value];
                    251:                if (p->p_pid == 2)
                    252:                        continue;
                    253:                if (getu(p))
                    254:                        continue;
                    255:                u.u_procp = p;
                    256:                pdmap();
                    257:                if ((p->p_flag & SLOAD) == 0)
                    258:                        continue;
                    259:                pid = p->p_pid;
                    260:                for (i = 0; i < p->p_tsize; i++) {
                    261:                        pte = tptopte(p, i);
                    262:                        if (pte->pg_fod || pte->pg_pfnum == 0)
                    263:                                continue;
                    264:                        if (pte->pg_pfnum >= firstfree && pte->pg_pfnum < maxfree && cmap[pgtocm(pte->pg_pfnum)].c_intrans)
                    265:                                count(p, pte, ZINTRAN);
                    266:                        else
                    267:                                count(p, pte, ZTEXT);
                    268:                }
                    269:                vprintf("\n");
                    270:                for (i = 0; i < p->p_dsize; i++) {
                    271:                        pte = dptopte(p, i);
                    272:                        if (pte->pg_fod || pte->pg_pfnum == 0)
                    273:                                continue;
                    274:                        if (pte->pg_pfnum >= firstfree && pte->pg_pfnum < maxfree && cmap[pgtocm(pte->pg_pfnum)].c_intrans)
                    275:                                count(p, pte, ZINTRAN);
                    276:                        else
                    277:                                count(p, pte, ZDATA);
                    278:                }
                    279:                vprintf("\n");
                    280:                for (i = 0; i < p->p_ssize; i++) {
                    281:                        pte = sptopte(p, i);
                    282:                        if (pte->pg_fod || pte->pg_pfnum == 0)
                    283:                                continue;
                    284:                        if (pte->pg_pfnum >= firstfree && pte->pg_pfnum < maxfree && cmap[pgtocm(pte->pg_pfnum)].c_intrans)
                    285:                                count(p, pte, ZINTRAN);
                    286:                        else
                    287:                                count(p, pte, ZSTACK);
                    288:                }
                    289:                vprintf("\n");
                    290:                for (i = 0; i < UPAGES; i++)
                    291:                        count(p, &p->p_addr[i], ZUDOT);
                    292:                vprintf("\n");
                    293:                vprintf("\n");
                    294:        }
                    295:        for (xp = &text[0]; xp < &text[NTEXT]; xp++)
                    296:                if (xp->x_iptr) {
                    297:                        for (i = 0; i < xp->x_size; i += DMTEXT)
                    298:                                duse(xp->x_daddr[i],
                    299:                                    (xp->x_size - i) > DMTEXT
                    300:                                        ? DMTEXT : xp->x_size - i,
                    301:                                    DTEXT, xp - text);
                    302:                        if (xp->x_flag & XPAGI)
                    303:                                duse(xp->x_ptdaddr, clrnd(ctopt(xp->x_size)),
                    304:                                    DTEXT, xp - text);
                    305:                }
                    306:        dmcheck();
                    307:        fixfree();
                    308:        summary();
                    309:        exit(0);
                    310: }
                    311: 
                    312: pdmap()
                    313: {
                    314:        register struct text *xp;
                    315: 
                    316:        if (fswap == -1 && (u.u_procp->p_flag & SLOAD) == 0)
                    317:                return;
                    318:        if (Dflg)
                    319:                printf("disk for pid %d", u.u_procp->p_pid);
                    320:        if ((xp = u.u_procp->p_textp) && Dflg)
                    321:                ptdmap(xp->x_daddr, xp->x_size);
                    322:        pdmseg("data", &u.u_dmap, DDATA);
                    323:        pdmseg("stack", &u.u_smap, DSTACK);
                    324:        if (Dflg)
                    325:                printf("\n");
                    326: }
                    327: 
                    328: ptdmap(dp, size)
                    329:        register daddr_t *dp;
                    330:        int size;
                    331: {
                    332:        register int i;
                    333:        int rem;
                    334: 
                    335:        if (Dflg)
                    336:                printf(" text:");
                    337:        for (i = 0, rem = size; rem > 0; i++) {
                    338:                if (Dflg)
                    339:                        printf(" %x<%x>", dp[i], rem < DMTEXT ? rem : DMTEXT);
                    340:                rem -= rem < DMTEXT ? rem : DMTEXT;
                    341:        }
                    342: }
                    343: 
                    344: pdmseg(cp, dmp, type)
                    345:        char *cp;
                    346:        struct dmap *dmp;
                    347: {
                    348:        register int i;
                    349:        int b, rem;
                    350: 
                    351:        if (Dflg)
                    352:                printf(", %s:", cp);
                    353:        b = DMMIN;
                    354:        for (i = 0, rem = dmp->dm_size; rem > 0; i++) {
                    355:                if (Dflg)
                    356:                        printf(" %x<%x>", dmp->dm_map[i], rem < b ? rem : b);
                    357:                duse(dmp->dm_map[i], b, type, u.u_procp - proc);
                    358:                rem -= b;
                    359:                if (b < DMMAX)
                    360:                        b *= 2;
                    361:        }
                    362: }
                    363: 
                    364: duse(first, size, type, index)
                    365: {
                    366:        register struct dblks *dp;
                    367: 
                    368:        if (fswap == -1)
                    369:                return;
                    370:        dp = &dblks[ndblks];
                    371:        if (++ndblks > NDBLKS) {
                    372:                fprintf(stderr, "too many disk blocks, increase NDBLKS\n");
                    373:                exit(1);
                    374:        }
                    375:        dp->d_first = first;
                    376:        dp->d_size = size;
                    377:        dp->d_type = type;
                    378:        dp->d_index = index;
                    379: }
                    380: 
                    381: dsort(d, e)
                    382:        register struct dblks *d, *e;
                    383: {
                    384: 
                    385:        return (e->d_first - d->d_first);
                    386: }
                    387: 
                    388: dmcheck()
                    389: {
                    390:        register struct map *smp;
                    391:        register struct dblks *d, *e;
                    392: 
                    393:        for (smp = swapmap; smp->m_size; smp++)
                    394:                duse(smp->m_addr, smp->m_size, DFREE, 0);
                    395:        duse(CLSIZE, DMTEXT - CLSIZE, DFREE, 0);
                    396:        qsort(dblks, ndblks, sizeof (struct dblks), dsort);
                    397:        d = &dblks[ndblks - 1];
                    398:        if (d->d_first > 1)
                    399:                printf("lost swap map: start %x size %x\n", 1, d->d_first);
                    400:        for (; d > dblks; d--) {
                    401:                if (dflg)
                    402:                        dprint(d);
                    403:                e = d - 1;
                    404:                if (d->d_first + d->d_size > e->d_first) {
                    405:                        printf("overlap in swap mappings:\n");
                    406:                        dprint(d);
                    407:                        dprint(e);
                    408:                } else if (d->d_first + d->d_size < e->d_first) {
                    409:                        printf("lost swap map: start %x size %x\n",
                    410:                            d->d_first + d->d_size,
                    411:                            e->d_first - (d->d_first + d->d_size)); 
                    412:                }
                    413:        }
                    414:        if (dflg)
                    415:                dprint(dblks);
                    416:        if (sflg)
                    417:                printf("swap space ends at %x\n", d->d_first + d->d_size);
                    418: }
                    419: 
                    420: char *dnames[] = {
                    421:        "DFREE",
                    422:        "DDATA",
                    423:        "DSTACK",
                    424:        "DTEXT",
                    425:        "DUDOT",
                    426:        "DPAGET",
                    427: };
                    428: 
                    429: dprint(d)
                    430:        register struct dblks *d;
                    431: {
                    432: 
                    433:        printf("at %4x size %4x type %s", d->d_first, d->d_size,
                    434:                dnames[d->d_type]);
                    435:        switch (d->d_type) {
                    436: 
                    437:        case DSTACK:
                    438:        case DDATA:
                    439:                printf(" pid %d", proc[d->d_index].p_pid);
                    440:                break;
                    441:        }
                    442:        printf("\n");
                    443: }
                    444: 
                    445: getpt(x, i)
                    446:        int x, i;
                    447: {
                    448: 
                    449:        lseek(fcore, (long)ctob((x & PG_PFNUM)), 0);
                    450:        if (read(fcore, (char *)(p0br[i]), NBPG) != NBPG) {
                    451:                perror("read");
                    452:                fprintf(stderr, "getpt error reading frame %x\n", clear(x));
                    453:                return (0);
                    454:        }
                    455:        return (1);
                    456: }
                    457: 
                    458: checkpg(p, pte, type)
                    459:        register struct pte *pte;
                    460:        register struct proc *p;
                    461:        int type;
                    462: {
                    463:        char corepg[NBPG], swapg[NBPG];
                    464:        register int i, count, dblock;
                    465:        register int pfnum = pte->pg_pfnum;
                    466: 
                    467:        if (type == ZPAGET || type == ZUDOT)
                    468:                return (0);
                    469:        lseek(fcore, (long)(NBPG * pfnum), 0);
                    470:        if (read(fcore, corepg, NBPG) != NBPG){
                    471:                perror("read");
                    472:                fprintf(stderr, "Error reading core page %x\n", pfnum);
                    473:                return (0);
                    474:        }
                    475:        switch (type) {
                    476: 
                    477:        case ZDATA:
                    478:                if (ptetodp(p, pte) >= u.u_dmap.dm_size)
                    479:                        return (0);
                    480:                break;
                    481: 
                    482:        case ZTEXT:
                    483:                break;
                    484: 
                    485:        case ZSTACK:
                    486:                if (ptetosp(p, pte) >= u.u_smap.dm_size)
                    487:                        return (0);
                    488:                break;
                    489: 
                    490:        default:
                    491:                return(0);
                    492:                break;
                    493:        }
                    494:        dblock = vtod(p, ptetov(p, pte), &u.u_dmap, &u.u_smap);
                    495:        vprintf("   %x", dblock);
                    496:        if (pte->pg_fod || pte->pg_pfnum == 0)
                    497:                return (0);
                    498:        if (cmap[pgtocm(pte->pg_pfnum)].c_intrans || pte->pg_m || pte->pg_swapm)
                    499:                return (0);
                    500:        lseek(fswap, (long)(NBPG * dblock), 0);
                    501:        if (read(fswap, swapg, NBPG) != NBPG) {
                    502:                fprintf(stderr,"swap page %x: ", dblock);
                    503:                perror("read");
                    504:        }
                    505:        count = 0;
                    506:        for (i = 0; i < NBPG; i++)
                    507:                if (corepg[i] != swapg[i])
                    508:                        count++;
                    509:        if (count == 0)
                    510:                vprintf("\tsame");
                    511:        return (count);
                    512: }
                    513: 
                    514: getu(p)
                    515:        register struct proc *p;
                    516: {
                    517:        int i, w, cc, errs = 0;
                    518: 
                    519:        for (i = 0; i < UPAGES; i++) {
                    520:                if (p->p_flag & SLOAD) {
                    521:                        lseek(fcore, ctob(p->p_addr[i].pg_pfnum), 0);
                    522:                        if (read(fcore, u_area.buf[i], NBPG) != NBPG)
                    523:                                perror("core u. read"), errs++;
                    524:                } else if (fswap >= 0) {
                    525:                        lseek(fswap, (long)(NBPG * (p->p_swaddr+i)), 0);
                    526:                        if (read(fswap, u_area.buf[i], NBPG) != NBPG)
                    527:                                perror("swap u. read"), errs++;
                    528:                }
                    529:        }
                    530:        return (errs);
                    531: }
                    532: 
                    533: char   *typepg[] = {
                    534:        "lost",
                    535:        "data",
                    536:        "stack",
                    537:        "udot",
                    538:        "paget",
                    539:        "text",
                    540:        "free",
                    541:        "intransit",
                    542: };
                    543: 
                    544: count(p, pte, type)
                    545:        struct proc *p;
                    546:        register struct pte *pte;
                    547:        int type;
                    548: {
                    549:        register int pfnum = pte->pg_pfnum;
                    550:        register struct paginfo *zp = &paginfo[pfnum];
                    551:        int ndif;
                    552: #define        zprintf if (type==ZINTRAN || vflg) printf
                    553: 
                    554:        if (type == ZINTRAN && pfnum == 0)
                    555:                return;
                    556:        zprintf("page %x %s", pfnum, typepg[type]);
                    557:        if (sflg == 0 || (ndif = checkpg(p, pte, type)) == 0) {
                    558:                zprintf("\n");
                    559:        } else {
                    560:                if (vflg == 0 && type != ZINTRAN)
                    561:                        printf("page %x %s,", pfnum, typepg[type]);
                    562:                printf(" %d bytes differ\n",ndif);
                    563:        }
                    564:        if (pfnum < firstfree || pfnum > maxfree) {
                    565:                printf("page number out of range:\n");
                    566:                printf("\tpage %x type %s pid %d\n", pfnum, typepg[type], pid);
                    567:                return;
                    568:        }
                    569:        if (bad(zp, type)) {
                    570:                printf("dup page pte %x", *(int *)pte);
                    571:                dumpcm("", pte->pg_pfnum);
                    572:                dump(zp);
                    573:                printf("pte %x and as %s in pid %d\n", zp->z_pte, typepg[type], pid);
                    574:                return;
                    575:        }
                    576:        zp->z_type = type;
                    577:        zp->z_count++;
                    578:        zp->z_pid = pid;
                    579:        zp->z_pte = *pte;
                    580: }
                    581: 
                    582: bad(zp, type)
                    583:        struct paginfo *zp;
                    584: {
                    585:        if (type == ZTEXT) {
                    586:                if (zp->z_type != 0 && zp->z_type != ZTEXT)
                    587:                        return (1);
                    588:                return (0);
                    589:        }
                    590:        return (zp->z_count);
                    591: }
                    592: 
                    593: dump(zp)
                    594:        struct paginfo *zp;
                    595: {
                    596: 
                    597:        printf("page %x type %s pid %d ", zp - paginfo, typepg[zp->z_type], zp->z_pid);
                    598: }
                    599: 
                    600: summary()
                    601: {
                    602:        register int i;
                    603:        register struct paginfo *zp;
                    604:        register int pfnum;
                    605: 
                    606:        for (i = firstfree + UPAGES; i < maxfree; i++) {
                    607:                zp = &paginfo[i];
                    608:                if (zp->z_type == ZLOST)
                    609:                        dumpcm("lost", i);
                    610:                pfnum = pgtocm(i);
                    611:                if (cmap[pfnum].c_lock && cmap[pfnum].c_type != CSYS)
                    612:                        dumpcm("locked", i);
                    613:                if (mflg)
                    614:                        dumpcm("mem", i);
                    615:        }
                    616: }
                    617: 
                    618: char   *tynames[] = {
                    619:        "sys",
                    620:        "text",
                    621:        "data",
                    622:        "stack"
                    623: };
                    624: dumpcm(cp, pg)
                    625:        char *cp;
                    626:        int pg;
                    627: {
                    628:        int pslot;
                    629:        int cm;
                    630:        register struct cmap *c;
                    631: 
                    632:        printf("%s page %x ", cp, pg);
                    633:        cm = pgtocm(pg);
                    634:        c = &cmap[cm];
                    635:        printf("\t[%x, %x", c->c_page, c->c_ndx);
                    636:        if (c->c_type != CTEXT)
                    637:                printf(" (=pid %d)", proc[c->c_ndx].p_pid);
                    638:        else {
                    639:                pslot=(text[c->c_ndx].x_caddr - (struct proc *)nl[X_PROC].n_value);
                    640:                printf(" (=pid");
                    641:                for(;;) {
                    642:                        printf(" %d", proc[pslot].p_pid);
                    643:                        if (proc[pslot].p_xlink == 0)
                    644:                                break;
                    645:                        pslot=(proc[pslot].p_xlink - (struct proc *)nl[X_PROC].n_value);
                    646:                }
                    647:                printf(")");
                    648:        }
                    649:        printf("] ");
                    650:        printf(tynames[c->c_type]);
                    651:        if (c->c_free)
                    652:                printf(" free");
                    653:        if (c->c_gone)
                    654:                printf(" gone");
                    655:        if (c->c_lock)
                    656:                printf(" lock");
                    657:        if (c->c_want)
                    658:                printf(" want");
                    659:        if (c->c_intrans)
                    660:                printf(" intrans");
                    661:        if (c->c_blkno)
                    662:                printf(" blkno %x mdev %d", c->c_blkno, c->c_mdev);
                    663:        printf("\n");
                    664: }
                    665: 
                    666: fixfree()
                    667: {
                    668:        register int i, next, prev;
                    669: 
                    670:        next = CMHEAD;
                    671:        for (i=freemem/CLSIZE; --i >=0; ) {
                    672:                prev = next;
                    673:                next = cmap[next].c_next;
                    674:                if (cmap[next].c_free == 0) {
                    675:                        printf("link to non free block: in %x to %x\n", cmtopg(prev), cmtopg(next));
                    676:                        dumpcm("bad free link in", cmtopg(prev));
                    677:                        dumpcm("to non free block", cmtopg(next));
                    678:                }
                    679:                if (cmtopg(next) > maxfree) {
                    680:                        printf("free list link out of range: in %x to %x\n", cmtopg(prev), cmtopg(next));
                    681:                        dumpcm("bad link in", cmtopg(prev));
                    682:                }
                    683:                paginfo[cmtopg(next)].z_type = ZFREE;
                    684:                if (fflg)
                    685:                        dumpcm("free", cmtopg(next));
                    686:                paginfo[cmtopg(next)+1].z_type = ZFREE;
                    687:                if (fflg)
                    688:                        dumpcm("free", cmtopg(next)+1);
                    689:        }
                    690: }
                    691: 
                    692: get(loc)
                    693: unsigned loc;
                    694: {
                    695:        int x;
                    696:        
                    697:        lseek(fcore, (long)clear(loc), 0);
                    698:        if (read(fcore, (char *)&x, sizeof (int)) != sizeof (int)) {
                    699:                perror("read");
                    700:                fprintf(stderr, "get failed on %x\n", clear(loc));
                    701:                return (0);
                    702:        }
                    703:        return (x);
                    704: }
                    705: /*
                    706:  * Convert a virtual page number 
                    707:  * to its corresponding disk block number.
                    708:  * Used in pagein/pageout to initiate single page transfers.
                    709:  */
                    710: vtod(p, v, dmap, smap)
                    711:        register struct proc *p;
                    712:        register struct dmap *dmap, *smap;
                    713: {
                    714:        struct dblock db;
                    715: 
                    716:        if (v < p->p_tsize)
                    717:                return(p->p_textp->x_daddr[v / DMTEXT] + v % DMTEXT);
                    718:        if (isassv(p, v))
                    719:                vstodb(vtosp(p, v), 1, smap, &db, 1);
                    720:        else
                    721:                vstodb(vtodp(p, v), 1, dmap, &db, 0);
                    722:        return (db.db_base);
                    723: }
                    724: 
                    725: /* 
                    726:  * Convert a pte pointer to
                    727:  * a virtual page number.
                    728:  */
                    729: ptetov(p, pte)
                    730:        register struct proc *p;
                    731:        register struct pte *pte;
                    732: {
                    733: 
                    734:        if (isatpte(p, pte))
                    735:                return (tptov(p, ptetotp(p, pte)));
                    736:        else if (isadpte(p, pte))
                    737:                return (dptov(p, ptetodp(p, pte)));
                    738:        else
                    739:                return (sptov(p, ptetosp(p, pte)));
                    740: }
                    741: 
                    742: /*
                    743:  * Given a base/size pair in virtual swap area,
                    744:  * return a physical base/size pair which is the
                    745:  * (largest) initial, physically contiguous block.
                    746:  */
                    747: vstodb(vsbase, vssize, dmp, dbp, rev)
                    748:        register int vsbase;
                    749:        int vssize;
                    750:        register struct dmap *dmp;
                    751:        register struct dblock *dbp;
                    752: {
                    753:        register int blk = DMMIN;
                    754:        register swblk_t *ip = dmp->dm_map;
                    755: 
                    756:        if (vsbase < 0 || vsbase + vssize > dmp->dm_size)
                    757:                panic("vstodb");
                    758:        while (vsbase >= blk) {
                    759:                vsbase -= blk;
                    760:                if (blk < DMMAX)
                    761:                        blk *= 2;
                    762:                ip++;
                    763:        }
                    764:        dbp->db_size = min(vssize, blk - vsbase);
                    765:        dbp->db_base = *ip + (rev ? blk - (vsbase + vssize) : vsbase);
                    766: }
                    767: 
                    768: panic(cp)
                    769:        char *cp;
                    770: {
                    771:        printf("panic!: %s\n", cp);
                    772: }
                    773: 
                    774: min(a, b)
                    775: {
                    776:        return (a < b ? a : b);
                    777: }

unix.superglobalmegacorp.com

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