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