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