date and time created 92/02/29 12:43:13 by bostic
[unix-history] / usr / src / lib / libkvm / kvm_proc.c
index 3e1a88d..79f5420 100644 (file)
@@ -1,48 +1,52 @@
-/*
+/*-
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms is permitted
- * provided that all copyright information, including this notice,
- * is retained in all such forms, and that any documentation,
- * advertising or other materials related to such distribution and
- * use acknowledge that the software was
- * developed by the University of California, Berkeley.  The name
- * of the University may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * %sccs.include.redist.c%
  */
 
  */
 
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm_proc.c 5.21 (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
 
 
-#include <machine/pte.h>
 #include <sys/param.h>
 #include <sys/user.h>
 #include <sys/proc.h>
 #include <sys/param.h>
 #include <sys/user.h>
 #include <sys/proc.h>
-#include <sys/file.h>
-#include <sys/text.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/vmmac.h>
 #include <sys/ioctl.h>
 #include <sys/ioctl.h>
+#include <sys/kinfo.h>
 #include <sys/tty.h>
 #include <sys/tty.h>
-#include <kvm.h>
-#include <ctype.h>
-#include <vis.h>
+#include <machine/vmparam.h>
+#include <fcntl.h>
 #include <nlist.h>
 #include <nlist.h>
-#include <pwd.h>
-#include <string.h>
+#include <kvm.h>
 #include <ndbm.h>
 #include <limits.h>
 #include <paths.h>
 #include <stdio.h>
 #include <ndbm.h>
 #include <limits.h>
 #include <paths.h>
 #include <stdio.h>
+#include <string.h>
+
+#ifdef SPPWAIT
+#define NEWVM
+#endif
+
+#ifdef NEWVM
+#define        btop(x)         (((unsigned)(x)) >> PGSHIFT)    /* XXX */
+#define        ptob(x)         ((caddr_t)((x) << PGSHIFT))     /* XXX */
+#include <vm/vm.h>     /* ??? kinfo_proc currently includes this*/
+#include <sys/kinfo_proc.h>
+#ifdef hp300
+#include <hp300/hp300/pte.h>
+#endif
+#else /* NEWVM */
+#include <machine/pte.h>
+#include <sys/vmmac.h>
+#include <sys/text.h>
+#endif /* NEWVM */
 
 /*
  * files
  */
 
 /*
  * files
  */
-static char *unixf, *memf, *kmemf, *swapf;
+static const char *unixf, *memf, *kmemf, *swapf;
 static int unixx, mem, kmem, swap;
 static DBM *db;
 /*
 static int unixx, mem, kmem, swap;
 static DBM *db;
 /*
@@ -66,48 +70,68 @@ static union {
 /*
  * random other stuff
  */
 /*
  * random other stuff
  */
+#ifndef NEWVM
 static struct pte *Usrptmap, *usrpt;
 static struct pte *Usrptmap, *usrpt;
-static int     dmmin, dmmax;
 static struct  pte *Sysmap;
 static int     Syssize;
 static struct  pte *Sysmap;
 static int     Syssize;
-static int     pcbpf;
-static int     argaddr0;       /* XXX */
-static int     argaddr1;
+#endif
+static int     dmmin, dmmax;
+static int     pcbpf;
+static int     argaddr0;       /* XXX */
+static int     argaddr1;
 static int     nswap;
 static char    *tmp;
 static int     nswap;
 static char    *tmp;
+#if defined(hp300)
+static int     lowram;
+static struct ste *Sysseg;
+#endif
 
 #define basename(cp)   ((tmp=rindex((cp), '/')) ? tmp+1 : (cp))
 #define        MAXSYMSIZE      256
 
 
 #define basename(cp)   ((tmp=rindex((cp), '/')) ? tmp+1 : (cp))
 #define        MAXSYMSIZE      256
 
+#if defined(hp300)
+#define pftoc(f)       ((f) - lowram)
+#define iskva(v)       (1)
+#endif
+
+#ifndef pftoc
+#define pftoc(f)       (f)
+#endif
+#ifndef iskva
+#define iskva(v)       ((u_long)(v) & KERNBASE)
+#endif
+
 static struct nlist nl[] = {
 static struct nlist nl[] = {
-       { "_Usrptmap" },
-#define        X_USRPTMAP      0
-       { "_usrpt" },
-#define        X_USRPT         1
        { "_nswap" },
        { "_nswap" },
-#define        X_NSWAP         2
+#define        X_NSWAP         0
        { "_dmmin" },
        { "_dmmin" },
-#define        X_DMMIN         3
+#define        X_DMMIN         X_NSWAP+1
        { "_dmmax" },
        { "_dmmax" },
-#define        X_DMMAX         4
+#define        X_DMMAX         X_DMMIN+1
        /*
         * everything here and down, only if a dead kernel
         */
        { "_Sysmap" },
        /*
         * everything here and down, only if a dead kernel
         */
        { "_Sysmap" },
-#define        X_SYSMAP        5
-#define        X_DEADKERNEL    X_SYSMAP        
-       { "_Syssize" },
-#define        X_SYSSIZE       6
+#define        X_SYSMAP        X_DMMAX+1
+#define        X_DEADKERNEL    X_SYSMAP
        { "_allproc" },
        { "_allproc" },
-#define X_ALLPROC      7
+#define X_ALLPROC      X_SYSMAP+1
        { "_zombproc" },
        { "_zombproc" },
-#define X_ZOMBPROC     8
-       { "_nproc" },
-#define        X_NPROC         9
+#define X_ZOMBPROC     X_ALLPROC+1
+       { "_nprocs" },
+#define        X_NPROCS        X_ZOMBPROC+1
+#if defined(hp300)
+       { "_Sysseg" },
+#define        X_SYSSEG        (X_NPROCS+1)
+       { "_lowram" },
+#define        X_LOWRAM        (X_SYSSEG+1)
+#endif
        { "" },
 };
 
        { "" },
 };
 
-static char *savestr();
+static off_t vtophys();
+static void seterr(), setsyserr(), vstodb();
+static int getkvars(), kvm_doprocs(), kvm_init(), klseek();
 
 /*
  * returns     0 if files were opened now,
 
 /*
  * returns     0 if files were opened now,
@@ -115,7 +139,7 @@ static char *savestr();
  *             -1 if files could not be opened.
  */
 kvm_openfiles(uf, mf, sf)
  *             -1 if files could not be opened.
  */
 kvm_openfiles(uf, mf, sf)
-       char *uf, *mf, *sf; 
+       const char *uf, *mf, *sf; 
 {
        if (kvmfilesopen)
                return (1);
 {
        if (kvmfilesopen)
                return (1);
@@ -156,6 +180,8 @@ kvm_openfiles(uf, mf, sf)
                goto failed;
        }
        kvmfilesopen++;
                goto failed;
        }
        kvmfilesopen++;
+       if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1) /*XXX*/
+               return (-1);
        return (0);
 failed:
        kvm_close();
        return (0);
 failed:
        kvm_close();
@@ -202,10 +228,12 @@ kvm_close()
        kvminit = 0;
        kvmfilesopen = 0;
        deadkernel = 0;
        kvminit = 0;
        kvmfilesopen = 0;
        deadkernel = 0;
+#ifndef NEWVM
        if (Sysmap) {
                free(Sysmap);
                Sysmap = NULL;
        }
        if (Sysmap) {
                free(Sysmap);
                Sysmap = NULL;
        }
+#endif
 }
 
 kvm_nlist(nl)
 }
 
 kvm_nlist(nl)
@@ -213,10 +241,10 @@ kvm_nlist(nl)
 {
        datum key, data;
        char dbname[MAXPATHLEN];
 {
        datum key, data;
        char dbname[MAXPATHLEN];
-       char dbversion[LINE_MAX];
-       char kversion[LINE_MAX];
+       char dbversion[_POSIX2_LINE_MAX];
+       char kversion[_POSIX2_LINE_MAX];
        int dbversionlen;
        int dbversionlen;
-       char symbuf[MAXSYMSIZE+1];
+       char symbuf[MAXSYMSIZE];
        struct nlist nbuf, *n;
        int num, did;
 
        struct nlist nbuf, *n;
        int num, did;
 
@@ -228,20 +256,19 @@ kvm_nlist(nl)
         * initialize key datum
         */
        key.dptr = symbuf;
         * initialize key datum
         */
        key.dptr = symbuf;
-       symbuf[0] = KVMDB_NLIST;
 
        if (db != NULL)
                goto win;       /* off to the races */
        /*
         * open database
         */
 
        if (db != NULL)
                goto win;       /* off to the races */
        /*
         * open database
         */
-       sprintf(dbname, "%s/kvm_%s", KVMDBDIR, basename(unixf));
+       sprintf(dbname, "%s/kvm_%s", _PATH_VARRUN, basename(unixf));
        if ((db = dbm_open(dbname, O_RDONLY, 0)) == NULL)
                goto hard2;
        /*
         * read version out of database
         */
        if ((db = dbm_open(dbname, O_RDONLY, 0)) == NULL)
                goto hard2;
        /*
         * read version out of database
         */
-       bcopy("VERSION", symbuf+1, sizeof ("VERSION")-1);
+       bcopy("VERSION", symbuf, sizeof ("VERSION")-1);
        key.dsize = (sizeof ("VERSION") - 1) + 1;
        data = dbm_fetch(db, key);
        if (data.dptr == NULL)
        key.dsize = (sizeof ("VERSION") - 1) + 1;
        data = dbm_fetch(db, key);
        if (data.dptr == NULL)
@@ -251,7 +278,7 @@ kvm_nlist(nl)
        /*
         * read version string from kernel memory
         */
        /*
         * read version string from kernel memory
         */
-       bcopy("_version", symbuf+1, sizeof ("_version")-1);
+       bcopy("_version", symbuf, sizeof ("_version")-1);
        key.dsize = (sizeof ("_version")-1) + 1;
        data = dbm_fetch(db, key);
        if (data.dptr == NULL)
        key.dsize = (sizeof ("_version")-1) + 1;
        data = dbm_fetch(db, key);
        if (data.dptr == NULL)
@@ -285,10 +312,10 @@ win:
                 * query db
                 */
                if ((len = strlen(n->n_name)) > MAXSYMSIZE) {
                 * query db
                 */
                if ((len = strlen(n->n_name)) > MAXSYMSIZE) {
-                       seterr("kvm_nlist: symbol too large");
+                       seterr("symbol too large");
                        return (-1);
                }
                        return (-1);
                }
-               strcpy(symbuf+1, n->n_name);
+               (void)strcpy(symbuf, n->n_name);
                key.dsize = len + 1;
                data = dbm_fetch(db, key);
                if (data.dptr == NULL || data.dsize != sizeof (struct nlist))
                key.dsize = len + 1;
                data = dbm_fetch(db, key);
                if (data.dptr == NULL || data.dsize != sizeof (struct nlist))
@@ -305,10 +332,14 @@ hard1:
        dbm_close(db);
        db = NULL;
 hard2:
        dbm_close(db);
        db = NULL;
 hard2:
-       return (nlist(unixf, nl));      /* XXX seterr if -1 */
+       num = nlist(unixf, nl);
+       if (num == -1)
+               seterr("nlist (hard way) failed");
+       return (num);
 }
 
 kvm_getprocs(what, arg)
 }
 
 kvm_getprocs(what, arg)
+       int what, arg;
 {
        if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1)
                return (NULL);
 {
        if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1)
                return (NULL);
@@ -331,23 +362,23 @@ kvm_getprocs(what, arg)
                        return (-1);
                }
                if (copysize % sizeof (struct kinfo_proc)) {
                        return (-1);
                }
                if (copysize % sizeof (struct kinfo_proc)) {
-                       seterr("proc size mismatch (kinfo_proc: %d)",
-                               sizeof (struct kinfo_proc));
+                       seterr("proc size mismatch (got %d total, kinfo_proc: %d)",
+                               copysize, sizeof (struct kinfo_proc));
                        return (-1);
                }
                kvmnprocs = copysize / sizeof (struct kinfo_proc);
        } else {
                        return (-1);
                }
                kvmnprocs = copysize / sizeof (struct kinfo_proc);
        } else {
-               int nproc;
+               int nprocs;
 
 
-               if (kvm_read(nl[X_NPROC].n_value, &nproc, sizeof (int)) !=
-                   sizeof (int)) {
+               if (kvm_read((void *)nl[X_NPROCS].n_value, &nprocs,
+                   sizeof (int)) != sizeof (int)) {
                        seterr("can't read nproc");
                        return (-1);
                }
                if ((kvmprocbase = (struct kinfo_proc *)
                        seterr("can't read nproc");
                        return (-1);
                }
                if ((kvmprocbase = (struct kinfo_proc *)
-                    malloc(nproc * sizeof (struct kinfo_proc))) == NULL) {
-                       seterr("out of memory (addr: %x nproc = %d)",
-                               nl[X_NPROC].n_value, nproc);
+                    malloc(nprocs * sizeof (struct kinfo_proc))) == NULL) {
+                       seterr("out of memory (addr: %x nprocs = %d)",
+                               nl[X_NPROCS].n_value, nprocs);
                        return (-1);
                }
                kvmnprocs = kvm_doprocs(what, arg, kvmprocbase);
                        return (-1);
                }
                kvmnprocs = kvm_doprocs(what, arg, kvmprocbase);
@@ -377,10 +408,12 @@ kvm_doprocs(what, arg, buff)
        struct pgrp pgrp;
        struct session sess;
        struct tty tty;
        struct pgrp pgrp;
        struct session sess;
        struct tty tty;
+#ifndef NEWVM
        struct text text;
        struct text text;
+#endif
 
        /* allproc */
 
        /* allproc */
-       if (kvm_read(nl[X_ALLPROC].n_value, &p, 
+       if (kvm_read((void *) nl[X_ALLPROC].n_value, &p, 
            sizeof (struct proc *)) != sizeof (struct proc *)) {
                seterr("can't read allproc");
                return (-1);
            sizeof (struct proc *)) != sizeof (struct proc *)) {
                seterr("can't read allproc");
                return (-1);
@@ -393,6 +426,30 @@ again:
                        seterr("can't read proc at %x", p);
                        return (-1);
                }
                        seterr("can't read proc at %x", p);
                        return (-1);
                }
+#ifdef NEWVM
+               if (kvm_read(proc.p_cred, &eproc.e_pcred,
+                   sizeof (struct pcred)) == sizeof (struct pcred))
+                       (void) kvm_read(eproc.e_pcred.pc_ucred, &eproc.e_ucred,
+                           sizeof (struct ucred));
+               switch(ki_op(what)) {
+                       
+               case KINFO_PROC_PID:
+                       if (proc.p_pid != (pid_t)arg)
+                               continue;
+                       break;
+
+
+               case KINFO_PROC_UID:
+                       if (eproc.e_ucred.cr_uid != (uid_t)arg)
+                               continue;
+                       break;
+
+               case KINFO_PROC_RUID:
+                       if (eproc.e_pcred.p_ruid != (uid_t)arg)
+                               continue;
+                       break;
+               }
+#else
                switch(ki_op(what)) {
                        
                case KINFO_PROC_PID:
                switch(ki_op(what)) {
                        
                case KINFO_PROC_PID:
@@ -411,6 +468,7 @@ again:
                                continue;
                        break;
                }
                                continue;
                        break;
                }
+#endif
                /*
                 * gather eproc
                 */
                /*
                 * gather eproc
                 */
@@ -448,8 +506,17 @@ again:
                                eproc.e_tpgid = -1;
                } else
                        eproc.e_tdev = NODEV;
                                eproc.e_tpgid = -1;
                } else
                        eproc.e_tdev = NODEV;
+               eproc.e_flag = sess.s_ttyvp ? EPROC_CTTY : 0;
+               if (sess.s_leader == p)
+                       eproc.e_flag |= EPROC_SLEADER;
                if (proc.p_wmesg)
                        kvm_read(proc.p_wmesg, eproc.e_wmesg, WMESGLEN);
                if (proc.p_wmesg)
                        kvm_read(proc.p_wmesg, eproc.e_wmesg, WMESGLEN);
+#ifdef NEWVM
+               (void) kvm_read(proc.p_vmspace, &eproc.e_vm,
+                   sizeof (struct vmspace));
+               eproc.e_xsize = eproc.e_xrssize =
+                       eproc.e_xccount = eproc.e_xswrss = 0;
+#else
                if (proc.p_textp) {
                        kvm_read(proc.p_textp, &text, sizeof (text));
                        eproc.e_xsize = text.x_size;
                if (proc.p_textp) {
                        kvm_read(proc.p_textp, &text, sizeof (text));
                        eproc.e_xsize = text.x_size;
@@ -460,6 +527,7 @@ again:
                        eproc.e_xsize = eproc.e_xrssize =
                          eproc.e_xccount = eproc.e_xswrss = 0;
                }
                        eproc.e_xsize = eproc.e_xrssize =
                          eproc.e_xccount = eproc.e_xswrss = 0;
                }
+#endif
 
                switch(ki_op(what)) {
 
 
                switch(ki_op(what)) {
 
@@ -483,7 +551,7 @@ again:
        }
        if (!doingzomb) {
                /* zombproc */
        }
        if (!doingzomb) {
                /* zombproc */
-               if (kvm_read(nl[X_ZOMBPROC].n_value, &p, 
+               if (kvm_read((void *) nl[X_ZOMBPROC].n_value, &p, 
                    sizeof (struct proc *)) != sizeof (struct proc *)) {
                        seterr("can't read zombproc");
                        return (-1);
                    sizeof (struct proc *)) != sizeof (struct proc *)) {
                        seterr("can't read zombproc");
                        return (-1);
@@ -494,7 +562,6 @@ again:
 
        return (i);
 }
 
        return (i);
 }
-       
 
 struct proc *
 kvm_nextproc()
 
 struct proc *
 kvm_nextproc()
@@ -511,14 +578,13 @@ kvm_nextproc()
 
 struct eproc *
 kvm_geteproc(p)
 
 struct eproc *
 kvm_geteproc(p)
-       struct proc *p;
+       const struct proc *p;
 {
        return ((struct eproc *)(((char *)p) + sizeof (struct proc)));
 }
 
 kvm_setproc()
 {
 {
        return ((struct eproc *)(((char *)p) + sizeof (struct proc)));
 }
 
 kvm_setproc()
 {
-
        kvmprocptr = kvmprocbase;
 }
 
        kvmprocptr = kvmprocbase;
 }
 
@@ -531,12 +597,67 @@ kvm_freeprocs()
        }
 }
 
        }
 }
 
+#ifdef NEWVM
 struct user *
 kvm_getu(p)
 struct user *
 kvm_getu(p)
-       struct proc *p;
+       const struct proc *p;
+{
+       register struct kinfo_proc *kp = (struct kinfo_proc *)p;
+       register int i;
+       register char *up;
+
+       if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1)
+               return (NULL);
+       if (p->p_stat == SZOMB) {
+               seterr("zombie process");
+               return (NULL);
+       }
+       /*
+        * Read u-area one page at a time for the benefit of post-mortems
+        */
+       up = (char *) p->p_addr;
+       for (i = 0; i < UPAGES; i++) {
+               if (klseek(kmem, (long)up, 0) == -1)
+                       return (NULL);
+               if (read(kmem, user.upages[i], CLBYTES) != CLBYTES) {
+                       seterr("cant read page %x of u of pid %d from %s",
+                           up, p->p_pid, kmemf);
+                       return(NULL);
+               }
+               up += CLBYTES;
+       }
+       pcbpf = (int) btop(p->p_addr);  /* what should this be really? */
+       /*
+        * Conjure up a physical address for the arguments.
+        */
+       argaddr0 = argaddr1 = 0;
+#ifdef hp300
+       if (kp->kp_eproc.e_vm.vm_pmap.pm_ptab) {
+               struct pte pte[CLSIZE*2];
+
+               if (klseek(kmem,
+                   (long)&kp->kp_eproc.e_vm.vm_pmap.pm_ptab
+                   [btoc(USRSTACK-CLBYTES*2)], 0) == -1)
+                       return (NULL);
+               if (read(kmem, (char *)&pte, sizeof(pte)) == sizeof(pte)) {
+#if CLBYTES < 2048
+                       argaddr0 = ctob(pftoc(pte[CLSIZE*0].pg_pfnum));
+#endif
+                       argaddr1 = ctob(pftoc(pte[CLSIZE*1].pg_pfnum));
+               }
+       }
+       kp->kp_eproc.e_vm.vm_rssize =
+           kp->kp_eproc.e_vm.vm_pmap.pm_stats.resident_count; /* XXX */
+#endif
+       return(&user.user);
+}
+#else
+struct user *
+kvm_getu(p)
+       const struct proc *p;
 {
        struct pte *pteaddr, apte;
 {
        struct pte *pteaddr, apte;
-       struct pte arguutl[UPAGES+(CLSIZE*2)];
+       struct pte arguutl[HIGHPAGES+(CLSIZE*2)];
        register int i;
        int ncl;
 
        register int i;
        int ncl;
 
@@ -554,7 +675,7 @@ kvm_getu(p)
                (void) lseek(swap, (long)dtob(p->p_swaddr), 0);
                if (read(swap, (char *)&user.user, sizeof (struct user)) != 
                    sizeof (struct user)) {
                (void) lseek(swap, (long)dtob(p->p_swaddr), 0);
                if (read(swap, (char *)&user.user, sizeof (struct user)) != 
                    sizeof (struct user)) {
-                       seterr("can't read u for pid %d from %s\n",
+                       seterr("can't read u for pid %d from %s",
                            p->p_pid, swapf);
                        return (NULL);
                }
                            p->p_pid, swapf);
                        return (NULL);
                }
@@ -564,91 +685,100 @@ kvm_getu(p)
                return (&user.user);
        }
        pteaddr = &Usrptmap[btokmx(p->p_p0br) + p->p_szpt - 1];
                return (&user.user);
        }
        pteaddr = &Usrptmap[btokmx(p->p_p0br) + p->p_szpt - 1];
-       klseek(kmem, (long)pteaddr, 0);
+       if (klseek(kmem, (long)pteaddr, 0) == -1)
+               return -1;
        if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
                seterr("can't read indir pte to get u for pid %d from %s",
                    p->p_pid, kmemf);
                return (NULL);
        }
        if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
                seterr("can't read indir pte to get u for pid %d from %s",
                    p->p_pid, kmemf);
                return (NULL);
        }
-       lseek(mem,
-           (long)ctob(apte.pg_pfnum+1) - (UPAGES+(CLSIZE*2)) * sizeof (struct pte),
-               0);
+       lseek(mem, (long)ctob(pftoc(apte.pg_pfnum+1)) - sizeof(arguutl), 0);
        if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
                seterr("can't read page table for u of pid %d from %s",
                    p->p_pid, memf);
                return (NULL);
        }
        if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
        if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
                seterr("can't read page table for u of pid %d from %s",
                    p->p_pid, memf);
                return (NULL);
        }
        if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
-               argaddr0 = ctob(arguutl[0].pg_pfnum);
+               argaddr0 = ctob(pftoc(arguutl[0].pg_pfnum));
        else
                argaddr0 = 0;
        if (arguutl[CLSIZE*1].pg_fod == 0 && arguutl[CLSIZE*1].pg_pfnum)
        else
                argaddr0 = 0;
        if (arguutl[CLSIZE*1].pg_fod == 0 && arguutl[CLSIZE*1].pg_pfnum)
-               argaddr1 = ctob(arguutl[CLSIZE*1].pg_pfnum);
+               argaddr1 = ctob(pftoc(arguutl[CLSIZE*1].pg_pfnum));
        else
                argaddr1 = 0;
        pcbpf = arguutl[CLSIZE*2].pg_pfnum;
        else
                argaddr1 = 0;
        pcbpf = arguutl[CLSIZE*2].pg_pfnum;
-       ncl = (sizeof (struct user) + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
+       ncl = (sizeof (struct user) + CLBYTES - 1) / CLBYTES;
        while (--ncl >= 0) {
                i = ncl * CLSIZE;
        while (--ncl >= 0) {
                i = ncl * CLSIZE;
-               lseek(mem, (long)ctob(arguutl[(CLSIZE*2)+i].pg_pfnum), 0);
-               if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
+               lseek(mem,
+                     (long)ctob(pftoc(arguutl[(CLSIZE*2)+i].pg_pfnum)), 0);
+               if (read(mem, user.upages[i], CLBYTES) != CLBYTES) {
                        seterr("can't read page %d of u of pid %d from %s",
                        seterr("can't read page %d of u of pid %d from %s",
-                           arguutl[CLSIZE+i].pg_pfnum, p->p_pid, memf);
+                           arguutl[(CLSIZE*2)+i].pg_pfnum, p->p_pid, memf);
                        return(NULL);
                }
        }
        return (&user.user);
 }
                        return(NULL);
                }
        }
        return (&user.user);
 }
+#endif
 
 char *
 kvm_getargs(p, up)
 
 char *
 kvm_getargs(p, up)
-       struct proc *p;
-       struct user *up;
+       const struct proc *p;
+       const struct user *up;
 {
 {
-       char cmdbuf[CLSIZE*NBPG*2];
+       static char cmdbuf[CLBYTES*2];
        union {
        union {
-               char    argc[CLSIZE*NBPG*2];
-               int     argi[CLSIZE*NBPG*2/sizeof (int)];
+               char    argc[CLBYTES*2];
+               int     argi[CLBYTES*2/sizeof (int)];
        } argspac;
        register char *cp;
        register int *ip;
        char c;
        int nbad;
        } argspac;
        register char *cp;
        register int *ip;
        char c;
        int nbad;
+#ifndef NEWVM
        struct dblock db;
        struct dblock db;
-       char *file;
+#endif
+       const char *file;
+       int stkoff = 0;
 
 
+#if defined(NEWVM) && defined(hp300)
+       stkoff = 20;                    /* XXX for sigcode */
+#endif
        if (up == NULL || p->p_pid == 0 || p->p_pid == 2)
                goto retucomm;
        if ((p->p_flag & SLOAD) == 0 || argaddr1 == 0) {
        if (up == NULL || p->p_pid == 0 || p->p_pid == 2)
                goto retucomm;
        if ((p->p_flag & SLOAD) == 0 || argaddr1 == 0) {
-               if (swap < 0)
+#ifdef NEWVM
+               goto retucomm;  /* XXX for now */
+#else
+               if (swap < 0 || p->p_ssize == 0)
                        goto retucomm;
                vstodb(0, CLSIZE, &up->u_smap, &db, 1);
                (void) lseek(swap, (long)dtob(db.db_base), 0);
                        goto retucomm;
                vstodb(0, CLSIZE, &up->u_smap, &db, 1);
                (void) lseek(swap, (long)dtob(db.db_base), 0);
-               if (read(swap, (char *)&argspac.argc[NBPG*CLSIZE], 
-                       NBPG*CLSIZE) != NBPG*CLSIZE)
+               if (read(swap, (char *)&argspac.argc[CLBYTES], CLBYTES)
+                       != CLBYTES)
                        goto bad;
                vstodb(1, CLSIZE, &up->u_smap, &db, 1);
                (void) lseek(swap, (long)dtob(db.db_base), 0);
                        goto bad;
                vstodb(1, CLSIZE, &up->u_smap, &db, 1);
                (void) lseek(swap, (long)dtob(db.db_base), 0);
-               if (read(swap, (char *)&argspac.argc[0], 
-                       NBPG*CLSIZE) != NBPG*CLSIZE)
+               if (read(swap, (char *)&argspac.argc[0], CLBYTES) != CLBYTES)
                        goto bad;
                file = swapf;
                        goto bad;
                file = swapf;
+#endif
        } else {
                if (argaddr0) {
                        lseek(mem, (long)argaddr0, 0);
        } else {
                if (argaddr0) {
                        lseek(mem, (long)argaddr0, 0);
-                       if (read(mem, (char *)&argspac, NBPG*CLSIZE)
-                           != NBPG*CLSIZE)
+                       if (read(mem, (char *)&argspac, CLBYTES) != CLBYTES)
                                goto bad;
                } else
                                goto bad;
                } else
-                       bzero(&argspac, NBPG*CLSIZE);
+                       bzero(&argspac, CLBYTES);
                lseek(mem, (long)argaddr1, 0);
                lseek(mem, (long)argaddr1, 0);
-               if (read(mem, &argspac.argc[NBPG*CLSIZE], NBPG*CLSIZE)
-                   != NBPG*CLSIZE)
+               if (read(mem, &argspac.argc[CLBYTES], CLBYTES) != CLBYTES)
                        goto bad;
                        goto bad;
-               file = memf;
+               file = (char *) memf;
        }
        }
-       ip = &argspac.argi[CLSIZE*NBPG*2/sizeof (int)];
-       ip -= 2;                /* last arg word and .long 0 */
+       ip = &argspac.argi[CLBYTES*2/sizeof (int)];
+       ip -= 2;                /* last arg word and .long 0 */
+       ip -= stkoff / sizeof (int);
        while (*--ip) {
                if (ip == argspac.argi)
                        goto retucomm;
        while (*--ip) {
                if (ip == argspac.argi)
                        goto retucomm;
@@ -656,7 +786,7 @@ kvm_getargs(p, up)
        *(char *)ip = ' ';
        ip++;
        nbad = 0;
        *(char *)ip = ' ';
        ip++;
        nbad = 0;
-       for (cp = (char *)ip; cp < &argspac.argc[CLSIZE*NBPG*2]; cp++) {
+       for (cp = (char *)ip; cp < &argspac.argc[CLBYTES*2-stkoff]; cp++) {
                c = *cp & 0177;
                if (c == 0)
                        *cp = ' ';
                c = *cp & 0177;
                if (c == 0)
                        *cp = ' ';
@@ -677,7 +807,7 @@ kvm_getargs(p, up)
        while (*--cp == ' ')
                *cp = 0;
        cp = (char *)ip;
        while (*--cp == ' ')
                *cp = 0;
        cp = (char *)ip;
-       (void) strncpy(cmdbuf, cp, &argspac.argc[CLSIZE*NBPG*2] - cp);
+       (void) strncpy(cmdbuf, cp, &argspac.argc[CLBYTES*2] - cp);
        if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') {
                (void) strcat(cmdbuf, " (");
                (void) strncat(cmdbuf, p->p_comm, sizeof(p->p_comm));
        if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') {
                (void) strcat(cmdbuf, " (");
                (void) strncat(cmdbuf, p->p_comm, sizeof(p->p_comm));
@@ -686,7 +816,7 @@ kvm_getargs(p, up)
        return (cmdbuf);
 
 bad:
        return (cmdbuf);
 
 bad:
-       seterr("error locating command name for pid %d from %s\n",
+       seterr("error locating command name for pid %d from %s",
            p->p_pid, file);
 retucomm:
        (void) strcpy(cmdbuf, " (");
            p->p_pid, file);
 retucomm:
        (void) strcpy(cmdbuf, " (");
@@ -699,42 +829,51 @@ retucomm:
 static
 getkvars()
 {
 static
 getkvars()
 {
+       int ret;
+       static nlisterr();
 
 
-       if (kvm_nlist(nl) == -1)
+       if ((ret = kvm_nlist(nl)) == -1)
                return (-1);
                return (-1);
+       else if (ret > 0)
+               nlisterr(nl);
        if (deadkernel) {
                /* We must do the sys map first because klseek uses it */
                long    addr;
        if (deadkernel) {
                /* We must do the sys map first because klseek uses it */
                long    addr;
-
-               Syssize = nl[X_SYSSIZE].n_value;
-               Sysmap = (struct pte *)
-                       calloc((unsigned) Syssize, sizeof (struct pte));
-               if (Sysmap == NULL) {
-                       seterr("out of space for Sysmap");
+#if defined(hp300)
+               addr = (long) nl[X_LOWRAM].n_value;
+               (void) lseek(kmem, addr, 0);
+               if (read(kmem, (char *) &lowram, sizeof (lowram))
+                   != sizeof (lowram)) {
+                       seterr("can't read lowram");
+                       return (-1);
+               }
+               lowram = btop(lowram);
+               Sysseg = (struct ste *) malloc(NBPG);
+               if (Sysseg == NULL) {
+                       seterr("out of space for Sysseg");
                        return (-1);
                }
                        return (-1);
                }
-               addr = (long) nl[X_SYSMAP].n_value;
-               addr &= ~KERNBASE;
+               addr = (long) nl[X_SYSSEG].n_value;
                (void) lseek(kmem, addr, 0);
                (void) lseek(kmem, addr, 0);
-               if (read(kmem, (char *) Sysmap, Syssize * sizeof (struct pte))
-                   != Syssize * sizeof (struct pte)) {
-                       seterr("can't read Sysmap");
+               read(kmem, (char *)&addr, sizeof(addr));
+               (void) lseek(kmem, (long)addr, 0);
+               if (read(kmem, (char *) Sysseg, NBPG) != NBPG) {
+                       seterr("can't read Sysseg");
                        return (-1);
                }
                        return (-1);
                }
+#endif
        }
        }
-       usrpt = (struct pte *)nl[X_USRPT].n_value;
-       Usrptmap = (struct pte *)nl[X_USRPTMAP].n_value;
-       if (kvm_read((long)nl[X_NSWAP].n_value, &nswap, sizeof (long)) !=
+       if (kvm_read((void *) nl[X_NSWAP].n_value, &nswap, sizeof (long)) !=
            sizeof (long)) {
                seterr("can't read nswap");
                return (-1);
        }
            sizeof (long)) {
                seterr("can't read nswap");
                return (-1);
        }
-       if (kvm_read((long)nl[X_DMMIN].n_value, &dmmin, sizeof (long)) !=
+       if (kvm_read((void *) nl[X_DMMIN].n_value, &dmmin, sizeof (long)) !=
            sizeof (long)) {
                seterr("can't read dmmin");
                return (-1);
        }
            sizeof (long)) {
                seterr("can't read dmmin");
                return (-1);
        }
-       if (kvm_read((long)nl[X_DMMAX].n_value, &dmmax, sizeof (long)) !=
+       if (kvm_read((void *) nl[X_DMMAX].n_value, &dmmax, sizeof (long)) !=
            sizeof (long)) {
                seterr("can't read dmmax");
                return (-1);
            sizeof (long)) {
                seterr("can't read dmmax");
                return (-1);
@@ -742,22 +881,37 @@ getkvars()
        return (0);
 }
 
        return (0);
 }
 
+static
+nlisterr(nl)
+       struct nlist nl[];
+{
+       int i;
+
+       fprintf(stderr, "kvm_nlist: can't find following names:");
+       for (i = 0; nl[i].n_name[0] != '\0'; i++)
+               if (nl[i].n_value == 0)
+                       fprintf(stderr, " %s", nl[i].n_name);
+       fprintf(stderr, ": continuing...\n");
+}
+
+
 kvm_read(loc, buf, len)
 kvm_read(loc, buf, len)
-       unsigned long loc;
-       char *buf;
+       void *loc;
+       void *buf;
 {
        if (kvmfilesopen == 0 && kvm_openfiles(NULL, NULL, NULL) == -1)
                return (-1);
 {
        if (kvmfilesopen == 0 && kvm_openfiles(NULL, NULL, NULL) == -1)
                return (-1);
-       if (loc & KERNBASE) {
-               klseek(kmem, loc, 0);
+       if (iskva(loc)) {
+               if (klseek(kmem, (off_t) loc, 0) == -1)
+                       return -1;
                if (read(kmem, buf, len) != len) {
                if (read(kmem, buf, len) != len) {
-                       seterr("error reading kmem at %x\n", loc);
+                       seterr("error reading kmem at %x", loc);
                        return (-1);
                }
        } else {
                        return (-1);
                }
        } else {
-               lseek(mem, loc, 0);
+               lseek(mem, (off_t) loc, 0);
                if (read(mem, buf, len) != len) {
                if (read(mem, buf, len) != len) {
-                       seterr("error reading mem at %x\n", loc);
+                       seterr("error reading mem at %x", loc);
                        return (-1);
                }
        }
                        return (-1);
                }
        }
@@ -772,20 +926,20 @@ klseek(fd, loc, off)
 {
 
        if (deadkernel) {
 {
 
        if (deadkernel) {
-               off_t vtophys();
-
                if ((loc = vtophys(loc)) == -1)
                if ((loc = vtophys(loc)) == -1)
-                       return;
+                       return -1;
        }
        }
-       (void) lseek(fd, (off_t)loc, off);
+       (void)lseek(fd, (off_t)loc, off);
+       return (0);
 }
 
 }
 
+#ifndef NEWVM
 /*
  * Given a base/size pair in virtual swap area,
  * return a physical base/size pair which is the
  * (largest) initial, physically contiguous block.
  */
 /*
  * Given a base/size pair in virtual swap area,
  * return a physical base/size pair which is the
  * (largest) initial, physically contiguous block.
  */
-static
+static void
 vstodb(vsbase, vssize, dmp, dbp, rev)
        register int vsbase;
        int vssize;
 vstodb(vsbase, vssize, dmp, dbp, rev)
        register int vsbase;
        int vssize;
@@ -810,41 +964,79 @@ vstodb(vsbase, vssize, dmp, dbp, rev)
        dbp->db_size = MIN(vssize, blk - vsbase);
        dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
 }
        dbp->db_size = MIN(vssize, blk - vsbase);
        dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
 }
+#endif
 
 
-/*
- * This routine was stolen from adb to simulate memory management
- * on the VAX.
- */
+#ifdef NEWVM
+static off_t
+vtophys(loc)
+       long    loc;
+{
+       off_t newloc = (off_t) -1;
+#ifdef hp300
+       int p, ste, pte;
+
+       ste = *(int *)&Sysseg[loc >> SG_ISHIFT];
+       if ((ste & SG_V) == 0) {
+               seterr("vtophys: segment not valid (%x)", ste);
+               return((off_t) -1);
+       }
+       p = btop(loc & SG_PMASK);
+       newloc = (ste & SG_FRAME) + (p * sizeof(struct pte));
+       (void) lseek(kmem, (long)(newloc-(off_t)ptob(lowram)), 0);
+       if (read(kmem, (char *)&pte, sizeof pte) != sizeof pte) {
+               seterr("vtophys: cannot locate pte");
+               return((off_t) -1);
+       }
+       newloc = pte & PG_FRAME;
+       if (pte == PG_NV || newloc < (off_t)ptob(lowram)) {
+               seterr("vtophys: page not valid");
+               return((off_t) -1);
+       }
+       newloc = (newloc - (off_t)ptob(lowram)) + (loc & PGOFSET);
+#endif
+       return((off_t) newloc);
+}
+#else
 static off_t
 vtophys(loc)
        long loc;
 {
 static off_t
 vtophys(loc)
        long loc;
 {
-       register p;
+       int p;
        off_t newloc;
        off_t newloc;
+       register struct pte *pte;
 
        newloc = loc & ~KERNBASE;
        p = btop(newloc);
 
        newloc = loc & ~KERNBASE;
        p = btop(newloc);
+#if defined(vax) || defined(tahoe)
        if ((loc & KERNBASE) == 0) {
                seterr("vtophys: translating non-kernel address");
                return((off_t) -1);
        }
        if ((loc & KERNBASE) == 0) {
                seterr("vtophys: translating non-kernel address");
                return((off_t) -1);
        }
+#endif
        if (p >= Syssize) {
                seterr("vtophys: page out of bound (%d>=%d)", p, Syssize);
                return((off_t) -1);
        }
        if (p >= Syssize) {
                seterr("vtophys: page out of bound (%d>=%d)", p, Syssize);
                return((off_t) -1);
        }
-       if (Sysmap[p].pg_v == 0 &&
-           (Sysmap[p].pg_fod || Sysmap[p].pg_pfnum == 0)) {
+       pte = &Sysmap[p];
+       if (pte->pg_v == 0 && (pte->pg_fod || pte->pg_pfnum == 0)) {
                seterr("vtophys: page not valid");
                return((off_t) -1);
        }
                seterr("vtophys: page not valid");
                return((off_t) -1);
        }
-       loc = (long) (ptob(Sysmap[p].pg_pfnum) + (loc & PGOFSET));
+#if defined(hp300)
+       if (pte->pg_pfnum < lowram) {
+               seterr("vtophys: non-RAM page (%d<%d)", pte->pg_pfnum, lowram);
+               return((off_t) -1);
+       }
+#endif
+       loc = (long) (ptob(pftoc(pte->pg_pfnum)) + (loc & PGOFSET));
        return(loc);
 }
        return(loc);
 }
+#endif
 
 #include <varargs.h>
 
 #include <varargs.h>
-static char errbuf[LINE_MAX];
+static char errbuf[_POSIX2_LINE_MAX];
 
 
-static
+static void
 seterr(va_alist)
        va_dcl
 {
 seterr(va_alist)
        va_dcl
 {
@@ -853,30 +1045,29 @@ seterr(va_alist)
 
        va_start(ap);
        fmt = va_arg(ap, char *);
 
        va_start(ap);
        fmt = va_arg(ap, char *);
-       (void) vsprintf(errbuf, fmt, ap);
+       (void) vsnprintf(errbuf, _POSIX2_LINE_MAX, fmt, ap);
        va_end(ap);
 }
 
        va_end(ap);
 }
 
-static
+static void
 setsyserr(va_alist)
        va_dcl
 {
        char *fmt, *cp;
        va_list ap;
 setsyserr(va_alist)
        va_dcl
 {
        char *fmt, *cp;
        va_list ap;
-       extern errno;
+       extern int errno;
 
        va_start(ap);
        fmt = va_arg(ap, char *);
 
        va_start(ap);
        fmt = va_arg(ap, char *);
-       (void) vsprintf(errbuf, fmt, ap);
+       (void) vsnprintf(errbuf, _POSIX2_LINE_MAX, fmt, ap);
        for (cp=errbuf; *cp; cp++)
                ;
        for (cp=errbuf; *cp; cp++)
                ;
-       sprintf(cp, ": %s", strerror(errno));
+       snprintf(cp, _POSIX2_LINE_MAX - (cp - errbuf), ": %s", strerror(errno));
        va_end(ap);
 }
 
 char *
 kvm_geterr()
 {
        va_end(ap);
 }
 
 char *
 kvm_geterr()
 {
-
        return (errbuf);
 }
        return (errbuf);
 }