xref: /openbsd-src/lib/libkvm/kvm.c (revision 0eea0d082377cb9c3ec583313dc4d52b7b6a4d6d)
1 /*	$OpenBSD: kvm.c,v 1.39 2004/07/01 02:04:10 mickey Exp $ */
2 /*	$NetBSD: kvm.c,v 1.43 1996/05/05 04:31:59 gwr Exp $	*/
3 
4 /*-
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. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 #if defined(LIBC_SCCS) && !defined(lint)
38 #if 0
39 static char sccsid[] = "@(#)kvm.c	8.2 (Berkeley) 2/13/94";
40 #else
41 static char *rcsid = "$OpenBSD: kvm.c,v 1.39 2004/07/01 02:04:10 mickey Exp $";
42 #endif
43 #endif /* LIBC_SCCS and not lint */
44 
45 #include <sys/param.h>
46 #include <sys/user.h>
47 #include <sys/proc.h>
48 #include <sys/ioctl.h>
49 #include <sys/stat.h>
50 #include <sys/sysctl.h>
51 
52 #include <sys/core.h>
53 #include <sys/exec_aout.h>
54 #include <sys/kcore.h>
55 
56 #include <ctype.h>
57 #include <db.h>
58 #include <fcntl.h>
59 #include <libgen.h>
60 #include <limits.h>
61 #include <nlist.h>
62 #include <paths.h>
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <string.h>
66 #include <unistd.h>
67 #include <kvm.h>
68 #include <stdarg.h>
69 
70 #include "kvm_private.h"
71 
72 static int	kvm_dbopen(kvm_t *, const char *);
73 static int	_kvm_get_header(kvm_t *);
74 static kvm_t	*_kvm_open(kvm_t *, const char *, const char *, const char *,
75 		    int, char *);
76 static int	clear_gap(kvm_t *, FILE *, int);
77 static int	kvm_setfd(kvm_t *);
78 
79 char *
80 kvm_geterr(kd)
81 	kvm_t *kd;
82 {
83 	return (kd->errbuf);
84 }
85 
86 /*
87  * Wrapper around pread.
88  */
89 ssize_t
90 _kvm_pread(kvm_t *kd, int fd, void *buf, size_t nbytes, off_t offset)
91 {
92 	ssize_t rval;
93 
94 	errno = 0;
95 	rval = pread(fd, buf, nbytes, offset);
96 	if (rval == -1 || errno != 0) {
97 		_kvm_syserr(kd, kd->program, "pread");
98 	}
99 	return (rval);
100 }
101 
102 /*
103  * Wrapper around pwrite.
104  */
105 ssize_t
106 _kvm_pwrite(kvm_t *kd, int fd, void *buf, size_t nbytes, off_t offset)
107 {
108 	ssize_t rval;
109 
110 	errno = 0;
111 	rval = pwrite(fd, buf, nbytes, offset);
112 	if (rval == -1 || errno != 0) {
113 		_kvm_syserr(kd, kd->program, "pwrite");
114 	}
115 	return (rval);
116 }
117 
118 /*
119  * Report an error using printf style arguments.  "program" is kd->program
120  * on hard errors, and 0 on soft errors, so that under sun error emulation,
121  * only hard errors are printed out (otherwise, programs like gdb will
122  * generate tons of error messages when trying to access bogus pointers).
123  */
124 void
125 _kvm_err(kvm_t *kd, const char *program, const char *fmt, ...)
126 {
127 	va_list ap;
128 
129 	va_start(ap, fmt);
130 	if (program != NULL) {
131 		(void)fprintf(stderr, "%s: ", program);
132 		(void)vfprintf(stderr, fmt, ap);
133 		(void)fputc('\n', stderr);
134 	} else
135 		(void)vsnprintf(kd->errbuf,
136 		    sizeof(kd->errbuf), (char *)fmt, ap);
137 
138 	va_end(ap);
139 }
140 
141 void
142 _kvm_syserr(kvm_t *kd, const char *program, const char *fmt, ...)
143 {
144 	va_list ap;
145 	int n;
146 
147 	va_start(ap, fmt);
148 	if (program != NULL) {
149 		(void)fprintf(stderr, "%s: ", program);
150 		(void)vfprintf(stderr, fmt, ap);
151 		(void)fprintf(stderr, ": %s\n", strerror(errno));
152 	} else {
153 		char *cp = kd->errbuf;
154 
155 		(void)vsnprintf(cp, sizeof(kd->errbuf), (char *)fmt, ap);
156 		n = strlen(cp);
157 		(void)snprintf(&cp[n], sizeof(kd->errbuf) - n, ": %s",
158 		    strerror(errno));
159 	}
160 	va_end(ap);
161 }
162 
163 void *
164 _kvm_malloc(kvm_t *kd, size_t n)
165 {
166 	void *p;
167 
168 	if ((p = malloc(n)) == NULL)
169 		_kvm_err(kd, kd->program, "%s", strerror(errno));
170 	return (p);
171 }
172 
173 static kvm_t *
174 _kvm_open(kvm_t *kd, const char *uf, const char *mf, const char *sf,
175     int flag, char *errout)
176 {
177 	struct stat st;
178 
179 	kd->db = 0;
180 	kd->pmfd = -1;
181 	kd->vmfd = -1;
182 	kd->swfd = -1;
183 	kd->nlfd = -1;
184 	kd->alive = 0;
185 	kd->procbase = 0;
186 	kd->procbase2 = 0;
187 	kd->nbpg = getpagesize();
188 	kd->swapspc = 0;
189 	kd->argspc = 0;
190 	kd->argbuf = 0;
191 	kd->argv = 0;
192 	kd->vmst = NULL;
193 	kd->vm_page_buckets = 0;
194 	kd->kcore_hdr = 0;
195 	kd->cpu_dsize = 0;
196 	kd->cpu_data = 0;
197 	kd->dump_off = 0;
198 
199 	if (flag & KVM_NO_FILES) {
200 		kd->alive = 1;
201 		return (kd);
202 	}
203 
204 	if (uf && strlen(uf) >= MAXPATHLEN) {
205 		_kvm_err(kd, kd->program, "exec file name too long");
206 		goto failed;
207 	}
208 	if (flag & ~O_ACCMODE) {
209 		_kvm_err(kd, kd->program, "bad flags arg");
210 		goto failed;
211 	}
212 	if (mf == 0)
213 		mf = _PATH_MEM;
214 	if (sf == 0)
215 		sf = _PATH_DRUM;
216 
217 	if ((kd->pmfd = open(mf, flag, 0)) < 0) {
218 		_kvm_syserr(kd, kd->program, "%s", mf);
219 		goto failed;
220 	}
221 	if (fstat(kd->pmfd, &st) < 0) {
222 		_kvm_syserr(kd, kd->program, "%s", mf);
223 		goto failed;
224 	}
225 	if (S_ISCHR(st.st_mode)) {
226 		/*
227 		 * If this is a character special device, then check that
228 		 * it's /dev/mem.  If so, open kmem too.  (Maybe we should
229 		 * make it work for either /dev/mem or /dev/kmem -- in either
230 		 * case you're working with a live kernel.)
231 		 */
232 		if (strcmp(mf, _PATH_MEM) != 0) {	/* XXX */
233 			_kvm_err(kd, kd->program,
234 				 "%s: not physical memory device", mf);
235 			goto failed;
236 		}
237 		if ((kd->vmfd = open(_PATH_KMEM, flag, 0)) < 0) {
238 			_kvm_syserr(kd, kd->program, "%s", _PATH_KMEM);
239 			goto failed;
240 		}
241 		kd->alive = 1;
242 		if ((kd->swfd = open(sf, flag, 0)) < 0) {
243 			_kvm_syserr(kd, kd->program, "%s", sf);
244 			goto failed;
245 		}
246 		/*
247 		 * Open kvm nlist database.  We only try to use
248 		 * the pre-built database if the namelist file name
249 		 * pointer is NULL.  If the database cannot or should
250 		 * not be opened, open the namelist argument so we
251 		 * revert to slow nlist() calls.
252 		 * If no file is specified, try opening _PATH_KSYMS and
253 		 * fall back to _PATH_UNIX.
254 		 */
255 		if (kvm_dbopen(kd, uf ? uf : _PATH_UNIX) == -1 &&
256 		    ((uf && (kd->nlfd = open(uf, O_RDONLY, 0)) == -1) || (!uf &&
257 		    (kd->nlfd = open((uf = _PATH_KSYMS), O_RDONLY, 0)) == -1 &&
258 		    (kd->nlfd = open((uf = _PATH_UNIX), O_RDONLY, 0)) == -1))) {
259 			_kvm_syserr(kd, kd->program, "%s", uf);
260 			goto failed;
261 		}
262 	} else {
263 		/*
264 		 * This is a crash dump.
265 		 * Initialize the virtual address translation machinery,
266 		 * but first setup the namelist fd.
267 		 * If no file is specified, try opening _PATH_KSYMS and
268 		 * fall back to _PATH_UNIX.
269 		 */
270 		if ((uf && (kd->nlfd = open(uf, O_RDONLY, 0)) == -1) || (!uf &&
271 		    (kd->nlfd = open((uf = _PATH_KSYMS), O_RDONLY, 0)) == -1 &&
272 		    (kd->nlfd = open((uf = _PATH_UNIX), O_RDONLY, 0)) == -1)) {
273 			_kvm_syserr(kd, kd->program, "%s", uf);
274 			goto failed;
275 		}
276 
277 		/*
278 		 * If there is no valid core header, fail silently here.
279 		 * The address translations however will fail without
280 		 * header. Things can be made to run by calling
281 		 * kvm_dump_mkheader() before doing any translation.
282 		 */
283 		if (_kvm_get_header(kd) == 0) {
284 			if (_kvm_initvtop(kd) < 0)
285 				goto failed;
286 		}
287 	}
288 	if (kvm_setfd(kd) == 0)
289 		return (kd);
290 	else
291 		_kvm_syserr(kd, kd->program, "can't set close on exec flag");
292 failed:
293 	/*
294 	 * Copy out the error if doing sane error semantics.
295 	 */
296 	if (errout != 0)
297 		(void)strlcpy(errout, kd->errbuf, _POSIX2_LINE_MAX);
298 	(void)kvm_close(kd);
299 	return (0);
300 }
301 
302 /*
303  * The kernel dump file (from savecore) contains:
304  *    kcore_hdr_t kcore_hdr;
305  *    kcore_seg_t cpu_hdr;
306  *    (opaque)    cpu_data; (size is cpu_hdr.c_size)
307  *    kcore_seg_t mem_hdr;
308  *    (memory)    mem_data; (size is mem_hdr.c_size)
309  *
310  * Note: khdr is padded to khdr.c_hdrsize;
311  * cpu_hdr and mem_hdr are padded to khdr.c_seghdrsize
312  */
313 static int
314 _kvm_get_header(kvm_t *kd)
315 {
316 	kcore_hdr_t	kcore_hdr;
317 	kcore_seg_t	cpu_hdr;
318 	kcore_seg_t	mem_hdr;
319 	size_t		offset;
320 	ssize_t		sz;
321 
322 	/*
323 	 * Read the kcore_hdr_t
324 	 */
325 	sz = _kvm_pread(kd, kd->pmfd, &kcore_hdr, sizeof(kcore_hdr), (off_t)0);
326 	if (sz != sizeof(kcore_hdr)) {
327 		return (-1);
328 	}
329 
330 	/*
331 	 * Currently, we only support dump-files made by the current
332 	 * architecture...
333 	 */
334 	if ((CORE_GETMAGIC(kcore_hdr) != KCORE_MAGIC) ||
335 	    (CORE_GETMID(kcore_hdr) != MID_MACHINE))
336 		return (-1);
337 
338 	/*
339 	 * Currently, we only support exactly 2 segments: cpu-segment
340 	 * and data-segment in exactly that order.
341 	 */
342 	if (kcore_hdr.c_nseg != 2)
343 		return (-1);
344 
345 	/*
346 	 * Save away the kcore_hdr.  All errors after this
347 	 * should do a to "goto fail" to deallocate things.
348 	 */
349 	kd->kcore_hdr = _kvm_malloc(kd, sizeof(kcore_hdr));
350 	if (kd->kcore_hdr == NULL)
351 		goto fail;
352 	memcpy(kd->kcore_hdr, &kcore_hdr, sizeof(kcore_hdr));
353 	offset = kcore_hdr.c_hdrsize;
354 
355 	/*
356 	 * Read the CPU segment header
357 	 */
358 	sz = _kvm_pread(kd, kd->pmfd, &cpu_hdr, sizeof(cpu_hdr), (off_t)offset);
359 	if (sz != sizeof(cpu_hdr)) {
360 		goto fail;
361 	}
362 
363 	if ((CORE_GETMAGIC(cpu_hdr) != KCORESEG_MAGIC) ||
364 	    (CORE_GETFLAG(cpu_hdr) != CORE_CPU))
365 		goto fail;
366 	offset += kcore_hdr.c_seghdrsize;
367 
368 	/*
369 	 * Read the CPU segment DATA.
370 	 */
371 	kd->cpu_dsize = cpu_hdr.c_size;
372 	kd->cpu_data = _kvm_malloc(kd, cpu_hdr.c_size);
373 	if (kd->cpu_data == NULL)
374 		goto fail;
375 
376 	sz = _kvm_pread(kd, kd->pmfd, kd->cpu_data, cpu_hdr.c_size, (off_t)offset);
377 	if (sz != cpu_hdr.c_size) {
378 		goto fail;
379 	}
380 
381 	offset += cpu_hdr.c_size;
382 
383 	/*
384 	 * Read the next segment header: data segment
385 	 */
386 	sz = _kvm_pread(kd, kd->pmfd, &mem_hdr, sizeof(mem_hdr), (off_t)offset);
387 	if (sz != sizeof(mem_hdr)) {
388 		goto fail;
389 	}
390 
391 	offset += kcore_hdr.c_seghdrsize;
392 
393 	if ((CORE_GETMAGIC(mem_hdr) != KCORESEG_MAGIC) ||
394 	    (CORE_GETFLAG(mem_hdr) != CORE_DATA))
395 		goto fail;
396 
397 	kd->dump_off = offset;
398 	return (0);
399 
400 fail:
401 	if (kd->kcore_hdr != NULL) {
402 		free(kd->kcore_hdr);
403 		kd->kcore_hdr = NULL;
404 	}
405 	if (kd->cpu_data != NULL) {
406 		free(kd->cpu_data);
407 		kd->cpu_data = NULL;
408 		kd->cpu_dsize = 0;
409 	}
410 
411 	return (-1);
412 }
413 
414 /*
415  * The format while on the dump device is: (new format)
416  *    kcore_seg_t cpu_hdr;
417  *    (opaque)    cpu_data; (size is cpu_hdr.c_size)
418  *    kcore_seg_t mem_hdr;
419  *    (memory)    mem_data; (size is mem_hdr.c_size)
420  */
421 int
422 kvm_dump_mkheader(kvm_t *kd, off_t dump_off)
423 {
424 	kcore_seg_t	cpu_hdr;
425 	int	hdr_size, sz;
426 
427 	if (kd->kcore_hdr != NULL) {
428 	    _kvm_err(kd, kd->program, "already has a dump header");
429 	    return (-1);
430 	}
431 	if (ISALIVE(kd)) {
432 		_kvm_err(kd, kd->program, "don't use on live kernel");
433 		return (-1);
434 	}
435 
436 	/*
437 	 * Validate new format crash dump
438 	 */
439 	sz = _kvm_pread(kd, kd->pmfd, &cpu_hdr, sizeof(cpu_hdr), (off_t)dump_off);
440 	if (sz != sizeof(cpu_hdr)) {
441 		return (-1);
442 	}
443 	if ((CORE_GETMAGIC(cpu_hdr) != KCORE_MAGIC)
444 		|| (CORE_GETMID(cpu_hdr) != MID_MACHINE)) {
445 		_kvm_err(kd, 0, "invalid magic in cpu_hdr");
446 		return (-1);
447 	}
448 	hdr_size = ALIGN(sizeof(cpu_hdr));
449 
450 	/*
451 	 * Read the CPU segment.
452 	 */
453 	kd->cpu_dsize = cpu_hdr.c_size;
454 	kd->cpu_data = _kvm_malloc(kd, kd->cpu_dsize);
455 	if (kd->cpu_data == NULL)
456 		goto fail;
457 
458 	sz = _kvm_pread(kd, kd->pmfd, kd->cpu_data, cpu_hdr.c_size,
459 	    (off_t)dump_off+hdr_size);
460 	if (sz != cpu_hdr.c_size) {
461 		_kvm_err(kd, 0, "invalid size in cpu_hdr");
462 		goto fail;
463 	}
464 	hdr_size += kd->cpu_dsize;
465 
466 	/*
467 	 * Leave phys mem pointer at beginning of memory data
468 	 */
469 	kd->dump_off = dump_off + hdr_size;
470 	errno = 0;
471 	if (lseek(kd->pmfd, kd->dump_off, SEEK_SET) != kd->dump_off && errno != 0) {
472 		_kvm_err(kd, 0, "invalid dump offset - lseek");
473 		goto fail;
474 	}
475 
476 	/*
477 	 * Create a kcore_hdr.
478 	 */
479 	kd->kcore_hdr = _kvm_malloc(kd, sizeof(kcore_hdr_t));
480 	if (kd->kcore_hdr == NULL)
481 		goto fail;
482 
483 	kd->kcore_hdr->c_hdrsize    = ALIGN(sizeof(kcore_hdr_t));
484 	kd->kcore_hdr->c_seghdrsize = ALIGN(sizeof(kcore_seg_t));
485 	kd->kcore_hdr->c_nseg       = 2;
486 	CORE_SETMAGIC(*(kd->kcore_hdr), KCORE_MAGIC, MID_MACHINE,0);
487 
488 	/*
489 	 * Now that we have a valid header, enable translations.
490 	 */
491 	if (_kvm_initvtop(kd) == 0)
492 		/* Success */
493 		return (hdr_size);
494 
495 fail:
496 	if (kd->kcore_hdr != NULL) {
497 		free(kd->kcore_hdr);
498 		kd->kcore_hdr = NULL;
499 	}
500 	if (kd->cpu_data != NULL) {
501 		free(kd->cpu_data);
502 		kd->cpu_data = NULL;
503 		kd->cpu_dsize = 0;
504 	}
505 	return (-1);
506 }
507 
508 static int
509 clear_gap(kvm_t *kd, FILE *fp, int size)
510 {
511 	if (size <= 0) /* XXX - < 0 should never happen */
512 		return (0);
513 	while (size-- > 0) {
514 		if (fputc(0, fp) == EOF) {
515 			_kvm_syserr(kd, kd->program, "clear_gap");
516 			return (-1);
517 		}
518 	}
519 	return (0);
520 }
521 
522 /*
523  * Write the dump header info to 'fp'. Note that we can't use fseek(3) here
524  * because 'fp' might be a file pointer obtained by zopen().
525  */
526 int
527 kvm_dump_wrtheader(kvm_t *kd, FILE *fp, int dumpsize)
528 {
529 	kcore_seg_t	seghdr;
530 	long		offset;
531 	int		gap;
532 
533 	if (kd->kcore_hdr == NULL || kd->cpu_data == NULL) {
534 		_kvm_err(kd, kd->program, "no valid dump header(s)");
535 		return (-1);
536 	}
537 
538 	/*
539 	 * Write the generic header
540 	 */
541 	offset = 0;
542 	if (fwrite((void*)kd->kcore_hdr, sizeof(kcore_hdr_t), 1, fp) <= 0) {
543 		_kvm_syserr(kd, kd->program, "kvm_dump_wrtheader");
544 		return (-1);
545 	}
546 	offset += kd->kcore_hdr->c_hdrsize;
547 	gap     = kd->kcore_hdr->c_hdrsize - sizeof(kcore_hdr_t);
548 	if (clear_gap(kd, fp, gap) == -1)
549 		return (-1);
550 
551 	/*
552 	 * Write the cpu header
553 	 */
554 	CORE_SETMAGIC(seghdr, KCORESEG_MAGIC, 0, CORE_CPU);
555 	seghdr.c_size = ALIGN(kd->cpu_dsize);
556 	if (fwrite((void*)&seghdr, sizeof(seghdr), 1, fp) <= 0) {
557 		_kvm_syserr(kd, kd->program, "kvm_dump_wrtheader");
558 		return (-1);
559 	}
560 	offset += kd->kcore_hdr->c_seghdrsize;
561 	gap     = kd->kcore_hdr->c_seghdrsize - sizeof(seghdr);
562 	if (clear_gap(kd, fp, gap) == -1)
563 		return (-1);
564 
565 	if (fwrite((void*)kd->cpu_data, kd->cpu_dsize, 1, fp) <= 0) {
566 		_kvm_syserr(kd, kd->program, "kvm_dump_wrtheader");
567 		return (-1);
568 	}
569 	offset += seghdr.c_size;
570 	gap     = seghdr.c_size - kd->cpu_dsize;
571 	if (clear_gap(kd, fp, gap) == -1)
572 		return (-1);
573 
574 	/*
575 	 * Write the actual dump data segment header
576 	 */
577 	CORE_SETMAGIC(seghdr, KCORESEG_MAGIC, 0, CORE_DATA);
578 	seghdr.c_size = dumpsize;
579 	if (fwrite((void*)&seghdr, sizeof(seghdr), 1, fp) <= 0) {
580 		_kvm_syserr(kd, kd->program, "kvm_dump_wrtheader");
581 		return (-1);
582 	}
583 	offset += kd->kcore_hdr->c_seghdrsize;
584 	gap     = kd->kcore_hdr->c_seghdrsize - sizeof(seghdr);
585 	if (clear_gap(kd, fp, gap) == -1)
586 		return (-1);
587 
588 	return (offset);
589 }
590 
591 kvm_t *
592 kvm_openfiles(const char *uf, const char *mf, const char *sf,
593     int flag, char *errout)
594 {
595 	kvm_t *kd;
596 
597 	if ((kd = malloc(sizeof(*kd))) == NULL) {
598 		(void)strlcpy(errout, strerror(errno), _POSIX2_LINE_MAX);
599 		return (0);
600 	}
601 	kd->program = 0;
602 	return (_kvm_open(kd, uf, mf, sf, flag, errout));
603 }
604 
605 kvm_t *
606 kvm_open(const char *uf, const char *mf, const char *sf, int flag,
607     const char *program)
608 {
609 	kvm_t *kd;
610 
611 	if ((kd = malloc(sizeof(*kd))) == NULL && program != NULL) {
612 		(void)fprintf(stderr, "%s: %s\n", program, strerror(errno));
613 		return (0);
614 	}
615 	kd->program = program;
616 	return (_kvm_open(kd, uf, mf, sf, flag, NULL));
617 }
618 
619 int
620 kvm_close(kvm_t *kd)
621 {
622 	int error = 0;
623 
624 	if (kd->pmfd >= 0)
625 		error |= close(kd->pmfd);
626 	if (kd->vmfd >= 0)
627 		error |= close(kd->vmfd);
628 	kd->alive = 0;
629 	if (kd->nlfd >= 0)
630 		error |= close(kd->nlfd);
631 	if (kd->swfd >= 0)
632 		error |= close(kd->swfd);
633 	if (kd->db != 0)
634 		error |= (kd->db->close)(kd->db);
635 	if (kd->vmst)
636 		_kvm_freevtop(kd);
637 	kd->cpu_dsize = 0;
638 	if (kd->cpu_data != NULL)
639 		free((void *)kd->cpu_data);
640 	if (kd->kcore_hdr != NULL)
641 		free((void *)kd->kcore_hdr);
642 	if (kd->procbase != 0)
643 		free((void *)kd->procbase);
644 	if (kd->swapspc != 0)
645 		free((void *)kd->swapspc);
646 	if (kd->argspc != 0)
647 		free((void *)kd->argspc);
648 	if (kd->argbuf != 0)
649 		free((void *)kd->argbuf);
650 	if (kd->argv != 0)
651 		free((void *)kd->argv);
652 	free((void *)kd);
653 
654 	return (error);
655 }
656 
657 /*
658  * Set up state necessary to do queries on the kernel namelist
659  * data base.  If the data base is out-of-data/incompatible with
660  * given executable, set up things so we revert to standard nlist call.
661  * Only called for live kernels.  Return 0 on success, -1 on failure.
662  */
663 static int
664 kvm_dbopen(kvm_t *kd, const char *uf)
665 {
666 	char dbversion[_POSIX2_LINE_MAX], kversion[_POSIX2_LINE_MAX];
667 	char dbname[MAXPATHLEN];
668 	struct nlist nitem;
669 	int dbversionlen;
670 	DBT rec;
671 
672 	uf = basename((char *)uf);
673 
674 	(void)snprintf(dbname, sizeof(dbname), "%skvm_%s.db", _PATH_VARDB, uf);
675 	kd->db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL);
676 	if (kd->db == NULL) {
677 		switch (errno) {
678 		case ENOENT:
679 			/* No kvm_bsd.db, fall back to /bsd silently */
680 			break;
681 		case EFTYPE:
682 			_kvm_err(kd, kd->program,
683 			    "file %s is incorrectly formatted", dbname);
684 			break;
685 		case EINVAL:
686 			_kvm_err(kd, kd->program,
687 			    "invalid argument to dbopen()");
688 			break;
689 		default:
690 			_kvm_err(kd, kd->program, "unknown dbopen() error");
691 			break;
692 		}
693 		return (-1);
694 	}
695 
696 	/*
697 	 * read version out of database
698 	 */
699 	rec.data = VRS_KEY;
700 	rec.size = sizeof(VRS_KEY) - 1;
701 	if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
702 		goto close;
703 	if (rec.data == 0 || rec.size > sizeof(dbversion))
704 		goto close;
705 
706 	bcopy(rec.data, dbversion, rec.size);
707 	dbversionlen = rec.size;
708 	/*
709 	 * Read version string from kernel memory.
710 	 * Since we are dealing with a live kernel, we can call kvm_read()
711 	 * at this point.
712 	 */
713 	rec.data = VRS_SYM;
714 	rec.size = sizeof(VRS_SYM) - 1;
715 	if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
716 		goto close;
717 	if (rec.data == 0 || rec.size != sizeof(struct nlist))
718 		goto close;
719 	bcopy((char *)rec.data, (char *)&nitem, sizeof(nitem));
720 	if (kvm_read(kd, (u_long)nitem.n_value, kversion, dbversionlen) !=
721 	    dbversionlen)
722 		goto close;
723 	/*
724 	 * If they match, we win - otherwise clear out kd->db so
725 	 * we revert to slow nlist().
726 	 */
727 	if (bcmp(dbversion, kversion, dbversionlen) == 0)
728 		return (0);
729 close:
730 	(void)(kd->db->close)(kd->db);
731 	kd->db = 0;
732 
733 	return (-1);
734 }
735 
736 int
737 kvm_nlist(kvm_t *kd, struct nlist *nl)
738 {
739 	struct nlist *p;
740 	int nvalid, rv;
741 
742 	/*
743 	 * If we can't use the data base, revert to the
744 	 * slow library call.
745 	 */
746 	if (kd->db == 0) {
747 		rv = __fdnlist(kd->nlfd, nl);
748 		if (rv == -1)
749 			_kvm_err(kd, 0, "bad namelist");
750 		return (rv);
751 	}
752 
753 	/*
754 	 * We can use the kvm data base.  Go through each nlist entry
755 	 * and look it up with a db query.
756 	 */
757 	nvalid = 0;
758 	for (p = nl; p->n_name && p->n_name[0]; ++p) {
759 		int len;
760 		DBT rec;
761 
762 		if ((len = strlen(p->n_name)) > 4096) {
763 			/* sanity */
764 			_kvm_err(kd, kd->program, "symbol too large");
765 			return (-1);
766 		}
767 		rec.data = p->n_name;
768 		rec.size = len;
769 
770 		/*
771 		 * Make sure that n_value = 0 when the symbol isn't found
772 		 */
773 		p->n_value = 0;
774 
775 		if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
776 			continue;
777 		if (rec.data == 0 || rec.size != sizeof(struct nlist))
778 			continue;
779 		++nvalid;
780 		/*
781 		 * Avoid alignment issues.
782 		 */
783 		bcopy((char *)&((struct nlist *)rec.data)->n_type,
784 		    (char *)&p->n_type, sizeof(p->n_type));
785 		bcopy((char *)&((struct nlist *)rec.data)->n_value,
786 		    (char *)&p->n_value, sizeof(p->n_value));
787 	}
788 	/*
789 	 * Return the number of entries that weren't found.
790 	 */
791 	return ((p - nl) - nvalid);
792 }
793 
794 int
795 kvm_dump_inval(kvm_t *kd)
796 {
797 	struct nlist	nlist[2];
798 	u_long		pa, x;
799 
800 	if (ISALIVE(kd)) {
801 		_kvm_err(kd, kd->program, "clearing dump on live kernel");
802 		return (-1);
803 	}
804 	nlist[0].n_name = "_dumpmag";
805 	nlist[1].n_name = NULL;
806 
807 	if (kvm_nlist(kd, nlist) == -1) {
808 		_kvm_err(kd, 0, "bad namelist");
809 		return (-1);
810 	}
811 
812 	if (nlist[0].n_value == 0) {
813 		_kvm_err(kd, nlist[0].n_name, "not in name list");
814 		return (-1);
815 	}
816 
817 	if (_kvm_kvatop(kd, (u_long)nlist[0].n_value, &pa) == 0)
818 		return (-1);
819 
820 	x = 0;
821 	if (_kvm_pwrite(kd, kd->pmfd, &x, sizeof(x),
822 	    (off_t)_kvm_pa2off(kd, pa)) != sizeof(x)) {
823 		_kvm_err(kd, 0, "cannot invalidate dump");
824 		return (-1);
825 	}
826 	return (0);
827 }
828 
829 ssize_t
830 kvm_read(kvm_t *kd, u_long kva, void *buf, size_t len)
831 {
832 	int cc;
833 	void *cp;
834 
835 	if (ISALIVE(kd)) {
836 		/*
837 		 * We're using /dev/kmem.  Just read straight from the
838 		 * device and let the active kernel do the address translation.
839 		 */
840 		cc = _kvm_pread(kd, kd->vmfd, buf, len, (off_t)kva);
841 		if (cc == -1) {
842 			_kvm_err(kd, 0, "invalid address (%lx)", kva);
843 			return (-1);
844 		} else if (cc < len)
845 			_kvm_err(kd, kd->program, "short read");
846 		return (cc);
847 	} else {
848 		if ((kd->kcore_hdr == NULL) || (kd->cpu_data == NULL)) {
849 			_kvm_err(kd, kd->program, "no valid dump header");
850 			return (-1);
851 		}
852 		cp = buf;
853 		while (len > 0) {
854 			u_long	pa;
855 
856 			/* In case of error, _kvm_kvatop sets the err string */
857 			cc = _kvm_kvatop(kd, kva, &pa);
858 			if (cc == 0)
859 				return (-1);
860 			if (cc > len)
861 				cc = len;
862 			cc = _kvm_pread(kd, kd->pmfd, cp, cc,
863 			    (off_t)_kvm_pa2off(kd, pa));
864 			if (cc == -1) {
865 				_kvm_syserr(kd, 0, _PATH_MEM);
866 				break;
867 			}
868 			/*
869 			 * If kvm_kvatop returns a bogus value or our core
870 			 * file is truncated, we might wind up seeking beyond
871 			 * the end of the core file in which case the read will
872 			 * return 0 (EOF).
873 			 */
874 			if (cc == 0)
875 				break;
876 			cp = (char *)cp + cc;
877 			kva += cc;
878 			len -= cc;
879 		}
880 		return ((char *)cp - (char *)buf);
881 	}
882 	/* NOTREACHED */
883 }
884 
885 ssize_t
886 kvm_write(kvm_t *kd, u_long kva, const void *buf, size_t len)
887 {
888 	int cc;
889 
890 	if (ISALIVE(kd)) {
891 		/*
892 		 * Just like kvm_read, only we write.
893 		 */
894 		cc = _kvm_pwrite(kd, kd->vmfd, (void*)buf, (size_t)len, (off_t)kva);
895 		if (cc == -1) {
896 			_kvm_err(kd, 0, "invalid address (%lx)", kva);
897 			return (-1);
898 		} else if (cc < len)
899 			_kvm_err(kd, kd->program, "short write");
900 		return (cc);
901 	} else {
902 		_kvm_err(kd, kd->program,
903 		    "kvm_write not implemented for dead kernels");
904 		return (-1);
905 	}
906 	/* NOTREACHED */
907 }
908 
909 static int
910 kvm_setfd(kvm_t *kd)
911 {
912 	if (kd->pmfd >= 0 && fcntl(kd->pmfd, F_SETFD, FD_CLOEXEC) < 0)
913 		return (-1);
914 	if (kd->vmfd >= 0 && fcntl(kd->vmfd, F_SETFD, FD_CLOEXEC) < 0)
915 		return (-1);
916 	if (kd->nlfd >= 0 && fcntl(kd->nlfd, F_SETFD, FD_CLOEXEC) < 0)
917 		return (-1);
918 	if (kd->swfd >= 0 && fcntl(kd->swfd, F_SETFD, FD_CLOEXEC) < 0)
919 		return (-1);
920 
921 	return (0);
922 }
923