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