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 #include <sys/cdefs.h> 28 29 /* 30 * file/module function dispatcher, support, etc. 31 */ 32 33 #include <stand.h> 34 #include <string.h> 35 #include <sys/param.h> 36 #include <sys/linker.h> 37 #include <sys/module.h> 38 #include <sys/queue.h> 39 #include <sys/stdint.h> 40 #include <sys/tem_impl.h> 41 #include <sys/font.h> 42 #include <sys/sha1.h> 43 #include <libcrypto.h> 44 45 #include "bootstrap.h" 46 47 #if defined(EFI) 48 #define PTOV(pa) ((void *)pa) 49 #else 50 #include "../i386/btx/lib/btxv86.h" 51 #endif 52 53 #define MDIR_REMOVED 0x0001 54 #define MDIR_NOHINTS 0x0002 55 56 struct moduledir { 57 char *d_path; /* path of modules directory */ 58 uchar_t *d_hints; /* content of linker.hints file */ 59 int d_hintsz; /* size of hints data */ 60 int d_flags; 61 STAILQ_ENTRY(moduledir) d_link; 62 }; 63 64 static int file_load(char *, vm_offset_t, struct preloaded_file **); 65 static int file_load_dependencies(struct preloaded_file *); 66 static char *file_search(const char *, const char **); 67 static struct kernel_module *file_findmodule(struct preloaded_file *, char *, 68 struct mod_depend *); 69 static int file_havepath(const char *); 70 static char *mod_searchmodule(char *, struct mod_depend *); 71 static void file_insert_tail(struct preloaded_file *); 72 static void file_remove(struct preloaded_file *); 73 struct file_metadata *metadata_next(struct file_metadata *, int); 74 static void moduledir_readhints(struct moduledir *); 75 static void moduledir_rebuild(void); 76 77 /* load address should be tweaked by first module loaded (kernel) */ 78 static vm_offset_t loadaddr = 0; 79 80 #if defined(LOADER_FDT_SUPPORT) 81 static const char *default_searchpath = "/boot/kernel;/boot/modules;/boot/dtb"; 82 #else 83 static const char *default_searchpath = "/platform/i86pc"; 84 #endif 85 86 static STAILQ_HEAD(, moduledir) moduledir_list = 87 STAILQ_HEAD_INITIALIZER(moduledir_list); 88 89 struct preloaded_file *preloaded_files = NULL; 90 91 static const char *kld_ext_list[] = { 92 ".ko", 93 "", 94 ".debug", 95 NULL 96 }; 97 98 99 /* 100 * load an object, either a disk file or code module. 101 * 102 * To load a file, the syntax is: 103 * 104 * load -t <type> <path> 105 * 106 * code modules are loaded as: 107 * 108 * load <path> <options> 109 */ 110 111 COMMAND_SET(load, "load", "load a kernel or module", command_load); 112 113 static int 114 command_load(int argc, char *argv[]) 115 { 116 char *typestr; 117 int dofile, dokld, ch, error; 118 119 dokld = dofile = 0; 120 optind = 1; 121 optreset = 1; 122 typestr = NULL; 123 if (argc == 1) { 124 command_errmsg = "no filename specified"; 125 return (CMD_CRIT); 126 } 127 while ((ch = getopt(argc, argv, "kt:")) != -1) { 128 switch (ch) { 129 case 'k': 130 dokld = 1; 131 break; 132 case 't': 133 typestr = optarg; 134 dofile = 1; 135 break; 136 case '?': 137 default: 138 /* getopt has already reported an error */ 139 return (CMD_OK); 140 } 141 } 142 argv += (optind - 1); 143 argc -= (optind - 1); 144 145 printf("Loading %s...\n", argv[1]); 146 /* 147 * Request to load a raw file? 148 */ 149 if (dofile) { 150 struct preloaded_file *fp; 151 152 if ((typestr == NULL) || (*typestr == 0)) { 153 command_errmsg = "invalid load type"; 154 return (CMD_CRIT); 155 } 156 157 if (file_findfile(argv[1], typestr) != NULL) { 158 (void) snprintf(command_errbuf, sizeof (command_errbuf), 159 "warning: file '%s' already loaded", argv[1]); 160 return (CMD_WARN); 161 } 162 163 fp = file_loadraw(argv[1], typestr, argc - 2, argv + 2, 1); 164 if (fp != NULL) 165 return (CMD_OK); 166 167 /* Failing to load mfs_root is never going to end well! */ 168 if (strcmp("mfs_root", typestr) == 0) 169 return (CMD_FATAL); 170 171 return (CMD_ERROR); 172 } 173 /* 174 * Do we have explicit KLD load ? 175 */ 176 if (dokld || file_havepath(argv[1])) { 177 error = mod_loadkld(argv[1], argc - 2, argv + 2); 178 if (error == EEXIST) { 179 (void) snprintf(command_errbuf, sizeof (command_errbuf), 180 "warning: KLD '%s' already loaded", argv[1]); 181 return (CMD_WARN); 182 } 183 184 return (error == 0 ? CMD_OK : CMD_CRIT); 185 } 186 /* 187 * Looks like a request for a module. 188 */ 189 error = mod_load(argv[1], NULL, argc - 2, argv + 2); 190 if (error == EEXIST) { 191 (void) snprintf(command_errbuf, sizeof (command_errbuf), 192 "warning: module '%s' already loaded", argv[1]); 193 return (CMD_WARN); 194 } 195 196 return (error == 0 ? CMD_OK : CMD_CRIT); 197 } 198 199 void 200 unload(void) 201 { 202 struct preloaded_file *fp; 203 204 while (preloaded_files != NULL) { 205 fp = preloaded_files; 206 preloaded_files = preloaded_files->f_next; 207 file_discard(fp); 208 } 209 loadaddr = 0; 210 (void) unsetenv("kernelname"); 211 } 212 213 COMMAND_SET(unload, "unload", "unload all modules", command_unload); 214 215 static int 216 command_unload(int argc __unused, char *argv[] __unused) 217 { 218 unload(); 219 return (CMD_OK); 220 } 221 222 COMMAND_SET(lsmod, "lsmod", "list loaded modules", command_lsmod); 223 224 static int 225 command_lsmod(int argc, char *argv[]) 226 { 227 struct preloaded_file *fp; 228 struct kernel_module *mp; 229 struct file_metadata *md; 230 char lbuf[80]; 231 int ch, verbose, hash, ret = 0; 232 233 verbose = 0; 234 hash = 0; 235 optind = 1; 236 optreset = 1; 237 while ((ch = getopt(argc, argv, "vs")) != -1) { 238 switch (ch) { 239 case 'v': 240 verbose = 1; 241 break; 242 case 's': 243 hash = 1; 244 break; 245 case '?': 246 default: 247 /* getopt has already reported an error */ 248 return (CMD_OK); 249 } 250 } 251 252 pager_open(); 253 for (fp = preloaded_files; fp; fp = fp->f_next) { 254 (void) snprintf(lbuf, sizeof (lbuf), " %p: ", 255 (void *) fp->f_addr); 256 (void) pager_output(lbuf); 257 (void) pager_output(fp->f_name); 258 (void) snprintf(lbuf, sizeof (lbuf), " (%s, 0x%lx)\n", 259 fp->f_type, (long)fp->f_size); 260 if (pager_output(lbuf)) 261 break; 262 if (fp->f_args != NULL) { 263 (void) pager_output(" args: "); 264 (void) pager_output(fp->f_args); 265 if (pager_output("\n")) 266 break; 267 if (strcmp(fp->f_type, "hash") == 0) { 268 size_t dsize; 269 270 (void) pager_output(" contents: "); 271 dsize = fp->f_size + 1; 272 if (sizeof (lbuf) < dsize) 273 dsize = sizeof (lbuf); 274 (void) strlcpy(lbuf, ptov(fp->f_addr), dsize); 275 if (pager_output(lbuf)) 276 break; 277 } 278 } 279 280 if (hash == 1) { 281 void *ptr = PTOV(fp->f_addr); 282 283 (void) pager_output(" hash: "); 284 sha1(ptr, fp->f_size, (uint8_t *)lbuf); 285 for (int i = 0; i < SHA1_DIGEST_LENGTH; i++) 286 printf("%02x", (int)(lbuf[i] & 0xff)); 287 if (pager_output("\n")) 288 break; 289 } 290 291 if (fp->f_modules) { 292 (void) pager_output(" modules: "); 293 for (mp = fp->f_modules; mp; mp = mp->m_next) { 294 (void) snprintf(lbuf, sizeof (lbuf), "%s.%d ", 295 mp->m_name, mp->m_version); 296 (void) pager_output(lbuf); 297 } 298 if (pager_output("\n")) 299 break; 300 } 301 if (verbose) { 302 /* 303 * XXX could add some formatting smarts here to 304 * display some better 305 */ 306 for (md = fp->f_metadata; md != NULL; 307 md = md->md_next) { 308 (void) snprintf(lbuf, sizeof (lbuf), 309 " 0x%04x, 0x%lx\n", 310 md->md_type, (long)md->md_size); 311 if ((ret = pager_output(lbuf))) 312 break; 313 } 314 } 315 if (ret != 0) 316 break; 317 } 318 pager_close(); 319 return (CMD_OK); 320 } 321 322 /* 323 * File level interface, functions file_* 324 */ 325 int 326 file_load(char *filename, vm_offset_t dest, struct preloaded_file **result) 327 { 328 static int last_file_format = 0; 329 struct preloaded_file *fp; 330 int error; 331 int i; 332 333 if (preloaded_files == NULL) 334 last_file_format = 0; 335 336 error = EFTYPE; 337 for (i = last_file_format, fp = NULL; 338 file_formats[i] && fp == NULL; i++) { 339 error = (file_formats[i]->l_load)(filename, dest, &fp); 340 if (error == 0) { 341 /* remember the loader */ 342 fp->f_loader = last_file_format = i; 343 *result = fp; 344 break; 345 } else if (last_file_format == i && i != 0) { 346 /* Restart from the beginning */ 347 i = -1; 348 last_file_format = 0; 349 fp = NULL; 350 continue; 351 } 352 if (error == EFTYPE) 353 continue; /* Unknown to this handler? */ 354 if (error) { 355 (void) snprintf(command_errbuf, sizeof (command_errbuf), 356 "can't load file '%s': %s", filename, 357 strerror(error)); 358 break; 359 } 360 } 361 return (error); 362 } 363 364 static int 365 file_load_dependencies(struct preloaded_file *base_file) 366 { 367 struct file_metadata *md; 368 struct preloaded_file *fp; 369 struct mod_depend *verinfo; 370 struct kernel_module *mp; 371 char *dmodname; 372 int error; 373 374 md = file_findmetadata(base_file, MODINFOMD_DEPLIST); 375 if (md == NULL) 376 return (0); 377 error = 0; 378 do { 379 verinfo = (struct mod_depend *)md->md_data; 380 dmodname = (char *)(verinfo + 1); 381 if (file_findmodule(NULL, dmodname, verinfo) == NULL) { 382 printf("loading required module '%s'\n", dmodname); 383 error = mod_load(dmodname, verinfo, 0, NULL); 384 if (error) 385 break; 386 /* 387 * If module loaded via kld name which isn't listed 388 * in the linker.hints file, we should check if it have 389 * required version. 390 */ 391 mp = file_findmodule(NULL, dmodname, verinfo); 392 if (mp == NULL) { 393 (void) snprintf(command_errbuf, 394 sizeof (command_errbuf), 395 "module '%s' exists but with wrong version", 396 dmodname); 397 error = ENOENT; 398 break; 399 } 400 } 401 md = metadata_next(md, MODINFOMD_DEPLIST); 402 } while (md); 403 if (!error) 404 return (0); 405 /* Load failed; discard everything */ 406 while (base_file != NULL) { 407 fp = base_file; 408 base_file = base_file->f_next; 409 file_discard(fp); 410 } 411 return (error); 412 } 413 414 /* 415 * Calculate the size of the environment module. 416 * The environment is list of name=value C strings, ending with a '\0' byte. 417 */ 418 static size_t 419 env_get_size(void) 420 { 421 size_t size = 0; 422 struct env_var *ep; 423 424 /* Traverse the environment. */ 425 for (ep = environ; ep != NULL; ep = ep->ev_next) { 426 size += strlen(ep->ev_name); 427 size++; /* "=" */ 428 if (ep->ev_value != NULL) 429 size += strlen(ep->ev_value); 430 size++; /* nul byte */ 431 } 432 size++; /* nul byte */ 433 return (size); 434 } 435 436 static void 437 module_hash(struct preloaded_file *fp, void *addr, size_t size) 438 { 439 uint8_t hash[SHA1_DIGEST_LENGTH]; 440 char ascii[2 * SHA1_DIGEST_LENGTH + 1]; 441 int i; 442 443 sha1(addr, size, hash); 444 for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { 445 (void) snprintf(ascii + 2 * i, sizeof (ascii) - 2 * i, "%02x", 446 hash[i] & 0xff); 447 } 448 /* Out of memory here is not fatal issue. */ 449 (void) asprintf(&fp->f_args, "hash=%s", ascii); 450 } 451 452 /* 453 * Create virtual module for environment variables. 454 * This module should be created as late as possible before executing 455 * the OS kernel, or we may miss some environment variable updates. 456 */ 457 void 458 build_environment_module(void) 459 { 460 struct preloaded_file *fp; 461 size_t size; 462 char *name = "environment"; 463 vm_offset_t laddr; 464 465 /* We can't load first */ 466 if (file_findfile(NULL, NULL) == NULL) { 467 printf("Can not load environment module: %s\n", 468 "the kernel is not loaded"); 469 return; 470 } 471 472 if (file_findfile(name, name) != NULL) { 473 printf("warning: '%s' is already loaded\n", name); 474 return; 475 } 476 477 tem_save_state(); /* Ask tem to save it's state in env. */ 478 size = env_get_size(); 479 480 fp = file_alloc(); 481 if (fp != NULL) { 482 fp->f_name = strdup(name); 483 fp->f_type = strdup(name); 484 } 485 486 if (fp == NULL || fp->f_name == NULL || fp->f_type == NULL) { 487 printf("Can not load environment module: %s\n", 488 "out of memory"); 489 file_discard(fp); 490 return; 491 } 492 493 494 if (archsw.arch_loadaddr != NULL) 495 loadaddr = archsw.arch_loadaddr(LOAD_MEM, &size, loadaddr); 496 497 if (loadaddr == 0) { 498 printf("Can not load environment module: %s\n", 499 "out of memory"); 500 file_discard(fp); 501 return; 502 } 503 504 laddr = bi_copyenv(loadaddr); 505 /* Looks OK so far; populate control structure */ 506 module_hash(fp, PTOV(loadaddr), laddr - loadaddr); 507 fp->f_loader = -1; 508 fp->f_addr = loadaddr; 509 fp->f_size = laddr - loadaddr; 510 511 /* recognise space consumption */ 512 loadaddr = laddr; 513 514 file_insert_tail(fp); 515 } 516 517 void 518 build_font_module(void) 519 { 520 bitmap_data_t *bd; 521 struct font *fd; 522 struct preloaded_file *fp; 523 size_t size; 524 uint32_t checksum; 525 int i; 526 char *name = "console-font"; 527 vm_offset_t laddr; 528 struct font_info fi; 529 struct fontlist *fl; 530 531 if (STAILQ_EMPTY(&fonts)) 532 return; 533 534 /* We can't load first */ 535 if (file_findfile(NULL, NULL) == NULL) { 536 printf("Can not load font module: %s\n", 537 "the kernel is not loaded"); 538 return; 539 } 540 541 if (file_findfile(name, name) != NULL) { 542 printf("warning: '%s' is already loaded\n", name); 543 return; 544 } 545 546 /* helper pointers */ 547 bd = NULL; 548 STAILQ_FOREACH(fl, &fonts, font_next) { 549 if (tems.ts_font.vf_width == fl->font_data->width && 550 tems.ts_font.vf_height == fl->font_data->height) { 551 /* 552 * Kernel does have better built in font. 553 */ 554 if (fl->font_flags == FONT_BUILTIN) 555 return; 556 557 bd = fl->font_data; 558 break; 559 } 560 } 561 if (bd == NULL) 562 return; 563 fd = bd->font; 564 565 fi.fi_width = fd->vf_width; 566 checksum = fi.fi_width; 567 fi.fi_height = fd->vf_height; 568 checksum += fi.fi_height; 569 fi.fi_bitmap_size = bd->uncompressed_size; 570 checksum += fi.fi_bitmap_size; 571 572 size = roundup2(sizeof (struct font_info), 8); 573 for (i = 0; i < VFNT_MAPS; i++) { 574 fi.fi_map_count[i] = fd->vf_map_count[i]; 575 checksum += fi.fi_map_count[i]; 576 size += fd->vf_map_count[i] * sizeof (struct font_map); 577 size += roundup2(size, 8); 578 } 579 size += bd->uncompressed_size; 580 581 fi.fi_checksum = -checksum; 582 583 fp = file_alloc(); 584 if (fp != NULL) { 585 fp->f_name = strdup(name); 586 fp->f_type = strdup(name); 587 } 588 589 if (fp == NULL || fp->f_name == NULL || fp->f_type == NULL) { 590 printf("Can not load font module: %s\n", 591 "out of memory"); 592 file_discard(fp); 593 return; 594 } 595 596 if (archsw.arch_loadaddr != NULL) 597 loadaddr = archsw.arch_loadaddr(LOAD_MEM, &size, loadaddr); 598 599 if (loadaddr == 0) { 600 printf("Can not load font module: %s\n", 601 "out of memory"); 602 file_discard(fp); 603 return; 604 } 605 606 laddr = loadaddr; 607 laddr += archsw.arch_copyin(&fi, laddr, sizeof (struct font_info)); 608 laddr = roundup2(laddr, 8); 609 610 /* Copy maps. */ 611 for (i = 0; i < VFNT_MAPS; i++) { 612 if (fd->vf_map_count[i] != 0) { 613 laddr += archsw.arch_copyin(fd->vf_map[i], laddr, 614 fd->vf_map_count[i] * sizeof (struct font_map)); 615 laddr = roundup2(laddr, 8); 616 } 617 } 618 619 /* Copy the bitmap. */ 620 laddr += archsw.arch_copyin(fd->vf_bytes, laddr, fi.fi_bitmap_size); 621 622 /* Looks OK so far; populate control structure */ 623 module_hash(fp, PTOV(loadaddr), laddr - loadaddr); 624 fp->f_loader = -1; 625 fp->f_addr = loadaddr; 626 fp->f_size = laddr - loadaddr; 627 628 /* recognise space consumption */ 629 loadaddr = laddr; 630 631 file_insert_tail(fp); 632 } 633 634 /* 635 * We've been asked to load (fname) as (type), so just suck it in, 636 * no arguments or anything. 637 */ 638 struct preloaded_file * 639 file_loadraw(const char *fname, char *type, int argc, char **argv, int insert) 640 { 641 struct preloaded_file *fp; 642 char *name; 643 int fd; 644 ssize_t got; 645 struct stat st; 646 647 /* We can't load first */ 648 if ((file_findfile(NULL, NULL)) == NULL) { 649 command_errmsg = "can't load file before kernel"; 650 return (NULL); 651 } 652 653 /* locate the file on the load path */ 654 name = file_search(fname, NULL); 655 if (name == NULL) { 656 (void) snprintf(command_errbuf, sizeof (command_errbuf), 657 "can't find '%s'", fname); 658 return (NULL); 659 } 660 661 if ((fd = open(name, O_RDONLY)) < 0) { 662 (void) snprintf(command_errbuf, sizeof (command_errbuf), 663 "can't open '%s': %s", name, strerror(errno)); 664 free(name); 665 return (NULL); 666 } 667 if (fstat(fd, &st) < 0) { 668 (void) close(fd); 669 (void) snprintf(command_errbuf, sizeof (command_errbuf), 670 "stat error '%s': %s", name, strerror(errno)); 671 free(name); 672 return (NULL); 673 } 674 675 if (archsw.arch_loadaddr != NULL) 676 loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr); 677 if (loadaddr == 0) { 678 (void) close(fd); 679 (void) snprintf(command_errbuf, sizeof (command_errbuf), 680 "no memory to load %s", name); 681 free(name); 682 return (NULL); 683 } 684 685 got = archsw.arch_readin(fd, loadaddr, st.st_size); 686 if ((size_t)got != st.st_size) { 687 (void) snprintf(command_errbuf, sizeof (command_errbuf), 688 "error reading '%s': %s", name, strerror(errno)); 689 free(name); 690 (void) close(fd); 691 if (archsw.arch_free_loadaddr != NULL && st.st_size != 0) { 692 archsw.arch_free_loadaddr(loadaddr, 693 (uint64_t)(roundup2(st.st_size, PAGE_SIZE) >> 12)); 694 } 695 return (NULL); 696 } 697 698 /* Looks OK so far; create & populate control structure */ 699 fp = file_alloc(); 700 if (fp == NULL) { 701 if (archsw.arch_free_loadaddr != NULL && st.st_size != 0) 702 archsw.arch_free_loadaddr(loadaddr, 703 (uint64_t)(roundup2(st.st_size, PAGE_SIZE) >> 12)); 704 (void) snprintf(command_errbuf, sizeof (command_errbuf), 705 "no memory to load %s", name); 706 free(name); 707 (void) close(fd); 708 return (NULL); 709 } 710 711 fp->f_name = name; 712 fp->f_args = unargv(argc, argv); 713 fp->f_type = strdup(type); 714 fp->f_metadata = NULL; 715 fp->f_loader = -1; 716 fp->f_addr = loadaddr; 717 fp->f_size = st.st_size; 718 719 if (fp->f_type == NULL || 720 (argc != 0 && fp->f_args == NULL)) { 721 (void) close(fd); 722 (void) snprintf(command_errbuf, sizeof (command_errbuf), 723 "no memory to load %s", name); 724 file_discard(fp); 725 return (NULL); 726 } 727 /* recognise space consumption */ 728 loadaddr += st.st_size; 729 730 /* Add to the list of loaded files */ 731 if (insert != 0) 732 file_insert_tail(fp); 733 (void) close(fd); 734 return (fp); 735 } 736 737 /* 738 * Load the module (name), pass it (argc),(argv), add container file 739 * to the list of loaded files. 740 * If module is already loaded just assign new argc/argv. 741 */ 742 int 743 mod_load(char *modname, struct mod_depend *verinfo, int argc, char *argv[]) 744 { 745 struct kernel_module *mp; 746 int err; 747 char *filename; 748 749 if (file_havepath(modname)) { 750 printf("Warning: mod_load() called instead of mod_loadkld() " 751 "for module '%s'\n", modname); 752 return (mod_loadkld(modname, argc, argv)); 753 } 754 /* see if module is already loaded */ 755 mp = file_findmodule(NULL, modname, verinfo); 756 if (mp != NULL) { 757 free(mp->m_args); 758 mp->m_args = unargv(argc, argv); 759 (void) snprintf(command_errbuf, sizeof (command_errbuf), 760 "warning: module '%s' already loaded", mp->m_name); 761 return (0); 762 } 763 /* locate file with the module on the search path */ 764 filename = mod_searchmodule(modname, verinfo); 765 if (filename == NULL) { 766 (void) snprintf(command_errbuf, sizeof (command_errbuf), 767 "can't find '%s'", modname); 768 return (ENOENT); 769 } 770 err = mod_loadkld(filename, argc, argv); 771 free(filename); 772 return (err); 773 } 774 775 /* 776 * Load specified KLD. If path is omitted, then try to locate it via 777 * search path. 778 */ 779 int 780 mod_loadkld(const char *kldname, int argc, char *argv[]) 781 { 782 struct preloaded_file *fp; 783 int err; 784 char *filename; 785 vm_offset_t loadaddr_saved; 786 787 /* 788 * Get fully qualified KLD name 789 */ 790 filename = file_search(kldname, kld_ext_list); 791 if (filename == NULL) { 792 (void) snprintf(command_errbuf, sizeof (command_errbuf), 793 "can't find '%s'", kldname); 794 return (ENOENT); 795 } 796 /* 797 * Check if KLD already loaded 798 */ 799 fp = file_findfile(filename, NULL); 800 if (fp != NULL) { 801 (void) snprintf(command_errbuf, sizeof (command_errbuf), 802 "warning: KLD '%s' already loaded", filename); 803 free(filename); 804 return (0); 805 } 806 807 do { 808 err = file_load(filename, loadaddr, &fp); 809 if (err) 810 break; 811 fp->f_args = unargv(argc, argv); 812 loadaddr_saved = loadaddr; 813 loadaddr = fp->f_addr + fp->f_size; 814 file_insert_tail(fp); /* Add to the list of loaded files */ 815 if (file_load_dependencies(fp) != 0) { 816 err = ENOENT; 817 file_remove(fp); 818 loadaddr = loadaddr_saved; 819 fp = NULL; 820 break; 821 } 822 } while (0); 823 if (err == EFTYPE) { 824 (void) snprintf(command_errbuf, sizeof (command_errbuf), 825 "don't know how to load module '%s'", filename); 826 } 827 if (err) 828 file_discard(fp); 829 free(filename); 830 return (err); 831 } 832 833 /* 834 * Find a file matching (name) and (type). 835 * NULL may be passed as a wildcard to either. 836 */ 837 struct preloaded_file * 838 file_findfile(const char *name, const char *type) 839 { 840 struct preloaded_file *fp; 841 842 for (fp = preloaded_files; fp != NULL; fp = fp->f_next) { 843 if (((name == NULL) || strcmp(name, fp->f_name) == 0) && 844 ((type == NULL) || strcmp(type, fp->f_type) == 0)) 845 break; 846 } 847 return (fp); 848 } 849 850 /* 851 * Find a module matching (name) inside of given file. 852 * NULL may be passed as a wildcard. 853 */ 854 struct kernel_module * 855 file_findmodule(struct preloaded_file *fp, char *modname, 856 struct mod_depend *verinfo) 857 { 858 struct kernel_module *mp, *best; 859 int bestver, mver; 860 861 if (fp == NULL) { 862 for (fp = preloaded_files; fp; fp = fp->f_next) { 863 mp = file_findmodule(fp, modname, verinfo); 864 if (mp != NULL) 865 return (mp); 866 } 867 return (NULL); 868 } 869 best = NULL; 870 bestver = 0; 871 for (mp = fp->f_modules; mp; mp = mp->m_next) { 872 if (strcmp(modname, mp->m_name) == 0) { 873 if (verinfo == NULL) 874 return (mp); 875 mver = mp->m_version; 876 if (mver == verinfo->md_ver_preferred) 877 return (mp); 878 if (mver >= verinfo->md_ver_minimum && 879 mver <= verinfo->md_ver_maximum && 880 mver > bestver) { 881 best = mp; 882 bestver = mver; 883 } 884 } 885 } 886 return (best); 887 } 888 /* 889 * Make a copy of (size) bytes of data from (p), and associate them as 890 * metadata of (type) to the module (mp). 891 */ 892 void 893 file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p) 894 { 895 struct file_metadata *md; 896 897 md = malloc(sizeof (struct file_metadata) - sizeof (md->md_data) + 898 size); 899 if (md != NULL) { 900 md->md_size = size; 901 md->md_type = type; 902 bcopy(p, md->md_data, size); 903 md->md_next = fp->f_metadata; 904 } 905 fp->f_metadata = md; 906 } 907 908 /* 909 * Find a metadata object of (type) associated with the file (fp) 910 */ 911 struct file_metadata * 912 file_findmetadata(struct preloaded_file *fp, int type) 913 { 914 struct file_metadata *md; 915 916 for (md = fp->f_metadata; md != NULL; md = md->md_next) 917 if (md->md_type == type) 918 break; 919 return (md); 920 } 921 922 struct file_metadata * 923 metadata_next(struct file_metadata *md, int type) 924 { 925 926 if (md == NULL) 927 return (NULL); 928 while ((md = md->md_next) != NULL) 929 if (md->md_type == type) 930 break; 931 return (md); 932 } 933 934 static const char *emptyextlist[] = { "", NULL }; 935 936 /* 937 * Check if the given file is in place and return full path to it. 938 */ 939 static char * 940 file_lookup(const char *path, const char *name, int namelen, 941 const char **extlist) 942 { 943 struct stat st; 944 char *result, *cp; 945 const char **cpp; 946 int pathlen, extlen, len; 947 948 pathlen = strlen(path); 949 extlen = 0; 950 if (extlist == NULL) 951 extlist = emptyextlist; 952 for (cpp = extlist; *cpp; cpp++) { 953 len = strlen(*cpp); 954 if (len > extlen) 955 extlen = len; 956 } 957 result = malloc(pathlen + namelen + extlen + 2); 958 if (result == NULL) 959 return (NULL); 960 bcopy(path, result, pathlen); 961 if (pathlen > 0 && result[pathlen - 1] != '/') 962 result[pathlen++] = '/'; 963 cp = result + pathlen; 964 bcopy(name, cp, namelen); 965 cp += namelen; 966 for (cpp = extlist; *cpp; cpp++) { 967 (void) strcpy(cp, *cpp); 968 if (stat(result, &st) == 0 && S_ISREG(st.st_mode)) 969 return (result); 970 } 971 free(result); 972 return (NULL); 973 } 974 975 /* 976 * Check if file name have any qualifiers 977 */ 978 static int 979 file_havepath(const char *name) 980 { 981 const char *cp; 982 983 (void) archsw.arch_getdev(NULL, name, &cp); 984 return (cp != name || strchr(name, '/') != NULL); 985 } 986 987 /* 988 * Attempt to find the file (name) on the module searchpath. 989 * If (name) is qualified in any way, we simply check it and 990 * return it or NULL. If it is not qualified, then we attempt 991 * to construct a path using entries in the environment variable 992 * module_path. 993 * 994 * The path we return a pointer to need never be freed, as we manage 995 * it internally. 996 */ 997 static char * 998 file_search(const char *name, const char **extlist) 999 { 1000 struct moduledir *mdp; 1001 struct stat sb; 1002 char *result; 1003 int namelen; 1004 1005 /* Don't look for nothing */ 1006 if (name == NULL) 1007 return (NULL); 1008 1009 if (*name == '\0') 1010 return (strdup(name)); 1011 1012 if (file_havepath(name)) { 1013 /* Qualified, so just see if it exists */ 1014 if (stat(name, &sb) == 0) 1015 return (strdup(name)); 1016 return (NULL); 1017 } 1018 moduledir_rebuild(); 1019 result = NULL; 1020 namelen = strlen(name); 1021 STAILQ_FOREACH(mdp, &moduledir_list, d_link) { 1022 result = file_lookup(mdp->d_path, name, namelen, extlist); 1023 if (result != NULL) 1024 break; 1025 } 1026 return (result); 1027 } 1028 1029 #define INT_ALIGN(base, ptr) ptr = \ 1030 (base) + (((ptr) - (base) + sizeof (int) - 1) & ~(sizeof (int) - 1)) 1031 1032 static char * 1033 mod_search_hints(struct moduledir *mdp, const char *modname, 1034 struct mod_depend *verinfo) 1035 { 1036 uchar_t *cp, *recptr, *bufend, *best; 1037 char *result; 1038 int *intp, bestver, blen, clen, ival, modnamelen, reclen; 1039 bool found; 1040 1041 moduledir_readhints(mdp); 1042 modnamelen = strlen(modname); 1043 found = false; 1044 result = NULL; 1045 bestver = 0; 1046 if (mdp->d_hints == NULL) 1047 goto bad; 1048 recptr = mdp->d_hints; 1049 bufend = recptr + mdp->d_hintsz; 1050 clen = blen = 0; 1051 best = cp = NULL; 1052 while (recptr < bufend && !found) { 1053 intp = (int *)recptr; 1054 reclen = *intp++; 1055 ival = *intp++; 1056 cp = (uchar_t *)intp; 1057 switch (ival) { 1058 case MDT_VERSION: 1059 clen = *cp++; 1060 if (clen != modnamelen || bcmp(cp, modname, clen) != 0) 1061 break; 1062 cp += clen; 1063 INT_ALIGN(mdp->d_hints, cp); 1064 ival = *(int *)cp; 1065 cp += sizeof (int); 1066 clen = *cp++; 1067 if (verinfo == NULL || 1068 ival == verinfo->md_ver_preferred) { 1069 found = true; 1070 break; 1071 } 1072 if (ival >= verinfo->md_ver_minimum && 1073 ival <= verinfo->md_ver_maximum && 1074 ival > bestver) { 1075 bestver = ival; 1076 best = cp; 1077 blen = clen; 1078 } 1079 break; 1080 default: 1081 break; 1082 } 1083 recptr += reclen + sizeof (int); 1084 } 1085 /* 1086 * Finally check if KLD is in the place 1087 */ 1088 if (found) 1089 result = file_lookup(mdp->d_path, (char *)cp, clen, NULL); 1090 else if (best) 1091 result = file_lookup(mdp->d_path, (char *)best, blen, NULL); 1092 bad: 1093 /* 1094 * If nothing found or hints is absent - fallback to the old way 1095 * by using "kldname[.ko]" as module name. 1096 */ 1097 if (!found && bestver == 0 && result == NULL) { 1098 result = file_lookup(mdp->d_path, modname, modnamelen, 1099 kld_ext_list); 1100 } 1101 return (result); 1102 } 1103 1104 /* 1105 * Attempt to locate the file containing the module (name) 1106 */ 1107 static char * 1108 mod_searchmodule(char *name, struct mod_depend *verinfo) 1109 { 1110 struct moduledir *mdp; 1111 char *result; 1112 1113 moduledir_rebuild(); 1114 /* 1115 * Now we ready to lookup module in the given directories 1116 */ 1117 result = NULL; 1118 STAILQ_FOREACH(mdp, &moduledir_list, d_link) { 1119 result = mod_search_hints(mdp, name, verinfo); 1120 if (result != NULL) 1121 break; 1122 } 1123 1124 return (result); 1125 } 1126 1127 int 1128 file_addmodule(struct preloaded_file *fp, char *modname, int version, 1129 struct kernel_module **newmp) 1130 { 1131 struct kernel_module *mp; 1132 struct mod_depend mdepend; 1133 1134 bzero(&mdepend, sizeof (mdepend)); 1135 mdepend.md_ver_preferred = version; 1136 mp = file_findmodule(fp, modname, &mdepend); 1137 if (mp != NULL) 1138 return (EEXIST); 1139 mp = calloc(1, sizeof (struct kernel_module)); 1140 if (mp == NULL) 1141 return (ENOMEM); 1142 mp->m_name = strdup(modname); 1143 if (mp->m_name == NULL) { 1144 free(mp); 1145 return (ENOMEM); 1146 } 1147 mp->m_version = version; 1148 mp->m_fp = fp; 1149 mp->m_next = fp->f_modules; 1150 fp->f_modules = mp; 1151 if (newmp) 1152 *newmp = mp; 1153 return (0); 1154 } 1155 1156 /* 1157 * Throw a file away 1158 */ 1159 void 1160 file_discard(struct preloaded_file *fp) 1161 { 1162 struct file_metadata *md, *md1; 1163 struct kernel_module *mp, *mp1; 1164 1165 if (fp == NULL) 1166 return; 1167 1168 if (archsw.arch_free_loadaddr != NULL && fp->f_addr && 1169 fp->f_size != 0) { 1170 archsw.arch_free_loadaddr(fp->f_addr, 1171 (uint64_t)(roundup2(fp->f_size, PAGE_SIZE) >> 12)); 1172 } 1173 1174 md = fp->f_metadata; 1175 while (md != NULL) { 1176 md1 = md; 1177 md = md->md_next; 1178 free(md1); 1179 } 1180 mp = fp->f_modules; 1181 while (mp != NULL) { 1182 free(mp->m_name); 1183 mp1 = mp; 1184 mp = mp->m_next; 1185 free(mp1); 1186 } 1187 free(fp->f_name); 1188 free(fp->f_type); 1189 free(fp->f_args); 1190 free(fp); 1191 } 1192 1193 /* 1194 * Allocate a new file; must be used instead of malloc() 1195 * to ensure safe initialisation. 1196 */ 1197 struct preloaded_file * 1198 file_alloc(void) 1199 { 1200 1201 return (calloc(1, sizeof (struct preloaded_file))); 1202 } 1203 1204 /* 1205 * Add a module to the chain 1206 */ 1207 static void 1208 file_insert_tail(struct preloaded_file *fp) 1209 { 1210 struct preloaded_file *cm; 1211 1212 /* Append to list of loaded file */ 1213 fp->f_next = NULL; 1214 if (preloaded_files == NULL) { 1215 preloaded_files = fp; 1216 } else { 1217 for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next) 1218 ; 1219 cm->f_next = fp; 1220 } 1221 } 1222 1223 /* 1224 * Remove module from the chain 1225 */ 1226 static void 1227 file_remove(struct preloaded_file *fp) 1228 { 1229 struct preloaded_file *cm; 1230 1231 if (preloaded_files == NULL) 1232 return; 1233 1234 if (preloaded_files == fp) { 1235 preloaded_files = fp->f_next; 1236 return; 1237 } 1238 for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next) { 1239 if (cm->f_next == fp) { 1240 cm->f_next = fp->f_next; 1241 return; 1242 } 1243 } 1244 } 1245 1246 static char * 1247 moduledir_fullpath(struct moduledir *mdp, const char *fname) 1248 { 1249 char *cp; 1250 1251 cp = malloc(strlen(mdp->d_path) + strlen(fname) + 2); 1252 if (cp == NULL) 1253 return (NULL); 1254 strcpy(cp, mdp->d_path); 1255 strcat(cp, "/"); 1256 strcat(cp, fname); 1257 return (cp); 1258 } 1259 1260 /* 1261 * Read linker.hints file into memory performing some sanity checks. 1262 */ 1263 static void 1264 moduledir_readhints(struct moduledir *mdp) 1265 { 1266 struct stat st; 1267 char *path; 1268 int fd, size, version; 1269 1270 if (mdp->d_hints != NULL || (mdp->d_flags & MDIR_NOHINTS)) 1271 return; 1272 path = moduledir_fullpath(mdp, "linker.hints"); 1273 if (stat(path, &st) != 0 || 1274 st.st_size < (ssize_t)(sizeof (version) + sizeof (int)) || 1275 st.st_size > LINKER_HINTS_MAX || 1276 (fd = open(path, O_RDONLY)) < 0) { 1277 free(path); 1278 mdp->d_flags |= MDIR_NOHINTS; 1279 return; 1280 } 1281 free(path); 1282 size = read(fd, &version, sizeof (version)); 1283 if (size != sizeof (version) || version != LINKER_HINTS_VERSION) 1284 goto bad; 1285 size = st.st_size - size; 1286 mdp->d_hints = malloc(size); 1287 if (mdp->d_hints == NULL) 1288 goto bad; 1289 if (read(fd, mdp->d_hints, size) != size) 1290 goto bad; 1291 mdp->d_hintsz = size; 1292 (void) close(fd); 1293 return; 1294 bad: 1295 (void) close(fd); 1296 free(mdp->d_hints); 1297 mdp->d_hints = NULL; 1298 mdp->d_flags |= MDIR_NOHINTS; 1299 } 1300 1301 /* 1302 * Extract directories from the ';' separated list, remove duplicates. 1303 */ 1304 static void 1305 moduledir_rebuild(void) 1306 { 1307 struct moduledir *mdp, *mtmp; 1308 const char *path, *cp, *ep; 1309 size_t cplen; 1310 1311 path = getenv("module_path"); 1312 if (path == NULL) 1313 path = default_searchpath; 1314 /* 1315 * Rebuild list of module directories if it changed 1316 */ 1317 STAILQ_FOREACH(mdp, &moduledir_list, d_link) 1318 mdp->d_flags |= MDIR_REMOVED; 1319 1320 for (ep = path; *ep != 0; ep++) { 1321 cp = ep; 1322 for (; *ep != 0 && *ep != ';'; ep++) 1323 ; 1324 /* 1325 * Ignore trailing slashes 1326 */ 1327 for (cplen = ep - cp; cplen > 1 && cp[cplen - 1] == '/'; 1328 cplen--) 1329 ; 1330 STAILQ_FOREACH(mdp, &moduledir_list, d_link) { 1331 if (strlen(mdp->d_path) != cplen || 1332 bcmp(cp, mdp->d_path, cplen) != 0) 1333 continue; 1334 mdp->d_flags &= ~MDIR_REMOVED; 1335 break; 1336 } 1337 if (mdp == NULL) { 1338 mdp = malloc(sizeof (*mdp) + cplen + 1); 1339 if (mdp == NULL) 1340 return; 1341 mdp->d_path = (char *)(mdp + 1); 1342 bcopy(cp, mdp->d_path, cplen); 1343 mdp->d_path[cplen] = 0; 1344 mdp->d_hints = NULL; 1345 mdp->d_flags = 0; 1346 STAILQ_INSERT_TAIL(&moduledir_list, mdp, d_link); 1347 } 1348 if (*ep == '\0') 1349 break; 1350 } 1351 /* 1352 * Delete unused directories if any 1353 */ 1354 mdp = STAILQ_FIRST(&moduledir_list); 1355 while (mdp) { 1356 if ((mdp->d_flags & MDIR_REMOVED) == 0) { 1357 mdp = STAILQ_NEXT(mdp, d_link); 1358 } else { 1359 free(mdp->d_hints); 1360 mtmp = mdp; 1361 mdp = STAILQ_NEXT(mdp, d_link); 1362 STAILQ_REMOVE(&moduledir_list, mtmp, moduledir, d_link); 1363 free(mtmp); 1364 } 1365 } 1366 } 1367