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 #include <sys/fnv_hash.h> 45 46 #define _WANT_VNET 47 48 #include <sys/user.h> 49 #include <sys/linker.h> 50 #include <sys/pcpu.h> 51 #include <sys/stat.h> 52 53 #include <net/vnet.h> 54 55 #include <fcntl.h> 56 #include <kvm.h> 57 #include <limits.h> 58 #include <paths.h> 59 #include <stdint.h> 60 #include <stdio.h> 61 #include <stdlib.h> 62 #include <string.h> 63 #include <unistd.h> 64 65 #include "kvm_private.h" 66 67 SET_DECLARE(kvm_arch, struct kvm_arch); 68 69 char * 70 kvm_geterr(kvm_t *kd) 71 { 72 return (kd->errbuf); 73 } 74 75 static int 76 _kvm_read_kernel_ehdr(kvm_t *kd) 77 { 78 Elf *elf; 79 80 if (elf_version(EV_CURRENT) == EV_NONE) { 81 _kvm_err(kd, kd->program, "Unsupported libelf"); 82 return (-1); 83 } 84 elf = elf_begin(kd->nlfd, ELF_C_READ, NULL); 85 if (elf == NULL) { 86 _kvm_err(kd, kd->program, "%s", elf_errmsg(0)); 87 return (-1); 88 } 89 if (elf_kind(elf) != ELF_K_ELF) { 90 _kvm_err(kd, kd->program, "kernel is not an ELF file"); 91 return (-1); 92 } 93 if (gelf_getehdr(elf, &kd->nlehdr) == NULL) { 94 _kvm_err(kd, kd->program, "%s", elf_errmsg(0)); 95 elf_end(elf); 96 return (-1); 97 } 98 elf_end(elf); 99 100 switch (kd->nlehdr.e_ident[EI_DATA]) { 101 case ELFDATA2LSB: 102 case ELFDATA2MSB: 103 return (0); 104 default: 105 _kvm_err(kd, kd->program, 106 "unsupported ELF data encoding for kernel"); 107 return (-1); 108 } 109 } 110 111 static kvm_t * 112 _kvm_open(kvm_t *kd, const char *uf, const char *mf, int flag, char *errout) 113 { 114 struct kvm_arch **parch; 115 struct stat st; 116 117 kd->vmfd = -1; 118 kd->pmfd = -1; 119 kd->nlfd = -1; 120 kd->vmst = NULL; 121 kd->procbase = NULL; 122 kd->argspc = NULL; 123 kd->argv = NULL; 124 125 if (uf == NULL) 126 uf = getbootfile(); 127 else if (strlen(uf) >= MAXPATHLEN) { 128 _kvm_err(kd, kd->program, "exec file name too long"); 129 goto failed; 130 } 131 if (flag & ~O_RDWR) { 132 _kvm_err(kd, kd->program, "bad flags arg"); 133 goto failed; 134 } 135 if (mf == NULL) 136 mf = _PATH_MEM; 137 138 if ((kd->pmfd = open(mf, flag | O_CLOEXEC, 0)) < 0) { 139 _kvm_syserr(kd, kd->program, "%s", mf); 140 goto failed; 141 } 142 if (fstat(kd->pmfd, &st) < 0) { 143 _kvm_syserr(kd, kd->program, "%s", mf); 144 goto failed; 145 } 146 if (S_ISREG(st.st_mode) && st.st_size <= 0) { 147 errno = EINVAL; 148 _kvm_syserr(kd, kd->program, "empty file"); 149 goto failed; 150 } 151 if (S_ISCHR(st.st_mode)) { 152 /* 153 * If this is a character special device, then check that 154 * it's /dev/mem. If so, open kmem too. (Maybe we should 155 * make it work for either /dev/mem or /dev/kmem -- in either 156 * case you're working with a live kernel.) 157 */ 158 if (strcmp(mf, _PATH_DEVNULL) == 0) { 159 kd->vmfd = open(_PATH_DEVNULL, O_RDONLY | O_CLOEXEC); 160 return (kd); 161 } else if (strcmp(mf, _PATH_MEM) == 0) { 162 if ((kd->vmfd = open(_PATH_KMEM, flag | O_CLOEXEC)) < 163 0) { 164 _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM); 165 goto failed; 166 } 167 return (kd); 168 } 169 } 170 171 /* 172 * This is either a crash dump or a remote live system with its physical 173 * memory fully accessible via a special device. 174 * Open the namelist fd and determine the architecture. 175 */ 176 if ((kd->nlfd = open(uf, O_RDONLY | O_CLOEXEC, 0)) < 0) { 177 _kvm_syserr(kd, kd->program, "%s", uf); 178 goto failed; 179 } 180 if (_kvm_read_kernel_ehdr(kd) < 0) 181 goto failed; 182 if (strncmp(mf, _PATH_FWMEM, strlen(_PATH_FWMEM)) == 0 || 183 strncmp(mf, _PATH_DEVVMM, strlen(_PATH_DEVVMM)) == 0) { 184 kd->rawdump = 1; 185 kd->writable = 1; 186 } 187 SET_FOREACH(parch, kvm_arch) { 188 if ((*parch)->ka_probe(kd)) { 189 kd->arch = *parch; 190 break; 191 } 192 } 193 if (kd->arch == NULL) { 194 _kvm_err(kd, kd->program, "unsupported architecture"); 195 goto failed; 196 } 197 198 /* 199 * Non-native kernels require a symbol resolver. 200 */ 201 if (!kd->arch->ka_native(kd) && kd->resolve_symbol == NULL) { 202 _kvm_err(kd, kd->program, 203 "non-native kernel requires a symbol resolver"); 204 goto failed; 205 } 206 207 /* 208 * Initialize the virtual address translation machinery. 209 */ 210 if (kd->arch->ka_initvtop(kd) < 0) 211 goto failed; 212 return (kd); 213 failed: 214 /* 215 * Copy out the error if doing sane error semantics. 216 */ 217 if (errout != NULL) 218 strlcpy(errout, kd->errbuf, _POSIX2_LINE_MAX); 219 (void)kvm_close(kd); 220 return (0); 221 } 222 223 kvm_t * 224 kvm_openfiles(const char *uf, const char *mf, const char *sf __unused, int flag, 225 char *errout) 226 { 227 kvm_t *kd; 228 229 if ((kd = calloc(1, sizeof(*kd))) == NULL) { 230 if (errout != NULL) 231 (void)strlcpy(errout, strerror(errno), 232 _POSIX2_LINE_MAX); 233 return (0); 234 } 235 return (_kvm_open(kd, uf, mf, flag, errout)); 236 } 237 238 kvm_t * 239 kvm_open(const char *uf, const char *mf, const char *sf __unused, int flag, 240 const char *errstr) 241 { 242 kvm_t *kd; 243 244 if ((kd = calloc(1, sizeof(*kd))) == NULL) { 245 if (errstr != NULL) 246 (void)fprintf(stderr, "%s: %s\n", 247 errstr, strerror(errno)); 248 return (0); 249 } 250 kd->program = errstr; 251 return (_kvm_open(kd, uf, mf, flag, NULL)); 252 } 253 254 kvm_t * 255 kvm_open2(const char *uf, const char *mf, int flag, char *errout, 256 int (*resolver)(const char *, kvaddr_t *)) 257 { 258 kvm_t *kd; 259 260 if ((kd = calloc(1, sizeof(*kd))) == NULL) { 261 if (errout != NULL) 262 (void)strlcpy(errout, strerror(errno), 263 _POSIX2_LINE_MAX); 264 return (0); 265 } 266 kd->resolve_symbol = resolver; 267 return (_kvm_open(kd, uf, mf, flag, errout)); 268 } 269 270 int 271 kvm_close(kvm_t *kd) 272 { 273 int error = 0; 274 275 if (kd->vmst != NULL) 276 kd->arch->ka_freevtop(kd); 277 if (kd->pmfd >= 0) 278 error |= close(kd->pmfd); 279 if (kd->vmfd >= 0) 280 error |= close(kd->vmfd); 281 if (kd->nlfd >= 0) 282 error |= close(kd->nlfd); 283 if (kd->procbase != 0) 284 free((void *)kd->procbase); 285 if (kd->argbuf != 0) 286 free((void *) kd->argbuf); 287 if (kd->argspc != 0) 288 free((void *) kd->argspc); 289 if (kd->argv != 0) 290 free((void *)kd->argv); 291 if (kd->pt_map != NULL) 292 free(kd->pt_map); 293 free((void *)kd); 294 295 return (0); 296 } 297 298 int 299 kvm_nlist2(kvm_t *kd, struct kvm_nlist *nl) 300 { 301 302 /* 303 * If called via the public interface, permit initialization of 304 * further virtualized modules on demand. 305 */ 306 return (_kvm_nlist(kd, nl, 1)); 307 } 308 309 int 310 kvm_nlist(kvm_t *kd, struct nlist *nl) 311 { 312 struct kvm_nlist *kl; 313 int count, i, nfail; 314 315 /* 316 * Avoid reporting truncated addresses by failing for non-native 317 * cores. 318 */ 319 if (!kvm_native(kd)) { 320 _kvm_err(kd, kd->program, "kvm_nlist of non-native vmcore"); 321 return (-1); 322 } 323 324 for (count = 0; nl[count].n_name != NULL && nl[count].n_name[0] != '\0'; 325 count++) 326 ; 327 if (count == 0) 328 return (0); 329 kl = calloc(count + 1, sizeof(*kl)); 330 for (i = 0; i < count; i++) 331 kl[i].n_name = nl[i].n_name; 332 nfail = kvm_nlist2(kd, kl); 333 for (i = 0; i < count; i++) { 334 nl[i].n_type = kl[i].n_type; 335 nl[i].n_other = 0; 336 nl[i].n_desc = 0; 337 nl[i].n_value = kl[i].n_value; 338 } 339 return (nfail); 340 } 341 342 ssize_t 343 kvm_read(kvm_t *kd, u_long kva, void *buf, size_t len) 344 { 345 346 return (kvm_read2(kd, kva, buf, len)); 347 } 348 349 ssize_t 350 kvm_read2(kvm_t *kd, kvaddr_t kva, void *buf, size_t len) 351 { 352 int cc; 353 ssize_t cr; 354 off_t pa; 355 char *cp; 356 357 if (ISALIVE(kd)) { 358 /* 359 * We're using /dev/kmem. Just read straight from the 360 * device and let the active kernel do the address translation. 361 */ 362 errno = 0; 363 if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) { 364 _kvm_err(kd, 0, "invalid address (0x%jx)", 365 (uintmax_t)kva); 366 return (-1); 367 } 368 cr = read(kd->vmfd, buf, len); 369 if (cr < 0) { 370 _kvm_syserr(kd, 0, "kvm_read"); 371 return (-1); 372 } else if (cr < (ssize_t)len) 373 _kvm_err(kd, kd->program, "short read"); 374 return (cr); 375 } 376 377 cp = buf; 378 while (len > 0) { 379 cc = kd->arch->ka_kvatop(kd, kva, &pa); 380 if (cc == 0) 381 return (-1); 382 if (cc > (ssize_t)len) 383 cc = len; 384 errno = 0; 385 if (lseek(kd->pmfd, pa, 0) == -1 && errno != 0) { 386 _kvm_syserr(kd, 0, _PATH_MEM); 387 break; 388 } 389 cr = read(kd->pmfd, cp, cc); 390 if (cr < 0) { 391 _kvm_syserr(kd, kd->program, "kvm_read"); 392 break; 393 } 394 /* 395 * If ka_kvatop returns a bogus value or our core file is 396 * truncated, we might wind up seeking beyond the end of the 397 * core file in which case the read will return 0 (EOF). 398 */ 399 if (cr == 0) 400 break; 401 cp += cr; 402 kva += cr; 403 len -= cr; 404 } 405 406 return (cp - (char *)buf); 407 } 408 409 ssize_t 410 kvm_write(kvm_t *kd, u_long kva, const void *buf, size_t len) 411 { 412 int cc; 413 ssize_t cw; 414 off_t pa; 415 const char *cp; 416 417 if (!ISALIVE(kd) && !kd->writable) { 418 _kvm_err(kd, kd->program, 419 "kvm_write not implemented for dead kernels"); 420 return (-1); 421 } 422 423 if (ISALIVE(kd)) { 424 /* 425 * Just like kvm_read, only we write. 426 */ 427 errno = 0; 428 if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) { 429 _kvm_err(kd, 0, "invalid address (%lx)", kva); 430 return (-1); 431 } 432 cc = write(kd->vmfd, buf, len); 433 if (cc < 0) { 434 _kvm_syserr(kd, 0, "kvm_write"); 435 return (-1); 436 } else if ((size_t)cc < len) 437 _kvm_err(kd, kd->program, "short write"); 438 return (cc); 439 } 440 441 cp = buf; 442 while (len > 0) { 443 cc = kd->arch->ka_kvatop(kd, kva, &pa); 444 if (cc == 0) 445 return (-1); 446 if (cc > (ssize_t)len) 447 cc = len; 448 errno = 0; 449 if (lseek(kd->pmfd, pa, 0) == -1 && errno != 0) { 450 _kvm_syserr(kd, 0, _PATH_MEM); 451 break; 452 } 453 cw = write(kd->pmfd, cp, cc); 454 if (cw < 0) { 455 _kvm_syserr(kd, kd->program, "kvm_write"); 456 break; 457 } 458 /* 459 * If ka_kvatop returns a bogus value or our core file is 460 * truncated, we might wind up seeking beyond the end of the 461 * core file in which case the read will return 0 (EOF). 462 */ 463 if (cw == 0) 464 break; 465 cp += cw; 466 kva += cw; 467 len -= cw; 468 } 469 470 return (cp - (char *)buf); 471 } 472 473 int 474 kvm_native(kvm_t *kd) 475 { 476 477 if (ISALIVE(kd)) 478 return (1); 479 return (kd->arch->ka_native(kd)); 480 } 481