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