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