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