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