Annotation of cci/usr/src/etc/analyze.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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