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/*
30 * file/module function dispatcher, support, etc.
31 */
32
33#include <stand.h>
34#include <string.h>
35#include <sys/param.h>
36#include <sys/linker.h>
37#include <sys/module.h>
38#include <sys/queue.h>
39#include <sys/stdint.h>
40#include <sys/tem_impl.h>
41#include <sys/font.h>
42#include <sys/sha1.h>
43#include <libcrypto.h>
44
45#include "bootstrap.h"
46
47#if defined(EFI)
48#define	PTOV(pa)	((void *)pa)
49#else
50#include "../i386/btx/lib/btxv86.h"
51#endif
52
53#define	MDIR_REMOVED	0x0001
54#define	MDIR_NOHINTS	0x0002
55
56struct moduledir {
57	char	*d_path;	/* path of modules directory */
58	uchar_t	*d_hints;	/* content of linker.hints file */
59	int	d_hintsz;	/* size of hints data */
60	int	d_flags;
61	STAILQ_ENTRY(moduledir) d_link;
62};
63
64static int file_load(char *, vm_offset_t, struct preloaded_file **);
65static int file_load_dependencies(struct preloaded_file *);
66static char *file_search(const char *, const char **);
67static struct kernel_module *file_findmodule(struct preloaded_file *, char *,
68    struct mod_depend *);
69static int file_havepath(const char *);
70static char *mod_searchmodule(char *, struct mod_depend *);
71static void file_insert_tail(struct preloaded_file *);
72static void file_remove(struct preloaded_file *);
73struct file_metadata *metadata_next(struct file_metadata *, int);
74static void moduledir_readhints(struct moduledir *);
75static void moduledir_rebuild(void);
76
77/* load address should be tweaked by first module loaded (kernel) */
78static vm_offset_t loadaddr = 0;
79
80#if defined(LOADER_FDT_SUPPORT)
81static const char *default_searchpath = "/boot/kernel;/boot/modules;/boot/dtb";
82#else
83static const char *default_searchpath = "/platform/i86pc";
84#endif
85
86static STAILQ_HEAD(, moduledir) moduledir_list =
87    STAILQ_HEAD_INITIALIZER(moduledir_list);
88
89struct preloaded_file *preloaded_files = NULL;
90
91static const char *kld_ext_list[] = {
92	".ko",
93	"",
94	".debug",
95	NULL
96};
97
98
99/*
100 * load an object, either a disk file or code module.
101 *
102 * To load a file, the syntax is:
103 *
104 * load -t <type> <path>
105 *
106 * code modules are loaded as:
107 *
108 * load <path> <options>
109 */
110
111COMMAND_SET(load, "load", "load a kernel or module", command_load);
112
113static int
114command_load(int argc, char *argv[])
115{
116	char *typestr;
117	int dofile, dokld, ch, error;
118
119	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	while ((ch = getopt(argc, argv, "kt:")) != -1) {
128		switch (ch) {
129		case 'k':
130			dokld = 1;
131			break;
132		case 't':
133			typestr = optarg;
134			dofile = 1;
135			break;
136		case '?':
137		default:
138			/* getopt has already reported an error */
139			return (CMD_OK);
140		}
141	}
142	argv += (optind - 1);
143	argc -= (optind - 1);
144
145	printf("Loading %s...\n", argv[1]);
146	/*
147	 * Request to load a raw file?
148	 */
149	if (dofile) {
150		struct preloaded_file *fp;
151
152		if ((typestr == NULL) || (*typestr == 0)) {
153			command_errmsg = "invalid load type";
154			return (CMD_CRIT);
155		}
156
157		if (file_findfile(argv[1], typestr) != NULL) {
158			snprintf(command_errbuf, sizeof (command_errbuf),
159			    "warning: file '%s' already loaded", argv[1]);
160			return (CMD_WARN);
161		}
162
163		fp = file_loadraw(argv[1], typestr, argc - 2, argv + 2, 1);
164		if (fp != NULL)
165			return (CMD_OK);
166
167		/* Failing to load mfs_root is never going to end well! */
168		if (strcmp("mfs_root", typestr) == 0)
169			return (CMD_FATAL);
170
171		return (CMD_ERROR);
172	}
173	/*
174	 * Do we have explicit KLD load ?
175	 */
176	if (dokld || file_havepath(argv[1])) {
177		error = mod_loadkld(argv[1], argc - 2, argv + 2);
178		if (error == EEXIST) {
179			snprintf(command_errbuf, sizeof (command_errbuf),
180			    "warning: KLD '%s' already loaded", argv[1]);
181			return (CMD_WARN);
182		}
183
184		return (error == 0 ? CMD_OK : CMD_CRIT);
185	}
186	/*
187	 * Looks like a request for a module.
188	 */
189	error = mod_load(argv[1], NULL, argc - 2, argv + 2);
190	if (error == EEXIST) {
191		snprintf(command_errbuf, sizeof (command_errbuf),
192		    "warning: module '%s' already loaded", argv[1]);
193		return (CMD_WARN);
194	}
195
196	return (error == 0 ? CMD_OK : CMD_CRIT);
197}
198
199void
200unload(void)
201{
202	struct preloaded_file *fp;
203
204	while (preloaded_files != NULL) {
205		fp = preloaded_files;
206		preloaded_files = preloaded_files->f_next;
207		file_discard(fp);
208	}
209	loadaddr = 0;
210	unsetenv("kernelname");
211}
212
213COMMAND_SET(unload, "unload", "unload all modules", command_unload);
214
215static int
216command_unload(int argc __unused, char *argv[] __unused)
217{
218	unload();
219	return (CMD_OK);
220}
221
222COMMAND_SET(lsmod, "lsmod", "list loaded modules", command_lsmod);
223
224static int
225command_lsmod(int argc, char *argv[])
226{
227	struct preloaded_file *fp;
228	struct kernel_module *mp;
229	struct file_metadata *md;
230	char lbuf[80];
231	int ch, verbose, hash, ret = 0;
232
233	verbose = 0;
234	hash = 0;
235	optind = 1;
236	optreset = 1;
237	while ((ch = getopt(argc, argv, "vs")) != -1) {
238		switch (ch) {
239		case 'v':
240			verbose = 1;
241			break;
242		case 's':
243			hash = 1;
244			break;
245		case '?':
246		default:
247			/* getopt has already reported an error */
248			return (CMD_OK);
249		}
250	}
251
252	pager_open();
253	for (fp = preloaded_files; fp; fp = fp->f_next) {
254		sprintf(lbuf, " %p: ", (void *) fp->f_addr);
255		pager_output(lbuf);
256		pager_output(fp->f_name);
257		sprintf(lbuf, " (%s, 0x%lx)\n", fp->f_type, (long)fp->f_size);
258		if (pager_output(lbuf))
259			break;
260		if (fp->f_args != NULL) {
261			pager_output("    args: ");
262			pager_output(fp->f_args);
263			if (pager_output("\n"))
264				break;
265			if (strcmp(fp->f_type, "hash") == 0) {
266				pager_output("    contents: ");
267				strlcpy(lbuf, PTOV(fp->f_addr), sizeof (lbuf));
268				if (pager_output(lbuf))
269					break;
270			}
271		}
272
273		if (hash == 1) {
274			void *ptr = PTOV(fp->f_addr);
275
276			pager_output("  hash: ");
277			sha1(ptr, fp->f_size, (uint8_t *)lbuf);
278			for (int i = 0; i < SHA1_DIGEST_LENGTH; i++)
279				printf("%02x", (int)(lbuf[i] & 0xff));
280			if (pager_output("\n"))
281				break;
282		}
283
284		if (fp->f_modules) {
285			pager_output("  modules: ");
286			for (mp = fp->f_modules; mp; mp = mp->m_next) {
287				sprintf(lbuf, "%s.%d ", mp->m_name,
288				    mp->m_version);
289				pager_output(lbuf);
290			}
291			if (pager_output("\n"))
292				break;
293		}
294		if (verbose) {
295			/*
296			 * XXX could add some formatting smarts here to
297			 * display some better
298			 */
299			for (md = fp->f_metadata; md != NULL;
300			    md = md->md_next) {
301				sprintf(lbuf, "      0x%04x, 0x%lx\n",
302				    md->md_type, (long)md->md_size);
303				if ((ret = pager_output(lbuf)))
304					break;
305			}
306		}
307		if (ret != 0)
308			break;
309	}
310	pager_close();
311	return (CMD_OK);
312}
313
314/*
315 * File level interface, functions file_*
316 */
317int
318file_load(char *filename, vm_offset_t dest, struct preloaded_file **result)
319{
320	static int last_file_format = 0;
321	struct preloaded_file *fp;
322	int error;
323	int i;
324
325	if (preloaded_files == NULL)
326		last_file_format = 0;
327
328	if (archsw.arch_loadaddr != NULL)
329		dest = archsw.arch_loadaddr(LOAD_RAW, filename, dest);
330
331	error = EFTYPE;
332	for (i = last_file_format, fp = NULL;
333	    file_formats[i] && fp == NULL; i++) {
334		error = (file_formats[i]->l_load)(filename, dest, &fp);
335		if (error == 0) {
336			/* remember the loader */
337			fp->f_loader = last_file_format = i;
338			*result = fp;
339			break;
340		} else if (last_file_format == i && i != 0) {
341			/* Restart from the beginning */
342			i = -1;
343			last_file_format = 0;
344			fp = NULL;
345			continue;
346		}
347		if (error == EFTYPE)
348			continue;	/* Unknown to this handler? */
349		if (error) {
350			snprintf(command_errbuf, sizeof (command_errbuf),
351			    "can't load file '%s': %s", filename,
352			    strerror(error));
353			break;
354		}
355	}
356	return (error);
357}
358
359static int
360file_load_dependencies(struct preloaded_file *base_file)
361{
362	struct file_metadata *md;
363	struct preloaded_file *fp;
364	struct mod_depend *verinfo;
365	struct kernel_module *mp;
366	char *dmodname;
367	int error;
368
369	md = file_findmetadata(base_file, MODINFOMD_DEPLIST);
370	if (md == NULL)
371		return (0);
372	error = 0;
373	do {
374		verinfo = (struct mod_depend *)md->md_data;
375		dmodname = (char *)(verinfo + 1);
376		if (file_findmodule(NULL, dmodname, verinfo) == NULL) {
377			printf("loading required module '%s'\n", dmodname);
378			error = mod_load(dmodname, verinfo, 0, NULL);
379			if (error)
380				break;
381			/*
382			 * If module loaded via kld name which isn't listed
383			 * in the linker.hints file, we should check if it have
384			 * required version.
385			 */
386			mp = file_findmodule(NULL, dmodname, verinfo);
387			if (mp == NULL) {
388				snprintf(command_errbuf,
389				    sizeof (command_errbuf),
390				    "module '%s' exists but with wrong version",
391				    dmodname);
392				error = ENOENT;
393				break;
394			}
395		}
396		md = metadata_next(md, MODINFOMD_DEPLIST);
397	} while (md);
398	if (!error)
399		return (0);
400	/* Load failed; discard everything */
401	while (base_file != NULL) {
402		fp = base_file;
403		base_file = base_file->f_next;
404		file_discard(fp);
405	}
406	return (error);
407}
408
409/*
410 * Calculate the size of the environment module.
411 * The environment is list of name=value C strings, ending with a '\0' byte.
412 */
413static size_t
414env_get_size(void)
415{
416	size_t size = 0;
417	struct env_var *ep;
418
419	/* Traverse the environment. */
420	for (ep = environ; ep != NULL; ep = ep->ev_next) {
421		size += strlen(ep->ev_name);
422		size++;		/* "=" */
423		if (ep->ev_value != NULL)
424			size += strlen(ep->ev_value);
425		size++;		/* nul byte */
426	}
427	size++;			/* nul byte */
428	return (size);
429}
430
431static void
432module_hash(struct preloaded_file *fp, void *addr, size_t size)
433{
434	uint8_t hash[SHA1_DIGEST_LENGTH];
435	char ascii[2 * SHA1_DIGEST_LENGTH + 1];
436	int i;
437
438	sha1(addr, size, hash);
439	for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
440		snprintf(ascii + 2 * i, sizeof (ascii) - 2 * i, "%02x",
441		    hash[i] & 0xff);
442	}
443	/* Out of memory here is not fatal issue. */
444	asprintf(&fp->f_args, "hash=%s", ascii);
445}
446
447/*
448 * Create virtual module for environment variables.
449 * This module should be created as late as possible before executing
450 * the OS kernel, or we may miss some environment variable updates.
451 */
452void
453build_environment_module(void)
454{
455	struct preloaded_file *fp;
456	size_t size;
457	char *name = "environment";
458	vm_offset_t laddr;
459
460	/* We can't load first */
461	if ((file_findfile(NULL, NULL)) == NULL) {
462		printf("Can not load environment module: %s\n",
463		    "the kernel is not loaded");
464		return;
465	}
466
467	tem_save_state();	/* Ask tem to save it's state in env. */
468	size = env_get_size();
469
470	fp = file_alloc();
471	if (fp != NULL) {
472		fp->f_name = strdup(name);
473		fp->f_type = strdup(name);
474	}
475
476	if (fp == NULL || fp->f_name == NULL || fp->f_type == NULL) {
477		printf("Can not load environment module: %s\n",
478		    "out of memory");
479		file_discard(fp);
480		return;
481	}
482
483
484	if (archsw.arch_loadaddr != NULL)
485		loadaddr = archsw.arch_loadaddr(LOAD_MEM, &size, loadaddr);
486
487	if (loadaddr == 0) {
488		printf("Can not load environment module: %s\n",
489		    "out of memory");
490		file_discard(fp);
491		return;
492	}
493
494	laddr = bi_copyenv(loadaddr);
495	/* Looks OK so far; populate control structure */
496	module_hash(fp, PTOV(loadaddr), laddr - loadaddr);
497	fp->f_loader = -1;
498	fp->f_addr = loadaddr;
499	fp->f_size = laddr - loadaddr;
500
501	/* recognise space consumption */
502	loadaddr = laddr;
503
504	file_insert_tail(fp);
505}
506
507void
508build_font_module(void)
509{
510	bitmap_data_t *bd;
511	struct font *fd;
512	struct preloaded_file *fp;
513	size_t size;
514	uint32_t checksum;
515	int i;
516	char *name = "console-font";
517	vm_offset_t laddr;
518	struct font_info fi;
519	struct fontlist *fl;
520
521	if (STAILQ_EMPTY(&fonts))
522		return;
523
524	/* We can't load first */
525	if ((file_findfile(NULL, NULL)) == NULL) {
526		printf("Can not load font module: %s\n",
527		    "the kernel is not loaded");
528		return;
529	}
530
531	/* helper pointers */
532	bd = NULL;
533	STAILQ_FOREACH(fl, &fonts, font_next) {
534		if (fl->font_data->font != NULL) {
535			bd = fl->font_data;
536			break;
537		}
538	}
539	if (bd == NULL)
540		return;
541	fd = bd->font;
542
543	fi.fi_width = fd->vf_width;
544	checksum = fi.fi_width;
545	fi.fi_height = fd->vf_height;
546	checksum += fi.fi_height;
547	fi.fi_bitmap_size = bd->uncompressed_size;
548	checksum += fi.fi_bitmap_size;
549
550	size = roundup2(sizeof (struct font_info), 8);
551	for (i = 0; i < VFNT_MAPS; i++) {
552		fi.fi_map_count[i] = fd->vf_map_count[i];
553		checksum += fi.fi_map_count[i];
554		size += fd->vf_map_count[i] * sizeof (struct font_map);
555		size += roundup2(size, 8);
556	}
557	size += bd->uncompressed_size;
558
559	fi.fi_checksum = -checksum;
560
561	fp = file_alloc();
562	if (fp != NULL) {
563		fp->f_name = strdup(name);
564		fp->f_type = strdup(name);
565	}
566
567	if (fp == NULL || fp->f_name == NULL || fp->f_type == NULL) {
568		printf("Can not load font module: %s\n",
569		    "out of memory");
570		file_discard(fp);
571		return;
572	}
573
574	if (archsw.arch_loadaddr != NULL)
575		loadaddr = archsw.arch_loadaddr(LOAD_MEM, &size, loadaddr);
576
577	if (loadaddr == 0) {
578		printf("Can not load font module: %s\n",
579		    "out of memory");
580		file_discard(fp);
581		return;
582	}
583
584	laddr = loadaddr;
585	laddr += archsw.arch_copyin(&fi, laddr, sizeof (struct font_info));
586	laddr = roundup2(laddr, 8);
587
588	/* Copy maps. */
589	for (i = 0; i < VFNT_MAPS; i++) {
590		if (fd->vf_map_count[i] != 0) {
591			laddr += archsw.arch_copyin(fd->vf_map[i], laddr,
592			    fd->vf_map_count[i] * sizeof (struct font_map));
593			laddr = roundup2(laddr, 8);
594		}
595	}
596
597	/* Copy the bitmap. */
598	laddr += archsw.arch_copyin(fd->vf_bytes, laddr, fi.fi_bitmap_size);
599
600	/* Looks OK so far; populate control structure */
601	module_hash(fp, PTOV(loadaddr), laddr - loadaddr);
602	fp->f_loader = -1;
603	fp->f_addr = loadaddr;
604	fp->f_size = laddr - loadaddr;
605
606	/* recognise space consumption */
607	loadaddr = laddr;
608
609	file_insert_tail(fp);
610}
611
612/*
613 * We've been asked to load (fname) as (type), so just suck it in,
614 * no arguments or anything.
615 */
616struct preloaded_file *
617file_loadraw(const char *fname, char *type, int argc, char **argv, int insert)
618{
619	struct preloaded_file *fp;
620	char *name;
621	int fd, got;
622	vm_offset_t laddr;
623	struct stat st;
624
625	/* We can't load first */
626	if ((file_findfile(NULL, NULL)) == NULL) {
627		command_errmsg = "can't load file before kernel";
628		return (NULL);
629	}
630
631	/* locate the file on the load path */
632	name = file_search(fname, NULL);
633	if (name == NULL) {
634		snprintf(command_errbuf, sizeof (command_errbuf),
635		    "can't find '%s'", fname);
636		return (NULL);
637	}
638
639	if ((fd = open(name, O_RDONLY)) < 0) {
640		snprintf(command_errbuf, sizeof (command_errbuf),
641		    "can't open '%s': %s", name, strerror(errno));
642		free(name);
643		return (NULL);
644	}
645	if (fstat(fd, &st) < 0) {
646		close(fd);
647		snprintf(command_errbuf, sizeof (command_errbuf),
648		    "stat error '%s': %s", name, strerror(errno));
649		free(name);
650		return (NULL);
651	}
652
653	if (archsw.arch_loadaddr != NULL)
654		loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr);
655	if (loadaddr == 0) {
656		close(fd);
657		snprintf(command_errbuf, sizeof (command_errbuf),
658		    "no memory to load %s", name);
659		free(name);
660		return (NULL);
661	}
662
663	laddr = loadaddr;
664	for (;;) {
665		/* read in 4k chunks; size is not really important */
666		got = archsw.arch_readin(fd, laddr, 4096);
667		if (got == 0)			/* end of file */
668			break;
669		if (got < 0) {			/* error */
670			snprintf(command_errbuf, sizeof (command_errbuf),
671			    "error reading '%s': %s", name, strerror(errno));
672			free(name);
673			close(fd);
674			if (archsw.arch_free_loadaddr != NULL &&
675			    st.st_size != 0) {
676				archsw.arch_free_loadaddr(loadaddr,
677				    (uint64_t)
678				    (roundup2(st.st_size, PAGE_SIZE) >> 12));
679			}
680			return (NULL);
681		}
682		laddr += got;
683	}
684
685	/* Looks OK so far; create & populate control structure */
686	fp = file_alloc();
687	if (fp == NULL) {
688		if (archsw.arch_free_loadaddr != NULL && st.st_size != 0)
689			archsw.arch_free_loadaddr(loadaddr,
690			    (uint64_t)(roundup2(st.st_size, PAGE_SIZE) >> 12));
691		snprintf(command_errbuf, sizeof (command_errbuf),
692		    "no memory to load %s", name);
693		free(name);
694		close(fd);
695		return (NULL);
696	}
697
698	fp->f_name = name;
699	fp->f_args = unargv(argc, argv);
700	fp->f_type = strdup(type);
701	fp->f_metadata = NULL;
702	fp->f_loader = -1;
703	fp->f_addr = loadaddr;
704	fp->f_size = laddr - loadaddr;
705
706	if (fp->f_type == NULL ||
707	    (argc != 0 && fp->f_args == NULL)) {
708		close(fd);
709		snprintf(command_errbuf, sizeof (command_errbuf),
710		    "no memory to load %s", name);
711		file_discard(fp);
712		return (NULL);
713	}
714	/* recognise space consumption */
715	loadaddr = laddr;
716
717	/* Add to the list of loaded files */
718	if (insert != 0)
719		file_insert_tail(fp);
720	close(fd);
721	return (fp);
722}
723
724/*
725 * Load the module (name), pass it (argc),(argv), add container file
726 * to the list of loaded files.
727 * If module is already loaded just assign new argc/argv.
728 */
729int
730mod_load(char *modname, struct mod_depend *verinfo, int argc, char *argv[])
731{
732	struct kernel_module *mp;
733	int err;
734	char *filename;
735
736	if (file_havepath(modname)) {
737		printf("Warning: mod_load() called instead of mod_loadkld() "
738		    "for module '%s'\n", modname);
739		return (mod_loadkld(modname, argc, argv));
740	}
741	/* see if module is already loaded */
742	mp = file_findmodule(NULL, modname, verinfo);
743	if (mp != NULL) {
744		free(mp->m_args);
745		mp->m_args = unargv(argc, argv);
746		snprintf(command_errbuf, sizeof (command_errbuf),
747		    "warning: module '%s' already loaded", mp->m_name);
748		return (0);
749	}
750	/* locate file with the module on the search path */
751	filename = mod_searchmodule(modname, verinfo);
752	if (filename == NULL) {
753		snprintf(command_errbuf, sizeof (command_errbuf),
754		    "can't find '%s'", modname);
755		return (ENOENT);
756	}
757	err = mod_loadkld(filename, argc, argv);
758	free(filename);
759	return (err);
760}
761
762/*
763 * Load specified KLD. If path is omitted, then try to locate it via
764 * search path.
765 */
766int
767mod_loadkld(const char *kldname, int argc, char *argv[])
768{
769	struct preloaded_file *fp;
770	int err;
771	char *filename;
772	vm_offset_t loadaddr_saved;
773
774	/*
775	 * Get fully qualified KLD name
776	 */
777	filename = file_search(kldname, kld_ext_list);
778	if (filename == NULL) {
779		snprintf(command_errbuf, sizeof (command_errbuf),
780		    "can't find '%s'", kldname);
781		return (ENOENT);
782	}
783	/*
784	 * Check if KLD already loaded
785	 */
786	fp = file_findfile(filename, NULL);
787	if (fp != NULL) {
788		snprintf(command_errbuf, sizeof (command_errbuf),
789		    "warning: KLD '%s' already loaded", filename);
790		free(filename);
791		return (0);
792	}
793
794	do {
795		err = file_load(filename, loadaddr, &fp);
796		if (err)
797			break;
798		fp->f_args = unargv(argc, argv);
799		loadaddr_saved = loadaddr;
800		loadaddr = fp->f_addr + fp->f_size;
801		file_insert_tail(fp);	/* Add to the list of loaded files */
802		if (file_load_dependencies(fp) != 0) {
803			err = ENOENT;
804			file_remove(fp);
805			loadaddr = loadaddr_saved;
806			fp = NULL;
807			break;
808		}
809	} while (0);
810	if (err == EFTYPE) {
811		snprintf(command_errbuf, sizeof (command_errbuf),
812		    "don't know how to load module '%s'", filename);
813	}
814	if (err)
815		file_discard(fp);
816	free(filename);
817	return (err);
818}
819
820/*
821 * Find a file matching (name) and (type).
822 * NULL may be passed as a wildcard to either.
823 */
824struct preloaded_file *
825file_findfile(const char *name, const char *type)
826{
827	struct preloaded_file *fp;
828
829	for (fp = preloaded_files; fp != NULL; fp = fp->f_next) {
830		if (((name == NULL) || strcmp(name, fp->f_name) == 0) &&
831		    ((type == NULL) || strcmp(type, fp->f_type) == 0))
832			break;
833	}
834	return (fp);
835}
836
837/*
838 * Find a module matching (name) inside of given file.
839 * NULL may be passed as a wildcard.
840 */
841struct kernel_module *
842file_findmodule(struct preloaded_file *fp, char *modname,
843    struct mod_depend *verinfo)
844{
845	struct kernel_module *mp, *best;
846	int bestver, mver;
847
848	if (fp == NULL) {
849		for (fp = preloaded_files; fp; fp = fp->f_next) {
850			mp = file_findmodule(fp, modname, verinfo);
851			if (mp != NULL)
852				return (mp);
853		}
854		return (NULL);
855	}
856	best = NULL;
857	bestver = 0;
858	for (mp = fp->f_modules; mp; mp = mp->m_next) {
859		if (strcmp(modname, mp->m_name) == 0) {
860			if (verinfo == NULL)
861				return (mp);
862			mver = mp->m_version;
863			if (mver == verinfo->md_ver_preferred)
864				return (mp);
865			if (mver >= verinfo->md_ver_minimum &&
866			    mver <= verinfo->md_ver_maximum &&
867			    mver > bestver) {
868				best = mp;
869				bestver = mver;
870			}
871		}
872	}
873	return (best);
874}
875/*
876 * Make a copy of (size) bytes of data from (p), and associate them as
877 * metadata of (type) to the module (mp).
878 */
879void
880file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p)
881{
882	struct file_metadata	*md;
883
884	md = malloc(sizeof (struct file_metadata) - sizeof (md->md_data) +
885	    size);
886	if (md != NULL) {
887		md->md_size = size;
888		md->md_type = type;
889		bcopy(p, md->md_data, size);
890		md->md_next = fp->f_metadata;
891	}
892	fp->f_metadata = md;
893}
894
895/*
896 * Find a metadata object of (type) associated with the file (fp)
897 */
898struct file_metadata *
899file_findmetadata(struct preloaded_file *fp, int type)
900{
901	struct file_metadata *md;
902
903	for (md = fp->f_metadata; md != NULL; md = md->md_next)
904		if (md->md_type == type)
905			break;
906	return (md);
907}
908
909struct file_metadata *
910metadata_next(struct file_metadata *md, int type)
911{
912
913	if (md == NULL)
914		return (NULL);
915	while ((md = md->md_next) != NULL)
916		if (md->md_type == type)
917			break;
918	return (md);
919}
920
921static const char *emptyextlist[] = { "", NULL };
922
923/*
924 * Check if the given file is in place and return full path to it.
925 */
926static char *
927file_lookup(const char *path, const char *name, int namelen,
928    const char **extlist)
929{
930	struct stat st;
931	char *result, *cp;
932	const char **cpp;
933	int pathlen, extlen, len;
934
935	pathlen = strlen(path);
936	extlen = 0;
937	if (extlist == NULL)
938		extlist = emptyextlist;
939	for (cpp = extlist; *cpp; cpp++) {
940		len = strlen(*cpp);
941		if (len > extlen)
942			extlen = len;
943	}
944	result = malloc(pathlen + namelen + extlen + 2);
945	if (result == NULL)
946		return (NULL);
947	bcopy(path, result, pathlen);
948	if (pathlen > 0 && result[pathlen - 1] != '/')
949		result[pathlen++] = '/';
950	cp = result + pathlen;
951	bcopy(name, cp, namelen);
952	cp += namelen;
953	for (cpp = extlist; *cpp; cpp++) {
954		strcpy(cp, *cpp);
955		if (stat(result, &st) == 0 && S_ISREG(st.st_mode))
956			return (result);
957	}
958	free(result);
959	return (NULL);
960}
961
962/*
963 * Check if file name have any qualifiers
964 */
965static int
966file_havepath(const char *name)
967{
968	const char *cp;
969
970	archsw.arch_getdev(NULL, name, &cp);
971	return (cp != name || strchr(name, '/') != NULL);
972}
973
974/*
975 * Attempt to find the file (name) on the module searchpath.
976 * If (name) is qualified in any way, we simply check it and
977 * return it or NULL.  If it is not qualified, then we attempt
978 * to construct a path using entries in the environment variable
979 * module_path.
980 *
981 * The path we return a pointer to need never be freed, as we manage
982 * it internally.
983 */
984static char *
985file_search(const char *name, const char **extlist)
986{
987	struct moduledir *mdp;
988	struct stat sb;
989	char *result;
990	int namelen;
991
992	/* Don't look for nothing */
993	if (name == NULL)
994		return (NULL);
995
996	if (*name == '\0')
997		return (strdup(name));
998
999	if (file_havepath(name)) {
1000		/* Qualified, so just see if it exists */
1001		if (stat(name, &sb) == 0)
1002			return (strdup(name));
1003		return (NULL);
1004	}
1005	moduledir_rebuild();
1006	result = NULL;
1007	namelen = strlen(name);
1008	STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1009		result = file_lookup(mdp->d_path, name, namelen, extlist);
1010		if (result != NULL)
1011			break;
1012	}
1013	return (result);
1014}
1015
1016#define	INT_ALIGN(base, ptr)	ptr = \
1017	(base) + (((ptr) - (base) + sizeof (int) - 1) & ~(sizeof (int) - 1))
1018
1019static char *
1020mod_search_hints(struct moduledir *mdp, const char *modname,
1021    struct mod_depend *verinfo)
1022{
1023	uchar_t *cp, *recptr, *bufend, *best;
1024	char *result;
1025	int *intp, bestver, blen, clen, ival, modnamelen, reclen;
1026	bool found;
1027
1028	moduledir_readhints(mdp);
1029	modnamelen = strlen(modname);
1030	found = false;
1031	result = NULL;
1032	bestver = 0;
1033	if (mdp->d_hints == NULL)
1034		goto bad;
1035	recptr = mdp->d_hints;
1036	bufend = recptr + mdp->d_hintsz;
1037	clen = blen = 0;
1038	best = cp = NULL;
1039	while (recptr < bufend && !found) {
1040		intp = (int *)recptr;
1041		reclen = *intp++;
1042		ival = *intp++;
1043		cp = (uchar_t *)intp;
1044		switch (ival) {
1045		case MDT_VERSION:
1046			clen = *cp++;
1047			if (clen != modnamelen || bcmp(cp, modname, clen) != 0)
1048				break;
1049			cp += clen;
1050			INT_ALIGN(mdp->d_hints, cp);
1051			ival = *(int *)cp;
1052			cp += sizeof (int);
1053			clen = *cp++;
1054			if (verinfo == NULL ||
1055			    ival == verinfo->md_ver_preferred) {
1056				found = true;
1057				break;
1058			}
1059			if (ival >= verinfo->md_ver_minimum &&
1060			    ival <= verinfo->md_ver_maximum &&
1061			    ival > bestver) {
1062				bestver = ival;
1063				best = cp;
1064				blen = clen;
1065			}
1066			break;
1067		default:
1068			break;
1069		}
1070		recptr += reclen + sizeof (int);
1071	}
1072	/*
1073	 * Finally check if KLD is in the place
1074	 */
1075	if (found)
1076		result = file_lookup(mdp->d_path, (char *)cp, clen, NULL);
1077	else if (best)
1078		result = file_lookup(mdp->d_path, (char *)best, blen, NULL);
1079bad:
1080	/*
1081	 * If nothing found or hints is absent - fallback to the old way
1082	 * by using "kldname[.ko]" as module name.
1083	 */
1084	if (!found && bestver == 0 && result == NULL) {
1085		result = file_lookup(mdp->d_path, modname, modnamelen,
1086		    kld_ext_list);
1087	}
1088	return (result);
1089}
1090
1091/*
1092 * Attempt to locate the file containing the module (name)
1093 */
1094static char *
1095mod_searchmodule(char *name, struct mod_depend *verinfo)
1096{
1097	struct moduledir *mdp;
1098	char *result;
1099
1100	moduledir_rebuild();
1101	/*
1102	 * Now we ready to lookup module in the given directories
1103	 */
1104	result = NULL;
1105	STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1106		result = mod_search_hints(mdp, name, verinfo);
1107		if (result != NULL)
1108			break;
1109	}
1110
1111	return (result);
1112}
1113
1114int
1115file_addmodule(struct preloaded_file *fp, char *modname, int version,
1116    struct kernel_module **newmp)
1117{
1118	struct kernel_module *mp;
1119	struct mod_depend mdepend;
1120
1121	bzero(&mdepend, sizeof (mdepend));
1122	mdepend.md_ver_preferred = version;
1123	mp = file_findmodule(fp, modname, &mdepend);
1124	if (mp != NULL)
1125		return (EEXIST);
1126	mp = calloc(1, sizeof (struct kernel_module));
1127	if (mp == NULL)
1128		return (ENOMEM);
1129	mp->m_name = strdup(modname);
1130	if (mp->m_name == NULL) {
1131		free(mp);
1132		return (ENOMEM);
1133	}
1134	mp->m_version = version;
1135	mp->m_fp = fp;
1136	mp->m_next = fp->f_modules;
1137	fp->f_modules = mp;
1138	if (newmp)
1139		*newmp = mp;
1140	return (0);
1141}
1142
1143/*
1144 * Throw a file away
1145 */
1146void
1147file_discard(struct preloaded_file *fp)
1148{
1149	struct file_metadata *md, *md1;
1150	struct kernel_module *mp, *mp1;
1151
1152	if (fp == NULL)
1153		return;
1154
1155	if (archsw.arch_free_loadaddr != NULL && fp->f_addr &&
1156	    fp->f_size != 0) {
1157		archsw.arch_free_loadaddr(fp->f_addr,
1158		    (uint64_t)(roundup2(fp->f_size, PAGE_SIZE) >> 12));
1159	}
1160
1161	md = fp->f_metadata;
1162	while (md != NULL) {
1163		md1 = md;
1164		md = md->md_next;
1165		free(md1);
1166	}
1167	mp = fp->f_modules;
1168	while (mp != NULL) {
1169		free(mp->m_name);
1170		mp1 = mp;
1171		mp = mp->m_next;
1172		free(mp1);
1173	}
1174	free(fp->f_name);
1175	free(fp->f_type);
1176	free(fp->f_args);
1177	free(fp);
1178}
1179
1180/*
1181 * Allocate a new file; must be used instead of malloc()
1182 * to ensure safe initialisation.
1183 */
1184struct preloaded_file *
1185file_alloc(void)
1186{
1187
1188	return (calloc(1, sizeof (struct preloaded_file)));
1189}
1190
1191/*
1192 * Add a module to the chain
1193 */
1194static void
1195file_insert_tail(struct preloaded_file *fp)
1196{
1197	struct preloaded_file *cm;
1198
1199	/* Append to list of loaded file */
1200	fp->f_next = NULL;
1201	if (preloaded_files == NULL) {
1202		preloaded_files = fp;
1203	} else {
1204		for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next)
1205			;
1206		cm->f_next = fp;
1207	}
1208}
1209
1210/*
1211 * Remove module from the chain
1212 */
1213static void
1214file_remove(struct preloaded_file *fp)
1215{
1216	struct preloaded_file   *cm;
1217
1218	if (preloaded_files == NULL)
1219		return;
1220
1221	if (preloaded_files == fp) {
1222		preloaded_files = fp->f_next;
1223		return;
1224	}
1225	for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next) {
1226		if (cm->f_next == fp) {
1227			cm->f_next = fp->f_next;
1228			return;
1229		}
1230	}
1231}
1232
1233static char *
1234moduledir_fullpath(struct moduledir *mdp, const char *fname)
1235{
1236	char *cp;
1237
1238	cp = malloc(strlen(mdp->d_path) + strlen(fname) + 2);
1239	if (cp == NULL)
1240		return (NULL);
1241	strcpy(cp, mdp->d_path);
1242	strcat(cp, "/");
1243	strcat(cp, fname);
1244	return (cp);
1245}
1246
1247/*
1248 * Read linker.hints file into memory performing some sanity checks.
1249 */
1250static void
1251moduledir_readhints(struct moduledir *mdp)
1252{
1253	struct stat st;
1254	char *path;
1255	int fd, size, version;
1256
1257	if (mdp->d_hints != NULL || (mdp->d_flags & MDIR_NOHINTS))
1258		return;
1259	path = moduledir_fullpath(mdp, "linker.hints");
1260	if (stat(path, &st) != 0 ||
1261	    st.st_size < (ssize_t)(sizeof (version) + sizeof (int)) ||
1262	    st.st_size > LINKER_HINTS_MAX ||
1263	    (fd = open(path, O_RDONLY)) < 0) {
1264		free(path);
1265		mdp->d_flags |= MDIR_NOHINTS;
1266		return;
1267	}
1268	free(path);
1269	size = read(fd, &version, sizeof (version));
1270	if (size != sizeof (version) || version != LINKER_HINTS_VERSION)
1271		goto bad;
1272	size = st.st_size - size;
1273	mdp->d_hints = malloc(size);
1274	if (mdp->d_hints == NULL)
1275		goto bad;
1276	if (read(fd, mdp->d_hints, size) != size)
1277		goto bad;
1278	mdp->d_hintsz = size;
1279	close(fd);
1280	return;
1281bad:
1282	close(fd);
1283	free(mdp->d_hints);
1284	mdp->d_hints = NULL;
1285	mdp->d_flags |= MDIR_NOHINTS;
1286}
1287
1288/*
1289 * Extract directories from the ';' separated list, remove duplicates.
1290 */
1291static void
1292moduledir_rebuild(void)
1293{
1294	struct moduledir *mdp, *mtmp;
1295	const char *path, *cp, *ep;
1296	size_t cplen;
1297
1298	path = getenv("module_path");
1299	if (path == NULL)
1300		path = default_searchpath;
1301	/*
1302	 * Rebuild list of module directories if it changed
1303	 */
1304	STAILQ_FOREACH(mdp, &moduledir_list, d_link)
1305		mdp->d_flags |= MDIR_REMOVED;
1306
1307	for (ep = path; *ep != 0; ep++) {
1308		cp = ep;
1309		for (; *ep != 0 && *ep != ';'; ep++)
1310			;
1311		/*
1312		 * Ignore trailing slashes
1313		 */
1314		for (cplen = ep - cp; cplen > 1 && cp[cplen - 1] == '/';
1315		    cplen--)
1316			;
1317		STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1318			if (strlen(mdp->d_path) != cplen ||
1319			    bcmp(cp, mdp->d_path, cplen) != 0)
1320				continue;
1321			mdp->d_flags &= ~MDIR_REMOVED;
1322			break;
1323		}
1324		if (mdp == NULL) {
1325			mdp = malloc(sizeof (*mdp) + cplen + 1);
1326			if (mdp == NULL)
1327				return;
1328			mdp->d_path = (char *)(mdp + 1);
1329			bcopy(cp, mdp->d_path, cplen);
1330			mdp->d_path[cplen] = 0;
1331			mdp->d_hints = NULL;
1332			mdp->d_flags = 0;
1333			STAILQ_INSERT_TAIL(&moduledir_list, mdp, d_link);
1334		}
1335		if (*ep == '\0')
1336			break;
1337	}
1338	/*
1339	 * Delete unused directories if any
1340	 */
1341	mdp = STAILQ_FIRST(&moduledir_list);
1342	while (mdp) {
1343		if ((mdp->d_flags & MDIR_REMOVED) == 0) {
1344			mdp = STAILQ_NEXT(mdp, d_link);
1345		} else {
1346			free(mdp->d_hints);
1347			mtmp = mdp;
1348			mdp = STAILQ_NEXT(mdp, d_link);
1349			STAILQ_REMOVE(&moduledir_list, mtmp, moduledir, d_link);
1350			free(mtmp);
1351		}
1352	}
1353}
1354