1 /* $NetBSD: kvm.c,v 1.97 2010/11/26 22:01:53 dholland 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.97 2010/11/26 22:01:53 dholland 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 < size + moff) 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 (error); 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