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 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 status = module->info->std_ops(B_MODULE_INIT); 574 TRACE(("...done (%s)\n", strerror(status))); 575 576 if (status >= B_OK) 577 module->state = MODULE_READY; 578 else { 579 put_dependent_modules(module); 580 module->state = MODULE_LOADED; 581 } 582 583 return status; 584 } 585 586 case MODULE_READY: 587 return B_OK; 588 589 case MODULE_INIT: 590 FATAL(("circular reference to %s\n", module->name)); 591 return B_ERROR; 592 593 case MODULE_UNINIT: 594 FATAL(("tried to load module %s which is currently unloading\n", module->name)); 595 return B_ERROR; 596 597 case MODULE_ERROR: 598 FATAL(("cannot load module %s because its earlier unloading failed\n", module->name)); 599 return B_ERROR; 600 601 default: 602 return B_ERROR; 603 } 604 // never trespasses here 605 } 606 607 608 /*! Uninitializes a module depeding on its state */ 609 static inline int 610 uninit_module(module *module) 611 { 612 TRACE(("uninit_module(%s)\n", module->name)); 613 614 switch (module->state) { 615 case MODULE_QUERIED: 616 case MODULE_LOADED: 617 return B_NO_ERROR; 618 619 case MODULE_INIT: 620 panic("Trying to unload module %s which is initializing\n", module->name); 621 return B_ERROR; 622 623 case MODULE_UNINIT: 624 panic("Trying to unload module %s which is un-initializing\n", module->name); 625 return B_ERROR; 626 627 case MODULE_READY: 628 { 629 status_t status; 630 631 module->state = MODULE_UNINIT; 632 633 TRACE(("uninitializing module %s...\n", module->name)); 634 status = module->info->std_ops(B_MODULE_UNINIT); 635 TRACE(("...done (%s)\n", strerror(status))); 636 637 if (status == B_NO_ERROR) { 638 module->state = MODULE_LOADED; 639 640 put_dependent_modules(module); 641 return B_OK; 642 } 643 644 FATAL(("Error unloading module %s (%s)\n", module->name, 645 strerror(status))); 646 647 module->state = MODULE_ERROR; 648 module->flags |= B_KEEP_LOADED; 649 650 return status; 651 } 652 default: 653 return B_ERROR; 654 } 655 // never trespasses here 656 } 657 658 659 static const char * 660 iterator_pop_path_from_stack(module_iterator *iterator, uint32 *_baseLength) 661 { 662 if (iterator->stack_current <= 0) 663 return NULL; 664 665 if (_baseLength) 666 *_baseLength = iterator->stack[iterator->stack_current - 1].base_length; 667 668 return iterator->stack[--iterator->stack_current].name; 669 } 670 671 672 static status_t 673 iterator_push_path_on_stack(module_iterator *iterator, const char *path, uint32 baseLength) 674 { 675 if (iterator->stack_current + 1 > iterator->stack_size) { 676 // allocate new space on the stack 677 module_path *stack = (module_path *)realloc(iterator->stack, 678 (iterator->stack_size + 8) * sizeof(module_path)); 679 if (stack == NULL) 680 return B_NO_MEMORY; 681 682 iterator->stack = stack; 683 iterator->stack_size += 8; 684 } 685 686 iterator->stack[iterator->stack_current].name = path; 687 iterator->stack[iterator->stack_current++].base_length = baseLength; 688 return B_OK; 689 } 690 691 692 static status_t 693 iterator_get_next_module(module_iterator *iterator, char *buffer, 694 size_t *_bufferSize) 695 { 696 status_t status; 697 698 TRACE(("iterator_get_next_module() -- start\n")); 699 700 if (iterator->builtin_modules) { 701 for (int32 i = iterator->module_offset; sBuiltInModules[i] != NULL; i++) { 702 // the module name must fit the prefix 703 if (strncmp(sBuiltInModules[i]->name, iterator->prefix, 704 iterator->prefix_length)) 705 continue; 706 707 *_bufferSize = strlcpy(buffer, sBuiltInModules[i]->name, 708 *_bufferSize); 709 iterator->module_offset = i + 1; 710 return B_OK; 711 } 712 iterator->builtin_modules = false; 713 } 714 715 if (iterator->loaded_modules) { 716 recursive_lock_lock(&sModulesLock); 717 hash_iterator hashIterator; 718 hash_open(sModulesHash, &hashIterator); 719 720 struct module *module = (struct module *)hash_next(sModulesHash, 721 &hashIterator); 722 for (int32 i = 0; module != NULL; i++) { 723 if (i >= iterator->module_offset) { 724 if (!strncmp(module->name, iterator->prefix, 725 iterator->prefix_length)) { 726 *_bufferSize = strlcpy(buffer, module->name, *_bufferSize); 727 iterator->module_offset = i + 1; 728 729 hash_close(sModulesHash, &hashIterator, false); 730 recursive_lock_unlock(&sModulesLock); 731 return B_OK; 732 } 733 } 734 module = (struct module *)hash_next(sModulesHash, &hashIterator); 735 } 736 737 hash_close(sModulesHash, &hashIterator, false); 738 recursive_lock_unlock(&sModulesLock); 739 740 // prevent from falling into modules hash iteration again 741 iterator->loaded_modules = false; 742 } 743 744 nextPath: 745 if (iterator->current_dir == NULL) { 746 // get next directory path from the stack 747 const char *path = iterator_pop_path_from_stack(iterator, 748 &iterator->path_base_length); 749 if (path == NULL) { 750 // we are finished, there are no more entries on the stack 751 return B_ENTRY_NOT_FOUND; 752 } 753 754 free((void *)iterator->current_path); 755 iterator->current_path = path; 756 iterator->current_dir = opendir(path); 757 TRACE(("open directory at %s -> %p\n", path, iterator->current_dir)); 758 759 if (iterator->current_dir == NULL) { 760 // we don't throw an error here, but silently go to 761 // the next directory on the stack 762 goto nextPath; 763 } 764 } 765 766 nextModuleImage: 767 if (iterator->current_header == NULL) { 768 // get next entry from the current directory 769 770 errno = 0; 771 772 struct dirent *dirent; 773 if ((dirent = readdir(iterator->current_dir)) == NULL) { 774 closedir(iterator->current_dir); 775 iterator->current_dir = NULL; 776 777 if (errno < B_OK) 778 return errno; 779 780 goto nextPath; 781 } 782 783 // check if the prefix matches 784 int32 passedOffset, commonLength; 785 passedOffset = strlen(iterator->current_path) + 1; 786 commonLength = iterator->path_base_length + iterator->prefix_length 787 - passedOffset; 788 789 if (commonLength > 0) { 790 // the prefix still reaches into the new path part 791 int32 length = strlen(dirent->d_name); 792 if (commonLength > length) 793 commonLength = length; 794 795 if (strncmp(dirent->d_name, iterator->prefix + passedOffset 796 - iterator->path_base_length, commonLength)) 797 goto nextModuleImage; 798 } 799 800 // we're not interested in traversing these again 801 if (!strcmp(dirent->d_name, ".") 802 || !strcmp(dirent->d_name, "..")) 803 goto nextModuleImage; 804 805 // build absolute path to current file 806 KPath path(iterator->current_path); 807 if (path.InitCheck() != B_OK) 808 return B_NO_MEMORY; 809 810 if (path.Append(dirent->d_name) != B_OK) 811 return B_BUFFER_OVERFLOW; 812 813 // find out if it's a directory or a file 814 struct stat st; 815 if (stat(path.Path(), &st) < 0) 816 return errno; 817 818 iterator->current_module_path = strdup(path.Path()); 819 if (iterator->current_module_path == NULL) 820 return B_NO_MEMORY; 821 822 if (S_ISDIR(st.st_mode)) { 823 status = iterator_push_path_on_stack(iterator, 824 iterator->current_module_path, iterator->path_base_length); 825 if (status < B_OK) 826 return status; 827 828 iterator->current_module_path = NULL; 829 goto nextModuleImage; 830 } 831 832 if (!S_ISREG(st.st_mode)) 833 return B_BAD_TYPE; 834 835 TRACE(("open module at %s\n", path.Path())); 836 837 status = get_module_image(path.Path(), &iterator->module_image); 838 if (status < B_OK) { 839 free((void *)iterator->current_module_path); 840 iterator->current_module_path = NULL; 841 goto nextModuleImage; 842 } 843 844 iterator->current_header = iterator->module_image->info; 845 iterator->module_offset = 0; 846 } 847 848 // search the current module image until we've got a match 849 while (*iterator->current_header != NULL) { 850 module_info *info = *iterator->current_header; 851 852 // ToDo: we might want to create a module here and cache it in the hash table 853 854 iterator->current_header++; 855 iterator->module_offset++; 856 857 if (strncmp(info->name, iterator->prefix, iterator->prefix_length)) 858 continue; 859 860 *_bufferSize = strlcpy(buffer, info->name, *_bufferSize); 861 return B_OK; 862 } 863 864 // leave this module and get the next one 865 866 iterator->current_header = NULL; 867 free((void *)iterator->current_module_path); 868 iterator->current_module_path = NULL; 869 870 put_module_image(iterator->module_image); 871 iterator->module_image = NULL; 872 873 goto nextModuleImage; 874 } 875 876 877 static void 878 register_builtin_modules(struct module_info **info) 879 { 880 for (; *info; info++) { 881 (*info)->flags |= B_BUILT_IN_MODULE; 882 // this is an internal flag, it doesn't have to be set by modules itself 883 884 if (create_module(*info, "", -1, NULL) != B_OK) 885 dprintf("creation of built-in module \"%s\" failed!\n", (*info)->name); 886 } 887 } 888 889 890 static status_t 891 register_preloaded_module_image(struct preloaded_image *image) 892 { 893 module_image *moduleImage; 894 struct module_info **info; 895 status_t status; 896 int32 index = 0; 897 898 TRACE(("register_preloaded_module_image(image = \"%s\")\n", image->name)); 899 900 image->is_module = false; 901 902 if (image->id < 0) 903 return B_BAD_VALUE; 904 905 moduleImage = (module_image *)malloc(sizeof(module_image)); 906 if (moduleImage == NULL) 907 return B_NO_MEMORY; 908 909 if (get_image_symbol(image->id, "modules", B_SYMBOL_TYPE_DATA, 910 (void **)&moduleImage->info) != B_OK) { 911 status = B_BAD_TYPE; 912 goto error; 913 } 914 915 image->is_module = true; 916 917 moduleImage->dependencies = NULL; 918 get_image_symbol(image->id, "module_dependencies", B_SYMBOL_TYPE_DATA, 919 (void **)&moduleImage->dependencies); 920 // this is allowed to be NULL 921 922 // Try to recreate the full module path, so that we don't try to load the 923 // image again when asked for a module it does not export (would only be 924 // problematic if it had got replaced and the new file actually exports 925 // that module). Also helpful for recurse_directory(). 926 { 927 // ToDo: this is kind of a hack to have the full path in the hash 928 // (it always assumes the preloaded add-ons to be in the system directory) 929 char path[B_FILE_NAME_LENGTH]; 930 const char *name, *suffix; 931 if (moduleImage->info[0] 932 && (suffix = strstr(name = moduleImage->info[0]->name, 933 image->name)) != NULL) { 934 // even if strlcpy() is used here, it's by no means safe 935 // against buffer overflows 936 size_t length = strlcpy(path, "/boot/beos/system/add-ons/kernel/", 937 sizeof(path)); 938 strlcpy(path + length, name, strlen(image->name) 939 + 1 + (suffix - name)); 940 941 moduleImage->path = strdup(path); 942 } else 943 moduleImage->path = strdup(image->name); 944 } 945 if (moduleImage->path == NULL) { 946 status = B_NO_MEMORY; 947 goto error; 948 } 949 950 moduleImage->image = image->id; 951 moduleImage->ref_count = 0; 952 moduleImage->keep_loaded = false; 953 954 hash_insert(sModuleImagesHash, moduleImage); 955 956 for (info = moduleImage->info; *info; info++) { 957 create_module(*info, moduleImage->path, index++, NULL); 958 } 959 960 return B_OK; 961 962 error: 963 free(moduleImage); 964 965 // We don't need this image anymore. We keep it, if it doesn't look like 966 // a module at all. It might be an old-style driver. 967 if (image->is_module) 968 unload_kernel_add_on(image->id); 969 970 return status; 971 } 972 973 974 static int 975 dump_modules(int argc, char **argv) 976 { 977 hash_iterator iterator; 978 struct module_image *image; 979 struct module *module; 980 981 hash_rewind(sModulesHash, &iterator); 982 dprintf("-- known modules:\n"); 983 984 while ((module = (struct module *)hash_next(sModulesHash, &iterator)) != NULL) { 985 dprintf("%p: \"%s\", \"%s\" (%ld), refcount = %ld, state = %d, mimage = %p\n", 986 module, module->name, module->file, module->offset, module->ref_count, 987 module->state, module->module_image); 988 } 989 990 hash_rewind(sModuleImagesHash, &iterator); 991 dprintf("\n-- loaded module images:\n"); 992 993 while ((image = (struct module_image *)hash_next(sModuleImagesHash, &iterator)) != NULL) { 994 dprintf("%p: \"%s\" (image_id = %ld), info = %p, refcount = %ld, %s\n", image, 995 image->path, image->image, image->info, image->ref_count, 996 image->keep_loaded ? "keep loaded" : "can be unloaded"); 997 } 998 return 0; 999 } 1000 1001 1002 // #pragma mark - Exported Kernel API (private part) 1003 1004 1005 /*! Unloads a module in case it's not in use. This is the counterpart 1006 to load_module(). 1007 */ 1008 status_t 1009 unload_module(const char *path) 1010 { 1011 struct module_image *moduleImage; 1012 1013 recursive_lock_lock(&sModulesLock); 1014 moduleImage = (module_image *)hash_lookup(sModuleImagesHash, path); 1015 recursive_lock_unlock(&sModulesLock); 1016 1017 if (moduleImage == NULL) 1018 return B_ENTRY_NOT_FOUND; 1019 1020 put_module_image(moduleImage); 1021 return B_OK; 1022 } 1023 1024 1025 /*! Unlike get_module(), this function lets you specify the add-on to 1026 be loaded by path. 1027 However, you must not use the exported modules without having called 1028 get_module() on them. When you're done with the NULL terminated 1029 \a modules array, you have to call unload_module(), no matter if 1030 you're actually using any of the modules or not - of course, the 1031 add-on won't be unloaded until the last put_module(). 1032 */ 1033 status_t 1034 load_module(const char *path, module_info ***_modules) 1035 { 1036 module_image *moduleImage; 1037 status_t status = get_module_image(path, &moduleImage); 1038 if (status != B_OK) 1039 return status; 1040 1041 *_modules = moduleImage->info; 1042 return B_OK; 1043 } 1044 1045 1046 /*! Setup the module structures and data for use - must be called 1047 before any other module call. 1048 */ 1049 status_t 1050 module_init(kernel_args *args) 1051 { 1052 struct preloaded_image *image; 1053 1054 if (recursive_lock_init(&sModulesLock, "modules rlock") < B_OK) 1055 return B_ERROR; 1056 1057 sModulesHash = hash_init(MODULE_HASH_SIZE, 0, module_compare, module_hash); 1058 if (sModulesHash == NULL) 1059 return B_NO_MEMORY; 1060 1061 sModuleImagesHash = hash_init(MODULE_HASH_SIZE, 0, module_image_compare, 1062 module_image_hash); 1063 if (sModuleImagesHash == NULL) 1064 return B_NO_MEMORY; 1065 1066 // register built-in modules 1067 1068 register_builtin_modules(sBuiltInModules); 1069 1070 // register preloaded images 1071 1072 for (image = args->preloaded_images; image != NULL; image = image->next) { 1073 status_t status = register_preloaded_module_image(image); 1074 if (status != B_OK) { 1075 dprintf("Could not register image \"%s\": %s\n", image->name, 1076 strerror(status)); 1077 } 1078 } 1079 1080 sDisableUserAddOns = get_safemode_boolean(B_SAFEMODE_DISABLE_USER_ADD_ONS, 1081 false); 1082 1083 add_debugger_command("modules", &dump_modules, 1084 "list all known & loaded modules"); 1085 1086 return B_OK; 1087 } 1088 1089 1090 // #pragma mark - Exported Kernel API (public part) 1091 1092 1093 /*! This returns a pointer to a structure that can be used to 1094 iterate through a list of all modules available under 1095 a given prefix. 1096 All paths will be searched and the returned list will 1097 contain all modules available under the prefix. 1098 The structure is then used by read_next_module_name(), and 1099 must be freed by calling close_module_list(). 1100 */ 1101 void * 1102 open_module_list(const char *prefix) 1103 { 1104 module_iterator *iterator; 1105 uint32 i; 1106 1107 TRACE(("open_module_list(prefix = %s)\n", prefix)); 1108 1109 if (sModulesHash == NULL) { 1110 dprintf("open_module_list() called too early!\n"); 1111 return NULL; 1112 } 1113 1114 iterator = (module_iterator *)malloc(sizeof(module_iterator)); 1115 if (!iterator) 1116 return NULL; 1117 1118 memset(iterator, 0, sizeof(module_iterator)); 1119 1120 iterator->prefix = strdup(prefix != NULL ? prefix : ""); 1121 if (iterator->prefix == NULL) { 1122 free(iterator); 1123 return NULL; 1124 } 1125 iterator->prefix_length = strlen(iterator->prefix); 1126 1127 if (gBootDevice > 0) { 1128 // We do have a boot device to scan 1129 1130 // first, we'll traverse over the built-in modules 1131 iterator->builtin_modules = true; 1132 iterator->loaded_modules = false; 1133 1134 // put all search paths on the stack 1135 for (i = 0; i < kNumModulePaths; i++) { 1136 if (sDisableUserAddOns && i >= kFirstNonSystemModulePath) 1137 break; 1138 1139 KPath pathBuffer; 1140 if (find_directory(kModulePaths[i], gBootDevice, true, 1141 pathBuffer.LockBuffer(), pathBuffer.BufferSize()) != B_OK) 1142 continue; 1143 1144 pathBuffer.UnlockBuffer(); 1145 pathBuffer.Append("kernel"); 1146 1147 // Copy base path onto the iterator stack 1148 char *path = strdup(pathBuffer.Path()); 1149 if (path == NULL) 1150 continue; 1151 1152 size_t length = strlen(path); 1153 1154 // TODO: it would currently be nicer to use the commented 1155 // version below, but the iterator won't work if the prefix 1156 // is inside a module then. 1157 // It works this way, but should be done better. 1158 #if 0 1159 // Build path component: base path + '/' + prefix 1160 size_t length = strlen(sModulePaths[i]); 1161 char *path = (char *)malloc(length + iterator->prefix_length + 2); 1162 if (path == NULL) { 1163 // ToDo: should we abort the whole operation here? 1164 // if we do, don't forget to empty the stack 1165 continue; 1166 } 1167 1168 memcpy(path, sModulePaths[i], length); 1169 path[length] = '/'; 1170 memcpy(path + length + 1, iterator->prefix, 1171 iterator->prefix_length + 1); 1172 #endif 1173 1174 iterator_push_path_on_stack(iterator, path, length + 1); 1175 } 1176 } else { 1177 // include loaded modules in case there is no boot device yet 1178 iterator->builtin_modules = false; 1179 iterator->loaded_modules = true; 1180 } 1181 1182 return (void *)iterator; 1183 } 1184 1185 1186 /*! Frees the cookie allocated by open_module_list() */ 1187 status_t 1188 close_module_list(void *cookie) 1189 { 1190 module_iterator *iterator = (module_iterator *)cookie; 1191 const char *path; 1192 1193 TRACE(("close_module_list()\n")); 1194 1195 if (iterator == NULL) 1196 return B_BAD_VALUE; 1197 1198 // free stack 1199 while ((path = iterator_pop_path_from_stack(iterator, NULL)) != NULL) 1200 free((void *)path); 1201 1202 // close what have been left open 1203 if (iterator->module_image != NULL) 1204 put_module_image(iterator->module_image); 1205 1206 if (iterator->current_dir != NULL) 1207 closedir(iterator->current_dir); 1208 1209 free(iterator->stack); 1210 free((void *)iterator->current_path); 1211 free((void *)iterator->current_module_path); 1212 1213 free(iterator->prefix); 1214 free(iterator); 1215 1216 return B_OK; 1217 } 1218 1219 1220 /*! Return the next module name from the available list, using 1221 a structure previously created by a call to open_module_list(). 1222 Returns B_OK as long as it found another module, B_ENTRY_NOT_FOUND 1223 when done. 1224 */ 1225 status_t 1226 read_next_module_name(void *cookie, char *buffer, size_t *_bufferSize) 1227 { 1228 module_iterator *iterator = (module_iterator *)cookie; 1229 status_t status; 1230 1231 TRACE(("read_next_module_name: looking for next module\n")); 1232 1233 if (iterator == NULL || buffer == NULL || _bufferSize == NULL) 1234 return B_BAD_VALUE; 1235 1236 if (iterator->status < B_OK) 1237 return iterator->status; 1238 1239 status = iterator->status; 1240 recursive_lock_lock(&sModulesLock); 1241 1242 status = iterator_get_next_module(iterator, buffer, _bufferSize); 1243 1244 iterator->status = status; 1245 recursive_lock_unlock(&sModulesLock); 1246 1247 TRACE(("read_next_module_name: finished with status %s\n", 1248 strerror(status))); 1249 return status; 1250 } 1251 1252 1253 /*! Iterates through all loaded modules, and stores its path in "buffer". 1254 ToDo: check if the function in BeOS really does that (could also mean: 1255 iterate through all modules that are currently loaded; have a valid 1256 module_image pointer, which would be hard to test for) 1257 */ 1258 status_t 1259 get_next_loaded_module_name(uint32 *_cookie, char *buffer, size_t *_bufferSize) 1260 { 1261 if (sModulesHash == NULL) { 1262 dprintf("get_next_loaded_module_name() called too early!\n"); 1263 return B_ERROR; 1264 } 1265 1266 //TRACE(("get_next_loaded_module_name(\"%s\")\n", buffer)); 1267 1268 if (_cookie == NULL || buffer == NULL || _bufferSize == NULL) 1269 return B_BAD_VALUE; 1270 1271 status_t status = B_ENTRY_NOT_FOUND; 1272 uint32 offset = *_cookie; 1273 1274 RecursiveLocker _(sModulesLock); 1275 1276 hash_iterator iterator; 1277 hash_open(sModulesHash, &iterator); 1278 struct module *module = (struct module *)hash_next(sModulesHash, 1279 &iterator); 1280 1281 for (uint32 i = 0; module != NULL; i++) { 1282 if (i >= offset) { 1283 *_bufferSize = strlcpy(buffer, module->name, *_bufferSize); 1284 *_cookie = i + 1; 1285 status = B_OK; 1286 break; 1287 } 1288 module = (struct module *)hash_next(sModulesHash, &iterator); 1289 } 1290 1291 hash_close(sModulesHash, &iterator, false); 1292 1293 return status; 1294 } 1295 1296 1297 status_t 1298 get_module(const char *path, module_info **_info) 1299 { 1300 module_image *moduleImage; 1301 module *module; 1302 status_t status; 1303 1304 TRACE(("get_module(%s)\n", path)); 1305 1306 if (path == NULL) 1307 return B_BAD_VALUE; 1308 1309 RecursiveLocker _(sModulesLock); 1310 1311 module = (struct module *)hash_lookup(sModulesHash, path); 1312 1313 // if we don't have it cached yet, search for it 1314 if (module == NULL) { 1315 module = search_module(path); 1316 if (module == NULL) { 1317 FATAL(("module: Search for %s failed.\n", path)); 1318 return B_ENTRY_NOT_FOUND; 1319 } 1320 } 1321 1322 if ((module->flags & B_BUILT_IN_MODULE) == 0) { 1323 /* We now need to find the module_image for the module. This should 1324 * be in memory if we have just run search_module(), but may not be 1325 * if we are using cached information. 1326 * We can't use the module->module_image pointer, because it is not 1327 * reliable at this point (it won't be set to NULL when the module_image 1328 * is unloaded). 1329 */ 1330 if (get_module_image(module->file, &moduleImage) < B_OK) 1331 return B_ENTRY_NOT_FOUND; 1332 1333 // (re)set in-memory data for the loaded module 1334 module->info = moduleImage->info[module->offset]; 1335 module->module_image = moduleImage; 1336 1337 // the module image must not be unloaded anymore 1338 if (module->flags & B_KEEP_LOADED) 1339 module->module_image->keep_loaded = true; 1340 } 1341 1342 // The state will be adjusted by the call to init_module 1343 // if we have just loaded the file 1344 if (module->ref_count == 0) 1345 status = init_module(module); 1346 else 1347 status = B_OK; 1348 1349 if (status == B_OK) { 1350 if (module->ref_count < 0) 1351 panic("argl %s", path); 1352 module->ref_count++; 1353 *_info = module->info; 1354 } else if ((module->flags & B_BUILT_IN_MODULE) == 0 1355 && (module->flags & B_KEEP_LOADED) == 0) 1356 put_module_image(module->module_image); 1357 1358 return status; 1359 } 1360 1361 1362 status_t 1363 put_module(const char *path) 1364 { 1365 module *module; 1366 1367 TRACE(("put_module(path = %s)\n", path)); 1368 1369 RecursiveLocker _(sModulesLock); 1370 1371 module = (struct module *)hash_lookup(sModulesHash, path); 1372 if (module == NULL) { 1373 FATAL(("module: We don't seem to have a reference to module %s\n", 1374 path)); 1375 return B_BAD_VALUE; 1376 } 1377 1378 if (module->ref_count == 0) 1379 panic("module %s has no references.\n", path); 1380 1381 if ((module->flags & B_KEEP_LOADED) == 0) { 1382 if (--module->ref_count == 0) 1383 uninit_module(module); 1384 } else if ((module->flags & B_BUILT_IN_MODULE) == 0) 1385 put_module_image(module->module_image); 1386 1387 return B_OK; 1388 } 1389