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.c 5.21 (Berkeley) 10/24/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 seterr(), setsyserr(), vstodb(); 134 static int getkvars(), kvm_doprocs(), kvm_init(), klseek(); 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 eproc.e_flag = sess.s_ttyvp ? EPROC_CTTY : 0; 510 if (sess.s_leader == p) 511 eproc.e_flag |= EPROC_SLEADER; 512 if (proc.p_wmesg) 513 kvm_read(proc.p_wmesg, eproc.e_wmesg, WMESGLEN); 514 #ifdef NEWVM 515 (void) kvm_read(proc.p_vmspace, &eproc.e_vm, 516 sizeof (struct vmspace)); 517 eproc.e_xsize = eproc.e_xrssize = 518 eproc.e_xccount = eproc.e_xswrss = 0; 519 #else 520 if (proc.p_textp) { 521 kvm_read(proc.p_textp, &text, sizeof (text)); 522 eproc.e_xsize = text.x_size; 523 eproc.e_xrssize = text.x_rssize; 524 eproc.e_xccount = text.x_ccount; 525 eproc.e_xswrss = text.x_swrss; 526 } else { 527 eproc.e_xsize = eproc.e_xrssize = 528 eproc.e_xccount = eproc.e_xswrss = 0; 529 } 530 #endif 531 532 switch(ki_op(what)) { 533 534 case KINFO_PROC_PGRP: 535 if (eproc.e_pgid != (pid_t)arg) 536 continue; 537 break; 538 539 case KINFO_PROC_TTY: 540 if ((proc.p_flag&SCTTY) == 0 || 541 eproc.e_tdev != (dev_t)arg) 542 continue; 543 break; 544 } 545 546 i++; 547 bcopy(&proc, bp, sizeof (struct proc)); 548 bp += sizeof (struct proc); 549 bcopy(&eproc, bp, sizeof (struct eproc)); 550 bp+= sizeof (struct eproc); 551 } 552 if (!doingzomb) { 553 /* zombproc */ 554 if (kvm_read((void *) nl[X_ZOMBPROC].n_value, &p, 555 sizeof (struct proc *)) != sizeof (struct proc *)) { 556 seterr("can't read zombproc"); 557 return (-1); 558 } 559 doingzomb = 1; 560 goto again; 561 } 562 563 return (i); 564 } 565 566 struct proc * 567 kvm_nextproc() 568 { 569 570 if (!kvmprocbase && kvm_getprocs(0, 0) == -1) 571 return (NULL); 572 if (kvmprocptr >= (kvmprocbase + kvmnprocs)) { 573 seterr("end of proc list"); 574 return (NULL); 575 } 576 return((struct proc *)(kvmprocptr++)); 577 } 578 579 struct eproc * 580 kvm_geteproc(p) 581 const struct proc *p; 582 { 583 return ((struct eproc *)(((char *)p) + sizeof (struct proc))); 584 } 585 586 kvm_setproc() 587 { 588 kvmprocptr = kvmprocbase; 589 } 590 591 kvm_freeprocs() 592 { 593 594 if (kvmprocbase) { 595 free(kvmprocbase); 596 kvmprocbase = NULL; 597 } 598 } 599 600 #ifdef NEWVM 601 struct user * 602 kvm_getu(p) 603 const struct proc *p; 604 { 605 register struct kinfo_proc *kp = (struct kinfo_proc *)p; 606 register int i; 607 register char *up; 608 609 if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1) 610 return (NULL); 611 if (p->p_stat == SZOMB) { 612 seterr("zombie process"); 613 return (NULL); 614 } 615 /* 616 * Read u-area one page at a time for the benefit of post-mortems 617 */ 618 up = (char *) p->p_addr; 619 for (i = 0; i < UPAGES; i++) { 620 if (klseek(kmem, (long)up, 0) == -1) 621 return (NULL); 622 if (read(kmem, user.upages[i], CLBYTES) != CLBYTES) { 623 seterr("cant read page %x of u of pid %d from %s", 624 up, p->p_pid, kmemf); 625 return(NULL); 626 } 627 up += CLBYTES; 628 } 629 pcbpf = (int) btop(p->p_addr); /* what should this be really? */ 630 /* 631 * Conjure up a physical address for the arguments. 632 */ 633 argaddr0 = argaddr1 = 0; 634 #ifdef hp300 635 if (kp->kp_eproc.e_vm.vm_pmap.pm_ptab) { 636 struct pte pte[CLSIZE*2]; 637 638 if (klseek(kmem, 639 (long)&kp->kp_eproc.e_vm.vm_pmap.pm_ptab 640 [btoc(USRSTACK-CLBYTES*2)], 0) == -1) 641 return (NULL); 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 if (klseek(kmem, (long)pteaddr, 0) == -1) 689 return -1; 690 if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) { 691 seterr("can't read indir pte to get u for pid %d from %s", 692 p->p_pid, kmemf); 693 return (NULL); 694 } 695 lseek(mem, (long)ctob(pftoc(apte.pg_pfnum+1)) - sizeof(arguutl), 0); 696 if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) { 697 seterr("can't read page table for u of pid %d from %s", 698 p->p_pid, memf); 699 return (NULL); 700 } 701 if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum) 702 argaddr0 = ctob(pftoc(arguutl[0].pg_pfnum)); 703 else 704 argaddr0 = 0; 705 if (arguutl[CLSIZE*1].pg_fod == 0 && arguutl[CLSIZE*1].pg_pfnum) 706 argaddr1 = ctob(pftoc(arguutl[CLSIZE*1].pg_pfnum)); 707 else 708 argaddr1 = 0; 709 pcbpf = arguutl[CLSIZE*2].pg_pfnum; 710 ncl = (sizeof (struct user) + CLBYTES - 1) / CLBYTES; 711 while (--ncl >= 0) { 712 i = ncl * CLSIZE; 713 lseek(mem, 714 (long)ctob(pftoc(arguutl[(CLSIZE*2)+i].pg_pfnum)), 0); 715 if (read(mem, user.upages[i], CLBYTES) != CLBYTES) { 716 seterr("can't read page %d of u of pid %d from %s", 717 arguutl[(CLSIZE*2)+i].pg_pfnum, p->p_pid, memf); 718 return(NULL); 719 } 720 } 721 return (&user.user); 722 } 723 #endif 724 725 char * 726 kvm_getargs(p, up) 727 const struct proc *p; 728 const struct user *up; 729 { 730 static char cmdbuf[CLBYTES*2]; 731 union { 732 char argc[CLBYTES*2]; 733 int argi[CLBYTES*2/sizeof (int)]; 734 } argspac; 735 register char *cp; 736 register int *ip; 737 char c; 738 int nbad; 739 #ifndef NEWVM 740 struct dblock db; 741 #endif 742 const char *file; 743 int stkoff = 0; 744 745 #if defined(NEWVM) && defined(hp300) 746 stkoff = 20; /* XXX for sigcode */ 747 #endif 748 if (up == NULL || p->p_pid == 0 || p->p_pid == 2) 749 goto retucomm; 750 if ((p->p_flag & SLOAD) == 0 || argaddr1 == 0) { 751 #ifdef NEWVM 752 goto retucomm; /* XXX for now */ 753 #else 754 if (swap < 0 || p->p_ssize == 0) 755 goto retucomm; 756 vstodb(0, CLSIZE, &up->u_smap, &db, 1); 757 (void) lseek(swap, (long)dtob(db.db_base), 0); 758 if (read(swap, (char *)&argspac.argc[CLBYTES], CLBYTES) 759 != CLBYTES) 760 goto bad; 761 vstodb(1, CLSIZE, &up->u_smap, &db, 1); 762 (void) lseek(swap, (long)dtob(db.db_base), 0); 763 if (read(swap, (char *)&argspac.argc[0], CLBYTES) != CLBYTES) 764 goto bad; 765 file = swapf; 766 #endif 767 } else { 768 if (argaddr0) { 769 lseek(mem, (long)argaddr0, 0); 770 if (read(mem, (char *)&argspac, CLBYTES) != CLBYTES) 771 goto bad; 772 } else 773 bzero(&argspac, CLBYTES); 774 lseek(mem, (long)argaddr1, 0); 775 if (read(mem, &argspac.argc[CLBYTES], CLBYTES) != CLBYTES) 776 goto bad; 777 file = (char *) memf; 778 } 779 ip = &argspac.argi[CLBYTES*2/sizeof (int)]; 780 ip -= 2; /* last arg word and .long 0 */ 781 ip -= stkoff / sizeof (int); 782 while (*--ip) { 783 if (ip == argspac.argi) 784 goto retucomm; 785 } 786 *(char *)ip = ' '; 787 ip++; 788 nbad = 0; 789 for (cp = (char *)ip; cp < &argspac.argc[CLBYTES*2-stkoff]; cp++) { 790 c = *cp & 0177; 791 if (c == 0) 792 *cp = ' '; 793 else if (c < ' ' || c > 0176) { 794 if (++nbad >= 5*(0+1)) { /* eflg -> 0 XXX */ 795 *cp++ = ' '; 796 break; 797 } 798 *cp = '?'; 799 } else if (0 == 0 && c == '=') { /* eflg -> 0 XXX */ 800 while (*--cp != ' ') 801 if (cp <= (char *)ip) 802 break; 803 break; 804 } 805 } 806 *cp = 0; 807 while (*--cp == ' ') 808 *cp = 0; 809 cp = (char *)ip; 810 (void) strncpy(cmdbuf, cp, &argspac.argc[CLBYTES*2] - cp); 811 if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') { 812 (void) strcat(cmdbuf, " ("); 813 (void) strncat(cmdbuf, p->p_comm, sizeof(p->p_comm)); 814 (void) strcat(cmdbuf, ")"); 815 } 816 return (cmdbuf); 817 818 bad: 819 seterr("error locating command name for pid %d from %s", 820 p->p_pid, file); 821 retucomm: 822 (void) strcpy(cmdbuf, " ("); 823 (void) strncat(cmdbuf, p->p_comm, sizeof (p->p_comm)); 824 (void) strcat(cmdbuf, ")"); 825 return (cmdbuf); 826 } 827 828 829 static 830 getkvars() 831 { 832 int ret; 833 static nlisterr(); 834 835 if ((ret = kvm_nlist(nl)) == -1) 836 return (-1); 837 else if (ret > 0) 838 nlisterr(nl); 839 if (deadkernel) { 840 /* We must do the sys map first because klseek uses it */ 841 long addr; 842 #if defined(hp300) 843 addr = (long) nl[X_LOWRAM].n_value; 844 (void) lseek(kmem, addr, 0); 845 if (read(kmem, (char *) &lowram, sizeof (lowram)) 846 != sizeof (lowram)) { 847 seterr("can't read lowram"); 848 return (-1); 849 } 850 lowram = btop(lowram); 851 Sysseg = (struct ste *) malloc(NBPG); 852 if (Sysseg == NULL) { 853 seterr("out of space for Sysseg"); 854 return (-1); 855 } 856 addr = (long) nl[X_SYSSEG].n_value; 857 (void) lseek(kmem, addr, 0); 858 read(kmem, (char *)&addr, sizeof(addr)); 859 (void) lseek(kmem, (long)addr, 0); 860 if (read(kmem, (char *) Sysseg, NBPG) != NBPG) { 861 seterr("can't read Sysseg"); 862 return (-1); 863 } 864 #endif 865 } 866 if (kvm_read((void *) nl[X_NSWAP].n_value, &nswap, sizeof (long)) != 867 sizeof (long)) { 868 seterr("can't read nswap"); 869 return (-1); 870 } 871 if (kvm_read((void *) nl[X_DMMIN].n_value, &dmmin, sizeof (long)) != 872 sizeof (long)) { 873 seterr("can't read dmmin"); 874 return (-1); 875 } 876 if (kvm_read((void *) nl[X_DMMAX].n_value, &dmmax, sizeof (long)) != 877 sizeof (long)) { 878 seterr("can't read dmmax"); 879 return (-1); 880 } 881 return (0); 882 } 883 884 static 885 nlisterr(nl) 886 struct nlist nl[]; 887 { 888 int i; 889 890 fprintf(stderr, "kvm_nlist: can't find following names:"); 891 for (i = 0; nl[i].n_name[0] != '\0'; i++) 892 if (nl[i].n_value == 0) 893 fprintf(stderr, " %s", nl[i].n_name); 894 fprintf(stderr, ": continuing...\n"); 895 } 896 897 898 kvm_read(loc, buf, len) 899 void *loc; 900 void *buf; 901 { 902 if (kvmfilesopen == 0 && kvm_openfiles(NULL, NULL, NULL) == -1) 903 return (-1); 904 if (iskva(loc)) { 905 if (klseek(kmem, (off_t) loc, 0) == -1) 906 return -1; 907 if (read(kmem, buf, len) != len) { 908 seterr("error reading kmem at %x", loc); 909 return (-1); 910 } 911 } else { 912 lseek(mem, (off_t) loc, 0); 913 if (read(mem, buf, len) != len) { 914 seterr("error reading mem at %x", loc); 915 return (-1); 916 } 917 } 918 return (len); 919 } 920 921 static 922 klseek(fd, loc, off) 923 int fd; 924 off_t loc; 925 int off; 926 { 927 928 if (deadkernel) { 929 if ((loc = vtophys(loc)) == -1) 930 return -1; 931 } 932 (void)lseek(fd, (off_t)loc, off); 933 return (0); 934 } 935 936 #ifndef NEWVM 937 /* 938 * Given a base/size pair in virtual swap area, 939 * return a physical base/size pair which is the 940 * (largest) initial, physically contiguous block. 941 */ 942 static void 943 vstodb(vsbase, vssize, dmp, dbp, rev) 944 register int vsbase; 945 int vssize; 946 struct dmap *dmp; 947 register struct dblock *dbp; 948 { 949 register int blk = dmmin; 950 register swblk_t *ip = dmp->dm_map; 951 952 vsbase = ctod(vsbase); 953 vssize = ctod(vssize); 954 if (vsbase < 0 || vsbase + vssize > dmp->dm_size) 955 /*panic("vstodb")*/; 956 while (vsbase >= blk) { 957 vsbase -= blk; 958 if (blk < dmmax) 959 blk *= 2; 960 ip++; 961 } 962 if (*ip <= 0 || *ip + blk > nswap) 963 /*panic("vstodb")*/; 964 dbp->db_size = MIN(vssize, blk - vsbase); 965 dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase); 966 } 967 #endif 968 969 #ifdef NEWVM 970 static off_t 971 vtophys(loc) 972 long loc; 973 { 974 off_t newloc = (off_t) -1; 975 #ifdef hp300 976 int p, ste, pte; 977 978 ste = *(int *)&Sysseg[loc >> SG_ISHIFT]; 979 if ((ste & SG_V) == 0) { 980 seterr("vtophys: segment not valid (%x)", ste); 981 return((off_t) -1); 982 } 983 p = btop(loc & SG_PMASK); 984 newloc = (ste & SG_FRAME) + (p * sizeof(struct pte)); 985 (void) lseek(kmem, (long)(newloc-(off_t)ptob(lowram)), 0); 986 if (read(kmem, (char *)&pte, sizeof pte) != sizeof pte) { 987 seterr("vtophys: cannot locate pte"); 988 return((off_t) -1); 989 } 990 newloc = pte & PG_FRAME; 991 if (pte == PG_NV || newloc < (off_t)ptob(lowram)) { 992 seterr("vtophys: page not valid"); 993 return((off_t) -1); 994 } 995 newloc = (newloc - (off_t)ptob(lowram)) + (loc & PGOFSET); 996 #endif 997 return((off_t) newloc); 998 } 999 #else 1000 static off_t 1001 vtophys(loc) 1002 long loc; 1003 { 1004 int p; 1005 off_t newloc; 1006 register struct pte *pte; 1007 1008 newloc = loc & ~KERNBASE; 1009 p = btop(newloc); 1010 #if defined(vax) || defined(tahoe) 1011 if ((loc & KERNBASE) == 0) { 1012 seterr("vtophys: translating non-kernel address"); 1013 return((off_t) -1); 1014 } 1015 #endif 1016 if (p >= Syssize) { 1017 seterr("vtophys: page out of bound (%d>=%d)", p, Syssize); 1018 return((off_t) -1); 1019 } 1020 pte = &Sysmap[p]; 1021 if (pte->pg_v == 0 && (pte->pg_fod || pte->pg_pfnum == 0)) { 1022 seterr("vtophys: page not valid"); 1023 return((off_t) -1); 1024 } 1025 #if defined(hp300) 1026 if (pte->pg_pfnum < lowram) { 1027 seterr("vtophys: non-RAM page (%d<%d)", pte->pg_pfnum, lowram); 1028 return((off_t) -1); 1029 } 1030 #endif 1031 loc = (long) (ptob(pftoc(pte->pg_pfnum)) + (loc & PGOFSET)); 1032 return(loc); 1033 } 1034 #endif 1035 1036 #include <varargs.h> 1037 static char errbuf[_POSIX2_LINE_MAX]; 1038 1039 static void 1040 seterr(va_alist) 1041 va_dcl 1042 { 1043 char *fmt; 1044 va_list ap; 1045 1046 va_start(ap); 1047 fmt = va_arg(ap, char *); 1048 (void) vsnprintf(errbuf, _POSIX2_LINE_MAX, fmt, ap); 1049 va_end(ap); 1050 } 1051 1052 static void 1053 setsyserr(va_alist) 1054 va_dcl 1055 { 1056 char *fmt, *cp; 1057 va_list ap; 1058 extern int errno; 1059 1060 va_start(ap); 1061 fmt = va_arg(ap, char *); 1062 (void) vsnprintf(errbuf, _POSIX2_LINE_MAX, fmt, ap); 1063 for (cp=errbuf; *cp; cp++) 1064 ; 1065 snprintf(cp, _POSIX2_LINE_MAX - (cp - errbuf), ": %s", strerror(errno)); 1066 va_end(ap); 1067 } 1068 1069 char * 1070 kvm_geterr() 1071 { 1072 return (errbuf); 1073 } 1074