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