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