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