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