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