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