1 /* $NetBSD: kvm_proc.c,v 1.53 2003/03/28 14:01:32 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles M. Hannum. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /*- 40 * Copyright (c) 1989, 1992, 1993 41 * The Regents of the University of California. All rights reserved. 42 * 43 * This code is derived from software developed by the Computer Systems 44 * Engineering group at Lawrence Berkeley Laboratory under DARPA contract 45 * BG 91-66 and contributed to Berkeley. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 2. Redistributions in binary form must reproduce the above copyright 53 * notice, this list of conditions and the following disclaimer in the 54 * documentation and/or other materials provided with the distribution. 55 * 3. All advertising materials mentioning features or use of this software 56 * must display the following acknowledgement: 57 * This product includes software developed by the University of 58 * California, Berkeley and its contributors. 59 * 4. Neither the name of the University nor the names of its contributors 60 * may be used to endorse or promote products derived from this software 61 * without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 66 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 73 * SUCH DAMAGE. 74 */ 75 76 #include <sys/cdefs.h> 77 #if defined(LIBC_SCCS) && !defined(lint) 78 #if 0 79 static char sccsid[] = "@(#)kvm_proc.c 8.3 (Berkeley) 9/23/93"; 80 #else 81 __RCSID("$NetBSD: kvm_proc.c,v 1.53 2003/03/28 14:01:32 christos Exp $"); 82 #endif 83 #endif /* LIBC_SCCS and not lint */ 84 85 /* 86 * Proc traversal interface for kvm. ps and w are (probably) the exclusive 87 * users of this code, so we've factored it out into a separate module. 88 * Thus, we keep this grunge out of the other kvm applications (i.e., 89 * most other applications are interested only in open/close/read/nlist). 90 */ 91 92 #include <sys/param.h> 93 #include <sys/user.h> 94 #include <sys/lwp.h> 95 #include <sys/proc.h> 96 #include <sys/exec.h> 97 #include <sys/stat.h> 98 #include <sys/ioctl.h> 99 #include <sys/tty.h> 100 #include <stdlib.h> 101 #include <stddef.h> 102 #include <string.h> 103 #include <unistd.h> 104 #include <nlist.h> 105 #include <kvm.h> 106 107 #include <uvm/uvm_extern.h> 108 #include <uvm/uvm_amap.h> 109 110 #include <sys/sysctl.h> 111 112 #include <limits.h> 113 #include <db.h> 114 #include <paths.h> 115 116 #include "kvm_private.h" 117 118 /* 119 * Common info from kinfo_proc and kinfo_proc2 used by helper routines. 120 */ 121 struct miniproc { 122 struct vmspace *p_vmspace; 123 char p_stat; 124 struct proc *p_paddr; 125 pid_t p_pid; 126 }; 127 128 /* 129 * Convert from struct proc and kinfo_proc{,2} to miniproc. 130 */ 131 #define PTOMINI(kp, p) \ 132 do { \ 133 (p)->p_stat = (kp)->p_stat; \ 134 (p)->p_pid = (kp)->p_pid; \ 135 (p)->p_paddr = NULL; \ 136 (p)->p_vmspace = (kp)->p_vmspace; \ 137 } while (/*CONSTCOND*/0); 138 139 #define KPTOMINI(kp, p) \ 140 do { \ 141 (p)->p_stat = (kp)->kp_proc.p_stat; \ 142 (p)->p_pid = (kp)->kp_proc.p_pid; \ 143 (p)->p_paddr = (kp)->kp_eproc.e_paddr; \ 144 (p)->p_vmspace = (kp)->kp_proc.p_vmspace; \ 145 } while (/*CONSTCOND*/0); 146 147 #define KP2TOMINI(kp, p) \ 148 do { \ 149 (p)->p_stat = (kp)->p_stat; \ 150 (p)->p_pid = (kp)->p_pid; \ 151 (p)->p_paddr = (void *)(long)(kp)->p_paddr; \ 152 (p)->p_vmspace = (void *)(long)(kp)->p_vmspace; \ 153 } while (/*CONSTCOND*/0); 154 155 156 #define PTRTOINT64(foo) ((u_int64_t)(const uintptr_t)(const void *)(foo)) 157 158 #define KREAD(kd, addr, obj) \ 159 (kvm_read(kd, addr, (obj), sizeof(*obj)) != sizeof(*obj)) 160 161 /* XXX: What uses these two functions? */ 162 char *_kvm_uread __P((kvm_t *, const struct proc *, u_long, 163 u_long *)); 164 ssize_t kvm_uread __P((kvm_t *, const struct proc *, u_long, char *, 165 size_t)); 166 167 static char *_kvm_ureadm __P((kvm_t *, const struct miniproc *, u_long, 168 u_long *)); 169 static ssize_t kvm_ureadm __P((kvm_t *, const struct miniproc *, u_long, 170 char *, size_t)); 171 172 static char **kvm_argv __P((kvm_t *, const struct miniproc *, u_long, int, 173 int)); 174 static int kvm_deadprocs __P((kvm_t *, int, int, u_long, u_long, int)); 175 static char **kvm_doargv __P((kvm_t *, const struct miniproc *, int, 176 void (*)(struct ps_strings *, u_long *, int *))); 177 static char **kvm_doargv2 __P((kvm_t *, pid_t, int, int)); 178 static int kvm_proclist __P((kvm_t *, int, int, struct proc *, 179 struct kinfo_proc *, int)); 180 static int proc_verify __P((kvm_t *, u_long, const struct miniproc *)); 181 static void ps_str_a __P((struct ps_strings *, u_long *, int *)); 182 static void ps_str_e __P((struct ps_strings *, u_long *, int *)); 183 184 185 static char * 186 _kvm_ureadm(kd, p, va, cnt) 187 kvm_t *kd; 188 const struct miniproc *p; 189 u_long va; 190 u_long *cnt; 191 { 192 int true = 1; 193 u_long addr, head; 194 u_long offset; 195 struct vm_map_entry vme; 196 struct vm_amap amap; 197 struct vm_anon *anonp, anon; 198 struct vm_page pg; 199 u_long slot; 200 201 if (kd->swapspc == NULL) { 202 kd->swapspc = (char *)_kvm_malloc(kd, (size_t)kd->nbpg); 203 if (kd->swapspc == NULL) 204 return (NULL); 205 } 206 207 /* 208 * Look through the address map for the memory object 209 * that corresponds to the given virtual address. 210 * The header just has the entire valid range. 211 */ 212 head = (u_long)&p->p_vmspace->vm_map.header; 213 addr = head; 214 while (true) { 215 if (KREAD(kd, addr, &vme)) 216 return (NULL); 217 218 if (va >= vme.start && va < vme.end && 219 vme.aref.ar_amap != NULL) 220 break; 221 222 addr = (u_long)vme.next; 223 if (addr == head) 224 return (NULL); 225 } 226 227 /* 228 * we found the map entry, now to find the object... 229 */ 230 if (vme.aref.ar_amap == NULL) 231 return (NULL); 232 233 addr = (u_long)vme.aref.ar_amap; 234 if (KREAD(kd, addr, &amap)) 235 return (NULL); 236 237 offset = va - vme.start; 238 slot = offset / kd->nbpg + vme.aref.ar_pageoff; 239 /* sanity-check slot number */ 240 if (slot > amap.am_nslot) 241 return (NULL); 242 243 addr = (u_long)amap.am_anon + (offset / kd->nbpg) * sizeof(anonp); 244 if (KREAD(kd, addr, &anonp)) 245 return (NULL); 246 247 addr = (u_long)anonp; 248 if (KREAD(kd, addr, &anon)) 249 return (NULL); 250 251 addr = (u_long)anon.u.an_page; 252 if (addr) { 253 if (KREAD(kd, addr, &pg)) 254 return (NULL); 255 256 if (pread(kd->pmfd, kd->swapspc, (size_t)kd->nbpg, 257 (off_t)pg.phys_addr) != kd->nbpg) 258 return (NULL); 259 } else { 260 if (pread(kd->swfd, kd->swapspc, (size_t)kd->nbpg, 261 (off_t)(anon.an_swslot * kd->nbpg)) != kd->nbpg) 262 return (NULL); 263 } 264 265 /* Found the page. */ 266 offset %= kd->nbpg; 267 *cnt = kd->nbpg - offset; 268 return (&kd->swapspc[(size_t)offset]); 269 } 270 271 char * 272 _kvm_uread(kd, p, va, cnt) 273 kvm_t *kd; 274 const struct proc *p; 275 u_long va; 276 u_long *cnt; 277 { 278 struct miniproc mp; 279 280 PTOMINI(p, &mp); 281 return (_kvm_ureadm(kd, &mp, va, cnt)); 282 } 283 284 /* 285 * Read proc's from memory file into buffer bp, which has space to hold 286 * at most maxcnt procs. 287 */ 288 static int 289 kvm_proclist(kd, what, arg, p, bp, maxcnt) 290 kvm_t *kd; 291 int what, arg; 292 struct proc *p; 293 struct kinfo_proc *bp; 294 int maxcnt; 295 { 296 int cnt = 0; 297 int nlwps; 298 struct kinfo_lwp *kl; 299 struct eproc eproc; 300 struct pgrp pgrp; 301 struct session sess; 302 struct tty tty; 303 struct proc proc; 304 305 for (; cnt < maxcnt && p != NULL; p = proc.p_list.le_next) { 306 if (KREAD(kd, (u_long)p, &proc)) { 307 _kvm_err(kd, kd->program, "can't read proc at %p", p); 308 return (-1); 309 } 310 if (KREAD(kd, (u_long)proc.p_cred, &eproc.e_pcred) == 0) 311 if (KREAD(kd, (u_long)eproc.e_pcred.pc_ucred, 312 &eproc.e_ucred)) { 313 _kvm_err(kd, kd->program, 314 "can't read proc credentials at %p", p); 315 return (-1); 316 } 317 318 switch (what) { 319 320 case KERN_PROC_PID: 321 if (proc.p_pid != (pid_t)arg) 322 continue; 323 break; 324 325 case KERN_PROC_UID: 326 if (eproc.e_ucred.cr_uid != (uid_t)arg) 327 continue; 328 break; 329 330 case KERN_PROC_RUID: 331 if (eproc.e_pcred.p_ruid != (uid_t)arg) 332 continue; 333 break; 334 } 335 /* 336 * We're going to add another proc to the set. If this 337 * will overflow the buffer, assume the reason is because 338 * nprocs (or the proc list) is corrupt and declare an error. 339 */ 340 if (cnt >= maxcnt) { 341 _kvm_err(kd, kd->program, "nprocs corrupt"); 342 return (-1); 343 } 344 /* 345 * gather eproc 346 */ 347 eproc.e_paddr = p; 348 if (KREAD(kd, (u_long)proc.p_pgrp, &pgrp)) { 349 _kvm_err(kd, kd->program, "can't read pgrp at %p", 350 proc.p_pgrp); 351 return (-1); 352 } 353 eproc.e_sess = pgrp.pg_session; 354 eproc.e_pgid = pgrp.pg_id; 355 eproc.e_jobc = pgrp.pg_jobc; 356 if (KREAD(kd, (u_long)pgrp.pg_session, &sess)) { 357 _kvm_err(kd, kd->program, "can't read session at %p", 358 pgrp.pg_session); 359 return (-1); 360 } 361 if ((proc.p_flag & P_CONTROLT) && sess.s_ttyp != NULL) { 362 if (KREAD(kd, (u_long)sess.s_ttyp, &tty)) { 363 _kvm_err(kd, kd->program, 364 "can't read tty at %p", sess.s_ttyp); 365 return (-1); 366 } 367 eproc.e_tdev = tty.t_dev; 368 eproc.e_tsess = tty.t_session; 369 if (tty.t_pgrp != NULL) { 370 if (KREAD(kd, (u_long)tty.t_pgrp, &pgrp)) { 371 _kvm_err(kd, kd->program, 372 "can't read tpgrp at %p", 373 tty.t_pgrp); 374 return (-1); 375 } 376 eproc.e_tpgid = pgrp.pg_id; 377 } else 378 eproc.e_tpgid = -1; 379 } else 380 eproc.e_tdev = NODEV; 381 eproc.e_flag = sess.s_ttyvp ? EPROC_CTTY : 0; 382 eproc.e_sid = sess.s_sid; 383 if (sess.s_leader == p) 384 eproc.e_flag |= EPROC_SLEADER; 385 /* 386 * Fill in the old-style proc.p_wmesg by copying the wmesg 387 * from the first avaliable LWP. 388 */ 389 kl = kvm_getlwps(kd, proc.p_pid, 390 (u_long)PTRTOINT64(eproc.e_paddr), 391 sizeof(struct kinfo_lwp), &nlwps); 392 if (kl) { 393 if (nlwps > 0) { 394 strcpy(eproc.e_wmesg, kl[0].l_wmesg); 395 } 396 } 397 (void)kvm_read(kd, (u_long)proc.p_vmspace, &eproc.e_vm, 398 sizeof(eproc.e_vm)); 399 400 eproc.e_xsize = eproc.e_xrssize = 0; 401 eproc.e_xccount = eproc.e_xswrss = 0; 402 403 switch (what) { 404 405 case KERN_PROC_PGRP: 406 if (eproc.e_pgid != (pid_t)arg) 407 continue; 408 break; 409 410 case KERN_PROC_TTY: 411 if ((proc.p_flag & P_CONTROLT) == 0 || 412 eproc.e_tdev != (dev_t)arg) 413 continue; 414 break; 415 } 416 memcpy(&bp->kp_proc, &proc, sizeof(proc)); 417 memcpy(&bp->kp_eproc, &eproc, sizeof(eproc)); 418 ++bp; 419 ++cnt; 420 } 421 return (cnt); 422 } 423 424 /* 425 * Build proc info array by reading in proc list from a crash dump. 426 * Return number of procs read. maxcnt is the max we will read. 427 */ 428 static int 429 kvm_deadprocs(kd, what, arg, a_allproc, a_zombproc, maxcnt) 430 kvm_t *kd; 431 int what, arg; 432 u_long a_allproc; 433 u_long a_zombproc; 434 int maxcnt; 435 { 436 struct kinfo_proc *bp = kd->procbase; 437 int acnt, zcnt; 438 struct proc *p; 439 440 if (KREAD(kd, a_allproc, &p)) { 441 _kvm_err(kd, kd->program, "cannot read allproc"); 442 return (-1); 443 } 444 acnt = kvm_proclist(kd, what, arg, p, bp, maxcnt); 445 if (acnt < 0) 446 return (acnt); 447 448 if (KREAD(kd, a_zombproc, &p)) { 449 _kvm_err(kd, kd->program, "cannot read zombproc"); 450 return (-1); 451 } 452 zcnt = kvm_proclist(kd, what, arg, p, bp + acnt, 453 maxcnt - acnt); 454 if (zcnt < 0) 455 zcnt = 0; 456 457 return (acnt + zcnt); 458 } 459 460 struct kinfo_proc2 * 461 kvm_getproc2(kd, op, arg, esize, cnt) 462 kvm_t *kd; 463 int op, arg; 464 size_t esize; 465 int *cnt; 466 { 467 size_t size; 468 int mib[6], st, nprocs; 469 struct pstats pstats; 470 471 if (kd->procbase2 != NULL) { 472 free(kd->procbase2); 473 /* 474 * Clear this pointer in case this call fails. Otherwise, 475 * kvm_close() will free it again. 476 */ 477 kd->procbase2 = NULL; 478 } 479 480 if (ISSYSCTL(kd)) { 481 size = 0; 482 mib[0] = CTL_KERN; 483 mib[1] = KERN_PROC2; 484 mib[2] = op; 485 mib[3] = arg; 486 mib[4] = (int)esize; 487 mib[5] = 0; 488 st = sysctl(mib, 6, NULL, &size, NULL, (size_t)0); 489 if (st == -1) { 490 _kvm_syserr(kd, kd->program, "kvm_getproc2"); 491 return (NULL); 492 } 493 494 mib[5] = (int) (size / esize); 495 kd->procbase2 = (struct kinfo_proc2 *)_kvm_malloc(kd, size); 496 if (kd->procbase2 == NULL) 497 return (NULL); 498 st = sysctl(mib, 6, kd->procbase2, &size, NULL, (size_t)0); 499 if (st == -1) { 500 _kvm_syserr(kd, kd->program, "kvm_getproc2"); 501 return (NULL); 502 } 503 nprocs = (int) (size / esize); 504 } else { 505 char *kp2c; 506 struct kinfo_proc *kp; 507 struct kinfo_proc2 kp2, *kp2p; 508 struct kinfo_lwp *kl; 509 int i, nlwps; 510 511 kp = kvm_getprocs(kd, op, arg, &nprocs); 512 if (kp == NULL) 513 return (NULL); 514 515 kd->procbase2 = _kvm_malloc(kd, nprocs * esize); 516 kp2c = (char *)(void *)kd->procbase2; 517 kp2p = &kp2; 518 for (i = 0; i < nprocs; i++, kp++) { 519 kl = kvm_getlwps(kd, kp->kp_proc.p_pid, 520 (u_long)PTRTOINT64(kp->kp_eproc.e_paddr), 521 sizeof(struct kinfo_lwp), &nlwps); 522 /* We use kl[0] as the "representative" LWP */ 523 memset(kp2p, 0, sizeof(kp2)); 524 kp2p->p_forw = kl[0].l_forw; 525 kp2p->p_back = kl[0].l_back; 526 kp2p->p_paddr = PTRTOINT64(kp->kp_eproc.e_paddr); 527 kp2p->p_addr = kl[0].l_addr; 528 kp2p->p_fd = PTRTOINT64(kp->kp_proc.p_fd); 529 kp2p->p_cwdi = PTRTOINT64(kp->kp_proc.p_cwdi); 530 kp2p->p_stats = PTRTOINT64(kp->kp_proc.p_stats); 531 kp2p->p_limit = PTRTOINT64(kp->kp_proc.p_limit); 532 kp2p->p_vmspace = PTRTOINT64(kp->kp_proc.p_vmspace); 533 kp2p->p_sigacts = PTRTOINT64(kp->kp_proc.p_sigacts); 534 kp2p->p_sess = PTRTOINT64(kp->kp_eproc.e_sess); 535 kp2p->p_tsess = 0; 536 kp2p->p_ru = PTRTOINT64(kp->kp_proc.p_ru); 537 538 kp2p->p_eflag = 0; 539 kp2p->p_exitsig = kp->kp_proc.p_exitsig; 540 kp2p->p_flag = kp->kp_proc.p_flag; 541 542 kp2p->p_pid = kp->kp_proc.p_pid; 543 544 kp2p->p_ppid = kp->kp_eproc.e_ppid; 545 kp2p->p_sid = kp->kp_eproc.e_sid; 546 kp2p->p__pgid = kp->kp_eproc.e_pgid; 547 548 kp2p->p_tpgid = -1 /* XXX NO_PGID! */; 549 550 kp2p->p_uid = kp->kp_eproc.e_ucred.cr_uid; 551 kp2p->p_ruid = kp->kp_eproc.e_pcred.p_ruid; 552 kp2p->p_svuid = kp->kp_eproc.e_pcred.p_svuid; 553 kp2p->p_gid = kp->kp_eproc.e_ucred.cr_gid; 554 kp2p->p_rgid = kp->kp_eproc.e_pcred.p_rgid; 555 kp2p->p_svgid = kp->kp_eproc.e_pcred.p_svgid; 556 557 /*CONSTCOND*/ 558 memcpy(kp2p->p_groups, kp->kp_eproc.e_ucred.cr_groups, 559 MIN(sizeof(kp2p->p_groups), 560 sizeof(kp->kp_eproc.e_ucred.cr_groups))); 561 kp2p->p_ngroups = kp->kp_eproc.e_ucred.cr_ngroups; 562 563 kp2p->p_jobc = kp->kp_eproc.e_jobc; 564 kp2p->p_tdev = kp->kp_eproc.e_tdev; 565 kp2p->p_tpgid = kp->kp_eproc.e_tpgid; 566 kp2p->p_tsess = PTRTOINT64(kp->kp_eproc.e_tsess); 567 568 kp2p->p_estcpu = kp->kp_proc.p_estcpu; 569 kp2p->p_rtime_sec = kp->kp_proc.p_estcpu; 570 kp2p->p_rtime_usec = kp->kp_proc.p_estcpu; 571 kp2p->p_cpticks = kp->kp_proc.p_cpticks; 572 kp2p->p_pctcpu = kp->kp_proc.p_pctcpu; 573 kp2p->p_swtime = kl[0].l_swtime; 574 kp2p->p_slptime = kl[0].l_slptime; 575 #if 0 /* XXX thorpej */ 576 kp2p->p_schedflags = kp->kp_proc.p_schedflags; 577 #else 578 kp2p->p_schedflags = 0; 579 #endif 580 581 kp2p->p_uticks = kp->kp_proc.p_uticks; 582 kp2p->p_sticks = kp->kp_proc.p_sticks; 583 kp2p->p_iticks = kp->kp_proc.p_iticks; 584 585 kp2p->p_tracep = PTRTOINT64(kp->kp_proc.p_tracep); 586 kp2p->p_traceflag = kp->kp_proc.p_traceflag; 587 588 kp2p->p_holdcnt = kl[0].l_holdcnt; 589 590 memcpy(&kp2p->p_siglist, 591 &kp->kp_proc.p_sigctx.ps_siglist, 592 sizeof(ki_sigset_t)); 593 memcpy(&kp2p->p_sigmask, 594 &kp->kp_proc.p_sigctx.ps_sigmask, 595 sizeof(ki_sigset_t)); 596 memcpy(&kp2p->p_sigignore, 597 &kp->kp_proc.p_sigctx.ps_sigignore, 598 sizeof(ki_sigset_t)); 599 memcpy(&kp2p->p_sigcatch, 600 &kp->kp_proc.p_sigctx.ps_sigcatch, 601 sizeof(ki_sigset_t)); 602 603 kp2p->p_stat = kp->kp_proc.p_stat; 604 kp2p->p_priority = kl[0].l_priority; 605 kp2p->p_usrpri = kl[0].l_usrpri; 606 kp2p->p_nice = kp->kp_proc.p_nice; 607 608 kp2p->p_xstat = kp->kp_proc.p_xstat; 609 kp2p->p_acflag = kp->kp_proc.p_acflag; 610 611 /*CONSTCOND*/ 612 strncpy(kp2p->p_comm, kp->kp_proc.p_comm, 613 MIN(sizeof(kp2p->p_comm), 614 sizeof(kp->kp_proc.p_comm))); 615 616 strncpy(kp2p->p_wmesg, kp->kp_eproc.e_wmesg, 617 sizeof(kp2p->p_wmesg)); 618 kp2p->p_wchan = kl[0].l_wchan; 619 strncpy(kp2p->p_login, kp->kp_eproc.e_login, 620 sizeof(kp2p->p_login)); 621 622 kp2p->p_vm_rssize = kp->kp_eproc.e_xrssize; 623 kp2p->p_vm_tsize = kp->kp_eproc.e_vm.vm_tsize; 624 kp2p->p_vm_dsize = kp->kp_eproc.e_vm.vm_dsize; 625 kp2p->p_vm_ssize = kp->kp_eproc.e_vm.vm_ssize; 626 627 kp2p->p_eflag = (int32_t)kp->kp_eproc.e_flag; 628 629 kp2p->p_realflag = kp->kp_proc.p_flag; 630 kp2p->p_nlwps = kp->kp_proc.p_nlwps; 631 kp2p->p_nrlwps = kp->kp_proc.p_nrlwps; 632 kp2p->p_realstat = kp->kp_proc.p_stat; 633 634 if (P_ZOMBIE(&kp->kp_proc) || 635 kp->kp_proc.p_stats == NULL || 636 KREAD(kd, (u_long)kp->kp_proc.p_stats, &pstats)) { 637 kp2p->p_uvalid = 0; 638 } else { 639 kp2p->p_uvalid = 1; 640 641 kp2p->p_ustart_sec = (u_int32_t) 642 pstats.p_start.tv_sec; 643 kp2p->p_ustart_usec = (u_int32_t) 644 pstats.p_start.tv_usec; 645 646 kp2p->p_uutime_sec = (u_int32_t) 647 pstats.p_ru.ru_utime.tv_sec; 648 kp2p->p_uutime_usec = (u_int32_t) 649 pstats.p_ru.ru_utime.tv_usec; 650 kp2p->p_ustime_sec = (u_int32_t) 651 pstats.p_ru.ru_stime.tv_sec; 652 kp2p->p_ustime_usec = (u_int32_t) 653 pstats.p_ru.ru_stime.tv_usec; 654 655 kp2p->p_uru_maxrss = pstats.p_ru.ru_maxrss; 656 kp2p->p_uru_ixrss = pstats.p_ru.ru_ixrss; 657 kp2p->p_uru_idrss = pstats.p_ru.ru_idrss; 658 kp2p->p_uru_isrss = pstats.p_ru.ru_isrss; 659 kp2p->p_uru_minflt = pstats.p_ru.ru_minflt; 660 kp2p->p_uru_majflt = pstats.p_ru.ru_majflt; 661 kp2p->p_uru_nswap = pstats.p_ru.ru_nswap; 662 kp2p->p_uru_inblock = pstats.p_ru.ru_inblock; 663 kp2p->p_uru_oublock = pstats.p_ru.ru_oublock; 664 kp2p->p_uru_msgsnd = pstats.p_ru.ru_msgsnd; 665 kp2p->p_uru_msgrcv = pstats.p_ru.ru_msgrcv; 666 kp2p->p_uru_nsignals = pstats.p_ru.ru_nsignals; 667 kp2p->p_uru_nvcsw = pstats.p_ru.ru_nvcsw; 668 kp2p->p_uru_nivcsw = pstats.p_ru.ru_nivcsw; 669 670 kp2p->p_uctime_sec = (u_int32_t) 671 (pstats.p_cru.ru_utime.tv_sec + 672 pstats.p_cru.ru_stime.tv_sec); 673 kp2p->p_uctime_usec = (u_int32_t) 674 (pstats.p_cru.ru_utime.tv_usec + 675 pstats.p_cru.ru_stime.tv_usec); 676 } 677 678 memcpy(kp2c, &kp2, esize); 679 kp2c += esize; 680 } 681 682 _kvm_freeprocs(kd); 683 } 684 *cnt = nprocs; 685 return (kd->procbase2); 686 } 687 688 struct kinfo_lwp * 689 kvm_getlwps(kd, pid, paddr, esize, cnt) 690 kvm_t *kd; 691 int pid; 692 u_long paddr; 693 size_t esize; 694 int *cnt; 695 { 696 size_t size; 697 int mib[5], nlwps; 698 ssize_t st; 699 struct kinfo_lwp *kl; 700 701 if (kd->lwpbase != NULL) { 702 free(kd->lwpbase); 703 /* 704 * Clear this pointer in case this call fails. Otherwise, 705 * kvm_close() will free it again. 706 */ 707 kd->lwpbase = NULL; 708 } 709 710 if (ISSYSCTL(kd)) { 711 size = 0; 712 mib[0] = CTL_KERN; 713 mib[1] = KERN_LWP; 714 mib[2] = pid; 715 mib[3] = (int)esize; 716 mib[4] = 0; 717 st = sysctl(mib, 5, NULL, &size, NULL, (size_t)0); 718 if (st == -1) { 719 _kvm_syserr(kd, kd->program, "kvm_getlwps"); 720 return (NULL); 721 } 722 723 mib[4] = (int) (size / esize); 724 kd->lwpbase = (struct kinfo_lwp *)_kvm_malloc(kd, size); 725 if (kd->lwpbase == NULL) 726 return (NULL); 727 st = sysctl(mib, 5, kd->lwpbase, &size, NULL, (size_t)0); 728 if (st == -1) { 729 _kvm_syserr(kd, kd->program, "kvm_getlwps"); 730 return (NULL); 731 } 732 nlwps = (int) (size / esize); 733 } else { 734 /* grovel through the memory image */ 735 struct proc p; 736 struct lwp l; 737 u_long laddr; 738 int i; 739 740 st = kvm_read(kd, paddr, &p, sizeof(p)); 741 if (st == -1) { 742 _kvm_syserr(kd, kd->program, "kvm_getlwps"); 743 return (NULL); 744 } 745 746 nlwps = p.p_nlwps; 747 kd->lwpbase = (struct kinfo_lwp *)_kvm_malloc(kd, 748 nlwps * sizeof(struct kinfo_lwp)); 749 if (kd->lwpbase == NULL) 750 return (NULL); 751 laddr = (u_long)PTRTOINT64(p.p_lwps.lh_first); 752 for (i = 0; (i < nlwps) && (laddr != 0); i++) { 753 st = kvm_read(kd, laddr, &l, sizeof(l)); 754 if (st == -1) { 755 _kvm_syserr(kd, kd->program, "kvm_getlwps"); 756 return (NULL); 757 } 758 kl = &kd->lwpbase[i]; 759 kl->l_laddr = laddr; 760 kl->l_forw = PTRTOINT64(l.l_forw); 761 kl->l_back = PTRTOINT64(l.l_back); 762 kl->l_addr = PTRTOINT64(l.l_addr); 763 kl->l_lid = l.l_lid; 764 kl->l_flag = l.l_flag; 765 kl->l_swtime = l.l_swtime; 766 kl->l_slptime = l.l_slptime; 767 kl->l_schedflags = 0; /* XXX */ 768 kl->l_holdcnt = l.l_holdcnt; 769 kl->l_priority = l.l_priority; 770 kl->l_usrpri = l.l_usrpri; 771 kl->l_stat = l.l_stat; 772 kl->l_wchan = PTRTOINT64(l.l_wchan); 773 if (l.l_wmesg) 774 (void)kvm_read(kd, (u_long)l.l_wmesg, 775 kl->l_wmesg, (size_t)WMESGLEN); 776 kl->l_cpuid = KI_NOCPU; 777 laddr = (u_long)PTRTOINT64(l.l_sibling.le_next); 778 } 779 } 780 781 *cnt = nlwps; 782 return (kd->lwpbase); 783 } 784 785 struct kinfo_proc * 786 kvm_getprocs(kd, op, arg, cnt) 787 kvm_t *kd; 788 int op, arg; 789 int *cnt; 790 { 791 size_t size; 792 int mib[4], st, nprocs; 793 794 if (kd->procbase != NULL) { 795 free(kd->procbase); 796 /* 797 * Clear this pointer in case this call fails. Otherwise, 798 * kvm_close() will free it again. 799 */ 800 kd->procbase = NULL; 801 } 802 if (ISKMEM(kd)) { 803 size = 0; 804 mib[0] = CTL_KERN; 805 mib[1] = KERN_PROC; 806 mib[2] = op; 807 mib[3] = arg; 808 st = sysctl(mib, 4, NULL, &size, NULL, (size_t)0); 809 if (st == -1) { 810 _kvm_syserr(kd, kd->program, "kvm_getprocs"); 811 return (NULL); 812 } 813 kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); 814 if (kd->procbase == NULL) 815 return (NULL); 816 st = sysctl(mib, 4, kd->procbase, &size, NULL, (size_t)0); 817 if (st == -1) { 818 _kvm_syserr(kd, kd->program, "kvm_getprocs"); 819 return (NULL); 820 } 821 if (size % sizeof(struct kinfo_proc) != 0) { 822 _kvm_err(kd, kd->program, 823 "proc size mismatch (%lu total, %lu chunks)", 824 (u_long)size, (u_long)sizeof(struct kinfo_proc)); 825 return (NULL); 826 } 827 nprocs = (int) (size / sizeof(struct kinfo_proc)); 828 } else if (ISSYSCTL(kd)) { 829 _kvm_err(kd, kd->program, "kvm_open called with KVM_NO_FILES, " 830 "can't use kvm_getprocs"); 831 return (NULL); 832 } else { 833 struct nlist nl[4], *p; 834 835 nl[0].n_name = "_nprocs"; 836 nl[1].n_name = "_allproc"; 837 nl[2].n_name = "_zombproc"; 838 nl[3].n_name = NULL; 839 840 if (kvm_nlist(kd, nl) != 0) { 841 for (p = nl; p->n_type != 0; ++p) 842 continue; 843 _kvm_err(kd, kd->program, 844 "%s: no such symbol", p->n_name); 845 return (NULL); 846 } 847 if (KREAD(kd, nl[0].n_value, &nprocs)) { 848 _kvm_err(kd, kd->program, "can't read nprocs"); 849 return (NULL); 850 } 851 size = nprocs * sizeof(struct kinfo_proc); 852 kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); 853 if (kd->procbase == NULL) 854 return (NULL); 855 856 nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value, 857 nl[2].n_value, nprocs); 858 if (nprocs < 0) 859 return (NULL); 860 #ifdef notdef 861 size = nprocs * sizeof(struct kinfo_proc); 862 (void)realloc(kd->procbase, size); 863 #endif 864 } 865 *cnt = nprocs; 866 return (kd->procbase); 867 } 868 869 void 870 _kvm_freeprocs(kd) 871 kvm_t *kd; 872 { 873 874 if (kd->procbase) { 875 free(kd->procbase); 876 kd->procbase = NULL; 877 } 878 } 879 880 void * 881 _kvm_realloc(kd, p, n) 882 kvm_t *kd; 883 void *p; 884 size_t n; 885 { 886 void *np = realloc(p, n); 887 888 if (np == NULL) 889 _kvm_err(kd, kd->program, "out of memory"); 890 return (np); 891 } 892 893 /* 894 * Read in an argument vector from the user address space of process p. 895 * addr if the user-space base address of narg null-terminated contiguous 896 * strings. This is used to read in both the command arguments and 897 * environment strings. Read at most maxcnt characters of strings. 898 */ 899 static char ** 900 kvm_argv(kd, p, addr, narg, maxcnt) 901 kvm_t *kd; 902 const struct miniproc *p; 903 u_long addr; 904 int narg; 905 int maxcnt; 906 { 907 char *np, *cp, *ep, *ap; 908 u_long oaddr = (u_long)~0L; 909 u_long len; 910 size_t cc; 911 char **argv; 912 913 /* 914 * Check that there aren't an unreasonable number of agruments, 915 * and that the address is in user space. 916 */ 917 if (narg > ARG_MAX || addr < kd->min_uva || addr >= kd->max_uva) 918 return (NULL); 919 920 if (kd->argv == NULL) { 921 /* 922 * Try to avoid reallocs. 923 */ 924 kd->argc = MAX(narg + 1, 32); 925 kd->argv = (char **)_kvm_malloc(kd, kd->argc * 926 sizeof(*kd->argv)); 927 if (kd->argv == NULL) 928 return (NULL); 929 } else if (narg + 1 > kd->argc) { 930 kd->argc = MAX(2 * kd->argc, narg + 1); 931 kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc * 932 sizeof(*kd->argv)); 933 if (kd->argv == NULL) 934 return (NULL); 935 } 936 if (kd->argspc == NULL) { 937 kd->argspc = (char *)_kvm_malloc(kd, (size_t)kd->nbpg); 938 if (kd->argspc == NULL) 939 return (NULL); 940 kd->arglen = kd->nbpg; 941 } 942 if (kd->argbuf == NULL) { 943 kd->argbuf = (char *)_kvm_malloc(kd, (size_t)kd->nbpg); 944 if (kd->argbuf == NULL) 945 return (NULL); 946 } 947 cc = sizeof(char *) * narg; 948 if (kvm_ureadm(kd, p, addr, (void *)kd->argv, cc) != cc) 949 return (NULL); 950 ap = np = kd->argspc; 951 argv = kd->argv; 952 len = 0; 953 /* 954 * Loop over pages, filling in the argument vector. 955 */ 956 while (argv < kd->argv + narg && *argv != NULL) { 957 addr = (u_long)*argv & ~(kd->nbpg - 1); 958 if (addr != oaddr) { 959 if (kvm_ureadm(kd, p, addr, kd->argbuf, 960 (size_t)kd->nbpg) != kd->nbpg) 961 return (NULL); 962 oaddr = addr; 963 } 964 addr = (u_long)*argv & (kd->nbpg - 1); 965 cp = kd->argbuf + (size_t)addr; 966 cc = kd->nbpg - (size_t)addr; 967 if (maxcnt > 0 && cc > (size_t)(maxcnt - len)) 968 cc = (size_t)(maxcnt - len); 969 ep = memchr(cp, '\0', cc); 970 if (ep != NULL) 971 cc = ep - cp + 1; 972 if (len + cc > kd->arglen) { 973 ptrdiff_t off; 974 char **pp; 975 char *op = kd->argspc; 976 977 kd->arglen *= 2; 978 kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, 979 (size_t)kd->arglen); 980 if (kd->argspc == NULL) 981 return (NULL); 982 /* 983 * Adjust argv pointers in case realloc moved 984 * the string space. 985 */ 986 off = kd->argspc - op; 987 for (pp = kd->argv; pp < argv; pp++) 988 *pp += off; 989 ap += off; 990 np += off; 991 } 992 memcpy(np, cp, cc); 993 np += cc; 994 len += cc; 995 if (ep != NULL) { 996 *argv++ = ap; 997 ap = np; 998 } else 999 *argv += cc; 1000 if (maxcnt > 0 && len >= maxcnt) { 1001 /* 1002 * We're stopping prematurely. Terminate the 1003 * current string. 1004 */ 1005 if (ep == NULL) { 1006 *np = '\0'; 1007 *argv++ = ap; 1008 } 1009 break; 1010 } 1011 } 1012 /* Make sure argv is terminated. */ 1013 *argv = NULL; 1014 return (kd->argv); 1015 } 1016 1017 static void 1018 ps_str_a(p, addr, n) 1019 struct ps_strings *p; 1020 u_long *addr; 1021 int *n; 1022 { 1023 1024 *addr = (u_long)p->ps_argvstr; 1025 *n = p->ps_nargvstr; 1026 } 1027 1028 static void 1029 ps_str_e(p, addr, n) 1030 struct ps_strings *p; 1031 u_long *addr; 1032 int *n; 1033 { 1034 1035 *addr = (u_long)p->ps_envstr; 1036 *n = p->ps_nenvstr; 1037 } 1038 1039 /* 1040 * Determine if the proc indicated by p is still active. 1041 * This test is not 100% foolproof in theory, but chances of 1042 * being wrong are very low. 1043 */ 1044 static int 1045 proc_verify(kd, kernp, p) 1046 kvm_t *kd; 1047 u_long kernp; 1048 const struct miniproc *p; 1049 { 1050 struct proc kernproc; 1051 1052 /* 1053 * Just read in the whole proc. It's not that big relative 1054 * to the cost of the read system call. 1055 */ 1056 if (kvm_read(kd, kernp, &kernproc, sizeof(kernproc)) != 1057 sizeof(kernproc)) 1058 return (0); 1059 return (p->p_pid == kernproc.p_pid && 1060 (kernproc.p_stat != SZOMB || p->p_stat == SZOMB)); 1061 } 1062 1063 static char ** 1064 kvm_doargv(kd, p, nchr, info) 1065 kvm_t *kd; 1066 const struct miniproc *p; 1067 int nchr; 1068 void (*info)(struct ps_strings *, u_long *, int *); 1069 { 1070 char **ap; 1071 u_long addr; 1072 int cnt; 1073 struct ps_strings arginfo; 1074 1075 /* 1076 * Pointers are stored at the top of the user stack. 1077 */ 1078 if (p->p_stat == SZOMB) 1079 return (NULL); 1080 cnt = (int)kvm_ureadm(kd, p, kd->usrstack - sizeof(arginfo), 1081 (void *)&arginfo, sizeof(arginfo)); 1082 if (cnt != sizeof(arginfo)) 1083 return (NULL); 1084 1085 (*info)(&arginfo, &addr, &cnt); 1086 if (cnt == 0) 1087 return (NULL); 1088 ap = kvm_argv(kd, p, addr, cnt, nchr); 1089 /* 1090 * For live kernels, make sure this process didn't go away. 1091 */ 1092 if (ap != NULL && ISALIVE(kd) && 1093 !proc_verify(kd, (u_long)p->p_paddr, p)) 1094 ap = NULL; 1095 return (ap); 1096 } 1097 1098 /* 1099 * Get the command args. This code is now machine independent. 1100 */ 1101 char ** 1102 kvm_getargv(kd, kp, nchr) 1103 kvm_t *kd; 1104 const struct kinfo_proc *kp; 1105 int nchr; 1106 { 1107 struct miniproc p; 1108 1109 KPTOMINI(kp, &p); 1110 return (kvm_doargv(kd, &p, nchr, ps_str_a)); 1111 } 1112 1113 char ** 1114 kvm_getenvv(kd, kp, nchr) 1115 kvm_t *kd; 1116 const struct kinfo_proc *kp; 1117 int nchr; 1118 { 1119 struct miniproc p; 1120 1121 KPTOMINI(kp, &p); 1122 return (kvm_doargv(kd, &p, nchr, ps_str_e)); 1123 } 1124 1125 static char ** 1126 kvm_doargv2(kd, pid, type, nchr) 1127 kvm_t *kd; 1128 pid_t pid; 1129 int type; 1130 int nchr; 1131 { 1132 size_t bufs; 1133 int narg, mib[4]; 1134 size_t newarglen; 1135 char **ap, *bp, *endp; 1136 1137 /* 1138 * Check that there aren't an unreasonable number of agruments. 1139 */ 1140 if (nchr > ARG_MAX) 1141 return (NULL); 1142 1143 if (nchr == 0) 1144 nchr = ARG_MAX; 1145 1146 /* Get number of strings in argv */ 1147 mib[0] = CTL_KERN; 1148 mib[1] = KERN_PROC_ARGS; 1149 mib[2] = pid; 1150 mib[3] = type == KERN_PROC_ARGV ? KERN_PROC_NARGV : KERN_PROC_NENV; 1151 bufs = sizeof(narg); 1152 if (sysctl(mib, 4, &narg, &bufs, NULL, (size_t)0) == -1) 1153 return (NULL); 1154 1155 if (kd->argv == NULL) { 1156 /* 1157 * Try to avoid reallocs. 1158 */ 1159 kd->argc = MAX(narg + 1, 32); 1160 kd->argv = (char **)_kvm_malloc(kd, kd->argc * 1161 sizeof(*kd->argv)); 1162 if (kd->argv == NULL) 1163 return (NULL); 1164 } else if (narg + 1 > kd->argc) { 1165 kd->argc = MAX(2 * kd->argc, narg + 1); 1166 kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc * 1167 sizeof(*kd->argv)); 1168 if (kd->argv == NULL) 1169 return (NULL); 1170 } 1171 1172 newarglen = MIN(nchr, ARG_MAX); 1173 if (kd->arglen < newarglen) { 1174 if (kd->arglen == 0) 1175 kd->argspc = (char *)_kvm_malloc(kd, newarglen); 1176 else 1177 kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, 1178 newarglen); 1179 if (kd->argspc == NULL) 1180 return (NULL); 1181 if (newarglen > INT_MAX) 1182 return NULL; 1183 kd->arglen = (int)newarglen; 1184 } 1185 memset(kd->argspc, 0, (size_t)kd->arglen); /* XXX necessary? */ 1186 1187 mib[0] = CTL_KERN; 1188 mib[1] = KERN_PROC_ARGS; 1189 mib[2] = pid; 1190 mib[3] = type; 1191 bufs = kd->arglen; 1192 if (sysctl(mib, 4, kd->argspc, &bufs, NULL, (size_t)0) == -1) 1193 return (NULL); 1194 1195 bp = kd->argspc; 1196 bp[kd->arglen-1] = '\0'; /* make sure the string ends with nul */ 1197 ap = kd->argv; 1198 endp = bp + MIN(nchr, bufs); 1199 1200 while (bp < endp) { 1201 *ap++ = bp; 1202 /* 1203 * XXX: don't need following anymore, or stick check 1204 * for max argc in above while loop? 1205 */ 1206 if (ap >= kd->argv + kd->argc) { 1207 kd->argc *= 2; 1208 kd->argv = _kvm_realloc(kd, kd->argv, 1209 kd->argc * sizeof(*kd->argv)); 1210 ap = kd->argv; 1211 } 1212 bp += strlen(bp) + 1; 1213 } 1214 *ap = NULL; 1215 1216 return (kd->argv); 1217 } 1218 1219 char ** 1220 kvm_getargv2(kd, kp, nchr) 1221 kvm_t *kd; 1222 const struct kinfo_proc2 *kp; 1223 int nchr; 1224 { 1225 1226 return (kvm_doargv2(kd, kp->p_pid, KERN_PROC_ARGV, nchr)); 1227 } 1228 1229 char ** 1230 kvm_getenvv2(kd, kp, nchr) 1231 kvm_t *kd; 1232 const struct kinfo_proc2 *kp; 1233 int nchr; 1234 { 1235 1236 return (kvm_doargv2(kd, kp->p_pid, KERN_PROC_ENV, nchr)); 1237 } 1238 1239 /* 1240 * Read from user space. The user context is given by p. 1241 */ 1242 static ssize_t 1243 kvm_ureadm(kd, p, uva, buf, len) 1244 kvm_t *kd; 1245 const struct miniproc *p; 1246 u_long uva; 1247 char *buf; 1248 size_t len; 1249 { 1250 char *cp; 1251 1252 cp = buf; 1253 while (len > 0) { 1254 size_t cc; 1255 char *dp; 1256 u_long cnt; 1257 1258 dp = _kvm_ureadm(kd, p, uva, &cnt); 1259 if (dp == NULL) { 1260 _kvm_err(kd, 0, "invalid address (%lx)", uva); 1261 return (0); 1262 } 1263 cc = (size_t)MIN(cnt, len); 1264 memcpy(cp, dp, cc); 1265 cp += cc; 1266 uva += cc; 1267 len -= cc; 1268 } 1269 return (ssize_t)(cp - buf); 1270 } 1271 1272 ssize_t 1273 kvm_uread(kd, p, uva, buf, len) 1274 kvm_t *kd; 1275 const struct proc *p; 1276 u_long uva; 1277 char *buf; 1278 size_t len; 1279 { 1280 struct miniproc mp; 1281 1282 PTOMINI(p, &mp); 1283 return (kvm_ureadm(kd, &mp, uva, buf, len)); 1284 } 1285