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