1 /* $NetBSD: kvm_proc.c,v 1.17 1997/06/20 05:18:22 mikel Exp $ */ 2 3 /*- 4 * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. 5 * Copyright (c) 1989, 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software developed by the Computer Systems 9 * Engineering group at Lawrence Berkeley Laboratory under DARPA contract 10 * BG 91-66 and contributed to Berkeley. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 */ 40 41 #if defined(LIBC_SCCS) && !defined(lint) 42 #if 0 43 static char sccsid[] = "@(#)kvm_proc.c 8.3 (Berkeley) 9/23/93"; 44 #else 45 static char *rcsid = "$NetBSD: kvm_proc.c,v 1.17 1997/06/20 05:18:22 mikel Exp $"; 46 #endif 47 #endif /* LIBC_SCCS and not lint */ 48 49 /* 50 * Proc traversal interface for kvm. ps and w are (probably) the exclusive 51 * users of this code, so we've factored it out into a separate module. 52 * Thus, we keep this grunge out of the other kvm applications (i.e., 53 * most other applications are interested only in open/close/read/nlist). 54 */ 55 56 #include <sys/param.h> 57 #include <sys/user.h> 58 #include <sys/proc.h> 59 #include <sys/exec.h> 60 #include <sys/stat.h> 61 #include <sys/ioctl.h> 62 #include <sys/tty.h> 63 #include <stdlib.h> 64 #include <string.h> 65 #include <unistd.h> 66 #include <nlist.h> 67 #include <kvm.h> 68 69 #include <vm/vm.h> 70 #include <vm/vm_param.h> 71 #include <vm/swap_pager.h> 72 73 #include <sys/sysctl.h> 74 75 #include <limits.h> 76 #include <db.h> 77 #include <paths.h> 78 79 #include "kvm_private.h" 80 81 #define KREAD(kd, addr, obj) \ 82 (kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj)) 83 84 int _kvm_readfromcore __P((kvm_t *, u_long, u_long)); 85 int _kvm_readfrompager __P((kvm_t *, struct vm_object *, u_long)); 86 ssize_t kvm_uread __P((kvm_t *, const struct proc *, u_long, char *, 87 size_t)); 88 89 static char **kvm_argv __P((kvm_t *, const struct proc *, u_long, int, 90 int)); 91 static int kvm_deadprocs __P((kvm_t *, int, int, u_long, u_long, int)); 92 static char **kvm_doargv __P((kvm_t *, const struct kinfo_proc *, int, 93 void (*)(struct ps_strings *, u_long *, int *))); 94 static int kvm_proclist __P((kvm_t *, int, int, struct proc *, 95 struct kinfo_proc *, int)); 96 static int proc_verify __P((kvm_t *, u_long, const struct proc *)); 97 static void ps_str_a __P((struct ps_strings *, u_long *, int *)); 98 static void ps_str_e __P((struct ps_strings *, u_long *, int *)); 99 100 char * 101 _kvm_uread(kd, p, va, cnt) 102 kvm_t *kd; 103 const struct proc *p; 104 u_long va; 105 u_long *cnt; 106 { 107 register u_long addr, head; 108 register u_long offset; 109 struct vm_map_entry vme; 110 struct vm_object vmo; 111 int rv; 112 113 if (kd->swapspc == 0) { 114 kd->swapspc = (char *)_kvm_malloc(kd, kd->nbpg); 115 if (kd->swapspc == 0) 116 return (0); 117 } 118 119 /* 120 * Look through the address map for the memory object 121 * that corresponds to the given virtual address. 122 * The header just has the entire valid range. 123 */ 124 head = (u_long)&p->p_vmspace->vm_map.header; 125 addr = head; 126 while (1) { 127 if (KREAD(kd, addr, &vme)) 128 return (0); 129 130 if (va >= vme.start && va < vme.end && 131 vme.object.vm_object != 0) 132 break; 133 134 addr = (u_long)vme.next; 135 if (addr == head) 136 return (0); 137 } 138 139 /* 140 * We found the right object -- follow shadow links. 141 */ 142 offset = va - vme.start + vme.offset; 143 addr = (u_long)vme.object.vm_object; 144 145 while (1) { 146 /* Try reading the page from core first. */ 147 if ((rv = _kvm_readfromcore(kd, addr, offset))) 148 break; 149 150 if (KREAD(kd, addr, &vmo)) 151 return (0); 152 153 /* If there is a pager here, see if it has the page. */ 154 if (vmo.pager != 0 && 155 (rv = _kvm_readfrompager(kd, &vmo, offset))) 156 break; 157 158 /* Move down the shadow chain. */ 159 addr = (u_long)vmo.shadow; 160 if (addr == 0) 161 return (0); 162 offset += vmo.shadow_offset; 163 } 164 165 if (rv == -1) 166 return (0); 167 168 /* Found the page. */ 169 offset %= kd->nbpg; 170 *cnt = kd->nbpg - offset; 171 return (&kd->swapspc[offset]); 172 } 173 174 #define vm_page_hash(kd, object, offset) \ 175 (((u_long)object + (u_long)(offset / kd->nbpg)) & kd->vm_page_hash_mask) 176 177 int 178 _kvm_coreinit(kd) 179 kvm_t *kd; 180 { 181 struct nlist nlist[3]; 182 183 nlist[0].n_name = "_vm_page_buckets"; 184 nlist[1].n_name = "_vm_page_hash_mask"; 185 nlist[2].n_name = 0; 186 if (kvm_nlist(kd, nlist) != 0) 187 return (-1); 188 189 if (KREAD(kd, nlist[0].n_value, &kd->vm_page_buckets) || 190 KREAD(kd, nlist[1].n_value, &kd->vm_page_hash_mask)) 191 return (-1); 192 193 return (0); 194 } 195 196 int 197 _kvm_readfromcore(kd, object, offset) 198 kvm_t *kd; 199 u_long object, offset; 200 { 201 u_long addr; 202 struct pglist bucket; 203 struct vm_page mem; 204 off_t seekpoint; 205 206 if (kd->vm_page_buckets == 0 && 207 _kvm_coreinit(kd)) 208 return (-1); 209 210 addr = (u_long)&kd->vm_page_buckets[vm_page_hash(kd, object, offset)]; 211 if (KREAD(kd, addr, &bucket)) 212 return (-1); 213 214 addr = (u_long)bucket.tqh_first; 215 offset &= ~(kd->nbpg -1); 216 while (1) { 217 if (addr == 0) 218 return (0); 219 220 if (KREAD(kd, addr, &mem)) 221 return (-1); 222 223 if ((u_long)mem.object == object && 224 (u_long)mem.offset == offset) 225 break; 226 227 addr = (u_long)mem.hashq.tqe_next; 228 } 229 230 seekpoint = mem.phys_addr; 231 232 if (lseek(kd->pmfd, seekpoint, 0) == -1) 233 return (-1); 234 if (read(kd->pmfd, kd->swapspc, kd->nbpg) != kd->nbpg) 235 return (-1); 236 237 return (1); 238 } 239 240 int 241 _kvm_readfrompager(kd, vmop, offset) 242 kvm_t *kd; 243 struct vm_object *vmop; 244 u_long offset; 245 { 246 u_long addr; 247 struct pager_struct pager; 248 struct swpager swap; 249 int ix; 250 struct swblock swb; 251 off_t seekpoint; 252 253 /* Read in the pager info and make sure it's a swap device. */ 254 addr = (u_long)vmop->pager; 255 if (KREAD(kd, addr, &pager) || pager.pg_type != PG_SWAP) 256 return (-1); 257 258 /* Read in the swap_pager private data. */ 259 addr = (u_long)pager.pg_data; 260 if (KREAD(kd, addr, &swap)) 261 return (-1); 262 263 /* 264 * Calculate the paging offset, and make sure it's within the 265 * bounds of the pager. 266 */ 267 offset += vmop->paging_offset; 268 ix = offset / dbtob(swap.sw_bsize); 269 #if 0 270 if (swap.sw_blocks == 0 || ix >= swap.sw_nblocks) 271 return (-1); 272 #else 273 if (swap.sw_blocks == 0 || ix >= swap.sw_nblocks) { 274 int i; 275 printf("BUG BUG BUG BUG:\n"); 276 printf("object %p offset %lx pgoffset %lx ", 277 vmop, offset - vmop->paging_offset, 278 (u_long)vmop->paging_offset); 279 printf("pager %p swpager %p\n", 280 vmop->pager, pager.pg_data); 281 printf("osize %lx bsize %x blocks %p nblocks %x\n", 282 (u_long)swap.sw_osize, swap.sw_bsize, swap.sw_blocks, 283 swap.sw_nblocks); 284 for (ix = 0; ix < swap.sw_nblocks; ix++) { 285 addr = (u_long)&swap.sw_blocks[ix]; 286 if (KREAD(kd, addr, &swb)) 287 return (0); 288 printf("sw_blocks[%d]: block %x mask %x\n", ix, 289 swb.swb_block, swb.swb_mask); 290 } 291 return (-1); 292 } 293 #endif 294 295 /* Read in the swap records. */ 296 addr = (u_long)&swap.sw_blocks[ix]; 297 if (KREAD(kd, addr, &swb)) 298 return (-1); 299 300 /* Calculate offset within pager. */ 301 offset %= dbtob(swap.sw_bsize); 302 303 /* Check that the page is actually present. */ 304 if ((swb.swb_mask & (1 << (offset / kd->nbpg))) == 0) 305 return (0); 306 307 if (!ISALIVE(kd)) 308 return (-1); 309 310 /* Calculate the physical address and read the page. */ 311 seekpoint = dbtob(swb.swb_block) + (offset & ~(kd->nbpg -1)); 312 313 if (lseek(kd->swfd, seekpoint, 0) == -1) 314 return (-1); 315 if (read(kd->swfd, kd->swapspc, kd->nbpg) != kd->nbpg) 316 return (-1); 317 318 return (1); 319 } 320 321 /* 322 * Read proc's from memory file into buffer bp, which has space to hold 323 * at most maxcnt procs. 324 */ 325 static int 326 kvm_proclist(kd, what, arg, p, bp, maxcnt) 327 kvm_t *kd; 328 int what, arg; 329 struct proc *p; 330 struct kinfo_proc *bp; 331 int maxcnt; 332 { 333 register int cnt = 0; 334 struct eproc eproc; 335 struct pgrp pgrp; 336 struct session sess; 337 struct tty tty; 338 struct proc proc; 339 340 for (; cnt < maxcnt && p != NULL; p = proc.p_list.le_next) { 341 if (KREAD(kd, (u_long)p, &proc)) { 342 _kvm_err(kd, kd->program, "can't read proc at %x", p); 343 return (-1); 344 } 345 if (KREAD(kd, (u_long)proc.p_cred, &eproc.e_pcred) == 0) 346 KREAD(kd, (u_long)eproc.e_pcred.pc_ucred, 347 &eproc.e_ucred); 348 349 switch(what) { 350 351 case KERN_PROC_PID: 352 if (proc.p_pid != (pid_t)arg) 353 continue; 354 break; 355 356 case KERN_PROC_UID: 357 if (eproc.e_ucred.cr_uid != (uid_t)arg) 358 continue; 359 break; 360 361 case KERN_PROC_RUID: 362 if (eproc.e_pcred.p_ruid != (uid_t)arg) 363 continue; 364 break; 365 } 366 /* 367 * We're going to add another proc to the set. If this 368 * will overflow the buffer, assume the reason is because 369 * nprocs (or the proc list) is corrupt and declare an error. 370 */ 371 if (cnt >= maxcnt) { 372 _kvm_err(kd, kd->program, "nprocs corrupt"); 373 return (-1); 374 } 375 /* 376 * gather eproc 377 */ 378 eproc.e_paddr = p; 379 if (KREAD(kd, (u_long)proc.p_pgrp, &pgrp)) { 380 _kvm_err(kd, kd->program, "can't read pgrp at %x", 381 proc.p_pgrp); 382 return (-1); 383 } 384 eproc.e_sess = pgrp.pg_session; 385 eproc.e_pgid = pgrp.pg_id; 386 eproc.e_jobc = pgrp.pg_jobc; 387 if (KREAD(kd, (u_long)pgrp.pg_session, &sess)) { 388 _kvm_err(kd, kd->program, "can't read session at %x", 389 pgrp.pg_session); 390 return (-1); 391 } 392 if ((proc.p_flag & P_CONTROLT) && sess.s_ttyp != NULL) { 393 if (KREAD(kd, (u_long)sess.s_ttyp, &tty)) { 394 _kvm_err(kd, kd->program, 395 "can't read tty at %x", sess.s_ttyp); 396 return (-1); 397 } 398 eproc.e_tdev = tty.t_dev; 399 eproc.e_tsess = tty.t_session; 400 if (tty.t_pgrp != NULL) { 401 if (KREAD(kd, (u_long)tty.t_pgrp, &pgrp)) { 402 _kvm_err(kd, kd->program, 403 "can't read tpgrp at &x", 404 tty.t_pgrp); 405 return (-1); 406 } 407 eproc.e_tpgid = pgrp.pg_id; 408 } else 409 eproc.e_tpgid = -1; 410 } else 411 eproc.e_tdev = NODEV; 412 eproc.e_flag = sess.s_ttyvp ? EPROC_CTTY : 0; 413 if (sess.s_leader == p) 414 eproc.e_flag |= EPROC_SLEADER; 415 if (proc.p_wmesg) 416 (void)kvm_read(kd, (u_long)proc.p_wmesg, 417 eproc.e_wmesg, WMESGLEN); 418 419 (void)kvm_read(kd, (u_long)proc.p_vmspace, 420 (char *)&eproc.e_vm, sizeof(eproc.e_vm)); 421 422 eproc.e_xsize = eproc.e_xrssize = 0; 423 eproc.e_xccount = eproc.e_xswrss = 0; 424 425 switch (what) { 426 427 case KERN_PROC_PGRP: 428 if (eproc.e_pgid != (pid_t)arg) 429 continue; 430 break; 431 432 case KERN_PROC_TTY: 433 if ((proc.p_flag & P_CONTROLT) == 0 || 434 eproc.e_tdev != (dev_t)arg) 435 continue; 436 break; 437 } 438 bcopy(&proc, &bp->kp_proc, sizeof(proc)); 439 bcopy(&eproc, &bp->kp_eproc, sizeof(eproc)); 440 ++bp; 441 ++cnt; 442 } 443 return (cnt); 444 } 445 446 /* 447 * Build proc info array by reading in proc list from a crash dump. 448 * Return number of procs read. maxcnt is the max we will read. 449 */ 450 static int 451 kvm_deadprocs(kd, what, arg, a_allproc, a_zombproc, maxcnt) 452 kvm_t *kd; 453 int what, arg; 454 u_long a_allproc; 455 u_long a_zombproc; 456 int maxcnt; 457 { 458 register struct kinfo_proc *bp = kd->procbase; 459 register int acnt, zcnt; 460 struct proc *p; 461 462 if (KREAD(kd, a_allproc, &p)) { 463 _kvm_err(kd, kd->program, "cannot read allproc"); 464 return (-1); 465 } 466 acnt = kvm_proclist(kd, what, arg, p, bp, maxcnt); 467 if (acnt < 0) 468 return (acnt); 469 470 if (KREAD(kd, a_zombproc, &p)) { 471 _kvm_err(kd, kd->program, "cannot read zombproc"); 472 return (-1); 473 } 474 zcnt = kvm_proclist(kd, what, arg, p, bp + acnt, maxcnt - acnt); 475 if (zcnt < 0) 476 zcnt = 0; 477 478 return (acnt + zcnt); 479 } 480 481 struct kinfo_proc * 482 kvm_getprocs(kd, op, arg, cnt) 483 kvm_t *kd; 484 int op, arg; 485 int *cnt; 486 { 487 size_t size; 488 int mib[4], st, nprocs; 489 490 if (kd->procbase != 0) { 491 free((void *)kd->procbase); 492 /* 493 * Clear this pointer in case this call fails. Otherwise, 494 * kvm_close() will free it again. 495 */ 496 kd->procbase = 0; 497 } 498 if (ISALIVE(kd)) { 499 size = 0; 500 mib[0] = CTL_KERN; 501 mib[1] = KERN_PROC; 502 mib[2] = op; 503 mib[3] = arg; 504 st = sysctl(mib, 4, NULL, &size, NULL, 0); 505 if (st == -1) { 506 _kvm_syserr(kd, kd->program, "kvm_getprocs"); 507 return (0); 508 } 509 kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); 510 if (kd->procbase == 0) 511 return (0); 512 st = sysctl(mib, 4, kd->procbase, &size, NULL, 0); 513 if (st == -1) { 514 _kvm_syserr(kd, kd->program, "kvm_getprocs"); 515 return (0); 516 } 517 if (size % sizeof(struct kinfo_proc) != 0) { 518 _kvm_err(kd, kd->program, 519 "proc size mismatch (%d total, %d chunks)", 520 size, sizeof(struct kinfo_proc)); 521 return (0); 522 } 523 nprocs = size / sizeof(struct kinfo_proc); 524 } else { 525 struct nlist nl[4], *p; 526 527 nl[0].n_name = "_nprocs"; 528 nl[1].n_name = "_allproc"; 529 nl[2].n_name = "_zombproc"; 530 nl[3].n_name = 0; 531 532 if (kvm_nlist(kd, nl) != 0) { 533 for (p = nl; p->n_type != 0; ++p) 534 ; 535 _kvm_err(kd, kd->program, 536 "%s: no such symbol", p->n_name); 537 return (0); 538 } 539 if (KREAD(kd, nl[0].n_value, &nprocs)) { 540 _kvm_err(kd, kd->program, "can't read nprocs"); 541 return (0); 542 } 543 size = nprocs * sizeof(struct kinfo_proc); 544 kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); 545 if (kd->procbase == 0) 546 return (0); 547 548 nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value, 549 nl[2].n_value, nprocs); 550 #ifdef notdef 551 size = nprocs * sizeof(struct kinfo_proc); 552 (void)realloc(kd->procbase, size); 553 #endif 554 } 555 *cnt = nprocs; 556 return (kd->procbase); 557 } 558 559 void 560 _kvm_freeprocs(kd) 561 kvm_t *kd; 562 { 563 if (kd->procbase) { 564 free(kd->procbase); 565 kd->procbase = 0; 566 } 567 } 568 569 void * 570 _kvm_realloc(kd, p, n) 571 kvm_t *kd; 572 void *p; 573 size_t n; 574 { 575 void *np = (void *)realloc(p, n); 576 577 if (np == 0) 578 _kvm_err(kd, kd->program, "out of memory"); 579 return (np); 580 } 581 582 #ifndef MAX 583 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 584 #endif 585 586 /* 587 * Read in an argument vector from the user address space of process p. 588 * addr if the user-space base address of narg null-terminated contiguous 589 * strings. This is used to read in both the command arguments and 590 * environment strings. Read at most maxcnt characters of strings. 591 */ 592 static char ** 593 kvm_argv(kd, p, addr, narg, maxcnt) 594 kvm_t *kd; 595 const struct proc *p; 596 register u_long addr; 597 register int narg; 598 register int maxcnt; 599 { 600 register char *np, *cp, *ep, *ap; 601 register u_long oaddr = -1; 602 register int len, cc; 603 register char **argv; 604 605 /* 606 * Check that there aren't an unreasonable number of agruments, 607 * and that the address is in user space. 608 */ 609 if (narg > ARG_MAX || addr < VM_MIN_ADDRESS || addr >= VM_MAXUSER_ADDRESS) 610 return (0); 611 612 if (kd->argv == 0) { 613 /* 614 * Try to avoid reallocs. 615 */ 616 kd->argc = MAX(narg + 1, 32); 617 kd->argv = (char **)_kvm_malloc(kd, kd->argc * 618 sizeof(*kd->argv)); 619 if (kd->argv == 0) 620 return (0); 621 } else if (narg + 1 > kd->argc) { 622 kd->argc = MAX(2 * kd->argc, narg + 1); 623 kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc * 624 sizeof(*kd->argv)); 625 if (kd->argv == 0) 626 return (0); 627 } 628 if (kd->argspc == 0) { 629 kd->argspc = (char *)_kvm_malloc(kd, kd->nbpg); 630 if (kd->argspc == 0) 631 return (0); 632 kd->arglen = kd->nbpg; 633 } 634 if (kd->argbuf == 0) { 635 kd->argbuf = (char *)_kvm_malloc(kd, kd->nbpg); 636 if (kd->argbuf == 0) 637 return (0); 638 } 639 cc = sizeof(char *) * narg; 640 if (kvm_uread(kd, p, addr, (char *)kd->argv, cc) != cc) 641 return (0); 642 ap = np = kd->argspc; 643 argv = kd->argv; 644 len = 0; 645 /* 646 * Loop over pages, filling in the argument vector. 647 */ 648 while (argv < kd->argv + narg && *argv != 0) { 649 addr = (u_long)*argv & ~(kd->nbpg - 1); 650 if (addr != oaddr) { 651 if (kvm_uread(kd, p, addr, kd->argbuf, kd->nbpg) != 652 kd->nbpg) 653 return (0); 654 oaddr = addr; 655 } 656 addr = (u_long)*argv & (kd->nbpg - 1); 657 cp = kd->argbuf + addr; 658 cc = kd->nbpg - addr; 659 if (maxcnt > 0 && cc > maxcnt - len) 660 cc = maxcnt - len;; 661 ep = memchr(cp, '\0', cc); 662 if (ep != 0) 663 cc = ep - cp + 1; 664 if (len + cc > kd->arglen) { 665 register int off; 666 register char **pp; 667 register char *op = kd->argspc; 668 669 kd->arglen *= 2; 670 kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, 671 kd->arglen); 672 if (kd->argspc == 0) 673 return (0); 674 /* 675 * Adjust argv pointers in case realloc moved 676 * the string space. 677 */ 678 off = kd->argspc - op; 679 for (pp = kd->argv; pp < argv; pp++) 680 *pp += off; 681 ap += off; 682 np += off; 683 } 684 memcpy(np, cp, cc); 685 np += cc; 686 len += cc; 687 if (ep != 0) { 688 *argv++ = ap; 689 ap = np; 690 } else 691 *argv += cc; 692 if (maxcnt > 0 && len >= maxcnt) { 693 /* 694 * We're stopping prematurely. Terminate the 695 * current string. 696 */ 697 if (ep == 0) { 698 *np = '\0'; 699 *argv++ = ap; 700 } 701 break; 702 } 703 } 704 /* Make sure argv is terminated. */ 705 *argv = 0; 706 return (kd->argv); 707 } 708 709 static void 710 ps_str_a(p, addr, n) 711 struct ps_strings *p; 712 u_long *addr; 713 int *n; 714 { 715 *addr = (u_long)p->ps_argvstr; 716 *n = p->ps_nargvstr; 717 } 718 719 static void 720 ps_str_e(p, addr, n) 721 struct ps_strings *p; 722 u_long *addr; 723 int *n; 724 { 725 *addr = (u_long)p->ps_envstr; 726 *n = p->ps_nenvstr; 727 } 728 729 /* 730 * Determine if the proc indicated by p is still active. 731 * This test is not 100% foolproof in theory, but chances of 732 * being wrong are very low. 733 */ 734 static int 735 proc_verify(kd, kernp, p) 736 kvm_t *kd; 737 u_long kernp; 738 const struct proc *p; 739 { 740 struct proc kernproc; 741 742 /* 743 * Just read in the whole proc. It's not that big relative 744 * to the cost of the read system call. 745 */ 746 if (kvm_read(kd, kernp, (char *)&kernproc, sizeof(kernproc)) != 747 sizeof(kernproc)) 748 return (0); 749 return (p->p_pid == kernproc.p_pid && 750 (kernproc.p_stat != SZOMB || p->p_stat == SZOMB)); 751 } 752 753 static char ** 754 kvm_doargv(kd, kp, nchr, info) 755 kvm_t *kd; 756 const struct kinfo_proc *kp; 757 int nchr; 758 void (*info)(struct ps_strings *, u_long *, int *); 759 { 760 register const struct proc *p = &kp->kp_proc; 761 register char **ap; 762 u_long addr; 763 int cnt; 764 struct ps_strings arginfo; 765 766 /* 767 * Pointers are stored at the top of the user stack. 768 */ 769 if (p->p_stat == SZOMB || 770 kvm_uread(kd, p, USRSTACK - sizeof(arginfo), (char *)&arginfo, 771 sizeof(arginfo)) != sizeof(arginfo)) 772 return (0); 773 774 (*info)(&arginfo, &addr, &cnt); 775 if (cnt == 0) 776 return (0); 777 ap = kvm_argv(kd, p, addr, cnt, nchr); 778 /* 779 * For live kernels, make sure this process didn't go away. 780 */ 781 if (ap != 0 && ISALIVE(kd) && 782 !proc_verify(kd, (u_long)kp->kp_eproc.e_paddr, p)) 783 ap = 0; 784 return (ap); 785 } 786 787 /* 788 * Get the command args. This code is now machine independent. 789 */ 790 char ** 791 kvm_getargv(kd, kp, nchr) 792 kvm_t *kd; 793 const struct kinfo_proc *kp; 794 int nchr; 795 { 796 return (kvm_doargv(kd, kp, nchr, ps_str_a)); 797 } 798 799 char ** 800 kvm_getenvv(kd, kp, nchr) 801 kvm_t *kd; 802 const struct kinfo_proc *kp; 803 int nchr; 804 { 805 return (kvm_doargv(kd, kp, nchr, ps_str_e)); 806 } 807 808 /* 809 * Read from user space. The user context is given by p. 810 */ 811 ssize_t 812 kvm_uread(kd, p, uva, buf, len) 813 kvm_t *kd; 814 register const struct proc *p; 815 register u_long uva; 816 register char *buf; 817 register size_t len; 818 { 819 register char *cp; 820 821 cp = buf; 822 while (len > 0) { 823 register int cc; 824 register char *dp; 825 u_long cnt; 826 827 dp = _kvm_uread(kd, p, uva, &cnt); 828 if (dp == 0) { 829 _kvm_err(kd, 0, "invalid address (%x)", uva); 830 return (0); 831 } 832 cc = MIN(cnt, len); 833 bcopy(dp, cp, cc); 834 835 cp += cc; 836 uva += cc; 837 len -= cc; 838 } 839 return (ssize_t)(cp - buf); 840 } 841