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 directory) 954 char path[B_FILE_NAME_LENGTH]; 955 const char *name, *suffix; 956 if (moduleImage->info[0] 957 && (suffix = strstr(name = moduleImage->info[0]->name, 958 image->name)) != NULL) { 959 // even if strlcpy() is used here, it's by no means safe 960 // against buffer overflows 961 size_t length = strlcpy(path, "/boot/beos/system/add-ons/kernel/", 962 sizeof(path)); 963 strlcpy(path + length, name, strlen(image->name) 964 + 1 + (suffix - name)); 965 966 moduleImage->path = strdup(path); 967 } else 968 moduleImage->path = strdup(image->name); 969 } 970 if (moduleImage->path == NULL) { 971 status = B_NO_MEMORY; 972 goto error; 973 } 974 975 moduleImage->image = image->id; 976 moduleImage->ref_count = 0; 977 moduleImage->keep_loaded = false; 978 979 hash_insert(sModuleImagesHash, moduleImage); 980 981 for (info = moduleImage->info; *info; info++) { 982 create_module(*info, moduleImage->path, index++, NULL); 983 } 984 985 return B_OK; 986 987 error: 988 free(moduleImage); 989 990 // We don't need this image anymore. We keep it, if it doesn't look like 991 // a module at all. It might be an old-style driver. 992 if (image->is_module) 993 unload_kernel_add_on(image->id); 994 995 return status; 996 } 997 998 999 static int 1000 dump_modules(int argc, char **argv) 1001 { 1002 hash_iterator iterator; 1003 struct module_image *image; 1004 struct module *module; 1005 1006 hash_rewind(sModulesHash, &iterator); 1007 dprintf("-- known modules:\n"); 1008 1009 while ((module = (struct module *)hash_next(sModulesHash, &iterator)) != NULL) { 1010 dprintf("%p: \"%s\", \"%s\" (%ld), refcount = %ld, state = %d, mimage = %p\n", 1011 module, module->name, module->file, module->offset, module->ref_count, 1012 module->state, module->module_image); 1013 } 1014 1015 hash_rewind(sModuleImagesHash, &iterator); 1016 dprintf("\n-- loaded module images:\n"); 1017 1018 while ((image = (struct module_image *)hash_next(sModuleImagesHash, &iterator)) != NULL) { 1019 dprintf("%p: \"%s\" (image_id = %ld), info = %p, refcount = %ld, %s\n", image, 1020 image->path, image->image, image->info, image->ref_count, 1021 image->keep_loaded ? "keep loaded" : "can be unloaded"); 1022 } 1023 return 0; 1024 } 1025 1026 1027 // #pragma mark - Exported Kernel API (private part) 1028 1029 1030 /*! Unloads a module in case it's not in use. This is the counterpart 1031 to load_module(). 1032 */ 1033 status_t 1034 unload_module(const char *path) 1035 { 1036 struct module_image *moduleImage; 1037 1038 recursive_lock_lock(&sModulesLock); 1039 moduleImage = (module_image *)hash_lookup(sModuleImagesHash, path); 1040 recursive_lock_unlock(&sModulesLock); 1041 1042 if (moduleImage == NULL) 1043 return B_ENTRY_NOT_FOUND; 1044 1045 put_module_image(moduleImage); 1046 return B_OK; 1047 } 1048 1049 1050 /*! Unlike get_module(), this function lets you specify the add-on to 1051 be loaded by path. 1052 However, you must not use the exported modules without having called 1053 get_module() on them. When you're done with the NULL terminated 1054 \a modules array, you have to call unload_module(), no matter if 1055 you're actually using any of the modules or not - of course, the 1056 add-on won't be unloaded until the last put_module(). 1057 */ 1058 status_t 1059 load_module(const char *path, module_info ***_modules) 1060 { 1061 module_image *moduleImage; 1062 status_t status = get_module_image(path, &moduleImage); 1063 if (status != B_OK) 1064 return status; 1065 1066 *_modules = moduleImage->info; 1067 return B_OK; 1068 } 1069 1070 1071 /*! Setup the module structures and data for use - must be called 1072 before any other module call. 1073 */ 1074 status_t 1075 module_init(kernel_args *args) 1076 { 1077 struct preloaded_image *image; 1078 1079 if (recursive_lock_init(&sModulesLock, "modules rlock") < B_OK) 1080 return B_ERROR; 1081 1082 sModulesHash = hash_init(MODULE_HASH_SIZE, 0, module_compare, module_hash); 1083 if (sModulesHash == NULL) 1084 return B_NO_MEMORY; 1085 1086 sModuleImagesHash = hash_init(MODULE_HASH_SIZE, 0, module_image_compare, 1087 module_image_hash); 1088 if (sModuleImagesHash == NULL) 1089 return B_NO_MEMORY; 1090 1091 // register built-in modules 1092 1093 register_builtin_modules(sBuiltInModules); 1094 1095 // register preloaded images 1096 1097 for (image = args->preloaded_images; image != NULL; image = image->next) { 1098 status_t status = register_preloaded_module_image(image); 1099 if (status != B_OK) { 1100 dprintf("Could not register image \"%s\": %s\n", image->name, 1101 strerror(status)); 1102 } 1103 } 1104 1105 sDisableUserAddOns = get_safemode_boolean(B_SAFEMODE_DISABLE_USER_ADD_ONS, 1106 false); 1107 1108 add_debugger_command("modules", &dump_modules, 1109 "list all known & loaded modules"); 1110 1111 return B_OK; 1112 } 1113 1114 1115 // #pragma mark - Exported Kernel API (public part) 1116 1117 1118 /*! This returns a pointer to a structure that can be used to 1119 iterate through a list of all modules available under 1120 a given prefix that adhere to the specified suffix. 1121 All paths will be searched and the returned list will 1122 contain all modules available under the prefix. 1123 The structure is then used by read_next_module_name(), and 1124 must be freed by calling close_module_list(). 1125 */ 1126 void * 1127 open_module_list_etc(const char *prefix, const char *suffix) 1128 { 1129 TRACE(("open_module_list(prefix = %s)\n", prefix)); 1130 1131 if (sModulesHash == NULL) { 1132 dprintf("open_module_list() called too early!\n"); 1133 return NULL; 1134 } 1135 1136 module_iterator *iterator = (module_iterator *)malloc( 1137 sizeof(module_iterator)); 1138 if (!iterator) 1139 return NULL; 1140 1141 memset(iterator, 0, sizeof(module_iterator)); 1142 1143 iterator->prefix = strdup(prefix != NULL ? prefix : ""); 1144 if (iterator->prefix == NULL) { 1145 free(iterator); 1146 return NULL; 1147 } 1148 iterator->prefix_length = strlen(iterator->prefix); 1149 1150 iterator->suffix = suffix; 1151 if (suffix != NULL) 1152 iterator->suffix_length = strlen(iterator->suffix); 1153 1154 if (gBootDevice > 0) { 1155 // We do have a boot device to scan 1156 1157 // first, we'll traverse over the built-in modules 1158 iterator->builtin_modules = true; 1159 iterator->loaded_modules = false; 1160 1161 // put all search paths on the stack 1162 for (uint32 i = 0; i < kNumModulePaths; i++) { 1163 if (sDisableUserAddOns && i >= kFirstNonSystemModulePath) 1164 break; 1165 1166 KPath pathBuffer; 1167 if (find_directory(kModulePaths[i], gBootDevice, true, 1168 pathBuffer.LockBuffer(), pathBuffer.BufferSize()) != B_OK) 1169 continue; 1170 1171 pathBuffer.UnlockBuffer(); 1172 pathBuffer.Append("kernel"); 1173 1174 // Copy base path onto the iterator stack 1175 char *path = strdup(pathBuffer.Path()); 1176 if (path == NULL) 1177 continue; 1178 1179 size_t length = strlen(path); 1180 1181 // TODO: it would currently be nicer to use the commented 1182 // version below, but the iterator won't work if the prefix 1183 // is inside a module then. 1184 // It works this way, but should be done better. 1185 #if 0 1186 // Build path component: base path + '/' + prefix 1187 size_t length = strlen(sModulePaths[i]); 1188 char *path = (char *)malloc(length + iterator->prefix_length + 2); 1189 if (path == NULL) { 1190 // ToDo: should we abort the whole operation here? 1191 // if we do, don't forget to empty the stack 1192 continue; 1193 } 1194 1195 memcpy(path, sModulePaths[i], length); 1196 path[length] = '/'; 1197 memcpy(path + length + 1, iterator->prefix, 1198 iterator->prefix_length + 1); 1199 #endif 1200 1201 iterator_push_path_on_stack(iterator, path, length + 1); 1202 } 1203 } else { 1204 // include loaded modules in case there is no boot device yet 1205 iterator->builtin_modules = false; 1206 iterator->loaded_modules = true; 1207 } 1208 1209 return (void *)iterator; 1210 } 1211 1212 1213 void * 1214 open_module_list(const char *prefix) 1215 { 1216 return open_module_list_etc(prefix, NULL); 1217 } 1218 1219 1220 /*! Frees the cookie allocated by open_module_list() */ 1221 status_t 1222 close_module_list(void *cookie) 1223 { 1224 module_iterator *iterator = (module_iterator *)cookie; 1225 const char *path; 1226 1227 TRACE(("close_module_list()\n")); 1228 1229 if (iterator == NULL) 1230 return B_BAD_VALUE; 1231 1232 // free stack 1233 while ((path = iterator_pop_path_from_stack(iterator, NULL)) != NULL) 1234 free((void *)path); 1235 1236 // close what have been left open 1237 if (iterator->module_image != NULL) 1238 put_module_image(iterator->module_image); 1239 1240 if (iterator->current_dir != NULL) 1241 closedir(iterator->current_dir); 1242 1243 free(iterator->stack); 1244 free((void *)iterator->current_path); 1245 free((void *)iterator->current_module_path); 1246 1247 free(iterator->prefix); 1248 free(iterator); 1249 1250 return B_OK; 1251 } 1252 1253 1254 /*! Return the next module name from the available list, using 1255 a structure previously created by a call to open_module_list(). 1256 Returns B_OK as long as it found another module, B_ENTRY_NOT_FOUND 1257 when done. 1258 */ 1259 status_t 1260 read_next_module_name(void *cookie, char *buffer, size_t *_bufferSize) 1261 { 1262 module_iterator *iterator = (module_iterator *)cookie; 1263 status_t status; 1264 1265 TRACE(("read_next_module_name: looking for next module\n")); 1266 1267 if (iterator == NULL || buffer == NULL || _bufferSize == NULL) 1268 return B_BAD_VALUE; 1269 1270 if (iterator->status < B_OK) 1271 return iterator->status; 1272 1273 status = iterator->status; 1274 recursive_lock_lock(&sModulesLock); 1275 1276 status = iterator_get_next_module(iterator, buffer, _bufferSize); 1277 1278 iterator->status = status; 1279 recursive_lock_unlock(&sModulesLock); 1280 1281 TRACE(("read_next_module_name: finished with status %s\n", 1282 strerror(status))); 1283 return status; 1284 } 1285 1286 1287 /*! Iterates through all loaded modules, and stores its path in "buffer". 1288 ToDo: check if the function in BeOS really does that (could also mean: 1289 iterate through all modules that are currently loaded; have a valid 1290 module_image pointer, which would be hard to test for) 1291 */ 1292 status_t 1293 get_next_loaded_module_name(uint32 *_cookie, char *buffer, size_t *_bufferSize) 1294 { 1295 if (sModulesHash == NULL) { 1296 dprintf("get_next_loaded_module_name() called too early!\n"); 1297 return B_ERROR; 1298 } 1299 1300 //TRACE(("get_next_loaded_module_name(\"%s\")\n", buffer)); 1301 1302 if (_cookie == NULL || buffer == NULL || _bufferSize == NULL) 1303 return B_BAD_VALUE; 1304 1305 status_t status = B_ENTRY_NOT_FOUND; 1306 uint32 offset = *_cookie; 1307 1308 RecursiveLocker _(sModulesLock); 1309 1310 hash_iterator iterator; 1311 hash_open(sModulesHash, &iterator); 1312 struct module *module = (struct module *)hash_next(sModulesHash, 1313 &iterator); 1314 1315 for (uint32 i = 0; module != NULL; i++) { 1316 if (i >= offset) { 1317 *_bufferSize = strlcpy(buffer, module->name, *_bufferSize); 1318 *_cookie = i + 1; 1319 status = B_OK; 1320 break; 1321 } 1322 module = (struct module *)hash_next(sModulesHash, &iterator); 1323 } 1324 1325 hash_close(sModulesHash, &iterator, false); 1326 1327 return status; 1328 } 1329 1330 1331 status_t 1332 get_module(const char *path, module_info **_info) 1333 { 1334 module_image *moduleImage; 1335 module *module; 1336 status_t status; 1337 1338 TRACE(("get_module(%s)\n", path)); 1339 1340 if (path == NULL) 1341 return B_BAD_VALUE; 1342 1343 RecursiveLocker _(sModulesLock); 1344 1345 module = (struct module *)hash_lookup(sModulesHash, path); 1346 1347 // if we don't have it cached yet, search for it 1348 if (module == NULL) { 1349 module = search_module(path); 1350 if (module == NULL) { 1351 FATAL(("module: Search for %s failed.\n", path)); 1352 return B_ENTRY_NOT_FOUND; 1353 } 1354 } 1355 1356 if ((module->flags & B_BUILT_IN_MODULE) == 0) { 1357 /* We now need to find the module_image for the module. This should 1358 * be in memory if we have just run search_module(), but may not be 1359 * if we are using cached information. 1360 * We can't use the module->module_image pointer, because it is not 1361 * reliable at this point (it won't be set to NULL when the module_image 1362 * is unloaded). 1363 */ 1364 if (get_module_image(module->file, &moduleImage) < B_OK) 1365 return B_ENTRY_NOT_FOUND; 1366 1367 // (re)set in-memory data for the loaded module 1368 module->info = moduleImage->info[module->offset]; 1369 module->module_image = moduleImage; 1370 1371 // the module image must not be unloaded anymore 1372 if (module->flags & B_KEEP_LOADED) 1373 module->module_image->keep_loaded = true; 1374 } 1375 1376 // The state will be adjusted by the call to init_module 1377 // if we have just loaded the file 1378 if (module->ref_count == 0) 1379 status = init_module(module); 1380 else 1381 status = B_OK; 1382 1383 if (status == B_OK) { 1384 if (module->ref_count < 0) 1385 panic("argl %s", path); 1386 module->ref_count++; 1387 *_info = module->info; 1388 } else if ((module->flags & B_BUILT_IN_MODULE) == 0 1389 && (module->flags & B_KEEP_LOADED) == 0) 1390 put_module_image(module->module_image); 1391 1392 return status; 1393 } 1394 1395 1396 status_t 1397 put_module(const char *path) 1398 { 1399 module *module; 1400 1401 TRACE(("put_module(path = %s)\n", path)); 1402 1403 RecursiveLocker _(sModulesLock); 1404 1405 module = (struct module *)hash_lookup(sModulesHash, path); 1406 if (module == NULL) { 1407 FATAL(("module: We don't seem to have a reference to module %s\n", 1408 path)); 1409 return B_BAD_VALUE; 1410 } 1411 1412 if (module->ref_count == 0) 1413 panic("module %s has no references.\n", path); 1414 1415 if ((module->flags & B_KEEP_LOADED) == 0) { 1416 if (--module->ref_count == 0) 1417 uninit_module(module); 1418 } else if ((module->flags & B_BUILT_IN_MODULE) == 0) 1419 put_module_image(module->module_image); 1420 1421 return B_OK; 1422 } 1423