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