|
|
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.