|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #if defined(LIBC_SCCS) && !defined(lint) ! 21: static char sccsid[] = "@(#)kvm.c 5.9 (Berkeley) 6/27/90"; ! 22: #endif /* LIBC_SCCS and not lint */ ! 23: ! 24: #include <machine/pte.h> ! 25: #include <machine/vmparam.h> ! 26: #include <sys/param.h> ! 27: #include <sys/user.h> ! 28: #include <sys/proc.h> ! 29: #include <sys/file.h> ! 30: #include <sys/text.h> ! 31: #include <sys/stat.h> ! 32: #include <sys/time.h> ! 33: #include <sys/vmmac.h> ! 34: #include <sys/ioctl.h> ! 35: #include <sys/tty.h> ! 36: #include <kvm.h> ! 37: #include <ctype.h> ! 38: #include <vis.h> ! 39: #include <nlist.h> ! 40: #include <pwd.h> ! 41: #include <string.h> ! 42: #include <ndbm.h> ! 43: #include <limits.h> ! 44: #include <paths.h> ! 45: #include <stdio.h> ! 46: ! 47: /* ! 48: * files ! 49: */ ! 50: static char *unixf, *memf, *kmemf, *swapf; ! 51: static int unixx, mem, kmem, swap; ! 52: static DBM *db; ! 53: /* ! 54: * flags ! 55: */ ! 56: static int deadkernel; ! 57: static int kvminit = 0; ! 58: static int kvmfilesopen = 0; ! 59: /* ! 60: * state ! 61: */ ! 62: static struct kinfo_proc *kvmprocbase, *kvmprocptr; ! 63: static int kvmnprocs; ! 64: /* ! 65: * u. buffer ! 66: */ ! 67: static union { ! 68: struct user user; ! 69: char upages[UPAGES][NBPG]; ! 70: } user; ! 71: /* ! 72: * random other stuff ! 73: */ ! 74: static struct pte *Usrptmap, *usrpt; ! 75: static int dmmin, dmmax; ! 76: static struct pte *Sysmap; ! 77: static int Syssize; ! 78: static int pcbpf; ! 79: static int argaddr0; /* XXX */ ! 80: static int argaddr1; ! 81: static int nswap; ! 82: static char *tmp; ! 83: #if defined(hp300) ! 84: static int lowram; ! 85: #endif ! 86: ! 87: #define basename(cp) ((tmp=rindex((cp), '/')) ? tmp+1 : (cp)) ! 88: #define MAXSYMSIZE 256 ! 89: ! 90: #if defined(hp300) ! 91: #define pftoc(f) ((f) - lowram) ! 92: #define iskva(v) (1) ! 93: #endif ! 94: ! 95: #ifndef pftoc ! 96: #define pftoc(f) (f) ! 97: #endif ! 98: #ifndef iskva ! 99: #define iskva(v) ((v) & KERNBASE) ! 100: #endif ! 101: ! 102: static struct nlist nl[] = { ! 103: { "_Usrptmap" }, ! 104: #define X_USRPTMAP 0 ! 105: { "_usrpt" }, ! 106: #define X_USRPT 1 ! 107: { "_nswap" }, ! 108: #define X_NSWAP 2 ! 109: { "_dmmin" }, ! 110: #define X_DMMIN 3 ! 111: { "_dmmax" }, ! 112: #define X_DMMAX 4 ! 113: /* ! 114: * everything here and down, only if a dead kernel ! 115: */ ! 116: { "_Sysmap" }, ! 117: #define X_SYSMAP 5 ! 118: #define X_DEADKERNEL X_SYSMAP ! 119: { "_Syssize" }, ! 120: #define X_SYSSIZE 6 ! 121: { "_allproc" }, ! 122: #define X_ALLPROC 7 ! 123: { "_zombproc" }, ! 124: #define X_ZOMBPROC 8 ! 125: { "_nproc" }, ! 126: #define X_NPROC 9 ! 127: #define X_LAST 9 ! 128: #if defined(hp300) ! 129: { "_lowram" }, ! 130: #define X_LOWRAM (X_LAST+1) ! 131: #endif ! 132: { "" }, ! 133: }; ! 134: ! 135: /* ! 136: * returns 0 if files were opened now, ! 137: * 1 if files were already opened, ! 138: * -1 if files could not be opened. ! 139: */ ! 140: kvm_openfiles(uf, mf, sf) ! 141: char *uf, *mf, *sf; ! 142: { ! 143: if (kvmfilesopen) ! 144: return (1); ! 145: unixx = mem = kmem = swap = -1; ! 146: unixf = (uf == NULL) ? _PATH_UNIX : uf; ! 147: memf = (mf == NULL) ? _PATH_MEM : mf; ! 148: ! 149: if ((unixx = open(unixf, O_RDONLY, 0)) == -1) { ! 150: setsyserr("can't open %s", unixf); ! 151: goto failed; ! 152: } ! 153: if ((mem = open(memf, O_RDONLY, 0)) == -1) { ! 154: setsyserr("can't open %s", memf); ! 155: goto failed; ! 156: } ! 157: if (sf != NULL) ! 158: swapf = sf; ! 159: if (mf != NULL) { ! 160: deadkernel++; ! 161: kmemf = mf; ! 162: kmem = mem; ! 163: swap = -1; ! 164: } else { ! 165: kmemf = _PATH_KMEM; ! 166: if ((kmem = open(kmemf, O_RDONLY, 0)) == -1) { ! 167: setsyserr("can't open %s", kmemf); ! 168: goto failed; ! 169: } ! 170: swapf = (sf == NULL) ? _PATH_DRUM : sf; ! 171: /* ! 172: * live kernel - avoid looking up nlist entries ! 173: * past X_DEADKERNEL. ! 174: */ ! 175: nl[X_DEADKERNEL].n_name = ""; ! 176: } ! 177: if (swapf != NULL && ((swap = open(swapf, O_RDONLY, 0)) == -1)) { ! 178: seterr("can't open %s", swapf); ! 179: goto failed; ! 180: } ! 181: kvmfilesopen++; ! 182: if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1) /*XXX*/ ! 183: return (-1); ! 184: return (0); ! 185: failed: ! 186: kvm_close(); ! 187: return (-1); ! 188: } ! 189: ! 190: static ! 191: kvm_init(uf, mf, sf) ! 192: char *uf, *mf, *sf; ! 193: { ! 194: if (kvmfilesopen == 0 && kvm_openfiles(NULL, NULL, NULL) == -1) ! 195: return (-1); ! 196: if (getkvars() == -1) ! 197: return (-1); ! 198: kvminit = 1; ! 199: ! 200: return (0); ! 201: } ! 202: ! 203: kvm_close() ! 204: { ! 205: if (unixx != -1) { ! 206: close(unixx); ! 207: unixx = -1; ! 208: } ! 209: if (kmem != -1) { ! 210: if (kmem != mem) ! 211: close(kmem); ! 212: /* otherwise kmem is a copy of mem, and will be closed below */ ! 213: kmem = -1; ! 214: } ! 215: if (mem != -1) { ! 216: close(mem); ! 217: mem = -1; ! 218: } ! 219: if (swap != -1) { ! 220: close(swap); ! 221: swap = -1; ! 222: } ! 223: if (db != NULL) { ! 224: dbm_close(db); ! 225: db = NULL; ! 226: } ! 227: kvminit = 0; ! 228: kvmfilesopen = 0; ! 229: deadkernel = 0; ! 230: if (Sysmap) { ! 231: free(Sysmap); ! 232: Sysmap = NULL; ! 233: } ! 234: } ! 235: ! 236: kvm_nlist(nl) ! 237: struct nlist *nl; ! 238: { ! 239: datum key, data; ! 240: char dbname[MAXPATHLEN]; ! 241: char dbversion[_BSD_LINE_MAX]; ! 242: char kversion[_BSD_LINE_MAX]; ! 243: int dbversionlen; ! 244: char symbuf[MAXSYMSIZE+1]; ! 245: struct nlist nbuf, *n; ! 246: int num, did; ! 247: ! 248: if (kvmfilesopen == 0 && kvm_openfiles(NULL, NULL, NULL) == -1) ! 249: return (-1); ! 250: if (deadkernel) ! 251: goto hard2; ! 252: /* ! 253: * initialize key datum ! 254: */ ! 255: key.dptr = symbuf; ! 256: symbuf[0] = KVMDB_NLIST; ! 257: ! 258: if (db != NULL) ! 259: goto win; /* off to the races */ ! 260: /* ! 261: * open database ! 262: */ ! 263: sprintf(dbname, "%s/kvm_%s", KVMDBDIR, basename(unixf)); ! 264: if ((db = dbm_open(dbname, O_RDONLY, 0)) == NULL) ! 265: goto hard2; ! 266: /* ! 267: * read version out of database ! 268: */ ! 269: bcopy("VERSION", symbuf+1, sizeof ("VERSION")-1); ! 270: key.dsize = (sizeof ("VERSION") - 1) + 1; ! 271: data = dbm_fetch(db, key); ! 272: if (data.dptr == NULL) ! 273: goto hard1; ! 274: bcopy(data.dptr, dbversion, data.dsize); ! 275: dbversionlen = data.dsize; ! 276: /* ! 277: * read version string from kernel memory ! 278: */ ! 279: bcopy("_version", symbuf+1, sizeof ("_version")-1); ! 280: key.dsize = (sizeof ("_version")-1) + 1; ! 281: data = dbm_fetch(db, key); ! 282: if (data.dptr == NULL) ! 283: goto hard1; ! 284: if (data.dsize != sizeof (struct nlist)) ! 285: goto hard1; ! 286: bcopy(data.dptr, &nbuf, sizeof (struct nlist)); ! 287: lseek(kmem, nbuf.n_value, 0); ! 288: if (read(kmem, kversion, dbversionlen) != dbversionlen) ! 289: goto hard1; ! 290: /* ! 291: * if they match, we win - otherwise do it the hard way ! 292: */ ! 293: if (bcmp(dbversion, kversion, dbversionlen) != 0) ! 294: goto hard1; ! 295: /* ! 296: * getem from the database. ! 297: */ ! 298: win: ! 299: num = did = 0; ! 300: for (n = nl; n->n_name && n->n_name[0]; n++, num++) { ! 301: int len; ! 302: /* ! 303: * clear out fields from users buffer ! 304: */ ! 305: n->n_type = 0; ! 306: n->n_other = 0; ! 307: n->n_desc = 0; ! 308: n->n_value = 0; ! 309: /* ! 310: * query db ! 311: */ ! 312: if ((len = strlen(n->n_name)) > MAXSYMSIZE) { ! 313: seterr("kvm_nlist: symbol too large"); ! 314: return (-1); ! 315: } ! 316: strcpy(symbuf+1, n->n_name); ! 317: key.dsize = len + 1; ! 318: data = dbm_fetch(db, key); ! 319: if (data.dptr == NULL || data.dsize != sizeof (struct nlist)) ! 320: continue; ! 321: bcopy(data.dptr, &nbuf, sizeof (struct nlist)); ! 322: n->n_value = nbuf.n_value; ! 323: n->n_type = nbuf.n_type; ! 324: n->n_desc = nbuf.n_desc; ! 325: n->n_other = nbuf.n_other; ! 326: did++; ! 327: } ! 328: return (num - did); ! 329: hard1: ! 330: dbm_close(db); ! 331: db = NULL; ! 332: hard2: ! 333: return (nlist(unixf, nl)); /* XXX seterr if -1 */ ! 334: } ! 335: ! 336: kvm_getprocs(what, arg) ! 337: { ! 338: if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1) ! 339: return (NULL); ! 340: if (!deadkernel) { ! 341: int ret, copysize; ! 342: ! 343: if ((ret = getkerninfo(what, NULL, NULL, arg)) == -1) { ! 344: setsyserr("can't get estimate for kerninfo"); ! 345: return (-1); ! 346: } ! 347: copysize = ret; ! 348: if ((kvmprocbase = (struct kinfo_proc *)malloc(copysize)) ! 349: == NULL) { ! 350: seterr("out of memory"); ! 351: return (-1); ! 352: } ! 353: if ((ret = getkerninfo(what, kvmprocbase, ©size, ! 354: arg)) == -1) { ! 355: setsyserr("can't get proc list"); ! 356: return (-1); ! 357: } ! 358: if (copysize % sizeof (struct kinfo_proc)) { ! 359: seterr("proc size mismatch (kinfo_proc: %d)", ! 360: sizeof (struct kinfo_proc)); ! 361: return (-1); ! 362: } ! 363: kvmnprocs = copysize / sizeof (struct kinfo_proc); ! 364: } else { ! 365: int nproc; ! 366: ! 367: if (kvm_read(nl[X_NPROC].n_value, &nproc, sizeof (int)) != ! 368: sizeof (int)) { ! 369: seterr("can't read nproc"); ! 370: return (-1); ! 371: } ! 372: if ((kvmprocbase = (struct kinfo_proc *) ! 373: malloc(nproc * sizeof (struct kinfo_proc))) == NULL) { ! 374: seterr("out of memory (addr: %x nproc = %d)", ! 375: nl[X_NPROC].n_value, nproc); ! 376: return (-1); ! 377: } ! 378: kvmnprocs = kvm_doprocs(what, arg, kvmprocbase); ! 379: realloc(kvmprocbase, kvmnprocs * sizeof (struct kinfo_proc)); ! 380: } ! 381: kvmprocptr = kvmprocbase; ! 382: ! 383: return (kvmnprocs); ! 384: } ! 385: ! 386: /* ! 387: * XXX - should NOT give up so easily - especially since the kernel ! 388: * may be corrupt (it died). Should gather as much information as possible. ! 389: * Follows proc ptrs instead of reading table since table may go ! 390: * away soon. ! 391: */ ! 392: static ! 393: kvm_doprocs(what, arg, buff) ! 394: int what, arg; ! 395: char *buff; ! 396: { ! 397: struct proc *p, proc; ! 398: register char *bp = buff; ! 399: int i = 0; ! 400: int doingzomb = 0; ! 401: struct eproc eproc; ! 402: struct pgrp pgrp; ! 403: struct session sess; ! 404: struct tty tty; ! 405: struct text text; ! 406: ! 407: /* allproc */ ! 408: if (kvm_read(nl[X_ALLPROC].n_value, &p, ! 409: sizeof (struct proc *)) != sizeof (struct proc *)) { ! 410: seterr("can't read allproc"); ! 411: return (-1); ! 412: } ! 413: ! 414: again: ! 415: for (; p; p = proc.p_nxt) { ! 416: if (kvm_read(p, &proc, sizeof (struct proc)) != ! 417: sizeof (struct proc)) { ! 418: seterr("can't read proc at %x", p); ! 419: return (-1); ! 420: } ! 421: switch(ki_op(what)) { ! 422: ! 423: case KINFO_PROC_PID: ! 424: if (proc.p_pid != (pid_t)arg) ! 425: continue; ! 426: break; ! 427: ! 428: ! 429: case KINFO_PROC_UID: ! 430: if (proc.p_uid != (uid_t)arg) ! 431: continue; ! 432: break; ! 433: ! 434: case KINFO_PROC_RUID: ! 435: if (proc.p_ruid != (uid_t)arg) ! 436: continue; ! 437: break; ! 438: } ! 439: /* ! 440: * gather eproc ! 441: */ ! 442: eproc.e_paddr = p; ! 443: if (kvm_read(proc.p_pgrp, &pgrp, sizeof (struct pgrp)) != ! 444: sizeof (struct pgrp)) { ! 445: seterr("can't read pgrp at %x", proc.p_pgrp); ! 446: return (-1); ! 447: } ! 448: eproc.e_sess = pgrp.pg_session; ! 449: eproc.e_pgid = pgrp.pg_id; ! 450: eproc.e_jobc = pgrp.pg_jobc; ! 451: if (kvm_read(pgrp.pg_session, &sess, sizeof (struct session)) ! 452: != sizeof (struct session)) { ! 453: seterr("can't read session at %x", pgrp.pg_session); ! 454: return (-1); ! 455: } ! 456: if ((proc.p_flag&SCTTY) && sess.s_ttyp != NULL) { ! 457: if (kvm_read(sess.s_ttyp, &tty, sizeof (struct tty)) ! 458: != sizeof (struct tty)) { ! 459: seterr("can't read tty at %x", sess.s_ttyp); ! 460: return (-1); ! 461: } ! 462: eproc.e_tdev = tty.t_dev; ! 463: eproc.e_tsess = tty.t_session; ! 464: if (tty.t_pgrp != NULL) { ! 465: if (kvm_read(tty.t_pgrp, &pgrp, sizeof (struct ! 466: pgrp)) != sizeof (struct pgrp)) { ! 467: seterr("can't read tpgrp at &x", ! 468: tty.t_pgrp); ! 469: return (-1); ! 470: } ! 471: eproc.e_tpgid = pgrp.pg_id; ! 472: } else ! 473: eproc.e_tpgid = -1; ! 474: } else ! 475: eproc.e_tdev = NODEV; ! 476: if (proc.p_wmesg) ! 477: kvm_read(proc.p_wmesg, eproc.e_wmesg, WMESGLEN); ! 478: if (proc.p_textp) { ! 479: kvm_read(proc.p_textp, &text, sizeof (text)); ! 480: eproc.e_xsize = text.x_size; ! 481: eproc.e_xrssize = text.x_rssize; ! 482: eproc.e_xccount = text.x_ccount; ! 483: eproc.e_xswrss = text.x_swrss; ! 484: } else { ! 485: eproc.e_xsize = eproc.e_xrssize = ! 486: eproc.e_xccount = eproc.e_xswrss = 0; ! 487: } ! 488: ! 489: switch(ki_op(what)) { ! 490: ! 491: case KINFO_PROC_PGRP: ! 492: if (eproc.e_pgid != (pid_t)arg) ! 493: continue; ! 494: break; ! 495: ! 496: case KINFO_PROC_TTY: ! 497: if ((proc.p_flag&SCTTY) == 0 || ! 498: eproc.e_tdev != (dev_t)arg) ! 499: continue; ! 500: break; ! 501: } ! 502: ! 503: i++; ! 504: bcopy(&proc, bp, sizeof (struct proc)); ! 505: bp += sizeof (struct proc); ! 506: bcopy(&eproc, bp, sizeof (struct eproc)); ! 507: bp+= sizeof (struct eproc); ! 508: } ! 509: if (!doingzomb) { ! 510: /* zombproc */ ! 511: if (kvm_read(nl[X_ZOMBPROC].n_value, &p, ! 512: sizeof (struct proc *)) != sizeof (struct proc *)) { ! 513: seterr("can't read zombproc"); ! 514: return (-1); ! 515: } ! 516: doingzomb = 1; ! 517: goto again; ! 518: } ! 519: ! 520: return (i); ! 521: } ! 522: ! 523: struct proc * ! 524: kvm_nextproc() ! 525: { ! 526: ! 527: if (!kvmprocbase && kvm_getprocs(0, 0) == -1) ! 528: return (NULL); ! 529: if (kvmprocptr >= (kvmprocbase + kvmnprocs)) { ! 530: seterr("end of proc list"); ! 531: return (NULL); ! 532: } ! 533: return((struct proc *)(kvmprocptr++)); ! 534: } ! 535: ! 536: struct eproc * ! 537: kvm_geteproc(p) ! 538: struct proc *p; ! 539: { ! 540: return ((struct eproc *)(((char *)p) + sizeof (struct proc))); ! 541: } ! 542: ! 543: kvm_setproc() ! 544: { ! 545: ! 546: kvmprocptr = kvmprocbase; ! 547: } ! 548: ! 549: kvm_freeprocs() ! 550: { ! 551: ! 552: if (kvmprocbase) { ! 553: free(kvmprocbase); ! 554: kvmprocbase = NULL; ! 555: } ! 556: } ! 557: ! 558: struct user * ! 559: kvm_getu(p) ! 560: struct proc *p; ! 561: { ! 562: struct pte *pteaddr, apte; ! 563: struct pte arguutl[HIGHPAGES+(CLSIZE*2)]; ! 564: register int i; ! 565: int ncl; ! 566: ! 567: if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1) ! 568: return (NULL); ! 569: if (p->p_stat == SZOMB) { ! 570: seterr("zombie process"); ! 571: return (NULL); ! 572: } ! 573: if ((p->p_flag & SLOAD) == 0) { ! 574: if (swap < 0) { ! 575: seterr("no swap"); ! 576: return (NULL); ! 577: } ! 578: (void) lseek(swap, (long)dtob(p->p_swaddr), 0); ! 579: if (read(swap, (char *)&user.user, sizeof (struct user)) != ! 580: sizeof (struct user)) { ! 581: seterr("can't read u for pid %d from %s\n", ! 582: p->p_pid, swapf); ! 583: return (NULL); ! 584: } ! 585: pcbpf = 0; ! 586: argaddr0 = 0; ! 587: argaddr1 = 0; ! 588: return (&user.user); ! 589: } ! 590: pteaddr = &Usrptmap[btokmx(p->p_p0br) + p->p_szpt - 1]; ! 591: klseek(kmem, (long)pteaddr, 0); ! 592: if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) { ! 593: seterr("can't read indir pte to get u for pid %d from %s", ! 594: p->p_pid, kmemf); ! 595: return (NULL); ! 596: } ! 597: lseek(mem, (long)ctob(pftoc(apte.pg_pfnum+1)) - sizeof(arguutl), 0); ! 598: if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) { ! 599: seterr("can't read page table for u of pid %d from %s", ! 600: p->p_pid, memf); ! 601: return (NULL); ! 602: } ! 603: if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum) ! 604: argaddr0 = ctob(pftoc(arguutl[0].pg_pfnum)); ! 605: else ! 606: argaddr0 = 0; ! 607: if (arguutl[CLSIZE*1].pg_fod == 0 && arguutl[CLSIZE*1].pg_pfnum) ! 608: argaddr1 = ctob(pftoc(arguutl[CLSIZE*1].pg_pfnum)); ! 609: else ! 610: argaddr1 = 0; ! 611: pcbpf = arguutl[CLSIZE*2].pg_pfnum; ! 612: ncl = (sizeof (struct user) + CLBYTES - 1) / CLBYTES; ! 613: while (--ncl >= 0) { ! 614: i = ncl * CLSIZE; ! 615: lseek(mem, ! 616: (long)ctob(pftoc(arguutl[(CLSIZE*2)+i].pg_pfnum)), 0); ! 617: if (read(mem, user.upages[i], CLBYTES) != CLBYTES) { ! 618: seterr("can't read page %d of u of pid %d from %s", ! 619: arguutl[(CLSIZE*2)+i].pg_pfnum, p->p_pid, memf); ! 620: return(NULL); ! 621: } ! 622: } ! 623: return (&user.user); ! 624: } ! 625: ! 626: char * ! 627: kvm_getargs(p, up) ! 628: struct proc *p; ! 629: struct user *up; ! 630: { ! 631: char cmdbuf[CLBYTES*2]; ! 632: union { ! 633: char argc[CLBYTES*2]; ! 634: int argi[CLBYTES*2/sizeof (int)]; ! 635: } argspac; ! 636: register char *cp; ! 637: register int *ip; ! 638: char c; ! 639: int nbad; ! 640: struct dblock db; ! 641: char *file; ! 642: ! 643: if (up == NULL || p->p_pid == 0 || p->p_pid == 2) ! 644: goto retucomm; ! 645: if ((p->p_flag & SLOAD) == 0 || argaddr1 == 0) { ! 646: if (swap < 0 || p->p_ssize == 0) ! 647: goto retucomm; ! 648: vstodb(0, CLSIZE, &up->u_smap, &db, 1); ! 649: (void) lseek(swap, (long)dtob(db.db_base), 0); ! 650: if (read(swap, (char *)&argspac.argc[CLBYTES], CLBYTES) ! 651: != CLBYTES) ! 652: goto bad; ! 653: vstodb(1, CLSIZE, &up->u_smap, &db, 1); ! 654: (void) lseek(swap, (long)dtob(db.db_base), 0); ! 655: if (read(swap, (char *)&argspac.argc[0], CLBYTES) != CLBYTES) ! 656: goto bad; ! 657: file = swapf; ! 658: } else { ! 659: if (argaddr0) { ! 660: lseek(mem, (long)argaddr0, 0); ! 661: if (read(mem, (char *)&argspac, CLBYTES) != CLBYTES) ! 662: goto bad; ! 663: } else ! 664: bzero(&argspac, CLBYTES); ! 665: lseek(mem, (long)argaddr1, 0); ! 666: if (read(mem, &argspac.argc[CLBYTES], CLBYTES) != CLBYTES) ! 667: goto bad; ! 668: file = memf; ! 669: } ! 670: ip = &argspac.argi[CLBYTES*2/sizeof (int)]; ! 671: ip -= 2; /* last arg word and .long 0 */ ! 672: while (*--ip) { ! 673: if (ip == argspac.argi) ! 674: goto retucomm; ! 675: } ! 676: *(char *)ip = ' '; ! 677: ip++; ! 678: nbad = 0; ! 679: for (cp = (char *)ip; cp < &argspac.argc[CLBYTES*2]; cp++) { ! 680: c = *cp & 0177; ! 681: if (c == 0) ! 682: *cp = ' '; ! 683: else if (c < ' ' || c > 0176) { ! 684: if (++nbad >= 5*(0+1)) { /* eflg -> 0 XXX */ ! 685: *cp++ = ' '; ! 686: break; ! 687: } ! 688: *cp = '?'; ! 689: } else if (0 == 0 && c == '=') { /* eflg -> 0 XXX */ ! 690: while (*--cp != ' ') ! 691: if (cp <= (char *)ip) ! 692: break; ! 693: break; ! 694: } ! 695: } ! 696: *cp = 0; ! 697: while (*--cp == ' ') ! 698: *cp = 0; ! 699: cp = (char *)ip; ! 700: (void) strncpy(cmdbuf, cp, &argspac.argc[CLBYTES*2] - cp); ! 701: if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') { ! 702: (void) strcat(cmdbuf, " ("); ! 703: (void) strncat(cmdbuf, p->p_comm, sizeof(p->p_comm)); ! 704: (void) strcat(cmdbuf, ")"); ! 705: } ! 706: return (cmdbuf); ! 707: ! 708: bad: ! 709: seterr("error locating command name for pid %d from %s\n", ! 710: p->p_pid, file); ! 711: retucomm: ! 712: (void) strcpy(cmdbuf, " ("); ! 713: (void) strncat(cmdbuf, p->p_comm, sizeof (p->p_comm)); ! 714: (void) strcat(cmdbuf, ")"); ! 715: return (cmdbuf); ! 716: } ! 717: ! 718: ! 719: static ! 720: getkvars() ! 721: { ! 722: ! 723: if (kvm_nlist(nl) == -1) ! 724: return (-1); ! 725: if (deadkernel) { ! 726: /* We must do the sys map first because klseek uses it */ ! 727: long addr; ! 728: ! 729: Syssize = nl[X_SYSSIZE].n_value; ! 730: Sysmap = (struct pte *) ! 731: calloc((unsigned) Syssize, sizeof (struct pte)); ! 732: if (Sysmap == NULL) { ! 733: seterr("out of space for Sysmap"); ! 734: return (-1); ! 735: } ! 736: addr = (long) nl[X_SYSMAP].n_value; ! 737: addr &= ~KERNBASE; ! 738: (void) lseek(kmem, addr, 0); ! 739: if (read(kmem, (char *) Sysmap, Syssize * sizeof (struct pte)) ! 740: != Syssize * sizeof (struct pte)) { ! 741: seterr("can't read Sysmap"); ! 742: return (-1); ! 743: } ! 744: #if defined(hp300) ! 745: addr = (long) nl[X_LOWRAM].n_value; ! 746: (void) lseek(kmem, addr, 0); ! 747: if (read(kmem, (char *) &lowram, sizeof (lowram)) ! 748: != sizeof (lowram)) { ! 749: seterr("can't read lowram"); ! 750: return (-1); ! 751: } ! 752: lowram = btop(lowram); ! 753: #endif ! 754: } ! 755: usrpt = (struct pte *)nl[X_USRPT].n_value; ! 756: Usrptmap = (struct pte *)nl[X_USRPTMAP].n_value; ! 757: if (kvm_read((long)nl[X_NSWAP].n_value, &nswap, sizeof (long)) != ! 758: sizeof (long)) { ! 759: seterr("can't read nswap"); ! 760: return (-1); ! 761: } ! 762: if (kvm_read((long)nl[X_DMMIN].n_value, &dmmin, sizeof (long)) != ! 763: sizeof (long)) { ! 764: seterr("can't read dmmin"); ! 765: return (-1); ! 766: } ! 767: if (kvm_read((long)nl[X_DMMAX].n_value, &dmmax, sizeof (long)) != ! 768: sizeof (long)) { ! 769: seterr("can't read dmmax"); ! 770: return (-1); ! 771: } ! 772: return (0); ! 773: } ! 774: ! 775: kvm_read(loc, buf, len) ! 776: unsigned long loc; ! 777: char *buf; ! 778: { ! 779: if (kvmfilesopen == 0 && kvm_openfiles(NULL, NULL, NULL) == -1) ! 780: return (-1); ! 781: if (iskva(loc)) { ! 782: klseek(kmem, loc, 0); ! 783: if (read(kmem, buf, len) != len) { ! 784: seterr("error reading kmem at %x\n", loc); ! 785: return (-1); ! 786: } ! 787: } else { ! 788: lseek(mem, loc, 0); ! 789: if (read(mem, buf, len) != len) { ! 790: seterr("error reading mem at %x\n", loc); ! 791: return (-1); ! 792: } ! 793: } ! 794: return (len); ! 795: } ! 796: ! 797: static ! 798: klseek(fd, loc, off) ! 799: int fd; ! 800: off_t loc; ! 801: int off; ! 802: { ! 803: ! 804: if (deadkernel) { ! 805: off_t vtophys(); ! 806: ! 807: if ((loc = vtophys(loc)) == -1) ! 808: return; ! 809: } ! 810: (void) lseek(fd, (off_t)loc, off); ! 811: } ! 812: ! 813: /* ! 814: * Given a base/size pair in virtual swap area, ! 815: * return a physical base/size pair which is the ! 816: * (largest) initial, physically contiguous block. ! 817: */ ! 818: static ! 819: vstodb(vsbase, vssize, dmp, dbp, rev) ! 820: register int vsbase; ! 821: int vssize; ! 822: struct dmap *dmp; ! 823: register struct dblock *dbp; ! 824: { ! 825: register int blk = dmmin; ! 826: register swblk_t *ip = dmp->dm_map; ! 827: ! 828: vsbase = ctod(vsbase); ! 829: vssize = ctod(vssize); ! 830: if (vsbase < 0 || vsbase + vssize > dmp->dm_size) ! 831: /*panic("vstodb")*/; ! 832: while (vsbase >= blk) { ! 833: vsbase -= blk; ! 834: if (blk < dmmax) ! 835: blk *= 2; ! 836: ip++; ! 837: } ! 838: if (*ip <= 0 || *ip + blk > nswap) ! 839: /*panic("vstodb")*/; ! 840: dbp->db_size = MIN(vssize, blk - vsbase); ! 841: dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase); ! 842: } ! 843: ! 844: static off_t ! 845: vtophys(loc) ! 846: long loc; ! 847: { ! 848: int p; ! 849: off_t newloc; ! 850: register struct pte *pte; ! 851: ! 852: newloc = loc & ~KERNBASE; ! 853: p = btop(newloc); ! 854: #if defined(vax) || defined(tahoe) ! 855: if ((loc & KERNBASE) == 0) { ! 856: seterr("vtophys: translating non-kernel address"); ! 857: return((off_t) -1); ! 858: } ! 859: #endif ! 860: if (p >= Syssize) { ! 861: seterr("vtophys: page out of bound (%d>=%d)", p, Syssize); ! 862: return((off_t) -1); ! 863: } ! 864: pte = &Sysmap[p]; ! 865: if (pte->pg_v == 0 && (pte->pg_fod || pte->pg_pfnum == 0)) { ! 866: seterr("vtophys: page not valid"); ! 867: return((off_t) -1); ! 868: } ! 869: #if defined(hp300) ! 870: if (pte->pg_pfnum < lowram) { ! 871: seterr("vtophys: non-RAM page (%d<%d)", pte->pg_pfnum, lowram); ! 872: return((off_t) -1); ! 873: } ! 874: #endif ! 875: loc = (long) (ptob(pftoc(pte->pg_pfnum)) + (loc & PGOFSET)); ! 876: return(loc); ! 877: } ! 878: ! 879: #include <varargs.h> ! 880: static char errbuf[_BSD_LINE_MAX]; ! 881: ! 882: static ! 883: seterr(va_alist) ! 884: va_dcl ! 885: { ! 886: char *fmt; ! 887: va_list ap; ! 888: ! 889: va_start(ap); ! 890: fmt = va_arg(ap, char *); ! 891: (void) vsprintf(errbuf, fmt, ap); ! 892: va_end(ap); ! 893: } ! 894: ! 895: static ! 896: setsyserr(va_alist) ! 897: va_dcl ! 898: { ! 899: char *fmt, *cp; ! 900: va_list ap; ! 901: extern int errno; ! 902: ! 903: va_start(ap); ! 904: fmt = va_arg(ap, char *); ! 905: (void) vsprintf(errbuf, fmt, ap); ! 906: for (cp=errbuf; *cp; cp++) ! 907: ; ! 908: sprintf(cp, ": %s", strerror(errno)); ! 909: va_end(ap); ! 910: } ! 911: ! 912: char * ! 913: kvm_geterr() ! 914: { ! 915: return (errbuf); ! 916: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.