BSD 4_3 release
[unix-history] / usr / src / etc / pstat.c
index 832c518..abc830f 100644 (file)
@@ -1,6 +1,19 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)pstat.c     4.24 (Berkeley) 10/15/83";
-#endif
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif not lint
+
+#ifndef lint
+static char sccsid[] = "@(#)pstat.c    5.8 (Berkeley) 5/5/86";
+#endif not lint
+
 /*
  * Print system stuff
  */
 /*
  * Print system stuff
  */
@@ -24,10 +37,12 @@ static char *sccsid = "@(#)pstat.c  4.24 (Berkeley) 10/15/83";
 #include <sys/vm.h>
 #include <nlist.h>
 #include <machine/pte.h>
 #include <sys/vm.h>
 #include <nlist.h>
 #include <machine/pte.h>
+#include <stdio.h>
 
 char   *fcore  = "/dev/kmem";
 
 char   *fcore  = "/dev/kmem";
+char   *fmem   = "/dev/mem";
 char   *fnlist = "/vmunix";
 char   *fnlist = "/vmunix";
-int    fc;
+int    fc, fm;
 
 struct nlist nl[] = {
 #define        SINODE  0
 
 struct nlist nl[] = {
 #define        SINODE  0
@@ -74,6 +89,22 @@ struct nlist nl[] = {
        { "_nswdev" },
 #define        SSWDEVT 21
        { "_swdevt" },
        { "_nswdev" },
 #define        SSWDEVT 21
        { "_swdevt" },
+#define        SDMF    22
+       { "_dmf_tty" },
+#define        SNDMF   23
+       { "_ndmf" },
+#define        SNPTY   24
+       { "_npty" },
+#define        SDHU    25
+       { "_dhu_tty" },
+#define        SNDHU   26
+       { "_ndhu" },
+#define        SYSMAP  27
+       { "_Sysmap" },
+#define        SDMZ    28
+       { "_dmz_tty" },
+#define        SNDMZ   29
+       { "_ndmz" },
        { "" }
 };
 
        { "" }
 };
 
@@ -93,6 +124,8 @@ int  allflg;
 int    kflg;
 struct pte *Usrptma;
 struct pte *usrpt;
 int    kflg;
 struct pte *Usrptma;
 struct pte *usrpt;
+u_long getw();
+off_t  mkphys();
 
 main(argc, argv)
 char **argv;
 
 main(argc, argv)
 char **argv;
@@ -122,7 +155,7 @@ char **argv;
 
                case 'k':
                        kflg++;
 
                case 'k':
                        kflg++;
-                       fcore = "/vmcore";
+                       fcore = fmem = "/vmcore";
                        break;
 
                case 'x':
                        break;
 
                case 'x':
@@ -156,12 +189,18 @@ char **argv;
                        exit(1);
                }
        }
                        exit(1);
                }
        }
-       if (argc>1)
-               fcore = argv[1];
+       if (argc>1) {
+               fcore = fmem = argv[1];
+               kflg++;
+       }
        if ((fc = open(fcore, 0)) < 0) {
                printf("Can't find %s\n", fcore);
                exit(1);
        }
        if ((fc = open(fcore, 0)) < 0) {
                printf("Can't find %s\n", fcore);
                exit(1);
        }
+       if ((fm = open(fmem, 0)) < 0) {
+               printf("Can't find %s\n", fmem);
+               exit(1);
+       }
        if (argc>0)
                fnlist = argv[0];
        nlist(fnlist, nl);
        if (argc>0)
                fnlist = argv[0];
        nlist(fnlist, nl);
@@ -208,7 +247,17 @@ doinode()
        nin = 0;
        ninode = getw(nl[SNINODE].n_value);
        xinode = (struct inode *)calloc(ninode, sizeof (struct inode));
        nin = 0;
        ninode = getw(nl[SNINODE].n_value);
        xinode = (struct inode *)calloc(ninode, sizeof (struct inode));
-       lseek(fc, (int)(ainode = (struct inode *)getw(nl[SINODE].n_value)), 0);
+       ainode = (struct inode *)getw(nl[SINODE].n_value);
+       if (ninode < 0 || ninode > 10000) {
+               fprintf(stderr, "number of inodes is preposterous (%d)\n",
+                       ninode);
+               return;
+       }
+       if (xinode == NULL) {
+               fprintf(stderr, "can't allocate memory for inode table\n");
+               return;
+       }
+       lseek(fc, mkphys((off_t)ainode), 0);
        read(fc, xinode, ninode * sizeof(struct inode));
        for (ip = xinode; ip < &xinode[ninode]; ip++)
                if (ip->i_count)
        read(fc, xinode, ninode * sizeof(struct inode));
        for (ip = xinode; ip < &xinode[ninode]; ip++)
                if (ip->i_count)
@@ -250,17 +299,16 @@ printf("   LOC      FLAGS    CNT DEVICE  RDC WRC  INO  MODE  NLK UID   SIZE/DEV\
        free(xinode);
 }
 
        free(xinode);
 }
 
+u_long
 getw(loc)
        off_t loc;
 {
 getw(loc)
        off_t loc;
 {
-       int word;
+       u_long word;
 
        if (kflg)
                loc &= 0x7fffffff;
        lseek(fc, loc, 0);
        read(fc, &word, sizeof (word));
 
        if (kflg)
                loc &= 0x7fffffff;
        lseek(fc, loc, 0);
        read(fc, &word, sizeof (word));
-       if (kflg)
-               word &= 0x7fffffff;
        return (word);
 }
 
        return (word);
 }
 
@@ -277,22 +325,36 @@ dotext()
        register struct text *xp;
        int ntext;
        struct text *xtext, *atext;
        register struct text *xp;
        int ntext;
        struct text *xtext, *atext;
-       int ntx;
+       int ntx, ntxca;
 
 
-       ntx = 0;
+       ntx = ntxca = 0;
        ntext = getw(nl[SNTEXT].n_value);
        xtext = (struct text *)calloc(ntext, sizeof (struct text));
        ntext = getw(nl[SNTEXT].n_value);
        xtext = (struct text *)calloc(ntext, sizeof (struct text));
-       lseek(fc, (int)(atext = (struct text *)getw(nl[STEXT].n_value)), 0);
+       atext = (struct text *)getw(nl[STEXT].n_value);
+       if (ntext < 0 || ntext > 10000) {
+               fprintf(stderr, "number of texts is preposterous (%d)\n",
+                       ntext);
+               return;
+       }
+       if (xtext == NULL) {
+               fprintf(stderr, "can't allocate memory for text table\n");
+               return;
+       }
+       lseek(fc, mkphys((off_t)atext), 0);
        read(fc, xtext, ntext * sizeof (struct text));
        read(fc, xtext, ntext * sizeof (struct text));
-       for (xp = xtext; xp < &xtext[ntext]; xp++)
-               if (xp->x_iptr!=NULL)
+       for (xp = xtext; xp < &xtext[ntext]; xp++) {
+               if (xp->x_iptr != NULL)
+                       ntxca++;
+               if (xp->x_count != 0)
                        ntx++;
                        ntx++;
+       }
        if (totflg) {
        if (totflg) {
-               printf("%3d/%3d texts\n", ntx, ntext);
+               printf("%3d/%3d texts active, %3d used\n", ntx, ntext, ntxca);
                return;
        }
                return;
        }
-       printf("%d/%d active texts\n", ntx, ntext);
-       printf("   LOC   FLAGS DADDR      CADDR  RSS SIZE      IPTR  CNT CCNT\n");
+       printf("%d/%d active texts, %d used\n", ntx, ntext, ntxca);
+       printf("\
+   LOC   FLAGS DADDR     CADDR  RSS SIZE     IPTR   CNT CCNT      FORW     BACK\n");
        for (xp = xtext; xp < &xtext[ntext]; xp++) {
                if (xp->x_iptr == NULL)
                        continue;
        for (xp = xtext; xp < &xtext[ntext]; xp++) {
                if (xp->x_iptr == NULL)
                        continue;
@@ -305,12 +367,14 @@ dotext()
                putf(xp->x_flag&XLOCK, 'K');
                putf(xp->x_flag&XWANT, 'w');
                printf("%5x", xp->x_daddr[0]);
                putf(xp->x_flag&XLOCK, 'K');
                putf(xp->x_flag&XWANT, 'w');
                printf("%5x", xp->x_daddr[0]);
-               printf("%11x", xp->x_caddr);
+               printf("%10x", xp->x_caddr);
                printf("%5d", xp->x_rssize);
                printf("%5d", xp->x_size);
                printf("%10.1x", xp->x_iptr);
                printf("%5d", xp->x_count&0377);
                printf("%5d", xp->x_ccount);
                printf("%5d", xp->x_rssize);
                printf("%5d", xp->x_size);
                printf("%10.1x", xp->x_iptr);
                printf("%5d", xp->x_count&0377);
                printf("%5d", xp->x_ccount);
+               printf("%10x", xp->x_forw);
+               printf("%9x", xp->x_back);
                printf("\n");
        }
        free(xtext);
                printf("\n");
        }
        free(xtext);
@@ -326,7 +390,17 @@ doproc()
 
        nproc = getw(nl[SNPROC].n_value);
        xproc = (struct proc *)calloc(nproc, sizeof (struct proc));
 
        nproc = getw(nl[SNPROC].n_value);
        xproc = (struct proc *)calloc(nproc, sizeof (struct proc));
-       lseek(fc, (int)(aproc = (struct proc *)getw(nl[SPROC].n_value)), 0);
+       aproc = (struct proc *)getw(nl[SPROC].n_value);
+       if (nproc < 0 || nproc > 10000) {
+               fprintf(stderr, "number of procs is preposterous (%d)\n",
+                       nproc);
+               return;
+       }
+       if (xproc == NULL) {
+               fprintf(stderr, "can't allocate memory for proc table\n");
+               return;
+       }
+       lseek(fc, mkphys((off_t)aproc), 0);
        read(fc, xproc, nproc * sizeof (struct proc));
        np = 0;
        for (pp=xproc; pp < &xproc[nproc]; pp++)
        read(fc, xproc, nproc * sizeof (struct proc));
        np = 0;
        for (pp=xproc; pp < &xproc[nproc]; pp++)
@@ -337,7 +411,7 @@ doproc()
                return;
        }
        printf("%d/%d processes\n", np, nproc);
                return;
        }
        printf("%d/%d processes\n", np, nproc);
-       printf("   LOC    S    F POIP PRI      SIG  UID SLP TIM  CPU  NI   PGRP    PID   PPID    ADDR   RSS SRSS SIZE    WCHAN    LINK   TEXTP CLKT\n");
+       printf("   LOC    S    F POIP PRI      SIG  UID SLP TIM  CPU  NI   PGRP    PID   PPID    ADDR   RSS SRSS SIZE    WCHAN    LINK   TEXTP\n");
        for (pp=xproc; pp<&xproc[nproc]; pp++) {
                if (pp->p_stat==0 && allflg==0)
                        continue;
        for (pp=xproc; pp<&xproc[nproc]; pp++) {
                if (pp->p_stat==0 && allflg==0)
                        continue;
@@ -357,9 +431,12 @@ doproc()
                printf(" %6d", pp->p_ppid);
                if (kflg)
                        pp->p_addr = (struct pte *)clear((int)pp->p_addr);
                printf(" %6d", pp->p_ppid);
                if (kflg)
                        pp->p_addr = (struct pte *)clear((int)pp->p_addr);
-               lseek(fc, (long)(Usrptma+btokmx(pp->p_addr)), 0);
-               read(fc, &apte, sizeof(apte));
-               printf(" %8x", ctob(apte.pg_pfnum+1) - sizeof(struct pte) * UPAGES);
+               if (pp->p_flag & SLOAD) {
+                       lseek(fc, (long)pp->p_addr, 0);
+                       read(fc, &apte, sizeof(apte));
+                       printf(" %8x", apte.pg_pfnum);
+               } else
+                       printf(" %8x", pp->p_swaddr);
                printf(" %4x", pp->p_rssize);
                printf(" %4x", pp->p_swrss);
                printf(" %5x", pp->p_dsize+pp->p_ssize);
                printf(" %4x", pp->p_rssize);
                printf(" %4x", pp->p_swrss);
                printf(" %5x", pp->p_dsize+pp->p_ssize);
@@ -368,61 +445,71 @@ doproc()
                printf(" %7x", clear(pp->p_textp));
                printf("\n");
        }
                printf(" %7x", clear(pp->p_textp));
                printf("\n");
        }
+       free(xproc);
 }
 
 }
 
+static char mesg[] =
+" # RAW CAN OUT     MODE     ADDR DEL COL     STATE  PGRP DISC\n";
+static int ttyspace = 128;
+static struct tty *tty;
+
 dotty()
 {
 dotty()
 {
-       struct tty dz_tty[128];
-       int ndz;
-       register struct tty *tp;
-       register char *mesg;
+       extern char *malloc();
 
 
+       if ((tty = (struct tty *)malloc(ttyspace * sizeof(*tty))) == 0) {
+               printf("pstat: out of memory\n");
+               return;
+       }
        printf("1 cons\n");
        if (kflg)
                nl[SKL].n_value = clear(nl[SKL].n_value);
        lseek(fc, (long)nl[SKL].n_value, 0);
        printf("1 cons\n");
        if (kflg)
                nl[SKL].n_value = clear(nl[SKL].n_value);
        lseek(fc, (long)nl[SKL].n_value, 0);
-       read(fc, dz_tty, sizeof(dz_tty[0]));
-       mesg = " # RAW CAN OUT   MODE    ADDR   DEL COL  STATE   PGRP DISC\n";
+       read(fc, tty, sizeof(*tty));
        printf(mesg);
        printf(mesg);
-       ttyprt(&dz_tty[0], 0);
-       if (nl[SNDZ].n_type == 0)
-               goto dh;
-       if (kflg) {
-               nl[SNDZ].n_value = clear(nl[SNDZ].n_value);
-               nl[SDZ].n_value = clear(nl[SDZ].n_value);
-       }
-       lseek(fc, (long)nl[SNDZ].n_value, 0);
-       read(fc, &ndz, sizeof(ndz));
-       printf("%d dz lines\n", ndz);
-       lseek(fc, (long)nl[SDZ].n_value, 0);
-       read(fc, dz_tty, ndz * sizeof (struct tty));
-       for (tp = dz_tty; tp < &dz_tty[ndz]; tp++)
-               ttyprt(tp, tp - dz_tty);
-dh:
-       if (nl[SNDH].n_type == 0)
-               goto pty;
-       if (kflg) {
-               nl[SNDH].n_value = clear(nl[SNDH].n_value);
-               nl[SDH].n_value = clear(nl[SDH].n_value);
-       }
-       lseek(fc, (long)nl[SNDH].n_value, 0);
-       read(fc, &ndz, sizeof(ndz));
-       printf("%d dh lines\n", ndz);
-       lseek(fc, (long)nl[SDH].n_value, 0);
-       read(fc, dz_tty, ndz * sizeof(struct tty));
-       for (tp = dz_tty; tp < &dz_tty[ndz]; tp++)
-               ttyprt(tp, tp - dz_tty);
-pty:
-       if (nl[SPTY].n_type == 0)
-               goto pty;
+       ttyprt(&tty[0], 0);
+       if (nl[SNDZ].n_type != 0)
+               dottytype("dz", SDZ, SNDZ);
+       if (nl[SNDH].n_type != 0)
+               dottytype("dh", SDH, SNDH);
+       if (nl[SNDMF].n_type != 0)
+               dottytype("dmf", SDMF, SNDMF);
+       if (nl[SNDHU].n_type != 0)
+               dottytype("dhu", SDHU, SNDHU);
+       if (nl[SNDMZ].n_type != 0)
+               dottytype("dmz", SDMZ, SNDMZ);
+       if (nl[SNPTY].n_type != 0)
+               dottytype("pty", SPTY, SNPTY);
+}
+
+dottytype(name, type, number)
+char *name;
+{
+       int ntty;
+       register struct tty *tp;
+       extern char *realloc();
+
+       if (tty == (struct tty *)0)
+               return;
        if (kflg) {
        if (kflg) {
-               nl[SPTY].n_value = clear(nl[SPTY].n_value);
+               nl[number].n_value = clear(nl[number].n_value);
+               nl[type].n_value = clear(nl[type].n_value);
+       }
+       lseek(fc, (long)nl[number].n_value, 0);
+       read(fc, &ntty, sizeof(ntty));
+       printf("%d %s lines\n", ntty, name);
+       if (ntty > ttyspace) {
+               ttyspace = ntty;
+               if ((tty = (struct tty *)realloc(tty, ttyspace * sizeof(*tty))) == 0) {
+                       printf("pstat: out of memory\n");
+                       return;
+               }
        }
        }
-       printf("32 pty lines\n");
-       lseek(fc, (long)nl[SPTY].n_value, 0);
-       read(fc, dz_tty, 32*sizeof(struct tty));
-       for (tp = dz_tty; tp < &dz_tty[32]; tp++)
-               ttyprt(tp, tp - dz_tty);
+       lseek(fc, (long)nl[type].n_value, 0);
+       read(fc, tty, ntty * sizeof(struct tty));
+       printf(mesg);
+       for (tp = tty; tp < &tty[ntty]; tp++)
+               ttyprt(tp, tp - tty);
 }
 
 ttyprt(atp, line)
 }
 
 ttyprt(atp, line)
@@ -444,44 +531,53 @@ struct tty *atp;
 */
 
        default:
 */
 
        default:
-               printf("%4d", tp->t_rawq.c_cc);
-               printf("%4d", tp->t_canq.c_cc);
-       }
-       printf("%4d", tp->t_outq.c_cc);
-       printf("%8.1x", tp->t_flags);
-       printf(" %8.1x", tp->t_addr);
-       printf("%3d", tp->t_delct);
-       printf("%4d ", tp->t_col);
+               printf("%4d%4d", tp->t_rawq.c_cc, tp->t_canq.c_cc);
+       }
+       printf("%4d %8x %8x%4d%4d", tp->t_outq.c_cc, tp->t_flags,
+               tp->t_addr, tp->t_delct, tp->t_col);
        putf(tp->t_state&TS_TIMEOUT, 'T');
        putf(tp->t_state&TS_WOPEN, 'W');
        putf(tp->t_state&TS_ISOPEN, 'O');
        putf(tp->t_state&TS_TIMEOUT, 'T');
        putf(tp->t_state&TS_WOPEN, 'W');
        putf(tp->t_state&TS_ISOPEN, 'O');
+       putf(tp->t_state&TS_FLUSH, 'F');
        putf(tp->t_state&TS_CARR_ON, 'C');
        putf(tp->t_state&TS_BUSY, 'B');
        putf(tp->t_state&TS_ASLEEP, 'A');
        putf(tp->t_state&TS_XCLUDE, 'X');
        putf(tp->t_state&TS_CARR_ON, 'C');
        putf(tp->t_state&TS_BUSY, 'B');
        putf(tp->t_state&TS_ASLEEP, 'A');
        putf(tp->t_state&TS_XCLUDE, 'X');
+       putf(tp->t_state&TS_TTSTOP, 'S');
        putf(tp->t_state&TS_HUPCLS, 'H');
        printf("%6d", tp->t_pgrp);
        switch (tp->t_line) {
 
        putf(tp->t_state&TS_HUPCLS, 'H');
        printf("%6d", tp->t_pgrp);
        switch (tp->t_line) {
 
+       case OTTYDISC:
+               printf("\n");
+               break;
+
        case NTTYDISC:
        case NTTYDISC:
-               printf(" ntty");
+               printf(" ntty\n");
                break;
 
        case NETLDISC:
                break;
 
        case NETLDISC:
-               printf(" net");
+               printf(" berknet\n");
                break;
                break;
+
+       case TABLDISC:
+               printf(" tab\n");
+               break;
+
+       default:
+               printf(" %d\n", tp->t_line);
        }
        }
-       printf("\n");
 }
 
 dousr()
 {
        struct user U;
        register i, j, *ip;
 }
 
 dousr()
 {
        struct user U;
        register i, j, *ip;
+       register struct nameidata *nd = &U.u_nd;
 
 
-       /* This wins only if PAGSIZ > sizeof (struct user) */
-       lseek(fc, ubase * NBPG, 0);
-       read(fc, &U, sizeof(U));
+       /* This wins only if CLBYTES >= sizeof (struct user) */
+       lseek(fm, ubase * NBPG, 0);
+       read(fm, &U, sizeof(U));
        printf("pcb");
        ip = (int *)&U.u_pcb;
        while (ip < &U.u_arg[0]) {
        printf("pcb");
        ip = (int *)&U.u_pcb;
        while (ip < &U.u_arg[0]) {
@@ -493,44 +589,47 @@ dousr()
        }
        if ((ip - (int *)&U.u_pcb) % 4 != 0)
                printf("\n");
        }
        if ((ip - (int *)&U.u_pcb) % 4 != 0)
                printf("\n");
-       printf("arg\t");
-       for (i=0; i<5; i++)
-               printf(" %.1x", U.u_arg[i]);
-       printf("\n");
-       for (i=0; i<sizeof(label_t)/sizeof(int); i++) {
+       printf("arg");
+       for (i=0; i<sizeof(U.u_arg)/sizeof(U.u_arg[0]); i++) {
                if (i%5==0)
                        printf("\t");
                if (i%5==0)
                        printf("\t");
-               printf("%9.1x", U.u_ssave.val[i]);
+               printf(" %.1x", U.u_arg[i]);
                if (i%5==4)
                        printf("\n");
        }
        if (i%5)
                printf("\n");
                if (i%5==4)
                        printf("\n");
        }
        if (i%5)
                printf("\n");
-       printf("segflg\t%d\nerror %d\n", U.u_segflg, U.u_error);
+       printf("segflg\t%d\nerror %d\n", nd->ni_segflg, U.u_error);
        printf("uids\t%d,%d,%d,%d\n", U.u_uid,U.u_gid,U.u_ruid,U.u_rgid);
        printf("procp\t%.1x\n", U.u_procp);
        printf("ap\t%.1x\n", U.u_ap);
        printf("r_val?\t%.1x %.1x\n", U.u_r.r_val1, U.u_r.r_val2);
        printf("uids\t%d,%d,%d,%d\n", U.u_uid,U.u_gid,U.u_ruid,U.u_rgid);
        printf("procp\t%.1x\n", U.u_procp);
        printf("ap\t%.1x\n", U.u_ap);
        printf("r_val?\t%.1x %.1x\n", U.u_r.r_val1, U.u_r.r_val2);
-       printf("base, count, offset %.1x %.1x %ld\n", U.u_base,
-               U.u_count, U.u_offset);
+       printf("base, count, offset %.1x %.1x %ld\n", nd->ni_base,
+               nd->ni_count, nd->ni_offset);
        printf("cdir rdir %.1x %.1x\n", U.u_cdir, U.u_rdir);
        printf("cdir rdir %.1x %.1x\n", U.u_cdir, U.u_rdir);
-       printf("dirp %.1x\n", U.u_dirp);
-       printf("dent %d %.14s\n", U.u_dent.d_ino, U.u_dent.d_name);
-       printf("pdir %.1o\n", U.u_pdir);
-       printf("file\t");
-       for (i=0; i<10; i++)
-               printf("%9.1x", U.u_ofile[i]);
-       printf("\n\t");
-       for (i=10; i<NOFILE; i++)
+       printf("dirp %.1x\n", nd->ni_dirp);
+       printf("dent %d %.14s\n", nd->ni_dent.d_ino, nd->ni_dent.d_name);
+       printf("pdir %.1o\n", nd->ni_pdir);
+       printf("file");
+       for (i=0; i<NOFILE; i++) {
+               if (i % 8 == 0)
+                       printf("\t");
                printf("%9.1x", U.u_ofile[i]);
                printf("%9.1x", U.u_ofile[i]);
-       printf("\n");
-       printf("pofile\t");
-       for (i=0; i<10; i++)
-               printf("%9.1x", U.u_pofile[i]);
-       printf("\n\t");
-       for (i=10; i<NOFILE; i++)
+               if (i % 8 == 7)
+                       printf("\n");
+       }
+       if (i % 8)
+               printf("\n");
+       printf("pofile");
+       for (i=0; i<NOFILE; i++) {
+               if (i % 8 == 0)
+                       printf("\t");
                printf("%9.1x", U.u_pofile[i]);
                printf("%9.1x", U.u_pofile[i]);
-       printf("\n");
+               if (i % 8 == 7)
+                       printf("\n");
+       }
+       if (i % 8)
+               printf("\n");
        printf("ssave");
        for (i=0; i<sizeof(label_t)/sizeof(int); i++) {
                if (i%5==0)
        printf("ssave");
        for (i=0; i<sizeof(label_t)/sizeof(int); i++) {
                if (i%5==0)
@@ -541,10 +640,16 @@ dousr()
        }
        if (i%5)
                printf("\n");
        }
        if (i%5)
                printf("\n");
-       printf("sigs\t");
-       for (i=0; i<NSIG; i++)
+       printf("sigs");
+       for (i=0; i<NSIG; i++) {
+               if (i % 8 == 0)
+                       printf("\t");
                printf("%.1x ", U.u_signal[i]);
                printf("%.1x ", U.u_signal[i]);
-       printf("\n");
+               if (i % 8 == 7)
+                       printf("\n");
+       }
+       if (i % 8)
+               printf("\n");
        printf("code\t%.1x\n", U.u_code);
        printf("ar0\t%.1x\n", U.u_ar0);
        printf("prof\t%X %X %X %X\n", U.u_prof.pr_base, U.u_prof.pr_size,
        printf("code\t%.1x\n", U.u_code);
        printf("ar0\t%.1x\n", U.u_ar0);
        printf("prof\t%X %X %X %X\n", U.u_prof.pr_base, U.u_prof.pr_size,
@@ -552,11 +657,6 @@ dousr()
        printf("\neosys\t%d\n", U.u_eosys);
        printf("ttyp\t%.1x\n", U.u_ttyp);
        printf("ttyd\t%d,%d\n", major(U.u_ttyd), minor(U.u_ttyd));
        printf("\neosys\t%d\n", U.u_eosys);
        printf("ttyp\t%.1x\n", U.u_ttyp);
        printf("ttyd\t%d,%d\n", major(U.u_ttyd), minor(U.u_ttyd));
-       printf("exdata\t");
-       ip = (int *)&U.u_exdata;
-       for (i = 0; i < 8; i++)
-               printf("%.1D ", *ip++);
-       printf("\n");
        printf("comm %.14s\n", U.u_comm);
        printf("start\t%D\n", U.u_start);
        printf("acflag\t%D\n", U.u_acflag);
        printf("comm %.14s\n", U.u_comm);
        printf("start\t%D\n", U.u_start);
        printf("acflag\t%D\n", U.u_acflag);
@@ -608,7 +708,17 @@ dofile()
        nf = 0;
        nfile = getw(nl[SNFILE].n_value);
        xfile = (struct file *)calloc(nfile, sizeof (struct file));
        nf = 0;
        nfile = getw(nl[SNFILE].n_value);
        xfile = (struct file *)calloc(nfile, sizeof (struct file));
-       lseek(fc, (int)(afile = (struct file *)getw(nl[SFIL].n_value)), 0);
+       afile = (struct file *)getw(nl[SFIL].n_value);
+       if (nfile < 0 || nfile > 10000) {
+               fprintf(stderr, "number of files is preposterous (%d)\n",
+                       nfile);
+               return;
+       }
+       if (xfile == NULL) {
+               fprintf(stderr, "can't allocate memory for file table\n");
+               return;
+       }
+       lseek(fc, mkphys((off_t)afile), 0);
        read(fc, xfile, nfile * sizeof (struct file));
        for (fp=xfile; fp < &xfile[nfile]; fp++)
                if (fp->f_count)
        read(fc, xfile, nfile * sizeof (struct file));
        for (fp=xfile; fp < &xfile[nfile]; fp++)
                if (fp->f_count)
@@ -641,6 +751,7 @@ dofile()
                else
                        printf("  %ld\n", fp->f_offset);
        }
                else
                        printf("  %ld\n", fp->f_offset);
        }
+       free(xfile);
 }
 
 int dmmin, dmmax, nswdev;
 }
 
 int dmmin, dmmax, nswdev;
@@ -662,20 +773,41 @@ doswap()
        int i, j;
 
        nproc = getw(nl[SNPROC].n_value);
        int i, j;
 
        nproc = getw(nl[SNPROC].n_value);
-       proc = (struct proc *)calloc(nproc, sizeof (struct proc));
        ntext = getw(nl[SNTEXT].n_value);
        ntext = getw(nl[SNTEXT].n_value);
+       if (nproc < 0 || nproc > 10000 || ntext < 0 || ntext > 10000) {
+               fprintf(stderr, "number of procs/texts is preposterous (%d, %d)\n",
+                       nproc, ntext);
+               return;
+       }
+       proc = (struct proc *)calloc(nproc, sizeof (struct proc));
+       if (proc == NULL) {
+               fprintf(stderr, "can't allocate memory for proc table\n");
+               exit(1);
+       }
        xtext = (struct text *)calloc(ntext, sizeof (struct text));
        xtext = (struct text *)calloc(ntext, sizeof (struct text));
+       if (xtext == NULL) {
+               fprintf(stderr, "can't allocate memory for text table\n");
+               exit(1);
+       }
        nswapmap = getw(nl[SNSWAPMAP].n_value);
        swapmap = (struct map *)calloc(nswapmap, sizeof (struct map));
        nswapmap = getw(nl[SNSWAPMAP].n_value);
        swapmap = (struct map *)calloc(nswapmap, sizeof (struct map));
+       if (swapmap == NULL) {
+               fprintf(stderr, "can't allocate memory for swapmap\n");
+               exit(1);
+       }
        nswdev = getw(nl[SNSWDEV].n_value);
        swdevt = (struct swdevt *)calloc(nswdev, sizeof (struct swdevt));
        nswdev = getw(nl[SNSWDEV].n_value);
        swdevt = (struct swdevt *)calloc(nswdev, sizeof (struct swdevt));
-       lseek(fc, nl[SSWDEVT].n_value, L_SET);
+       if (swdevt == NULL) {
+               fprintf(stderr, "can't allocate memory for swdevt table\n");
+               exit(1);
+       }
+       lseek(fc, mkphys((off_t)nl[SSWDEVT].n_value), L_SET);
        read(fc, swdevt, nswdev * sizeof (struct swdevt));
        read(fc, swdevt, nswdev * sizeof (struct swdevt));
-       lseek(fc, getw(nl[SPROC].n_value), 0);
+       lseek(fc, mkphys((off_t)getw(nl[SPROC].n_value)), 0);
        read(fc, proc, nproc * sizeof (struct proc));
        read(fc, proc, nproc * sizeof (struct proc));
-       lseek(fc, getw(nl[STEXT].n_value), 0);
+       lseek(fc, mkphys((off_t)getw(nl[STEXT].n_value)), 0);
        read(fc, xtext, ntext * sizeof (struct text));
        read(fc, xtext, ntext * sizeof (struct text));
-       lseek(fc, getw(nl[SWAPMAP].n_value), 0);
+       lseek(fc, mkphys((off_t)getw(nl[SWAPMAP].n_value)), 0);
        read(fc, swapmap, nswapmap * sizeof (struct map));
        swapmap->m_name = "swap";
        swapmap->m_limit = (struct mapent *)&swapmap[nswapmap];
        read(fc, swapmap, nswapmap * sizeof (struct map));
        swapmap->m_name = "swap";
        swapmap->m_limit = (struct mapent *)&swapmap[nswapmap];
@@ -683,7 +815,8 @@ doswap()
        dmmax = getw(nl[SDMMAX].n_value);
        nswap = 0;
        for (sw = swdevt; sw < &swdevt[nswdev]; sw++)
        dmmax = getw(nl[SDMMAX].n_value);
        nswap = 0;
        for (sw = swdevt; sw < &swdevt[nswdev]; sw++)
-               nswap += sw->sw_nblks,
+               if (sw->sw_freed)
+                       nswap += sw->sw_nblks;
        free = 0;
        for (me = (struct mapent *)(swapmap+1);
            me < (struct mapent *)&swapmap[nswapmap]; me++)
        free = 0;
        for (me = (struct mapent *)(swapmap+1);
            me < (struct mapent *)&swapmap[nswapmap]; me++)
@@ -691,9 +824,9 @@ doswap()
        tused = 0;
        for (xp = xtext; xp < &xtext[ntext]; xp++)
                if (xp->x_iptr!=NULL) {
        tused = 0;
        for (xp = xtext; xp < &xtext[ntext]; xp++)
                if (xp->x_iptr!=NULL) {
-                       tused += ctod(xp->x_size);
+                       tused += ctod(clrnd(xp->x_size));
                        if (xp->x_flag & XPAGI)
                        if (xp->x_flag & XPAGI)
-                               tused += ctod(ctopt(xp->x_size));
+                               tused += ctod(clrnd(ctopt(xp->x_size)));
                }
        used = tused;
        waste = 0;
                }
        used = tused;
        waste = 0;
@@ -709,7 +842,7 @@ doswap()
                used += sb;
                waste += sb - db;
                if ((pp->p_flag&SLOAD) == 0)
                used += sb;
                waste += sb - db;
                if ((pp->p_flag&SLOAD) == 0)
-                       used += vusize(pp);
+                       used += ctod(vusize(pp));
        }
        if (totflg) {
 #define        btok(x) ((x) / (1024 / DEV_BSIZE))
        }
        if (totflg) {
 #define        btok(x) ((x) / (1024 / DEV_BSIZE))
@@ -942,3 +1075,27 @@ done:
 badrmfree:
        printf("bad rmfree\n");
 }
 badrmfree:
        printf("bad rmfree\n");
 }
+/*
+ * "addr"  is a kern virt addr and does not correspond
+ * To a phys addr after zipping out the high bit..
+ * since it was valloc'd in the kernel.
+ *
+ * We return the phys addr by simulating kernel vm (/dev/kmem)
+ * when we are reading a crash dump.
+ */
+off_t
+mkphys(addr)
+       off_t addr;
+{
+       register off_t o;
+
+       if (!kflg)
+               return(addr);
+       o = addr & PGOFSET;
+       addr >>= PGSHIFT;
+       addr &= PG_PFNUM;
+       addr *=  NBPW;
+       addr = getw(nl[SYSMAP].n_value + addr);
+       addr = ((addr & PG_PFNUM) << PGSHIFT) | o;
+       return(addr);
+}