1 /* 2 * Copyright 2002-2008, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Copyright 2001, Thomas Kurschel. All rights reserved. 6 * Distributed under the terms of the NewOS License. 7 */ 8 9 /*! Manages kernel add-ons and their exported modules. */ 10 11 12 #include <kmodule.h> 13 14 #include <errno.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <sys/stat.h> 18 19 #include <FindDirectory.h> 20 21 #include <boot_device.h> 22 #include <elf.h> 23 #include <lock.h> 24 #include <vfs.h> 25 #include <boot/elf.h> 26 #include <fs/KPath.h> 27 #include <safemode.h> 28 #include <util/AutoLock.h> 29 #include <util/khash.h> 30 31 32 //#define TRACE_MODULE 33 #ifdef TRACE_MODULE 34 # define TRACE(x) dprintf x 35 #else 36 # define TRACE(x) ; 37 #endif 38 #define FATAL(x) dprintf x 39 40 41 #define MODULE_HASH_SIZE 16 42 43 /*! The modules referenced by this structure are built-in 44 modules that can't be loaded from disk. 45 */ 46 extern module_info gDeviceManagerModule; 47 extern module_info gDeviceRootModule; 48 extern module_info gDeviceForDriversModule; 49 extern module_info gFrameBufferConsoleModule; 50 51 // file systems 52 extern module_info gRootFileSystem; 53 extern module_info gDeviceFileSystem; 54 55 static module_info *sBuiltInModules[] = { 56 &gDeviceManagerModule, 57 &gDeviceRootModule, 58 &gDeviceForDriversModule, 59 &gFrameBufferConsoleModule, 60 61 &gRootFileSystem, 62 &gDeviceFileSystem, 63 NULL 64 }; 65 66 enum module_state { 67 MODULE_QUERIED = 0, 68 MODULE_LOADED, 69 MODULE_INIT, 70 MODULE_READY, 71 MODULE_UNINIT, 72 MODULE_ERROR 73 }; 74 75 76 /* Each loaded module image (which can export several modules) is put 77 * in a hash (gModuleImagesHash) to be easily found when you search 78 * for a specific file name. 79 * ToDo: Could use only the inode number for hashing. Would probably be 80 * a little bit slower, but would lower the memory foot print quite a lot. 81 */ 82 83 struct module_image { 84 struct module_image *next; 85 module_info **info; /* the module_info we use */ 86 module_dependency *dependencies; 87 char *path; /* the full path for the module */ 88 image_id image; 89 int32 ref_count; /* how many ref's to this file */ 90 bool keep_loaded; 91 }; 92 93 /* Each known module will have this structure which is put in the 94 * gModulesHash, and looked up by name. 95 */ 96 97 struct module { 98 struct module *next; 99 ::module_image *module_image; 100 char *name; 101 char *file; 102 int32 ref_count; 103 module_info *info; /* will only be valid if ref_count > 0 */ 104 int32 offset; /* this is the offset in the headers */ 105 module_state state; /* state of module */ 106 uint32 flags; 107 }; 108 109 #define B_BUILT_IN_MODULE 2 110 111 typedef struct module_path { 112 const char *name; 113 uint32 base_length; 114 } module_path; 115 116 typedef struct module_iterator { 117 module_path *stack; 118 int32 stack_size; 119 int32 stack_current; 120 121 char *prefix; 122 size_t prefix_length; 123 const char *suffix; 124 size_t suffix_length; 125 DIR *current_dir; 126 status_t status; 127 int32 module_offset; 128 /* This is used to keep track of which module_info 129 * within a module we're addressing. */ 130 ::module_image *module_image; 131 module_info **current_header; 132 const char *current_path; 133 uint32 path_base_length; 134 const char *current_module_path; 135 bool builtin_modules; 136 bool loaded_modules; 137 } module_iterator; 138 139 140 static bool sDisableUserAddOns = false; 141 142 /* locking scheme: there is a global lock only; having several locks 143 * makes trouble if dependent modules get loaded concurrently -> 144 * they have to wait for each other, i.e. we need one lock per module; 145 * also we must detect circular references during init and not dead-lock 146 */ 147 static recursive_lock sModulesLock; 148 149 /* These are the standard base paths where we start to look for modules 150 * to load. Order is important, the last entry here will be searched 151 * first. 152 */ 153 static const directory_which kModulePaths[] = { 154 B_BEOS_ADDONS_DIRECTORY, 155 B_COMMON_ADDONS_DIRECTORY, 156 B_USER_ADDONS_DIRECTORY, 157 }; 158 159 static const uint32 kNumModulePaths = sizeof(kModulePaths) 160 / sizeof(kModulePaths[0]); 161 static const uint32 kFirstNonSystemModulePath = 1; 162 163 /* We store the loaded modules by directory path, and all known modules 164 * by module name in a hash table for quick access 165 */ 166 static hash_table *sModuleImagesHash; 167 static hash_table *sModulesHash; 168 169 170 /*! Calculates hash for a module using its name */ 171 static uint32 172 module_hash(void *_module, const void *_key, uint32 range) 173 { 174 module *module = (struct module *)_module; 175 const char *name = (const char *)_key; 176 177 if (module != NULL) 178 return hash_hash_string(module->name) % range; 179 180 if (name != NULL) 181 return hash_hash_string(name) % range; 182 183 return 0; 184 } 185 186 187 /*! Compares a module to a given name */ 188 static int 189 module_compare(void *_module, const void *_key) 190 { 191 module *module = (struct module *)_module; 192 const char *name = (const char *)_key; 193 if (name == NULL) 194 return -1; 195 196 return strcmp(module->name, name); 197 } 198 199 200 /*! Calculates the hash of a module image using its path */ 201 static uint32 202 module_image_hash(void *_module, const void *_key, uint32 range) 203 { 204 module_image *image = (module_image *)_module; 205 const char *path = (const char *)_key; 206 207 if (image != NULL) 208 return hash_hash_string(image->path) % range; 209 210 if (path != NULL) 211 return hash_hash_string(path) % range; 212 213 return 0; 214 } 215 216 217 /*! Compares a module image to a path */ 218 static int 219 module_image_compare(void *_module, const void *_key) 220 { 221 module_image *image = (module_image *)_module; 222 const char *path = (const char *)_key; 223 if (path == NULL) 224 return -1; 225 226 return strcmp(image->path, path); 227 } 228 229 230 /*! Try to load the module image at the specified location. 231 If it could be loaded, it returns B_OK, and stores a pointer 232 to the module_image object in "_moduleImage". 233 */ 234 static status_t 235 load_module_image(const char *path, module_image **_moduleImage) 236 { 237 module_image *moduleImage; 238 status_t status; 239 image_id image; 240 241 TRACE(("load_module_image(path = \"%s\", _image = %p)\n", path, _moduleImage)); 242 ASSERT(_moduleImage != NULL); 243 244 image = load_kernel_add_on(path); 245 if (image < 0) { 246 dprintf("load_module_image(%s) failed: %s\n", path, strerror(image)); 247 return image; 248 } 249 250 moduleImage = (module_image *)malloc(sizeof(module_image)); 251 if (!moduleImage) { 252 status = B_NO_MEMORY; 253 goto err; 254 } 255 256 if (get_image_symbol(image, "modules", B_SYMBOL_TYPE_DATA, 257 (void **)&moduleImage->info) != B_OK) { 258 TRACE(("load_module_image: Failed to load \"%s\" due to lack of 'modules' symbol\n", path)); 259 status = B_BAD_TYPE; 260 goto err1; 261 } 262 263 moduleImage->dependencies = NULL; 264 get_image_symbol(image, "module_dependencies", B_SYMBOL_TYPE_DATA, 265 (void **)&moduleImage->dependencies); 266 // this is allowed to be NULL 267 268 moduleImage->path = strdup(path); 269 if (!moduleImage->path) { 270 status = B_NO_MEMORY; 271 goto err1; 272 } 273 274 moduleImage->image = image; 275 moduleImage->ref_count = 0; 276 moduleImage->keep_loaded = false; 277 278 recursive_lock_lock(&sModulesLock); 279 hash_insert(sModuleImagesHash, moduleImage); 280 recursive_lock_unlock(&sModulesLock); 281 282 *_moduleImage = moduleImage; 283 return B_OK; 284 285 err1: 286 free(moduleImage); 287 err: 288 unload_kernel_add_on(image); 289 290 return status; 291 } 292 293 294 static status_t 295 unload_module_image(module_image *moduleImage, const char *path) 296 { 297 TRACE(("unload_module_image(image = %p, path = %s)\n", moduleImage, path)); 298 299 RecursiveLocker locker(sModulesLock); 300 301 if (moduleImage == NULL) { 302 // if no image was specified, lookup it up in the hash table 303 moduleImage = (module_image *)hash_lookup(sModuleImagesHash, path); 304 if (moduleImage == NULL) 305 return B_ENTRY_NOT_FOUND; 306 } 307 308 if (moduleImage->ref_count != 0) { 309 FATAL(("Can't unload %s due to ref_cnt = %ld\n", moduleImage->path, 310 moduleImage->ref_count)); 311 return B_ERROR; 312 } 313 314 hash_remove(sModuleImagesHash, moduleImage); 315 locker.Unlock(); 316 317 unload_kernel_add_on(moduleImage->image); 318 free(moduleImage->path); 319 free(moduleImage); 320 321 return B_OK; 322 } 323 324 325 static void 326 put_module_image(module_image *image) 327 { 328 int32 refCount = atomic_add(&image->ref_count, -1); 329 ASSERT(refCount > 0); 330 331 // Don't unload anything when there is no boot device yet 332 // (because chances are that we will never be able to access it again) 333 334 if (refCount == 1 && !image->keep_loaded && gBootDevice > 0) 335 unload_module_image(image, NULL); 336 } 337 338 339 static status_t 340 get_module_image(const char *path, module_image **_image) 341 { 342 struct module_image *image; 343 344 TRACE(("get_module_image(path = \"%s\")\n", path)); 345 346 RecursiveLocker _(sModulesLock); 347 348 image = (module_image *)hash_lookup(sModuleImagesHash, path); 349 if (image == NULL) { 350 status_t status = load_module_image(path, &image); 351 if (status < B_OK) 352 return status; 353 } 354 355 atomic_add(&image->ref_count, 1); 356 *_image = image; 357 358 return B_OK; 359 } 360 361 362 /*! Extract the information from the module_info structure pointed at 363 by "info" and create the entries required for access to it's details. 364 */ 365 static status_t 366 create_module(module_info *info, const char *file, int offset, module **_module) 367 { 368 module *module; 369 370 TRACE(("create_module(info = %p, file = \"%s\", offset = %d, _module = %p)\n", 371 info, file, offset, _module)); 372 373 if (!info->name) 374 return B_BAD_VALUE; 375 376 module = (struct module *)hash_lookup(sModulesHash, info->name); 377 if (module) { 378 FATAL(("Duplicate module name (%s) detected... ignoring new one\n", info->name)); 379 return B_FILE_EXISTS; 380 } 381 382 if ((module = (struct module *)malloc(sizeof(struct module))) == NULL) 383 return B_NO_MEMORY; 384 385 TRACE(("create_module: name = \"%s\", file = \"%s\"\n", info->name, file)); 386 387 module->module_image = NULL; 388 module->name = strdup(info->name); 389 if (module->name == NULL) { 390 free(module); 391 return B_NO_MEMORY; 392 } 393 394 module->file = strdup(file); 395 if (module->file == NULL) { 396 free(module->name); 397 free(module); 398 return B_NO_MEMORY; 399 } 400 401 module->state = MODULE_QUERIED; 402 module->info = info; 403 module->offset = offset; 404 // record where the module_info can be found in the module_info array 405 module->ref_count = 0; 406 module->flags = info->flags; 407 408 recursive_lock_lock(&sModulesLock); 409 hash_insert(sModulesHash, module); 410 recursive_lock_unlock(&sModulesLock); 411 412 if (_module) 413 *_module = module; 414 415 return B_OK; 416 } 417 418 419 /*! Loads the file at "path" and scans all modules contained therein. 420 Returns B_OK if "searchedName" could be found under those modules, 421 B_ENTRY_NOT_FOUND if not. 422 Must only be called for files that haven't been scanned yet. 423 "searchedName" is allowed to be NULL (if all modules should be scanned) 424 */ 425 static status_t 426 check_module_image(const char *path, const char *searchedName) 427 { 428 module_image *image; 429 module_info **info; 430 int index = 0, match = B_ENTRY_NOT_FOUND; 431 432 TRACE(("check_module_image(path = \"%s\", searchedName = \"%s\")\n", path, 433 searchedName)); 434 435 if (get_module_image(path, &image) < B_OK) 436 return B_ENTRY_NOT_FOUND; 437 438 for (info = image->info; *info; info++) { 439 // try to create a module for every module_info, check if the 440 // name matches if it was a new entry 441 if (create_module(*info, path, index++, NULL) == B_OK) { 442 if (searchedName && !strcmp((*info)->name, searchedName)) 443 match = B_OK; 444 } 445 } 446 447 // The module we looked for couldn't be found, so we can unload the 448 // loaded module at this point 449 if (match != B_OK) { 450 TRACE(("check_module_file: unloading module file \"%s\" (not used yet)\n", 451 path)); 452 unload_module_image(image, path); 453 } 454 455 // decrement the ref we got in get_module_image 456 put_module_image(image); 457 458 return match; 459 } 460 461 462 /*! This is only called if we fail to find a module already in our cache... 463 saves us some extra checking here :) 464 */ 465 static module * 466 search_module(const char *name) 467 { 468 status_t status = B_ENTRY_NOT_FOUND; 469 uint32 i; 470 471 TRACE(("search_module(%s)\n", name)); 472 473 for (i = kNumModulePaths; i-- > 0;) { 474 if (sDisableUserAddOns && i >= kFirstNonSystemModulePath) 475 continue; 476 477 // let the VFS find that module for us 478 479 KPath basePath; 480 if (find_directory(kModulePaths[i], gBootDevice, true, 481 basePath.LockBuffer(), basePath.BufferSize()) != B_OK) 482 continue; 483 484 basePath.UnlockBuffer(); 485 basePath.Append("kernel"); 486 487 KPath path; 488 status = vfs_get_module_path(basePath.Path(), name, path.LockBuffer(), 489 path.BufferSize()); 490 if (status == B_OK) { 491 path.UnlockBuffer(); 492 status = check_module_image(path.Path(), name); 493 if (status == B_OK) 494 break; 495 } 496 } 497 498 if (status != B_OK) 499 return NULL; 500 501 return (module *)hash_lookup(sModulesHash, name); 502 } 503 504 505 static status_t 506 put_dependent_modules(struct module *module) 507 { 508 module_image *image = module->module_image; 509 module_dependency *dependencies; 510 511 // built-in modules don't have a module_image structure 512 if (image == NULL 513 || (dependencies = image->dependencies) == NULL) 514 return B_OK; 515 516 for (int32 i = 0; dependencies[i].name != NULL; i++) { 517 status_t status = put_module(dependencies[i].name); 518 if (status < B_OK) 519 return status; 520 } 521 522 return B_OK; 523 } 524 525 526 static status_t 527 get_dependent_modules(struct module *module) 528 { 529 module_image *image = module->module_image; 530 module_dependency *dependencies; 531 532 // built-in modules don't have a module_image structure 533 if (image == NULL 534 || (dependencies = image->dependencies) == NULL) 535 return B_OK; 536 537 TRACE(("resolving module dependencies...\n")); 538 539 for (int32 i = 0; dependencies[i].name != NULL; i++) { 540 status_t status = get_module(dependencies[i].name, 541 dependencies[i].info); 542 if (status < B_OK) { 543 dprintf("loading dependent module %s of %s failed!\n", 544 dependencies[i].name, module->name); 545 return status; 546 } 547 } 548 549 return B_OK; 550 } 551 552 553 /*! Initializes a loaded module depending on its state */ 554 static inline status_t 555 init_module(module *module) 556 { 557 switch (module->state) { 558 case MODULE_QUERIED: 559 case MODULE_LOADED: 560 { 561 status_t status; 562 module->state = MODULE_INIT; 563 564 // resolve dependencies 565 566 status = get_dependent_modules(module); 567 if (status < B_OK) { 568 module->state = MODULE_LOADED; 569 return status; 570 } 571 572 // init module 573 574 TRACE(("initializing module %s (at %p)... \n", module->name, module->info->std_ops)); 575 576 if (module->info->std_ops != NULL) 577 status = module->info->std_ops(B_MODULE_INIT); 578 579 TRACE(("...done (%s)\n", strerror(status))); 580 581 if (status >= B_OK) 582 module->state = MODULE_READY; 583 else { 584 put_dependent_modules(module); 585 module->state = MODULE_LOADED; 586 } 587 588 return status; 589 } 590 591 case MODULE_READY: 592 return B_OK; 593 594 case MODULE_INIT: 595 FATAL(("circular reference to %s\n", module->name)); 596 return B_ERROR; 597 598 case MODULE_UNINIT: 599 FATAL(("tried to load module %s which is currently unloading\n", module->name)); 600 return B_ERROR; 601 602 case MODULE_ERROR: 603 FATAL(("cannot load module %s because its earlier unloading failed\n", module->name)); 604 return B_ERROR; 605 606 default: 607 return B_ERROR; 608 } 609 // never trespasses here 610 } 611 612 613 /*! Uninitializes a module depeding on its state */ 614 static inline int 615 uninit_module(module *module) 616 { 617 TRACE(("uninit_module(%s)\n", module->name)); 618 619 switch (module->state) { 620 case MODULE_QUERIED: 621 case MODULE_LOADED: 622 return B_NO_ERROR; 623 624 case MODULE_INIT: 625 panic("Trying to unload module %s which is initializing\n", module->name); 626 return B_ERROR; 627 628 case MODULE_UNINIT: 629 panic("Trying to unload module %s which is un-initializing\n", module->name); 630 return B_ERROR; 631 632 case MODULE_READY: 633 { 634 status_t status = B_OK; 635 module->state = MODULE_UNINIT; 636 637 TRACE(("uninitializing module %s...\n", module->name)); 638 639 if (module->info->std_ops != NULL) 640 status = module->info->std_ops(B_MODULE_UNINIT); 641 642 TRACE(("...done (%s)\n", strerror(status))); 643 644 if (status == B_OK) { 645 module->state = MODULE_LOADED; 646 put_dependent_modules(module); 647 return B_OK; 648 } 649 650 FATAL(("Error unloading module %s (%s)\n", module->name, 651 strerror(status))); 652 653 module->state = MODULE_ERROR; 654 module->flags |= B_KEEP_LOADED; 655 656 return status; 657 } 658 default: 659 return B_ERROR; 660 } 661 // never trespasses here 662 } 663 664 665 static const char * 666 iterator_pop_path_from_stack(module_iterator *iterator, uint32 *_baseLength) 667 { 668 if (iterator->stack_current <= 0) 669 return NULL; 670 671 if (_baseLength) 672 *_baseLength = iterator->stack[iterator->stack_current - 1].base_length; 673 674 return iterator->stack[--iterator->stack_current].name; 675 } 676 677 678 static status_t 679 iterator_push_path_on_stack(module_iterator *iterator, const char *path, uint32 baseLength) 680 { 681 if (iterator->stack_current + 1 > iterator->stack_size) { 682 // allocate new space on the stack 683 module_path *stack = (module_path *)realloc(iterator->stack, 684 (iterator->stack_size + 8) * sizeof(module_path)); 685 if (stack == NULL) 686 return B_NO_MEMORY; 687 688 iterator->stack = stack; 689 iterator->stack_size += 8; 690 } 691 692 iterator->stack[iterator->stack_current].name = path; 693 iterator->stack[iterator->stack_current++].base_length = baseLength; 694 return B_OK; 695 } 696 697 698 static bool 699 match_iterator_suffix(module_iterator *iterator, const char *name) 700 { 701 if (iterator->suffix == NULL || iterator->suffix_length == 0) 702 return true; 703 704 size_t length = strlen(name); 705 if (length <= iterator->suffix_length) 706 return false; 707 708 return name[length - iterator->suffix_length - 1] == '/' 709 && !strcmp(name + length - iterator->suffix_length, iterator->suffix); 710 } 711 712 713 static status_t 714 iterator_get_next_module(module_iterator *iterator, char *buffer, 715 size_t *_bufferSize) 716 { 717 status_t status; 718 719 TRACE(("iterator_get_next_module() -- start\n")); 720 721 if (iterator->builtin_modules) { 722 for (int32 i = iterator->module_offset; sBuiltInModules[i] != NULL; i++) { 723 // the module name must fit the prefix 724 if (strncmp(sBuiltInModules[i]->name, iterator->prefix, 725 iterator->prefix_length) 726 || !match_iterator_suffix(iterator, sBuiltInModules[i]->name)) 727 continue; 728 729 *_bufferSize = strlcpy(buffer, sBuiltInModules[i]->name, 730 *_bufferSize); 731 iterator->module_offset = i + 1; 732 return B_OK; 733 } 734 iterator->builtin_modules = false; 735 } 736 737 if (iterator->loaded_modules) { 738 recursive_lock_lock(&sModulesLock); 739 hash_iterator hashIterator; 740 hash_open(sModulesHash, &hashIterator); 741 742 struct module *module = (struct module *)hash_next(sModulesHash, 743 &hashIterator); 744 for (int32 i = 0; module != NULL; i++) { 745 if (i >= iterator->module_offset) { 746 if (!strncmp(module->name, iterator->prefix, 747 iterator->prefix_length) 748 && match_iterator_suffix(iterator, module->name)) { 749 *_bufferSize = strlcpy(buffer, module->name, *_bufferSize); 750 iterator->module_offset = i + 1; 751 752 hash_close(sModulesHash, &hashIterator, false); 753 recursive_lock_unlock(&sModulesLock); 754 return B_OK; 755 } 756 } 757 module = (struct module *)hash_next(sModulesHash, &hashIterator); 758 } 759 760 hash_close(sModulesHash, &hashIterator, false); 761 recursive_lock_unlock(&sModulesLock); 762 763 // prevent from falling into modules hash iteration again 764 iterator->loaded_modules = false; 765 } 766 767 nextPath: 768 if (iterator->current_dir == NULL) { 769 // get next directory path from the stack 770 const char *path = iterator_pop_path_from_stack(iterator, 771 &iterator->path_base_length); 772 if (path == NULL) { 773 // we are finished, there are no more entries on the stack 774 return B_ENTRY_NOT_FOUND; 775 } 776 777 free((void *)iterator->current_path); 778 iterator->current_path = path; 779 iterator->current_dir = opendir(path); 780 TRACE(("open directory at %s -> %p\n", path, iterator->current_dir)); 781 782 if (iterator->current_dir == NULL) { 783 // we don't throw an error here, but silently go to 784 // the next directory on the stack 785 goto nextPath; 786 } 787 } 788 789 nextModuleImage: 790 if (iterator->current_header == NULL) { 791 // get next entry from the current directory 792 793 errno = 0; 794 795 struct dirent *dirent; 796 if ((dirent = readdir(iterator->current_dir)) == NULL) { 797 closedir(iterator->current_dir); 798 iterator->current_dir = NULL; 799 800 if (errno < B_OK) 801 return errno; 802 803 goto nextPath; 804 } 805 806 // check if the prefix matches 807 int32 passedOffset, commonLength; 808 passedOffset = strlen(iterator->current_path) + 1; 809 commonLength = iterator->path_base_length + iterator->prefix_length 810 - passedOffset; 811 812 if (commonLength > 0) { 813 // the prefix still reaches into the new path part 814 int32 length = strlen(dirent->d_name); 815 if (commonLength > length) 816 commonLength = length; 817 818 if (strncmp(dirent->d_name, iterator->prefix + passedOffset 819 - iterator->path_base_length, commonLength)) 820 goto nextModuleImage; 821 } 822 823 // we're not interested in traversing these again 824 if (!strcmp(dirent->d_name, ".") 825 || !strcmp(dirent->d_name, "..")) 826 goto nextModuleImage; 827 828 // build absolute path to current file 829 KPath path(iterator->current_path); 830 if (path.InitCheck() != B_OK) 831 return B_NO_MEMORY; 832 833 if (path.Append(dirent->d_name) != B_OK) 834 return B_BUFFER_OVERFLOW; 835 836 // find out if it's a directory or a file 837 struct stat st; 838 if (stat(path.Path(), &st) < 0) 839 return errno; 840 841 iterator->current_module_path = strdup(path.Path()); 842 if (iterator->current_module_path == NULL) 843 return B_NO_MEMORY; 844 845 if (S_ISDIR(st.st_mode)) { 846 status = iterator_push_path_on_stack(iterator, 847 iterator->current_module_path, iterator->path_base_length); 848 if (status < B_OK) 849 return status; 850 851 iterator->current_module_path = NULL; 852 goto nextModuleImage; 853 } 854 855 if (!S_ISREG(st.st_mode)) 856 return B_BAD_TYPE; 857 858 TRACE(("open module at %s\n", path.Path())); 859 860 status = get_module_image(path.Path(), &iterator->module_image); 861 if (status < B_OK) { 862 free((void *)iterator->current_module_path); 863 iterator->current_module_path = NULL; 864 goto nextModuleImage; 865 } 866 867 iterator->current_header = iterator->module_image->info; 868 iterator->module_offset = 0; 869 } 870 871 // search the current module image until we've got a match 872 while (*iterator->current_header != NULL) { 873 module_info *info = *iterator->current_header; 874 875 // TODO: we might want to create a module here and cache it in the 876 // hash table 877 878 iterator->current_header++; 879 iterator->module_offset++; 880 881 if (strncmp(info->name, iterator->prefix, iterator->prefix_length) 882 || !match_iterator_suffix(iterator, info->name)) 883 continue; 884 885 *_bufferSize = strlcpy(buffer, info->name, *_bufferSize); 886 return B_OK; 887 } 888 889 // leave this module and get the next one 890 891 iterator->current_header = NULL; 892 free((void *)iterator->current_module_path); 893 iterator->current_module_path = NULL; 894 895 put_module_image(iterator->module_image); 896 iterator->module_image = NULL; 897 898 goto nextModuleImage; 899 } 900 901 902 static void 903 register_builtin_modules(struct module_info **info) 904 { 905 for (; *info; info++) { 906 (*info)->flags |= B_BUILT_IN_MODULE; 907 // this is an internal flag, it doesn't have to be set by modules itself 908 909 if (create_module(*info, "", -1, NULL) != B_OK) 910 dprintf("creation of built-in module \"%s\" failed!\n", (*info)->name); 911 } 912 } 913 914 915 static status_t 916 register_preloaded_module_image(struct preloaded_image *image) 917 { 918 module_image *moduleImage; 919 struct module_info **info; 920 status_t status; 921 int32 index = 0; 922 923 TRACE(("register_preloaded_module_image(image = \"%s\")\n", image->name)); 924 925 image->is_module = false; 926 927 if (image->id < 0) 928 return B_BAD_VALUE; 929 930 moduleImage = (module_image *)malloc(sizeof(module_image)); 931 if (moduleImage == NULL) 932 return B_NO_MEMORY; 933 934 if (get_image_symbol(image->id, "modules", B_SYMBOL_TYPE_DATA, 935 (void **)&moduleImage->info) != B_OK) { 936 status = B_BAD_TYPE; 937 goto error; 938 } 939 940 image->is_module = true; 941 942 moduleImage->dependencies = NULL; 943 get_image_symbol(image->id, "module_dependencies", B_SYMBOL_TYPE_DATA, 944 (void **)&moduleImage->dependencies); 945 // this is allowed to be NULL 946 947 // Try to recreate the full module path, so that we don't try to load the 948 // image again when asked for a module it does not export (would only be 949 // problematic if it had got replaced and the new file actually exports 950 // that module). Also helpful for recurse_directory(). 951 { 952 // ToDo: this is kind of a hack to have the full path in the hash 953 // (it always assumes the preloaded add-ons to be in the system 954 // directory) 955 char path[B_FILE_NAME_LENGTH]; 956 const char *name, *suffix; 957 if (moduleImage->info[0] 958 && (suffix = strstr(name = moduleImage->info[0]->name, 959 image->name)) != NULL) { 960 // even if strlcpy() is used here, it's by no means safe 961 // against buffer overflows 962 KPath addonsKernelPath; 963 status_t status = find_directory(B_BEOS_ADDONS_DIRECTORY, 964 gBootDevice, false, addonsKernelPath.LockBuffer(), 965 addonsKernelPath.BufferSize()); 966 if (status != B_OK) { 967 dprintf("register_preloaded_module_image: find_directory() " 968 "failed: %s\n", strerror(status)); 969 } 970 addonsKernelPath.UnlockBuffer(); 971 if (status == B_OK) { 972 status = addonsKernelPath.Append("kernel/"); 973 // KPath does not remove the trailing '/' 974 } 975 if (status == B_OK) { 976 size_t length = strlcpy(path, addonsKernelPath.Path(), 977 sizeof(path)); 978 strlcpy(path + length, name, strlen(image->name) 979 + 1 + (suffix - name)); 980 981 moduleImage->path = strdup(path); 982 } else { 983 moduleImage->path = NULL; 984 // this will trigger B_NO_MEMORY, which is the only 985 // reason to get here anyways... 986 } 987 } else 988 moduleImage->path = strdup(image->name); 989 } 990 if (moduleImage->path == NULL) { 991 status = B_NO_MEMORY; 992 goto error; 993 } 994 995 moduleImage->image = image->id; 996 moduleImage->ref_count = 0; 997 moduleImage->keep_loaded = false; 998 999 hash_insert(sModuleImagesHash, moduleImage); 1000 1001 for (info = moduleImage->info; *info; info++) { 1002 create_module(*info, moduleImage->path, index++, NULL); 1003 } 1004 1005 return B_OK; 1006 1007 error: 1008 free(moduleImage); 1009 1010 // We don't need this image anymore. We keep it, if it doesn't look like 1011 // a module at all. It might be an old-style driver. 1012 if (image->is_module) 1013 unload_kernel_add_on(image->id); 1014 1015 return status; 1016 } 1017 1018 1019 static int 1020 dump_modules(int argc, char **argv) 1021 { 1022 hash_iterator iterator; 1023 struct module_image *image; 1024 struct module *module; 1025 1026 hash_rewind(sModulesHash, &iterator); 1027 dprintf("-- known modules:\n"); 1028 1029 while ((module = (struct module *)hash_next(sModulesHash, &iterator)) != NULL) { 1030 dprintf("%p: \"%s\", \"%s\" (%ld), refcount = %ld, state = %d, mimage = %p\n", 1031 module, module->name, module->file, module->offset, module->ref_count, 1032 module->state, module->module_image); 1033 } 1034 1035 hash_rewind(sModuleImagesHash, &iterator); 1036 dprintf("\n-- loaded module images:\n"); 1037 1038 while ((image = (struct module_image *)hash_next(sModuleImagesHash, &iterator)) != NULL) { 1039 dprintf("%p: \"%s\" (image_id = %ld), info = %p, refcount = %ld, %s\n", image, 1040 image->path, image->image, image->info, image->ref_count, 1041 image->keep_loaded ? "keep loaded" : "can be unloaded"); 1042 } 1043 return 0; 1044 } 1045 1046 1047 // #pragma mark - Exported Kernel API (private part) 1048 1049 1050 /*! Unloads a module in case it's not in use. This is the counterpart 1051 to load_module(). 1052 */ 1053 status_t 1054 unload_module(const char *path) 1055 { 1056 struct module_image *moduleImage; 1057 1058 recursive_lock_lock(&sModulesLock); 1059 moduleImage = (module_image *)hash_lookup(sModuleImagesHash, path); 1060 recursive_lock_unlock(&sModulesLock); 1061 1062 if (moduleImage == NULL) 1063 return B_ENTRY_NOT_FOUND; 1064 1065 put_module_image(moduleImage); 1066 return B_OK; 1067 } 1068 1069 1070 /*! Unlike get_module(), this function lets you specify the add-on to 1071 be loaded by path. 1072 However, you must not use the exported modules without having called 1073 get_module() on them. When you're done with the NULL terminated 1074 \a modules array, you have to call unload_module(), no matter if 1075 you're actually using any of the modules or not - of course, the 1076 add-on won't be unloaded until the last put_module(). 1077 */ 1078 status_t 1079 load_module(const char *path, module_info ***_modules) 1080 { 1081 module_image *moduleImage; 1082 status_t status = get_module_image(path, &moduleImage); 1083 if (status != B_OK) 1084 return status; 1085 1086 *_modules = moduleImage->info; 1087 return B_OK; 1088 } 1089 1090 1091 /*! Setup the module structures and data for use - must be called 1092 before any other module call. 1093 */ 1094 status_t 1095 module_init(kernel_args *args) 1096 { 1097 struct preloaded_image *image; 1098 1099 if (recursive_lock_init(&sModulesLock, "modules rlock") < B_OK) 1100 return B_ERROR; 1101 1102 sModulesHash = hash_init(MODULE_HASH_SIZE, 0, module_compare, module_hash); 1103 if (sModulesHash == NULL) 1104 return B_NO_MEMORY; 1105 1106 sModuleImagesHash = hash_init(MODULE_HASH_SIZE, 0, module_image_compare, 1107 module_image_hash); 1108 if (sModuleImagesHash == NULL) 1109 return B_NO_MEMORY; 1110 1111 // register built-in modules 1112 1113 register_builtin_modules(sBuiltInModules); 1114 1115 // register preloaded images 1116 1117 for (image = args->preloaded_images; image != NULL; image = image->next) { 1118 status_t status = register_preloaded_module_image(image); 1119 if (status != B_OK) { 1120 dprintf("Could not register image \"%s\": %s\n", image->name, 1121 strerror(status)); 1122 } 1123 } 1124 1125 sDisableUserAddOns = get_safemode_boolean(B_SAFEMODE_DISABLE_USER_ADD_ONS, 1126 false); 1127 1128 add_debugger_command("modules", &dump_modules, 1129 "list all known & loaded modules"); 1130 1131 return B_OK; 1132 } 1133 1134 1135 // #pragma mark - Exported Kernel API (public part) 1136 1137 1138 /*! This returns a pointer to a structure that can be used to 1139 iterate through a list of all modules available under 1140 a given prefix that adhere to the specified suffix. 1141 All paths will be searched and the returned list will 1142 contain all modules available under the prefix. 1143 The structure is then used by read_next_module_name(), and 1144 must be freed by calling close_module_list(). 1145 */ 1146 void * 1147 open_module_list_etc(const char *prefix, const char *suffix) 1148 { 1149 TRACE(("open_module_list(prefix = %s)\n", prefix)); 1150 1151 if (sModulesHash == NULL) { 1152 dprintf("open_module_list() called too early!\n"); 1153 return NULL; 1154 } 1155 1156 module_iterator *iterator = (module_iterator *)malloc( 1157 sizeof(module_iterator)); 1158 if (!iterator) 1159 return NULL; 1160 1161 memset(iterator, 0, sizeof(module_iterator)); 1162 1163 iterator->prefix = strdup(prefix != NULL ? prefix : ""); 1164 if (iterator->prefix == NULL) { 1165 free(iterator); 1166 return NULL; 1167 } 1168 iterator->prefix_length = strlen(iterator->prefix); 1169 1170 iterator->suffix = suffix; 1171 if (suffix != NULL) 1172 iterator->suffix_length = strlen(iterator->suffix); 1173 1174 if (gBootDevice > 0) { 1175 // We do have a boot device to scan 1176 1177 // first, we'll traverse over the built-in modules 1178 iterator->builtin_modules = true; 1179 iterator->loaded_modules = false; 1180 1181 // put all search paths on the stack 1182 for (uint32 i = 0; i < kNumModulePaths; i++) { 1183 if (sDisableUserAddOns && i >= kFirstNonSystemModulePath) 1184 break; 1185 1186 KPath pathBuffer; 1187 if (find_directory(kModulePaths[i], gBootDevice, true, 1188 pathBuffer.LockBuffer(), pathBuffer.BufferSize()) != B_OK) 1189 continue; 1190 1191 pathBuffer.UnlockBuffer(); 1192 pathBuffer.Append("kernel"); 1193 1194 // Copy base path onto the iterator stack 1195 char *path = strdup(pathBuffer.Path()); 1196 if (path == NULL) 1197 continue; 1198 1199 size_t length = strlen(path); 1200 1201 // TODO: it would currently be nicer to use the commented 1202 // version below, but the iterator won't work if the prefix 1203 // is inside a module then. 1204 // It works this way, but should be done better. 1205 #if 0 1206 // Build path component: base path + '/' + prefix 1207 size_t length = strlen(sModulePaths[i]); 1208 char *path = (char *)malloc(length + iterator->prefix_length + 2); 1209 if (path == NULL) { 1210 // ToDo: should we abort the whole operation here? 1211 // if we do, don't forget to empty the stack 1212 continue; 1213 } 1214 1215 memcpy(path, sModulePaths[i], length); 1216 path[length] = '/'; 1217 memcpy(path + length + 1, iterator->prefix, 1218 iterator->prefix_length + 1); 1219 #endif 1220 1221 iterator_push_path_on_stack(iterator, path, length + 1); 1222 } 1223 } else { 1224 // include loaded modules in case there is no boot device yet 1225 iterator->builtin_modules = false; 1226 iterator->loaded_modules = true; 1227 } 1228 1229 return (void *)iterator; 1230 } 1231 1232 1233 void * 1234 open_module_list(const char *prefix) 1235 { 1236 return open_module_list_etc(prefix, NULL); 1237 } 1238 1239 1240 /*! Frees the cookie allocated by open_module_list() */ 1241 status_t 1242 close_module_list(void *cookie) 1243 { 1244 module_iterator *iterator = (module_iterator *)cookie; 1245 const char *path; 1246 1247 TRACE(("close_module_list()\n")); 1248 1249 if (iterator == NULL) 1250 return B_BAD_VALUE; 1251 1252 // free stack 1253 while ((path = iterator_pop_path_from_stack(iterator, NULL)) != NULL) 1254 free((void *)path); 1255 1256 // close what have been left open 1257 if (iterator->module_image != NULL) 1258 put_module_image(iterator->module_image); 1259 1260 if (iterator->current_dir != NULL) 1261 closedir(iterator->current_dir); 1262 1263 free(iterator->stack); 1264 free((void *)iterator->current_path); 1265 free((void *)iterator->current_module_path); 1266 1267 free(iterator->prefix); 1268 free(iterator); 1269 1270 return B_OK; 1271 } 1272 1273 1274 /*! Return the next module name from the available list, using 1275 a structure previously created by a call to open_module_list(). 1276 Returns B_OK as long as it found another module, B_ENTRY_NOT_FOUND 1277 when done. 1278 */ 1279 status_t 1280 read_next_module_name(void *cookie, char *buffer, size_t *_bufferSize) 1281 { 1282 module_iterator *iterator = (module_iterator *)cookie; 1283 status_t status; 1284 1285 TRACE(("read_next_module_name: looking for next module\n")); 1286 1287 if (iterator == NULL || buffer == NULL || _bufferSize == NULL) 1288 return B_BAD_VALUE; 1289 1290 if (iterator->status < B_OK) 1291 return iterator->status; 1292 1293 status = iterator->status; 1294 recursive_lock_lock(&sModulesLock); 1295 1296 status = iterator_get_next_module(iterator, buffer, _bufferSize); 1297 1298 iterator->status = status; 1299 recursive_lock_unlock(&sModulesLock); 1300 1301 TRACE(("read_next_module_name: finished with status %s\n", 1302 strerror(status))); 1303 return status; 1304 } 1305 1306 1307 /*! Iterates through all loaded modules, and stores its path in "buffer". 1308 ToDo: check if the function in BeOS really does that (could also mean: 1309 iterate through all modules that are currently loaded; have a valid 1310 module_image pointer, which would be hard to test for) 1311 */ 1312 status_t 1313 get_next_loaded_module_name(uint32 *_cookie, char *buffer, size_t *_bufferSize) 1314 { 1315 if (sModulesHash == NULL) { 1316 dprintf("get_next_loaded_module_name() called too early!\n"); 1317 return B_ERROR; 1318 } 1319 1320 //TRACE(("get_next_loaded_module_name(\"%s\")\n", buffer)); 1321 1322 if (_cookie == NULL || buffer == NULL || _bufferSize == NULL) 1323 return B_BAD_VALUE; 1324 1325 status_t status = B_ENTRY_NOT_FOUND; 1326 uint32 offset = *_cookie; 1327 1328 RecursiveLocker _(sModulesLock); 1329 1330 hash_iterator iterator; 1331 hash_open(sModulesHash, &iterator); 1332 struct module *module = (struct module *)hash_next(sModulesHash, 1333 &iterator); 1334 1335 for (uint32 i = 0; module != NULL; i++) { 1336 if (i >= offset) { 1337 *_bufferSize = strlcpy(buffer, module->name, *_bufferSize); 1338 *_cookie = i + 1; 1339 status = B_OK; 1340 break; 1341 } 1342 module = (struct module *)hash_next(sModulesHash, &iterator); 1343 } 1344 1345 hash_close(sModulesHash, &iterator, false); 1346 1347 return status; 1348 } 1349 1350 1351 status_t 1352 get_module(const char *path, module_info **_info) 1353 { 1354 module_image *moduleImage; 1355 module *module; 1356 status_t status; 1357 1358 TRACE(("get_module(%s)\n", path)); 1359 1360 if (path == NULL) 1361 return B_BAD_VALUE; 1362 1363 RecursiveLocker _(sModulesLock); 1364 1365 module = (struct module *)hash_lookup(sModulesHash, path); 1366 1367 // if we don't have it cached yet, search for it 1368 if (module == NULL) { 1369 module = search_module(path); 1370 if (module == NULL) { 1371 FATAL(("module: Search for %s failed.\n", path)); 1372 return B_ENTRY_NOT_FOUND; 1373 } 1374 } 1375 1376 if ((module->flags & B_BUILT_IN_MODULE) == 0) { 1377 /* We now need to find the module_image for the module. This should 1378 * be in memory if we have just run search_module(), but may not be 1379 * if we are using cached information. 1380 * We can't use the module->module_image pointer, because it is not 1381 * reliable at this point (it won't be set to NULL when the module_image 1382 * is unloaded). 1383 */ 1384 if (get_module_image(module->file, &moduleImage) < B_OK) 1385 return B_ENTRY_NOT_FOUND; 1386 1387 // (re)set in-memory data for the loaded module 1388 module->info = moduleImage->info[module->offset]; 1389 module->module_image = moduleImage; 1390 1391 // the module image must not be unloaded anymore 1392 if (module->flags & B_KEEP_LOADED) 1393 module->module_image->keep_loaded = true; 1394 } 1395 1396 // The state will be adjusted by the call to init_module 1397 // if we have just loaded the file 1398 if (module->ref_count == 0) 1399 status = init_module(module); 1400 else 1401 status = B_OK; 1402 1403 if (status == B_OK) { 1404 if (module->ref_count < 0) 1405 panic("argl %s", path); 1406 module->ref_count++; 1407 *_info = module->info; 1408 } else if ((module->flags & B_BUILT_IN_MODULE) == 0 1409 && (module->flags & B_KEEP_LOADED) == 0) 1410 put_module_image(module->module_image); 1411 1412 return status; 1413 } 1414 1415 1416 status_t 1417 put_module(const char *path) 1418 { 1419 module *module; 1420 1421 TRACE(("put_module(path = %s)\n", path)); 1422 1423 RecursiveLocker _(sModulesLock); 1424 1425 module = (struct module *)hash_lookup(sModulesHash, path); 1426 if (module == NULL) { 1427 FATAL(("module: We don't seem to have a reference to module %s\n", 1428 path)); 1429 return B_BAD_VALUE; 1430 } 1431 1432 if (module->ref_count == 0) 1433 panic("module %s has no references.\n", path); 1434 1435 if ((module->flags & B_KEEP_LOADED) == 0) { 1436 if (--module->ref_count == 0) 1437 uninit_module(module); 1438 } else if ((module->flags & B_BUILT_IN_MODULE) == 0) 1439 put_module_image(module->module_image); 1440 1441 return B_OK; 1442 } 1443