1 /* $OpenBSD: kvm.c,v 1.23 2001/06/27 09:11:51 deraadt Exp $ */ 2 /* $NetBSD: kvm.c,v 1.43 1996/05/05 04:31:59 gwr Exp $ */ 3 4 /*- 5 * Copyright (c) 1989, 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software developed by the Computer Systems 9 * Engineering group at Lawrence Berkeley Laboratory under DARPA contract 10 * BG 91-66 and contributed to Berkeley. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 */ 40 41 #if defined(LIBC_SCCS) && !defined(lint) 42 #if 0 43 static char sccsid[] = "@(#)kvm.c 8.2 (Berkeley) 2/13/94"; 44 #else 45 static char *rcsid = "$OpenBSD: kvm.c,v 1.23 2001/06/27 09:11:51 deraadt Exp $"; 46 #endif 47 #endif /* LIBC_SCCS and not lint */ 48 49 #include <sys/param.h> 50 #include <sys/user.h> 51 #include <sys/proc.h> 52 #include <sys/ioctl.h> 53 #include <sys/stat.h> 54 #include <sys/sysctl.h> 55 56 #include <sys/core.h> 57 #include <sys/exec_aout.h> 58 #include <sys/kcore.h> 59 60 #include <vm/vm.h> 61 #include <vm/vm_param.h> 62 63 #include <ctype.h> 64 #include <db.h> 65 #include <fcntl.h> 66 #include <libgen.h> 67 #include <limits.h> 68 #include <nlist.h> 69 #include <paths.h> 70 #include <stdio.h> 71 #include <stdlib.h> 72 #include <string.h> 73 #include <unistd.h> 74 #include <kvm.h> 75 76 #include "kvm_private.h" 77 78 static int kvm_dbopen __P((kvm_t *, const char *)); 79 static int _kvm_get_header __P((kvm_t *)); 80 static kvm_t *_kvm_open __P((kvm_t *, const char *, const char *, 81 const char *, int, char *)); 82 static int clear_gap __P((kvm_t *, FILE *, int)); 83 84 char * 85 kvm_geterr(kd) 86 kvm_t *kd; 87 { 88 return (kd->errbuf); 89 } 90 91 #ifdef __STDC__ 92 #include <stdarg.h> 93 #else 94 #include <varargs.h> 95 #endif 96 97 /* 98 * Wrapper around pread. 99 */ 100 ssize_t 101 #ifdef __STDC__ 102 _kvm_pread(kvm_t *kd, int fd, void *buf, size_t nbytes, off_t offset) 103 #else 104 _kvm_pread(kd, fd, buf, nbytes, offset) 105 kvm_t *kd; 106 int fd; 107 void *buf; 108 size_t nbytes; 109 off_t offset; 110 #endif 111 { 112 ssize_t rval; 113 114 errno = 0; 115 rval = pread(fd, buf, nbytes, offset); 116 if (rval == -1 || errno != 0) { 117 _kvm_syserr(kd, kd->program, "pread"); 118 } 119 return(rval); 120 } 121 122 /* 123 * Wrapper around pwrite. 124 */ 125 ssize_t 126 #ifdef __STDC__ 127 _kvm_pwrite(kvm_t *kd, int fd, void *buf, size_t nbytes, off_t offset) 128 #else 129 _kvm_pwrite(kd, fd, buf, nbytes, offset) 130 kvm_t *kd; 131 int fd; 132 void *buf; 133 size_t nbytes; 134 off_t offset; 135 #endif 136 { 137 ssize_t rval; 138 139 errno = 0; 140 rval = pwrite(fd, buf, nbytes, offset); 141 if (rval == -1 || errno != 0) { 142 _kvm_syserr(kd, kd->program, "pwrite"); 143 } 144 return(rval); 145 } 146 147 /* 148 * Report an error using printf style arguments. "program" is kd->program 149 * on hard errors, and 0 on soft errors, so that under sun error emulation, 150 * only hard errors are printed out (otherwise, programs like gdb will 151 * generate tons of error messages when trying to access bogus pointers). 152 */ 153 void 154 #ifdef __STDC__ 155 _kvm_err(kvm_t *kd, const char *program, const char *fmt, ...) 156 #else 157 _kvm_err(kd, program, fmt, va_alist) 158 kvm_t *kd; 159 char *program, *fmt; 160 va_dcl 161 #endif 162 { 163 va_list ap; 164 165 #ifdef __STDC__ 166 va_start(ap, fmt); 167 #else 168 va_start(ap); 169 #endif 170 if (program != NULL) { 171 (void)fprintf(stderr, "%s: ", program); 172 (void)vfprintf(stderr, fmt, ap); 173 (void)fputc('\n', stderr); 174 } else 175 (void)vsnprintf(kd->errbuf, 176 sizeof(kd->errbuf), (char *)fmt, ap); 177 178 va_end(ap); 179 } 180 181 void 182 #ifdef __STDC__ 183 _kvm_syserr(kvm_t *kd, const char *program, const char *fmt, ...) 184 #else 185 _kvm_syserr(kd, program, fmt, va_alist) 186 kvm_t *kd; 187 char *program, *fmt; 188 va_dcl 189 #endif 190 { 191 va_list ap; 192 register int n; 193 194 #ifdef __STDC__ 195 va_start(ap, fmt); 196 #else 197 va_start(ap); 198 #endif 199 if (program != NULL) { 200 (void)fprintf(stderr, "%s: ", program); 201 (void)vfprintf(stderr, fmt, ap); 202 (void)fprintf(stderr, ": %s\n", strerror(errno)); 203 } else { 204 register char *cp = kd->errbuf; 205 206 (void)vsnprintf(cp, sizeof(kd->errbuf), (char *)fmt, ap); 207 n = strlen(cp); 208 (void)snprintf(&cp[n], sizeof(kd->errbuf) - n, ": %s", 209 strerror(errno)); 210 } 211 va_end(ap); 212 } 213 214 void * 215 _kvm_malloc(kd, n) 216 register kvm_t *kd; 217 register size_t n; 218 { 219 void *p; 220 221 if ((p = malloc(n)) == NULL) 222 _kvm_err(kd, kd->program, "%s", strerror(errno)); 223 return (p); 224 } 225 226 static kvm_t * 227 _kvm_open(kd, uf, mf, sf, flag, errout) 228 register kvm_t *kd; 229 const char *uf; 230 const char *mf; 231 const char *sf; 232 int flag; 233 char *errout; 234 { 235 struct stat st; 236 237 kd->db = 0; 238 kd->pmfd = -1; 239 kd->vmfd = -1; 240 kd->swfd = -1; 241 kd->nlfd = -1; 242 kd->procbase = 0; 243 kd->nbpg = getpagesize(); 244 kd->swapspc = 0; 245 kd->argspc = 0; 246 kd->argbuf = 0; 247 kd->argv = 0; 248 kd->vmst = 0; 249 kd->vm_page_buckets = 0; 250 kd->kcore_hdr = 0; 251 kd->cpu_dsize = 0; 252 kd->cpu_data = 0; 253 kd->dump_off = 0; 254 255 if (uf && strlen(uf) >= MAXPATHLEN) { 256 _kvm_err(kd, kd->program, "exec file name too long"); 257 goto failed; 258 } 259 if (flag & ~O_ACCMODE) { 260 _kvm_err(kd, kd->program, "bad flags arg"); 261 goto failed; 262 } 263 if (mf == 0) 264 mf = _PATH_MEM; 265 if (sf == 0) 266 sf = _PATH_DRUM; 267 268 if ((kd->pmfd = open(mf, flag, 0)) < 0) { 269 _kvm_syserr(kd, kd->program, "%s", mf); 270 goto failed; 271 } 272 if (fstat(kd->pmfd, &st) < 0) { 273 _kvm_syserr(kd, kd->program, "%s", mf); 274 goto failed; 275 } 276 if (S_ISCHR(st.st_mode)) { 277 /* 278 * If this is a character special device, then check that 279 * it's /dev/mem. If so, open kmem too. (Maybe we should 280 * make it work for either /dev/mem or /dev/kmem -- in either 281 * case you're working with a live kernel.) 282 */ 283 if (strcmp(mf, _PATH_MEM) != 0) { /* XXX */ 284 _kvm_err(kd, kd->program, 285 "%s: not physical memory device", mf); 286 goto failed; 287 } 288 if ((kd->vmfd = open(_PATH_KMEM, flag)) < 0) { 289 _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM); 290 goto failed; 291 } 292 if ((kd->swfd = open(sf, flag, 0)) < 0) { 293 _kvm_syserr(kd, kd->program, "%s", sf); 294 goto failed; 295 } 296 /* 297 * Open kvm nlist database. We only try to use 298 * the pre-built database if the namelist file name 299 * pointer is NULL. If the database cannot or should 300 * not be opened, open the namelist argument so we 301 * revert to slow nlist() calls. 302 * If no file is specified, try opening _PATH_KSYMS and 303 * fall back to _PATH_UNIX. 304 */ 305 if (kvm_dbopen(kd, uf ? uf : _PATH_UNIX) == -1 && 306 ((uf && (kd->nlfd = open(uf, O_RDONLY)) == -1) || (!uf && 307 (kd->nlfd = open((uf = _PATH_KSYMS), O_RDONLY)) == -1 && 308 (kd->nlfd = open((uf = _PATH_UNIX), O_RDONLY)) == -1))) { 309 _kvm_syserr(kd, kd->program, "%s", uf); 310 goto failed; 311 } 312 } else { 313 /* 314 * This is a crash dump. 315 * Initialize the virtual address translation machinery, 316 * but first setup the namelist fd. 317 * If no file is specified, try opening _PATH_KSYMS and 318 * fall back to _PATH_UNIX. 319 */ 320 if ((uf && (kd->nlfd = open(uf, O_RDONLY)) == -1) || (!uf && 321 (kd->nlfd = open((uf = _PATH_KSYMS), O_RDONLY)) == -1 && 322 (kd->nlfd = open((uf = _PATH_UNIX), O_RDONLY)) == -1)) { 323 _kvm_syserr(kd, kd->program, "%s", uf); 324 goto failed; 325 } 326 327 /* 328 * If there is no valid core header, fail silently here. 329 * The address translations however will fail without 330 * header. Things can be made to run by calling 331 * kvm_dump_mkheader() before doing any translation. 332 */ 333 if (_kvm_get_header(kd) == 0) { 334 if (_kvm_initvtop(kd) < 0) 335 goto failed; 336 } 337 } 338 return (kd); 339 failed: 340 /* 341 * Copy out the error if doing sane error semantics. 342 */ 343 if (errout != 0) 344 (void)strncpy(errout, kd->errbuf, _POSIX2_LINE_MAX - 1); 345 (void)kvm_close(kd); 346 return (0); 347 } 348 349 /* 350 * The kernel dump file (from savecore) contains: 351 * kcore_hdr_t kcore_hdr; 352 * kcore_seg_t cpu_hdr; 353 * (opaque) cpu_data; (size is cpu_hdr.c_size) 354 * kcore_seg_t mem_hdr; 355 * (memory) mem_data; (size is mem_hdr.c_size) 356 * 357 * Note: khdr is padded to khdr.c_hdrsize; 358 * cpu_hdr and mem_hdr are padded to khdr.c_seghdrsize 359 */ 360 static int 361 _kvm_get_header(kd) 362 kvm_t *kd; 363 { 364 kcore_hdr_t kcore_hdr; 365 kcore_seg_t cpu_hdr; 366 kcore_seg_t mem_hdr; 367 size_t offset; 368 ssize_t sz; 369 370 /* 371 * Read the kcore_hdr_t 372 */ 373 sz = _kvm_pread(kd, kd->pmfd, &kcore_hdr, sizeof(kcore_hdr), (off_t)0); 374 if (sz != sizeof(kcore_hdr)) { 375 return (-1); 376 } 377 378 /* 379 * Currently, we only support dump-files made by the current 380 * architecture... 381 */ 382 if ((CORE_GETMAGIC(kcore_hdr) != KCORE_MAGIC) || 383 (CORE_GETMID(kcore_hdr) != MID_MACHINE)) 384 return (-1); 385 386 /* 387 * Currently, we only support exactly 2 segments: cpu-segment 388 * and data-segment in exactly that order. 389 */ 390 if (kcore_hdr.c_nseg != 2) 391 return (-1); 392 393 /* 394 * Save away the kcore_hdr. All errors after this 395 * should do a to "goto fail" to deallocate things. 396 */ 397 kd->kcore_hdr = _kvm_malloc(kd, sizeof(kcore_hdr)); 398 if (kd->kcore_hdr == NULL) 399 goto fail; 400 memcpy(kd->kcore_hdr, &kcore_hdr, sizeof(kcore_hdr)); 401 offset = kcore_hdr.c_hdrsize; 402 403 /* 404 * Read the CPU segment header 405 */ 406 sz = _kvm_pread(kd, kd->pmfd, &cpu_hdr, sizeof(cpu_hdr), (off_t)offset); 407 if (sz != sizeof(cpu_hdr)) { 408 goto fail; 409 } 410 411 if ((CORE_GETMAGIC(cpu_hdr) != KCORESEG_MAGIC) || 412 (CORE_GETFLAG(cpu_hdr) != CORE_CPU)) 413 goto fail; 414 offset += kcore_hdr.c_seghdrsize; 415 416 /* 417 * Read the CPU segment DATA. 418 */ 419 kd->cpu_dsize = cpu_hdr.c_size; 420 kd->cpu_data = _kvm_malloc(kd, cpu_hdr.c_size); 421 if (kd->cpu_data == NULL) 422 goto fail; 423 424 sz = _kvm_pread(kd, kd->pmfd, kd->cpu_data, cpu_hdr.c_size, (off_t)offset); 425 if (sz != cpu_hdr.c_size) { 426 goto fail; 427 } 428 429 offset += cpu_hdr.c_size; 430 431 /* 432 * Read the next segment header: data segment 433 */ 434 sz = _kvm_pread(kd, kd->pmfd, &mem_hdr, sizeof(mem_hdr), (off_t)offset); 435 if (sz != sizeof(mem_hdr)) { 436 goto fail; 437 } 438 439 offset += kcore_hdr.c_seghdrsize; 440 441 if ((CORE_GETMAGIC(mem_hdr) != KCORESEG_MAGIC) || 442 (CORE_GETFLAG(mem_hdr) != CORE_DATA)) 443 goto fail; 444 445 kd->dump_off = offset; 446 return (0); 447 448 fail: 449 if (kd->kcore_hdr != NULL) { 450 free(kd->kcore_hdr); 451 kd->kcore_hdr = NULL; 452 } 453 if (kd->cpu_data != NULL) { 454 free(kd->cpu_data); 455 kd->cpu_data = NULL; 456 kd->cpu_dsize = 0; 457 } 458 459 return (-1); 460 } 461 462 /* 463 * The format while on the dump device is: (new format) 464 * kcore_seg_t cpu_hdr; 465 * (opaque) cpu_data; (size is cpu_hdr.c_size) 466 * kcore_seg_t mem_hdr; 467 * (memory) mem_data; (size is mem_hdr.c_size) 468 */ 469 int 470 kvm_dump_mkheader(kd, dump_off) 471 kvm_t *kd; 472 off_t dump_off; 473 { 474 kcore_seg_t cpu_hdr; 475 int hdr_size, sz; 476 477 if (kd->kcore_hdr != NULL) { 478 _kvm_err(kd, kd->program, "already has a dump header"); 479 return (-1); 480 } 481 if (ISALIVE(kd)) { 482 _kvm_err(kd, kd->program, "don't use on live kernel"); 483 return (-1); 484 } 485 486 /* 487 * Validate new format crash dump 488 */ 489 sz = _kvm_pread(kd, kd->pmfd, &cpu_hdr, sizeof(cpu_hdr), (off_t)dump_off); 490 if (sz != sizeof(cpu_hdr)) { 491 return (-1); 492 } 493 if ((CORE_GETMAGIC(cpu_hdr) != KCORE_MAGIC) 494 || (CORE_GETMID(cpu_hdr) != MID_MACHINE)) { 495 _kvm_err(kd, 0, "invalid magic in cpu_hdr"); 496 return (-1); 497 } 498 hdr_size = ALIGN(sizeof(cpu_hdr)); 499 500 /* 501 * Read the CPU segment. 502 */ 503 kd->cpu_dsize = cpu_hdr.c_size; 504 kd->cpu_data = _kvm_malloc(kd, kd->cpu_dsize); 505 if (kd->cpu_data == NULL) 506 goto fail; 507 508 sz = _kvm_pread(kd, kd->pmfd, kd->cpu_data, cpu_hdr.c_size, (off_t)dump_off+hdr_size); 509 if (sz != cpu_hdr.c_size) { 510 _kvm_err(kd, 0, "invalid size in cpu_hdr"); 511 goto fail; 512 } 513 hdr_size += kd->cpu_dsize; 514 515 /* 516 * Leave phys mem pointer at beginning of memory data 517 */ 518 kd->dump_off = dump_off + hdr_size; 519 errno = 0; 520 if (lseek(kd->pmfd, kd->dump_off, SEEK_SET) != kd->dump_off && errno != 0) { 521 _kvm_err(kd, 0, "invalid dump offset - lseek"); 522 goto fail; 523 } 524 525 /* 526 * Create a kcore_hdr. 527 */ 528 kd->kcore_hdr = _kvm_malloc(kd, sizeof(kcore_hdr_t)); 529 if (kd->kcore_hdr == NULL) 530 goto fail; 531 532 kd->kcore_hdr->c_hdrsize = ALIGN(sizeof(kcore_hdr_t)); 533 kd->kcore_hdr->c_seghdrsize = ALIGN(sizeof(kcore_seg_t)); 534 kd->kcore_hdr->c_nseg = 2; 535 CORE_SETMAGIC(*(kd->kcore_hdr), KCORE_MAGIC, MID_MACHINE,0); 536 537 /* 538 * Now that we have a valid header, enable translations. 539 */ 540 if (_kvm_initvtop(kd) == 0) 541 /* Success */ 542 return (hdr_size); 543 544 fail: 545 if (kd->kcore_hdr != NULL) { 546 free(kd->kcore_hdr); 547 kd->kcore_hdr = NULL; 548 } 549 if (kd->cpu_data != NULL) { 550 free(kd->cpu_data); 551 kd->cpu_data = NULL; 552 kd->cpu_dsize = 0; 553 } 554 return (-1); 555 } 556 557 static int 558 clear_gap(kd, fp, size) 559 kvm_t *kd; 560 FILE *fp; 561 int size; 562 { 563 if (size <= 0) /* XXX - < 0 should never happen */ 564 return (0); 565 while (size-- > 0) { 566 if (fputc(0, fp) == EOF) { 567 _kvm_syserr(kd, kd->program, "clear_gap"); 568 return (-1); 569 } 570 } 571 return (0); 572 } 573 574 /* 575 * Write the dump header info to 'fp'. Note that we can't use fseek(3) here 576 * because 'fp' might be a file pointer obtained by zopen(). 577 */ 578 int 579 kvm_dump_wrtheader(kd, fp, dumpsize) 580 kvm_t *kd; 581 FILE *fp; 582 int dumpsize; 583 { 584 kcore_seg_t seghdr; 585 long offset; 586 int gap; 587 588 if (kd->kcore_hdr == NULL || kd->cpu_data == NULL) { 589 _kvm_err(kd, kd->program, "no valid dump header(s)"); 590 return (-1); 591 } 592 593 /* 594 * Write the generic header 595 */ 596 offset = 0; 597 if (fwrite((void*)kd->kcore_hdr, sizeof(kcore_hdr_t), 1, fp) <= 0) { 598 _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader"); 599 return (-1); 600 } 601 offset += kd->kcore_hdr->c_hdrsize; 602 gap = kd->kcore_hdr->c_hdrsize - sizeof(kcore_hdr_t); 603 if (clear_gap(kd, fp, gap) == -1) 604 return (-1); 605 606 /* 607 * Write the cpu header 608 */ 609 CORE_SETMAGIC(seghdr, KCORESEG_MAGIC, 0, CORE_CPU); 610 seghdr.c_size = ALIGN(kd->cpu_dsize); 611 if (fwrite((void*)&seghdr, sizeof(seghdr), 1, fp) <= 0) { 612 _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader"); 613 return (-1); 614 } 615 offset += kd->kcore_hdr->c_seghdrsize; 616 gap = kd->kcore_hdr->c_seghdrsize - sizeof(seghdr); 617 if (clear_gap(kd, fp, gap) == -1) 618 return (-1); 619 620 if (fwrite((void*)kd->cpu_data, kd->cpu_dsize, 1, fp) <= 0) { 621 _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader"); 622 return (-1); 623 } 624 offset += seghdr.c_size; 625 gap = seghdr.c_size - kd->cpu_dsize; 626 if (clear_gap(kd, fp, gap) == -1) 627 return (-1); 628 629 /* 630 * Write the actual dump data segment header 631 */ 632 CORE_SETMAGIC(seghdr, KCORESEG_MAGIC, 0, CORE_DATA); 633 seghdr.c_size = dumpsize; 634 if (fwrite((void*)&seghdr, sizeof(seghdr), 1, fp) <= 0) { 635 _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader"); 636 return (-1); 637 } 638 offset += kd->kcore_hdr->c_seghdrsize; 639 gap = kd->kcore_hdr->c_seghdrsize - sizeof(seghdr); 640 if (clear_gap(kd, fp, gap) == -1) 641 return (-1); 642 643 return (offset); 644 } 645 646 kvm_t * 647 kvm_openfiles(uf, mf, sf, flag, errout) 648 const char *uf; 649 const char *mf; 650 const char *sf; 651 int flag; 652 char *errout; 653 { 654 register kvm_t *kd; 655 656 if ((kd = malloc(sizeof(*kd))) == NULL) { 657 (void)strncpy(errout, strerror(errno), _POSIX2_LINE_MAX - 1); 658 return (0); 659 } 660 kd->program = 0; 661 return (_kvm_open(kd, uf, mf, sf, flag, errout)); 662 } 663 664 kvm_t * 665 kvm_open(uf, mf, sf, flag, program) 666 const char *uf; 667 const char *mf; 668 const char *sf; 669 int flag; 670 const char *program; 671 { 672 register kvm_t *kd; 673 674 if ((kd = malloc(sizeof(*kd))) == NULL && program != NULL) { 675 (void)fprintf(stderr, "%s: %s\n", program, strerror(errno)); 676 return (0); 677 } 678 kd->program = program; 679 return (_kvm_open(kd, uf, mf, sf, flag, NULL)); 680 } 681 682 int 683 kvm_close(kd) 684 kvm_t *kd; 685 { 686 register int error = 0; 687 688 if (kd->pmfd >= 0) 689 error |= close(kd->pmfd); 690 if (kd->vmfd >= 0) 691 error |= close(kd->vmfd); 692 if (kd->nlfd >= 0) 693 error |= close(kd->nlfd); 694 if (kd->swfd >= 0) 695 error |= close(kd->swfd); 696 if (kd->db != 0) 697 error |= (kd->db->close)(kd->db); 698 if (kd->vmst) 699 _kvm_freevtop(kd); 700 kd->cpu_dsize = 0; 701 if (kd->cpu_data != NULL) 702 free((void *)kd->cpu_data); 703 if (kd->kcore_hdr != NULL) 704 free((void *)kd->kcore_hdr); 705 if (kd->procbase != 0) 706 free((void *)kd->procbase); 707 if (kd->swapspc != 0) 708 free((void *)kd->swapspc); 709 if (kd->argspc != 0) 710 free((void *)kd->argspc); 711 if (kd->argbuf != 0) 712 free((void *)kd->argbuf); 713 if (kd->argv != 0) 714 free((void *)kd->argv); 715 free((void *)kd); 716 717 return (error); 718 } 719 720 /* 721 * Set up state necessary to do queries on the kernel namelist 722 * data base. If the data base is out-of-data/incompatible with 723 * given executable, set up things so we revert to standard nlist call. 724 * Only called for live kernels. Return 0 on success, -1 on failure. 725 */ 726 static int 727 kvm_dbopen(kd, uf) 728 kvm_t *kd; 729 const char *uf; 730 { 731 DBT rec; 732 int dbversionlen; 733 struct nlist nitem; 734 char dbversion[_POSIX2_LINE_MAX]; 735 char kversion[_POSIX2_LINE_MAX]; 736 char dbname[MAXPATHLEN]; 737 738 uf = basename((char *)uf); 739 740 (void)snprintf(dbname, sizeof(dbname), "%skvm_%s.db", _PATH_VARDB, uf); 741 kd->db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL); 742 if (kd->db == NULL) { 743 switch (errno) { 744 case ENOENT: 745 /* No kvm_bsd.db, fall back to /bsd silently */ 746 break; 747 case EFTYPE: 748 _kvm_err(kd, kd->program, 749 "file %s is incorrectly formatted", dbname); 750 break; 751 case EINVAL: 752 _kvm_err(kd, kd->program, 753 "invalid argument to dbopen()"); 754 break; 755 default: 756 _kvm_err(kd, kd->program, "unknown dbopen() error"); 757 break; 758 } 759 return (-1); 760 } 761 762 /* 763 * read version out of database 764 */ 765 rec.data = VRS_KEY; 766 rec.size = sizeof(VRS_KEY) - 1; 767 if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0)) 768 goto close; 769 if (rec.data == 0 || rec.size > sizeof(dbversion)) 770 goto close; 771 772 bcopy(rec.data, dbversion, rec.size); 773 dbversionlen = rec.size; 774 /* 775 * Read version string from kernel memory. 776 * Since we are dealing with a live kernel, we can call kvm_read() 777 * at this point. 778 */ 779 rec.data = VRS_SYM; 780 rec.size = sizeof(VRS_SYM) - 1; 781 if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0)) 782 goto close; 783 if (rec.data == 0 || rec.size != sizeof(struct nlist)) 784 goto close; 785 bcopy((char *)rec.data, (char *)&nitem, sizeof(nitem)); 786 if (kvm_read(kd, (u_long)nitem.n_value, kversion, dbversionlen) != 787 dbversionlen) 788 goto close; 789 /* 790 * If they match, we win - otherwise clear out kd->db so 791 * we revert to slow nlist(). 792 */ 793 if (bcmp(dbversion, kversion, dbversionlen) == 0) 794 return (0); 795 close: 796 (void)(kd->db->close)(kd->db); 797 kd->db = 0; 798 799 return (-1); 800 } 801 802 int 803 kvm_nlist(kd, nl) 804 kvm_t *kd; 805 struct nlist *nl; 806 { 807 register struct nlist *p; 808 register int nvalid, rv; 809 810 /* 811 * If we can't use the data base, revert to the 812 * slow library call. 813 */ 814 if (kd->db == 0) { 815 rv = __fdnlist(kd->nlfd, nl); 816 if (rv == -1) 817 _kvm_err(kd, 0, "bad namelist"); 818 return (rv); 819 } 820 821 /* 822 * We can use the kvm data base. Go through each nlist entry 823 * and look it up with a db query. 824 */ 825 nvalid = 0; 826 for (p = nl; p->n_name && p->n_name[0]; ++p) { 827 register int len; 828 DBT rec; 829 830 if ((len = strlen(p->n_name)) > 4096) { 831 /* sanity */ 832 _kvm_err(kd, kd->program, "symbol too large"); 833 return (-1); 834 } 835 rec.data = p->n_name; 836 rec.size = len; 837 838 /* 839 * Make sure that n_value = 0 when the symbol isn't found 840 */ 841 p->n_value = 0; 842 843 if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0)) 844 continue; 845 if (rec.data == 0 || rec.size != sizeof(struct nlist)) 846 continue; 847 ++nvalid; 848 /* 849 * Avoid alignment issues. 850 */ 851 bcopy((char *)&((struct nlist *)rec.data)->n_type, 852 (char *)&p->n_type, 853 sizeof(p->n_type)); 854 bcopy((char *)&((struct nlist *)rec.data)->n_value, 855 (char *)&p->n_value, 856 sizeof(p->n_value)); 857 } 858 /* 859 * Return the number of entries that weren't found. 860 */ 861 return ((p - nl) - nvalid); 862 } 863 864 int kvm_dump_inval(kd) 865 kvm_t *kd; 866 { 867 struct nlist nlist[2]; 868 u_long pa; 869 870 if (ISALIVE(kd)) { 871 _kvm_err(kd, kd->program, "clearing dump on live kernel"); 872 return (-1); 873 } 874 nlist[0].n_name = "_dumpmag"; 875 nlist[1].n_name = NULL; 876 877 if (kvm_nlist(kd, nlist) == -1) { 878 _kvm_err(kd, 0, "bad namelist"); 879 return (-1); 880 } 881 if (_kvm_kvatop(kd, (u_long)nlist[0].n_value, &pa) == 0) 882 return (-1); 883 884 pa = 0; 885 if (_kvm_pwrite(kd, kd->pmfd, &pa, sizeof(pa), (off_t)_kvm_pa2off(kd, pa)) != sizeof(pa)) { 886 _kvm_err(kd, 0, "cannot invalidate dump"); 887 return (-1); 888 } 889 return (0); 890 } 891 892 ssize_t 893 kvm_read(kd, kva, buf, len) 894 kvm_t *kd; 895 register u_long kva; 896 register void *buf; 897 register size_t len; 898 { 899 register int cc; 900 register void *cp; 901 902 if (ISALIVE(kd)) { 903 /* 904 * We're using /dev/kmem. Just read straight from the 905 * device and let the active kernel do the address translation. 906 */ 907 cc = _kvm_pread(kd, kd->vmfd, buf, len, (off_t)kva); 908 if (cc < 0) { 909 _kvm_err(kd, 0, "invalid address (%lx)", kva); 910 return (-1); 911 } else if (cc < len) 912 _kvm_err(kd, kd->program, "short read"); 913 return (cc); 914 } else { 915 if ((kd->kcore_hdr == NULL) || (kd->cpu_data == NULL)) { 916 _kvm_err(kd, kd->program, "no valid dump header"); 917 return (-1); 918 } 919 cp = buf; 920 while (len > 0) { 921 u_long pa; 922 923 /* In case of error, _kvm_kvatop sets the err string */ 924 cc = _kvm_kvatop(kd, kva, &pa); 925 if (cc == 0) 926 return (-1); 927 if (cc > len) 928 cc = len; 929 cc = _kvm_pread(kd, kd->pmfd, cp, cc, (off_t)_kvm_pa2off(kd, pa)); 930 if (cc < 0) { 931 _kvm_syserr(kd, 0, _PATH_MEM); 932 break; 933 } 934 /* 935 * If kvm_kvatop returns a bogus value or our core 936 * file is truncated, we might wind up seeking beyond 937 * the end of the core file in which case the read will 938 * return 0 (EOF). 939 */ 940 if (cc == 0) 941 break; 942 cp = (char *)cp + cc; 943 kva += cc; 944 len -= cc; 945 } 946 return ((char *)cp - (char *)buf); 947 } 948 /* NOTREACHED */ 949 } 950 951 ssize_t 952 kvm_write(kd, kva, buf, len) 953 kvm_t *kd; 954 register u_long kva; 955 register const void *buf; 956 register size_t len; 957 { 958 register int cc; 959 960 if (ISALIVE(kd)) { 961 /* 962 * Just like kvm_read, only we write. 963 */ 964 cc = _kvm_pwrite(kd, kd->vmfd, (void*)buf, (size_t)len, (off_t)kva); 965 if (cc < 0) { 966 _kvm_err(kd, 0, "invalid address (%lx)", kva); 967 return (-1); 968 } else if (cc < len) 969 _kvm_err(kd, kd->program, "short write"); 970 return (cc); 971 } else { 972 _kvm_err(kd, kd->program, 973 "kvm_write not implemented for dead kernels"); 974 return (-1); 975 } 976 /* NOTREACHED */ 977 } 978