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