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