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 (tems.ts_font.vf_width == fl->font_data->width &&
535		    tems.ts_font.vf_height == fl->font_data->height) {
536			/*
537			 * Kernel does have better built in font.
538			 */
539			if (fl->font_flags == FONT_BUILTIN)
540				return;
541
542			bd = fl->font_data;
543			break;
544		}
545	}
546	if (bd == NULL)
547		return;
548	fd = bd->font;
549
550	fi.fi_width = fd->vf_width;
551	checksum = fi.fi_width;
552	fi.fi_height = fd->vf_height;
553	checksum += fi.fi_height;
554	fi.fi_bitmap_size = bd->uncompressed_size;
555	checksum += fi.fi_bitmap_size;
556
557	size = roundup2(sizeof (struct font_info), 8);
558	for (i = 0; i < VFNT_MAPS; i++) {
559		fi.fi_map_count[i] = fd->vf_map_count[i];
560		checksum += fi.fi_map_count[i];
561		size += fd->vf_map_count[i] * sizeof (struct font_map);
562		size += roundup2(size, 8);
563	}
564	size += bd->uncompressed_size;
565
566	fi.fi_checksum = -checksum;
567
568	fp = file_alloc();
569	if (fp != NULL) {
570		fp->f_name = strdup(name);
571		fp->f_type = strdup(name);
572	}
573
574	if (fp == NULL || fp->f_name == NULL || fp->f_type == NULL) {
575		printf("Can not load font module: %s\n",
576		    "out of memory");
577		file_discard(fp);
578		return;
579	}
580
581	if (archsw.arch_loadaddr != NULL)
582		loadaddr = archsw.arch_loadaddr(LOAD_MEM, &size, loadaddr);
583
584	if (loadaddr == 0) {
585		printf("Can not load font module: %s\n",
586		    "out of memory");
587		file_discard(fp);
588		return;
589	}
590
591	laddr = loadaddr;
592	laddr += archsw.arch_copyin(&fi, laddr, sizeof (struct font_info));
593	laddr = roundup2(laddr, 8);
594
595	/* Copy maps. */
596	for (i = 0; i < VFNT_MAPS; i++) {
597		if (fd->vf_map_count[i] != 0) {
598			laddr += archsw.arch_copyin(fd->vf_map[i], laddr,
599			    fd->vf_map_count[i] * sizeof (struct font_map));
600			laddr = roundup2(laddr, 8);
601		}
602	}
603
604	/* Copy the bitmap. */
605	laddr += archsw.arch_copyin(fd->vf_bytes, laddr, fi.fi_bitmap_size);
606
607	/* Looks OK so far; populate control structure */
608	module_hash(fp, PTOV(loadaddr), laddr - loadaddr);
609	fp->f_loader = -1;
610	fp->f_addr = loadaddr;
611	fp->f_size = laddr - loadaddr;
612
613	/* recognise space consumption */
614	loadaddr = laddr;
615
616	file_insert_tail(fp);
617}
618
619/*
620 * We've been asked to load (fname) as (type), so just suck it in,
621 * no arguments or anything.
622 */
623struct preloaded_file *
624file_loadraw(const char *fname, char *type, int argc, char **argv, int insert)
625{
626	struct preloaded_file *fp;
627	char *name;
628	int fd, got;
629	vm_offset_t laddr;
630	struct stat st;
631
632	/* We can't load first */
633	if ((file_findfile(NULL, NULL)) == NULL) {
634		command_errmsg = "can't load file before kernel";
635		return (NULL);
636	}
637
638	/* locate the file on the load path */
639	name = file_search(fname, NULL);
640	if (name == NULL) {
641		snprintf(command_errbuf, sizeof (command_errbuf),
642		    "can't find '%s'", fname);
643		return (NULL);
644	}
645
646	if ((fd = open(name, O_RDONLY)) < 0) {
647		snprintf(command_errbuf, sizeof (command_errbuf),
648		    "can't open '%s': %s", name, strerror(errno));
649		free(name);
650		return (NULL);
651	}
652	if (fstat(fd, &st) < 0) {
653		close(fd);
654		snprintf(command_errbuf, sizeof (command_errbuf),
655		    "stat error '%s': %s", name, strerror(errno));
656		free(name);
657		return (NULL);
658	}
659
660	if (archsw.arch_loadaddr != NULL)
661		loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr);
662	if (loadaddr == 0) {
663		close(fd);
664		snprintf(command_errbuf, sizeof (command_errbuf),
665		    "no memory to load %s", name);
666		free(name);
667		return (NULL);
668	}
669
670	laddr = loadaddr;
671	for (;;) {
672		/* read in 4k chunks; size is not really important */
673		got = archsw.arch_readin(fd, laddr, 4096);
674		if (got == 0)			/* end of file */
675			break;
676		if (got < 0) {			/* error */
677			snprintf(command_errbuf, sizeof (command_errbuf),
678			    "error reading '%s': %s", name, strerror(errno));
679			free(name);
680			close(fd);
681			if (archsw.arch_free_loadaddr != NULL &&
682			    st.st_size != 0) {
683				archsw.arch_free_loadaddr(loadaddr,
684				    (uint64_t)
685				    (roundup2(st.st_size, PAGE_SIZE) >> 12));
686			}
687			return (NULL);
688		}
689		laddr += got;
690	}
691
692	/* Looks OK so far; create & populate control structure */
693	fp = file_alloc();
694	if (fp == NULL) {
695		if (archsw.arch_free_loadaddr != NULL && st.st_size != 0)
696			archsw.arch_free_loadaddr(loadaddr,
697			    (uint64_t)(roundup2(st.st_size, PAGE_SIZE) >> 12));
698		snprintf(command_errbuf, sizeof (command_errbuf),
699		    "no memory to load %s", name);
700		free(name);
701		close(fd);
702		return (NULL);
703	}
704
705	fp->f_name = name;
706	fp->f_args = unargv(argc, argv);
707	fp->f_type = strdup(type);
708	fp->f_metadata = NULL;
709	fp->f_loader = -1;
710	fp->f_addr = loadaddr;
711	fp->f_size = laddr - loadaddr;
712
713	if (fp->f_type == NULL ||
714	    (argc != 0 && fp->f_args == NULL)) {
715		close(fd);
716		snprintf(command_errbuf, sizeof (command_errbuf),
717		    "no memory to load %s", name);
718		file_discard(fp);
719		return (NULL);
720	}
721	/* recognise space consumption */
722	loadaddr = laddr;
723
724	/* Add to the list of loaded files */
725	if (insert != 0)
726		file_insert_tail(fp);
727	close(fd);
728	return (fp);
729}
730
731/*
732 * Load the module (name), pass it (argc),(argv), add container file
733 * to the list of loaded files.
734 * If module is already loaded just assign new argc/argv.
735 */
736int
737mod_load(char *modname, struct mod_depend *verinfo, int argc, char *argv[])
738{
739	struct kernel_module *mp;
740	int err;
741	char *filename;
742
743	if (file_havepath(modname)) {
744		printf("Warning: mod_load() called instead of mod_loadkld() "
745		    "for module '%s'\n", modname);
746		return (mod_loadkld(modname, argc, argv));
747	}
748	/* see if module is already loaded */
749	mp = file_findmodule(NULL, modname, verinfo);
750	if (mp != NULL) {
751		free(mp->m_args);
752		mp->m_args = unargv(argc, argv);
753		snprintf(command_errbuf, sizeof (command_errbuf),
754		    "warning: module '%s' already loaded", mp->m_name);
755		return (0);
756	}
757	/* locate file with the module on the search path */
758	filename = mod_searchmodule(modname, verinfo);
759	if (filename == NULL) {
760		snprintf(command_errbuf, sizeof (command_errbuf),
761		    "can't find '%s'", modname);
762		return (ENOENT);
763	}
764	err = mod_loadkld(filename, argc, argv);
765	free(filename);
766	return (err);
767}
768
769/*
770 * Load specified KLD. If path is omitted, then try to locate it via
771 * search path.
772 */
773int
774mod_loadkld(const char *kldname, int argc, char *argv[])
775{
776	struct preloaded_file *fp;
777	int err;
778	char *filename;
779	vm_offset_t loadaddr_saved;
780
781	/*
782	 * Get fully qualified KLD name
783	 */
784	filename = file_search(kldname, kld_ext_list);
785	if (filename == NULL) {
786		snprintf(command_errbuf, sizeof (command_errbuf),
787		    "can't find '%s'", kldname);
788		return (ENOENT);
789	}
790	/*
791	 * Check if KLD already loaded
792	 */
793	fp = file_findfile(filename, NULL);
794	if (fp != NULL) {
795		snprintf(command_errbuf, sizeof (command_errbuf),
796		    "warning: KLD '%s' already loaded", filename);
797		free(filename);
798		return (0);
799	}
800
801	do {
802		err = file_load(filename, loadaddr, &fp);
803		if (err)
804			break;
805		fp->f_args = unargv(argc, argv);
806		loadaddr_saved = loadaddr;
807		loadaddr = fp->f_addr + fp->f_size;
808		file_insert_tail(fp);	/* Add to the list of loaded files */
809		if (file_load_dependencies(fp) != 0) {
810			err = ENOENT;
811			file_remove(fp);
812			loadaddr = loadaddr_saved;
813			fp = NULL;
814			break;
815		}
816	} while (0);
817	if (err == EFTYPE) {
818		snprintf(command_errbuf, sizeof (command_errbuf),
819		    "don't know how to load module '%s'", filename);
820	}
821	if (err)
822		file_discard(fp);
823	free(filename);
824	return (err);
825}
826
827/*
828 * Find a file matching (name) and (type).
829 * NULL may be passed as a wildcard to either.
830 */
831struct preloaded_file *
832file_findfile(const char *name, const char *type)
833{
834	struct preloaded_file *fp;
835
836	for (fp = preloaded_files; fp != NULL; fp = fp->f_next) {
837		if (((name == NULL) || strcmp(name, fp->f_name) == 0) &&
838		    ((type == NULL) || strcmp(type, fp->f_type) == 0))
839			break;
840	}
841	return (fp);
842}
843
844/*
845 * Find a module matching (name) inside of given file.
846 * NULL may be passed as a wildcard.
847 */
848struct kernel_module *
849file_findmodule(struct preloaded_file *fp, char *modname,
850    struct mod_depend *verinfo)
851{
852	struct kernel_module *mp, *best;
853	int bestver, mver;
854
855	if (fp == NULL) {
856		for (fp = preloaded_files; fp; fp = fp->f_next) {
857			mp = file_findmodule(fp, modname, verinfo);
858			if (mp != NULL)
859				return (mp);
860		}
861		return (NULL);
862	}
863	best = NULL;
864	bestver = 0;
865	for (mp = fp->f_modules; mp; mp = mp->m_next) {
866		if (strcmp(modname, mp->m_name) == 0) {
867			if (verinfo == NULL)
868				return (mp);
869			mver = mp->m_version;
870			if (mver == verinfo->md_ver_preferred)
871				return (mp);
872			if (mver >= verinfo->md_ver_minimum &&
873			    mver <= verinfo->md_ver_maximum &&
874			    mver > bestver) {
875				best = mp;
876				bestver = mver;
877			}
878		}
879	}
880	return (best);
881}
882/*
883 * Make a copy of (size) bytes of data from (p), and associate them as
884 * metadata of (type) to the module (mp).
885 */
886void
887file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p)
888{
889	struct file_metadata	*md;
890
891	md = malloc(sizeof (struct file_metadata) - sizeof (md->md_data) +
892	    size);
893	if (md != NULL) {
894		md->md_size = size;
895		md->md_type = type;
896		bcopy(p, md->md_data, size);
897		md->md_next = fp->f_metadata;
898	}
899	fp->f_metadata = md;
900}
901
902/*
903 * Find a metadata object of (type) associated with the file (fp)
904 */
905struct file_metadata *
906file_findmetadata(struct preloaded_file *fp, int type)
907{
908	struct file_metadata *md;
909
910	for (md = fp->f_metadata; md != NULL; md = md->md_next)
911		if (md->md_type == type)
912			break;
913	return (md);
914}
915
916struct file_metadata *
917metadata_next(struct file_metadata *md, int type)
918{
919
920	if (md == NULL)
921		return (NULL);
922	while ((md = md->md_next) != NULL)
923		if (md->md_type == type)
924			break;
925	return (md);
926}
927
928static const char *emptyextlist[] = { "", NULL };
929
930/*
931 * Check if the given file is in place and return full path to it.
932 */
933static char *
934file_lookup(const char *path, const char *name, int namelen,
935    const char **extlist)
936{
937	struct stat st;
938	char *result, *cp;
939	const char **cpp;
940	int pathlen, extlen, len;
941
942	pathlen = strlen(path);
943	extlen = 0;
944	if (extlist == NULL)
945		extlist = emptyextlist;
946	for (cpp = extlist; *cpp; cpp++) {
947		len = strlen(*cpp);
948		if (len > extlen)
949			extlen = len;
950	}
951	result = malloc(pathlen + namelen + extlen + 2);
952	if (result == NULL)
953		return (NULL);
954	bcopy(path, result, pathlen);
955	if (pathlen > 0 && result[pathlen - 1] != '/')
956		result[pathlen++] = '/';
957	cp = result + pathlen;
958	bcopy(name, cp, namelen);
959	cp += namelen;
960	for (cpp = extlist; *cpp; cpp++) {
961		strcpy(cp, *cpp);
962		if (stat(result, &st) == 0 && S_ISREG(st.st_mode))
963			return (result);
964	}
965	free(result);
966	return (NULL);
967}
968
969/*
970 * Check if file name have any qualifiers
971 */
972static int
973file_havepath(const char *name)
974{
975	const char *cp;
976
977	archsw.arch_getdev(NULL, name, &cp);
978	return (cp != name || strchr(name, '/') != NULL);
979}
980
981/*
982 * Attempt to find the file (name) on the module searchpath.
983 * If (name) is qualified in any way, we simply check it and
984 * return it or NULL.  If it is not qualified, then we attempt
985 * to construct a path using entries in the environment variable
986 * module_path.
987 *
988 * The path we return a pointer to need never be freed, as we manage
989 * it internally.
990 */
991static char *
992file_search(const char *name, const char **extlist)
993{
994	struct moduledir *mdp;
995	struct stat sb;
996	char *result;
997	int namelen;
998
999	/* Don't look for nothing */
1000	if (name == NULL)
1001		return (NULL);
1002
1003	if (*name == '\0')
1004		return (strdup(name));
1005
1006	if (file_havepath(name)) {
1007		/* Qualified, so just see if it exists */
1008		if (stat(name, &sb) == 0)
1009			return (strdup(name));
1010		return (NULL);
1011	}
1012	moduledir_rebuild();
1013	result = NULL;
1014	namelen = strlen(name);
1015	STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1016		result = file_lookup(mdp->d_path, name, namelen, extlist);
1017		if (result != NULL)
1018			break;
1019	}
1020	return (result);
1021}
1022
1023#define	INT_ALIGN(base, ptr)	ptr = \
1024	(base) + (((ptr) - (base) + sizeof (int) - 1) & ~(sizeof (int) - 1))
1025
1026static char *
1027mod_search_hints(struct moduledir *mdp, const char *modname,
1028    struct mod_depend *verinfo)
1029{
1030	uchar_t *cp, *recptr, *bufend, *best;
1031	char *result;
1032	int *intp, bestver, blen, clen, ival, modnamelen, reclen;
1033	bool found;
1034
1035	moduledir_readhints(mdp);
1036	modnamelen = strlen(modname);
1037	found = false;
1038	result = NULL;
1039	bestver = 0;
1040	if (mdp->d_hints == NULL)
1041		goto bad;
1042	recptr = mdp->d_hints;
1043	bufend = recptr + mdp->d_hintsz;
1044	clen = blen = 0;
1045	best = cp = NULL;
1046	while (recptr < bufend && !found) {
1047		intp = (int *)recptr;
1048		reclen = *intp++;
1049		ival = *intp++;
1050		cp = (uchar_t *)intp;
1051		switch (ival) {
1052		case MDT_VERSION:
1053			clen = *cp++;
1054			if (clen != modnamelen || bcmp(cp, modname, clen) != 0)
1055				break;
1056			cp += clen;
1057			INT_ALIGN(mdp->d_hints, cp);
1058			ival = *(int *)cp;
1059			cp += sizeof (int);
1060			clen = *cp++;
1061			if (verinfo == NULL ||
1062			    ival == verinfo->md_ver_preferred) {
1063				found = true;
1064				break;
1065			}
1066			if (ival >= verinfo->md_ver_minimum &&
1067			    ival <= verinfo->md_ver_maximum &&
1068			    ival > bestver) {
1069				bestver = ival;
1070				best = cp;
1071				blen = clen;
1072			}
1073			break;
1074		default:
1075			break;
1076		}
1077		recptr += reclen + sizeof (int);
1078	}
1079	/*
1080	 * Finally check if KLD is in the place
1081	 */
1082	if (found)
1083		result = file_lookup(mdp->d_path, (char *)cp, clen, NULL);
1084	else if (best)
1085		result = file_lookup(mdp->d_path, (char *)best, blen, NULL);
1086bad:
1087	/*
1088	 * If nothing found or hints is absent - fallback to the old way
1089	 * by using "kldname[.ko]" as module name.
1090	 */
1091	if (!found && bestver == 0 && result == NULL) {
1092		result = file_lookup(mdp->d_path, modname, modnamelen,
1093		    kld_ext_list);
1094	}
1095	return (result);
1096}
1097
1098/*
1099 * Attempt to locate the file containing the module (name)
1100 */
1101static char *
1102mod_searchmodule(char *name, struct mod_depend *verinfo)
1103{
1104	struct moduledir *mdp;
1105	char *result;
1106
1107	moduledir_rebuild();
1108	/*
1109	 * Now we ready to lookup module in the given directories
1110	 */
1111	result = NULL;
1112	STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1113		result = mod_search_hints(mdp, name, verinfo);
1114		if (result != NULL)
1115			break;
1116	}
1117
1118	return (result);
1119}
1120
1121int
1122file_addmodule(struct preloaded_file *fp, char *modname, int version,
1123    struct kernel_module **newmp)
1124{
1125	struct kernel_module *mp;
1126	struct mod_depend mdepend;
1127
1128	bzero(&mdepend, sizeof (mdepend));
1129	mdepend.md_ver_preferred = version;
1130	mp = file_findmodule(fp, modname, &mdepend);
1131	if (mp != NULL)
1132		return (EEXIST);
1133	mp = calloc(1, sizeof (struct kernel_module));
1134	if (mp == NULL)
1135		return (ENOMEM);
1136	mp->m_name = strdup(modname);
1137	if (mp->m_name == NULL) {
1138		free(mp);
1139		return (ENOMEM);
1140	}
1141	mp->m_version = version;
1142	mp->m_fp = fp;
1143	mp->m_next = fp->f_modules;
1144	fp->f_modules = mp;
1145	if (newmp)
1146		*newmp = mp;
1147	return (0);
1148}
1149
1150/*
1151 * Throw a file away
1152 */
1153void
1154file_discard(struct preloaded_file *fp)
1155{
1156	struct file_metadata *md, *md1;
1157	struct kernel_module *mp, *mp1;
1158
1159	if (fp == NULL)
1160		return;
1161
1162	if (archsw.arch_free_loadaddr != NULL && fp->f_addr &&
1163	    fp->f_size != 0) {
1164		archsw.arch_free_loadaddr(fp->f_addr,
1165		    (uint64_t)(roundup2(fp->f_size, PAGE_SIZE) >> 12));
1166	}
1167
1168	md = fp->f_metadata;
1169	while (md != NULL) {
1170		md1 = md;
1171		md = md->md_next;
1172		free(md1);
1173	}
1174	mp = fp->f_modules;
1175	while (mp != NULL) {
1176		free(mp->m_name);
1177		mp1 = mp;
1178		mp = mp->m_next;
1179		free(mp1);
1180	}
1181	free(fp->f_name);
1182	free(fp->f_type);
1183	free(fp->f_args);
1184	free(fp);
1185}
1186
1187/*
1188 * Allocate a new file; must be used instead of malloc()
1189 * to ensure safe initialisation.
1190 */
1191struct preloaded_file *
1192file_alloc(void)
1193{
1194
1195	return (calloc(1, sizeof (struct preloaded_file)));
1196}
1197
1198/*
1199 * Add a module to the chain
1200 */
1201static void
1202file_insert_tail(struct preloaded_file *fp)
1203{
1204	struct preloaded_file *cm;
1205
1206	/* Append to list of loaded file */
1207	fp->f_next = NULL;
1208	if (preloaded_files == NULL) {
1209		preloaded_files = fp;
1210	} else {
1211		for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next)
1212			;
1213		cm->f_next = fp;
1214	}
1215}
1216
1217/*
1218 * Remove module from the chain
1219 */
1220static void
1221file_remove(struct preloaded_file *fp)
1222{
1223	struct preloaded_file   *cm;
1224
1225	if (preloaded_files == NULL)
1226		return;
1227
1228	if (preloaded_files == fp) {
1229		preloaded_files = fp->f_next;
1230		return;
1231	}
1232	for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next) {
1233		if (cm->f_next == fp) {
1234			cm->f_next = fp->f_next;
1235			return;
1236		}
1237	}
1238}
1239
1240static char *
1241moduledir_fullpath(struct moduledir *mdp, const char *fname)
1242{
1243	char *cp;
1244
1245	cp = malloc(strlen(mdp->d_path) + strlen(fname) + 2);
1246	if (cp == NULL)
1247		return (NULL);
1248	strcpy(cp, mdp->d_path);
1249	strcat(cp, "/");
1250	strcat(cp, fname);
1251	return (cp);
1252}
1253
1254/*
1255 * Read linker.hints file into memory performing some sanity checks.
1256 */
1257static void
1258moduledir_readhints(struct moduledir *mdp)
1259{
1260	struct stat st;
1261	char *path;
1262	int fd, size, version;
1263
1264	if (mdp->d_hints != NULL || (mdp->d_flags & MDIR_NOHINTS))
1265		return;
1266	path = moduledir_fullpath(mdp, "linker.hints");
1267	if (stat(path, &st) != 0 ||
1268	    st.st_size < (ssize_t)(sizeof (version) + sizeof (int)) ||
1269	    st.st_size > LINKER_HINTS_MAX ||
1270	    (fd = open(path, O_RDONLY)) < 0) {
1271		free(path);
1272		mdp->d_flags |= MDIR_NOHINTS;
1273		return;
1274	}
1275	free(path);
1276	size = read(fd, &version, sizeof (version));
1277	if (size != sizeof (version) || version != LINKER_HINTS_VERSION)
1278		goto bad;
1279	size = st.st_size - size;
1280	mdp->d_hints = malloc(size);
1281	if (mdp->d_hints == NULL)
1282		goto bad;
1283	if (read(fd, mdp->d_hints, size) != size)
1284		goto bad;
1285	mdp->d_hintsz = size;
1286	close(fd);
1287	return;
1288bad:
1289	close(fd);
1290	free(mdp->d_hints);
1291	mdp->d_hints = NULL;
1292	mdp->d_flags |= MDIR_NOHINTS;
1293}
1294
1295/*
1296 * Extract directories from the ';' separated list, remove duplicates.
1297 */
1298static void
1299moduledir_rebuild(void)
1300{
1301	struct moduledir *mdp, *mtmp;
1302	const char *path, *cp, *ep;
1303	size_t cplen;
1304
1305	path = getenv("module_path");
1306	if (path == NULL)
1307		path = default_searchpath;
1308	/*
1309	 * Rebuild list of module directories if it changed
1310	 */
1311	STAILQ_FOREACH(mdp, &moduledir_list, d_link)
1312		mdp->d_flags |= MDIR_REMOVED;
1313
1314	for (ep = path; *ep != 0; ep++) {
1315		cp = ep;
1316		for (; *ep != 0 && *ep != ';'; ep++)
1317			;
1318		/*
1319		 * Ignore trailing slashes
1320		 */
1321		for (cplen = ep - cp; cplen > 1 && cp[cplen - 1] == '/';
1322		    cplen--)
1323			;
1324		STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
1325			if (strlen(mdp->d_path) != cplen ||
1326			    bcmp(cp, mdp->d_path, cplen) != 0)
1327				continue;
1328			mdp->d_flags &= ~MDIR_REMOVED;
1329			break;
1330		}
1331		if (mdp == NULL) {
1332			mdp = malloc(sizeof (*mdp) + cplen + 1);
1333			if (mdp == NULL)
1334				return;
1335			mdp->d_path = (char *)(mdp + 1);
1336			bcopy(cp, mdp->d_path, cplen);
1337			mdp->d_path[cplen] = 0;
1338			mdp->d_hints = NULL;
1339			mdp->d_flags = 0;
1340			STAILQ_INSERT_TAIL(&moduledir_list, mdp, d_link);
1341		}
1342		if (*ep == '\0')
1343			break;
1344	}
1345	/*
1346	 * Delete unused directories if any
1347	 */
1348	mdp = STAILQ_FIRST(&moduledir_list);
1349	while (mdp) {
1350		if ((mdp->d_flags & MDIR_REMOVED) == 0) {
1351			mdp = STAILQ_NEXT(mdp, d_link);
1352		} else {
1353			free(mdp->d_hints);
1354			mtmp = mdp;
1355			mdp = STAILQ_NEXT(mdp, d_link);
1356			STAILQ_REMOVE(&moduledir_list, mtmp, moduledir, d_link);
1357			free(mtmp);
1358		}
1359	}
1360}
1361