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

Defined functions

kvm_close defined in line 147; never used
kvm_dummy defined in line 392; never used
kvm_getproc defined in line 372; never used
kvm_getu defined in line 250; never used
kvm_nextproc defined in line 309; used 1 times
kvm_nlist defined in line 170; used 1 times
kvm_open defined in line 75; never used
kvm_read defined in line 238; never used
kvm_setproc defined in line 322; used 2 times
readbuf defined in line 213; used 8 times

Defined macros

K0_TO_PHYS defined in line 35; used 2 times
N_NPROC defined in line 331; used 1 times
N_PROC defined in line 329; used 1 times
N_USRPT defined in line 332; used 1 times
N_USRPTMA defined in line 330; used 1 times
_K32U32 defined in line 28; never used
_K64U64 defined in line 26; never used
nlist defined in line 39; used 1 times
Last modified: 1996-11-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4610
Valid CSS Valid XHTML 1.0 Strict