xref: /freebsd/stand/common/module.c (revision 00698711dee1d990d3db9c41bf58394e589eecfe)
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 			printf("loading required module '%s'\n", dmodname);
609 			error = mod_load(dmodname, verinfo, 0, NULL);
610 			if (error)
611 				break;
612 			/*
613 			 * If module loaded via kld name which isn't listed
614 			 * in the linker.hints file, we should check if it have
615 			 * required version.
616 			 */
617 			mp = file_findmodule(NULL, dmodname, verinfo);
618 			if (mp == NULL) {
619 				snprintf(command_errbuf, sizeof(command_errbuf),
620 				  "module '%s' exists but with wrong version", dmodname);
621 				error = ENOENT;
622 				break;
623 			}
624 		}
625 		md = metadata_next(md, MODINFOMD_DEPLIST);
626 	} while (md);
627 	if (!error)
628 		return (0);
629 	/* Load failed; discard everything */
630 	while (base_file != NULL) {
631 		fp = base_file;
632 		base_file = base_file->f_next;
633 		file_discard(fp);
634 	}
635 	return (error);
636 }
637 
638 vm_offset_t
639 build_font_module(vm_offset_t addr)
640 {
641 	vt_font_bitmap_data_t *bd;
642 	struct vt_font *fd;
643 	struct preloaded_file *fp;
644 	size_t size;
645 	uint32_t checksum;
646 	int i;
647 	struct font_info fi;
648 	struct fontlist *fl;
649 	uint64_t fontp;
650 
651 	if (STAILQ_EMPTY(&fonts))
652 		return (addr);
653 
654 	/* We can't load first */
655 	if ((file_findfile(NULL, NULL)) == NULL) {
656 		printf("Can not load font module: %s\n",
657 		    "the kernel is not loaded");
658 		return (addr);
659 	}
660 
661 	/* helper pointers */
662 	bd = NULL;
663 	STAILQ_FOREACH(fl, &fonts, font_next) {
664 		if (gfx_state.tg_font.vf_width == fl->font_data->vfbd_width &&
665 		    gfx_state.tg_font.vf_height == fl->font_data->vfbd_height) {
666 			/*
667 			 * Kernel does have better built in font.
668 			 */
669 			if (fl->font_flags == FONT_BUILTIN)
670 				return (addr);
671 
672 			bd = fl->font_data;
673 			break;
674 		}
675 	}
676 	if (bd == NULL)
677 		return (addr);
678 	fd = bd->vfbd_font;
679 
680 	fi.fi_width = fd->vf_width;
681 	checksum = fi.fi_width;
682 	fi.fi_height = fd->vf_height;
683 	checksum += fi.fi_height;
684 	fi.fi_bitmap_size = bd->vfbd_uncompressed_size;
685 	checksum += fi.fi_bitmap_size;
686 
687 	size = roundup2(sizeof (struct font_info), 8);
688 	for (i = 0; i < VFNT_MAPS; i++) {
689 		fi.fi_map_count[i] = fd->vf_map_count[i];
690 		checksum += fi.fi_map_count[i];
691 		size += fd->vf_map_count[i] * sizeof (struct vfnt_map);
692 		size += roundup2(size, 8);
693 	}
694 	size += bd->vfbd_uncompressed_size;
695 
696 	fi.fi_checksum = -checksum;
697 
698 	fp = file_findfile(NULL, "elf kernel");
699 	if (fp == NULL)
700 		fp = file_findfile(NULL, "elf64 kernel");
701 	if (fp == NULL)
702 		panic("can't find kernel file");
703 
704 	fontp = addr;
705 	addr += archsw.arch_copyin(&fi, addr, sizeof (struct font_info));
706 	addr = roundup2(addr, 8);
707 
708 	/* Copy maps. */
709 	for (i = 0; i < VFNT_MAPS; i++) {
710 		if (fd->vf_map_count[i] != 0) {
711 			addr += archsw.arch_copyin(fd->vf_map[i], addr,
712 			    fd->vf_map_count[i] * sizeof (struct vfnt_map));
713 			addr = roundup2(addr, 8);
714 		}
715 	}
716 
717 	/* Copy the bitmap. */
718 	addr += archsw.arch_copyin(fd->vf_bytes, addr, fi.fi_bitmap_size);
719 
720 	/* Looks OK so far; populate control structure */
721 	file_addmetadata(fp, MODINFOMD_FONT, sizeof(fontp), &fontp);
722 	return (addr);
723 }
724 
725 #ifdef LOADER_VERIEXEC_VECTX
726 #define VECTX_HANDLE(fd) vctx
727 #else
728 #define VECTX_HANDLE(fd) fd
729 #endif
730 
731 
732 /*
733  * We've been asked to load (fname) as (type), so just suck it in,
734  * no arguments or anything.
735  */
736 struct preloaded_file *
737 file_loadraw(const char *fname, char *type, int insert)
738 {
739 	struct preloaded_file	*fp;
740 	char			*name;
741 	int				fd, got;
742 	vm_offset_t			laddr;
743 #ifdef LOADER_VERIEXEC_VECTX
744 	struct vectx		*vctx;
745 	int			verror;
746 #endif
747 
748 	TSENTER2(fname);
749 	/* We can't load first */
750 	if ((file_findfile(NULL, NULL)) == NULL) {
751 		command_errmsg = "can't load file before kernel";
752 		TSEXIT();
753 		return(NULL);
754 	}
755 
756 	/* locate the file on the load path */
757 	name = file_search(fname, NULL);
758 	if (name == NULL) {
759 		snprintf(command_errbuf, sizeof(command_errbuf),
760 		  "can't find '%s'", fname);
761 		TSEXIT();
762 		return(NULL);
763 	}
764 
765 	if ((fd = open(name, O_RDONLY)) < 0) {
766 		snprintf(command_errbuf, sizeof(command_errbuf),
767 		  "can't open '%s': %s", name, strerror(errno));
768 		free(name);
769 		TSEXIT();
770 		return(NULL);
771 	}
772 
773 #ifdef LOADER_VERIEXEC_VECTX
774 	vctx = vectx_open(fd, name, 0L, NULL, &verror, __func__);
775 	if (verror) {
776 		sprintf(command_errbuf, "can't verify '%s': %s",
777 		    name, ve_error_get());
778 		free(name);
779 		free(vctx);
780 		close(fd);
781 		TSEXIT();
782 		return(NULL);
783 	}
784 #else
785 #ifdef LOADER_VERIEXEC
786 	if (verify_file(fd, name, 0, VE_MUST, __func__) < 0) {
787 		sprintf(command_errbuf, "can't verify '%s': %s",
788 		    name, ve_error_get());
789 		free(name);
790 		close(fd);
791 		TSEXIT();
792 		return(NULL);
793 	}
794 #endif
795 #endif
796 
797 	if (archsw.arch_loadaddr != NULL)
798 		loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr);
799 
800 	printf("%s ", name);
801 
802 	laddr = loadaddr;
803 	for (;;) {
804 		/* read in 4k chunks; size is not really important */
805 		got = archsw.arch_readin(VECTX_HANDLE(fd), laddr, 4096);
806 		if (got == 0)				/* end of file */
807 			break;
808 		if (got < 0) {				/* error */
809 			snprintf(command_errbuf, sizeof(command_errbuf),
810 			  "error reading '%s': %s", name, strerror(errno));
811 			free(name);
812 			close(fd);
813 #ifdef LOADER_VERIEXEC_VECTX
814 			free(vctx);
815 #endif
816 			TSEXIT();
817 			return(NULL);
818 		}
819 		laddr += got;
820 	}
821 
822 	printf("size=%#jx\n", (uintmax_t)(laddr - loadaddr));
823 #ifdef LOADER_VERIEXEC_VECTX
824 	verror = vectx_close(vctx, VE_MUST, __func__);
825 	if (verror) {
826 		free(name);
827 		close(fd);
828 		free(vctx);
829 		TSEXIT();
830 		return(NULL);
831 	}
832 #endif
833 
834 	/* Looks OK so far; create & populate control structure */
835 	fp = file_alloc();
836 	if (fp == NULL) {
837 		snprintf(command_errbuf, sizeof (command_errbuf),
838 		    "no memory to load %s", name);
839 		free(name);
840 		close(fd);
841 		TSEXIT();
842 		return (NULL);
843 	}
844 	fp->f_name = name;
845 	fp->f_type = strdup(type);
846 	fp->f_args = NULL;
847 	fp->f_metadata = NULL;
848 	fp->f_loader = -1;
849 	fp->f_addr = loadaddr;
850 	fp->f_size = laddr - loadaddr;
851 
852 	if (fp->f_type == NULL) {
853 		snprintf(command_errbuf, sizeof (command_errbuf),
854 		    "no memory to load %s", name);
855 		free(name);
856 		close(fd);
857 		TSEXIT();
858 		return (NULL);
859 	}
860 	/* recognise space consumption */
861 	loadaddr = laddr;
862 
863 	/* Add to the list of loaded files */
864 	if (insert != 0)
865 		file_insert_tail(fp);
866 	close(fd);
867 	TSEXIT();
868 	return(fp);
869 }
870 
871 /*
872  * Load the module (name), pass it (argc),(argv), add container file
873  * to the list of loaded files.
874  * If module is already loaded just assign new argc/argv.
875  */
876 int
877 mod_load(char *modname, struct mod_depend *verinfo, int argc, char *argv[])
878 {
879 	struct kernel_module	*mp;
880 	int				err;
881 	char			*filename;
882 
883 	TSENTER2(modname);
884 	if (file_havepath(modname)) {
885 		printf("Warning: mod_load() called instead of mod_loadkld() for module '%s'\n", modname);
886 		TSEXIT();
887 		return (mod_loadkld(modname, argc, argv));
888 	}
889 	/* see if module is already loaded */
890 	mp = file_findmodule(NULL, modname, verinfo);
891 	if (mp) {
892 #ifdef moduleargs
893 		free(mp->m_args);
894 		mp->m_args = unargv(argc, argv);
895 #endif
896 		snprintf(command_errbuf, sizeof(command_errbuf),
897 		  "warning: module '%s' already loaded", mp->m_name);
898 		TSEXIT();
899 		return (0);
900 	}
901 	/* locate file with the module on the search path */
902 	filename = mod_searchmodule(modname, verinfo);
903 	if (filename == NULL) {
904 		snprintf(command_errbuf, sizeof(command_errbuf),
905 		  "can't find '%s'", modname);
906 		TSEXIT();
907 		return (ENOENT);
908 	}
909 	err = mod_loadkld(filename, argc, argv);
910 	free(filename);
911 	TSEXIT();
912 	return (err);
913 }
914 
915 /*
916  * Load specified KLD. If path is omitted, then try to locate it via
917  * search path.
918  */
919 int
920 mod_loadkld(const char *kldname, int argc, char *argv[])
921 {
922 	struct preloaded_file	*fp;
923 	int			err;
924 	char			*filename;
925 	vm_offset_t		loadaddr_saved;
926 
927 	TSENTER2(kldname);
928 	/*
929 	 * Get fully qualified KLD name
930 	 */
931 	filename = file_search(kldname, kld_ext_list);
932 	if (filename == NULL) {
933 		snprintf(command_errbuf, sizeof(command_errbuf),
934 		  "can't find '%s'", kldname);
935 		TSEXIT();
936 		return (ENOENT);
937 	}
938 	/*
939 	 * Check if KLD already loaded
940 	 */
941 	fp = file_findfile(filename, NULL);
942 	if (fp) {
943 		snprintf(command_errbuf, sizeof(command_errbuf),
944 		  "warning: KLD '%s' already loaded", filename);
945 		free(filename);
946 		TSEXIT();
947 		return (0);
948 	}
949 
950 	do {
951 		err = file_load(filename, loadaddr, &fp);
952 		if (err)
953 			break;
954 		fp->f_args = unargv(argc, argv);
955 		loadaddr_saved = loadaddr;
956 		loadaddr = fp->f_addr + fp->f_size;
957 		file_insert_tail(fp);	/* Add to the list of loaded files */
958 		if (file_load_dependencies(fp) != 0) {
959 			err = ENOENT;
960 			file_remove(fp);
961 			loadaddr = loadaddr_saved;
962 			fp = NULL;
963 			break;
964 		}
965 	} while(0);
966 	if (err == EFTYPE) {
967 		snprintf(command_errbuf, sizeof(command_errbuf),
968 		  "don't know how to load module '%s'", filename);
969 	}
970 	if (err)
971 		file_discard(fp);
972 	free(filename);
973 	TSEXIT();
974 	return (err);
975 }
976 
977 /*
978  * Find a file matching (name) and (type).
979  * NULL may be passed as a wildcard to either.
980  */
981 struct preloaded_file *
982 file_findfile(const char *name, const char *type)
983 {
984 	struct preloaded_file *fp;
985 
986 	for (fp = preloaded_files; fp != NULL; fp = fp->f_next) {
987 		if (((name == NULL) || !strcmp(name, fp->f_name)) &&
988 		  ((type == NULL) || !strcmp(type, fp->f_type)))
989 			break;
990 	}
991 	return (fp);
992 }
993 
994 /*
995  * Find a module matching (name) inside of given file.
996  * NULL may be passed as a wildcard.
997  */
998 struct kernel_module *
999 file_findmodule(struct preloaded_file *fp, char *modname,
1000 	struct mod_depend *verinfo)
1001 {
1002 	struct kernel_module *mp, *best;
1003 	int bestver, mver;
1004 
1005 	if (fp == NULL) {
1006 		for (fp = preloaded_files; fp; fp = fp->f_next) {
1007 			mp = file_findmodule(fp, modname, verinfo);
1008 			if (mp)
1009 				return (mp);
1010 		}
1011 		return (NULL);
1012 	}
1013 	best = NULL;
1014 	bestver = 0;
1015 	for (mp = fp->f_modules; mp; mp = mp->m_next) {
1016 		if (strcmp(modname, mp->m_name) == 0) {
1017 			if (verinfo == NULL)
1018 				return (mp);
1019 			mver = mp->m_version;
1020 			if (mver == verinfo->md_ver_preferred)
1021 				return (mp);
1022 			if (mver >= verinfo->md_ver_minimum &&
1023 			  mver <= verinfo->md_ver_maximum &&
1024 			  mver > bestver) {
1025 				best = mp;
1026 				bestver = mver;
1027 			}
1028 		}
1029 	}
1030 	return (best);
1031 }
1032 /*
1033  * Make a copy of (size) bytes of data from (p), and associate them as
1034  * metadata of (type) to the module (mp).
1035  */
1036 void
1037 file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p)
1038 {
1039 	struct file_metadata	*md;
1040 
1041 	md = malloc(sizeof(struct file_metadata) - sizeof(md->md_data) + size);
1042 	if (md != NULL) {
1043 		md->md_size = size;
1044 		md->md_type = type;
1045 		bcopy(p, md->md_data, size);
1046 		md->md_next = fp->f_metadata;
1047 	}
1048 	fp->f_metadata = md;
1049 }
1050 
1051 /*
1052  * Find a metadata object of (type) associated with the file (fp)
1053  */
1054 struct file_metadata *
1055 file_findmetadata(struct preloaded_file *fp, int type)
1056 {
1057 	struct file_metadata *md;
1058 
1059 	for (md = fp->f_metadata; md != NULL; md = md->md_next)
1060 		if (md->md_type == type)
1061 			break;
1062 	return(md);
1063 }
1064 
1065 /*
1066  * Remove all metadata from the file.
1067  */
1068 void
1069 file_removemetadata(struct preloaded_file *fp)
1070 {
1071 	struct file_metadata *md, *next;
1072 
1073 	for (md = fp->f_metadata; md != NULL; md = next)
1074 	{
1075 		next = md->md_next;
1076 		free(md);
1077 	}
1078 	fp->f_metadata = NULL;
1079 }
1080 
1081 /*
1082  * Add a buffer to the list of preloaded "files".
1083  */
1084 int
1085 file_addbuf(const char *name, const char *type, size_t len, void *buf)
1086 {
1087 	struct preloaded_file	*fp;
1088 	vm_offset_t dest;
1089 
1090 	/* We can't load first */
1091 	if ((file_findfile(NULL, NULL)) == NULL) {
1092 		command_errmsg = "can't load file before kernel";
1093 		return (-1);
1094 	}
1095 
1096 	/* Figure out where to load the data. */
1097 	dest = loadaddr;
1098 	if (archsw.arch_loadaddr != NULL)
1099 		dest = archsw.arch_loadaddr(LOAD_RAW, (void *)name, dest);
1100 
1101 	/* Create & populate control structure */
1102 	fp = file_alloc();
1103 	if (fp == NULL) {
1104 		snprintf(command_errbuf, sizeof (command_errbuf),
1105 		    "no memory to load %s", name);
1106 		return (-1);
1107 	}
1108 	fp->f_name = strdup(name);
1109 	fp->f_type = strdup(type);
1110 	fp->f_args = NULL;
1111 	fp->f_metadata = NULL;
1112 	fp->f_loader = -1;
1113 	fp->f_addr = dest;
1114 	fp->f_size = len;
1115 	if ((fp->f_name == NULL) || (fp->f_type == NULL)) {
1116 		snprintf(command_errbuf, sizeof (command_errbuf),
1117 		    "no memory to load %s", name);
1118 		free(fp->f_name);
1119 		free(fp->f_type);
1120 		return (-1);
1121 	}
1122 
1123 	/* Copy the data in. */
1124 	archsw.arch_copyin(buf, fp->f_addr, len);
1125 	loadaddr = fp->f_addr + len;
1126 
1127 	/* Add to the list of loaded files */
1128 	file_insert_tail(fp);
1129 	return(0);
1130 }
1131 
1132 struct file_metadata *
1133 metadata_next(struct file_metadata *md, int type)
1134 {
1135 
1136 	if (md == NULL)
1137 		return (NULL);
1138 	while((md = md->md_next) != NULL)
1139 		if (md->md_type == type)
1140 			break;
1141 	return (md);
1142 }
1143 
1144 static char *emptyextlist[] = { "", NULL };
1145 
1146 /*
1147  * Check if the given file is in place and return full path to it.
1148  */
1149 static char *
1150 file_lookup(const char *path, const char *name, int namelen, char **extlist)
1151 {
1152 	struct stat	st;
1153 	char	*result, *cp, **cpp;
1154 	int		pathlen, extlen, len;
1155 
1156 	pathlen = strlen(path);
1157 	extlen = 0;
1158 	if (extlist == NULL)
1159 		extlist = emptyextlist;
1160 	for (cpp = extlist; *cpp; cpp++) {
1161 		len = strlen(*cpp);
1162 		if (len > extlen)
1163 			extlen = len;
1164 	}
1165 	result = malloc(pathlen + namelen + extlen + 2);
1166 	if (result == NULL)
1167 		return (NULL);
1168 	bcopy(path, result, pathlen);
1169 	if (pathlen > 0 && result[pathlen - 1] != '/')
1170 		result[pathlen++] = '/';
1171 	cp = result + pathlen;
1172 	bcopy(name, cp, namelen);
1173 	cp += namelen;
1174 	for (cpp = extlist; *cpp; cpp++) {
1175 		strcpy(cp, *cpp);
1176 		if (stat(result, &st) == 0 && S_ISREG(st.st_mode))
1177 			return result;
1178 	}
1179 	free(result);
1180 	return NULL;
1181 }
1182 
1183 /*
1184  * Check if file name have any qualifiers
1185  */
1186 static int
1187 file_havepath(const char *name)
1188 {
1189 	const char		*cp;
1190 
1191 	archsw.arch_getdev(NULL, name, &cp);
1192 	return (cp != name || strchr(name, '/') != NULL);
1193 }
1194 
1195 /*
1196  * Attempt to find the file (name) on the module searchpath.
1197  * If (name) is qualified in any way, we simply check it and
1198  * return it or NULL.  If it is not qualified, then we attempt
1199  * to construct a path using entries in the environment variable
1200  * module_path.
1201  *
1202  * The path we return a pointer to need never be freed, as we manage
1203  * it internally.
1204  */
1205 static char *
1206 file_search(const char *name, char **extlist)
1207 {
1208 	struct moduledir	*mdp;
1209 	struct stat		sb;
1210 	char		*result;
1211 	int			namelen;
1212 
1213 	/* Don't look for nothing */
1214 	if (name == NULL)
1215 		return(NULL);
1216 
1217 	if (*name == 0)
1218 		return(strdup(name));
1219 
1220 	if (file_havepath(name)) {
1221 		/* Qualified, so just see if it exists */
1222 		if (stat(name, &sb) == 0)
1223 			return(strdup(name));
1224 		return(NULL);
1225 	}
1226 	moduledir_rebuild();
1227 	result = NULL;
1228 	namelen = strlen(name);
1229 	STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1230 		result = file_lookup(mdp->d_path, name, namelen, extlist);
1231 		if (result)
1232 			break;
1233 	}
1234 	return(result);
1235 }
1236 
1237 #define	INT_ALIGN(base, ptr)	ptr = \
1238 	(base) + roundup2((ptr) - (base), sizeof(int))
1239 
1240 static char *
1241 mod_search_hints(struct moduledir *mdp, const char *modname,
1242 	struct mod_depend *verinfo)
1243 {
1244 	u_char	*cp, *recptr, *bufend, *best;
1245 	char	*result;
1246 	int		*intp, bestver, blen, clen, found, ival, modnamelen, reclen;
1247 
1248 	moduledir_readhints(mdp);
1249 	modnamelen = strlen(modname);
1250 	found = 0;
1251 	result = NULL;
1252 	bestver = 0;
1253 	if (mdp->d_hints == NULL)
1254 		goto bad;
1255 	recptr = mdp->d_hints;
1256 	bufend = recptr + mdp->d_hintsz;
1257 	clen = blen = 0;
1258 	best = cp = NULL;
1259 	while (recptr < bufend && !found) {
1260 		intp = (int*)recptr;
1261 		reclen = *intp++;
1262 		ival = *intp++;
1263 		cp = (u_char*)intp;
1264 		switch (ival) {
1265 		case MDT_VERSION:
1266 			clen = *cp++;
1267 			if (clen != modnamelen || bcmp(cp, modname, clen) != 0)
1268 				break;
1269 			cp += clen;
1270 			INT_ALIGN(mdp->d_hints, cp);
1271 			ival = *(int*)cp;
1272 			cp += sizeof(int);
1273 			clen = *cp++;
1274 			if (verinfo == NULL || ival == verinfo->md_ver_preferred) {
1275 				found = 1;
1276 				break;
1277 			}
1278 			if (ival >= verinfo->md_ver_minimum &&
1279 			  ival <= verinfo->md_ver_maximum &&
1280 			  ival > bestver) {
1281 				bestver = ival;
1282 				best = cp;
1283 				blen = clen;
1284 			}
1285 			break;
1286 		default:
1287 			break;
1288 		}
1289 		recptr += reclen + sizeof(int);
1290 	}
1291 	/*
1292 	 * Finally check if KLD is in the place
1293 	 */
1294 	if (found)
1295 		result = file_lookup(mdp->d_path, (const char *)cp, clen, NULL);
1296 	else if (best)
1297 		result = file_lookup(mdp->d_path, (const char *)best, blen, NULL);
1298 bad:
1299 	/*
1300 	 * If nothing found or hints is absent - fallback to the old way
1301 	 * by using "kldname[.ko]" as module name.
1302 	 */
1303 	if (!found && !bestver && result == NULL)
1304 		result = file_lookup(mdp->d_path, modname, modnamelen, kld_ext_list);
1305 	return result;
1306 }
1307 
1308 static int
1309 getint(void **ptr)
1310 {
1311 	int *p = *ptr;
1312 	int rv;
1313 
1314 	p = (int *)roundup2((intptr_t)p, sizeof(int));
1315 	rv = *p++;
1316 	*ptr = p;
1317 	return rv;
1318 }
1319 
1320 static void
1321 getstr(void **ptr, char *val)
1322 {
1323 	int *p = *ptr;
1324 	char *c = (char *)p;
1325 	int len = *(uint8_t *)c;
1326 
1327 	memcpy(val, c + 1, len);
1328 	val[len] = 0;
1329 	c += len + 1;
1330 	*ptr = (void *)c;
1331 }
1332 
1333 static int
1334 pnpval_as_int(const char *val, const char *pnpinfo)
1335 {
1336 	int rv;
1337 	char key[256];
1338 	char *cp;
1339 
1340 	if (pnpinfo == NULL)
1341 		return -1;
1342 
1343 	cp = strchr(val, ';');
1344 	key[0] = ' ';
1345 	if (cp == NULL)
1346 		strlcpy(key + 1, val, sizeof(key) - 1);
1347 	else {
1348 		memcpy(key + 1, val, cp - val);
1349 		key[cp - val + 1] = '\0';
1350 	}
1351 	strlcat(key, "=", sizeof(key));
1352 	if (strncmp(key + 1, pnpinfo, strlen(key + 1)) == 0)
1353 		rv = strtol(pnpinfo + strlen(key + 1), NULL, 0);
1354 	else {
1355 		cp = strstr(pnpinfo, key);
1356 		if (cp == NULL)
1357 			rv = -1;
1358 		else
1359 			rv = strtol(cp + strlen(key), NULL, 0);
1360 	}
1361 	return rv;
1362 }
1363 
1364 static void
1365 quoted_strcpy(char *dst, const char *src)
1366 {
1367 	char q = ' ';
1368 
1369 	if (*src == '\'' || *src == '"')
1370 		q = *src++;
1371 	while (*src && *src != q)
1372 		*dst++ = *src++; // XXX backtick quoting
1373 	*dst++ = '\0';
1374 	// XXX overflow
1375 }
1376 
1377 static char *
1378 pnpval_as_str(const char *val, const char *pnpinfo)
1379 {
1380 	static char retval[256];
1381 	char key[256];
1382 	char *cp;
1383 
1384 	if (pnpinfo == NULL) {
1385 		*retval = '\0';
1386 		return retval;
1387 	}
1388 
1389 	cp = strchr(val, ';');
1390 	key[0] = ' ';
1391 	if (cp == NULL)
1392 		strlcpy(key + 1, val, sizeof(key) - 1);
1393 	else {
1394 		memcpy(key + 1, val, cp - val);
1395 		key[cp - val + 1] = '\0';
1396 	}
1397 	strlcat(key, "=", sizeof(key));
1398 	if (strncmp(key + 1, pnpinfo, strlen(key + 1)) == 0)
1399 		quoted_strcpy(retval, pnpinfo + strlen(key + 1));
1400 	else {
1401 		cp = strstr(pnpinfo, key);
1402 		if (cp == NULL)
1403 			strcpy(retval, "MISSING");
1404 		else
1405 			quoted_strcpy(retval, cp + strlen(key));
1406 	}
1407 	return retval;
1408 }
1409 
1410 static char *
1411 devmatch_search_hints(struct moduledir *mdp, const char *bus, const char *dev, const char *pnpinfo)
1412 {
1413 	char val1[256], val2[256];
1414 	int ival, len, ents, i, notme, mask, bit, v, found;
1415 	void *ptr, *walker, *hints_end;
1416 	char *lastmod = NULL, *cp, *s;
1417 
1418 	moduledir_readhints(mdp);
1419 	found = 0;
1420 	if (mdp->d_hints == NULL)
1421 		goto bad;
1422 	walker = mdp->d_hints;
1423 	hints_end = walker + mdp->d_hintsz;
1424 	while (walker < hints_end && !found) {
1425 		len = getint(&walker);
1426 		ival = getint(&walker);
1427 		ptr = walker;
1428 		switch (ival) {
1429 		case MDT_VERSION:
1430 			getstr(&ptr, val1);
1431 			ival = getint(&ptr);
1432 			getstr(&ptr, val2);
1433 			if (pnp_dump_flag || pnp_verbose_flag)
1434 				printf("Version: if %s.%d kmod %s\n", val1, ival, val2);
1435 			break;
1436 		case MDT_MODULE:
1437 			getstr(&ptr, val1);
1438 			getstr(&ptr, val2);
1439 			if (lastmod)
1440 				free(lastmod);
1441 			lastmod = strdup(val2);
1442 			if (pnp_dump_flag || pnp_verbose_flag)
1443 				printf("module %s in %s\n", val1, val1);
1444 			break;
1445 		case MDT_PNP_INFO:
1446 			if (!pnp_dump_flag && !pnp_unbound_flag && lastmod && strcmp(lastmod, "kernel") == 0)
1447 				break;
1448 			getstr(&ptr, val1);
1449 			getstr(&ptr, val2);
1450 			ents = getint(&ptr);
1451 			if (pnp_dump_flag || pnp_verbose_flag)
1452 				printf("PNP info for bus %s format %s %d entries (%s)\n",
1453 				    val1, val2, ents, lastmod);
1454 			if (strcmp(val1, "usb") == 0) {
1455 				if (pnp_verbose_flag)
1456 					printf("Treating usb as uhub -- bug in source table still?\n");
1457 				strcpy(val1, "uhub");
1458 			}
1459 			if (bus && strcmp(val1, bus) != 0) {
1460 				if (pnp_verbose_flag)
1461 					printf("Skipped because table for bus %s, looking for %s\n",
1462 					    val1, bus);
1463 				break;
1464 			}
1465 			for (i = 0; i < ents; i++) {
1466 				if (pnp_verbose_flag)
1467 					printf("---------- Entry %d ----------\n", i);
1468 				if (pnp_dump_flag)
1469 					printf("   ");
1470 				cp = val2;
1471 				notme = 0;
1472 				mask = -1;
1473 				bit = -1;
1474 				do {
1475 					switch (*cp) {
1476 						/* All integer fields */
1477 					case 'I':
1478 					case 'J':
1479 					case 'G':
1480 					case 'L':
1481 					case 'M':
1482 						ival = getint(&ptr);
1483 						if (pnp_dump_flag) {
1484 							printf("%#x:", ival);
1485 							break;
1486 						}
1487 						if (bit >= 0 && ((1 << bit) & mask) == 0)
1488 							break;
1489 						v = pnpval_as_int(cp + 2, pnpinfo);
1490 						if (pnp_verbose_flag)
1491 							printf("Matching %s (%c) table=%#x tomatch=%#x\n",
1492 							    cp + 2, *cp, v, ival);
1493 						switch (*cp) {
1494 						case 'J':
1495 							if (ival == -1)
1496 								break;
1497 							/*FALLTHROUGH*/
1498 						case 'I':
1499 							if (v != ival)
1500 								notme++;
1501 							break;
1502 						case 'G':
1503 							if (v < ival)
1504 								notme++;
1505 							break;
1506 						case 'L':
1507 							if (v > ival)
1508 								notme++;
1509 							break;
1510 						case 'M':
1511 							mask = ival;
1512 							break;
1513 						}
1514 						break;
1515 						/* String fields */
1516 					case 'D':
1517 					case 'Z':
1518 						getstr(&ptr, val1);
1519 						if (pnp_dump_flag) {
1520 							printf("'%s':", val1);
1521 							break;
1522 						}
1523 						if (*cp == 'D')
1524 							break;
1525 						s = pnpval_as_str(cp + 2, pnpinfo);
1526 						if (strcmp(s, val1) != 0)
1527 							notme++;
1528 						break;
1529 						/* Key override fields, required to be last in the string */
1530 					case 'T':
1531 						/*
1532 						 * This is imperfect and only does one key and will be redone
1533 						 * to be more general for multiple keys. Currently, nothing
1534 						 * does that.
1535 						 */
1536 						if (pnp_dump_flag)				/* No per-row data stored */
1537 							break;
1538 						if (cp[strlen(cp) - 1] == ';')		/* Skip required ; at end */
1539 							cp[strlen(cp) - 1] = '\0';	/* in case it's not there */
1540 						if ((s = strstr(pnpinfo, cp + 2)) == NULL)
1541 							notme++;
1542 						else if (s > pnpinfo && s[-1] != ' ')
1543 							notme++;
1544 						break;
1545 					default:
1546 						printf("Unknown field type %c\n:", *cp);
1547 						break;
1548 					}
1549 					bit++;
1550 					cp = strchr(cp, ';');
1551 					if (cp)
1552 						cp++;
1553 				} while (cp && *cp);
1554 				if (pnp_dump_flag)
1555 					printf("\n");
1556 				else if (!notme) {
1557 					if (!pnp_unbound_flag) {
1558 						if (pnp_verbose_flag)
1559 							printf("Matches --- %s ---\n", lastmod);
1560 					}
1561 					found++;
1562 				}
1563 			}
1564 			break;
1565 		default:
1566 			break;
1567 		}
1568 		walker = (void *)(len - sizeof(int) + (intptr_t)walker);
1569 	}
1570 	if (pnp_unbound_flag && found == 0 && *pnpinfo) {
1571 		if (pnp_verbose_flag)
1572 			printf("------------------------- ");
1573 		printf("%s on %s pnpinfo %s", *dev ? dev : "unattached", bus, pnpinfo);
1574 		if (pnp_verbose_flag)
1575 			printf(" -------------------------");
1576 		printf("\n");
1577 	}
1578 	if (found != 0)
1579 		return (lastmod);
1580 	free(lastmod);
1581 
1582 bad:
1583 	return (NULL);
1584 }
1585 
1586 /*
1587  * Attempt to locate the file containing the module (name)
1588  */
1589 static char *
1590 mod_searchmodule(char *name, struct mod_depend *verinfo)
1591 {
1592 	struct	moduledir *mdp;
1593 	char	*result;
1594 
1595 	moduledir_rebuild();
1596 	/*
1597 	 * Now we ready to lookup module in the given directories
1598 	 */
1599 	result = NULL;
1600 	STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1601 		result = mod_search_hints(mdp, name, verinfo);
1602 		if (result)
1603 			break;
1604 	}
1605 
1606 	return(result);
1607 }
1608 
1609 static char *
1610 mod_searchmodule_pnpinfo(const char *bus, const char *pnpinfo)
1611 {
1612 	struct	moduledir *mdp;
1613 	char	*result;
1614 
1615 	moduledir_rebuild();
1616 	/*
1617 	 * Now we ready to lookup module in the given directories
1618 	 */
1619 	result = NULL;
1620 	STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1621 		result = devmatch_search_hints(mdp, bus, NULL, pnpinfo);
1622 		if (result)
1623 			break;
1624 	}
1625 
1626 	return(result);
1627 }
1628 
1629 int
1630 file_addmodule(struct preloaded_file *fp, char *modname, int version,
1631 	struct kernel_module **newmp)
1632 {
1633 	struct kernel_module *mp;
1634 	struct mod_depend mdepend;
1635 
1636 	bzero(&mdepend, sizeof(mdepend));
1637 	mdepend.md_ver_preferred = version;
1638 	mp = file_findmodule(fp, modname, &mdepend);
1639 	if (mp)
1640 		return (EEXIST);
1641 	mp = calloc(1, sizeof(struct kernel_module));
1642 	if (mp == NULL)
1643 		return (ENOMEM);
1644 	mp->m_name = strdup(modname);
1645 	if (mp->m_name == NULL) {
1646 		free(mp);
1647 		return (ENOMEM);
1648 	}
1649 	mp->m_version = version;
1650 	mp->m_fp = fp;
1651 	mp->m_next = fp->f_modules;
1652 	fp->f_modules = mp;
1653 	if (newmp)
1654 		*newmp = mp;
1655 	return (0);
1656 }
1657 
1658 /*
1659  * Throw a file away
1660  */
1661 void
1662 file_discard(struct preloaded_file *fp)
1663 {
1664 	struct file_metadata	*md, *md1;
1665 	struct kernel_module	*mp, *mp1;
1666 	if (fp == NULL)
1667 		return;
1668 	md = fp->f_metadata;
1669 	while (md) {
1670 		md1 = md;
1671 		md = md->md_next;
1672 		free(md1);
1673 	}
1674 	mp = fp->f_modules;
1675 	while (mp) {
1676 		free(mp->m_name);
1677 		mp1 = mp;
1678 		mp = mp->m_next;
1679 		free(mp1);
1680 	}
1681 	free(fp->f_name);
1682 	free(fp->f_type);
1683 	free(fp->f_args);
1684 	free(fp);
1685 }
1686 
1687 /*
1688  * Allocate a new file; must be used instead of malloc()
1689  * to ensure safe initialisation.
1690  */
1691 struct preloaded_file *
1692 file_alloc(void)
1693 {
1694 
1695 	return (calloc(1, sizeof(struct preloaded_file)));
1696 }
1697 
1698 /*
1699  * Add a module to the chain
1700  */
1701 static void
1702 file_insert_tail(struct preloaded_file *fp)
1703 {
1704 	struct preloaded_file	*cm;
1705 
1706 	/* Append to list of loaded file */
1707 	fp->f_next = NULL;
1708 	if (preloaded_files == NULL) {
1709 		preloaded_files = fp;
1710 	} else {
1711 		for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next)
1712 			;
1713 		cm->f_next = fp;
1714 	}
1715 }
1716 
1717 /*
1718  * Remove module from the chain
1719  */
1720 static void
1721 file_remove(struct preloaded_file *fp)
1722 {
1723 	struct preloaded_file   *cm;
1724 
1725 	if (preloaded_files == NULL)
1726 		return;
1727 
1728 	if (preloaded_files == fp) {
1729 		preloaded_files = fp->f_next;
1730 		return;
1731         }
1732         for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next) {
1733 		if (cm->f_next == fp) {
1734 			cm->f_next = fp->f_next;
1735 			return;
1736 		}
1737 	}
1738 }
1739 
1740 static char *
1741 moduledir_fullpath(struct moduledir *mdp, const char *fname)
1742 {
1743 	char *cp;
1744 
1745 	cp = malloc(strlen(mdp->d_path) + strlen(fname) + 2);
1746 	if (cp == NULL)
1747 		return NULL;
1748 	strcpy(cp, mdp->d_path);
1749 	strcat(cp, "/");
1750 	strcat(cp, fname);
1751 	return (cp);
1752 }
1753 
1754 /*
1755  * Read linker.hints file into memory performing some sanity checks.
1756  */
1757 static void
1758 moduledir_readhints(struct moduledir *mdp)
1759 {
1760 	struct stat	st;
1761 	char	*path;
1762 	int		fd, size, version;
1763 
1764 	if (mdp->d_hints != NULL || (mdp->d_flags & MDIR_NOHINTS))
1765 		return;
1766 	path = moduledir_fullpath(mdp, "linker.hints");
1767 	if (stat(path, &st) != 0 ||
1768 	  st.st_size < (ssize_t)(sizeof(version) + sizeof(int)) ||
1769 	  st.st_size > LINKER_HINTS_MAX || (fd = open(path, O_RDONLY)) < 0) {
1770 		free(path);
1771 		mdp->d_flags |= MDIR_NOHINTS;
1772 		return;
1773 	}
1774 	free(path);
1775 	size = read(fd, &version, sizeof(version));
1776 	if (size != sizeof(version) || version != LINKER_HINTS_VERSION)
1777 		goto bad;
1778 	size = st.st_size - size;
1779 	mdp->d_hints = malloc(size);
1780 	if (mdp->d_hints == NULL)
1781 		goto bad;
1782 	if (read(fd, mdp->d_hints, size) != size)
1783 		goto bad;
1784 	mdp->d_hintsz = size;
1785 	close(fd);
1786 	return;
1787 bad:
1788 	close(fd);
1789 	free(mdp->d_hints);
1790 	mdp->d_hints = NULL;
1791 	mdp->d_flags |= MDIR_NOHINTS;
1792 	return;
1793 }
1794 
1795 /*
1796  * Extract directories from the ';' separated list, remove duplicates.
1797  */
1798 static void
1799 moduledir_rebuild(void)
1800 {
1801 	struct	moduledir *mdp, *mtmp;
1802 	const char	*path, *cp, *ep;
1803 	size_t	cplen;
1804 
1805 	path = getenv("module_path");
1806 	if (path == NULL)
1807 		path = default_searchpath;
1808 	/*
1809 	 * Rebuild list of module directories if it changed
1810 	 */
1811 	STAILQ_FOREACH(mdp, &moduledir_list, d_link)
1812 		mdp->d_flags |= MDIR_REMOVED;
1813 
1814 	for (ep = path; *ep != 0;  ep++) {
1815 		cp = ep;
1816 		for (; *ep != 0 && *ep != ';'; ep++)
1817 			;
1818 		/*
1819 		 * Ignore trailing slashes
1820 		 */
1821 		for (cplen = ep - cp; cplen > 1 && cp[cplen - 1] == '/'; cplen--)
1822 			;
1823 		STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1824 			if (strlen(mdp->d_path) != cplen ||	bcmp(cp, mdp->d_path, cplen) != 0)
1825 				continue;
1826 			mdp->d_flags &= ~MDIR_REMOVED;
1827 			break;
1828 		}
1829 		if (mdp == NULL) {
1830 			mdp = malloc(sizeof(*mdp) + cplen + 1);
1831 			if (mdp == NULL)
1832 				return;
1833 			mdp->d_path = (char*)(mdp + 1);
1834 			bcopy(cp, mdp->d_path, cplen);
1835 			mdp->d_path[cplen] = 0;
1836 			mdp->d_hints = NULL;
1837 			mdp->d_flags = 0;
1838 			STAILQ_INSERT_TAIL(&moduledir_list, mdp, d_link);
1839 		}
1840 		if (*ep == 0)
1841 			break;
1842 	}
1843 	/*
1844 	 * Delete unused directories if any
1845 	 */
1846 	mdp = STAILQ_FIRST(&moduledir_list);
1847 	while (mdp) {
1848 		if ((mdp->d_flags & MDIR_REMOVED) == 0) {
1849 			mdp = STAILQ_NEXT(mdp, d_link);
1850 		} else {
1851 			free(mdp->d_hints);
1852 			mtmp = mdp;
1853 			mdp = STAILQ_NEXT(mdp, d_link);
1854 			STAILQ_REMOVE(&moduledir_list, mtmp, moduledir, d_link);
1855 			free(mtmp);
1856 		}
1857 	}
1858 	return;
1859 }
1860