home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-A.06 / NETKIT-A / NetKit-A-0.06 / pidentd-2.2 / src / kvm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-17  |  6.1 KB  |  367 lines

  1. /*
  2. ** kvm.c            A set of functions emulating KVM for machines without them.
  3. **
  4. ** This code is in the public domain and may be used freely by anyone
  5. ** who wants to.
  6. **
  7. ** Last update: 12 Dec 1992
  8. **
  9. ** Author: Peter Eriksson <pen@lysator.liu.se>
  10. */
  11.  
  12. #ifndef NO_KVM
  13. #ifndef HAVE_KVM
  14.  
  15. #ifdef NeXT31
  16. #  include <libc.h>
  17. #endif
  18.  
  19. #include <stdio.h>
  20. #include <errno.h>
  21. #include <nlist.h>
  22.  
  23. #ifdef IRIX
  24. #include <sys/sbd.h>
  25. #endif
  26.  
  27. #ifdef BSD43
  28. #  include <sys/types.h>
  29. #  include <sys/dir.h>
  30. #  include <sys/param.h>
  31. #  include <sys/vmmac.h>
  32. #if 0
  33. #  include <sys/time.h>
  34. #else
  35. #  include <sys/user.h>
  36. #endif
  37. #  ifdef DIRBLKSIZ
  38. #    undef DIRBLKSIZ
  39. #  endif
  40. #if 0
  41. #  include <sys/user.h>
  42. #endif
  43. #  include <sys/proc.h>
  44. #  include <machine/pte.h>
  45. #  include "paths.h"
  46. #endif
  47.  
  48.  
  49. #include "kvm.h"
  50. #include "paths.h"
  51.  
  52. #if defined(BSD43) || defined(MIPS)
  53. extern int errno;
  54. #endif
  55.  
  56. extern void *malloc();
  57.  
  58.  
  59. kvm_t *kvm_open(namelist, corefile, swapfile, flag, errstr)
  60.   char *namelist;
  61.   char *corefile;
  62.   char *swapfile;
  63.   int flag;
  64.   char *errstr;
  65. {
  66.   kvm_t *kd;
  67.  
  68.   if (!namelist)
  69.     namelist = _PATH_UNIX;
  70.   if (!corefile)
  71.     corefile = _PATH_KMEM;
  72.   
  73. #ifdef BSD43
  74.   if (!swapfile)
  75.     swapfile = _PATH_SWAP;
  76. #endif
  77.   
  78.   kd = (kvm_t *) malloc(sizeof(kvm_t));
  79.   if (!kd)
  80.   {
  81.     if (errstr)
  82.       perror(errstr);
  83.     return NULL;
  84.   }
  85.  
  86.   kd->namelist = (char *) malloc(strlen(namelist)+1);
  87.   if (!kd->namelist)
  88.   {
  89.     if (errstr)
  90.       perror(errstr);
  91.     return NULL;
  92.   }
  93.   
  94.   if ((kd->fd = open(corefile, flag)) < 0)
  95.   {
  96.     if (errstr)
  97.       perror(errstr);
  98.     free(kd->namelist);
  99.     free(kd);
  100.     return NULL;
  101.   }
  102.  
  103. #ifdef BSD43
  104.   if ((kd->swap_fd = open(swapfile, flag)) < 0)
  105.   {
  106.     if (errstr)
  107.       perror(errstr);
  108.     close(kd->fd);
  109.     free(kd->namelist);
  110.     free(kd);
  111.     return NULL;
  112.   }
  113.  
  114.   if ((kd->mem_fd = open(_PATH_MEM, flag)) < 0)
  115.   {
  116.     if (errstr)
  117.       perror(errstr);
  118.     close(kd->swap_fd);
  119.     close(kd->fd);
  120.     free(kd->namelist);
  121.     free(kd);
  122.     return NULL;
  123.   }
  124. #endif
  125.   
  126.   strcpy(kd->namelist, namelist);
  127.   return kd;
  128. }
  129.  
  130.  
  131. int kvm_close(kd)
  132.   kvm_t *kd;
  133. {
  134.   int code;
  135.   
  136.   code = close(kd->fd);
  137. #ifdef BSD43
  138.   close(kd->swap_fd);
  139.   close(kd->mem_fd);
  140.   if (kd->proctab)
  141.     free(kd->proctab);
  142. #endif
  143.   free(kd->namelist);
  144.   free(kd);
  145.  
  146.   return code;
  147. }
  148.  
  149.  
  150. /*
  151. ** Extract offsets to the symbols in the 'nl' list. Returns 0 if all found,
  152. ** or else the number of variables that was not found.
  153. */
  154. int kvm_nlist(kd, nl)
  155.   kvm_t *kd;
  156.   struct nlist *nl;
  157. {
  158.   int code;
  159.   int i;
  160.  
  161.  
  162.   code = nlist(kd->namelist, nl);
  163.   if (code != 0)
  164.     return code;
  165.   
  166.   /*
  167.   ** Verify that we got all the needed variables. Needed because some
  168.   ** implementations of nlist() returns 0 although it didn't find all
  169.   ** variables.
  170.   */
  171.   if (code == 0)
  172.   {
  173. #if defined(__convex__) || defined(NeXT)
  174.     for (i = 0; nl[i].n_un.n_name && nl[i].n_un.n_name[0]; i++)
  175. #else  
  176.     for (i = 0; nl[i].n_name && nl[i].n_name[0]; i++)
  177. #endif
  178. #if defined(_AUX_SOURCE) || defined(_CRAY) || defined(sco)
  179.       /* A/UX sets n_type to 0 if not compiled with -g. n_value will still
  180.       ** contain the (correct?) value (unless symbol unknown).
  181.       */
  182.       if( nl[i].n_value == 0)
  183.     code++;
  184. #else
  185.       if (nl[i].n_type == 0)
  186.     code++;
  187. #endif
  188.   }
  189.   
  190.   return code;
  191. }
  192.  
  193.  
  194. /*
  195. ** Get a piece of the kernel memory
  196. */
  197. static int readbuf(fd, addr, buf, len)
  198.   int fd;
  199.   long addr;
  200.   char *buf;
  201.   int len;
  202. {
  203. #ifdef IRIX
  204.   addr = K0_TO_PHYS(addr);
  205. #endif
  206.   errno = 0;
  207.   if (lseek(fd, addr, 0) == -1 && errno != 0)
  208.     return -1;
  209.  
  210.   return read(fd, buf, len);
  211. }
  212.  
  213. int kvm_read(kd, addr, buf, len)
  214.   kvm_t *kd;
  215.   long addr;
  216.   char *buf;
  217.   int len;
  218. {
  219.   return readbuf(kd->fd, addr, buf, len);
  220. }
  221.  
  222.  
  223. #ifdef BSD43
  224.  
  225. struct user *kvm_getu(kd, procp)
  226.   kvm_t *kd;
  227.   struct proc *procp;
  228. {
  229.   static union
  230.   {
  231.     struct user user;
  232.     char upages[UPAGES][NBPG];
  233.   } userb;
  234.  
  235.   int ncl;
  236.   struct pte *pteaddr, apte;
  237.   struct pte arguutl[UPAGES+CLSIZE];
  238.   
  239.   
  240.   if ((procp->p_flag & SLOAD) == 0)
  241.   {
  242.     if(readbuf(kd->swap_fd,
  243.            dtob(procp->p_swaddr),
  244.            &userb.user, sizeof(struct user)) < 0)
  245.       return NULL;
  246.   }
  247.   else
  248.   {
  249.     /*
  250.     ** Sigh. I just *love* hard coded variable names in macros...
  251.     */
  252.     {
  253.       struct pte *usrpt = kd->usrpt;
  254.       
  255.       pteaddr = &kd->Usrptma[btokmx(procp->p_p0br) + procp->p_szpt - 1];
  256.       if (readbuf(kd->fd, pteaddr, &apte, sizeof(apte)) < 0)
  257.     return NULL;
  258.     }
  259.     
  260.     if (readbuf(kd->mem_fd,
  261.         ctob(apte.pg_pfnum+1)-(UPAGES+CLSIZE)*sizeof(struct pte),
  262.         arguutl, sizeof(arguutl)) < 0)
  263.       return NULL;
  264.  
  265.     ncl = (sizeof(struct user) + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
  266.     while (--ncl >= 0)
  267.     {
  268.       int i;
  269.  
  270.       
  271.       i = ncl * CLSIZE;
  272.       if(readbuf(kd->mem_fd,
  273.          ctob(arguutl[CLSIZE+i].pg_pfnum),
  274.          userb.upages[i], CLSIZE*NBPG) < 0)
  275.     return NULL;
  276.     }
  277.   }
  278.  
  279.   return &userb.user;
  280. }
  281.  
  282.  
  283.  
  284. struct proc *kvm_nextproc(kd)
  285.   kvm_t *kd;
  286. {
  287.   if (kd->proctab == NULL)
  288.     if (kvm_setproc(kd) < 0)
  289.       return NULL;
  290.  
  291.   if (kd->procidx < kd->nproc)
  292.     return &kd->proctab[kd->procidx++];
  293.  
  294.   return (struct proc *) NULL;
  295. }
  296.  
  297. int kvm_setproc(kd)
  298.   kvm_t *kd;
  299. {
  300.   long procaddr;
  301.   
  302.   static struct nlist nl[] =
  303.   {
  304. #define N_PROC 0
  305. #define N_USRPTMA 1
  306. #define N_NPROC 2
  307. #define N_USRPT 3
  308.  
  309.     { "_proc" },
  310.     { "_Usrptmap" },
  311.     { "_nproc" },
  312.     { "_usrpt" },
  313.     { "" }
  314.   };
  315.  
  316.   if (kvm_nlist(kd, nl) != 0)
  317.     return -1;
  318.   
  319.   kd->Usrptma = (struct pte *) nl[N_USRPTMA].n_value;
  320.   kd->usrpt   = (struct pte *) nl[N_USRPT].n_value;
  321.   
  322.   if (readbuf(kd->fd, nl[N_NPROC].n_value, &kd->nproc, sizeof(kd->nproc)) < 0)
  323.     return -1;
  324.  
  325.   if (readbuf(kd->fd, nl[N_PROC].n_value, &procaddr, sizeof(procaddr)) < 0)
  326.     return -1;
  327.   
  328.   if (kd->proctab)
  329.     free(kd->proctab);
  330.  
  331.   kd->proctab = (struct proc *) calloc(kd->nproc, sizeof(struct proc));
  332.   if (!kd->proctab)
  333.     return -1;
  334.  
  335.   if (readbuf(kd->fd,
  336.           procaddr,
  337.           kd->proctab,
  338.           kd->nproc*sizeof(struct proc)) < 0)
  339.     return -1;
  340.  
  341.   kd->procidx = 0;
  342.  
  343.   return 0;
  344. }
  345.  
  346.  
  347. struct proc *kvm_getproc(kd, pid)
  348.   kvm_t *kd;
  349.   int pid;
  350. {
  351.   struct proc *procp;
  352.  
  353.  
  354.   if (kvm_setproc(kd) < 0)
  355.     return NULL;
  356.  
  357.   while ((procp = kvm_nextproc(kd)) && procp->p_pid != pid)
  358.     ;
  359.   
  360.   return procp;
  361. }
  362.  
  363. #endif
  364.  
  365. #endif
  366. #endif
  367.