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