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