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