1 /* $NetBSD: kvm.c,v 1.101 2014/02/19 20:21:22 dsl Exp $ */
4 * Copyright (c) 1989, 1992, 1993
5 * The Regents of the University of California. All rights reserved.
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.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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
36 #include <sys/cdefs.h>
37 #if defined(LIBC_SCCS) && !defined(lint)
39 static char sccsid
[] = "@(#)kvm.c 8.2 (Berkeley) 2/13/94";
41 __RCSID("$NetBSD: kvm.c,v 1.101 2014/02/19 20:21:22 dsl Exp $");
43 #endif /* LIBC_SCCS and not lint */
45 #include <sys/param.h>
48 #include <sys/ioctl.h>
50 #include <sys/sysctl.h>
54 #include <sys/kcore.h>
55 #include <sys/ksyms.h>
56 #include <sys/types.h>
58 #include <uvm/uvm_extern.h>
60 #include <machine/cpu.h>
75 #include "kvm_private.h"
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),
82 static off_t
Lseek(kvm_t
*, int, off_t
, int);
83 static ssize_t
Pread(kvm_t
*, int, void *, size_t, off_t
);
92 kvm_getkernelname(kvm_t
*kd
)
94 return kd
->kernelname
;
98 * Report an error using printf style arguments. "program" is kd->program
99 * on hard errors, and 0 on soft errors, so that under sun error emulation,
100 * only hard errors are printed out (otherwise, programs like gdb will
101 * generate tons of error messages when trying to access bogus pointers).
104 _kvm_err(kvm_t
*kd
, const char *program
, const char *fmt
, ...)
109 if (program
!= NULL
) {
110 (void)fprintf(stderr
, "%s: ", program
);
111 (void)vfprintf(stderr
, fmt
, ap
);
112 (void)fputc('\n', stderr
);
114 (void)vsnprintf(kd
->errbuf
,
115 sizeof(kd
->errbuf
), fmt
, ap
);
121 _kvm_syserr(kvm_t
*kd
, const char *program
, const char *fmt
, ...)
127 if (program
!= NULL
) {
128 (void)fprintf(stderr
, "%s: ", program
);
129 (void)vfprintf(stderr
, fmt
, ap
);
130 (void)fprintf(stderr
, ": %s\n", strerror(errno
));
132 char *cp
= kd
->errbuf
;
134 (void)vsnprintf(cp
, sizeof(kd
->errbuf
), fmt
, ap
);
136 (void)snprintf(&cp
[n
], sizeof(kd
->errbuf
) - n
, ": %s",
143 _kvm_malloc(kvm_t
*kd
, size_t n
)
147 if ((p
= malloc(n
)) == NULL
)
148 _kvm_err(kd
, kd
->program
, "%s", strerror(errno
));
153 * Wrapper around the lseek(2) system call; calls _kvm_syserr() for us
154 * in the event of emergency.
157 Lseek(kvm_t
*kd
, int fd
, off_t offset
, int whence
)
163 if ((off
= lseek(fd
, offset
, whence
)) == -1 && errno
!= 0) {
164 _kvm_syserr(kd
, kd
->program
, "Lseek");
171 _kvm_pread(kvm_t
*kd
, int fd
, void *buf
, size_t size
, off_t off
)
179 /* If aligned nothing to do. */
180 if (((off
% kd
->fdalign
) | (size
% kd
->fdalign
)) == 0) {
181 return pread(fd
, buf
, size
, off
);
185 * Otherwise must buffer. We can't tolerate short reads in this
188 moff
= (ptrdiff_t)off
% kd
->fdalign
;
190 dsize
= moff
+ size
+ kd
->fdalign
- 1;
191 dsize
-= dsize
% kd
->fdalign
;
192 if (kd
->iobufsz
< dsize
) {
193 newbuf
= realloc(kd
->iobuf
, dsize
);
194 if (newbuf
== NULL
) {
195 _kvm_syserr(kd
, 0, "cannot allocate I/O buffer");
201 rv
= pread(fd
, kd
->iobuf
, dsize
, doff
);
202 if (rv
< size
+ moff
)
204 memcpy(buf
, kd
->iobuf
+ moff
, size
);
209 * Wrapper around the pread(2) system call; calls _kvm_syserr() for us
210 * in the event of emergency.
213 Pread(kvm_t
*kd
, int fd
, void *buf
, size_t nbytes
, off_t offset
)
219 if ((rv
= _kvm_pread(kd
, fd
, buf
, nbytes
, offset
)) != nbytes
&&
221 _kvm_syserr(kd
, kd
->program
, "Pread");
226 _kvm_open(kvm_t
*kd
, const char *uf
, const char *mf
, const char *sf
, int flag
,
236 kd
->alive
= KVM_ALIVE_DEAD
;
238 kd
->procbase_len
= 0;
239 kd
->procbase2
= NULL
;
240 kd
->procbase2_len
= 0;
243 kd
->nbpg
= getpagesize();
250 kd
->vm_page_buckets
= NULL
;
251 kd
->kcore_hdr
= NULL
;
259 if (flag
& KVM_NO_FILES
) {
260 kd
->alive
= KVM_ALIVE_SYSCTL
;
265 * Call the MD open hook. This sets:
266 * usrstack, min_uva, max_uva
268 if (_kvm_mdopen(kd
)) {
269 _kvm_err(kd
, kd
->program
, "md init failed");
273 ufgiven
= (uf
!= NULL
);
275 #ifdef CPU_BOOTED_KERNEL
276 /* 130 is 128 + '/' + '\0' */
277 static char booted_kernel
[130];
281 mib
[0] = CTL_MACHDEP
;
282 mib
[1] = CPU_BOOTED_KERNEL
;
283 booted_kernel
[0] = '/';
284 booted_kernel
[1] = '\0';
285 len
= sizeof(booted_kernel
) - 2;
286 rc
= sysctl(&mib
[0], 2, &booted_kernel
[1], &len
, NULL
, 0);
287 booted_kernel
[sizeof(booted_kernel
) - 1] = '\0';
288 uf
= (booted_kernel
[1] == '/') ?
289 &booted_kernel
[1] : &booted_kernel
[0];
292 if (rc
!= -1 && !S_ISREG(st
.st_mode
))
295 #endif /* CPU_BOOTED_KERNEL */
298 else if (strlen(uf
) >= MAXPATHLEN
) {
299 _kvm_err(kd
, kd
->program
, "exec file name too long");
302 if (flag
& ~O_RDWR
) {
303 _kvm_err(kd
, kd
->program
, "bad flags arg");
312 * Open the kernel namelist. If /dev/ksyms doesn't
313 * exist, open the current kernel.
316 kd
->nlfd
= open(_PATH_KSYMS
, O_RDONLY
| O_CLOEXEC
, 0);
318 if ((kd
->nlfd
= open(uf
, O_RDONLY
| O_CLOEXEC
, 0)) < 0) {
319 _kvm_syserr(kd
, kd
->program
, "%s", uf
);
322 strlcpy(kd
->kernelname
, uf
, sizeof(kd
->kernelname
));
324 strlcpy(kd
->kernelname
, _PATH_KSYMS
, sizeof(kd
->kernelname
));
326 * We're here because /dev/ksyms was opened
327 * successfully. However, we don't want to keep it
328 * open, so we close it now. Later, we will open
329 * it again, since it will be the only case where
330 * kd->nlfd is negative.
336 if ((kd
->pmfd
= open(mf
, flag
| O_CLOEXEC
, 0)) < 0) {
337 _kvm_syserr(kd
, kd
->program
, "%s", mf
);
340 if (fstat(kd
->pmfd
, &st
) < 0) {
341 _kvm_syserr(kd
, kd
->program
, "%s", mf
);
344 if (S_ISCHR(st
.st_mode
) && strcmp(mf
, _PATH_MEM
) == 0) {
346 * If this is /dev/mem, open kmem too. (Maybe we should
347 * make it work for either /dev/mem or /dev/kmem -- in either
348 * case you're working with a live kernel.)
350 if ((kd
->vmfd
= open(_PATH_KMEM
, flag
| O_CLOEXEC
, 0)) < 0) {
351 _kvm_syserr(kd
, kd
->program
, "%s", _PATH_KMEM
);
354 kd
->alive
= KVM_ALIVE_FILES
;
355 if ((kd
->swfd
= open(sf
, flag
| O_CLOEXEC
, 0)) < 0) {
356 if (errno
!= ENXIO
) {
357 _kvm_syserr(kd
, kd
->program
, "%s", sf
);
360 /* swap is not configured? not fatal */
363 kd
->fdalign
= DEV_BSIZE
; /* XXX */
365 * This is a crash dump.
366 * Initialize the virtual address translation machinery.
368 * If there is no valid core header, fail silently here.
369 * The address translations however will fail without
370 * header. Things can be made to run by calling
371 * kvm_dump_mkheader() before doing any translation.
373 if (_kvm_get_header(kd
) == 0) {
374 if (_kvm_initvtop(kd
) < 0)
381 * Copy out the error if doing sane error semantics.
384 (void)strlcpy(errout
, kd
->errbuf
, _POSIX2_LINE_MAX
);
390 * The kernel dump file (from savecore) contains:
391 * kcore_hdr_t kcore_hdr;
392 * kcore_seg_t cpu_hdr;
393 * (opaque) cpu_data; (size is cpu_hdr.c_size)
394 * kcore_seg_t mem_hdr;
395 * (memory) mem_data; (size is mem_hdr.c_size)
397 * Note: khdr is padded to khdr.c_hdrsize;
398 * cpu_hdr and mem_hdr are padded to khdr.c_seghdrsize
401 _kvm_get_header(kvm_t
*kd
)
403 kcore_hdr_t kcore_hdr
;
410 * Read the kcore_hdr_t
412 sz
= Pread(kd
, kd
->pmfd
, &kcore_hdr
, sizeof(kcore_hdr
), (off_t
)0);
413 if (sz
!= sizeof(kcore_hdr
))
417 * Currently, we only support dump-files made by the current
420 if ((CORE_GETMAGIC(kcore_hdr
) != KCORE_MAGIC
) ||
421 (CORE_GETMID(kcore_hdr
) != MID_MACHINE
))
425 * Currently, we only support exactly 2 segments: cpu-segment
426 * and data-segment in exactly that order.
428 if (kcore_hdr
.c_nseg
!= 2)
432 * Save away the kcore_hdr. All errors after this
433 * should do a to "goto fail" to deallocate things.
435 kd
->kcore_hdr
= _kvm_malloc(kd
, sizeof(kcore_hdr
));
436 memcpy(kd
->kcore_hdr
, &kcore_hdr
, sizeof(kcore_hdr
));
437 offset
= kcore_hdr
.c_hdrsize
;
440 * Read the CPU segment header
442 sz
= Pread(kd
, kd
->pmfd
, &cpu_hdr
, sizeof(cpu_hdr
), (off_t
)offset
);
443 if (sz
!= sizeof(cpu_hdr
))
445 if ((CORE_GETMAGIC(cpu_hdr
) != KCORESEG_MAGIC
) ||
446 (CORE_GETFLAG(cpu_hdr
) != CORE_CPU
))
448 offset
+= kcore_hdr
.c_seghdrsize
;
451 * Read the CPU segment DATA.
453 kd
->cpu_dsize
= cpu_hdr
.c_size
;
454 kd
->cpu_data
= _kvm_malloc(kd
, cpu_hdr
.c_size
);
455 if (kd
->cpu_data
== NULL
)
457 sz
= Pread(kd
, kd
->pmfd
, kd
->cpu_data
, cpu_hdr
.c_size
, (off_t
)offset
);
458 if (sz
!= cpu_hdr
.c_size
)
460 offset
+= cpu_hdr
.c_size
;
463 * Read the next segment header: data segment
465 sz
= Pread(kd
, kd
->pmfd
, &mem_hdr
, sizeof(mem_hdr
), (off_t
)offset
);
466 if (sz
!= sizeof(mem_hdr
))
468 offset
+= kcore_hdr
.c_seghdrsize
;
470 if ((CORE_GETMAGIC(mem_hdr
) != KCORESEG_MAGIC
) ||
471 (CORE_GETFLAG(mem_hdr
) != CORE_DATA
))
474 kd
->dump_off
= offset
;
478 if (kd
->kcore_hdr
!= NULL
) {
480 kd
->kcore_hdr
= NULL
;
482 if (kd
->cpu_data
!= NULL
) {
491 * The format while on the dump device is: (new format)
492 * kcore_seg_t cpu_hdr;
493 * (opaque) cpu_data; (size is cpu_hdr.c_size)
494 * kcore_seg_t mem_hdr;
495 * (memory) mem_data; (size is mem_hdr.c_size)
498 kvm_dump_mkheader(kvm_t
*kd
, off_t dump_off
)
504 if (kd
->kcore_hdr
!= NULL
) {
505 _kvm_err(kd
, kd
->program
, "already has a dump header");
509 _kvm_err(kd
, kd
->program
, "don't use on live kernel");
514 * Validate new format crash dump
516 sz
= Pread(kd
, kd
->pmfd
, &cpu_hdr
, sizeof(cpu_hdr
), dump_off
);
517 if (sz
!= sizeof(cpu_hdr
)) {
518 _kvm_err(kd
, 0, "read %zx bytes at offset %"PRIx64
519 " for cpu_hdr instead of requested %zu",
520 sz
, dump_off
, sizeof(cpu_hdr
));
523 if ((CORE_GETMAGIC(cpu_hdr
) != KCORE_MAGIC
)
524 || (CORE_GETMID(cpu_hdr
) != MID_MACHINE
)) {
525 _kvm_err(kd
, 0, "invalid magic in cpu_hdr");
528 hdr_size
= ALIGN(sizeof(cpu_hdr
));
531 * Read the CPU segment.
533 kd
->cpu_dsize
= cpu_hdr
.c_size
;
534 kd
->cpu_data
= _kvm_malloc(kd
, kd
->cpu_dsize
);
535 if (kd
->cpu_data
== NULL
) {
536 _kvm_err(kd
, kd
->program
, "no cpu_data");
539 sz
= Pread(kd
, kd
->pmfd
, kd
->cpu_data
, cpu_hdr
.c_size
,
540 dump_off
+ hdr_size
);
541 if (sz
!= cpu_hdr
.c_size
) {
542 _kvm_err(kd
, kd
->program
, "size %zu != cpu_hdr.csize %"PRIu32
,
546 hdr_size
+= kd
->cpu_dsize
;
549 * Leave phys mem pointer at beginning of memory data
551 kd
->dump_off
= dump_off
+ hdr_size
;
552 if (Lseek(kd
, kd
->pmfd
, kd
->dump_off
, SEEK_SET
) == -1) {
553 _kvm_err(kd
, kd
->program
, "failed to seek to %" PRId64
,
554 (int64_t)kd
->dump_off
);
559 * Create a kcore_hdr.
561 kd
->kcore_hdr
= _kvm_malloc(kd
, sizeof(kcore_hdr_t
));
562 if (kd
->kcore_hdr
== NULL
) {
563 _kvm_err(kd
, kd
->program
, "failed to allocate header");
567 kd
->kcore_hdr
->c_hdrsize
= ALIGN(sizeof(kcore_hdr_t
));
568 kd
->kcore_hdr
->c_seghdrsize
= ALIGN(sizeof(kcore_seg_t
));
569 kd
->kcore_hdr
->c_nseg
= 2;
570 CORE_SETMAGIC(*(kd
->kcore_hdr
), KCORE_MAGIC
, MID_MACHINE
,0);
573 * Now that we have a valid header, enable translations.
575 if (_kvm_initvtop(kd
) == 0)
580 if (kd
->kcore_hdr
!= NULL
) {
582 kd
->kcore_hdr
= NULL
;
584 if (kd
->cpu_data
!= NULL
) {
593 clear_gap(kvm_t
*kd
, bool (*write_buf
)(void *, const void *, size_t),
594 void *cookie
, size_t size
)
599 (void)memset(buf
, 0, size
> sizeof(buf
) ? sizeof(buf
) : size
);
602 len
= size
> sizeof(buf
) ? sizeof(buf
) : size
;
603 if (!(*write_buf
)(cookie
, buf
, len
)) {
604 _kvm_syserr(kd
, kd
->program
, "clear_gap");
614 * Write the dump header by calling write_buf with cookie as first argument.
617 kvm_dump_header(kvm_t
*kd
, bool (*write_buf
)(void *, const void *, size_t),
618 void *cookie
, int dumpsize
)
624 if (kd
->kcore_hdr
== NULL
|| kd
->cpu_data
== NULL
) {
625 _kvm_err(kd
, kd
->program
, "no valid dump header(s)");
630 * Write the generic header
633 if (!(*write_buf
)(cookie
, kd
->kcore_hdr
, sizeof(kcore_hdr_t
))) {
634 _kvm_syserr(kd
, kd
->program
, "kvm_dump_header");
637 offset
+= kd
->kcore_hdr
->c_hdrsize
;
638 gap
= kd
->kcore_hdr
->c_hdrsize
- sizeof(kcore_hdr_t
);
639 if (clear_gap(kd
, write_buf
, cookie
, gap
) == -1)
643 * Write the CPU header
645 CORE_SETMAGIC(seghdr
, KCORESEG_MAGIC
, 0, CORE_CPU
);
646 seghdr
.c_size
= ALIGN(kd
->cpu_dsize
);
647 if (!(*write_buf
)(cookie
, &seghdr
, sizeof(seghdr
))) {
648 _kvm_syserr(kd
, kd
->program
, "kvm_dump_header");
651 offset
+= kd
->kcore_hdr
->c_seghdrsize
;
652 gap
= kd
->kcore_hdr
->c_seghdrsize
- sizeof(seghdr
);
653 if (clear_gap(kd
, write_buf
, cookie
, gap
) == -1)
656 if (!(*write_buf
)(cookie
, kd
->cpu_data
, kd
->cpu_dsize
)) {
657 _kvm_syserr(kd
, kd
->program
, "kvm_dump_header");
660 offset
+= seghdr
.c_size
;
661 gap
= seghdr
.c_size
- kd
->cpu_dsize
;
662 if (clear_gap(kd
, write_buf
, cookie
, gap
) == -1)
666 * Write the actual dump data segment header
668 CORE_SETMAGIC(seghdr
, KCORESEG_MAGIC
, 0, CORE_DATA
);
669 seghdr
.c_size
= dumpsize
;
670 if (!(*write_buf
)(cookie
, &seghdr
, sizeof(seghdr
))) {
671 _kvm_syserr(kd
, kd
->program
, "kvm_dump_header");
674 offset
+= kd
->kcore_hdr
->c_seghdrsize
;
675 gap
= kd
->kcore_hdr
->c_seghdrsize
- sizeof(seghdr
);
676 if (clear_gap(kd
, write_buf
, cookie
, gap
) == -1)
683 kvm_dump_header_stdio(void *cookie
, const void *buf
, size_t len
)
685 return fwrite(buf
, len
, 1, (FILE *)cookie
) == 1;
689 kvm_dump_wrtheader(kvm_t
*kd
, FILE *fp
, int dumpsize
)
691 return kvm_dump_header(kd
, kvm_dump_header_stdio
, fp
, dumpsize
);
695 kvm_openfiles(const char *uf
, const char *mf
, const char *sf
,
696 int flag
, char *errout
)
700 if ((kd
= malloc(sizeof(*kd
))) == NULL
) {
701 (void)strlcpy(errout
, strerror(errno
), _POSIX2_LINE_MAX
);
705 return (_kvm_open(kd
, uf
, mf
, sf
, flag
, errout
));
709 kvm_open(const char *uf
, const char *mf
, const char *sf
, int flag
,
714 if ((kd
= malloc(sizeof(*kd
))) == NULL
) {
715 (void)fprintf(stderr
, "%s: %s\n",
716 program
? program
: getprogname(), strerror(errno
));
719 kd
->program
= program
;
720 return (_kvm_open(kd
, uf
, mf
, sf
, flag
, NULL
));
729 error
|= close(kd
->pmfd
);
731 error
|= close(kd
->vmfd
);
733 error
|= close(kd
->nlfd
);
735 error
|= close(kd
->swfd
);
739 if (kd
->cpu_data
!= NULL
)
741 if (kd
->kcore_hdr
!= NULL
)
743 if (kd
->procbase
!= 0)
745 if (kd
->procbase2
!= 0)
747 if (kd
->lwpbase
!= 0)
749 if (kd
->swapspc
!= 0)
765 kvm_nlist(kvm_t
*kd
, struct nlist
*nl
)
770 * kd->nlfd might be negative when we get here, and in that
771 * case that means that we're using /dev/ksyms.
772 * So open it again, just for the time we retrieve the list.
775 nlfd
= open(_PATH_KSYMS
, O_RDONLY
| O_CLOEXEC
, 0);
777 _kvm_err(kd
, 0, "failed to open %s", _PATH_KSYMS
);
784 * Call the nlist(3) routines to retrieve the given namelist.
786 rv
= __fdnlist(nlfd
, nl
);
789 _kvm_err(kd
, 0, "bad namelist");
798 kvm_dump_inval(kvm_t
*kd
)
807 _kvm_err(kd
, kd
->program
, "clearing dump on live kernel");
810 nl
[0].n_name
= "_dumpmag";
813 if (kvm_nlist(kd
, nl
) == -1) {
814 _kvm_err(kd
, 0, "bad namelist");
817 if (_kvm_kvatop(kd
, (vaddr_t
)nl
[0].n_value
, &pa
) == 0)
821 dsize
= MAX(kd
->fdalign
, sizeof(u_long
));
822 if (kd
->iobufsz
< dsize
) {
823 newbuf
= realloc(kd
->iobuf
, dsize
);
824 if (newbuf
== NULL
) {
825 _kvm_syserr(kd
, 0, "cannot allocate I/O buffer");
831 memset(kd
->iobuf
, 0, dsize
);
832 doff
= _kvm_pa2off(kd
, pa
);
833 doff
-= doff
% kd
->fdalign
;
834 if (pwrite(kd
->pmfd
, kd
->iobuf
, dsize
, doff
) == -1) {
835 _kvm_syserr(kd
, 0, "cannot invalidate dump - pwrite");
842 kvm_read(kvm_t
*kd
, u_long kva
, void *buf
, size_t len
)
849 * We're using /dev/kmem. Just read straight from the
850 * device and let the active kernel do the address translation.
853 cc
= _kvm_pread(kd
, kd
->vmfd
, buf
, len
, (off_t
)kva
);
855 _kvm_syserr(kd
, 0, "kvm_read");
858 _kvm_err(kd
, kd
->program
, "short read");
860 } else if (ISSYSCTL(kd
)) {
861 _kvm_err(kd
, kd
->program
, "kvm_open called with KVM_NO_FILES, "
862 "can't use kvm_read");
865 if ((kd
->kcore_hdr
== NULL
) || (kd
->cpu_data
== NULL
)) {
866 _kvm_err(kd
, kd
->program
, "no valid dump header");
874 cc
= _kvm_kvatop(kd
, (vaddr_t
)kva
, &pa
);
879 foff
= _kvm_pa2off(kd
, pa
);
881 cc
= _kvm_pread(kd
, kd
->pmfd
, cp
, (size_t)cc
, foff
);
883 _kvm_syserr(kd
, kd
->program
, "kvm_read");
887 * If kvm_kvatop returns a bogus value or our core
888 * file is truncated, we might wind up seeking beyond
889 * the end of the core file in which case the read will
894 cp
= (char *)cp
+ cc
;
898 return ((char *)cp
- (char *)buf
);
904 kvm_write(kvm_t
*kd
, u_long kva
, const void *buf
, size_t len
)
910 * Just like kvm_read, only we write.
913 cc
= pwrite(kd
->vmfd
, buf
, len
, (off_t
)kva
);
915 _kvm_syserr(kd
, 0, "kvm_write");
918 _kvm_err(kd
, kd
->program
, "short write");
920 } else if (ISSYSCTL(kd
)) {
921 _kvm_err(kd
, kd
->program
, "kvm_open called with KVM_NO_FILES, "
922 "can't use kvm_write");
925 _kvm_err(kd
, kd
->program
,
926 "kvm_write not implemented for dead kernels");