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