xref: /freebsd/stand/common/module.c (revision a0b9e2e854027e6ff61fb075a1309dbc71c42b54)
1 /*-
2  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 /*
31  * file/module function dispatcher, support, etc.
32  */
33 
34 #include <stand.h>
35 #include <string.h>
36 #include <sys/param.h>
37 #include <sys/linker.h>
38 #include <sys/module.h>
39 #include <sys/queue.h>
40 #include <sys/stdint.h>
41 
42 #if defined(LOADER_FDT_SUPPORT)
43 #include <fdt_platform.h>
44 #endif
45 
46 #include "bootstrap.h"
47 
48 #define	MDIR_REMOVED	0x0001
49 #define	MDIR_NOHINTS	0x0002
50 
51 struct moduledir {
52 	char	*d_path;	/* path of modules directory */
53 	u_char	*d_hints;	/* content of linker.hints file */
54 	int	d_hintsz;	/* size of hints data */
55 	int	d_flags;
56 	STAILQ_ENTRY(moduledir) d_link;
57 };
58 
59 static int			file_load(char *filename, vm_offset_t dest, struct preloaded_file **result);
60 static int			file_load_dependencies(struct preloaded_file *base_mod);
61 static char *			file_search(const char *name, char **extlist);
62 static struct kernel_module *	file_findmodule(struct preloaded_file *fp, char *modname, struct mod_depend *verinfo);
63 static int			file_havepath(const char *name);
64 static char			*mod_searchmodule(char *name, struct mod_depend *verinfo);
65 static char *			mod_searchmodule_pnpinfo(const char *bus, const char *pnpinfo);
66 static void			file_insert_tail(struct preloaded_file *mp);
67 static void			file_remove(struct preloaded_file *fp);
68 struct file_metadata*		metadata_next(struct file_metadata *base_mp, int type);
69 static void			moduledir_readhints(struct moduledir *mdp);
70 static void			moduledir_rebuild(void);
71 
72 /* load address should be tweaked by first module loaded (kernel) */
73 static vm_offset_t	loadaddr = 0;
74 
75 #if defined(LOADER_FDT_SUPPORT)
76 static const char	*default_searchpath =
77     "/boot/kernel;/boot/modules;/boot/dtb";
78 #else
79 static const char	*default_searchpath = "/boot/kernel;/boot/modules";
80 #endif
81 
82 static STAILQ_HEAD(, moduledir) moduledir_list =
83     STAILQ_HEAD_INITIALIZER(moduledir_list);
84 
85 struct preloaded_file *preloaded_files = NULL;
86 
87 static char *kld_ext_list[] = {
88     ".ko",
89     "",
90     ".debug",
91     NULL
92 };
93 
94 
95 /*
96  * load an object, either a disk file or code module.
97  *
98  * To load a file, the syntax is:
99  *
100  * load -t <type> <path>
101  *
102  * code modules are loaded as:
103  *
104  * load <path> <options>
105  */
106 
107 COMMAND_SET(load, "load", "load a kernel or module", command_load);
108 
109 static int
110 command_load(int argc, char *argv[])
111 {
112 	struct preloaded_file *fp;
113 	char	*typestr;
114 	char	*prefix;
115 	char	*skip;
116 	int		dflag, dofile, dokld, ch, error;
117 
118 	dflag = dokld = dofile = 0;
119 	optind = 1;
120 	optreset = 1;
121 	typestr = NULL;
122 	if (argc == 1) {
123 		command_errmsg = "no filename specified";
124 		return (CMD_CRIT);
125 	}
126 	prefix = skip = NULL;
127 	while ((ch = getopt(argc, argv, "dkp:s:t:")) != -1) {
128 		switch(ch) {
129 		case 'd':
130 			dflag++;
131 			break;
132 		case 'k':
133 			dokld = 1;
134 			break;
135 		case 'p':
136 			prefix = optarg;
137 			break;
138 		case 's':
139 			skip = optarg;
140 			break;
141 		case 't':
142 			typestr = optarg;
143 			dofile = 1;
144 			break;
145 		case '?':
146 		default:
147 			/* getopt has already reported an error */
148 			return (CMD_OK);
149 		}
150 	}
151 	argv += (optind - 1);
152 	argc -= (optind - 1);
153 
154 	/*
155 	 * Request to load a raw file?
156 	 */
157 	if (dofile) {
158 		if ((argc != 2) || (typestr == NULL) || (*typestr == 0)) {
159 			command_errmsg = "invalid load type";
160 			return (CMD_CRIT);
161 		}
162 
163 #ifdef LOADER_VERIEXEC
164 		if (strncmp(typestr, "manifest", 8) == 0) {
165 			if (dflag > 0)
166 				ve_debug_set(dflag);
167 			return (load_manifest(argv[1], prefix, skip, NULL));
168 		}
169 #ifdef LOADER_VERIEXEC_PASS_MANIFEST
170 		if (strncmp(typestr, "pass_manifest", 13) == 0) {
171 			if (dflag > 0)
172 				ve_debug_set(dflag);
173 		    return (pass_manifest(argv[1], prefix));
174 		}
175 #endif
176 #endif
177 
178 		fp = file_findfile(argv[1], typestr);
179 		if (fp) {
180 			snprintf(command_errbuf, sizeof(command_errbuf),
181 			  "warning: file '%s' already loaded", argv[1]);
182 			return (CMD_WARN);
183 		}
184 
185 		if (file_loadraw(argv[1], typestr, 1) != NULL)
186 			return (CMD_OK);
187 
188 		/* Failing to load mfs_root is never going to end well! */
189 		if (strcmp("mfs_root", typestr) == 0)
190 			return (CMD_FATAL);
191 
192 		return (CMD_ERROR);
193 	}
194 	/*
195 	 * Do we have explicit KLD load ?
196 	 */
197 	if (dokld || file_havepath(argv[1])) {
198 		error = mod_loadkld(argv[1], argc - 2, argv + 2);
199 		if (error == EEXIST) {
200 			snprintf(command_errbuf, sizeof(command_errbuf),
201 			  "warning: KLD '%s' already loaded", argv[1]);
202 			return (CMD_WARN);
203 		}
204 
205 		return (error == 0 ? CMD_OK : CMD_CRIT);
206 	}
207 	/*
208 	 * Looks like a request for a module.
209 	 */
210 	error = mod_load(argv[1], NULL, argc - 2, argv + 2);
211 	if (error == EEXIST) {
212 		snprintf(command_errbuf, sizeof(command_errbuf),
213 		  "warning: module '%s' already loaded", argv[1]);
214 		return (CMD_WARN);
215 	}
216 
217 	return (error == 0 ? CMD_OK : CMD_CRIT);
218 }
219 
220 #ifdef LOADER_GELI_SUPPORT
221 COMMAND_SET(load_geli, "load_geli", "load a geli key", command_load_geli);
222 
223 static int
224 command_load_geli(int argc, char *argv[])
225 {
226 	char	typestr[80];
227 	char	*cp;
228 	int		ch, num;
229 
230 	if (argc < 3) {
231 		command_errmsg = "usage is [-n key#] <prov> <file>";
232 		return(CMD_ERROR);
233 	}
234 
235 	num = 0;
236 	optind = 1;
237 	optreset = 1;
238 	while ((ch = getopt(argc, argv, "n:")) != -1) {
239 		switch(ch) {
240 		case 'n':
241 			num = strtol(optarg, &cp, 0);
242 			if (cp == optarg) {
243 				snprintf(command_errbuf, sizeof(command_errbuf),
244 				  "bad key index '%s'", optarg);
245 				return(CMD_ERROR);
246 			}
247 			break;
248 		case '?':
249 		default:
250 			/* getopt has already reported an error */
251 			return(CMD_OK);
252 		}
253 	}
254 	argv += (optind - 1);
255 	argc -= (optind - 1);
256 	sprintf(typestr, "%s:geli_keyfile%d", argv[1], num);
257 	return (file_loadraw(argv[2], typestr, 1) ? CMD_OK : CMD_ERROR);
258 }
259 #endif
260 
261 void
262 unload(void)
263 {
264 	struct preloaded_file *fp;
265 
266 	while (preloaded_files != NULL) {
267 		fp = preloaded_files;
268 		preloaded_files = preloaded_files->f_next;
269 		file_discard(fp);
270 	}
271 	loadaddr = 0;
272 	unsetenv("kernelname");
273 }
274 
275 COMMAND_SET(unload, "unload", "unload all modules", command_unload);
276 
277 static int
278 command_unload(int argc, char *argv[])
279 {
280 	unload();
281 	return(CMD_OK);
282 }
283 
284 COMMAND_SET(lsmod, "lsmod", "list loaded modules", command_lsmod);
285 
286 static int
287 command_lsmod(int argc, char *argv[])
288 {
289 	struct preloaded_file	*fp;
290 	struct kernel_module	*mp;
291 	struct file_metadata	*md;
292 	char			lbuf[80];
293 	int				ch, verbose, ret = 0;
294 
295 	verbose = 0;
296 	optind = 1;
297 	optreset = 1;
298 	while ((ch = getopt(argc, argv, "v")) != -1) {
299 		switch(ch) {
300 		case 'v':
301 			verbose = 1;
302 			break;
303 		case '?':
304 		default:
305 			/* getopt has already reported an error */
306 			return(CMD_OK);
307 		}
308 	}
309 
310 	pager_open();
311 	for (fp = preloaded_files; fp; fp = fp->f_next) {
312 		snprintf(lbuf, sizeof(lbuf), " %p: ", (void *) fp->f_addr);
313 		pager_output(lbuf);
314 		pager_output(fp->f_name);
315 		snprintf(lbuf, sizeof(lbuf), " (%s, 0x%lx)\n", fp->f_type,
316 		  (long)fp->f_size);
317 		if (pager_output(lbuf))
318 			break;
319 		if (fp->f_args != NULL) {
320 			pager_output("    args: ");
321 			pager_output(fp->f_args);
322 			if (pager_output("\n"))
323 				break;
324 		}
325 		if (fp->f_modules) {
326 			pager_output("  modules: ");
327 			for (mp = fp->f_modules; mp; mp = mp->m_next) {
328 				snprintf(lbuf, sizeof(lbuf), "%s.%d ", mp->m_name,
329 				  mp->m_version);
330 				pager_output(lbuf);
331 			}
332 			if (pager_output("\n"))
333 				break;
334 		}
335 		if (verbose) {
336 			/* XXX could add some formatting smarts here to display some better */
337 			for (md = fp->f_metadata; md != NULL; md = md->md_next) {
338 				snprintf(lbuf, sizeof(lbuf), "      0x%04x, 0x%lx\n",
339 				  md->md_type, (long) md->md_size);
340 				if (pager_output(lbuf))
341 					break;
342 			}
343 		}
344 		if (ret)
345 			break;
346 	}
347 	pager_close();
348 	return(CMD_OK);
349 }
350 
351 COMMAND_SET(pnpmatch, "pnpmatch", "list matched modules based on pnpinfo", command_pnpmatch);
352 
353 static int pnp_dump_flag = 0;
354 static int pnp_unbound_flag = 0;
355 static int pnp_verbose_flag = 0;
356 
357 static int
358 command_pnpmatch(int argc, char *argv[])
359 {
360 	char *module;
361 	int ch;
362 
363 	pnp_verbose_flag = 0;
364 	pnp_dump_flag = 0;
365 	optind = 1;
366 	optreset = 1;
367 	while ((ch = getopt(argc, argv, "vd")) != -1) {
368 		switch(ch) {
369 		case 'v':
370 			pnp_verbose_flag = 1;
371 			break;
372 		case 'd':
373 			pnp_dump_flag = 1;
374 			break;
375 		case '?':
376 		default:
377 			/* getopt has already reported an error */
378 			return(CMD_OK);
379 		}
380 	}
381 	argv += (optind - 1);
382 	argc -= (optind - 1);
383 
384 	module = mod_searchmodule_pnpinfo(argv[1], argv[2]);
385 	if (module)
386 		printf("Matched module: %s\n", module);
387 	else if(argv[1])
388 		printf("No module matches %s\n", argv[1]);
389 
390 	return (CMD_OK);
391 }
392 
393 COMMAND_SET(pnpload, "pnpload", "load matched modules based on pnpinfo", command_pnpload);
394 
395 static int
396 command_pnpload(int argc, char *argv[])
397 {
398 	char *module;
399 	int ch, error;
400 
401 	pnp_verbose_flag = 0;
402 	pnp_dump_flag = 0;
403 	optind = 1;
404 	optreset = 1;
405 	while ((ch = getopt(argc, argv, "vd")) != -1) {
406 		switch(ch) {
407 		case 'v':
408 			pnp_verbose_flag = 1;
409 			break;
410 		case 'd':
411 			pnp_dump_flag = 1;
412 			break;
413 		case '?':
414 		default:
415 			/* getopt has already reported an error */
416 			return(CMD_OK);
417 		}
418 	}
419 	argv += (optind - 1);
420 	argc -= (optind - 1);
421 
422 	if (argc != 2)
423 		return (CMD_ERROR);
424 
425 	module = mod_searchmodule_pnpinfo(argv[1], argv[2]);
426 
427 	error = mod_load(module, NULL, 0, NULL);
428 	if (error == EEXIST) {
429 		snprintf(command_errbuf, sizeof(command_errbuf),
430 		  "warning: module '%s' already loaded", argv[1]);
431 		return (CMD_WARN);
432 	}
433 
434 	return (error == 0 ? CMD_OK : CMD_CRIT);
435 }
436 
437 #if defined(LOADER_FDT_SUPPORT)
438 static void
439 pnpautoload_simplebus(void) {
440 	const char *pnpstring;
441 	const char *compatstr;
442 	char *pnpinfo = NULL;
443 	char *module = NULL;
444 	int tag = 0, len, pnplen;
445 	int error;
446 
447 	while (1) {
448 		pnpstring = fdt_devmatch_next(&tag, &len);
449 		if (pnpstring == NULL)
450 			return;
451 
452 		compatstr = pnpstring;
453 		for (pnplen = 0; pnplen != len; compatstr = pnpstring + pnplen) {
454 			pnplen += strlen(compatstr) + 1;
455 			asprintf(&pnpinfo, "compat=%s", compatstr);
456 
457 			module = mod_searchmodule_pnpinfo("simplebus", pnpinfo);
458 			if (module) {
459 				error = mod_loadkld(module, 0, NULL);
460 				if (error)
461 					printf("Cannot load module %s\n", module);
462 				break;
463 			}
464 		}
465 		free(pnpinfo);
466 		free(module);
467 	}
468 }
469 #endif
470 
471 struct pnp_bus {
472 	const char *name;
473 	void (*load)(void);
474 };
475 
476 struct pnp_bus pnp_buses[] = {
477 #if defined(LOADER_FDT_SUPPORT)
478 	{"simplebus", pnpautoload_simplebus},
479 #endif
480 };
481 
482 COMMAND_SET(pnpautoload, "pnpautoload", "auto load modules based on pnpinfo", command_pnpautoload);
483 
484 static int
485 command_pnpautoload(int argc, char *argv[])
486 {
487 	int i;
488 	int verbose;
489 	int ch, match;
490 
491 	pnp_verbose_flag = 0;
492 	pnp_dump_flag = 0;
493 	verbose = 0;
494 	optind = 1;
495 	optreset = 1;
496 	match = 0;
497 	while ((ch = getopt(argc, argv, "v")) != -1) {
498 		switch(ch) {
499 		case 'v':
500 			verbose = 1;
501 			break;
502 		case '?':
503 		default:
504 			/* getopt has already reported an error */
505 			return(CMD_OK);
506 		}
507 	}
508 	argv += (optind - 1);
509 	argc -= (optind - 1);
510 
511 	if (argc > 2)
512 		return (CMD_ERROR);
513 
514 	for (i = 0; i < nitems(pnp_buses); i++) {
515 		if (argc == 2 && strcmp(argv[1], pnp_buses[i].name) != 0) {
516 			if (verbose)
517 				printf("Skipping bus %s\n", pnp_buses[i].name);
518 			continue;
519 		}
520 		if (verbose)
521 			printf("Autoloading modules for simplebus\n");
522 		pnp_buses[i].load();
523 		match = 1;
524 	}
525 	if (match == 0)
526 		printf("Unsupported bus %s\n", argv[1]);
527 
528 	return (CMD_OK);
529 }
530 
531 /*
532  * File level interface, functions file_*
533  */
534 int
535 file_load(char *filename, vm_offset_t dest, struct preloaded_file **result)
536 {
537 	static int last_file_format = 0;
538 	struct preloaded_file *fp;
539 	int error;
540 	int i;
541 
542 	if (archsw.arch_loadaddr != NULL)
543 		dest = archsw.arch_loadaddr(LOAD_RAW, filename, dest);
544 
545 	error = EFTYPE;
546 	for (i = last_file_format, fp = NULL;
547 	     file_formats[i] && fp == NULL; i++) {
548 		error = (file_formats[i]->l_load)(filename, dest, &fp);
549 		if (error == 0) {
550 			fp->f_loader = last_file_format = i; /* remember the loader */
551 			*result = fp;
552 			break;
553 		} else if (last_file_format == i && i != 0) {
554 			/* Restart from the beginning */
555 			i = -1;
556 			last_file_format = 0;
557 			fp = NULL;
558 			continue;
559 		}
560 		if (error == EFTYPE)
561 			continue;		/* Unknown to this handler? */
562 		if (error) {
563 			snprintf(command_errbuf, sizeof(command_errbuf),
564 			  "can't load file '%s': %s", filename, strerror(error));
565 			break;
566 		}
567 	}
568 	return (error);
569 }
570 
571 static int
572 file_load_dependencies(struct preloaded_file *base_file)
573 {
574 	struct file_metadata *md;
575 	struct preloaded_file *fp;
576 	struct mod_depend *verinfo;
577 	struct kernel_module *mp;
578 	char *dmodname;
579 	int error;
580 
581 	md = file_findmetadata(base_file, MODINFOMD_DEPLIST);
582 	if (md == NULL)
583 		return (0);
584 	error = 0;
585 	do {
586 		verinfo = (struct mod_depend*)md->md_data;
587 		dmodname = (char *)(verinfo + 1);
588 		if (file_findmodule(NULL, dmodname, verinfo) == NULL) {
589 			printf("loading required module '%s'\n", dmodname);
590 			error = mod_load(dmodname, verinfo, 0, NULL);
591 			if (error)
592 				break;
593 			/*
594 			 * If module loaded via kld name which isn't listed
595 			 * in the linker.hints file, we should check if it have
596 			 * required version.
597 			 */
598 			mp = file_findmodule(NULL, dmodname, verinfo);
599 			if (mp == NULL) {
600 				snprintf(command_errbuf, sizeof(command_errbuf),
601 				  "module '%s' exists but with wrong version", dmodname);
602 				error = ENOENT;
603 				break;
604 			}
605 		}
606 		md = metadata_next(md, MODINFOMD_DEPLIST);
607 	} while (md);
608 	if (!error)
609 		return (0);
610 	/* Load failed; discard everything */
611 	while (base_file != NULL) {
612 		fp = base_file;
613 		base_file = base_file->f_next;
614 		file_discard(fp);
615 	}
616 	return (error);
617 }
618 
619 
620 #ifdef LOADER_VERIEXEC_VECTX
621 #define VECTX_HANDLE(fd) vctx
622 #else
623 #define VECTX_HANDLE(fd) fd
624 #endif
625 
626 
627 /*
628  * We've been asked to load (fname) as (type), so just suck it in,
629  * no arguments or anything.
630  */
631 struct preloaded_file *
632 file_loadraw(const char *fname, char *type, int insert)
633 {
634 	struct preloaded_file	*fp;
635 	char			*name;
636 	int				fd, got;
637 	vm_offset_t			laddr;
638 #ifdef LOADER_VERIEXEC_VECTX
639 	struct vectx		*vctx;
640 	int			verror;
641 #endif
642 
643 	/* We can't load first */
644 	if ((file_findfile(NULL, NULL)) == NULL) {
645 		command_errmsg = "can't load file before kernel";
646 		return(NULL);
647 	}
648 
649 	/* locate the file on the load path */
650 	name = file_search(fname, NULL);
651 	if (name == NULL) {
652 		snprintf(command_errbuf, sizeof(command_errbuf),
653 		  "can't find '%s'", fname);
654 		return(NULL);
655 	}
656 
657 	if ((fd = open(name, O_RDONLY)) < 0) {
658 		snprintf(command_errbuf, sizeof(command_errbuf),
659 		  "can't open '%s': %s", name, strerror(errno));
660 		free(name);
661 		return(NULL);
662 	}
663 
664 #ifdef LOADER_VERIEXEC_VECTX
665 	vctx = vectx_open(fd, name, 0L, NULL, &verror, __func__);
666 	if (verror) {
667 		sprintf(command_errbuf, "can't verify '%s': %s",
668 		    name, ve_error_get());
669 		free(name);
670 		free(vctx);
671 		close(fd);
672 		return(NULL);
673 	}
674 #else
675 #ifdef LOADER_VERIEXEC
676 	if (verify_file(fd, name, 0, VE_MUST, __func__) < 0) {
677 		sprintf(command_errbuf, "can't verify '%s': %s",
678 		    name, ve_error_get());
679 		free(name);
680 		close(fd);
681 		return(NULL);
682 	}
683 #endif
684 #endif
685 
686 	if (archsw.arch_loadaddr != NULL)
687 		loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr);
688 
689 	printf("%s ", name);
690 
691 	laddr = loadaddr;
692 	for (;;) {
693 		/* read in 4k chunks; size is not really important */
694 		got = archsw.arch_readin(VECTX_HANDLE(fd), laddr, 4096);
695 		if (got == 0)				/* end of file */
696 			break;
697 		if (got < 0) {				/* error */
698 			snprintf(command_errbuf, sizeof(command_errbuf),
699 			  "error reading '%s': %s", name, strerror(errno));
700 			free(name);
701 			close(fd);
702 #ifdef LOADER_VERIEXEC_VECTX
703 			free(vctx);
704 #endif
705 			return(NULL);
706 		}
707 		laddr += got;
708 	}
709 
710 	printf("size=%#jx\n", (uintmax_t)(laddr - loadaddr));
711 #ifdef LOADER_VERIEXEC_VECTX
712 	verror = vectx_close(vctx, VE_MUST, __func__);
713 	if (verror) {
714 		free(name);
715 		close(fd);
716 		free(vctx);
717 		return(NULL);
718 	}
719 #endif
720 
721 	/* Looks OK so far; create & populate control structure */
722 	fp = file_alloc();
723 	if (fp == NULL) {
724 		snprintf(command_errbuf, sizeof (command_errbuf),
725 		    "no memory to load %s", name);
726 		free(name);
727 		close(fd);
728 		return (NULL);
729 	}
730 	fp->f_name = name;
731 	fp->f_type = strdup(type);
732 	fp->f_args = NULL;
733 	fp->f_metadata = NULL;
734 	fp->f_loader = -1;
735 	fp->f_addr = loadaddr;
736 	fp->f_size = laddr - loadaddr;
737 
738 	if (fp->f_type == NULL) {
739 		snprintf(command_errbuf, sizeof (command_errbuf),
740 		    "no memory to load %s", name);
741 		free(name);
742 		close(fd);
743 		return (NULL);
744 	}
745 	/* recognise space consumption */
746 	loadaddr = laddr;
747 
748 	/* Add to the list of loaded files */
749 	if (insert != 0)
750 		file_insert_tail(fp);
751 	close(fd);
752 	return(fp);
753 }
754 
755 /*
756  * Load the module (name), pass it (argc),(argv), add container file
757  * to the list of loaded files.
758  * If module is already loaded just assign new argc/argv.
759  */
760 int
761 mod_load(char *modname, struct mod_depend *verinfo, int argc, char *argv[])
762 {
763 	struct kernel_module	*mp;
764 	int				err;
765 	char			*filename;
766 
767 	if (file_havepath(modname)) {
768 		printf("Warning: mod_load() called instead of mod_loadkld() for module '%s'\n", modname);
769 		return (mod_loadkld(modname, argc, argv));
770 	}
771 	/* see if module is already loaded */
772 	mp = file_findmodule(NULL, modname, verinfo);
773 	if (mp) {
774 #ifdef moduleargs
775 		free(mp->m_args);
776 		mp->m_args = unargv(argc, argv);
777 #endif
778 		snprintf(command_errbuf, sizeof(command_errbuf),
779 		  "warning: module '%s' already loaded", mp->m_name);
780 		return (0);
781 	}
782 	/* locate file with the module on the search path */
783 	filename = mod_searchmodule(modname, verinfo);
784 	if (filename == NULL) {
785 		snprintf(command_errbuf, sizeof(command_errbuf),
786 		  "can't find '%s'", modname);
787 		return (ENOENT);
788 	}
789 	err = mod_loadkld(filename, argc, argv);
790 	free(filename);
791 	return (err);
792 }
793 
794 /*
795  * Load specified KLD. If path is omitted, then try to locate it via
796  * search path.
797  */
798 int
799 mod_loadkld(const char *kldname, int argc, char *argv[])
800 {
801 	struct preloaded_file	*fp;
802 	int			err;
803 	char			*filename;
804 	vm_offset_t		loadaddr_saved;
805 
806 	/*
807 	 * Get fully qualified KLD name
808 	 */
809 	filename = file_search(kldname, kld_ext_list);
810 	if (filename == NULL) {
811 		snprintf(command_errbuf, sizeof(command_errbuf),
812 		  "can't find '%s'", kldname);
813 		return (ENOENT);
814 	}
815 	/*
816 	 * Check if KLD already loaded
817 	 */
818 	fp = file_findfile(filename, NULL);
819 	if (fp) {
820 		snprintf(command_errbuf, sizeof(command_errbuf),
821 		  "warning: KLD '%s' already loaded", filename);
822 		free(filename);
823 		return (0);
824 	}
825 
826 	do {
827 		err = file_load(filename, loadaddr, &fp);
828 		if (err)
829 			break;
830 		fp->f_args = unargv(argc, argv);
831 		loadaddr_saved = loadaddr;
832 		loadaddr = fp->f_addr + fp->f_size;
833 		file_insert_tail(fp);	/* Add to the list of loaded files */
834 		if (file_load_dependencies(fp) != 0) {
835 			err = ENOENT;
836 			file_remove(fp);
837 			loadaddr = loadaddr_saved;
838 			fp = NULL;
839 			break;
840 		}
841 	} while(0);
842 	if (err == EFTYPE) {
843 		snprintf(command_errbuf, sizeof(command_errbuf),
844 		  "don't know how to load module '%s'", filename);
845 	}
846 	if (err)
847 		file_discard(fp);
848 	free(filename);
849 	return (err);
850 }
851 
852 /*
853  * Find a file matching (name) and (type).
854  * NULL may be passed as a wildcard to either.
855  */
856 struct preloaded_file *
857 file_findfile(const char *name, const char *type)
858 {
859 	struct preloaded_file *fp;
860 
861 	for (fp = preloaded_files; fp != NULL; fp = fp->f_next) {
862 		if (((name == NULL) || !strcmp(name, fp->f_name)) &&
863 		  ((type == NULL) || !strcmp(type, fp->f_type)))
864 			break;
865 	}
866 	return (fp);
867 }
868 
869 /*
870  * Find a module matching (name) inside of given file.
871  * NULL may be passed as a wildcard.
872  */
873 struct kernel_module *
874 file_findmodule(struct preloaded_file *fp, char *modname,
875 	struct mod_depend *verinfo)
876 {
877 	struct kernel_module *mp, *best;
878 	int bestver, mver;
879 
880 	if (fp == NULL) {
881 		for (fp = preloaded_files; fp; fp = fp->f_next) {
882 			mp = file_findmodule(fp, modname, verinfo);
883 			if (mp)
884 				return (mp);
885 		}
886 		return (NULL);
887 	}
888 	best = NULL;
889 	bestver = 0;
890 	for (mp = fp->f_modules; mp; mp = mp->m_next) {
891 		if (strcmp(modname, mp->m_name) == 0) {
892 			if (verinfo == NULL)
893 				return (mp);
894 			mver = mp->m_version;
895 			if (mver == verinfo->md_ver_preferred)
896 				return (mp);
897 			if (mver >= verinfo->md_ver_minimum &&
898 			  mver <= verinfo->md_ver_maximum &&
899 			  mver > bestver) {
900 				best = mp;
901 				bestver = mver;
902 			}
903 		}
904 	}
905 	return (best);
906 }
907 /*
908  * Make a copy of (size) bytes of data from (p), and associate them as
909  * metadata of (type) to the module (mp).
910  */
911 void
912 file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p)
913 {
914 	struct file_metadata	*md;
915 
916 	md = malloc(sizeof(struct file_metadata) - sizeof(md->md_data) + size);
917 	if (md != NULL) {
918 		md->md_size = size;
919 		md->md_type = type;
920 		bcopy(p, md->md_data, size);
921 		md->md_next = fp->f_metadata;
922 	}
923 	fp->f_metadata = md;
924 }
925 
926 /*
927  * Find a metadata object of (type) associated with the file (fp)
928  */
929 struct file_metadata *
930 file_findmetadata(struct preloaded_file *fp, int type)
931 {
932 	struct file_metadata *md;
933 
934 	for (md = fp->f_metadata; md != NULL; md = md->md_next)
935 		if (md->md_type == type)
936 			break;
937 	return(md);
938 }
939 
940 /*
941  * Remove all metadata from the file.
942  */
943 void
944 file_removemetadata(struct preloaded_file *fp)
945 {
946 	struct file_metadata *md, *next;
947 
948 	for (md = fp->f_metadata; md != NULL; md = next)
949 	{
950 		next = md->md_next;
951 		free(md);
952 	}
953 	fp->f_metadata = NULL;
954 }
955 
956 struct file_metadata *
957 metadata_next(struct file_metadata *md, int type)
958 {
959 
960 	if (md == NULL)
961 		return (NULL);
962 	while((md = md->md_next) != NULL)
963 		if (md->md_type == type)
964 			break;
965 	return (md);
966 }
967 
968 static char *emptyextlist[] = { "", NULL };
969 
970 /*
971  * Check if the given file is in place and return full path to it.
972  */
973 static char *
974 file_lookup(const char *path, const char *name, int namelen, char **extlist)
975 {
976 	struct stat	st;
977 	char	*result, *cp, **cpp;
978 	int		pathlen, extlen, len;
979 
980 	pathlen = strlen(path);
981 	extlen = 0;
982 	if (extlist == NULL)
983 		extlist = emptyextlist;
984 	for (cpp = extlist; *cpp; cpp++) {
985 		len = strlen(*cpp);
986 		if (len > extlen)
987 			extlen = len;
988 	}
989 	result = malloc(pathlen + namelen + extlen + 2);
990 	if (result == NULL)
991 		return (NULL);
992 	bcopy(path, result, pathlen);
993 	if (pathlen > 0 && result[pathlen - 1] != '/')
994 		result[pathlen++] = '/';
995 	cp = result + pathlen;
996 	bcopy(name, cp, namelen);
997 	cp += namelen;
998 	for (cpp = extlist; *cpp; cpp++) {
999 		strcpy(cp, *cpp);
1000 		if (stat(result, &st) == 0 && S_ISREG(st.st_mode))
1001 			return result;
1002 	}
1003 	free(result);
1004 	return NULL;
1005 }
1006 
1007 /*
1008  * Check if file name have any qualifiers
1009  */
1010 static int
1011 file_havepath(const char *name)
1012 {
1013 	const char		*cp;
1014 
1015 	archsw.arch_getdev(NULL, name, &cp);
1016 	return (cp != name || strchr(name, '/') != NULL);
1017 }
1018 
1019 /*
1020  * Attempt to find the file (name) on the module searchpath.
1021  * If (name) is qualified in any way, we simply check it and
1022  * return it or NULL.  If it is not qualified, then we attempt
1023  * to construct a path using entries in the environment variable
1024  * module_path.
1025  *
1026  * The path we return a pointer to need never be freed, as we manage
1027  * it internally.
1028  */
1029 static char *
1030 file_search(const char *name, char **extlist)
1031 {
1032 	struct moduledir	*mdp;
1033 	struct stat		sb;
1034 	char		*result;
1035 	int			namelen;
1036 
1037 	/* Don't look for nothing */
1038 	if (name == NULL)
1039 		return(NULL);
1040 
1041 	if (*name == 0)
1042 		return(strdup(name));
1043 
1044 	if (file_havepath(name)) {
1045 		/* Qualified, so just see if it exists */
1046 		if (stat(name, &sb) == 0)
1047 			return(strdup(name));
1048 		return(NULL);
1049 	}
1050 	moduledir_rebuild();
1051 	result = NULL;
1052 	namelen = strlen(name);
1053 	STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1054 		result = file_lookup(mdp->d_path, name, namelen, extlist);
1055 		if (result)
1056 			break;
1057 	}
1058 	return(result);
1059 }
1060 
1061 #define	INT_ALIGN(base, ptr)	ptr = \
1062 	(base) + roundup2((ptr) - (base), sizeof(int))
1063 
1064 static char *
1065 mod_search_hints(struct moduledir *mdp, const char *modname,
1066 	struct mod_depend *verinfo)
1067 {
1068 	u_char	*cp, *recptr, *bufend, *best;
1069 	char	*result;
1070 	int		*intp, bestver, blen, clen, found, ival, modnamelen, reclen;
1071 
1072 	moduledir_readhints(mdp);
1073 	modnamelen = strlen(modname);
1074 	found = 0;
1075 	result = NULL;
1076 	bestver = 0;
1077 	if (mdp->d_hints == NULL)
1078 		goto bad;
1079 	recptr = mdp->d_hints;
1080 	bufend = recptr + mdp->d_hintsz;
1081 	clen = blen = 0;
1082 	best = cp = NULL;
1083 	while (recptr < bufend && !found) {
1084 		intp = (int*)recptr;
1085 		reclen = *intp++;
1086 		ival = *intp++;
1087 		cp = (u_char*)intp;
1088 		switch (ival) {
1089 		case MDT_VERSION:
1090 			clen = *cp++;
1091 			if (clen != modnamelen || bcmp(cp, modname, clen) != 0)
1092 				break;
1093 			cp += clen;
1094 			INT_ALIGN(mdp->d_hints, cp);
1095 			ival = *(int*)cp;
1096 			cp += sizeof(int);
1097 			clen = *cp++;
1098 			if (verinfo == NULL || ival == verinfo->md_ver_preferred) {
1099 				found = 1;
1100 				break;
1101 			}
1102 			if (ival >= verinfo->md_ver_minimum &&
1103 			  ival <= verinfo->md_ver_maximum &&
1104 			  ival > bestver) {
1105 				bestver = ival;
1106 				best = cp;
1107 				blen = clen;
1108 			}
1109 			break;
1110 		default:
1111 			break;
1112 		}
1113 		recptr += reclen + sizeof(int);
1114 	}
1115 	/*
1116 	 * Finally check if KLD is in the place
1117 	 */
1118 	if (found)
1119 		result = file_lookup(mdp->d_path, (const char *)cp, clen, NULL);
1120 	else if (best)
1121 		result = file_lookup(mdp->d_path, (const char *)best, blen, NULL);
1122 bad:
1123 	/*
1124 	 * If nothing found or hints is absent - fallback to the old way
1125 	 * by using "kldname[.ko]" as module name.
1126 	 */
1127 	if (!found && !bestver && result == NULL)
1128 		result = file_lookup(mdp->d_path, modname, modnamelen, kld_ext_list);
1129 	return result;
1130 }
1131 
1132 static int
1133 getint(void **ptr)
1134 {
1135 	int *p = *ptr;
1136 	int rv;
1137 
1138 	p = (int *)roundup2((intptr_t)p, sizeof(int));
1139 	rv = *p++;
1140 	*ptr = p;
1141 	return rv;
1142 }
1143 
1144 static void
1145 getstr(void **ptr, char *val)
1146 {
1147 	int *p = *ptr;
1148 	char *c = (char *)p;
1149 	int len = *(uint8_t *)c;
1150 
1151 	memcpy(val, c + 1, len);
1152 	val[len] = 0;
1153 	c += len + 1;
1154 	*ptr = (void *)c;
1155 }
1156 
1157 static int
1158 pnpval_as_int(const char *val, const char *pnpinfo)
1159 {
1160 	int rv;
1161 	char key[256];
1162 	char *cp;
1163 
1164 	if (pnpinfo == NULL)
1165 		return -1;
1166 
1167 	cp = strchr(val, ';');
1168 	key[0] = ' ';
1169 	if (cp == NULL)
1170 		strlcpy(key + 1, val, sizeof(key) - 1);
1171 	else {
1172 		memcpy(key + 1, val, cp - val);
1173 		key[cp - val + 1] = '\0';
1174 	}
1175 	strlcat(key, "=", sizeof(key));
1176 	if (strncmp(key + 1, pnpinfo, strlen(key + 1)) == 0)
1177 		rv = strtol(pnpinfo + strlen(key + 1), NULL, 0);
1178 	else {
1179 		cp = strstr(pnpinfo, key);
1180 		if (cp == NULL)
1181 			rv = -1;
1182 		else
1183 			rv = strtol(cp + strlen(key), NULL, 0);
1184 	}
1185 	return rv;
1186 }
1187 
1188 static void
1189 quoted_strcpy(char *dst, const char *src)
1190 {
1191 	char q = ' ';
1192 
1193 	if (*src == '\'' || *src == '"')
1194 		q = *src++;
1195 	while (*src && *src != q)
1196 		*dst++ = *src++; // XXX backtick quoting
1197 	*dst++ = '\0';
1198 	// XXX overflow
1199 }
1200 
1201 static char *
1202 pnpval_as_str(const char *val, const char *pnpinfo)
1203 {
1204 	static char retval[256];
1205 	char key[256];
1206 	char *cp;
1207 
1208 	if (pnpinfo == NULL) {
1209 		*retval = '\0';
1210 		return retval;
1211 	}
1212 
1213 	cp = strchr(val, ';');
1214 	key[0] = ' ';
1215 	if (cp == NULL)
1216 		strlcpy(key + 1, val, sizeof(key) - 1);
1217 	else {
1218 		memcpy(key + 1, val, cp - val);
1219 		key[cp - val + 1] = '\0';
1220 	}
1221 	strlcat(key, "=", sizeof(key));
1222 	if (strncmp(key + 1, pnpinfo, strlen(key + 1)) == 0)
1223 		quoted_strcpy(retval, pnpinfo + strlen(key + 1));
1224 	else {
1225 		cp = strstr(pnpinfo, key);
1226 		if (cp == NULL)
1227 			strcpy(retval, "MISSING");
1228 		else
1229 			quoted_strcpy(retval, cp + strlen(key));
1230 	}
1231 	return retval;
1232 }
1233 
1234 static char *
1235 devmatch_search_hints(struct moduledir *mdp, const char *bus, const char *dev, const char *pnpinfo)
1236 {
1237 	char val1[256], val2[256];
1238 	int ival, len, ents, i, notme, mask, bit, v, found;
1239 	void *ptr, *walker, *hints_end;
1240 	char *lastmod = NULL, *cp, *s;
1241 
1242 	moduledir_readhints(mdp);
1243 	found = 0;
1244 	if (mdp->d_hints == NULL)
1245 		goto bad;
1246 	walker = mdp->d_hints;
1247 	hints_end = walker + mdp->d_hintsz;
1248 	while (walker < hints_end && !found) {
1249 		len = getint(&walker);
1250 		ival = getint(&walker);
1251 		ptr = walker;
1252 		switch (ival) {
1253 		case MDT_VERSION:
1254 			getstr(&ptr, val1);
1255 			ival = getint(&ptr);
1256 			getstr(&ptr, val2);
1257 			if (pnp_dump_flag || pnp_verbose_flag)
1258 				printf("Version: if %s.%d kmod %s\n", val1, ival, val2);
1259 			break;
1260 		case MDT_MODULE:
1261 			getstr(&ptr, val1);
1262 			getstr(&ptr, val2);
1263 			if (lastmod)
1264 				free(lastmod);
1265 			lastmod = strdup(val2);
1266 			if (pnp_dump_flag || pnp_verbose_flag)
1267 				printf("module %s in %s\n", val1, val1);
1268 			break;
1269 		case MDT_PNP_INFO:
1270 			if (!pnp_dump_flag && !pnp_unbound_flag && lastmod && strcmp(lastmod, "kernel") == 0)
1271 				break;
1272 			getstr(&ptr, val1);
1273 			getstr(&ptr, val2);
1274 			ents = getint(&ptr);
1275 			if (pnp_dump_flag || pnp_verbose_flag)
1276 				printf("PNP info for bus %s format %s %d entries (%s)\n",
1277 				    val1, val2, ents, lastmod);
1278 			if (strcmp(val1, "usb") == 0) {
1279 				if (pnp_verbose_flag)
1280 					printf("Treating usb as uhub -- bug in source table still?\n");
1281 				strcpy(val1, "uhub");
1282 			}
1283 			if (bus && strcmp(val1, bus) != 0) {
1284 				if (pnp_verbose_flag)
1285 					printf("Skipped because table for bus %s, looking for %s\n",
1286 					    val1, bus);
1287 				break;
1288 			}
1289 			for (i = 0; i < ents; i++) {
1290 				if (pnp_verbose_flag)
1291 					printf("---------- Entry %d ----------\n", i);
1292 				if (pnp_dump_flag)
1293 					printf("   ");
1294 				cp = val2;
1295 				notme = 0;
1296 				mask = -1;
1297 				bit = -1;
1298 				do {
1299 					switch (*cp) {
1300 						/* All integer fields */
1301 					case 'I':
1302 					case 'J':
1303 					case 'G':
1304 					case 'L':
1305 					case 'M':
1306 						ival = getint(&ptr);
1307 						if (pnp_dump_flag) {
1308 							printf("%#x:", ival);
1309 							break;
1310 						}
1311 						if (bit >= 0 && ((1 << bit) & mask) == 0)
1312 							break;
1313 						v = pnpval_as_int(cp + 2, pnpinfo);
1314 						if (pnp_verbose_flag)
1315 							printf("Matching %s (%c) table=%#x tomatch=%#x\n",
1316 							    cp + 2, *cp, v, ival);
1317 						switch (*cp) {
1318 						case 'J':
1319 							if (ival == -1)
1320 								break;
1321 							/*FALLTHROUGH*/
1322 						case 'I':
1323 							if (v != ival)
1324 								notme++;
1325 							break;
1326 						case 'G':
1327 							if (v < ival)
1328 								notme++;
1329 							break;
1330 						case 'L':
1331 							if (v > ival)
1332 								notme++;
1333 							break;
1334 						case 'M':
1335 							mask = ival;
1336 							break;
1337 						}
1338 						break;
1339 						/* String fields */
1340 					case 'D':
1341 					case 'Z':
1342 						getstr(&ptr, val1);
1343 						if (pnp_dump_flag) {
1344 							printf("'%s':", val1);
1345 							break;
1346 						}
1347 						if (*cp == 'D')
1348 							break;
1349 						s = pnpval_as_str(cp + 2, pnpinfo);
1350 						if (strcmp(s, val1) != 0)
1351 							notme++;
1352 						break;
1353 						/* Key override fields, required to be last in the string */
1354 					case 'T':
1355 						/*
1356 						 * This is imperfect and only does one key and will be redone
1357 						 * to be more general for multiple keys. Currently, nothing
1358 						 * does that.
1359 						 */
1360 						if (pnp_dump_flag)				/* No per-row data stored */
1361 							break;
1362 						if (cp[strlen(cp) - 1] == ';')		/* Skip required ; at end */
1363 							cp[strlen(cp) - 1] = '\0';	/* in case it's not there */
1364 						if ((s = strstr(pnpinfo, cp + 2)) == NULL)
1365 							notme++;
1366 						else if (s > pnpinfo && s[-1] != ' ')
1367 							notme++;
1368 						break;
1369 					default:
1370 						printf("Unknown field type %c\n:", *cp);
1371 						break;
1372 					}
1373 					bit++;
1374 					cp = strchr(cp, ';');
1375 					if (cp)
1376 						cp++;
1377 				} while (cp && *cp);
1378 				if (pnp_dump_flag)
1379 					printf("\n");
1380 				else if (!notme) {
1381 					if (!pnp_unbound_flag) {
1382 						if (pnp_verbose_flag)
1383 							printf("Matches --- %s ---\n", lastmod);
1384 					}
1385 					found++;
1386 				}
1387 			}
1388 			break;
1389 		default:
1390 			break;
1391 		}
1392 		walker = (void *)(len - sizeof(int) + (intptr_t)walker);
1393 	}
1394 	if (pnp_unbound_flag && found == 0 && *pnpinfo) {
1395 		if (pnp_verbose_flag)
1396 			printf("------------------------- ");
1397 		printf("%s on %s pnpinfo %s", *dev ? dev : "unattached", bus, pnpinfo);
1398 		if (pnp_verbose_flag)
1399 			printf(" -------------------------");
1400 		printf("\n");
1401 	}
1402 	if (found != 0)
1403 		return (lastmod);
1404 	free(lastmod);
1405 
1406 bad:
1407 	return (NULL);
1408 }
1409 
1410 /*
1411  * Attempt to locate the file containing the module (name)
1412  */
1413 static char *
1414 mod_searchmodule(char *name, struct mod_depend *verinfo)
1415 {
1416 	struct	moduledir *mdp;
1417 	char	*result;
1418 
1419 	moduledir_rebuild();
1420 	/*
1421 	 * Now we ready to lookup module in the given directories
1422 	 */
1423 	result = NULL;
1424 	STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1425 		result = mod_search_hints(mdp, name, verinfo);
1426 		if (result)
1427 			break;
1428 	}
1429 
1430 	return(result);
1431 }
1432 
1433 static char *
1434 mod_searchmodule_pnpinfo(const char *bus, const char *pnpinfo)
1435 {
1436 	struct	moduledir *mdp;
1437 	char	*result;
1438 
1439 	moduledir_rebuild();
1440 	/*
1441 	 * Now we ready to lookup module in the given directories
1442 	 */
1443 	result = NULL;
1444 	STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1445 		result = devmatch_search_hints(mdp, bus, NULL, pnpinfo);
1446 		if (result)
1447 			break;
1448 	}
1449 
1450 	return(result);
1451 }
1452 
1453 int
1454 file_addmodule(struct preloaded_file *fp, char *modname, int version,
1455 	struct kernel_module **newmp)
1456 {
1457 	struct kernel_module *mp;
1458 	struct mod_depend mdepend;
1459 
1460 	bzero(&mdepend, sizeof(mdepend));
1461 	mdepend.md_ver_preferred = version;
1462 	mp = file_findmodule(fp, modname, &mdepend);
1463 	if (mp)
1464 		return (EEXIST);
1465 	mp = calloc(1, sizeof(struct kernel_module));
1466 	if (mp == NULL)
1467 		return (ENOMEM);
1468 	mp->m_name = strdup(modname);
1469 	if (mp->m_name == NULL) {
1470 		free(mp);
1471 		return (ENOMEM);
1472 	}
1473 	mp->m_version = version;
1474 	mp->m_fp = fp;
1475 	mp->m_next = fp->f_modules;
1476 	fp->f_modules = mp;
1477 	if (newmp)
1478 		*newmp = mp;
1479 	return (0);
1480 }
1481 
1482 /*
1483  * Throw a file away
1484  */
1485 void
1486 file_discard(struct preloaded_file *fp)
1487 {
1488 	struct file_metadata	*md, *md1;
1489 	struct kernel_module	*mp, *mp1;
1490 	if (fp == NULL)
1491 		return;
1492 	md = fp->f_metadata;
1493 	while (md) {
1494 		md1 = md;
1495 		md = md->md_next;
1496 		free(md1);
1497 	}
1498 	mp = fp->f_modules;
1499 	while (mp) {
1500 		free(mp->m_name);
1501 		mp1 = mp;
1502 		mp = mp->m_next;
1503 		free(mp1);
1504 	}
1505 	free(fp->f_name);
1506 	free(fp->f_type);
1507 	free(fp->f_args);
1508 	free(fp);
1509 }
1510 
1511 /*
1512  * Allocate a new file; must be used instead of malloc()
1513  * to ensure safe initialisation.
1514  */
1515 struct preloaded_file *
1516 file_alloc(void)
1517 {
1518 
1519 	return (calloc(1, sizeof(struct preloaded_file)));
1520 }
1521 
1522 /*
1523  * Add a module to the chain
1524  */
1525 static void
1526 file_insert_tail(struct preloaded_file *fp)
1527 {
1528 	struct preloaded_file	*cm;
1529 
1530 	/* Append to list of loaded file */
1531 	fp->f_next = NULL;
1532 	if (preloaded_files == NULL) {
1533 		preloaded_files = fp;
1534 	} else {
1535 		for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next)
1536 			;
1537 		cm->f_next = fp;
1538 	}
1539 }
1540 
1541 /*
1542  * Remove module from the chain
1543  */
1544 static void
1545 file_remove(struct preloaded_file *fp)
1546 {
1547 	struct preloaded_file   *cm;
1548 
1549 	if (preloaded_files == NULL)
1550 		return;
1551 
1552 	if (preloaded_files == fp) {
1553 		preloaded_files = fp->f_next;
1554 		return;
1555         }
1556         for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next) {
1557 		if (cm->f_next == fp) {
1558 			cm->f_next = fp->f_next;
1559 			return;
1560 		}
1561 	}
1562 }
1563 
1564 static char *
1565 moduledir_fullpath(struct moduledir *mdp, const char *fname)
1566 {
1567 	char *cp;
1568 
1569 	cp = malloc(strlen(mdp->d_path) + strlen(fname) + 2);
1570 	if (cp == NULL)
1571 		return NULL;
1572 	strcpy(cp, mdp->d_path);
1573 	strcat(cp, "/");
1574 	strcat(cp, fname);
1575 	return (cp);
1576 }
1577 
1578 /*
1579  * Read linker.hints file into memory performing some sanity checks.
1580  */
1581 static void
1582 moduledir_readhints(struct moduledir *mdp)
1583 {
1584 	struct stat	st;
1585 	char	*path;
1586 	int		fd, size, version;
1587 
1588 	if (mdp->d_hints != NULL || (mdp->d_flags & MDIR_NOHINTS))
1589 		return;
1590 	path = moduledir_fullpath(mdp, "linker.hints");
1591 	if (stat(path, &st) != 0 ||
1592 	  st.st_size < (ssize_t)(sizeof(version) + sizeof(int)) ||
1593 	  st.st_size > LINKER_HINTS_MAX || (fd = open(path, O_RDONLY)) < 0) {
1594 		free(path);
1595 		mdp->d_flags |= MDIR_NOHINTS;
1596 		return;
1597 	}
1598 	free(path);
1599 	size = read(fd, &version, sizeof(version));
1600 	if (size != sizeof(version) || version != LINKER_HINTS_VERSION)
1601 		goto bad;
1602 	size = st.st_size - size;
1603 	mdp->d_hints = malloc(size);
1604 	if (mdp->d_hints == NULL)
1605 		goto bad;
1606 	if (read(fd, mdp->d_hints, size) != size)
1607 		goto bad;
1608 	mdp->d_hintsz = size;
1609 	close(fd);
1610 	return;
1611 bad:
1612 	close(fd);
1613 	free(mdp->d_hints);
1614 	mdp->d_hints = NULL;
1615 	mdp->d_flags |= MDIR_NOHINTS;
1616 	return;
1617 }
1618 
1619 /*
1620  * Extract directories from the ';' separated list, remove duplicates.
1621  */
1622 static void
1623 moduledir_rebuild(void)
1624 {
1625 	struct	moduledir *mdp, *mtmp;
1626 	const char	*path, *cp, *ep;
1627 	size_t	cplen;
1628 
1629 	path = getenv("module_path");
1630 	if (path == NULL)
1631 		path = default_searchpath;
1632 	/*
1633 	 * Rebuild list of module directories if it changed
1634 	 */
1635 	STAILQ_FOREACH(mdp, &moduledir_list, d_link)
1636 		mdp->d_flags |= MDIR_REMOVED;
1637 
1638 	for (ep = path; *ep != 0;  ep++) {
1639 		cp = ep;
1640 		for (; *ep != 0 && *ep != ';'; ep++)
1641 			;
1642 		/*
1643 		 * Ignore trailing slashes
1644 		 */
1645 		for (cplen = ep - cp; cplen > 1 && cp[cplen - 1] == '/'; cplen--)
1646 			;
1647 		STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1648 			if (strlen(mdp->d_path) != cplen ||	bcmp(cp, mdp->d_path, cplen) != 0)
1649 				continue;
1650 			mdp->d_flags &= ~MDIR_REMOVED;
1651 			break;
1652 		}
1653 		if (mdp == NULL) {
1654 			mdp = malloc(sizeof(*mdp) + cplen + 1);
1655 			if (mdp == NULL)
1656 				return;
1657 			mdp->d_path = (char*)(mdp + 1);
1658 			bcopy(cp, mdp->d_path, cplen);
1659 			mdp->d_path[cplen] = 0;
1660 			mdp->d_hints = NULL;
1661 			mdp->d_flags = 0;
1662 			STAILQ_INSERT_TAIL(&moduledir_list, mdp, d_link);
1663 		}
1664 		if (*ep == 0)
1665 			break;
1666 	}
1667 	/*
1668 	 * Delete unused directories if any
1669 	 */
1670 	mdp = STAILQ_FIRST(&moduledir_list);
1671 	while (mdp) {
1672 		if ((mdp->d_flags & MDIR_REMOVED) == 0) {
1673 			mdp = STAILQ_NEXT(mdp, d_link);
1674 		} else {
1675 			free(mdp->d_hints);
1676 			mtmp = mdp;
1677 			mdp = STAILQ_NEXT(mdp, d_link);
1678 			STAILQ_REMOVE(&moduledir_list, mtmp, moduledir, d_link);
1679 			free(mtmp);
1680 		}
1681 	}
1682 	return;
1683 }
1684