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