|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.