diff options
Diffstat (limited to 'lib/libutil/kvm.c')
| -rw-r--r-- | lib/libutil/kvm.c | 741 |
1 files changed, 125 insertions, 616 deletions
diff --git a/lib/libutil/kvm.c b/lib/libutil/kvm.c index 96121cbb454a..2c5de35dd0b8 100644 --- a/lib/libutil/kvm.c +++ b/lib/libutil/kvm.c @@ -30,27 +30,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE - * -------------------- ----- ---------------------- - * CURRENT PATCH LEVEL: 3 00136 - * -------------------- ----- ---------------------- - * - * 08 Sep 92 Greenman & Kranenburg Change vaddr calc, move bogus #endif - * 05 Aug 92 David Greenman Fix kernel namelist db create/use - * 08 Aug 93 Paul Kranenburg Fix for command line args from ps and w + * $Id: kvm.c,v 1.8 1994/02/23 09:56:45 rgrimes Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)kvm.c 5.18 (Berkeley) 5/7/91"; #endif /* LIBC_SCCS and not lint */ -/* - * Updated for 386BSD 0.1 by David Greenman (davidg%implode@percy.rain.com) - * and Paul Kranenburg (pk@cs.few.eur.nl) - * 20-Aug-1992 - * And again by same on 04-Aug-1993 - */ - +#define DEBUG 0 #include <sys/param.h> #include <sys/user.h> @@ -58,6 +45,8 @@ static char sccsid[] = "@(#)kvm.c 5.18 (Berkeley) 5/7/91"; #include <sys/ioctl.h> #include <sys/kinfo.h> #include <sys/tty.h> +#include <sys/file.h> +#include <sys/types.h> #include <machine/vmparam.h> #include <fcntl.h> #include <nlist.h> @@ -67,26 +56,14 @@ static char sccsid[] = "@(#)kvm.c 5.18 (Berkeley) 5/7/91"; #include <paths.h> #include <stdio.h> #include <string.h> +#include <sys/mman.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 <vm/vm_page.h> #include <vm/swap_pager.h> #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 @@ -113,20 +90,13 @@ static union { char upages[UPAGES][NBPG]; } user; -#ifdef NEWVM struct swapblk { long offset; /* offset in swap device */ long size; /* remaining size of block in swap device */ }; -#endif /* * random other stuff */ -#ifndef NEWVM -static struct pte *Usrptmap, *usrpt; -static struct pte *Sysmap; -static int Syssize; -#endif static int dmmin, dmmax; static int pcbpf; static int argaddr0; /* XXX */ @@ -134,22 +104,11 @@ static int argaddr1; static int swaddr; static int nswap; static char *tmp; -#if defined(hp300) -static int lowram; -static struct ste *Sysseg; -#endif -#if defined(i386) static struct pde *PTD; -#endif #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 @@ -174,41 +133,36 @@ static struct nlist nl[] = { #define X_VM_PAGE_HASH_MASK 6 { "_page_shift" }, #define X_PAGE_SHIFT 7 + { "_kstack" }, +#define X_KSTACK 8 + { "_kernel_object" }, +#define X_KERNEL_OBJECT 9 + { "_btext",}, +#define X_KERNEL_BTEXT 10 /* * everything here and down, only if a dead kernel */ { "_Sysmap" }, -#define X_SYSMAP 8 +#define X_SYSMAP 11 #define X_DEADKERNEL X_SYSMAP { "_Syssize" }, -#define X_SYSSIZE 9 +#define X_SYSSIZE 12 { "_allproc" }, -#define X_ALLPROC 10 +#define X_ALLPROC 13 { "_zombproc" }, -#define X_ZOMBPROC 11 +#define X_ZOMBPROC 14 { "_nproc" }, -#define X_NPROC 12 -#define X_LAST 12 -#if defined(hp300) - { "_Sysseg" }, -#define X_SYSSEG (X_LAST+1) - { "_lowram" }, -#define X_LOWRAM (X_LAST+2) -#endif -#if defined(i386) +#define X_NPROC 15 +#define X_LAST 15 { "_IdlePTD" }, #define X_IdlePTD (X_LAST+1) -#endif { "" }, }; static off_t Vtophys(); static void klseek(), seterr(), setsyserr(), vstodb(); static int getkvars(), kvm_doprocs(), kvm_init(); -#ifdef NEWVM -static int vatosw(); static int findpage(); -#endif /* * returns 0 if files were opened now, @@ -305,12 +259,6 @@ kvm_close() kvminit = 0; kvmfilesopen = 0; deadkernel = 0; -#ifndef NEWVM - if (Sysmap) { - free(Sysmap); - Sysmap = NULL; - } -#endif } kvm_nlist(nl) @@ -430,9 +378,10 @@ kvm_getprocs(what, arg) return (-1); } copysize = ret; - if (copysize > ocopysize && - (kvmprocbase = (struct kinfo_proc *)malloc(copysize)) - == NULL) { + if ((copysize > ocopysize || + kvmprocbase == (struct kinfo_proc *) NULL) && + (kvmprocbase = (struct kinfo_proc *) + realloc(kvmprocbase, copysize)) == NULL) { seterr("out of memory"); return (-1); } @@ -489,9 +438,6 @@ kvm_doprocs(what, arg, buff) struct pgrp pgrp; struct session sess; struct tty tty; -#ifndef NEWVM - struct text text; -#endif /* allproc */ if (kvm_read((void *) nl[X_ALLPROC].n_value, &p, @@ -507,7 +453,6 @@ again: 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, @@ -530,26 +475,6 @@ again: continue; break; } -#else - switch(ki_op(what)) { - - case KINFO_PROC_PID: - if (proc.p_pid != (pid_t)arg) - continue; - break; - - - case KINFO_PROC_UID: - if (proc.p_uid != (uid_t)arg) - continue; - break; - - case KINFO_PROC_RUID: - if (proc.p_ruid != (uid_t)arg) - continue; - break; - } -#endif /* * gather eproc */ @@ -589,23 +514,10 @@ again: eproc.e_tdev = NODEV; 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; - eproc.e_xrssize = text.x_rssize; - eproc.e_xccount = text.x_ccount; - eproc.e_xswrss = text.x_swrss; - } else { - eproc.e_xsize = eproc.e_xrssize = - eproc.e_xccount = eproc.e_xswrss = 0; - } -#endif switch(ki_op(what)) { @@ -648,7 +560,9 @@ kvm_nextproc() if (!kvmprocbase && kvm_getprocs(0, 0) == -1) return (NULL); if (kvmprocptr >= (kvmprocbase + kvmnprocs)) { +#if 0 seterr("end of proc list"); +#endif return (NULL); } return((struct proc *)(kvmprocptr++)); @@ -675,12 +589,29 @@ kvm_freeprocs() } } -#ifdef i386 -/* See also ./sys/kern/kern_execve.c */ -#define ARGSIZE (roundup(ARG_MAX, NBPG)) -#endif +proc_getmem(const struct proc *p, void *buffer, vm_offset_t size, vm_offset_t offset) { + int fd; + char fn[512+1]; + sprintf(fn,"/proc/%d",p->p_pid); + if (p->p_flag & SSYS) + return 0; + fd = open(fn,O_RDONLY); + if (fd == -1) { + return 0; + } + + if (lseek(fd, offset, 0) == -1) { + close(fd); + return 0; + } + if (read(fd, buffer, size) <= 0) { + close(fd); + return 0; + } + close(fd); + return 1; +} -#ifdef NEWVM struct user * kvm_getu(p) const struct proc *p; @@ -689,7 +620,7 @@ kvm_getu(p) register int i; register char *up; u_int vaddr; - struct swapblk swb; + int arg_size; if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1) return (NULL); @@ -698,48 +629,15 @@ kvm_getu(p) return (NULL); } - argaddr0 = argaddr1 = swaddr = 0; - if ((p->p_flag & SLOAD) == 0) { - vm_offset_t maddr; - - if (swap < 0) { - seterr("no swap"); - return (NULL); - } - /* - * Costly operation, better set enable_swap to zero - * in vm/vm_glue.c, since paging of user pages isn't - * done yet anyway. - */ - if (vatosw(p, USRSTACK + i * NBPG, &maddr, &swb) == 0) - return NULL; - - if (maddr == 0 && swb.size < UPAGES * NBPG) - return NULL; - - for (i = 0; i < UPAGES; i++) { - if (maddr) { - (void) lseek(mem, maddr + i * NBPG, 0); - if (read(mem, - (char *)user.upages[i], NBPG) != NBPG) { - seterr( - "can't read u for pid %d from %s", - p->p_pid, swapf); - return NULL; - } - } else { - (void) lseek(swap, swb.offset + i * NBPG, 0); - if (read(swap, - (char *)user.upages[i], NBPG) != NBPG) { - seterr( - "can't read u for pid %d from %s", - p->p_pid, swapf); - return NULL; - } - } + if (!deadkernel) { + if (proc_getmem(p, user.upages, sizeof user.upages, USRSTACK)) { + kp->kp_eproc.e_vm.vm_rssize = + kp->kp_eproc.e_vm.vm_pmap.pm_stats.resident_count; /* XXX */ + return &user.user; } - return(&user.user); } + + argaddr0 = argaddr1 = 0; /* * Read u-area one page at a time for the benefit of post-mortems */ @@ -753,31 +651,17 @@ kvm_getu(p) } up += CLBYTES; } + pcbpf = (int) btop(p->p_addr); /* what should this be really? */ /* * Conjure up a physical address for the arguments. */ -#ifdef hp300 - if (kp->kp_eproc.e_vm.vm_pmap.pm_ptab) { - struct pte pte[CLSIZE*2]; - - klseek(kmem, - (long)&kp->kp_eproc.e_vm.vm_pmap.pm_ptab - [btoc(USRSTACK-CLBYTES*2)], 0); - 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)); - } - } -#endif kp->kp_eproc.e_vm.vm_rssize = kp->kp_eproc.e_vm.vm_pmap.pm_stats.resident_count; /* XXX */ - vaddr = (u_int)kp->kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ - ARGSIZE; + vaddr = (u_int)kp->kp_eproc.e_vm.vm_minsaddr; + arg_size = USRSTACK - vaddr; -#ifdef i386 if (kp->kp_eproc.e_vm.vm_pmap.pm_pdir) { struct pde pde; @@ -794,239 +678,116 @@ kvm_getu(p) seterr("kvm_getu: lseek"); if (read(mem, (char *)&pte, sizeof pte) == sizeof pte) { if (pte.pg_v) { - argaddr1 = (long)ctob(pte.pg_pfnum); - } else { - goto hard; + argaddr1 = (pte.pg_pfnum << PGSHIFT) | + ((u_long)vaddr & (NBPG-1)); } } else { seterr("kvm_getu: read"); } - } else { - goto hard; } } -#endif /* i386 */ - -hard: - if (vatosw(p, vaddr, &argaddr1, &swb)) { - if (argaddr1 == 0 && swb.size >= ARGSIZE) - swaddr = swb.offset; - } return(&user.user); } -#else -struct user * -kvm_getu(p) - const struct proc *p; -{ - struct pte *pteaddr, apte; - struct pte arguutl[HIGHPAGES+(CLSIZE*2)]; - register int i; - int ncl; - - if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1) - return (NULL); - if (p->p_stat == SZOMB) { - seterr("zombie process"); - return (NULL); - } - if ((p->p_flag & SLOAD) == 0) { - if (swap < 0) { - seterr("no swap"); - return (NULL); - } - (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", - p->p_pid, swapf); - return (NULL); - } - pcbpf = 0; - argaddr0 = 0; - argaddr1 = 0; - return (&user.user); - } - pteaddr = &Usrptmap[btokmx(p->p_p0br) + p->p_szpt - 1]; - klseek(kmem, (long)pteaddr, 0); - 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(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) - argaddr0 = ctob(pftoc(arguutl[0].pg_pfnum)); - else - argaddr0 = 0; - if (arguutl[CLSIZE*1].pg_fod == 0 && arguutl[CLSIZE*1].pg_pfnum) - argaddr1 = ctob(pftoc(arguutl[CLSIZE*1].pg_pfnum)); - else - argaddr1 = 0; - pcbpf = arguutl[CLSIZE*2].pg_pfnum; - ncl = (sizeof (struct user) + CLBYTES - 1) / CLBYTES; - while (--ncl >= 0) { - i = ncl * CLSIZE; - 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", - arguutl[(CLSIZE*2)+i].pg_pfnum, p->p_pid, memf); - return(NULL); - } - } - return (&user.user); -} -#endif char * kvm_getargs(p, up) const struct proc *p; const struct user *up; { -#ifdef i386 - /* See also ./sys/kern/kern_execve.c */ - static char cmdbuf[ARGSIZE]; - static union { - char argc[ARGSIZE]; - int argi[ARGSIZE/sizeof (int)]; - } argspac; -#else - static char cmdbuf[CLBYTES*2]; - static union { - char argc[CLBYTES*2]; - int argi[CLBYTES*2/sizeof (int)]; - } argspac; -#endif + int arg_size, arg_offset; + static char cmdbuf[ARG_MAX]; + char argc[ARG_MAX*3]; + int *argv; register char *cp; - register int *ip; char c; int nbad; -#ifndef NEWVM - struct dblock db; + char *cmdbufp; + vm_offset_t vaddr; + char procfile[16]; + int mmfd; +#if 0 + char *argc = NULL; #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) { -#ifdef NEWVM - if (swaddr == 0) - goto retucomm; /* XXX for now */ -#ifdef i386 - (void) lseek(swap, swaddr, 0); - if (read(swap, &argspac.argc[0], ARGSIZE) != ARGSIZE) - goto bad; -#else - if (argaddr0) { - lseek(swap, (long)argaddr0, 0); - if (read(swap, (char *)&argspac, CLBYTES) != CLBYTES) - goto bad; - } else - bzero(&argspac, CLBYTES); - lseek(swap, (long)argaddr1, 0); - if (read(swap, &argspac.argc[CLBYTES], CLBYTES) != CLBYTES) - goto bad; -#endif -#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); - 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); - if (read(swap, (char *)&argspac.argc[0], CLBYTES) != CLBYTES) - goto bad; - file = swapf; + *cmdbuf = 0; + + vaddr = (u_int)((struct kinfo_proc *)p)->kp_eproc.e_vm.vm_minsaddr; + arg_size = USRSTACK - vaddr; + + if (arg_size >= 3*ARG_MAX) + goto bad; + +#if 0 + sprintf(procfile, "/proc/%d", p->p_pid); + if ((mmfd = open(procfile, O_RDONLY, 0)) == -1) { +printf("failed to open %s\n",procfile); + goto bad; + } + + if ((argc = mmap(0, arg_size, PROT_READ, MAP_FILE, mmfd, vaddr)) + == (char *)-1) { +printf("failed to mmap %s error=%s\n", procfile, strerror(errno)); + goto bad; + } #endif - } else { -#ifdef i386 - lseek(mem, (long)argaddr1, 0); - if (read(mem, &argspac.argc[0], ARGSIZE) != ARGSIZE) + + if (!proc_getmem(p, argc, arg_size, vaddr)) { + if ((p->p_flag & SLOAD) == 0 || argaddr1 == 0) { goto bad; -#else - if (argaddr0) { - lseek(mem, (long)argaddr0, 0); - if (read(mem, (char *)&argspac, CLBYTES) != CLBYTES) + } else { + lseek(mem, (long)argaddr1, 0); + if (read(mem, argc, arg_size) != arg_size) goto bad; - } else - bzero(&argspac, CLBYTES); - lseek(mem, (long)argaddr1, 0); - if (read(mem, &argspac.argc[CLBYTES], CLBYTES) != CLBYTES) - goto bad; -#endif - file = (char *) memf; + } } + argv = (int *)argc; + + arg_offset = argv[0] - vaddr; + if (arg_offset >= 3*ARG_MAX) + goto bad; + nbad = 0; -#ifdef i386 - ip = &argspac.argi[(ARGSIZE-ARG_MAX)/sizeof (int)]; - - for (cp = (char *)ip; cp < &argspac.argc[ARGSIZE-stkoff]; cp++) { -#else - 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; - } - *(char *)ip = ' '; - ip++; - for (cp = (char *)ip; cp < &argspac.argc[CLBYTES*2-stkoff]; cp++) { -#endif - c = *cp; + cmdbufp = cmdbuf; + for (cp = &argc[arg_offset]; cp < &argc[arg_size]; cp++, cmdbufp++) { + c = *cmdbufp = *cp; if (c == 0) { /* convert null between arguments to space */ - *cp = ' '; + *cmdbufp = ' '; if (*(cp+1) == 0) break; /* if null argument follows then no more args */ } else if (c < ' ' || c > 0176) { if (++nbad >= 5*(0+1)) { /* eflg -> 0 XXX */ /* limit number of bad chars to 5 */ - *cp++ = '?'; + *cmdbufp++ = '?'; break; } - *cp = '?'; + *cmdbufp = '?'; } else if (0 == 0 && c == '=') { /* eflg -> 0 XXX */ - while (*--cp != ' ') - if (cp <= (char *)ip) + while (*--cmdbufp != ' ') + if (cmdbufp <= cmdbuf) break; break; } } - *cp = 0; - while (*--cp == ' ') - *cp = 0; - cp = (char *)ip; - (void) strcpy(cmdbuf, cp); - if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') { + *cmdbufp = 0; + + while (*--cmdbufp == ' ') + *cmdbufp = 0; + + if (cmdbuf[0] == '-' || cmdbuf[0] == '?' || cmdbuf[0] <= ' ') { +bad: (void) strcat(cmdbuf, " ("); (void) strncat(cmdbuf, p->p_comm, sizeof(p->p_comm)); (void) strcat(cmdbuf, ")"); } - return (cmdbuf); - -bad: - seterr("error locating command name for pid %d from %s", - p->p_pid, file); -retucomm: - (void) strcpy(cmdbuf, " ("); - (void) strncat(cmdbuf, p->p_comm, sizeof (p->p_comm)); - (void) strcat(cmdbuf, ")"); +#if 0 + if (argc && argc != (char *)-1) + munmap(argc, arg_size); + if (mmfd && mmfd != -1) + close (mmfd); +#endif return (cmdbuf); } @@ -1040,47 +801,6 @@ getkvars() /* We must do the sys map first because klseek uses it */ long addr; -#ifndef NEWVM - Syssize = nl[X_SYSSIZE].n_value; - Sysmap = (struct pte *) - calloc((unsigned) Syssize, sizeof (struct pte)); - if (Sysmap == NULL) { - seterr("out of space for Sysmap"); - return (-1); - } - addr = (long) nl[X_SYSMAP].n_value; - addr &= ~KERNBASE; - (void) lseek(kmem, addr, 0); - if (read(kmem, (char *) Sysmap, Syssize * sizeof (struct pte)) - != Syssize * sizeof (struct pte)) { - seterr("can't read Sysmap"); - return (-1); - } -#endif -#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); - } - addr = (long) nl[X_SYSSEG].n_value; - (void) lseek(kmem, addr, 0); - 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); - } -#endif -#if defined(i386) PTD = (struct pde *) malloc(NBPG); if (PTD == NULL) { seterr("out of space for PTD"); @@ -1094,12 +814,7 @@ getkvars() seterr("can't read PTD"); return (-1); } -#endif } -#ifndef NEWVM - usrpt = (struct pte *)nl[X_USRPT].n_value; - Usrptmap = (struct pte *)nl[X_USRPTMAP].n_value; -#endif if (kvm_read((void *) nl[X_NSWAP].n_value, &nswap, sizeof (long)) != sizeof (long)) { seterr("can't read nswap"); @@ -1154,68 +869,11 @@ klseek(fd, loc, off) (void) lseek(fd, (off_t)loc, off); } -#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. - */ -static void -vstodb(vsbase, vssize, dmp, dbp, rev) - register int vsbase; - int vssize; - struct dmap *dmp; - register struct dblock *dbp; -{ - register int blk = dmmin; - register swblk_t *ip = dmp->dm_map; - - vsbase = ctod(vsbase); - vssize = ctod(vssize); - if (vsbase < 0 || vsbase + vssize > dmp->dm_size) - /*panic("vstodb")*/; - while (vsbase >= blk) { - vsbase -= blk; - if (blk < dmmax) - blk *= 2; - ip++; - } - if (*ip <= 0 || *ip + blk > nswap) - /*panic("vstodb")*/; - dbp->db_size = MIN(vssize, blk - vsbase); - dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase); -} -#endif - -#ifdef NEWVM static off_t Vtophys(loc) u_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"); - 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 -#ifdef i386 struct pde pde; struct pte pte; int p; @@ -1238,168 +896,17 @@ Vtophys(loc) return((off_t) -1); } newloc += (loc & PGOFSET); -#endif return((off_t) newloc); } -#else -static off_t -vtophys(loc) - long loc; -{ - int p; - off_t newloc; - register struct pte *pte; - - 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); - } -#endif - if (p >= Syssize) { - seterr("vtophys: page out of bound (%d>=%d)", p, Syssize); - return((off_t) -1); - } - pte = &Sysmap[p]; - if (pte->pg_v == 0 && (pte->pg_fod || pte->pg_pfnum == 0)) { - seterr("vtophys: page not valid"); - return((off_t) -1); - } -#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); -} -#endif - -#ifdef NEWVM /* * locate address of unwired or swapped page */ -#define DEBUG 0 #define KREAD(off, addr, len) \ (kvm_read((void *)(off), (char *)(addr), (len)) == (len)) - -static int -vatosw(p, vaddr, maddr, swb) -struct proc *p ; -vm_offset_t vaddr; -vm_offset_t *maddr; -struct swapblk *swb; -{ - register struct kinfo_proc *kp = (struct kinfo_proc *)p; - vm_map_t mp = &kp->kp_eproc.e_vm.vm_map; - struct vm_object vm_object; - struct vm_map_entry vm_entry; - struct pager_struct pager; - struct swpager swpager; - struct swblock swblock; - long addr, off; - int i; - - if (p->p_pid == 0 || p->p_pid == 2) - return 0; - - addr = (long)mp->header.next; - for (i = 0; i < mp->nentries; i++) { - /* Weed through map entries until vaddr in range */ - if (!KREAD(addr, &vm_entry, sizeof(vm_entry))) { - setsyserr("vatosw: read vm_map_entry"); - return 0; - } - if ((vaddr >= vm_entry.start) && (vaddr <= vm_entry.end) && - (vm_entry.object.vm_object != 0)) - break; - - addr = (long)vm_entry.next; - } - if (i == mp->nentries) { - seterr("%u: map not found\n", p->p_pid); - return 0; - } - - if (vm_entry.is_a_map || vm_entry.is_sub_map) { - seterr("%u: Is a map\n", p->p_pid); - return 0; - } - - /* Locate memory object */ - off = (vaddr - vm_entry.start) + vm_entry.offset; - addr = (long)vm_entry.object.vm_object; - while (1) { - if (!KREAD(addr, &vm_object, sizeof vm_object)) { - setsyserr("vatosw: read vm_object"); - return 0; - } - -#if DEBUG - fprintf(stderr, "%u: find page: object %#x offset %x\n", - p->p_pid, addr, off); -#endif - - /* Lookup in page queue */ - if (findpage(addr, off, maddr)) - return 1; - - if (vm_object.shadow == 0) - break; - -#if DEBUG - fprintf(stderr, "%u: shadow obj at %x: offset %x+%x\n", - p->p_pid, addr, off, vm_object.shadow_offset); -#endif - - addr = (long)vm_object.shadow; - off += vm_object.shadow_offset; - } - - if (!vm_object.pager) { - seterr("%u: no pager\n", p->p_pid); - return 0; - } - - /* Find address in swap space */ - if (!KREAD(vm_object.pager, &pager, sizeof pager)) { - setsyserr("vatosw: read pager"); - return 0; - } - if (pager.pg_type != PG_SWAP) { - seterr("%u: weird pager\n", p->p_pid); - return 0; - } - - /* Get swap pager data */ - if (!KREAD(pager.pg_data, &swpager, sizeof swpager)) { - setsyserr("vatosw: read swpager"); - return 0; - } - - off += vm_object.paging_offset; - - /* Read swap block array */ - if (!KREAD((long)swpager.sw_blocks + - (off/dbtob(swpager.sw_bsize)) * sizeof swblock, - &swblock, sizeof swblock)) { - setsyserr("vatosw: read swblock"); - return 0; - } - swb->offset = dbtob(swblock.swb_block)+ (off % dbtob(swpager.sw_bsize)); - swb->size = dbtob(swpager.sw_bsize) - (off % dbtob(swpager.sw_bsize)); - return 1; -} - - -#define atop(x) (((unsigned)(x)) >> page_shift) #define vm_page_hash(object, offset) \ (((unsigned)object+(unsigned)atop(offset))&vm_page_hash_mask) @@ -1452,7 +959,6 @@ static long page_shift; } return 0; } -#endif /* NEWVM */ #include <varargs.h> static char errbuf[_POSIX2_LINE_MAX]; @@ -1487,6 +993,9 @@ setsyserr(va_alist) for (cp=errbuf; *cp; cp++) ; snprintf(cp, _POSIX2_LINE_MAX - (cp - errbuf), ": %s", strerror(errno)); +#if DEBUG + (void) fprintf(stderr, "%s\n", errbuf); +#endif va_end(ap); } |
