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