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 if (recursive_lock_init(&sModulesLock, "modules rlock") < B_OK) 1098 return B_ERROR; 1099 1100 sModulesHash = hash_init(MODULE_HASH_SIZE, 0, module_compare, module_hash); 1101 if (sModulesHash == NULL) 1102 return B_NO_MEMORY; 1103 1104 sModuleImagesHash = hash_init(MODULE_HASH_SIZE, 0, module_image_compare, 1105 module_image_hash); 1106 if (sModuleImagesHash == NULL) 1107 return B_NO_MEMORY; 1108 1109 // register built-in modules 1110 1111 register_builtin_modules(sBuiltInModules); 1112 1113 // register preloaded images 1114 1115 for (image = args->preloaded_images; image != NULL; image = image->next) { 1116 status_t status = register_preloaded_module_image(image); 1117 if (status != B_OK) { 1118 dprintf("Could not register image \"%s\": %s\n", image->name, 1119 strerror(status)); 1120 } 1121 } 1122 1123 sDisableUserAddOns = get_safemode_boolean(B_SAFEMODE_DISABLE_USER_ADD_ONS, 1124 false); 1125 1126 add_debugger_command("modules", &dump_modules, 1127 "list all known & loaded modules"); 1128 1129 return B_OK; 1130 } 1131 1132 1133 // #pragma mark - Exported Kernel API (public part) 1134 1135 1136 /*! This returns a pointer to a structure that can be used to 1137 iterate through a list of all modules available under 1138 a given prefix that adhere to the specified suffix. 1139 All paths will be searched and the returned list will 1140 contain all modules available under the prefix. 1141 The structure is then used by read_next_module_name(), and 1142 must be freed by calling close_module_list(). 1143 */ 1144 void * 1145 open_module_list_etc(const char *prefix, const char *suffix) 1146 { 1147 TRACE(("open_module_list(prefix = %s)\n", prefix)); 1148 1149 if (sModulesHash == NULL) { 1150 dprintf("open_module_list() called too early!\n"); 1151 return NULL; 1152 } 1153 1154 module_iterator *iterator = (module_iterator *)malloc( 1155 sizeof(module_iterator)); 1156 if (!iterator) 1157 return NULL; 1158 1159 memset(iterator, 0, sizeof(module_iterator)); 1160 1161 iterator->prefix = strdup(prefix != NULL ? prefix : ""); 1162 if (iterator->prefix == NULL) { 1163 free(iterator); 1164 return NULL; 1165 } 1166 iterator->prefix_length = strlen(iterator->prefix); 1167 1168 iterator->suffix = suffix; 1169 if (suffix != NULL) 1170 iterator->suffix_length = strlen(iterator->suffix); 1171 1172 if (gBootDevice > 0) { 1173 // We do have a boot device to scan 1174 1175 // first, we'll traverse over the built-in modules 1176 iterator->builtin_modules = true; 1177 iterator->loaded_modules = false; 1178 1179 // put all search paths on the stack 1180 for (uint32 i = 0; i < kNumModulePaths; i++) { 1181 if (sDisableUserAddOns && i >= kFirstNonSystemModulePath) 1182 break; 1183 1184 KPath pathBuffer; 1185 if (find_directory(kModulePaths[i], gBootDevice, true, 1186 pathBuffer.LockBuffer(), pathBuffer.BufferSize()) != B_OK) 1187 continue; 1188 1189 pathBuffer.UnlockBuffer(); 1190 pathBuffer.Append("kernel"); 1191 1192 // Copy base path onto the iterator stack 1193 char *path = strdup(pathBuffer.Path()); 1194 if (path == NULL) 1195 continue; 1196 1197 size_t length = strlen(path); 1198 1199 // TODO: it would currently be nicer to use the commented 1200 // version below, but the iterator won't work if the prefix 1201 // is inside a module then. 1202 // It works this way, but should be done better. 1203 #if 0 1204 // Build path component: base path + '/' + prefix 1205 size_t length = strlen(sModulePaths[i]); 1206 char *path = (char *)malloc(length + iterator->prefix_length + 2); 1207 if (path == NULL) { 1208 // ToDo: should we abort the whole operation here? 1209 // if we do, don't forget to empty the stack 1210 continue; 1211 } 1212 1213 memcpy(path, sModulePaths[i], length); 1214 path[length] = '/'; 1215 memcpy(path + length + 1, iterator->prefix, 1216 iterator->prefix_length + 1); 1217 #endif 1218 1219 iterator_push_path_on_stack(iterator, path, length + 1); 1220 } 1221 } else { 1222 // include loaded modules in case there is no boot device yet 1223 iterator->builtin_modules = false; 1224 iterator->loaded_modules = true; 1225 } 1226 1227 return (void *)iterator; 1228 } 1229 1230 1231 void * 1232 open_module_list(const char *prefix) 1233 { 1234 return open_module_list_etc(prefix, NULL); 1235 } 1236 1237 1238 /*! Frees the cookie allocated by open_module_list() */ 1239 status_t 1240 close_module_list(void *cookie) 1241 { 1242 module_iterator *iterator = (module_iterator *)cookie; 1243 const char *path; 1244 1245 TRACE(("close_module_list()\n")); 1246 1247 if (iterator == NULL) 1248 return B_BAD_VALUE; 1249 1250 // free stack 1251 while ((path = iterator_pop_path_from_stack(iterator, NULL)) != NULL) 1252 free((void *)path); 1253 1254 // close what have been left open 1255 if (iterator->module_image != NULL) 1256 put_module_image(iterator->module_image); 1257 1258 if (iterator->current_dir != NULL) 1259 closedir(iterator->current_dir); 1260 1261 free(iterator->stack); 1262 free((void *)iterator->current_path); 1263 free((void *)iterator->current_module_path); 1264 1265 free(iterator->prefix); 1266 free(iterator); 1267 1268 return B_OK; 1269 } 1270 1271 1272 /*! Return the next module name from the available list, using 1273 a structure previously created by a call to open_module_list(). 1274 Returns B_OK as long as it found another module, B_ENTRY_NOT_FOUND 1275 when done. 1276 */ 1277 status_t 1278 read_next_module_name(void *cookie, char *buffer, size_t *_bufferSize) 1279 { 1280 module_iterator *iterator = (module_iterator *)cookie; 1281 status_t status; 1282 1283 TRACE(("read_next_module_name: looking for next module\n")); 1284 1285 if (iterator == NULL || buffer == NULL || _bufferSize == NULL) 1286 return B_BAD_VALUE; 1287 1288 if (iterator->status < B_OK) 1289 return iterator->status; 1290 1291 status = iterator->status; 1292 recursive_lock_lock(&sModulesLock); 1293 1294 status = iterator_get_next_module(iterator, buffer, _bufferSize); 1295 1296 iterator->status = status; 1297 recursive_lock_unlock(&sModulesLock); 1298 1299 TRACE(("read_next_module_name: finished with status %s\n", 1300 strerror(status))); 1301 return status; 1302 } 1303 1304 1305 /*! Iterates through all loaded modules, and stores its path in "buffer". 1306 ToDo: check if the function in BeOS really does that (could also mean: 1307 iterate through all modules that are currently loaded; have a valid 1308 module_image pointer, which would be hard to test for) 1309 */ 1310 status_t 1311 get_next_loaded_module_name(uint32 *_cookie, char *buffer, size_t *_bufferSize) 1312 { 1313 if (sModulesHash == NULL) { 1314 dprintf("get_next_loaded_module_name() called too early!\n"); 1315 return B_ERROR; 1316 } 1317 1318 //TRACE(("get_next_loaded_module_name(\"%s\")\n", buffer)); 1319 1320 if (_cookie == NULL || buffer == NULL || _bufferSize == NULL) 1321 return B_BAD_VALUE; 1322 1323 status_t status = B_ENTRY_NOT_FOUND; 1324 uint32 offset = *_cookie; 1325 1326 RecursiveLocker _(sModulesLock); 1327 1328 hash_iterator iterator; 1329 hash_open(sModulesHash, &iterator); 1330 struct module *module = (struct module *)hash_next(sModulesHash, 1331 &iterator); 1332 1333 for (uint32 i = 0; module != NULL; i++) { 1334 if (i >= offset) { 1335 *_bufferSize = strlcpy(buffer, module->name, *_bufferSize); 1336 *_cookie = i + 1; 1337 status = B_OK; 1338 break; 1339 } 1340 module = (struct module *)hash_next(sModulesHash, &iterator); 1341 } 1342 1343 hash_close(sModulesHash, &iterator, false); 1344 1345 return status; 1346 } 1347 1348 1349 status_t 1350 get_module(const char *path, module_info **_info) 1351 { 1352 module_image *moduleImage; 1353 module *module; 1354 status_t status; 1355 1356 TRACE(("get_module(%s)\n", path)); 1357 1358 if (path == NULL) 1359 return B_BAD_VALUE; 1360 1361 RecursiveLocker _(sModulesLock); 1362 1363 module = (struct module *)hash_lookup(sModulesHash, path); 1364 1365 // if we don't have it cached yet, search for it 1366 if (module == NULL) { 1367 module = search_module(path); 1368 if (module == NULL) { 1369 FATAL(("module: Search for %s failed.\n", path)); 1370 return B_ENTRY_NOT_FOUND; 1371 } 1372 } 1373 1374 if ((module->flags & B_BUILT_IN_MODULE) == 0) { 1375 /* We now need to find the module_image for the module. This should 1376 * be in memory if we have just run search_module(), but may not be 1377 * if we are using cached information. 1378 * We can't use the module->module_image pointer, because it is not 1379 * reliable at this point (it won't be set to NULL when the module_image 1380 * is unloaded). 1381 */ 1382 if (get_module_image(module->file, &moduleImage) < B_OK) 1383 return B_ENTRY_NOT_FOUND; 1384 1385 // (re)set in-memory data for the loaded module 1386 module->info = moduleImage->info[module->offset]; 1387 module->module_image = moduleImage; 1388 1389 // the module image must not be unloaded anymore 1390 if (module->flags & B_KEEP_LOADED) 1391 module->module_image->keep_loaded = true; 1392 } 1393 1394 // The state will be adjusted by the call to init_module 1395 // if we have just loaded the file 1396 if (module->ref_count == 0) 1397 status = init_module(module); 1398 else 1399 status = B_OK; 1400 1401 if (status == B_OK) { 1402 if (module->ref_count < 0) 1403 panic("argl %s", path); 1404 module->ref_count++; 1405 *_info = module->info; 1406 } else if ((module->flags & B_BUILT_IN_MODULE) == 0 1407 && (module->flags & B_KEEP_LOADED) == 0) 1408 put_module_image(module->module_image); 1409 1410 return status; 1411 } 1412 1413 1414 status_t 1415 put_module(const char *path) 1416 { 1417 module *module; 1418 1419 TRACE(("put_module(path = %s)\n", path)); 1420 1421 RecursiveLocker _(sModulesLock); 1422 1423 module = (struct module *)hash_lookup(sModulesHash, path); 1424 if (module == NULL) { 1425 FATAL(("module: We don't seem to have a reference to module %s\n", 1426 path)); 1427 return B_BAD_VALUE; 1428 } 1429 1430 if (module->ref_count == 0) 1431 panic("module %s has no references.\n", path); 1432 1433 if ((module->flags & B_KEEP_LOADED) == 0) { 1434 if (--module->ref_count == 0) 1435 uninit_module(module); 1436 } else if ((module->flags & B_BUILT_IN_MODULE) == 0) 1437 put_module_image(module->module_image); 1438 1439 return B_OK; 1440 } 1441