1 /* $OpenBSD: kvm.c,v 1.37 2004/02/23 23:19:09 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. 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.37 2004/02/23 23:19:09 deraadt 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->procbase2 = 0; 194 kd->nbpg = getpagesize(); 195 kd->swapspc = 0; 196 kd->argspc = 0; 197 kd->argbuf = 0; 198 kd->argv = 0; 199 kd->vmst = 0; 200 kd->vm_page_buckets = 0; 201 kd->kcore_hdr = 0; 202 kd->cpu_dsize = 0; 203 kd->cpu_data = 0; 204 kd->dump_off = 0; 205 206 if (flag & KVM_NO_FILES) { 207 kd->alive = 1; 208 return (kd); 209 } 210 211 if (uf && strlen(uf) >= MAXPATHLEN) { 212 _kvm_err(kd, kd->program, "exec file name too long"); 213 goto failed; 214 } 215 if (flag & ~O_ACCMODE) { 216 _kvm_err(kd, kd->program, "bad flags arg"); 217 goto failed; 218 } 219 if (mf == 0) 220 mf = _PATH_MEM; 221 if (sf == 0) 222 sf = _PATH_DRUM; 223 224 if ((kd->pmfd = open(mf, flag, 0)) < 0) { 225 _kvm_syserr(kd, kd->program, "%s", mf); 226 goto failed; 227 } 228 if (fstat(kd->pmfd, &st) < 0) { 229 _kvm_syserr(kd, kd->program, "%s", mf); 230 goto failed; 231 } 232 if (S_ISCHR(st.st_mode)) { 233 /* 234 * If this is a character special device, then check that 235 * it's /dev/mem. If so, open kmem too. (Maybe we should 236 * make it work for either /dev/mem or /dev/kmem -- in either 237 * case you're working with a live kernel.) 238 */ 239 if (strcmp(mf, _PATH_MEM) != 0) { /* XXX */ 240 _kvm_err(kd, kd->program, 241 "%s: not physical memory device", mf); 242 goto failed; 243 } 244 if ((kd->vmfd = open(_PATH_KMEM, flag, 0)) < 0) { 245 _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM); 246 goto failed; 247 } 248 kd->alive = 1; 249 if ((kd->swfd = open(sf, flag, 0)) < 0) { 250 _kvm_syserr(kd, kd->program, "%s", sf); 251 goto failed; 252 } 253 /* 254 * Open kvm nlist database. We only try to use 255 * the pre-built database if the namelist file name 256 * pointer is NULL. If the database cannot or should 257 * not be opened, open the namelist argument so we 258 * revert to slow nlist() calls. 259 * If no file is specified, try opening _PATH_KSYMS and 260 * fall back to _PATH_UNIX. 261 */ 262 if (kvm_dbopen(kd, uf ? uf : _PATH_UNIX) == -1 && 263 ((uf && (kd->nlfd = open(uf, O_RDONLY, 0)) == -1) || (!uf && 264 (kd->nlfd = open((uf = _PATH_KSYMS), O_RDONLY, 0)) == -1 && 265 (kd->nlfd = open((uf = _PATH_UNIX), O_RDONLY, 0)) == -1))) { 266 _kvm_syserr(kd, kd->program, "%s", uf); 267 goto failed; 268 } 269 } else { 270 /* 271 * This is a crash dump. 272 * Initialize the virtual address translation machinery, 273 * but first setup the namelist fd. 274 * If no file is specified, try opening _PATH_KSYMS and 275 * fall back to _PATH_UNIX. 276 */ 277 if ((uf && (kd->nlfd = open(uf, O_RDONLY, 0)) == -1) || (!uf && 278 (kd->nlfd = open((uf = _PATH_KSYMS), O_RDONLY, 0)) == -1 && 279 (kd->nlfd = open((uf = _PATH_UNIX), O_RDONLY, 0)) == -1)) { 280 _kvm_syserr(kd, kd->program, "%s", uf); 281 goto failed; 282 } 283 284 /* 285 * If there is no valid core header, fail silently here. 286 * The address translations however will fail without 287 * header. Things can be made to run by calling 288 * kvm_dump_mkheader() before doing any translation. 289 */ 290 if (_kvm_get_header(kd) == 0) { 291 if (_kvm_initvtop(kd) < 0) 292 goto failed; 293 } 294 } 295 if (kvm_setfd(kd) == 0) 296 return (kd); 297 else 298 _kvm_syserr(kd, kd->program, "can't set close on exec flag"); 299 failed: 300 /* 301 * Copy out the error if doing sane error semantics. 302 */ 303 if (errout != 0) 304 (void)strlcpy(errout, kd->errbuf, _POSIX2_LINE_MAX); 305 (void)kvm_close(kd); 306 return (0); 307 } 308 309 /* 310 * The kernel dump file (from savecore) contains: 311 * kcore_hdr_t kcore_hdr; 312 * kcore_seg_t cpu_hdr; 313 * (opaque) cpu_data; (size is cpu_hdr.c_size) 314 * kcore_seg_t mem_hdr; 315 * (memory) mem_data; (size is mem_hdr.c_size) 316 * 317 * Note: khdr is padded to khdr.c_hdrsize; 318 * cpu_hdr and mem_hdr are padded to khdr.c_seghdrsize 319 */ 320 static int 321 _kvm_get_header(kd) 322 kvm_t *kd; 323 { 324 kcore_hdr_t kcore_hdr; 325 kcore_seg_t cpu_hdr; 326 kcore_seg_t mem_hdr; 327 size_t offset; 328 ssize_t sz; 329 330 /* 331 * Read the kcore_hdr_t 332 */ 333 sz = _kvm_pread(kd, kd->pmfd, &kcore_hdr, sizeof(kcore_hdr), (off_t)0); 334 if (sz != sizeof(kcore_hdr)) { 335 return (-1); 336 } 337 338 /* 339 * Currently, we only support dump-files made by the current 340 * architecture... 341 */ 342 if ((CORE_GETMAGIC(kcore_hdr) != KCORE_MAGIC) || 343 (CORE_GETMID(kcore_hdr) != MID_MACHINE)) 344 return (-1); 345 346 /* 347 * Currently, we only support exactly 2 segments: cpu-segment 348 * and data-segment in exactly that order. 349 */ 350 if (kcore_hdr.c_nseg != 2) 351 return (-1); 352 353 /* 354 * Save away the kcore_hdr. All errors after this 355 * should do a to "goto fail" to deallocate things. 356 */ 357 kd->kcore_hdr = _kvm_malloc(kd, sizeof(kcore_hdr)); 358 if (kd->kcore_hdr == NULL) 359 goto fail; 360 memcpy(kd->kcore_hdr, &kcore_hdr, sizeof(kcore_hdr)); 361 offset = kcore_hdr.c_hdrsize; 362 363 /* 364 * Read the CPU segment header 365 */ 366 sz = _kvm_pread(kd, kd->pmfd, &cpu_hdr, sizeof(cpu_hdr), (off_t)offset); 367 if (sz != sizeof(cpu_hdr)) { 368 goto fail; 369 } 370 371 if ((CORE_GETMAGIC(cpu_hdr) != KCORESEG_MAGIC) || 372 (CORE_GETFLAG(cpu_hdr) != CORE_CPU)) 373 goto fail; 374 offset += kcore_hdr.c_seghdrsize; 375 376 /* 377 * Read the CPU segment DATA. 378 */ 379 kd->cpu_dsize = cpu_hdr.c_size; 380 kd->cpu_data = _kvm_malloc(kd, cpu_hdr.c_size); 381 if (kd->cpu_data == NULL) 382 goto fail; 383 384 sz = _kvm_pread(kd, kd->pmfd, kd->cpu_data, cpu_hdr.c_size, (off_t)offset); 385 if (sz != cpu_hdr.c_size) { 386 goto fail; 387 } 388 389 offset += cpu_hdr.c_size; 390 391 /* 392 * Read the next segment header: data segment 393 */ 394 sz = _kvm_pread(kd, kd->pmfd, &mem_hdr, sizeof(mem_hdr), (off_t)offset); 395 if (sz != sizeof(mem_hdr)) { 396 goto fail; 397 } 398 399 offset += kcore_hdr.c_seghdrsize; 400 401 if ((CORE_GETMAGIC(mem_hdr) != KCORESEG_MAGIC) || 402 (CORE_GETFLAG(mem_hdr) != CORE_DATA)) 403 goto fail; 404 405 kd->dump_off = offset; 406 return (0); 407 408 fail: 409 if (kd->kcore_hdr != NULL) { 410 free(kd->kcore_hdr); 411 kd->kcore_hdr = NULL; 412 } 413 if (kd->cpu_data != NULL) { 414 free(kd->cpu_data); 415 kd->cpu_data = NULL; 416 kd->cpu_dsize = 0; 417 } 418 419 return (-1); 420 } 421 422 /* 423 * The format while on the dump device is: (new format) 424 * kcore_seg_t cpu_hdr; 425 * (opaque) cpu_data; (size is cpu_hdr.c_size) 426 * kcore_seg_t mem_hdr; 427 * (memory) mem_data; (size is mem_hdr.c_size) 428 */ 429 int 430 kvm_dump_mkheader(kd, dump_off) 431 kvm_t *kd; 432 off_t dump_off; 433 { 434 kcore_seg_t cpu_hdr; 435 int hdr_size, sz; 436 437 if (kd->kcore_hdr != NULL) { 438 _kvm_err(kd, kd->program, "already has a dump header"); 439 return (-1); 440 } 441 if (ISALIVE(kd)) { 442 _kvm_err(kd, kd->program, "don't use on live kernel"); 443 return (-1); 444 } 445 446 /* 447 * Validate new format crash dump 448 */ 449 sz = _kvm_pread(kd, kd->pmfd, &cpu_hdr, sizeof(cpu_hdr), (off_t)dump_off); 450 if (sz != sizeof(cpu_hdr)) { 451 return (-1); 452 } 453 if ((CORE_GETMAGIC(cpu_hdr) != KCORE_MAGIC) 454 || (CORE_GETMID(cpu_hdr) != MID_MACHINE)) { 455 _kvm_err(kd, 0, "invalid magic in cpu_hdr"); 456 return (-1); 457 } 458 hdr_size = ALIGN(sizeof(cpu_hdr)); 459 460 /* 461 * Read the CPU segment. 462 */ 463 kd->cpu_dsize = cpu_hdr.c_size; 464 kd->cpu_data = _kvm_malloc(kd, kd->cpu_dsize); 465 if (kd->cpu_data == NULL) 466 goto fail; 467 468 sz = _kvm_pread(kd, kd->pmfd, kd->cpu_data, cpu_hdr.c_size, 469 (off_t)dump_off+hdr_size); 470 if (sz != cpu_hdr.c_size) { 471 _kvm_err(kd, 0, "invalid size in cpu_hdr"); 472 goto fail; 473 } 474 hdr_size += kd->cpu_dsize; 475 476 /* 477 * Leave phys mem pointer at beginning of memory data 478 */ 479 kd->dump_off = dump_off + hdr_size; 480 errno = 0; 481 if (lseek(kd->pmfd, kd->dump_off, SEEK_SET) != kd->dump_off && errno != 0) { 482 _kvm_err(kd, 0, "invalid dump offset - lseek"); 483 goto fail; 484 } 485 486 /* 487 * Create a kcore_hdr. 488 */ 489 kd->kcore_hdr = _kvm_malloc(kd, sizeof(kcore_hdr_t)); 490 if (kd->kcore_hdr == NULL) 491 goto fail; 492 493 kd->kcore_hdr->c_hdrsize = ALIGN(sizeof(kcore_hdr_t)); 494 kd->kcore_hdr->c_seghdrsize = ALIGN(sizeof(kcore_seg_t)); 495 kd->kcore_hdr->c_nseg = 2; 496 CORE_SETMAGIC(*(kd->kcore_hdr), KCORE_MAGIC, MID_MACHINE,0); 497 498 /* 499 * Now that we have a valid header, enable translations. 500 */ 501 if (_kvm_initvtop(kd) == 0) 502 /* Success */ 503 return (hdr_size); 504 505 fail: 506 if (kd->kcore_hdr != NULL) { 507 free(kd->kcore_hdr); 508 kd->kcore_hdr = NULL; 509 } 510 if (kd->cpu_data != NULL) { 511 free(kd->cpu_data); 512 kd->cpu_data = NULL; 513 kd->cpu_dsize = 0; 514 } 515 return (-1); 516 } 517 518 static int 519 clear_gap(kd, fp, size) 520 kvm_t *kd; 521 FILE *fp; 522 int size; 523 { 524 if (size <= 0) /* XXX - < 0 should never happen */ 525 return (0); 526 while (size-- > 0) { 527 if (fputc(0, fp) == EOF) { 528 _kvm_syserr(kd, kd->program, "clear_gap"); 529 return (-1); 530 } 531 } 532 return (0); 533 } 534 535 /* 536 * Write the dump header info to 'fp'. Note that we can't use fseek(3) here 537 * because 'fp' might be a file pointer obtained by zopen(). 538 */ 539 int 540 kvm_dump_wrtheader(kd, fp, dumpsize) 541 kvm_t *kd; 542 FILE *fp; 543 int dumpsize; 544 { 545 kcore_seg_t seghdr; 546 long offset; 547 int gap; 548 549 if (kd->kcore_hdr == NULL || kd->cpu_data == NULL) { 550 _kvm_err(kd, kd->program, "no valid dump header(s)"); 551 return (-1); 552 } 553 554 /* 555 * Write the generic header 556 */ 557 offset = 0; 558 if (fwrite((void*)kd->kcore_hdr, sizeof(kcore_hdr_t), 1, fp) <= 0) { 559 _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader"); 560 return (-1); 561 } 562 offset += kd->kcore_hdr->c_hdrsize; 563 gap = kd->kcore_hdr->c_hdrsize - sizeof(kcore_hdr_t); 564 if (clear_gap(kd, fp, gap) == -1) 565 return (-1); 566 567 /* 568 * Write the cpu header 569 */ 570 CORE_SETMAGIC(seghdr, KCORESEG_MAGIC, 0, CORE_CPU); 571 seghdr.c_size = ALIGN(kd->cpu_dsize); 572 if (fwrite((void*)&seghdr, sizeof(seghdr), 1, fp) <= 0) { 573 _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader"); 574 return (-1); 575 } 576 offset += kd->kcore_hdr->c_seghdrsize; 577 gap = kd->kcore_hdr->c_seghdrsize - sizeof(seghdr); 578 if (clear_gap(kd, fp, gap) == -1) 579 return (-1); 580 581 if (fwrite((void*)kd->cpu_data, kd->cpu_dsize, 1, fp) <= 0) { 582 _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader"); 583 return (-1); 584 } 585 offset += seghdr.c_size; 586 gap = seghdr.c_size - kd->cpu_dsize; 587 if (clear_gap(kd, fp, gap) == -1) 588 return (-1); 589 590 /* 591 * Write the actual dump data segment header 592 */ 593 CORE_SETMAGIC(seghdr, KCORESEG_MAGIC, 0, CORE_DATA); 594 seghdr.c_size = dumpsize; 595 if (fwrite((void*)&seghdr, sizeof(seghdr), 1, fp) <= 0) { 596 _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader"); 597 return (-1); 598 } 599 offset += kd->kcore_hdr->c_seghdrsize; 600 gap = kd->kcore_hdr->c_seghdrsize - sizeof(seghdr); 601 if (clear_gap(kd, fp, gap) == -1) 602 return (-1); 603 604 return (offset); 605 } 606 607 kvm_t * 608 kvm_openfiles(uf, mf, sf, flag, errout) 609 const char *uf; 610 const char *mf; 611 const char *sf; 612 int flag; 613 char *errout; 614 { 615 register kvm_t *kd; 616 617 if ((kd = malloc(sizeof(*kd))) == NULL) { 618 (void)strlcpy(errout, strerror(errno), _POSIX2_LINE_MAX); 619 return (0); 620 } 621 kd->program = 0; 622 return (_kvm_open(kd, uf, mf, sf, flag, errout)); 623 } 624 625 kvm_t * 626 kvm_open(uf, mf, sf, flag, program) 627 const char *uf; 628 const char *mf; 629 const char *sf; 630 int flag; 631 const char *program; 632 { 633 register kvm_t *kd; 634 635 if ((kd = malloc(sizeof(*kd))) == NULL && program != NULL) { 636 (void)fprintf(stderr, "%s: %s\n", program, strerror(errno)); 637 return (0); 638 } 639 kd->program = program; 640 return (_kvm_open(kd, uf, mf, sf, flag, NULL)); 641 } 642 643 int 644 kvm_close(kd) 645 kvm_t *kd; 646 { 647 register int error = 0; 648 649 if (kd->pmfd >= 0) 650 error |= close(kd->pmfd); 651 if (kd->vmfd >= 0) 652 error |= close(kd->vmfd); 653 kd->alive = 0; 654 if (kd->nlfd >= 0) 655 error |= close(kd->nlfd); 656 if (kd->swfd >= 0) 657 error |= close(kd->swfd); 658 if (kd->db != 0) 659 error |= (kd->db->close)(kd->db); 660 if (kd->vmst) 661 _kvm_freevtop(kd); 662 kd->cpu_dsize = 0; 663 if (kd->cpu_data != NULL) 664 free((void *)kd->cpu_data); 665 if (kd->kcore_hdr != NULL) 666 free((void *)kd->kcore_hdr); 667 if (kd->procbase != 0) 668 free((void *)kd->procbase); 669 if (kd->swapspc != 0) 670 free((void *)kd->swapspc); 671 if (kd->argspc != 0) 672 free((void *)kd->argspc); 673 if (kd->argbuf != 0) 674 free((void *)kd->argbuf); 675 if (kd->argv != 0) 676 free((void *)kd->argv); 677 free((void *)kd); 678 679 return (error); 680 } 681 682 /* 683 * Set up state necessary to do queries on the kernel namelist 684 * data base. If the data base is out-of-data/incompatible with 685 * given executable, set up things so we revert to standard nlist call. 686 * Only called for live kernels. Return 0 on success, -1 on failure. 687 */ 688 static int 689 kvm_dbopen(kd, uf) 690 kvm_t *kd; 691 const char *uf; 692 { 693 DBT rec; 694 int dbversionlen; 695 struct nlist nitem; 696 char dbversion[_POSIX2_LINE_MAX]; 697 char kversion[_POSIX2_LINE_MAX]; 698 char dbname[MAXPATHLEN]; 699 700 uf = basename((char *)uf); 701 702 (void)snprintf(dbname, sizeof(dbname), "%skvm_%s.db", _PATH_VARDB, uf); 703 kd->db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL); 704 if (kd->db == NULL) { 705 switch (errno) { 706 case ENOENT: 707 /* No kvm_bsd.db, fall back to /bsd silently */ 708 break; 709 case EFTYPE: 710 _kvm_err(kd, kd->program, 711 "file %s is incorrectly formatted", dbname); 712 break; 713 case EINVAL: 714 _kvm_err(kd, kd->program, 715 "invalid argument to dbopen()"); 716 break; 717 default: 718 _kvm_err(kd, kd->program, "unknown dbopen() error"); 719 break; 720 } 721 return (-1); 722 } 723 724 /* 725 * read version out of database 726 */ 727 rec.data = VRS_KEY; 728 rec.size = sizeof(VRS_KEY) - 1; 729 if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0)) 730 goto close; 731 if (rec.data == 0 || rec.size > sizeof(dbversion)) 732 goto close; 733 734 bcopy(rec.data, dbversion, rec.size); 735 dbversionlen = rec.size; 736 /* 737 * Read version string from kernel memory. 738 * Since we are dealing with a live kernel, we can call kvm_read() 739 * at this point. 740 */ 741 rec.data = VRS_SYM; 742 rec.size = sizeof(VRS_SYM) - 1; 743 if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0)) 744 goto close; 745 if (rec.data == 0 || rec.size != sizeof(struct nlist)) 746 goto close; 747 bcopy((char *)rec.data, (char *)&nitem, sizeof(nitem)); 748 if (kvm_read(kd, (u_long)nitem.n_value, kversion, dbversionlen) != 749 dbversionlen) 750 goto close; 751 /* 752 * If they match, we win - otherwise clear out kd->db so 753 * we revert to slow nlist(). 754 */ 755 if (bcmp(dbversion, kversion, dbversionlen) == 0) 756 return (0); 757 close: 758 (void)(kd->db->close)(kd->db); 759 kd->db = 0; 760 761 return (-1); 762 } 763 764 int 765 kvm_nlist(kd, nl) 766 kvm_t *kd; 767 struct nlist *nl; 768 { 769 register struct nlist *p; 770 register int nvalid, rv; 771 772 /* 773 * If we can't use the data base, revert to the 774 * slow library call. 775 */ 776 if (kd->db == 0) { 777 rv = __fdnlist(kd->nlfd, nl); 778 if (rv == -1) 779 _kvm_err(kd, 0, "bad namelist"); 780 return (rv); 781 } 782 783 /* 784 * We can use the kvm data base. Go through each nlist entry 785 * and look it up with a db query. 786 */ 787 nvalid = 0; 788 for (p = nl; p->n_name && p->n_name[0]; ++p) { 789 register int len; 790 DBT rec; 791 792 if ((len = strlen(p->n_name)) > 4096) { 793 /* sanity */ 794 _kvm_err(kd, kd->program, "symbol too large"); 795 return (-1); 796 } 797 rec.data = p->n_name; 798 rec.size = len; 799 800 /* 801 * Make sure that n_value = 0 when the symbol isn't found 802 */ 803 p->n_value = 0; 804 805 if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0)) 806 continue; 807 if (rec.data == 0 || rec.size != sizeof(struct nlist)) 808 continue; 809 ++nvalid; 810 /* 811 * Avoid alignment issues. 812 */ 813 bcopy((char *)&((struct nlist *)rec.data)->n_type, 814 (char *)&p->n_type, 815 sizeof(p->n_type)); 816 bcopy((char *)&((struct nlist *)rec.data)->n_value, 817 (char *)&p->n_value, 818 sizeof(p->n_value)); 819 } 820 /* 821 * Return the number of entries that weren't found. 822 */ 823 return ((p - nl) - nvalid); 824 } 825 826 int kvm_dump_inval(kd) 827 kvm_t *kd; 828 { 829 struct nlist nlist[2]; 830 u_long pa, x; 831 832 if (ISALIVE(kd)) { 833 _kvm_err(kd, kd->program, "clearing dump on live kernel"); 834 return (-1); 835 } 836 nlist[0].n_name = "_dumpmag"; 837 nlist[1].n_name = NULL; 838 839 if (kvm_nlist(kd, nlist) == -1) { 840 _kvm_err(kd, 0, "bad namelist"); 841 return (-1); 842 } 843 if (_kvm_kvatop(kd, (u_long)nlist[0].n_value, &pa) == 0) 844 return (-1); 845 846 x = 0; 847 if (_kvm_pwrite(kd, kd->pmfd, &x, sizeof(x), 848 (off_t)_kvm_pa2off(kd, pa)) != sizeof(x)) { 849 _kvm_err(kd, 0, "cannot invalidate dump"); 850 return (-1); 851 } 852 return (0); 853 } 854 855 ssize_t 856 kvm_read(kd, kva, buf, len) 857 kvm_t *kd; 858 register u_long kva; 859 register void *buf; 860 register size_t len; 861 { 862 register int cc; 863 register void *cp; 864 865 if (ISALIVE(kd)) { 866 /* 867 * We're using /dev/kmem. Just read straight from the 868 * device and let the active kernel do the address translation. 869 */ 870 cc = _kvm_pread(kd, kd->vmfd, buf, len, (off_t)kva); 871 if (cc == -1) { 872 _kvm_err(kd, 0, "invalid address (%lx)", kva); 873 return (-1); 874 } else if (cc < len) 875 _kvm_err(kd, kd->program, "short read"); 876 return (cc); 877 } else { 878 if ((kd->kcore_hdr == NULL) || (kd->cpu_data == NULL)) { 879 _kvm_err(kd, kd->program, "no valid dump header"); 880 return (-1); 881 } 882 cp = buf; 883 while (len > 0) { 884 u_long pa; 885 886 /* In case of error, _kvm_kvatop sets the err string */ 887 cc = _kvm_kvatop(kd, kva, &pa); 888 if (cc == 0) 889 return (-1); 890 if (cc > len) 891 cc = len; 892 cc = _kvm_pread(kd, kd->pmfd, cp, cc, 893 (off_t)_kvm_pa2off(kd, pa)); 894 if (cc == -1) { 895 _kvm_syserr(kd, 0, _PATH_MEM); 896 break; 897 } 898 /* 899 * If kvm_kvatop returns a bogus value or our core 900 * file is truncated, we might wind up seeking beyond 901 * the end of the core file in which case the read will 902 * return 0 (EOF). 903 */ 904 if (cc == 0) 905 break; 906 cp = (char *)cp + cc; 907 kva += cc; 908 len -= cc; 909 } 910 return ((char *)cp - (char *)buf); 911 } 912 /* NOTREACHED */ 913 } 914 915 ssize_t 916 kvm_write(kd, kva, buf, len) 917 kvm_t *kd; 918 register u_long kva; 919 register const void *buf; 920 register size_t len; 921 { 922 register int cc; 923 924 if (ISALIVE(kd)) { 925 /* 926 * Just like kvm_read, only we write. 927 */ 928 cc = _kvm_pwrite(kd, kd->vmfd, (void*)buf, (size_t)len, (off_t)kva); 929 if (cc == -1) { 930 _kvm_err(kd, 0, "invalid address (%lx)", kva); 931 return (-1); 932 } else if (cc < len) 933 _kvm_err(kd, kd->program, "short write"); 934 return (cc); 935 } else { 936 _kvm_err(kd, kd->program, 937 "kvm_write not implemented for dead kernels"); 938 return (-1); 939 } 940 /* NOTREACHED */ 941 } 942 943 static int 944 kvm_setfd(kd) 945 kvm_t *kd; 946 { 947 if (kd->pmfd >= 0 && fcntl(kd->pmfd, F_SETFD, FD_CLOEXEC) < 0) 948 return (-1); 949 if (kd->vmfd >= 0 && fcntl(kd->vmfd, F_SETFD, FD_CLOEXEC) < 0) 950 return (-1); 951 if (kd->nlfd >= 0 && fcntl(kd->nlfd, F_SETFD, FD_CLOEXEC) < 0) 952 return (-1); 953 if (kd->swfd >= 0 && fcntl(kd->swfd, F_SETFD, FD_CLOEXEC) < 0) 954 return (-1); 955 956 return (0); 957 } 958