1 /*- 2 * Copyright (c) 1989, 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software developed by the Computer Systems 6 * Engineering group at Lawrence Berkeley Laboratory under DARPA contract 7 * BG 91-66 and contributed to Berkeley. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #if defined(LIBC_SCCS) && !defined(lint) 38 #if 0 39 static char sccsid[] = "@(#)kvm.c 8.2 (Berkeley) 2/13/94"; 40 #endif 41 #endif /* LIBC_SCCS and not lint */ 42 43 #include <sys/param.h> 44 45 #define _WANT_VNET 46 47 #include <sys/user.h> 48 #include <sys/proc.h> 49 #include <sys/ioctl.h> 50 #include <sys/stat.h> 51 #include <sys/sysctl.h> 52 #include <sys/linker.h> 53 #include <sys/pcpu.h> 54 55 #include <net/vnet.h> 56 57 #include <vm/vm.h> 58 #include <vm/vm_param.h> 59 60 #include <machine/vmparam.h> 61 62 #include <ctype.h> 63 #include <fcntl.h> 64 #include <kvm.h> 65 #include <limits.h> 66 #include <nlist.h> 67 #include <paths.h> 68 #include <stdio.h> 69 #include <stdlib.h> 70 #include <string.h> 71 #include <strings.h> 72 #include <unistd.h> 73 74 #include "kvm_private.h" 75 76 /* from src/lib/libc/gen/nlist.c */ 77 int __fdnlist(int, struct nlist *); 78 79 char * 80 kvm_geterr(kd) 81 kvm_t *kd; 82 { 83 return (kd->errbuf); 84 } 85 86 #include <stdarg.h> 87 88 /* 89 * Report an error using printf style arguments. "program" is kd->program 90 * on hard errors, and 0 on soft errors, so that under sun error emulation, 91 * only hard errors are printed out (otherwise, programs like gdb will 92 * generate tons of error messages when trying to access bogus pointers). 93 */ 94 void 95 _kvm_err(kvm_t *kd, const char *program, const char *fmt, ...) 96 { 97 va_list ap; 98 99 va_start(ap, fmt); 100 if (program != NULL) { 101 (void)fprintf(stderr, "%s: ", program); 102 (void)vfprintf(stderr, fmt, ap); 103 (void)fputc('\n', stderr); 104 } else 105 (void)vsnprintf(kd->errbuf, 106 sizeof(kd->errbuf), (char *)fmt, ap); 107 108 va_end(ap); 109 } 110 111 void 112 _kvm_syserr(kvm_t *kd, const char *program, const char *fmt, ...) 113 { 114 va_list ap; 115 int n; 116 117 va_start(ap, fmt); 118 if (program != NULL) { 119 (void)fprintf(stderr, "%s: ", program); 120 (void)vfprintf(stderr, fmt, ap); 121 (void)fprintf(stderr, ": %s\n", strerror(errno)); 122 } else { 123 char *cp = kd->errbuf; 124 125 (void)vsnprintf(cp, sizeof(kd->errbuf), (char *)fmt, ap); 126 n = strlen(cp); 127 (void)snprintf(&cp[n], sizeof(kd->errbuf) - n, ": %s", 128 strerror(errno)); 129 } 130 va_end(ap); 131 } 132 133 void * 134 _kvm_malloc(kd, n) 135 kvm_t *kd; 136 size_t n; 137 { 138 void *p; 139 140 if ((p = calloc(n, sizeof(char))) == NULL) 141 _kvm_err(kd, kd->program, "can't allocate %u bytes: %s", 142 n, strerror(errno)); 143 return (p); 144 } 145 146 static kvm_t * 147 _kvm_open(kd, uf, mf, flag, errout) 148 kvm_t *kd; 149 const char *uf; 150 const char *mf; 151 int flag; 152 char *errout; 153 { 154 struct stat st; 155 156 kd->vmfd = -1; 157 kd->pmfd = -1; 158 kd->nlfd = -1; 159 kd->vmst = 0; 160 kd->procbase = 0; 161 kd->argspc = 0; 162 kd->argv = 0; 163 164 if (uf == 0) 165 uf = getbootfile(); 166 else if (strlen(uf) >= MAXPATHLEN) { 167 _kvm_err(kd, kd->program, "exec file name too long"); 168 goto failed; 169 } 170 if (flag & ~O_RDWR) { 171 _kvm_err(kd, kd->program, "bad flags arg"); 172 goto failed; 173 } 174 if (mf == 0) 175 mf = _PATH_MEM; 176 177 if ((kd->pmfd = open(mf, flag, 0)) < 0) { 178 _kvm_syserr(kd, kd->program, "%s", mf); 179 goto failed; 180 } 181 if (fstat(kd->pmfd, &st) < 0) { 182 _kvm_syserr(kd, kd->program, "%s", mf); 183 goto failed; 184 } 185 if (S_ISREG(st.st_mode) && st.st_size <= 0) { 186 errno = EINVAL; 187 _kvm_syserr(kd, kd->program, "empty file"); 188 goto failed; 189 } 190 if (fcntl(kd->pmfd, F_SETFD, FD_CLOEXEC) < 0) { 191 _kvm_syserr(kd, kd->program, "%s", mf); 192 goto failed; 193 } 194 if (S_ISCHR(st.st_mode)) { 195 /* 196 * If this is a character special device, then check that 197 * it's /dev/mem. If so, open kmem too. (Maybe we should 198 * make it work for either /dev/mem or /dev/kmem -- in either 199 * case you're working with a live kernel.) 200 */ 201 if (strcmp(mf, _PATH_DEVNULL) == 0) { 202 kd->vmfd = open(_PATH_DEVNULL, O_RDONLY); 203 return (kd); 204 } else if (strcmp(mf, _PATH_MEM) == 0) { 205 if ((kd->vmfd = open(_PATH_KMEM, flag)) < 0) { 206 _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM); 207 goto failed; 208 } 209 if (fcntl(kd->vmfd, F_SETFD, FD_CLOEXEC) < 0) { 210 _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM); 211 goto failed; 212 } 213 return (kd); 214 } 215 } 216 /* 217 * This is a crash dump. 218 * Initialize the virtual address translation machinery, 219 * but first setup the namelist fd. 220 */ 221 if ((kd->nlfd = open(uf, O_RDONLY, 0)) < 0) { 222 _kvm_syserr(kd, kd->program, "%s", uf); 223 goto failed; 224 } 225 if (fcntl(kd->nlfd, F_SETFD, FD_CLOEXEC) < 0) { 226 _kvm_syserr(kd, kd->program, "%s", uf); 227 goto failed; 228 } 229 if (strncmp(mf, _PATH_FWMEM, strlen(_PATH_FWMEM)) == 0) 230 kd->rawdump = 1; 231 if (_kvm_initvtop(kd) < 0) 232 goto failed; 233 return (kd); 234 failed: 235 /* 236 * Copy out the error if doing sane error semantics. 237 */ 238 if (errout != 0) 239 strlcpy(errout, kd->errbuf, _POSIX2_LINE_MAX); 240 (void)kvm_close(kd); 241 return (0); 242 } 243 244 kvm_t * 245 kvm_openfiles(uf, mf, sf, flag, errout) 246 const char *uf; 247 const char *mf; 248 const char *sf __unused; 249 int flag; 250 char *errout; 251 { 252 kvm_t *kd; 253 254 if ((kd = calloc(1, sizeof(*kd))) == NULL) { 255 (void)strlcpy(errout, strerror(errno), _POSIX2_LINE_MAX); 256 return (0); 257 } 258 kd->program = 0; 259 return (_kvm_open(kd, uf, mf, flag, errout)); 260 } 261 262 kvm_t * 263 kvm_open(uf, mf, sf, flag, errstr) 264 const char *uf; 265 const char *mf; 266 const char *sf __unused; 267 int flag; 268 const char *errstr; 269 { 270 kvm_t *kd; 271 272 if ((kd = calloc(1, sizeof(*kd))) == NULL) { 273 if (errstr != NULL) 274 (void)fprintf(stderr, "%s: %s\n", 275 errstr, strerror(errno)); 276 return (0); 277 } 278 kd->program = errstr; 279 return (_kvm_open(kd, uf, mf, flag, NULL)); 280 } 281 282 int 283 kvm_close(kd) 284 kvm_t *kd; 285 { 286 int error = 0; 287 288 if (kd->pmfd >= 0) 289 error |= close(kd->pmfd); 290 if (kd->vmfd >= 0) 291 error |= close(kd->vmfd); 292 if (kd->nlfd >= 0) 293 error |= close(kd->nlfd); 294 if (kd->vmst) 295 _kvm_freevtop(kd); 296 if (kd->procbase != 0) 297 free((void *)kd->procbase); 298 if (kd->argbuf != 0) 299 free((void *) kd->argbuf); 300 if (kd->argspc != 0) 301 free((void *) kd->argspc); 302 if (kd->argv != 0) 303 free((void *)kd->argv); 304 free((void *)kd); 305 306 return (0); 307 } 308 309 /* 310 * Walk the list of unresolved symbols, generate a new list and prefix the 311 * symbol names, try again, and merge back what we could resolve. 312 */ 313 static int 314 kvm_fdnlist_prefix(kvm_t *kd, struct nlist *nl, int missing, const char *prefix, 315 uintptr_t (*validate_fn)(kvm_t *, uintptr_t)) 316 { 317 struct nlist *n, *np, *p; 318 char *cp, *ce; 319 size_t len; 320 int unresolved; 321 322 /* 323 * Calculate the space we need to malloc for nlist and names. 324 * We are going to store the name twice for later lookups: once 325 * with the prefix and once the unmodified name delmited by \0. 326 */ 327 len = 0; 328 unresolved = 0; 329 for (p = nl; p->n_name && p->n_name[0]; ++p) { 330 if (p->n_type != N_UNDF) 331 continue; 332 len += sizeof(struct nlist) + strlen(prefix) + 333 2 * (strlen(p->n_name) + 1); 334 unresolved++; 335 } 336 if (unresolved == 0) 337 return (unresolved); 338 /* Add space for the terminating nlist entry. */ 339 len += sizeof(struct nlist); 340 unresolved++; 341 342 /* Alloc one chunk for (nlist, [names]) and setup pointers. */ 343 n = np = malloc(len); 344 bzero(n, len); 345 if (n == NULL) 346 return (missing); 347 cp = ce = (char *)np; 348 cp += unresolved * sizeof(struct nlist); 349 ce += len; 350 351 /* Generate shortened nlist with special prefix. */ 352 unresolved = 0; 353 for (p = nl; p->n_name && p->n_name[0]; ++p) { 354 if (p->n_type != N_UNDF) 355 continue; 356 bcopy(p, np, sizeof(struct nlist)); 357 /* Save the new\0orig. name so we can later match it again. */ 358 len = snprintf(cp, ce - cp, "%s%s%c%s", prefix, 359 (prefix[0] != '\0' && p->n_name[0] == '_') ? 360 (p->n_name + 1) : p->n_name, '\0', p->n_name); 361 if (len >= ce - cp) 362 continue; 363 np->n_name = cp; 364 cp += len + 1; 365 np++; 366 unresolved++; 367 } 368 369 /* Do lookup on the reduced list. */ 370 np = n; 371 unresolved = __fdnlist(kd->nlfd, np); 372 373 /* Check if we could resolve further symbols and update the list. */ 374 if (unresolved >= 0 && unresolved < missing) { 375 /* Find the first freshly resolved entry. */ 376 for (; np->n_name && np->n_name[0]; np++) 377 if (np->n_type != N_UNDF) 378 break; 379 /* 380 * The lists are both in the same order, 381 * so we can walk them in parallel. 382 */ 383 for (p = nl; np->n_name && np->n_name[0] && 384 p->n_name && p->n_name[0]; ++p) { 385 if (p->n_type != N_UNDF) 386 continue; 387 /* Skip expanded name and compare to orig. one. */ 388 cp = np->n_name + strlen(np->n_name) + 1; 389 if (strcmp(cp, p->n_name)) 390 continue; 391 /* Update nlist with new, translated results. */ 392 p->n_type = np->n_type; 393 p->n_other = np->n_other; 394 p->n_desc = np->n_desc; 395 if (validate_fn) 396 p->n_value = (*validate_fn)(kd, np->n_value); 397 else 398 p->n_value = np->n_value; 399 missing--; 400 /* Find next freshly resolved entry. */ 401 for (np++; np->n_name && np->n_name[0]; np++) 402 if (np->n_type != N_UNDF) 403 break; 404 } 405 } 406 /* We could assert missing = unresolved here. */ 407 408 free(n); 409 return (unresolved); 410 } 411 412 int 413 _kvm_nlist(kvm_t *kd, struct nlist *nl, int initialize) 414 { 415 struct nlist *p; 416 int nvalid; 417 struct kld_sym_lookup lookup; 418 int error; 419 char *prefix = "", symname[1024]; /* XXX-BZ symbol name length limit? */ 420 int tried_vnet, tried_dpcpu; 421 422 /* 423 * If we can't use the kld symbol lookup, revert to the 424 * slow library call. 425 */ 426 if (!ISALIVE(kd)) { 427 error = __fdnlist(kd->nlfd, nl); 428 if (error <= 0) /* Hard error or success. */ 429 return (error); 430 431 if (_kvm_vnet_initialized(kd, initialize)) 432 error = kvm_fdnlist_prefix(kd, nl, error, 433 VNET_SYMPREFIX, _kvm_vnet_validaddr); 434 435 if (error > 0 && _kvm_dpcpu_initialized(kd, initialize)) 436 error = kvm_fdnlist_prefix(kd, nl, error, 437 DPCPU_SYMPREFIX, _kvm_dpcpu_validaddr); 438 439 return (error); 440 } 441 442 /* 443 * We can use the kld lookup syscall. Go through each nlist entry 444 * and look it up with a kldsym(2) syscall. 445 */ 446 nvalid = 0; 447 tried_vnet = 0; 448 tried_dpcpu = 0; 449 again: 450 for (p = nl; p->n_name && p->n_name[0]; ++p) { 451 if (p->n_type != N_UNDF) 452 continue; 453 454 lookup.version = sizeof(lookup); 455 lookup.symvalue = 0; 456 lookup.symsize = 0; 457 458 error = snprintf(symname, sizeof(symname), "%s%s", prefix, 459 (prefix[0] != '\0' && p->n_name[0] == '_') ? 460 (p->n_name + 1) : p->n_name); 461 if (error >= sizeof(symname)) 462 continue; 463 464 lookup.symname = symname; 465 if (lookup.symname[0] == '_') 466 lookup.symname++; 467 468 if (kldsym(0, KLDSYM_LOOKUP, &lookup) != -1) { 469 p->n_type = N_TEXT; 470 p->n_other = 0; 471 p->n_desc = 0; 472 if (_kvm_vnet_initialized(kd, initialize) && 473 !strcmp(prefix, VNET_SYMPREFIX)) 474 p->n_value = 475 _kvm_vnet_validaddr(kd, lookup.symvalue); 476 else if (_kvm_dpcpu_initialized(kd, initialize) && 477 !strcmp(prefix, DPCPU_SYMPREFIX)) 478 p->n_value = 479 _kvm_dpcpu_validaddr(kd, lookup.symvalue); 480 else 481 p->n_value = lookup.symvalue; 482 ++nvalid; 483 /* lookup.symsize */ 484 } 485 } 486 487 /* 488 * Check the number of entries that weren't found. If they exist, 489 * try again with a prefix for virtualized or DPCPU symbol names. 490 */ 491 error = ((p - nl) - nvalid); 492 if (error && _kvm_vnet_initialized(kd, initialize) && !tried_vnet) { 493 tried_vnet = 1; 494 prefix = VNET_SYMPREFIX; 495 goto again; 496 } 497 if (error && _kvm_dpcpu_initialized(kd, initialize) && !tried_dpcpu) { 498 tried_dpcpu = 1; 499 prefix = DPCPU_SYMPREFIX; 500 goto again; 501 } 502 503 /* 504 * Return the number of entries that weren't found. If they exist, 505 * also fill internal error buffer. 506 */ 507 error = ((p - nl) - nvalid); 508 if (error) 509 _kvm_syserr(kd, kd->program, "kvm_nlist"); 510 return (error); 511 } 512 513 int 514 kvm_nlist(kd, nl) 515 kvm_t *kd; 516 struct nlist *nl; 517 { 518 519 /* 520 * If called via the public interface, permit intialization of 521 * further virtualized modules on demand. 522 */ 523 return (_kvm_nlist(kd, nl, 1)); 524 } 525 526 ssize_t 527 kvm_read(kd, kva, buf, len) 528 kvm_t *kd; 529 u_long kva; 530 void *buf; 531 size_t len; 532 { 533 int cc; 534 char *cp; 535 536 if (ISALIVE(kd)) { 537 /* 538 * We're using /dev/kmem. Just read straight from the 539 * device and let the active kernel do the address translation. 540 */ 541 errno = 0; 542 if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) { 543 _kvm_err(kd, 0, "invalid address (%x)", kva); 544 return (-1); 545 } 546 cc = read(kd->vmfd, buf, len); 547 if (cc < 0) { 548 _kvm_syserr(kd, 0, "kvm_read"); 549 return (-1); 550 } else if (cc < len) 551 _kvm_err(kd, kd->program, "short read"); 552 return (cc); 553 } else { 554 cp = buf; 555 while (len > 0) { 556 off_t pa; 557 558 cc = _kvm_kvatop(kd, kva, &pa); 559 if (cc == 0) 560 return (-1); 561 if (cc > len) 562 cc = len; 563 errno = 0; 564 if (lseek(kd->pmfd, pa, 0) == -1 && errno != 0) { 565 _kvm_syserr(kd, 0, _PATH_MEM); 566 break; 567 } 568 cc = read(kd->pmfd, cp, cc); 569 if (cc < 0) { 570 _kvm_syserr(kd, kd->program, "kvm_read"); 571 break; 572 } 573 /* 574 * If kvm_kvatop returns a bogus value or our core 575 * file is truncated, we might wind up seeking beyond 576 * the end of the core file in which case the read will 577 * return 0 (EOF). 578 */ 579 if (cc == 0) 580 break; 581 cp += cc; 582 kva += cc; 583 len -= cc; 584 } 585 return (cp - (char *)buf); 586 } 587 /* NOTREACHED */ 588 } 589 590 ssize_t 591 kvm_write(kd, kva, buf, len) 592 kvm_t *kd; 593 u_long kva; 594 const void *buf; 595 size_t len; 596 { 597 int cc; 598 599 if (ISALIVE(kd)) { 600 /* 601 * Just like kvm_read, only we write. 602 */ 603 errno = 0; 604 if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) { 605 _kvm_err(kd, 0, "invalid address (%x)", kva); 606 return (-1); 607 } 608 cc = write(kd->vmfd, buf, len); 609 if (cc < 0) { 610 _kvm_syserr(kd, 0, "kvm_write"); 611 return (-1); 612 } else if (cc < len) 613 _kvm_err(kd, kd->program, "short write"); 614 return (cc); 615 } else { 616 _kvm_err(kd, kd->program, 617 "kvm_write not implemented for dead kernels"); 618 return (-1); 619 } 620 /* NOTREACHED */ 621 } 622