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