[BACK]Return to kvm.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libkvm

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libkvm/kvm.c between version 1.2 and 1.3

version 1.2, 1993/03/21 18:04:42 version 1.3, 1993/04/10 15:02:41
Line 74  static char sccsid[] = "@(#)kvm.c 5.18 (
Line 74  static char sccsid[] = "@(#)kvm.c 5.18 (
 #define btop(x)         (((unsigned)(x)) >> PGSHIFT)    /* XXX */  #define btop(x)         (((unsigned)(x)) >> PGSHIFT)    /* XXX */
 #define ptob(x)         ((caddr_t)((x) << PGSHIFT))     /* XXX */  #define ptob(x)         ((caddr_t)((x) << PGSHIFT))     /* XXX */
 #include <vm/vm.h>      /* ??? kinfo_proc currently includes this*/  #include <vm/vm.h>      /* ??? kinfo_proc currently includes this*/
   #include <vm/vm_page.h>
   #include <vm/swap_pager.h>
 #include <sys/kinfo_proc.h>  #include <sys/kinfo_proc.h>
 #ifdef hp300  #ifdef hp300
 #include <hp300/hp300/pte.h>  #include <hp300/hp300/pte.h>
Line 108  static union {
Line 110  static union {
         struct  user user;          struct  user user;
         char    upages[UPAGES][NBPG];          char    upages[UPAGES][NBPG];
 } user;  } user;
   
   #ifdef NEWVM
   struct swapblk {
           long    offset;         /* offset in swap device */
           long    size;           /* remaining size of block in swap device */
   };
   #endif
 /*  /*
  * random other stuff   * random other stuff
  */   */
Line 120  static int dmmin, dmmax;
Line 129  static int dmmin, dmmax;
 static  int     pcbpf;  static  int     pcbpf;
 static  int     argaddr0;       /* XXX */  static  int     argaddr0;       /* XXX */
 static  int     argaddr1;  static  int     argaddr1;
   static  int     swaddr;
 static  int     nswap;  static  int     nswap;
 static  char    *tmp;  static  char    *tmp;
 #if defined(hp300)  #if defined(hp300)
Line 156  static struct nlist nl[] = {
Line 166  static struct nlist nl[] = {
 #define X_DMMIN         3  #define X_DMMIN         3
         { "_dmmax" },          { "_dmmax" },
 #define X_DMMAX         4  #define X_DMMAX         4
           { "_vm_page_buckets" },
   #define X_VM_PAGE_BUCKETS       5
           { "_vm_page_hash_mask" },
   #define X_VM_PAGE_HASH_MASK     6
           { "_page_shift" },
   #define X_PAGE_SHIFT    7
         /*          /*
          * everything here and down, only if a dead kernel           * everything here and down, only if a dead kernel
          */           */
         { "_Sysmap" },          { "_Sysmap" },
 #define X_SYSMAP        5  #define X_SYSMAP        8
 #define X_DEADKERNEL    X_SYSMAP  #define X_DEADKERNEL    X_SYSMAP
         { "_Syssize" },          { "_Syssize" },
 #define X_SYSSIZE       6  #define X_SYSSIZE       9
         { "_allproc" },          { "_allproc" },
 #define X_ALLPROC       7  #define X_ALLPROC       10
         { "_zombproc" },          { "_zombproc" },
 #define X_ZOMBPROC      8  #define X_ZOMBPROC      11
         { "_nproc" },          { "_nproc" },
 #define X_NPROC         9  #define X_NPROC         12
 #define X_LAST          9  #define X_LAST          12
 #if defined(hp300)  #if defined(hp300)
         { "_Sysseg" },          { "_Sysseg" },
 #define X_SYSSEG        (X_LAST+1)  #define X_SYSSEG        (X_LAST+1)
Line 187  static struct nlist nl[] = {
Line 203  static struct nlist nl[] = {
 static off_t Vtophys();  static off_t Vtophys();
 static void klseek(), seterr(), setsyserr(), vstodb();  static void klseek(), seterr(), setsyserr(), vstodb();
 static int getkvars(), kvm_doprocs(), kvm_init();  static int getkvars(), kvm_doprocs(), kvm_init();
   #ifdef NEWVM
   static int vatosw();
   static int findpage();
   #endif
   
 /*  /*
  * returns      0 if files were opened now,   * returns      0 if files were opened now,
Line 396  hard2:
Line 416  hard2:
 kvm_getprocs(what, arg)  kvm_getprocs(what, arg)
         int what, arg;          int what, arg;
 {  {
           static int      ocopysize = -1;
   
         if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1)          if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1)
                 return (NULL);                  return (NULL);
         if (!deadkernel) {          if (!deadkernel) {
Line 406  kvm_getprocs(what, arg)
Line 428  kvm_getprocs(what, arg)
                         return (-1);                          return (-1);
                 }                  }
                 copysize = ret;                  copysize = ret;
                 if ((kvmprocbase = (struct kinfo_proc *)malloc(copysize))                  if (copysize > ocopysize &&
                      == NULL) {                          (kvmprocbase = (struct kinfo_proc *)malloc(copysize))
                                                                        == NULL) {
                         seterr("out of memory");                          seterr("out of memory");
                         return (-1);                          return (-1);
                 }                  }
                   ocopysize = copysize;
                 if ((ret = getkerninfo(what, kvmprocbase, &copysize,                  if ((ret = getkerninfo(what, kvmprocbase, &copysize,
                      arg)) == -1) {                       arg)) == -1) {
                         setsyserr("can't get proc list");                          setsyserr("can't get proc list");
Line 662  kvm_getu(p)
Line 686  kvm_getu(p)
         register struct kinfo_proc *kp = (struct kinfo_proc *)p;          register struct kinfo_proc *kp = (struct kinfo_proc *)p;
         register int i;          register int i;
         register char *up;          register char *up;
           u_int vaddr;
           struct swapblk swb;
   
         if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1)          if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1)
                 return (NULL);                  return (NULL);
Line 669  kvm_getu(p)
Line 695  kvm_getu(p)
                 seterr("zombie process");                  seterr("zombie process");
                 return (NULL);                  return (NULL);
         }          }
         /*  
          * Reading from swap is too complicated right now.          argaddr0 = argaddr1 = swaddr = 0;
          */          if ((p->p_flag & SLOAD) == 0) {
         if ((p->p_flag & SLOAD) == 0)                  vm_offset_t     maddr;
                 return(NULL);  
                   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;
                                   }
                           }
                   }
                   return(&user.user);
           }
         /*          /*
          * Read u-area one page at a time for the benefit of post-mortems           * Read u-area one page at a time for the benefit of post-mortems
          */           */
Line 691  kvm_getu(p)
Line 755  kvm_getu(p)
         /*          /*
          * Conjure up a physical address for the arguments.           * Conjure up a physical address for the arguments.
          */           */
         argaddr0 = argaddr1 = 0;  
 #ifdef hp300  #ifdef hp300
         if (kp->kp_eproc.e_vm.vm_pmap.pm_ptab) {          if (kp->kp_eproc.e_vm.vm_pmap.pm_ptab) {
                 struct pte pte[CLSIZE*2];                  struct pte pte[CLSIZE*2];
Line 706  kvm_getu(p)
Line 769  kvm_getu(p)
                         argaddr1 = ctob(pftoc(pte[CLSIZE*1].pg_pfnum));                          argaddr1 = ctob(pftoc(pte[CLSIZE*1].pg_pfnum));
                 }                  }
         }          }
 #endif                                                  /* 08 Sep 92*/  #endif
         kp->kp_eproc.e_vm.vm_rssize =          kp->kp_eproc.e_vm.vm_rssize =
             kp->kp_eproc.e_vm.vm_pmap.pm_stats.resident_count; /* XXX */              kp->kp_eproc.e_vm.vm_pmap.pm_stats.resident_count; /* XXX */
   
           vaddr = (u_int)kp->kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ - ARGSIZE;
   
 #ifdef i386  #ifdef i386
         if (kp->kp_eproc.e_vm.vm_pmap.pm_pdir) {          if (kp->kp_eproc.e_vm.vm_pmap.pm_pdir) {
                 struct pde pde;                  struct pde pde;
                 /* u_int vaddr = USRSTACK-ARGSIZE;*/  
 /* 08 Sep 92*/  u_int vaddr = (u_int)kp->kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ - ARGSIZE;  
   
                 /* 08 Sep 92 ---------  
                 if ((u_int)kp->kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ < USRSTACK)  
                         vaddr -= MAXSSIZ;  
                  */  
 #if 0  
                 klseek(kmem,  
                         (long)(kp->kp_eproc.e_vm.vm_pmap.pm_pdir + UPTDI), 0);  
 #else  
                 klseek(kmem,                  klseek(kmem,
                 (long)(&kp->kp_eproc.e_vm.vm_pmap.pm_pdir[pdei(vaddr)]), 0);                  (long)(&kp->kp_eproc.e_vm.vm_pmap.pm_pdir[pdei(vaddr)]), 0);
 #endif  
                 if (read(kmem, (char *)&pde, sizeof pde) == sizeof pde                  if (read(kmem, (char *)&pde, sizeof pde) == sizeof pde
                                 && pde.pd_v) {                                  && pde.pd_v) {
   
                         struct pte pte;                          struct pte pte;
   
                         lseek(mem, (long)ctob(pde.pd_pfnum) +                          if (lseek(mem, (long)ctob(pde.pd_pfnum) +
                                 (ptei(vaddr) * sizeof pte), 0);                                          (ptei(vaddr) * sizeof pte), 0) == -1)
                         if (read(mem, (char *)&pte, sizeof pte) == sizeof pte                                  seterr("kvm_getu: lseek");
                                         && pte.pg_v) {                          if (read(mem, (char *)&pte, sizeof pte) == sizeof pte) {
                                 argaddr1 = (long)ctob(pte.pg_pfnum);                                  if (pte.pg_v) {
                                           argaddr1 = (long)ctob(pte.pg_pfnum);
                                   } else {
                                           goto hard;
                                   }
                           } else {
                                   seterr("kvm_getu: read");
                         }                          }
                   } else {
                           goto hard;
                 }                  }
         }          }
 #endif  #endif  /* i386 */
   
   hard:
           if (vatosw(p, vaddr, &argaddr1, &swb)) {
                   if (argaddr1 == 0 && swb.size >= ARGSIZE)
                           swaddr = swb.offset;
           }
   
         return(&user.user);          return(&user.user);
 }  }
 #else  #else
Line 849  kvm_getargs(p, up)
Line 919  kvm_getargs(p, up)
                 goto retucomm;                  goto retucomm;
         if ((p->p_flag & SLOAD) == 0 || argaddr1 == 0) {          if ((p->p_flag & SLOAD) == 0 || argaddr1 == 0) {
 #ifdef NEWVM  #ifdef NEWVM
                 goto retucomm;  /* XXX for now */                  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  #else
                 if (swap < 0 || p->p_ssize == 0)                  if (swap < 0 || p->p_ssize == 0)
                         goto retucomm;                          goto retucomm;
Line 882  kvm_getargs(p, up)
Line 968  kvm_getargs(p, up)
 #endif  #endif
                 file = (char *) memf;                  file = (char *) memf;
         }          }
   
           nbad = 0;
 #ifdef i386  #ifdef i386
         ip = &argspac.argi[(ARGSIZE-ARG_MAX)/sizeof (int)];          ip = &argspac.argi[(ARGSIZE-ARG_MAX)/sizeof (int)];
   
         nbad = 0;  
         for (cp = (char *)ip; cp < &argspac.argc[ARGSIZE-stkoff]; cp++) {          for (cp = (char *)ip; cp < &argspac.argc[ARGSIZE-stkoff]; cp++) {
 #else  #else
         ip = &argspac.argi[CLBYTES*2/sizeof (int)];          ip = &argspac.argi[CLBYTES*2/sizeof (int)];
Line 897  kvm_getargs(p, up)
Line 984  kvm_getargs(p, up)
         }          }
         *(char *)ip = ' ';          *(char *)ip = ' ';
         ip++;          ip++;
         nbad = 0;  
   
         for (cp = (char *)ip; cp < &argspac.argc[CLBYTES*2-stkoff]; cp++) {          for (cp = (char *)ip; cp < &argspac.argc[CLBYTES*2-stkoff]; cp++) {
 #endif  #endif
Line 1190  vtophys(loc)
Line 1276  vtophys(loc)
 }  }
 #endif  #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)
   
   static int
   findpage(object, offset, maddr)
   long                    object;
   long                    offset;
   vm_offset_t             *maddr;
   {
   static  long            vm_page_hash_mask;
   static  long            vm_page_buckets;
   static  long            page_shift;
           queue_head_t    bucket;
           struct vm_page  mem;
           long            addr, baddr;
   
           if (vm_page_hash_mask == 0 && !KREAD(nl[X_VM_PAGE_HASH_MASK].n_value,
                           &vm_page_hash_mask, sizeof (long))) {
                   seterr("can't read vm_page_hash_mask");
                   return 0;
           }
           if (page_shift == 0 && !KREAD(nl[X_PAGE_SHIFT].n_value,
                           &page_shift, sizeof (long))) {
                   seterr("can't read page_shift");
                   return 0;
           }
           if (vm_page_buckets == 0 && !KREAD(nl[X_VM_PAGE_BUCKETS].n_value,
                           &vm_page_buckets, sizeof (long))) {
                   seterr("can't read vm_page_buckets");
                   return 0;
           }
   
           baddr = vm_page_buckets + vm_page_hash(object,offset) * sizeof(queue_head_t);
           if (!KREAD(baddr, &bucket, sizeof (bucket))) {
                   seterr("can't read vm_page_bucket");
                   return 0;
           }
   
           addr = (long)bucket.next;
           while (addr != baddr) {
                   if (!KREAD(addr, &mem, sizeof (mem))) {
                           seterr("can't read vm_page");
                           return 0;
                   }
                   if ((long)mem.object == object && mem.offset == offset) {
                           *maddr = (long)mem.phys_addr;
                           return 1;
                   }
                   addr = (long)mem.hashq.next;
           }
           return 0;
   }
   #endif  /* NEWVM */
   
 #include <varargs.h>  #include <varargs.h>
 static char errbuf[_POSIX2_LINE_MAX];  static char errbuf[_POSIX2_LINE_MAX];
   
Line 1203  seterr(va_alist)
Line 1465  seterr(va_alist)
         va_start(ap);          va_start(ap);
         fmt = va_arg(ap, char *);          fmt = va_arg(ap, char *);
         (void) vsnprintf(errbuf, _POSIX2_LINE_MAX, fmt, ap);          (void) vsnprintf(errbuf, _POSIX2_LINE_MAX, fmt, ap);
   #if DEBUG
           (void) vfprintf(stderr, fmt, ap);
   #endif
         va_end(ap);          va_end(ap);
 }  }
   

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

CVSweb <webmaster@jp.NetBSD.org>