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