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