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