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