xref: /freebsd/lib/libkvm/kvm_proc.c (revision e627b39baccd1ec9129690167cf5e6d860509655)
1 /*-
2  * Copyright (c) 1989, 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software developed by the Computer Systems
6  * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
7  * BG 91-66 and contributed to Berkeley.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *	This product includes software developed by the University of
20  *	California, Berkeley and its contributors.
21  * 4. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 
38 #if defined(LIBC_SCCS) && !defined(lint)
39 static char sccsid[] = "@(#)kvm_proc.c	8.3 (Berkeley) 9/23/93";
40 #endif /* LIBC_SCCS and not lint */
41 
42 /*
43  * Proc traversal interface for kvm.  ps and w are (probably) the exclusive
44  * users of this code, so we've factored it out into a separate module.
45  * Thus, we keep this grunge out of the other kvm applications (i.e.,
46  * most other applications are interested only in open/close/read/nlist).
47  */
48 
49 #include <sys/param.h>
50 #include <sys/user.h>
51 #include <sys/proc.h>
52 #include <sys/exec.h>
53 #include <sys/stat.h>
54 #include <sys/ioctl.h>
55 #include <sys/tty.h>
56 #include <sys/file.h>
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <unistd.h>
60 #include <nlist.h>
61 #include <kvm.h>
62 
63 #include <vm/vm.h>
64 #include <vm/vm_param.h>
65 #include <vm/swap_pager.h>
66 
67 #include <sys/sysctl.h>
68 
69 #include <limits.h>
70 #include <memory.h>
71 #include <db.h>
72 #include <paths.h>
73 
74 #include "kvm_private.h"
75 
76 #if used
77 static char *
78 kvm_readswap(kd, p, va, cnt)
79 	kvm_t *kd;
80 	const struct proc *p;
81 	u_long va;
82 	u_long *cnt;
83 {
84 #ifdef __FreeBSD__
85 	/* XXX Stubbed out, our vm system is differnet */
86 	_kvm_err(kd, kd->program, "kvm_readswap not implemented");
87 	return(0);
88 #endif	/* __FreeBSD__ */
89 }
90 #endif
91 
92 #define KREAD(kd, addr, obj) \
93 	(kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj))
94 
95 /*
96  * Read proc's from memory file into buffer bp, which has space to hold
97  * at most maxcnt procs.
98  */
99 static int
100 kvm_proclist(kd, what, arg, p, bp, maxcnt)
101 	kvm_t *kd;
102 	int what, arg;
103 	struct proc *p;
104 	struct kinfo_proc *bp;
105 	int maxcnt;
106 {
107 	register int cnt = 0;
108 	struct eproc eproc;
109 	struct pgrp pgrp;
110 	struct session sess;
111 	struct tty tty;
112 	struct proc proc;
113 
114 	for (; cnt < maxcnt && p != NULL; p = proc.p_list.le_next) {
115 		if (KREAD(kd, (u_long)p, &proc)) {
116 			_kvm_err(kd, kd->program, "can't read proc at %x", p);
117 			return (-1);
118 		}
119 		if (KREAD(kd, (u_long)proc.p_cred, &eproc.e_pcred) == 0)
120 			(void)(KREAD(kd, (u_long)eproc.e_pcred.pc_ucred,
121 			             &eproc.e_ucred));
122 
123 		switch(what) {
124 
125 		case KERN_PROC_PID:
126 			if (proc.p_pid != (pid_t)arg)
127 				continue;
128 			break;
129 
130 		case KERN_PROC_UID:
131 			if (eproc.e_ucred.cr_uid != (uid_t)arg)
132 				continue;
133 			break;
134 
135 		case KERN_PROC_RUID:
136 			if (eproc.e_pcred.p_ruid != (uid_t)arg)
137 				continue;
138 			break;
139 		}
140 		/*
141 		 * We're going to add another proc to the set.  If this
142 		 * will overflow the buffer, assume the reason is because
143 		 * nprocs (or the proc list) is corrupt and declare an error.
144 		 */
145 		if (cnt >= maxcnt) {
146 			_kvm_err(kd, kd->program, "nprocs corrupt");
147 			return (-1);
148 		}
149 		/*
150 		 * gather eproc
151 		 */
152 		eproc.e_paddr = p;
153 		if (KREAD(kd, (u_long)proc.p_pgrp, &pgrp)) {
154 			_kvm_err(kd, kd->program, "can't read pgrp at %x",
155 				 proc.p_pgrp);
156 			return (-1);
157 		}
158 		eproc.e_sess = pgrp.pg_session;
159 		eproc.e_pgid = pgrp.pg_id;
160 		eproc.e_jobc = pgrp.pg_jobc;
161 		if (KREAD(kd, (u_long)pgrp.pg_session, &sess)) {
162 			_kvm_err(kd, kd->program, "can't read session at %x",
163 				pgrp.pg_session);
164 			return (-1);
165 		}
166 		(void)memcpy(eproc.e_login, sess.s_login,
167 						sizeof(eproc.e_login));
168 		if ((proc.p_flag & P_CONTROLT) && sess.s_ttyp != NULL) {
169 			if (KREAD(kd, (u_long)sess.s_ttyp, &tty)) {
170 				_kvm_err(kd, kd->program,
171 					 "can't read tty at %x", sess.s_ttyp);
172 				return (-1);
173 			}
174 			eproc.e_tdev = tty.t_dev;
175 			eproc.e_tsess = tty.t_session;
176 			if (tty.t_pgrp != NULL) {
177 				if (KREAD(kd, (u_long)tty.t_pgrp, &pgrp)) {
178 					_kvm_err(kd, kd->program,
179 						 "can't read tpgrp at &x",
180 						tty.t_pgrp);
181 					return (-1);
182 				}
183 				eproc.e_tpgid = pgrp.pg_id;
184 			} else
185 				eproc.e_tpgid = -1;
186 		} else
187 			eproc.e_tdev = NODEV;
188 		eproc.e_flag = sess.s_ttyvp ? EPROC_CTTY : 0;
189 		if (sess.s_leader == p)
190 			eproc.e_flag |= EPROC_SLEADER;
191 		if (proc.p_wmesg)
192 			(void)kvm_read(kd, (u_long)proc.p_wmesg,
193 			    eproc.e_wmesg, WMESGLEN);
194 
195 #ifdef sparc
196 		(void)kvm_read(kd, (u_long)&proc.p_vmspace->vm_rssize,
197 		    (char *)&eproc.e_vm.vm_rssize,
198 		    sizeof(eproc.e_vm.vm_rssize));
199 		(void)kvm_read(kd, (u_long)&proc.p_vmspace->vm_tsize,
200 		    (char *)&eproc.e_vm.vm_tsize,
201 		    3 * sizeof(eproc.e_vm.vm_rssize));	/* XXX */
202 #else
203 		(void)kvm_read(kd, (u_long)proc.p_vmspace,
204 		    (char *)&eproc.e_vm, sizeof(eproc.e_vm));
205 #endif
206 		eproc.e_xsize = eproc.e_xrssize = 0;
207 		eproc.e_xccount = eproc.e_xswrss = 0;
208 
209 		switch (what) {
210 
211 		case KERN_PROC_PGRP:
212 			if (eproc.e_pgid != (pid_t)arg)
213 				continue;
214 			break;
215 
216 		case KERN_PROC_TTY:
217 			if ((proc.p_flag & P_CONTROLT) == 0 ||
218 			     eproc.e_tdev != (dev_t)arg)
219 				continue;
220 			break;
221 		}
222 		bcopy(&proc, &bp->kp_proc, sizeof(proc));
223 		bcopy(&eproc, &bp->kp_eproc, sizeof(eproc));
224 		++bp;
225 		++cnt;
226 	}
227 	return (cnt);
228 }
229 
230 /*
231  * Build proc info array by reading in proc list from a crash dump.
232  * Return number of procs read.  maxcnt is the max we will read.
233  */
234 static int
235 kvm_deadprocs(kd, what, arg, a_allproc, a_zombproc, maxcnt)
236 	kvm_t *kd;
237 	int what, arg;
238 	u_long a_allproc;
239 	u_long a_zombproc;
240 	int maxcnt;
241 {
242 	register struct kinfo_proc *bp = kd->procbase;
243 	register int acnt, zcnt;
244 	struct proc *p;
245 
246 	if (KREAD(kd, a_allproc, &p)) {
247 		_kvm_err(kd, kd->program, "cannot read allproc");
248 		return (-1);
249 	}
250 	acnt = kvm_proclist(kd, what, arg, p, bp, maxcnt);
251 	if (acnt < 0)
252 		return (acnt);
253 
254 	if (KREAD(kd, a_zombproc, &p)) {
255 		_kvm_err(kd, kd->program, "cannot read zombproc");
256 		return (-1);
257 	}
258 	zcnt = kvm_proclist(kd, what, arg, p, bp + acnt, maxcnt - acnt);
259 	if (zcnt < 0)
260 		zcnt = 0;
261 
262 	return (acnt + zcnt);
263 }
264 
265 struct kinfo_proc *
266 kvm_getprocs(kd, op, arg, cnt)
267 	kvm_t *kd;
268 	int op, arg;
269 	int *cnt;
270 {
271 	int mib[4], size, st, nprocs;
272 
273 	if (kd->procbase != 0) {
274 		free((void *)kd->procbase);
275 		/*
276 		 * Clear this pointer in case this call fails.  Otherwise,
277 		 * kvm_close() will free it again.
278 		 */
279 		kd->procbase = 0;
280 	}
281 	if (ISALIVE(kd)) {
282 		size = 0;
283 		mib[0] = CTL_KERN;
284 		mib[1] = KERN_PROC;
285 		mib[2] = op;
286 		mib[3] = arg;
287 		st = sysctl(mib, op == KERN_PROC_ALL ? 3 : 4, NULL, &size, NULL, 0);
288 		if (st == -1) {
289 			_kvm_syserr(kd, kd->program, "kvm_getprocs");
290 			return (0);
291 		}
292 		kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size);
293 		if (kd->procbase == 0)
294 			return (0);
295 		st = sysctl(mib, op == KERN_PROC_ALL ? 3 : 4, kd->procbase, &size, NULL, 0);
296 		if (st == -1) {
297 			_kvm_syserr(kd, kd->program, "kvm_getprocs");
298 			return (0);
299 		}
300 		if (size % sizeof(struct kinfo_proc) != 0) {
301 			_kvm_err(kd, kd->program,
302 				"proc size mismatch (%d total, %d chunks)",
303 				size, sizeof(struct kinfo_proc));
304 			return (0);
305 		}
306 		nprocs = size / sizeof(struct kinfo_proc);
307 	} else {
308 		struct nlist nl[4], *p;
309 
310 		nl[0].n_name = "_nprocs";
311 		nl[1].n_name = "_allproc";
312 		nl[2].n_name = "_zombproc";
313 		nl[3].n_name = 0;
314 
315 		if (kvm_nlist(kd, nl) != 0) {
316 			for (p = nl; p->n_type != 0; ++p)
317 				;
318 			_kvm_err(kd, kd->program,
319 				 "%s: no such symbol", p->n_name);
320 			return (0);
321 		}
322 		if (KREAD(kd, nl[0].n_value, &nprocs)) {
323 			_kvm_err(kd, kd->program, "can't read nprocs");
324 			return (0);
325 		}
326 		size = nprocs * sizeof(struct kinfo_proc);
327 		kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size);
328 		if (kd->procbase == 0)
329 			return (0);
330 
331 		nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value,
332 				      nl[2].n_value, nprocs);
333 #ifdef notdef
334 		size = nprocs * sizeof(struct kinfo_proc);
335 		(void)realloc(kd->procbase, size);
336 #endif
337 	}
338 	*cnt = nprocs;
339 	return (kd->procbase);
340 }
341 
342 void
343 _kvm_freeprocs(kd)
344 	kvm_t *kd;
345 {
346 	if (kd->procbase) {
347 		free(kd->procbase);
348 		kd->procbase = 0;
349 	}
350 }
351 
352 void *
353 _kvm_realloc(kd, p, n)
354 	kvm_t *kd;
355 	void *p;
356 	size_t n;
357 {
358 	void *np = (void *)realloc(p, n);
359 
360 	if (np == 0)
361 		_kvm_err(kd, kd->program, "out of memory");
362 	return (np);
363 }
364 
365 #ifndef MAX
366 #define MAX(a, b) ((a) > (b) ? (a) : (b))
367 #endif
368 
369 /*
370  * Read in an argument vector from the user address space of process p.
371  * addr if the user-space base address of narg null-terminated contiguous
372  * strings.  This is used to read in both the command arguments and
373  * environment strings.  Read at most maxcnt characters of strings.
374  */
375 static char **
376 kvm_argv(kd, p, addr, narg, maxcnt)
377 	kvm_t *kd;
378 	const struct proc *p;
379 	register u_long addr;
380 	register int narg;
381 	register int maxcnt;
382 {
383 	register char *np, *cp, *ep, *ap;
384 	register u_long oaddr = -1;
385 	register int len, cc;
386 	register char **argv;
387 
388 	/*
389 	 * Check that there aren't an unreasonable number of agruments,
390 	 * and that the address is in user space.
391 	 */
392 	if (narg > 512 || addr < VM_MIN_ADDRESS || addr >= VM_MAXUSER_ADDRESS)
393 		return (0);
394 
395 	/*
396 	 * kd->argv : work space for fetching the strings from the target
397 	 *            process's space, and is converted for returning to caller
398 	 */
399 	if (kd->argv == 0) {
400 		/*
401 		 * Try to avoid reallocs.
402 		 */
403 		kd->argc = MAX(narg + 1, 32);
404 		kd->argv = (char **)_kvm_malloc(kd, kd->argc *
405 						sizeof(*kd->argv));
406 		if (kd->argv == 0)
407 			return (0);
408 	} else if (narg + 1 > kd->argc) {
409 		kd->argc = MAX(2 * kd->argc, narg + 1);
410 		kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc *
411 						sizeof(*kd->argv));
412 		if (kd->argv == 0)
413 			return (0);
414 	}
415 	/*
416 	 * kd->argspc : returned to user, this is where the kd->argv
417 	 *              arrays are left pointing to the collected strings.
418 	 */
419 	if (kd->argspc == 0) {
420 		kd->argspc = (char *)_kvm_malloc(kd, PAGE_SIZE);
421 		if (kd->argspc == 0)
422 			return (0);
423 		kd->arglen = PAGE_SIZE;
424 	}
425 	/*
426 	 * kd->argbuf : used to pull in pages from the target process.
427 	 *              the strings are copied out of here.
428 	 */
429 	if (kd->argbuf == 0) {
430 		kd->argbuf = (char *)_kvm_malloc(kd, PAGE_SIZE);
431 		if (kd->argbuf == 0)
432 			return (0);
433 	}
434 
435 	/* Pull in the target process'es argv vector */
436 	cc = sizeof(char *) * narg;
437 	if (kvm_uread(kd, p, addr, (char *)kd->argv, cc) != cc)
438 		return (0);
439 	/*
440 	 * ap : saved start address of string we're working on in kd->argspc
441 	 * np : pointer to next place to write in kd->argspc
442 	 * len: length of data in kd->argspc
443 	 * argv: pointer to the argv vector that we are hunting around the
444 	 *       target process space for, and converting to addresses in
445 	 *       our address space (kd->argspc).
446 	 */
447 	ap = np = kd->argspc;
448 	argv = kd->argv;
449 	len = 0;
450 	/*
451 	 * Loop over pages, filling in the argument vector.
452 	 * Note that the argv strings could be pointing *anywhere* in
453 	 * the user address space and are no longer contiguous.
454 	 * Note that *argv is modified when we are going to fetch a string
455 	 * that crosses a page boundary.  We copy the next part of the string
456 	 * into to "np" and eventually convert the pointer.
457 	 */
458 	while (argv < kd->argv + narg && *argv != 0) {
459 
460 		/* get the address that the current argv string is on */
461 		addr = (u_long)*argv & ~(PAGE_SIZE - 1);
462 
463 		/* is it the same page as the last one? */
464 		if (addr != oaddr) {
465 			if (kvm_uread(kd, p, addr, kd->argbuf, PAGE_SIZE) !=
466 			    PAGE_SIZE)
467 				return (0);
468 			oaddr = addr;
469 		}
470 
471 		/* offset within the page... kd->argbuf */
472 		addr = (u_long)*argv & (PAGE_SIZE - 1);
473 
474 		/* cp = start of string, cc = count of chars in this chunk */
475 		cp = kd->argbuf + addr;
476 		cc = PAGE_SIZE - addr;
477 
478 		/* dont get more than asked for by user process */
479 		if (maxcnt > 0 && cc > maxcnt - len)
480 			cc = maxcnt - len;
481 
482 		/* pointer to end of string if we found it in this page */
483 		ep = memchr(cp, '\0', cc);
484 		if (ep != 0)
485 			cc = ep - cp + 1;
486 		/*
487 		 * at this point, cc is the count of the chars that we are
488 		 * going to retrieve this time. we may or may not have found
489 		 * the end of it.  (ep points to the null if the end is known)
490 		 */
491 
492 		/* will we exceed the malloc/realloced buffer? */
493 		if (len + cc > kd->arglen) {
494 			register int off;
495 			register char **pp;
496 			register char *op = kd->argspc;
497 
498 			kd->arglen *= 2;
499 			kd->argspc = (char *)_kvm_realloc(kd, kd->argspc,
500 							  kd->arglen);
501 			if (kd->argspc == 0)
502 				return (0);
503 			/*
504 			 * Adjust argv pointers in case realloc moved
505 			 * the string space.
506 			 */
507 			off = kd->argspc - op;
508 			for (pp = kd->argv; pp < argv; pp++)
509 				*pp += off;
510 			ap += off;
511 			np += off;
512 		}
513 		/* np = where to put the next part of the string in kd->argspc*/
514 		/* np is kinda redundant.. could use "kd->argspc + len" */
515 		memcpy(np, cp, cc);
516 		np += cc;	/* inc counters */
517 		len += cc;
518 
519 		/*
520 		 * if end of string found, set the *argv pointer to the
521 		 * saved beginning of string, and advance. argv points to
522 		 * somewhere in kd->argv..  This is initially relative
523 		 * to the target process, but when we close it off, we set
524 		 * it to point in our address space.
525 		 */
526 		if (ep != 0) {
527 			*argv++ = ap;
528 			ap = np;
529 		} else {
530 			/* update the address relative to the target process */
531 			*argv += cc;
532 		}
533 
534 		if (maxcnt > 0 && len >= maxcnt) {
535 			/*
536 			 * We're stopping prematurely.  Terminate the
537 			 * current string.
538 			 */
539 			if (ep == 0) {
540 				*np = '\0';
541 				*argv++ = ap;
542 			}
543 			break;
544 		}
545 	}
546 	/* Make sure argv is terminated. */
547 	*argv = 0;
548 	return (kd->argv);
549 }
550 
551 static void
552 ps_str_a(p, addr, n)
553 	struct ps_strings *p;
554 	u_long *addr;
555 	int *n;
556 {
557 	*addr = (u_long)p->ps_argvstr;
558 	*n = p->ps_nargvstr;
559 }
560 
561 static void
562 ps_str_e(p, addr, n)
563 	struct ps_strings *p;
564 	u_long *addr;
565 	int *n;
566 {
567 	*addr = (u_long)p->ps_envstr;
568 	*n = p->ps_nenvstr;
569 }
570 
571 /*
572  * Determine if the proc indicated by p is still active.
573  * This test is not 100% foolproof in theory, but chances of
574  * being wrong are very low.
575  */
576 static int
577 proc_verify(kd, kernp, p)
578 	kvm_t *kd;
579 	u_long kernp;
580 	const struct proc *p;
581 {
582 	struct proc kernproc;
583 
584 	/*
585 	 * Just read in the whole proc.  It's not that big relative
586 	 * to the cost of the read system call.
587 	 */
588 	if (kvm_read(kd, kernp, (char *)&kernproc, sizeof(kernproc)) !=
589 	    sizeof(kernproc))
590 		return (0);
591 	return (p->p_pid == kernproc.p_pid &&
592 		(kernproc.p_stat != SZOMB || p->p_stat == SZOMB));
593 }
594 
595 static char **
596 kvm_doargv(kd, kp, nchr, info)
597 	kvm_t *kd;
598 	const struct kinfo_proc *kp;
599 	int nchr;
600 	void (*info)(struct ps_strings *, u_long *, int *);
601 {
602 	register const struct proc *p = &kp->kp_proc;
603 	register char **ap;
604 	u_long addr;
605 	int cnt;
606 	struct ps_strings arginfo, *ps_strings;
607 	int mib[2];
608 	size_t len;
609 
610 	ps_strings = NULL;
611 	mib[0] = CTL_KERN;
612 	mib[1] = KERN_PS_STRINGS;
613 	len = sizeof(ps_strings);
614 	if (sysctl(mib, 2, &ps_strings, &len, NULL, 0) < 0 ||
615 	    ps_strings == NULL)
616 		ps_strings = PS_STRINGS;
617 
618 	/*
619 	 * Pointers are stored at the top of the user stack.
620 	 */
621 	if (p->p_stat == SZOMB ||
622 	    kvm_uread(kd, p, ps_strings, (char *)&arginfo,
623 		      sizeof(arginfo)) != sizeof(arginfo))
624 		return (0);
625 
626 	(*info)(&arginfo, &addr, &cnt);
627 	if (cnt == 0)
628 		return (0);
629 	ap = kvm_argv(kd, p, addr, cnt, nchr);
630 	/*
631 	 * For live kernels, make sure this process didn't go away.
632 	 */
633 	if (ap != 0 && ISALIVE(kd) &&
634 	    !proc_verify(kd, (u_long)kp->kp_eproc.e_paddr, p))
635 		ap = 0;
636 	return (ap);
637 }
638 
639 /*
640  * Get the command args.  This code is now machine independent.
641  */
642 char **
643 kvm_getargv(kd, kp, nchr)
644 	kvm_t *kd;
645 	const struct kinfo_proc *kp;
646 	int nchr;
647 {
648 	return (kvm_doargv(kd, kp, nchr, ps_str_a));
649 }
650 
651 char **
652 kvm_getenvv(kd, kp, nchr)
653 	kvm_t *kd;
654 	const struct kinfo_proc *kp;
655 	int nchr;
656 {
657 	return (kvm_doargv(kd, kp, nchr, ps_str_e));
658 }
659 
660 /*
661  * Read from user space.  The user context is given by p.
662  */
663 ssize_t
664 kvm_uread(kd, p, uva, buf, len)
665 	kvm_t *kd;
666 	register const struct proc *p;
667 	register u_long uva;
668 	register char *buf;
669 	register size_t len;
670 {
671 	register char *cp;
672 	char procfile[MAXPATHLEN];
673 	ssize_t amount;
674 	int fd;
675 
676 	if (!ISALIVE(kd)) {
677 		_kvm_err(kd, kd->program, "cannot read user space from dead kernel");
678 		return(0);
679 	}
680 
681 	cp = buf;
682 
683 	sprintf(procfile, "/proc/%d/mem", p->p_pid);
684 	fd = open(procfile, O_RDONLY, 0);
685 
686 	if (fd < 0) {
687 		_kvm_err(kd, kd->program, "cannot open %s", procfile);
688 		close(fd);
689 		return (0);
690 	}
691 
692 
693 	while (len > 0) {
694 		if (lseek(fd, (off_t)uva, 0) == -1 && errno != 0) {
695 			_kvm_err(kd, kd->program, "invalid address (%x) in %s", uva, procfile);
696 			break;
697 		}
698 		amount = read(fd, cp, len);
699 		if (amount < 0) {
700 			_kvm_err(kd, kd->program, "error reading %s", procfile);
701 			break;
702 		}
703 		cp += amount;
704 		uva += amount;
705 		len -= amount;
706 	}
707 
708 	close(fd);
709 	return (ssize_t)(cp - buf);
710 }
711