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