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