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