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 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Berkeley and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 #if defined(LIBC_SCCS) && !defined(lint) 39 #if 0 40 static char sccsid[] = "@(#)kvm.c 8.2 (Berkeley) 2/13/94"; 41 #else 42 static const char rcsid[] = 43 "$FreeBSD$"; 44 #endif 45 #endif /* LIBC_SCCS and not lint */ 46 47 #include <sys/param.h> 48 #include <sys/user.h> 49 #include <sys/proc.h> 50 #include <sys/ioctl.h> 51 #include <sys/stat.h> 52 #include <sys/sysctl.h> 53 54 #include <vm/vm.h> 55 #include <vm/vm_param.h> 56 #include <vm/swap_pager.h> 57 58 #include <machine/vmparam.h> 59 60 #include <ctype.h> 61 #include <db.h> 62 #include <fcntl.h> 63 #include <kvm.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 72 #include "kvm_private.h" 73 74 static int kvm_dbopen __P((kvm_t *, const char *)); 75 76 char * 77 kvm_geterr(kd) 78 kvm_t *kd; 79 { 80 return (kd->errbuf); 81 } 82 83 #if __STDC__ 84 #include <stdarg.h> 85 #else 86 #include <varargs.h> 87 #endif 88 89 /* 90 * Report an error using printf style arguments. "program" is kd->program 91 * on hard errors, and 0 on soft errors, so that under sun error emulation, 92 * only hard errors are printed out (otherwise, programs like gdb will 93 * generate tons of error messages when trying to access bogus pointers). 94 */ 95 void 96 #if __STDC__ 97 _kvm_err(kvm_t *kd, const char *program, const char *fmt, ...) 98 #else 99 _kvm_err(kd, program, fmt, va_alist) 100 kvm_t *kd; 101 char *program, *fmt; 102 va_dcl 103 #endif 104 { 105 va_list ap; 106 107 #ifdef __STDC__ 108 va_start(ap, fmt); 109 #else 110 va_start(ap); 111 #endif 112 if (program != NULL) { 113 (void)fprintf(stderr, "%s: ", program); 114 (void)vfprintf(stderr, fmt, ap); 115 (void)fputc('\n', stderr); 116 } else 117 (void)vsnprintf(kd->errbuf, 118 sizeof(kd->errbuf), (char *)fmt, ap); 119 120 va_end(ap); 121 } 122 123 void 124 #if __STDC__ 125 _kvm_syserr(kvm_t *kd, const char *program, const char *fmt, ...) 126 #else 127 _kvm_syserr(kd, program, fmt, va_alist) 128 kvm_t *kd; 129 char *program, *fmt; 130 va_dcl 131 #endif 132 { 133 va_list ap; 134 register int n; 135 136 #if __STDC__ 137 va_start(ap, fmt); 138 #else 139 va_start(ap); 140 #endif 141 if (program != NULL) { 142 (void)fprintf(stderr, "%s: ", program); 143 (void)vfprintf(stderr, fmt, ap); 144 (void)fprintf(stderr, ": %s\n", strerror(errno)); 145 } else { 146 register char *cp = kd->errbuf; 147 148 (void)vsnprintf(cp, sizeof(kd->errbuf), (char *)fmt, ap); 149 n = strlen(cp); 150 (void)snprintf(&cp[n], sizeof(kd->errbuf) - n, ": %s", 151 strerror(errno)); 152 } 153 va_end(ap); 154 } 155 156 void * 157 _kvm_malloc(kd, n) 158 register kvm_t *kd; 159 register size_t n; 160 { 161 void *p; 162 163 if ((p = calloc(n, sizeof(char))) == NULL) 164 _kvm_err(kd, kd->program, "can't allocate %u bytes: %s", 165 n, strerror(errno)); 166 return (p); 167 } 168 169 static kvm_t * 170 _kvm_open(kd, uf, mf, flag, errout) 171 register kvm_t *kd; 172 const char *uf; 173 const char *mf; 174 int flag; 175 char *errout; 176 { 177 struct stat st; 178 179 kd->vmfd = -1; 180 kd->pmfd = -1; 181 kd->nlfd = -1; 182 kd->vmst = 0; 183 kd->db = 0; 184 kd->procbase = 0; 185 kd->argspc = 0; 186 kd->argv = 0; 187 188 if (uf == 0) 189 uf = getbootfile(); 190 else if (strlen(uf) >= MAXPATHLEN) { 191 _kvm_err(kd, kd->program, "exec file name too long"); 192 goto failed; 193 } 194 if (flag & ~O_RDWR) { 195 _kvm_err(kd, kd->program, "bad flags arg"); 196 goto failed; 197 } 198 if (mf == 0) 199 mf = _PATH_MEM; 200 201 if ((kd->pmfd = open(mf, flag, 0)) < 0) { 202 _kvm_syserr(kd, kd->program, "%s", mf); 203 goto failed; 204 } 205 if (fstat(kd->pmfd, &st) < 0) { 206 _kvm_syserr(kd, kd->program, "%s", mf); 207 goto failed; 208 } 209 if (S_ISCHR(st.st_mode)) { 210 /* 211 * If this is a character special device, then check that 212 * it's /dev/mem. If so, open kmem too. (Maybe we should 213 * make it work for either /dev/mem or /dev/kmem -- in either 214 * case you're working with a live kernel.) 215 */ 216 if (strcmp(mf, _PATH_DEVNULL) == 0) { 217 kd->vmfd = open(_PATH_DEVNULL, O_RDONLY); 218 } else if (strcmp(mf, _PATH_MEM) != 0) { 219 _kvm_err(kd, kd->program, 220 "%s: not physical memory device", mf); 221 goto failed; 222 } else { 223 if ((kd->vmfd = open(_PATH_KMEM, flag)) < 0) { 224 _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM); 225 goto failed; 226 } 227 } 228 /* 229 * Open kvm nlist database. We go ahead and do this 230 * here so that we don't have to hold on to the kernel 231 * path name. Since a kvm application will surely do 232 * a kvm_nlist(), this probably won't be a wasted effort. 233 * If the database cannot be opened, open the namelist 234 * argument so we revert to slow nlist() calls. 235 */ 236 if (kvm_dbopen(kd, uf) < 0 && 237 (kd->nlfd = open(uf, O_RDONLY, 0)) < 0) { 238 _kvm_syserr(kd, kd->program, "%s", uf); 239 goto failed; 240 } 241 } else { 242 /* 243 * This is a crash dump. 244 * Initialize the virtual address translation machinery, 245 * but first setup the namelist fd. 246 */ 247 if ((kd->nlfd = open(uf, O_RDONLY, 0)) < 0) { 248 _kvm_syserr(kd, kd->program, "%s", uf); 249 goto failed; 250 } 251 if (_kvm_initvtop(kd) < 0) 252 goto failed; 253 } 254 return (kd); 255 failed: 256 /* 257 * Copy out the error if doing sane error semantics. 258 */ 259 if (errout != 0) 260 strcpy(errout, kd->errbuf); 261 (void)kvm_close(kd); 262 return (0); 263 } 264 265 kvm_t * 266 kvm_openfiles(uf, mf, sf, flag, errout) 267 const char *uf; 268 const char *mf; 269 const char *sf; 270 int flag; 271 char *errout; 272 { 273 register kvm_t *kd; 274 275 if ((kd = malloc(sizeof(*kd))) == NULL) { 276 (void)strcpy(errout, strerror(errno)); 277 return (0); 278 } 279 memset(kd, 0, sizeof(*kd)); 280 kd->program = 0; 281 return (_kvm_open(kd, uf, mf, flag, errout)); 282 } 283 284 kvm_t * 285 kvm_open(uf, mf, sf, flag, errstr) 286 const char *uf; 287 const char *mf; 288 const char *sf; 289 int flag; 290 const char *errstr; 291 { 292 register kvm_t *kd; 293 294 if ((kd = malloc(sizeof(*kd))) == NULL) { 295 if (errstr != NULL) 296 (void)fprintf(stderr, "%s: %s\n", 297 errstr, strerror(errno)); 298 return (0); 299 } 300 memset(kd, 0, sizeof(*kd)); 301 kd->program = errstr; 302 return (_kvm_open(kd, uf, mf, flag, NULL)); 303 } 304 305 int 306 kvm_close(kd) 307 kvm_t *kd; 308 { 309 register int error = 0; 310 311 if (kd->pmfd >= 0) 312 error |= close(kd->pmfd); 313 if (kd->vmfd >= 0) 314 error |= close(kd->vmfd); 315 if (kd->nlfd >= 0) 316 error |= close(kd->nlfd); 317 if (kd->db != 0) 318 error |= (kd->db->close)(kd->db); 319 if (kd->vmst) 320 _kvm_freevtop(kd); 321 if (kd->procbase != 0) 322 free((void *)kd->procbase); 323 if (kd->argv != 0) 324 free((void *)kd->argv); 325 free((void *)kd); 326 327 return (0); 328 } 329 330 /* 331 * Set up state necessary to do queries on the kernel namelist 332 * data base. If the data base is out-of-data/incompatible with 333 * given executable, set up things so we revert to standard nlist call. 334 * Only called for live kernels. Return 0 on success, -1 on failure. 335 */ 336 static int 337 kvm_dbopen(kd, uf) 338 kvm_t *kd; 339 const char *uf; 340 { 341 char *cp; 342 DBT rec; 343 int dbversionlen; 344 struct nlist nitem; 345 char dbversion[_POSIX2_LINE_MAX]; 346 char kversion[_POSIX2_LINE_MAX]; 347 char dbname[MAXPATHLEN]; 348 349 if ((cp = rindex(uf, '/')) != 0) 350 uf = cp + 1; 351 352 (void)snprintf(dbname, sizeof(dbname), "%skvm_%s.db", _PATH_VARDB, uf); 353 kd->db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL); 354 if (kd->db == 0) 355 return (-1); 356 /* 357 * read version out of database 358 */ 359 rec.data = VRS_KEY; 360 rec.size = sizeof(VRS_KEY) - 1; 361 if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0)) 362 goto close; 363 if (rec.data == 0 || rec.size > sizeof(dbversion)) 364 goto close; 365 366 bcopy(rec.data, dbversion, rec.size); 367 dbversionlen = rec.size; 368 /* 369 * Read version string from kernel memory. 370 * Since we are dealing with a live kernel, we can call kvm_read() 371 * at this point. 372 */ 373 rec.data = VRS_SYM; 374 rec.size = sizeof(VRS_SYM) - 1; 375 if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0)) 376 goto close; 377 if (rec.data == 0 || rec.size != sizeof(struct nlist)) 378 goto close; 379 bcopy((char *)rec.data, (char *)&nitem, sizeof(nitem)); 380 if (kvm_read(kd, (u_long)nitem.n_value, kversion, dbversionlen) != 381 dbversionlen) 382 goto close; 383 /* 384 * If they match, we win - otherwise clear out kd->db so 385 * we revert to slow nlist(). 386 */ 387 if (bcmp(dbversion, kversion, dbversionlen) == 0) 388 return (0); 389 close: 390 (void)(kd->db->close)(kd->db); 391 kd->db = 0; 392 393 return (-1); 394 } 395 396 int 397 kvm_nlist(kd, nl) 398 kvm_t *kd; 399 struct nlist *nl; 400 { 401 register struct nlist *p; 402 register int nvalid; 403 404 /* 405 * If we can't use the data base, revert to the 406 * slow library call. 407 */ 408 if (kd->db == 0) 409 return (__fdnlist(kd->nlfd, nl)); 410 411 /* 412 * We can use the kvm data base. Go through each nlist entry 413 * and look it up with a db query. 414 */ 415 nvalid = 0; 416 for (p = nl; p->n_name && p->n_name[0]; ++p) { 417 register int len; 418 DBT rec; 419 420 if ((len = strlen(p->n_name)) > 4096) { 421 /* sanity */ 422 _kvm_err(kd, kd->program, "symbol too large"); 423 return (-1); 424 } 425 rec.data = p->n_name; 426 rec.size = len; 427 if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0)) 428 continue; 429 if (rec.data == 0 || rec.size != sizeof(struct nlist)) 430 continue; 431 ++nvalid; 432 /* 433 * Avoid alignment issues. 434 */ 435 bcopy((char *)&((struct nlist *)rec.data)->n_type, 436 (char *)&p->n_type, 437 sizeof(p->n_type)); 438 bcopy((char *)&((struct nlist *)rec.data)->n_value, 439 (char *)&p->n_value, 440 sizeof(p->n_value)); 441 } 442 /* 443 * Return the number of entries that weren't found. 444 */ 445 return ((p - nl) - nvalid); 446 } 447 448 ssize_t 449 kvm_read(kd, kva, buf, len) 450 kvm_t *kd; 451 register u_long kva; 452 register void *buf; 453 register size_t len; 454 { 455 register int cc; 456 register void *cp; 457 458 if (ISALIVE(kd)) { 459 /* 460 * We're using /dev/kmem. Just read straight from the 461 * device and let the active kernel do the address translation. 462 */ 463 errno = 0; 464 if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) { 465 _kvm_err(kd, 0, "invalid address (%x)", kva); 466 return (0); 467 } 468 cc = read(kd->vmfd, buf, len); 469 if (cc < 0) { 470 _kvm_syserr(kd, 0, "kvm_read"); 471 return (0); 472 } else if (cc < len) 473 _kvm_err(kd, kd->program, "short read"); 474 return (cc); 475 } else { 476 cp = buf; 477 while (len > 0) { 478 u_long pa; 479 480 cc = _kvm_kvatop(kd, kva, &pa); 481 if (cc == 0) 482 return (0); 483 if (cc > len) 484 cc = len; 485 errno = 0; 486 if (lseek(kd->pmfd, (off_t)pa, 0) == -1 && errno != 0) { 487 _kvm_syserr(kd, 0, _PATH_MEM); 488 break; 489 } 490 cc = read(kd->pmfd, cp, cc); 491 if (cc < 0) { 492 _kvm_syserr(kd, kd->program, "kvm_read"); 493 break; 494 } 495 /* 496 * If kvm_kvatop returns a bogus value or our core 497 * file is truncated, we might wind up seeking beyond 498 * the end of the core file in which case the read will 499 * return 0 (EOF). 500 */ 501 if (cc == 0) 502 break; 503 (char *)cp += cc; 504 kva += cc; 505 len -= cc; 506 } 507 return ((char *)cp - (char *)buf); 508 } 509 /* NOTREACHED */ 510 } 511 512 ssize_t 513 kvm_write(kd, kva, buf, len) 514 kvm_t *kd; 515 register u_long kva; 516 register const void *buf; 517 register size_t len; 518 { 519 register int cc; 520 521 if (ISALIVE(kd)) { 522 /* 523 * Just like kvm_read, only we write. 524 */ 525 errno = 0; 526 if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) { 527 _kvm_err(kd, 0, "invalid address (%x)", kva); 528 return (0); 529 } 530 cc = write(kd->vmfd, buf, len); 531 if (cc < 0) { 532 _kvm_syserr(kd, 0, "kvm_write"); 533 return (0); 534 } else if (cc < len) 535 _kvm_err(kd, kd->program, "short write"); 536 return (cc); 537 } else { 538 _kvm_err(kd, kd->program, 539 "kvm_write not implemented for dead kernels"); 540 return (0); 541 } 542 /* NOTREACHED */ 543 } 544