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