1 /*- 2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 /* 28 * file/module function dispatcher, support, etc. 29 */ 30 31 #include <stand.h> 32 #include <string.h> 33 #include <sys/param.h> 34 #include <sys/linker.h> 35 #include <sys/module.h> 36 #include <sys/queue.h> 37 #include <sys/stdint.h> 38 #include <sys/font.h> 39 #include <gfx_fb.h> 40 41 #if defined(LOADER_FDT_SUPPORT) 42 #include <fdt_platform.h> 43 #endif 44 45 #include "bootstrap.h" 46 #include "modinfo.h" 47 48 #define MDIR_REMOVED 0x0001 49 #define MDIR_NOHINTS 0x0002 50 51 struct moduledir { 52 char *d_path; /* path of modules directory */ 53 u_char *d_hints; /* content of linker.hints file */ 54 int d_hintsz; /* size of hints data */ 55 int d_flags; 56 STAILQ_ENTRY(moduledir) d_link; 57 }; 58 59 static int file_load(char *filename, vm_offset_t dest, struct preloaded_file **result); 60 static int file_load_dependencies(struct preloaded_file *base_mod); 61 static char * file_search(const char *name, char **extlist); 62 static struct kernel_module * file_findmodule(struct preloaded_file *fp, char *modname, struct mod_depend *verinfo); 63 static int file_havepath(const char *name); 64 static char *mod_searchmodule(char *name, struct mod_depend *verinfo); 65 static char * mod_searchmodule_pnpinfo(const char *bus, const char *pnpinfo); 66 static void file_insert_tail(struct preloaded_file *mp); 67 static void file_remove(struct preloaded_file *fp); 68 static void file_remove_tail(struct preloaded_file *fp); 69 static struct file_metadata * metadata_next(struct file_metadata *base_mp, int type); 70 static void moduledir_readhints(struct moduledir *mdp); 71 static void moduledir_rebuild(void); 72 73 /* load address should be tweaked by first module loaded (kernel) */ 74 static vm_offset_t loadaddr = 0; 75 76 #if defined(LOADER_FDT_SUPPORT) 77 static const char *default_searchpath = 78 "/boot/kernel;/boot/modules;/boot/dtb"; 79 #else 80 static const char *default_searchpath = "/boot/kernel;/boot/modules"; 81 #endif 82 83 static STAILQ_HEAD(, moduledir) moduledir_list = 84 STAILQ_HEAD_INITIALIZER(moduledir_list); 85 86 struct preloaded_file *preloaded_files = NULL; 87 88 static char *kld_ext_list[] = { 89 ".ko", 90 "", 91 ".debug", 92 NULL 93 }; 94 95 /* 96 * load an object, either a disk file or code module. 97 * 98 * To load a file, the syntax is: 99 * 100 * load -t <type> <path> 101 * 102 * code modules are loaded as: 103 * 104 * load <path> <options> 105 */ 106 107 COMMAND_SET(load, "load", "load a kernel or module", command_load); 108 109 static int 110 command_load(int argc, char *argv[]) 111 { 112 struct preloaded_file *fp; 113 char *typestr; 114 #ifdef LOADER_VERIEXEC 115 char *prefix, *skip; 116 int dflag = 0; 117 char *args = "dkp:s:t:"; 118 #else 119 char *args = "kt:"; 120 #endif 121 int dofile, dokld, ch, error; 122 123 dokld = dofile = 0; 124 optind = 1; 125 optreset = 1; 126 typestr = NULL; 127 if (argc == 1) { 128 command_errmsg = "no filename specified"; 129 return (CMD_CRIT); 130 } 131 #ifdef LOADER_VERIEXEC 132 prefix = NULL; 133 skip = NULL; 134 #endif 135 while ((ch = getopt(argc, argv, args)) != -1) { 136 switch(ch) { 137 #ifdef LOADER_VERIEXEC 138 case 'd': 139 dflag++; 140 break; 141 #endif 142 case 'k': 143 dokld = 1; 144 break; 145 #ifdef LOADER_VERIEXEC 146 case 'p': 147 prefix = optarg; 148 break; 149 case 's': 150 skip = optarg; 151 break; 152 #endif 153 case 't': 154 typestr = optarg; 155 dofile = 1; 156 break; 157 case '?': 158 default: 159 /* getopt has already reported an error */ 160 return (CMD_OK); 161 } 162 } 163 argv += (optind - 1); 164 argc -= (optind - 1); 165 166 /* 167 * Request to load a raw file? 168 */ 169 if (dofile) { 170 if ((argc != 2) || (typestr == NULL) || (*typestr == 0)) { 171 command_errmsg = "invalid load type"; 172 return (CMD_CRIT); 173 } 174 175 #ifdef LOADER_VERIEXEC 176 if (strncmp(typestr, "manifest", 8) == 0) { 177 if (dflag > 0) 178 ve_debug_set(dflag); 179 return (load_manifest(argv[1], prefix, skip, NULL)); 180 } 181 #ifdef LOADER_VERIEXEC_PASS_MANIFEST 182 if (strncmp(typestr, "pass_manifest", 13) == 0) { 183 if (dflag > 0) 184 ve_debug_set(dflag); 185 return (pass_manifest(argv[1], prefix)); 186 } 187 #endif 188 #endif 189 190 fp = file_findfile(argv[1], typestr); 191 if (fp) { 192 snprintf(command_errbuf, sizeof(command_errbuf), 193 "warning: file '%s' already loaded", argv[1]); 194 return (CMD_WARN); 195 } 196 197 if (file_loadraw(argv[1], typestr, 1) != NULL) 198 return (CMD_OK); 199 200 /* Failing to load mfs_root is never going to end well! */ 201 if (strcmp("mfs_root", typestr) == 0) 202 return (CMD_FATAL); 203 204 return (CMD_ERROR); 205 } 206 /* 207 * Do we have explicit KLD load ? 208 */ 209 if (dokld || file_havepath(argv[1])) { 210 error = mod_loadkld(argv[1], argc - 2, argv + 2); 211 if (error == EEXIST) { 212 snprintf(command_errbuf, sizeof(command_errbuf), 213 "warning: KLD '%s' already loaded", argv[1]); 214 return (CMD_WARN); 215 } 216 217 return (error == 0 ? CMD_OK : CMD_CRIT); 218 } 219 /* 220 * Looks like a request for a module. 221 */ 222 error = mod_load(argv[1], NULL, argc - 2, argv + 2); 223 if (error == EEXIST) { 224 snprintf(command_errbuf, sizeof(command_errbuf), 225 "warning: module '%s' already loaded", argv[1]); 226 return (CMD_WARN); 227 } 228 229 return (error == 0 ? CMD_OK : CMD_CRIT); 230 } 231 232 #ifdef LOADER_GELI_SUPPORT 233 COMMAND_SET(load_geli, "load_geli", "load a geli key", command_load_geli); 234 235 static int 236 command_load_geli(int argc, char *argv[]) 237 { 238 char typestr[80]; 239 char *cp; 240 int ch, num; 241 242 if (argc < 3) { 243 command_errmsg = "usage is [-n key#] <prov> <file>"; 244 return(CMD_ERROR); 245 } 246 247 num = 0; 248 optind = 1; 249 optreset = 1; 250 while ((ch = getopt(argc, argv, "n:")) != -1) { 251 switch(ch) { 252 case 'n': 253 num = strtol(optarg, &cp, 0); 254 if (cp == optarg) { 255 snprintf(command_errbuf, sizeof(command_errbuf), 256 "bad key index '%s'", optarg); 257 return(CMD_ERROR); 258 } 259 break; 260 case '?': 261 default: 262 /* getopt has already reported an error */ 263 return(CMD_OK); 264 } 265 } 266 argv += (optind - 1); 267 argc -= (optind - 1); 268 sprintf(typestr, "%s:geli_keyfile%d", argv[1], num); 269 return (file_loadraw(argv[2], typestr, 1) ? CMD_OK : CMD_ERROR); 270 } 271 #endif 272 273 void 274 unload(void) 275 { 276 struct preloaded_file *fp; 277 278 while (preloaded_files != NULL) { 279 fp = preloaded_files; 280 preloaded_files = preloaded_files->f_next; 281 file_discard(fp); 282 } 283 loadaddr = 0; 284 unsetenv("kernelname"); 285 } 286 287 COMMAND_SET(unload, "unload", "unload all modules", command_unload); 288 289 static int 290 command_unload(int argc, char *argv[]) 291 { 292 unload(); 293 return(CMD_OK); 294 } 295 296 COMMAND_SET(lsmod, "lsmod", "list loaded modules", command_lsmod); 297 298 static int 299 command_lsmod(int argc, char *argv[]) 300 { 301 struct preloaded_file *fp; 302 struct kernel_module *mp; 303 struct file_metadata *md; 304 char lbuf[80]; 305 int ch, verbose, ret = 0; 306 307 verbose = 0; 308 optind = 1; 309 optreset = 1; 310 while ((ch = getopt(argc, argv, "v")) != -1) { 311 switch(ch) { 312 case 'v': 313 verbose = 1; 314 break; 315 case '?': 316 default: 317 /* getopt has already reported an error */ 318 return(CMD_OK); 319 } 320 } 321 322 pager_open(); 323 for (fp = preloaded_files; fp; fp = fp->f_next) { 324 snprintf(lbuf, sizeof(lbuf), " %p: ", (void *) fp->f_addr); 325 pager_output(lbuf); 326 pager_output(fp->f_name); 327 snprintf(lbuf, sizeof(lbuf), " (%s, 0x%lx)\n", fp->f_type, 328 (long)fp->f_size); 329 if (pager_output(lbuf)) 330 break; 331 if (fp->f_args != NULL) { 332 pager_output(" args: "); 333 pager_output(fp->f_args); 334 if (pager_output("\n")) 335 break; 336 } 337 if (fp->f_modules) { 338 pager_output(" modules: "); 339 for (mp = fp->f_modules; mp; mp = mp->m_next) { 340 snprintf(lbuf, sizeof(lbuf), "%s.%d ", mp->m_name, 341 mp->m_version); 342 pager_output(lbuf); 343 } 344 if (pager_output("\n")) 345 break; 346 } 347 if (verbose) { 348 /* XXX could add some formatting smarts here to display some better */ 349 for (md = fp->f_metadata; md != NULL; md = md->md_next) { 350 snprintf(lbuf, sizeof(lbuf), " 0x%04x, 0x%lx\n", 351 md->md_type, (long) md->md_size); 352 if (pager_output(lbuf)) 353 break; 354 } 355 } 356 if (ret) 357 break; 358 } 359 pager_close(); 360 return(CMD_OK); 361 } 362 363 COMMAND_SET(pnpmatch, "pnpmatch", "list matched modules based on pnpinfo", command_pnpmatch); 364 365 static int pnp_dump_flag = 0; 366 static int pnp_unbound_flag = 0; 367 static int pnp_verbose_flag = 0; 368 369 static int 370 command_pnpmatch(int argc, char *argv[]) 371 { 372 char *module; 373 int ch; 374 375 pnp_verbose_flag = 0; 376 pnp_dump_flag = 0; 377 optind = 1; 378 optreset = 1; 379 while ((ch = getopt(argc, argv, "vd")) != -1) { 380 switch(ch) { 381 case 'v': 382 pnp_verbose_flag = 1; 383 break; 384 case 'd': 385 pnp_dump_flag = 1; 386 break; 387 case '?': 388 default: 389 /* getopt has already reported an error */ 390 return(CMD_OK); 391 } 392 } 393 argv += optind; 394 argc -= optind; 395 396 if (argc != 2) { 397 command_errmsg = "Usage: pnpmatch <busname> compat=<compatdata>"; 398 return (CMD_CRIT); 399 } 400 401 module = mod_searchmodule_pnpinfo(argv[0], argv[1]); 402 if (module) 403 printf("Matched module: %s\n", module); 404 else 405 printf("No module matches %s on bus %s\n", argv[1], argv[0]); 406 407 return (CMD_OK); 408 } 409 410 COMMAND_SET(pnpload, "pnpload", "load matched modules based on pnpinfo", command_pnpload); 411 412 static int 413 command_pnpload(int argc, char *argv[]) 414 { 415 char *module; 416 int ch, error; 417 418 pnp_verbose_flag = 0; 419 pnp_dump_flag = 0; 420 optind = 1; 421 optreset = 1; 422 while ((ch = getopt(argc, argv, "vd")) != -1) { 423 switch(ch) { 424 case 'v': 425 pnp_verbose_flag = 1; 426 break; 427 case 'd': 428 pnp_dump_flag = 1; 429 break; 430 case '?': 431 default: 432 /* getopt has already reported an error */ 433 return(CMD_OK); 434 } 435 } 436 argv += optind; 437 argc -= optind; 438 439 if (argc != 2) { 440 command_errmsg = "Usage: pnpload <busname> compat=<compatdata>"; 441 return (CMD_ERROR); 442 } 443 444 module = mod_searchmodule_pnpinfo(argv[0], argv[1]); 445 446 error = mod_load(module, NULL, 0, NULL); 447 if (error == EEXIST) { 448 snprintf(command_errbuf, sizeof(command_errbuf), 449 "warning: module '%s' already loaded", argv[1]); 450 return (CMD_WARN); 451 } 452 453 return (error == 0 ? CMD_OK : CMD_CRIT); 454 } 455 456 #if defined(LOADER_FDT_SUPPORT) 457 static void 458 pnpautoload_fdt_bus(const char *busname) 459 { 460 const char *pnpstring; 461 const char *compatstr; 462 char *pnpinfo = NULL; 463 char *module = NULL; 464 int tag = 0, len, pnplen; 465 int error; 466 467 while (1) { 468 pnpstring = fdt_devmatch_next(&tag, &len); 469 if (pnpstring == NULL) 470 return; 471 472 compatstr = pnpstring; 473 for (pnplen = 0; pnplen != len; compatstr = pnpstring + pnplen) { 474 pnplen += strlen(compatstr) + 1; 475 asprintf(&pnpinfo, "compat=%s", compatstr); 476 477 module = mod_searchmodule_pnpinfo(busname, pnpinfo); 478 if (module) { 479 error = mod_loadkld(module, 0, NULL); 480 if (error) 481 printf("Cannot load module %s\n", module); 482 break; 483 } 484 } 485 free(pnpinfo); 486 free(module); 487 } 488 } 489 #endif 490 491 struct pnp_bus { 492 const char *name; 493 void (*load)(const char *busname); 494 }; 495 496 struct pnp_bus pnp_buses[] = { 497 #if defined(LOADER_FDT_SUPPORT) 498 {"simplebus", pnpautoload_fdt_bus}, 499 {"ofwbus", pnpautoload_fdt_bus}, 500 {"iicbus", pnpautoload_fdt_bus}, 501 {"spibus", pnpautoload_fdt_bus}, 502 #endif 503 }; 504 505 COMMAND_SET(pnpautoload, "pnpautoload", "auto load modules based on pnpinfo", command_pnpautoload); 506 507 static int 508 command_pnpautoload(int argc, char *argv[]) 509 { 510 int i; 511 int verbose; 512 int ch, match; 513 514 pnp_verbose_flag = 0; 515 pnp_dump_flag = 0; 516 verbose = 0; 517 optind = 1; 518 optreset = 1; 519 match = 0; 520 while ((ch = getopt(argc, argv, "v")) != -1) { 521 switch(ch) { 522 case 'v': 523 verbose = 1; 524 break; 525 case '?': 526 default: 527 /* getopt has already reported an error */ 528 return(CMD_OK); 529 } 530 } 531 argv += (optind - 1); 532 argc -= (optind - 1); 533 534 if (argc > 2) 535 return (CMD_ERROR); 536 537 for (i = 0; i < nitems(pnp_buses); i++) { 538 if (argc == 2 && strcmp(argv[1], pnp_buses[i].name) != 0) { 539 if (verbose) 540 printf("Skipping bus %s\n", pnp_buses[i].name); 541 continue; 542 } 543 if (verbose) 544 printf("Autoloading modules for %s\n", pnp_buses[i].name); 545 pnp_buses[i].load(pnp_buses[i].name); 546 match = 1; 547 } 548 if (match == 0) 549 printf("Unsupported bus %s\n", argv[1]); 550 551 return (CMD_OK); 552 } 553 554 /* 555 * File level interface, functions file_* 556 */ 557 static int 558 file_load(char *filename, vm_offset_t dest, struct preloaded_file **result) 559 { 560 static int last_file_format = 0; 561 struct preloaded_file *fp; 562 int error; 563 int i; 564 565 TSENTER2(filename); 566 dest = md_align(dest); 567 568 error = EFTYPE; 569 for (i = last_file_format, fp = NULL; 570 file_formats[i] && fp == NULL; i++) { 571 error = (file_formats[i]->l_load)(filename, dest, &fp); 572 if (error == 0) { 573 fp->f_loader = last_file_format = i; /* remember the loader */ 574 *result = fp; 575 break; 576 } else if (last_file_format == i && i != 0) { 577 /* Restart from the beginning */ 578 i = -1; 579 last_file_format = 0; 580 fp = NULL; 581 continue; 582 } 583 if (error == EFTYPE) 584 continue; /* Unknown to this handler? */ 585 if (error) { 586 snprintf(command_errbuf, sizeof(command_errbuf), 587 "can't load file '%s': %s", filename, strerror(error)); 588 break; 589 } 590 } 591 TSEXIT(); 592 return (error); 593 } 594 595 static int 596 file_load_dependencies(struct preloaded_file *base_file) 597 { 598 struct file_metadata *md; 599 struct preloaded_file *fp; 600 struct mod_depend *verinfo; 601 struct kernel_module *mp; 602 char *dmodname; 603 int error; 604 605 md = file_findmetadata(base_file, MODINFOMD_DEPLIST); 606 if (md == NULL) 607 return (0); 608 error = 0; 609 do { 610 verinfo = (struct mod_depend*)md->md_data; 611 dmodname = (char *)(verinfo + 1); 612 if (file_findmodule(NULL, dmodname, verinfo) == NULL) { 613 if (module_verbose > MODULE_VERBOSE_SILENT) 614 printf("loading required module '%s'\n", dmodname); 615 error = mod_load(dmodname, verinfo, 0, NULL); 616 if (error) 617 break; 618 /* 619 * If module loaded via kld name which isn't listed 620 * in the linker.hints file, we should check if it have 621 * required version. 622 */ 623 mp = file_findmodule(NULL, dmodname, verinfo); 624 if (mp == NULL) { 625 snprintf(command_errbuf, sizeof(command_errbuf), 626 "module '%s' exists but with wrong version", dmodname); 627 error = ENOENT; 628 break; 629 } 630 } 631 md = metadata_next(md, MODINFOMD_DEPLIST); 632 } while (md); 633 if (!error) 634 return (0); 635 /* Load failed; discard everything */ 636 while (base_file != NULL) { 637 fp = base_file; 638 base_file = base_file->f_next; 639 file_discard(fp); 640 } 641 return (error); 642 } 643 644 #ifdef LOADER_VERIEXEC_VECTX 645 #define VECTX_HANDLE(fd) vctx 646 #else 647 #define VECTX_HANDLE(fd) fd 648 #endif 649 650 651 /* 652 * We've been asked to load (fname) as (type), so just suck it in, 653 * no arguments or anything. 654 */ 655 struct preloaded_file * 656 file_loadraw(const char *fname, const char *type, int insert) 657 { 658 struct preloaded_file *fp; 659 char *name; 660 int fd, got; 661 vm_offset_t laddr; 662 #ifdef LOADER_VERIEXEC_VECTX 663 struct vectx *vctx; 664 int verror; 665 #endif 666 667 TSENTER2(fname); 668 /* We can't load first */ 669 if ((file_findfile(NULL, NULL)) == NULL) { 670 command_errmsg = "can't load file before kernel"; 671 TSEXIT(); 672 return(NULL); 673 } 674 675 /* locate the file on the load path */ 676 name = file_search(fname, NULL); 677 if (name == NULL) { 678 snprintf(command_errbuf, sizeof(command_errbuf), 679 "can't find '%s'", fname); 680 TSEXIT(); 681 return(NULL); 682 } 683 684 if ((fd = open(name, O_RDONLY)) < 0) { 685 snprintf(command_errbuf, sizeof(command_errbuf), 686 "can't open '%s': %s", name, strerror(errno)); 687 free(name); 688 TSEXIT(); 689 return(NULL); 690 } 691 692 #ifdef LOADER_VERIEXEC_VECTX 693 vctx = vectx_open(fd, name, 0L, NULL, &verror, __func__); 694 if (verror) { 695 sprintf(command_errbuf, "can't verify '%s': %s", 696 name, ve_error_get()); 697 free(name); 698 free(vctx); 699 close(fd); 700 TSEXIT(); 701 return(NULL); 702 } 703 #else 704 #ifdef LOADER_VERIEXEC 705 if (verify_file(fd, name, 0, VE_MUST, __func__) < 0) { 706 sprintf(command_errbuf, "can't verify '%s': %s", 707 name, ve_error_get()); 708 free(name); 709 close(fd); 710 TSEXIT(); 711 return(NULL); 712 } 713 #endif 714 #endif 715 716 loadaddr = md_align(loadaddr); 717 718 if (module_verbose > MODULE_VERBOSE_SILENT) 719 printf("%s ", name); 720 721 laddr = loadaddr; 722 for (;;) { 723 /* read in 4k chunks; size is not really important */ 724 got = archsw.arch_readin(VECTX_HANDLE(fd), laddr, 4096); 725 if (got == 0) /* end of file */ 726 break; 727 if (got < 0) { /* error */ 728 snprintf(command_errbuf, sizeof(command_errbuf), 729 "error reading '%s': %s", name, strerror(errno)); 730 free(name); 731 close(fd); 732 #ifdef LOADER_VERIEXEC_VECTX 733 free(vctx); 734 #endif 735 TSEXIT(); 736 return(NULL); 737 } 738 laddr += got; 739 } 740 741 if (module_verbose > MODULE_VERBOSE_SILENT) 742 printf("size=%#jx\n", (uintmax_t)(laddr - loadaddr)); 743 #ifdef LOADER_VERIEXEC_VECTX 744 verror = vectx_close(vctx, VE_MUST, __func__); 745 if (verror) { 746 free(name); 747 close(fd); 748 free(vctx); 749 TSEXIT(); 750 return(NULL); 751 } 752 #endif 753 754 /* Looks OK so far; create & populate control structure */ 755 fp = file_alloc(); 756 if (fp == NULL) { 757 snprintf(command_errbuf, sizeof (command_errbuf), 758 "no memory to load %s", name); 759 free(name); 760 close(fd); 761 TSEXIT(); 762 return (NULL); 763 } 764 fp->f_name = name; 765 fp->f_type = strdup(type); 766 fp->f_args = NULL; 767 fp->f_metadata = NULL; 768 fp->f_loader = -1; 769 fp->f_addr = loadaddr; 770 fp->f_size = laddr - loadaddr; 771 772 if (fp->f_type == NULL) { 773 snprintf(command_errbuf, sizeof (command_errbuf), 774 "no memory to load %s", name); 775 free(name); 776 close(fd); 777 TSEXIT(); 778 return (NULL); 779 } 780 /* recognise space consumption */ 781 loadaddr = laddr; 782 783 /* Add to the list of loaded files */ 784 if (insert != 0) 785 file_insert_tail(fp); 786 close(fd); 787 TSEXIT(); 788 return(fp); 789 } 790 791 /* 792 * Load the module (name), pass it (argc),(argv), add container file 793 * to the list of loaded files. 794 * If module is already loaded just assign new argc/argv. 795 */ 796 int 797 mod_load(char *modname, struct mod_depend *verinfo, int argc, char *argv[]) 798 { 799 struct kernel_module *mp; 800 int err; 801 char *filename; 802 803 TSENTER2(modname); 804 if (file_havepath(modname)) { 805 printf("Warning: mod_load() called instead of mod_loadkld() for module '%s'\n", modname); 806 TSEXIT(); 807 return (mod_loadkld(modname, argc, argv)); 808 } 809 /* see if module is already loaded */ 810 mp = file_findmodule(NULL, modname, verinfo); 811 if (mp) { 812 #ifdef moduleargs 813 free(mp->m_args); 814 mp->m_args = unargv(argc, argv); 815 #endif 816 snprintf(command_errbuf, sizeof(command_errbuf), 817 "warning: module '%s' already loaded", mp->m_name); 818 TSEXIT(); 819 return (0); 820 } 821 /* locate file with the module on the search path */ 822 filename = mod_searchmodule(modname, verinfo); 823 if (filename == NULL) { 824 snprintf(command_errbuf, sizeof(command_errbuf), 825 "can't find '%s'", modname); 826 TSEXIT(); 827 return (ENOENT); 828 } 829 err = mod_loadkld(filename, argc, argv); 830 free(filename); 831 TSEXIT(); 832 return (err); 833 } 834 835 /* 836 * Load specified KLD. If path is omitted, then try to locate it via 837 * search path. 838 */ 839 int 840 mod_loadkld(const char *kldname, int argc, char *argv[]) 841 { 842 struct preloaded_file *fp; 843 int err; 844 char *filename; 845 vm_offset_t loadaddr_saved; 846 847 TSENTER2(kldname); 848 /* 849 * Get fully qualified KLD name 850 */ 851 filename = file_search(kldname, kld_ext_list); 852 if (filename == NULL) { 853 snprintf(command_errbuf, sizeof(command_errbuf), 854 "can't find '%s'", kldname); 855 TSEXIT(); 856 return (ENOENT); 857 } 858 /* 859 * Check if KLD already loaded 860 */ 861 fp = file_findfile(filename, NULL); 862 if (fp) { 863 snprintf(command_errbuf, sizeof(command_errbuf), 864 "warning: KLD '%s' already loaded", filename); 865 free(filename); 866 TSEXIT(); 867 return (0); 868 } 869 870 do { 871 err = file_load(filename, loadaddr, &fp); 872 if (err) 873 break; 874 fp->f_args = unargv(argc, argv); 875 loadaddr_saved = loadaddr; 876 loadaddr = fp->f_addr + fp->f_size; 877 file_insert_tail(fp); /* Add to the list of loaded files */ 878 if (file_load_dependencies(fp) != 0) { 879 err = ENOENT; 880 file_remove_tail(fp); 881 loadaddr = loadaddr_saved; 882 fp = NULL; 883 break; 884 } 885 } while(0); 886 if (err == EFTYPE) { 887 snprintf(command_errbuf, sizeof(command_errbuf), 888 "don't know how to load module '%s'", filename); 889 } 890 if (err) 891 file_discard(fp); 892 free(filename); 893 TSEXIT(); 894 return (err); 895 } 896 897 /* 898 * Find a file matching (name) and (type). 899 * NULL may be passed as a wildcard to either. 900 */ 901 struct preloaded_file * 902 file_findfile(const char *name, const char *type) 903 { 904 struct preloaded_file *fp; 905 906 for (fp = preloaded_files; fp != NULL; fp = fp->f_next) { 907 if (((name == NULL) || !strcmp(name, fp->f_name)) && 908 ((type == NULL) || !strcmp(type, fp->f_type))) 909 break; 910 } 911 return (fp); 912 } 913 914 /* 915 * Find a module matching (name) inside of given file. 916 * NULL may be passed as a wildcard. 917 */ 918 static struct kernel_module * 919 file_findmodule(struct preloaded_file *fp, char *modname, 920 struct mod_depend *verinfo) 921 { 922 struct kernel_module *mp, *best; 923 int bestver, mver; 924 925 if (fp == NULL) { 926 for (fp = preloaded_files; fp; fp = fp->f_next) { 927 mp = file_findmodule(fp, modname, verinfo); 928 if (mp) 929 return (mp); 930 } 931 return (NULL); 932 } 933 best = NULL; 934 bestver = 0; 935 for (mp = fp->f_modules; mp; mp = mp->m_next) { 936 if (strcmp(modname, mp->m_name) == 0) { 937 if (verinfo == NULL) 938 return (mp); 939 mver = mp->m_version; 940 if (mver == verinfo->md_ver_preferred) 941 return (mp); 942 if (mver >= verinfo->md_ver_minimum && 943 mver <= verinfo->md_ver_maximum && 944 mver > bestver) { 945 best = mp; 946 bestver = mver; 947 } 948 } 949 } 950 return (best); 951 } 952 /* 953 * Make a copy of (size) bytes of data from (p), and associate them as 954 * metadata of (type) to the module (mp). 955 */ 956 void 957 file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p) 958 { 959 struct file_metadata *md; 960 961 md = malloc(sizeof(struct file_metadata) - sizeof(md->md_data) + size); 962 if (md != NULL) { 963 md->md_size = size; 964 md->md_type = type; 965 bcopy(p, md->md_data, size); 966 md->md_next = fp->f_metadata; 967 } 968 fp->f_metadata = md; 969 } 970 971 /* 972 * Find a metadata object of (type) associated with the file (fp) 973 */ 974 struct file_metadata * 975 file_findmetadata(struct preloaded_file *fp, int type) 976 { 977 struct file_metadata *md; 978 979 for (md = fp->f_metadata; md != NULL; md = md->md_next) 980 if (md->md_type == type) 981 break; 982 return(md); 983 } 984 985 /* 986 * Remove all metadata from the file. 987 */ 988 void 989 file_removemetadata(struct preloaded_file *fp) 990 { 991 struct file_metadata *md, *next; 992 993 for (md = fp->f_metadata; md != NULL; md = next) 994 { 995 next = md->md_next; 996 free(md); 997 } 998 fp->f_metadata = NULL; 999 } 1000 1001 /* 1002 * Add a buffer to the list of preloaded "files". 1003 */ 1004 int 1005 file_addbuf(const char *name, const char *type, size_t len, void *buf) 1006 { 1007 struct preloaded_file *fp; 1008 vm_offset_t dest; 1009 1010 /* We can't load first */ 1011 if ((file_findfile(NULL, NULL)) == NULL) { 1012 command_errmsg = "can't load file before kernel"; 1013 return (-1); 1014 } 1015 1016 /* Figure out where to load the data. */ 1017 dest = md_align(loadaddr); 1018 1019 /* Create & populate control structure */ 1020 fp = file_alloc(); 1021 if (fp == NULL) { 1022 snprintf(command_errbuf, sizeof (command_errbuf), 1023 "no memory to load %s", name); 1024 return (-1); 1025 } 1026 fp->f_name = strdup(name); 1027 fp->f_type = strdup(type); 1028 fp->f_args = NULL; 1029 fp->f_metadata = NULL; 1030 fp->f_loader = -1; 1031 fp->f_addr = dest; 1032 fp->f_size = len; 1033 if ((fp->f_name == NULL) || (fp->f_type == NULL)) { 1034 snprintf(command_errbuf, sizeof (command_errbuf), 1035 "no memory to load %s", name); 1036 free(fp->f_name); 1037 free(fp->f_type); 1038 return (-1); 1039 } 1040 1041 /* Copy the data in. */ 1042 archsw.arch_copyin(buf, fp->f_addr, len); 1043 loadaddr = fp->f_addr + len; 1044 1045 /* Add to the list of loaded files */ 1046 file_insert_tail(fp); 1047 return(0); 1048 } 1049 1050 static struct file_metadata * 1051 metadata_next(struct file_metadata *md, int type) 1052 { 1053 1054 if (md == NULL) 1055 return (NULL); 1056 while((md = md->md_next) != NULL) 1057 if (md->md_type == type) 1058 break; 1059 return (md); 1060 } 1061 1062 static char *emptyextlist[] = { "", NULL }; 1063 1064 /* 1065 * Check if the given file is in place and return full path to it. 1066 */ 1067 static char * 1068 file_lookup(const char *path, const char *name, int namelen, char **extlist) 1069 { 1070 struct stat st; 1071 char *result, *cp, **cpp; 1072 int pathlen, extlen, len; 1073 1074 pathlen = strlen(path); 1075 extlen = 0; 1076 if (extlist == NULL) 1077 extlist = emptyextlist; 1078 for (cpp = extlist; *cpp; cpp++) { 1079 len = strlen(*cpp); 1080 if (len > extlen) 1081 extlen = len; 1082 } 1083 result = malloc(pathlen + namelen + extlen + 2); 1084 if (result == NULL) 1085 return (NULL); 1086 bcopy(path, result, pathlen); 1087 if (pathlen > 0 && result[pathlen - 1] != '/') 1088 result[pathlen++] = '/'; 1089 cp = result + pathlen; 1090 bcopy(name, cp, namelen); 1091 cp += namelen; 1092 for (cpp = extlist; *cpp; cpp++) { 1093 strcpy(cp, *cpp); 1094 if (stat(result, &st) == 0 && S_ISREG(st.st_mode)) 1095 return result; 1096 } 1097 free(result); 1098 return NULL; 1099 } 1100 1101 /* 1102 * Check if file name have any qualifiers 1103 */ 1104 static int 1105 file_havepath(const char *name) 1106 { 1107 const char *cp; 1108 1109 archsw.arch_getdev(NULL, name, &cp); 1110 return (cp != name || strchr(name, '/') != NULL); 1111 } 1112 1113 /* 1114 * Attempt to find the file (name) on the module searchpath. 1115 * If (name) is qualified in any way, we simply check it and 1116 * return it or NULL. If it is not qualified, then we attempt 1117 * to construct a path using entries in the environment variable 1118 * module_path. 1119 * 1120 * The path we return a pointer to need never be freed, as we manage 1121 * it internally. 1122 */ 1123 static char * 1124 file_search(const char *name, char **extlist) 1125 { 1126 struct moduledir *mdp; 1127 struct stat sb; 1128 char *result; 1129 int namelen; 1130 1131 /* Don't look for nothing */ 1132 if (name == NULL) 1133 return(NULL); 1134 1135 if (*name == 0) 1136 return(strdup(name)); 1137 1138 if (file_havepath(name)) { 1139 /* Qualified, so just see if it exists */ 1140 if (stat(name, &sb) == 0) 1141 return(strdup(name)); 1142 return(NULL); 1143 } 1144 moduledir_rebuild(); 1145 result = NULL; 1146 namelen = strlen(name); 1147 STAILQ_FOREACH(mdp, &moduledir_list, d_link) { 1148 result = file_lookup(mdp->d_path, name, namelen, extlist); 1149 if (result) 1150 break; 1151 } 1152 return(result); 1153 } 1154 1155 #define INT_ALIGN(base, ptr) ptr = \ 1156 (base) + roundup2((ptr) - (base), sizeof(int)) 1157 1158 static char * 1159 mod_search_hints(struct moduledir *mdp, const char *modname, 1160 struct mod_depend *verinfo) 1161 { 1162 u_char *cp, *recptr, *bufend, *best; 1163 char *result; 1164 int *intp, bestver, blen, clen, found, ival, modnamelen, reclen; 1165 1166 moduledir_readhints(mdp); 1167 modnamelen = strlen(modname); 1168 found = 0; 1169 result = NULL; 1170 bestver = 0; 1171 if (mdp->d_hints == NULL) 1172 goto bad; 1173 recptr = mdp->d_hints; 1174 bufend = recptr + mdp->d_hintsz; 1175 clen = blen = 0; 1176 best = cp = NULL; 1177 while (recptr < bufend && !found) { 1178 intp = (int*)recptr; 1179 reclen = *intp++; 1180 ival = *intp++; 1181 cp = (u_char*)intp; 1182 switch (ival) { 1183 case MDT_VERSION: 1184 clen = *cp++; 1185 if (clen != modnamelen || bcmp(cp, modname, clen) != 0) 1186 break; 1187 cp += clen; 1188 INT_ALIGN(mdp->d_hints, cp); 1189 ival = *(int*)cp; 1190 cp += sizeof(int); 1191 clen = *cp++; 1192 if (verinfo == NULL || ival == verinfo->md_ver_preferred) { 1193 found = 1; 1194 break; 1195 } 1196 if (ival >= verinfo->md_ver_minimum && 1197 ival <= verinfo->md_ver_maximum && 1198 ival > bestver) { 1199 bestver = ival; 1200 best = cp; 1201 blen = clen; 1202 } 1203 break; 1204 default: 1205 break; 1206 } 1207 recptr += reclen + sizeof(int); 1208 } 1209 /* 1210 * Finally check if KLD is in the place 1211 */ 1212 if (found) 1213 result = file_lookup(mdp->d_path, (const char *)cp, clen, NULL); 1214 else if (best) 1215 result = file_lookup(mdp->d_path, (const char *)best, blen, NULL); 1216 bad: 1217 /* 1218 * If nothing found or hints is absent - fallback to the old way 1219 * by using "kldname[.ko]" as module name. 1220 */ 1221 if (!found && !bestver && result == NULL) 1222 result = file_lookup(mdp->d_path, modname, modnamelen, kld_ext_list); 1223 return result; 1224 } 1225 1226 static int 1227 getint(void **ptr) 1228 { 1229 int *p = *ptr; 1230 int rv; 1231 1232 p = (int *)roundup2((intptr_t)p, sizeof(int)); 1233 rv = *p++; 1234 *ptr = p; 1235 return rv; 1236 } 1237 1238 static void 1239 getstr(void **ptr, char *val) 1240 { 1241 int *p = *ptr; 1242 char *c = (char *)p; 1243 int len = *(uint8_t *)c; 1244 1245 memcpy(val, c + 1, len); 1246 val[len] = 0; 1247 c += len + 1; 1248 *ptr = (void *)c; 1249 } 1250 1251 static int 1252 pnpval_as_int(const char *val, const char *pnpinfo) 1253 { 1254 int rv; 1255 char key[256]; 1256 char *cp; 1257 1258 if (pnpinfo == NULL) 1259 return -1; 1260 1261 cp = strchr(val, ';'); 1262 key[0] = ' '; 1263 if (cp == NULL) 1264 strlcpy(key + 1, val, sizeof(key) - 1); 1265 else { 1266 memcpy(key + 1, val, cp - val); 1267 key[cp - val + 1] = '\0'; 1268 } 1269 strlcat(key, "=", sizeof(key)); 1270 if (strncmp(key + 1, pnpinfo, strlen(key + 1)) == 0) 1271 rv = strtol(pnpinfo + strlen(key + 1), NULL, 0); 1272 else { 1273 cp = strstr(pnpinfo, key); 1274 if (cp == NULL) 1275 rv = -1; 1276 else 1277 rv = strtol(cp + strlen(key), NULL, 0); 1278 } 1279 return rv; 1280 } 1281 1282 static void 1283 quoted_strcpy(char *dst, const char *src) 1284 { 1285 char q = ' '; 1286 1287 if (*src == '\'' || *src == '"') 1288 q = *src++; 1289 while (*src && *src != q) 1290 *dst++ = *src++; // XXX backtick quoting 1291 *dst++ = '\0'; 1292 // XXX overflow 1293 } 1294 1295 static char * 1296 pnpval_as_str(const char *val, const char *pnpinfo) 1297 { 1298 static char retval[256]; 1299 char key[256]; 1300 char *cp; 1301 1302 if (pnpinfo == NULL) { 1303 *retval = '\0'; 1304 return retval; 1305 } 1306 1307 cp = strchr(val, ';'); 1308 key[0] = ' '; 1309 if (cp == NULL) 1310 strlcpy(key + 1, val, sizeof(key) - 1); 1311 else { 1312 memcpy(key + 1, val, cp - val); 1313 key[cp - val + 1] = '\0'; 1314 } 1315 strlcat(key, "=", sizeof(key)); 1316 if (strncmp(key + 1, pnpinfo, strlen(key + 1)) == 0) 1317 quoted_strcpy(retval, pnpinfo + strlen(key + 1)); 1318 else { 1319 cp = strstr(pnpinfo, key); 1320 if (cp == NULL) 1321 strcpy(retval, "MISSING"); 1322 else 1323 quoted_strcpy(retval, cp + strlen(key)); 1324 } 1325 return retval; 1326 } 1327 1328 static char * 1329 devmatch_search_hints(struct moduledir *mdp, const char *bus, const char *dev, const char *pnpinfo) 1330 { 1331 char val1[256], val2[256]; 1332 int ival, len, ents, i, notme, mask, bit, v, found; 1333 void *ptr, *walker, *hints_end; 1334 char *lastmod = NULL, *cp, *s; 1335 1336 moduledir_readhints(mdp); 1337 found = 0; 1338 if (mdp->d_hints == NULL) 1339 goto bad; 1340 walker = mdp->d_hints; 1341 hints_end = walker + mdp->d_hintsz; 1342 while (walker < hints_end && !found) { 1343 len = getint(&walker); 1344 ival = getint(&walker); 1345 ptr = walker; 1346 switch (ival) { 1347 case MDT_VERSION: 1348 getstr(&ptr, val1); 1349 ival = getint(&ptr); 1350 getstr(&ptr, val2); 1351 if (pnp_dump_flag || pnp_verbose_flag) 1352 printf("Version: if %s.%d kmod %s\n", val1, ival, val2); 1353 break; 1354 case MDT_MODULE: 1355 getstr(&ptr, val1); 1356 getstr(&ptr, val2); 1357 if (lastmod) 1358 free(lastmod); 1359 lastmod = strdup(val2); 1360 if (pnp_dump_flag || pnp_verbose_flag) 1361 printf("module %s in %s\n", val1, val1); 1362 break; 1363 case MDT_PNP_INFO: 1364 if (!pnp_dump_flag && !pnp_unbound_flag && lastmod && strcmp(lastmod, "kernel") == 0) 1365 break; 1366 getstr(&ptr, val1); 1367 getstr(&ptr, val2); 1368 ents = getint(&ptr); 1369 if (pnp_dump_flag || pnp_verbose_flag) 1370 printf("PNP info for bus %s format %s %d entries (%s)\n", 1371 val1, val2, ents, lastmod); 1372 if (strcmp(val1, "usb") == 0) { 1373 if (pnp_verbose_flag) 1374 printf("Treating usb as uhub -- bug in source table still?\n"); 1375 strcpy(val1, "uhub"); 1376 } 1377 if (bus && strcmp(val1, bus) != 0) { 1378 if (pnp_verbose_flag) 1379 printf("Skipped because table for bus %s, looking for %s\n", 1380 val1, bus); 1381 break; 1382 } 1383 for (i = 0; i < ents; i++) { 1384 if (pnp_verbose_flag) 1385 printf("---------- Entry %d ----------\n", i); 1386 if (pnp_dump_flag) 1387 printf(" "); 1388 cp = val2; 1389 notme = 0; 1390 mask = -1; 1391 bit = -1; 1392 do { 1393 switch (*cp) { 1394 /* All integer fields */ 1395 case 'I': 1396 case 'J': 1397 case 'G': 1398 case 'L': 1399 case 'M': 1400 ival = getint(&ptr); 1401 if (pnp_dump_flag) { 1402 printf("%#x:", ival); 1403 break; 1404 } 1405 if (bit >= 0 && ((1 << bit) & mask) == 0) 1406 break; 1407 v = pnpval_as_int(cp + 2, pnpinfo); 1408 if (pnp_verbose_flag) 1409 printf("Matching %s (%c) table=%#x tomatch=%#x\n", 1410 cp + 2, *cp, v, ival); 1411 switch (*cp) { 1412 case 'J': 1413 if (ival == -1) 1414 break; 1415 /*FALLTHROUGH*/ 1416 case 'I': 1417 if (v != ival) 1418 notme++; 1419 break; 1420 case 'G': 1421 if (v < ival) 1422 notme++; 1423 break; 1424 case 'L': 1425 if (v > ival) 1426 notme++; 1427 break; 1428 case 'M': 1429 mask = ival; 1430 break; 1431 } 1432 break; 1433 /* String fields */ 1434 case 'D': 1435 case 'Z': 1436 getstr(&ptr, val1); 1437 if (pnp_dump_flag) { 1438 printf("'%s':", val1); 1439 break; 1440 } 1441 if (*cp == 'D') 1442 break; 1443 s = pnpval_as_str(cp + 2, pnpinfo); 1444 if (strcmp(s, val1) != 0) 1445 notme++; 1446 break; 1447 /* Key override fields, required to be last in the string */ 1448 case 'T': 1449 /* 1450 * This is imperfect and only does one key and will be redone 1451 * to be more general for multiple keys. Currently, nothing 1452 * does that. 1453 */ 1454 if (pnp_dump_flag) /* No per-row data stored */ 1455 break; 1456 if (cp[strlen(cp) - 1] == ';') /* Skip required ; at end */ 1457 cp[strlen(cp) - 1] = '\0'; /* in case it's not there */ 1458 if ((s = strstr(pnpinfo, cp + 2)) == NULL) 1459 notme++; 1460 else if (s > pnpinfo && s[-1] != ' ') 1461 notme++; 1462 break; 1463 default: 1464 printf("Unknown field type %c\n:", *cp); 1465 break; 1466 } 1467 bit++; 1468 cp = strchr(cp, ';'); 1469 if (cp) 1470 cp++; 1471 } while (cp && *cp); 1472 if (pnp_dump_flag) 1473 printf("\n"); 1474 else if (!notme) { 1475 if (!pnp_unbound_flag) { 1476 if (pnp_verbose_flag) 1477 printf("Matches --- %s ---\n", lastmod); 1478 } 1479 found++; 1480 } 1481 } 1482 break; 1483 default: 1484 break; 1485 } 1486 walker = (void *)(len - sizeof(int) + (intptr_t)walker); 1487 } 1488 if (pnp_unbound_flag && found == 0 && *pnpinfo) { 1489 if (pnp_verbose_flag) 1490 printf("------------------------- "); 1491 printf("%s on %s pnpinfo %s", *dev ? dev : "unattached", bus, pnpinfo); 1492 if (pnp_verbose_flag) 1493 printf(" -------------------------"); 1494 printf("\n"); 1495 } 1496 if (found != 0) 1497 return (lastmod); 1498 free(lastmod); 1499 1500 bad: 1501 return (NULL); 1502 } 1503 1504 /* 1505 * Attempt to locate the file containing the module (name) 1506 */ 1507 static char * 1508 mod_searchmodule(char *name, struct mod_depend *verinfo) 1509 { 1510 struct moduledir *mdp; 1511 char *result; 1512 1513 moduledir_rebuild(); 1514 /* 1515 * Now we ready to lookup module in the given directories 1516 */ 1517 result = NULL; 1518 STAILQ_FOREACH(mdp, &moduledir_list, d_link) { 1519 result = mod_search_hints(mdp, name, verinfo); 1520 if (result) 1521 break; 1522 } 1523 1524 return(result); 1525 } 1526 1527 static char * 1528 mod_searchmodule_pnpinfo(const char *bus, const char *pnpinfo) 1529 { 1530 struct moduledir *mdp; 1531 char *result; 1532 1533 moduledir_rebuild(); 1534 /* 1535 * Now we ready to lookup module in the given directories 1536 */ 1537 result = NULL; 1538 STAILQ_FOREACH(mdp, &moduledir_list, d_link) { 1539 result = devmatch_search_hints(mdp, bus, NULL, pnpinfo); 1540 if (result) 1541 break; 1542 } 1543 1544 return(result); 1545 } 1546 1547 int 1548 file_addmodule(struct preloaded_file *fp, char *modname, int version, 1549 struct kernel_module **newmp) 1550 { 1551 struct kernel_module *mp; 1552 struct mod_depend mdepend; 1553 1554 bzero(&mdepend, sizeof(mdepend)); 1555 mdepend.md_ver_preferred = version; 1556 mp = file_findmodule(fp, modname, &mdepend); 1557 if (mp) 1558 return (EEXIST); 1559 mp = calloc(1, sizeof(struct kernel_module)); 1560 if (mp == NULL) 1561 return (ENOMEM); 1562 mp->m_name = strdup(modname); 1563 if (mp->m_name == NULL) { 1564 free(mp); 1565 return (ENOMEM); 1566 } 1567 mp->m_version = version; 1568 mp->m_fp = fp; 1569 mp->m_next = fp->f_modules; 1570 fp->f_modules = mp; 1571 if (newmp) 1572 *newmp = mp; 1573 return (0); 1574 } 1575 1576 /* 1577 * Throw a file away 1578 */ 1579 void 1580 file_discard(struct preloaded_file *fp) 1581 { 1582 struct file_metadata *md, *md1; 1583 struct kernel_module *mp, *mp1; 1584 if (fp == NULL) 1585 return; 1586 md = fp->f_metadata; 1587 while (md) { 1588 md1 = md; 1589 md = md->md_next; 1590 free(md1); 1591 } 1592 mp = fp->f_modules; 1593 while (mp) { 1594 free(mp->m_name); 1595 mp1 = mp; 1596 mp = mp->m_next; 1597 free(mp1); 1598 } 1599 free(fp->f_name); 1600 free(fp->f_type); 1601 free(fp->f_args); 1602 free(fp); 1603 } 1604 1605 /* 1606 * Allocate a new file; must be used instead of malloc() 1607 * to ensure safe initialisation. 1608 */ 1609 struct preloaded_file * 1610 file_alloc(void) 1611 { 1612 1613 return (calloc(1, sizeof(struct preloaded_file))); 1614 } 1615 1616 /* 1617 * Add a module to the chain 1618 */ 1619 static void 1620 file_insert_tail(struct preloaded_file *fp) 1621 { 1622 struct preloaded_file *cm; 1623 1624 /* Append to list of loaded file */ 1625 fp->f_next = NULL; 1626 if (preloaded_files == NULL) { 1627 preloaded_files = fp; 1628 } else { 1629 for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next) 1630 ; 1631 cm->f_next = fp; 1632 } 1633 } 1634 1635 /* 1636 * Remove module from the chain 1637 */ 1638 static void 1639 file_remove_impl(struct preloaded_file *fp, bool keep_tail) 1640 { 1641 struct preloaded_file *cm, *next; 1642 1643 if (preloaded_files == NULL) 1644 return; 1645 1646 if (keep_tail) 1647 next = fp->f_next; 1648 else 1649 next = NULL; 1650 1651 if (preloaded_files == fp) { 1652 preloaded_files = next; 1653 return; 1654 } 1655 1656 for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next) { 1657 if (cm->f_next == fp) { 1658 cm->f_next = next; 1659 return; 1660 } 1661 } 1662 } 1663 1664 static void 1665 file_remove(struct preloaded_file *fp) 1666 { 1667 1668 file_remove_impl(fp, true); 1669 } 1670 1671 static void 1672 file_remove_tail(struct preloaded_file *fp) 1673 { 1674 1675 file_remove_impl(fp, false); 1676 } 1677 1678 static char * 1679 moduledir_fullpath(struct moduledir *mdp, const char *fname) 1680 { 1681 char *cp; 1682 1683 cp = malloc(strlen(mdp->d_path) + strlen(fname) + 2); 1684 if (cp == NULL) 1685 return NULL; 1686 strcpy(cp, mdp->d_path); 1687 strcat(cp, "/"); 1688 strcat(cp, fname); 1689 return (cp); 1690 } 1691 1692 /* 1693 * Read linker.hints file into memory performing some sanity checks. 1694 */ 1695 static void 1696 moduledir_readhints(struct moduledir *mdp) 1697 { 1698 struct stat st; 1699 char *path; 1700 int fd, size, version; 1701 1702 if (mdp->d_hints != NULL || (mdp->d_flags & MDIR_NOHINTS)) 1703 return; 1704 path = moduledir_fullpath(mdp, "linker.hints"); 1705 if (stat(path, &st) != 0 || 1706 st.st_size < (ssize_t)(sizeof(version) + sizeof(int)) || 1707 st.st_size > LINKER_HINTS_MAX || (fd = open(path, O_RDONLY)) < 0) { 1708 free(path); 1709 mdp->d_flags |= MDIR_NOHINTS; 1710 return; 1711 } 1712 free(path); 1713 size = read(fd, &version, sizeof(version)); 1714 if (size != sizeof(version) || version != LINKER_HINTS_VERSION) 1715 goto bad; 1716 size = st.st_size - size; 1717 mdp->d_hints = malloc(size); 1718 if (mdp->d_hints == NULL) 1719 goto bad; 1720 if (read(fd, mdp->d_hints, size) != size) 1721 goto bad; 1722 mdp->d_hintsz = size; 1723 close(fd); 1724 return; 1725 bad: 1726 close(fd); 1727 free(mdp->d_hints); 1728 mdp->d_hints = NULL; 1729 mdp->d_flags |= MDIR_NOHINTS; 1730 return; 1731 } 1732 1733 /* 1734 * Extract directories from the ';' separated list, remove duplicates. 1735 */ 1736 static void 1737 moduledir_rebuild(void) 1738 { 1739 struct moduledir *mdp, *mtmp; 1740 const char *path, *cp, *ep; 1741 size_t cplen; 1742 1743 path = getenv("module_path"); 1744 if (path == NULL) 1745 path = default_searchpath; 1746 /* 1747 * Rebuild list of module directories if it changed 1748 */ 1749 STAILQ_FOREACH(mdp, &moduledir_list, d_link) 1750 mdp->d_flags |= MDIR_REMOVED; 1751 1752 for (ep = path; *ep != 0; ep++) { 1753 cp = ep; 1754 for (; *ep != 0 && *ep != ';'; ep++) 1755 ; 1756 /* 1757 * Ignore trailing slashes 1758 */ 1759 for (cplen = ep - cp; cplen > 1 && cp[cplen - 1] == '/'; cplen--) 1760 ; 1761 STAILQ_FOREACH(mdp, &moduledir_list, d_link) { 1762 if (strlen(mdp->d_path) != cplen || bcmp(cp, mdp->d_path, cplen) != 0) 1763 continue; 1764 mdp->d_flags &= ~MDIR_REMOVED; 1765 break; 1766 } 1767 if (mdp == NULL) { 1768 mdp = malloc(sizeof(*mdp) + cplen + 1); 1769 if (mdp == NULL) 1770 return; 1771 mdp->d_path = (char*)(mdp + 1); 1772 bcopy(cp, mdp->d_path, cplen); 1773 mdp->d_path[cplen] = 0; 1774 mdp->d_hints = NULL; 1775 mdp->d_flags = 0; 1776 STAILQ_INSERT_TAIL(&moduledir_list, mdp, d_link); 1777 } 1778 if (*ep == 0) 1779 break; 1780 } 1781 /* 1782 * Delete unused directories if any 1783 */ 1784 mdp = STAILQ_FIRST(&moduledir_list); 1785 while (mdp) { 1786 if ((mdp->d_flags & MDIR_REMOVED) == 0) { 1787 mdp = STAILQ_NEXT(mdp, d_link); 1788 } else { 1789 free(mdp->d_hints); 1790 mtmp = mdp; 1791 mdp = STAILQ_NEXT(mdp, d_link); 1792 STAILQ_REMOVE(&moduledir_list, mtmp, moduledir, d_link); 1793 free(mtmp); 1794 } 1795 } 1796 return; 1797 } 1798