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