kern_linker.c revision 185895
125537Sdfr/*-
259603Sdfr * Copyright (c) 1997-2000 Doug Rabson
325537Sdfr * All rights reserved.
425537Sdfr *
525537Sdfr * Redistribution and use in source and binary forms, with or without
625537Sdfr * modification, are permitted provided that the following conditions
725537Sdfr * are met:
825537Sdfr * 1. Redistributions of source code must retain the above copyright
925537Sdfr *    notice, this list of conditions and the following disclaimer.
1025537Sdfr * 2. Redistributions in binary form must reproduce the above copyright
1125537Sdfr *    notice, this list of conditions and the following disclaimer in the
1225537Sdfr *    documentation and/or other materials provided with the distribution.
1325537Sdfr *
1425537Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1525537Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1625537Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1725537Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1825537Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1925537Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2025537Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2125537Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2225537Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2325537Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2425537Sdfr * SUCH DAMAGE.
2525537Sdfr */
2625537Sdfr
27116182Sobrien#include <sys/cdefs.h>
28116182Sobrien__FBSDID("$FreeBSD: head/sys/kern/kern_linker.c 185895 2008-12-10 23:12:39Z zec $");
29116182Sobrien
3040159Speter#include "opt_ddb.h"
31157144Sjkoshy#include "opt_hwpmc_hooks.h"
32107089Srwatson#include "opt_mac.h"
3340159Speter
3425537Sdfr#include <sys/param.h>
3525537Sdfr#include <sys/kernel.h>
3625537Sdfr#include <sys/systm.h>
3725537Sdfr#include <sys/malloc.h>
3825537Sdfr#include <sys/sysproto.h>
3925537Sdfr#include <sys/sysent.h>
40164033Srwatson#include <sys/priv.h>
4125537Sdfr#include <sys/proc.h>
4225537Sdfr#include <sys/lock.h>
4382749Sdillon#include <sys/mutex.h>
4492547Sarr#include <sys/sx.h>
4525537Sdfr#include <sys/module.h>
46159808Sjhb#include <sys/mount.h>
4725537Sdfr#include <sys/linker.h>
4840159Speter#include <sys/fcntl.h>
4940159Speter#include <sys/libkern.h>
5040159Speter#include <sys/namei.h>
5140159Speter#include <sys/vnode.h>
52159588Sjhb#include <sys/syscallsubr.h>
5340159Speter#include <sys/sysctl.h>
54185895Szec#include <sys/vimage.h>
5525537Sdfr
56163606Srwatson#include <security/mac/mac_framework.h>
57163606Srwatson
5859603Sdfr#include "linker_if.h"
5959603Sdfr
60157144Sjkoshy#ifdef HWPMC_HOOKS
61157144Sjkoshy#include <sys/pmckern.h>
62157144Sjkoshy#endif
63157144Sjkoshy
6440961Speter#ifdef KLD_DEBUG
6540961Speterint kld_debug = 0;
6640961Speter#endif
6740961Speter
68160142Sjhb#define	KLD_LOCK()		sx_xlock(&kld_sx)
69160142Sjhb#define	KLD_UNLOCK()		sx_xunlock(&kld_sx)
70159845Sjhb#define	KLD_LOCKED()		sx_xlocked(&kld_sx)
71160142Sjhb#define	KLD_LOCK_ASSERT() do {						\
72160142Sjhb	if (!cold)							\
73160142Sjhb		sx_assert(&kld_sx, SX_XLOCKED);				\
74160142Sjhb} while (0)
75159845Sjhb
7691040Sarr/*
7791040Sarr * static char *linker_search_path(const char *name, struct mod_depend
7891040Sarr * *verinfo);
7991040Sarr */
8091040Sarrstatic const char 	*linker_basename(const char *path);
8159751Speter
82159800Sjhb/*
83159800Sjhb * Find a currently loaded file given its filename.
84159800Sjhb */
85159800Sjhbstatic linker_file_t linker_find_file_by_name(const char* _filename);
86159800Sjhb
87159800Sjhb/*
88159800Sjhb * Find a currently loaded file given its file id.
89159800Sjhb */
90159800Sjhbstatic linker_file_t linker_find_file_by_id(int _fileid);
91159800Sjhb
9278161Speter/* Metadata from the static kernel */
9378161SpeterSET_DECLARE(modmetadata_set, struct mod_metadata);
9478161Speter
9559751SpeterMALLOC_DEFINE(M_LINKER, "linker", "kernel linker");
9659751Speter
9740906Speterlinker_file_t linker_kernel_file;
9831324Sbde
99159845Sjhbstatic struct sx kld_sx;	/* kernel linker lock */
10098452Sarr
101172862Sjb/*
102172862Sjb * Load counter used by clients to determine if a linker file has been
103172862Sjb * re-loaded. This counter is incremented for each file load.
104172862Sjb */
105172862Sjbstatic int loadcnt;
106172862Sjb
10725537Sdfrstatic linker_class_list_t classes;
10850068Sgrogstatic linker_file_list_t linker_files;
10925537Sdfrstatic int next_file_id = 1;
11098452Sarrstatic int linker_no_more_classes = 0;
11125537Sdfr
11286553Sarr#define	LINKER_GET_NEXT_FILE_ID(a) do {					\
11391040Sarr	linker_file_t lftmp;						\
11486553Sarr									\
115159845Sjhb	KLD_LOCK_ASSERT();						\
11686553Sarrretry:									\
11791040Sarr	TAILQ_FOREACH(lftmp, &linker_files, link) {			\
11891040Sarr		if (next_file_id == lftmp->id) {			\
11991040Sarr			next_file_id++;					\
12091040Sarr			goto retry;					\
12191040Sarr		}							\
12291040Sarr	}								\
12391040Sarr	(a) = next_file_id;						\
12486553Sarr} while(0)
12586553Sarr
12686553Sarr
12759751Speter/* XXX wrong name; we're looking at version provision tags here, not modules */
12860938Sjaketypedef TAILQ_HEAD(, modlist) modlisthead_t;
12959751Speterstruct modlist {
13091040Sarr	TAILQ_ENTRY(modlist) link;	/* chain together all modules */
13191040Sarr	linker_file_t   container;
13291040Sarr	const char 	*name;
13391040Sarr	int             version;
13459751Speter};
13591040Sarrtypedef struct modlist *modlist_t;
13691040Sarrstatic modlisthead_t found_modules;
13759751Speter
138159796Sjhbstatic int	linker_file_add_dependency(linker_file_t file,
139159796Sjhb		    linker_file_t dep);
140159845Sjhbstatic caddr_t	linker_file_lookup_symbol_internal(linker_file_t file,
141159845Sjhb		    const char* name, int deps);
142159796Sjhbstatic int	linker_load_module(const char *kldname,
143159796Sjhb		    const char *modname, struct linker_file *parent,
144159796Sjhb		    struct mod_depend *verinfo, struct linker_file **lfpp);
145159796Sjhbstatic modlist_t modlist_lookup2(const char *name, struct mod_depend *verinfo);
14694321Sbrian
14759603Sdfrstatic char *
14859603Sdfrlinker_strdup(const char *str)
14959603Sdfr{
15091040Sarr	char *result;
15159603Sdfr
152111119Simp	if ((result = malloc((strlen(str) + 1), M_LINKER, M_WAITOK)) != NULL)
15391040Sarr		strcpy(result, str);
15491040Sarr	return (result);
15559603Sdfr}
15659603Sdfr
15725537Sdfrstatic void
15891040Sarrlinker_init(void *arg)
15925537Sdfr{
16091040Sarr
161159845Sjhb	sx_init(&kld_sx, "kernel linker");
16291040Sarr	TAILQ_INIT(&classes);
16391040Sarr	TAILQ_INIT(&linker_files);
16425537Sdfr}
16525537Sdfr
166177253SrwatsonSYSINIT(linker, SI_SUB_KLD, SI_ORDER_FIRST, linker_init, 0);
16725537Sdfr
16898452Sarrstatic void
16998452Sarrlinker_stop_class_add(void *arg)
17098452Sarr{
17198452Sarr
17298452Sarr	linker_no_more_classes = 1;
17398452Sarr}
17498452Sarr
175177253SrwatsonSYSINIT(linker_class, SI_SUB_KLD, SI_ORDER_ANY, linker_stop_class_add, NULL);
17698452Sarr
17725537Sdfrint
17859603Sdfrlinker_add_class(linker_class_t lc)
17925537Sdfr{
18091040Sarr
18198452Sarr	/*
182144443Sjhb	 * We disallow any class registration past SI_ORDER_ANY
183144443Sjhb	 * of SI_SUB_KLD.  We bump the reference count to keep the
184144443Sjhb	 * ops from being freed.
18598452Sarr	 */
18698452Sarr	if (linker_no_more_classes == 1)
18798452Sarr		return (EPERM);
18891040Sarr	kobj_class_compile((kobj_class_t) lc);
189144443Sjhb	((kobj_class_t)lc)->refs++;	/* XXX: kobj_mtx */
19091040Sarr	TAILQ_INSERT_TAIL(&classes, lc, link);
19191040Sarr	return (0);
19225537Sdfr}
19325537Sdfr
19425537Sdfrstatic void
19525537Sdfrlinker_file_sysinit(linker_file_t lf)
19625537Sdfr{
19791040Sarr	struct sysinit **start, **stop, **sipp, **xipp, *save;
19825537Sdfr
19991040Sarr	KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n",
20091040Sarr	    lf->filename));
20125537Sdfr
20291040Sarr	if (linker_file_lookup_set(lf, "sysinit_set", &start, &stop, NULL) != 0)
20391040Sarr		return;
20491040Sarr	/*
20591040Sarr	 * Perform a bubble sort of the system initialization objects by
20691040Sarr	 * their subsystem (primary key) and order (secondary key).
207159840Sjhb	 *
20891040Sarr	 * Since some things care about execution order, this is the operation
20991040Sarr	 * which ensures continued function.
21091040Sarr	 */
21191040Sarr	for (sipp = start; sipp < stop; sipp++) {
21291040Sarr		for (xipp = sipp + 1; xipp < stop; xipp++) {
21391040Sarr			if ((*sipp)->subsystem < (*xipp)->subsystem ||
21491040Sarr			    ((*sipp)->subsystem == (*xipp)->subsystem &&
21591040Sarr			    (*sipp)->order <= (*xipp)->order))
21691040Sarr				continue;	/* skip */
21791040Sarr			save = *sipp;
21891040Sarr			*sipp = *xipp;
21991040Sarr			*xipp = save;
22091040Sarr		}
22125537Sdfr	}
22225537Sdfr
22391040Sarr	/*
22491040Sarr	 * Traverse the (now) ordered list of system initialization tasks.
22591040Sarr	 * Perform each task, and continue on to the next task.
22691040Sarr	 */
227160142Sjhb	mtx_lock(&Giant);
22891040Sarr	for (sipp = start; sipp < stop; sipp++) {
22991040Sarr		if ((*sipp)->subsystem == SI_SUB_DUMMY)
23091040Sarr			continue;	/* skip dummy task(s) */
23125537Sdfr
23291040Sarr		/* Call function */
23391040Sarr		(*((*sipp)->func)) ((*sipp)->udata);
23491040Sarr	}
235160142Sjhb	mtx_unlock(&Giant);
23625537Sdfr}
23725537Sdfr
23841055Speterstatic void
23941055Speterlinker_file_sysuninit(linker_file_t lf)
24041055Speter{
24191040Sarr	struct sysinit **start, **stop, **sipp, **xipp, *save;
24241055Speter
24391040Sarr	KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n",
24491040Sarr	    lf->filename));
24541055Speter
24691068Sarr	if (linker_file_lookup_set(lf, "sysuninit_set", &start, &stop,
24791040Sarr	    NULL) != 0)
24891040Sarr		return;
24941055Speter
25091040Sarr	/*
25191040Sarr	 * Perform a reverse bubble sort of the system initialization objects
25291040Sarr	 * by their subsystem (primary key) and order (secondary key).
253159840Sjhb	 *
25491040Sarr	 * Since some things care about execution order, this is the operation
25591040Sarr	 * which ensures continued function.
25691040Sarr	 */
25791040Sarr	for (sipp = start; sipp < stop; sipp++) {
25891040Sarr		for (xipp = sipp + 1; xipp < stop; xipp++) {
25991040Sarr			if ((*sipp)->subsystem > (*xipp)->subsystem ||
26091040Sarr			    ((*sipp)->subsystem == (*xipp)->subsystem &&
26191040Sarr			    (*sipp)->order >= (*xipp)->order))
26291040Sarr				continue;	/* skip */
26391040Sarr			save = *sipp;
26491040Sarr			*sipp = *xipp;
26591040Sarr			*xipp = save;
26691040Sarr		}
26741055Speter	}
26841055Speter
26991040Sarr	/*
27091040Sarr	 * Traverse the (now) ordered list of system initialization tasks.
27191040Sarr	 * Perform each task, and continue on to the next task.
27291040Sarr	 */
273160142Sjhb	mtx_lock(&Giant);
27491040Sarr	for (sipp = start; sipp < stop; sipp++) {
27591040Sarr		if ((*sipp)->subsystem == SI_SUB_DUMMY)
27691040Sarr			continue;	/* skip dummy task(s) */
27741055Speter
27891040Sarr		/* Call function */
27991040Sarr		(*((*sipp)->func)) ((*sipp)->udata);
28091040Sarr	}
281160142Sjhb	mtx_unlock(&Giant);
28241055Speter}
28341055Speter
28444078Sdfrstatic void
28544078Sdfrlinker_file_register_sysctls(linker_file_t lf)
28644078Sdfr{
28791040Sarr	struct sysctl_oid **start, **stop, **oidp;
28844078Sdfr
28991040Sarr	KLD_DPF(FILE,
29091040Sarr	    ("linker_file_register_sysctls: registering SYSCTLs for %s\n",
29191040Sarr	    lf->filename));
29244078Sdfr
29391040Sarr	if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
29491040Sarr		return;
29544078Sdfr
296159845Sjhb	mtx_lock(&Giant);
29791040Sarr	for (oidp = start; oidp < stop; oidp++)
29891040Sarr		sysctl_register_oid(*oidp);
299159845Sjhb	mtx_unlock(&Giant);
30044078Sdfr}
30144078Sdfr
30244078Sdfrstatic void
30344078Sdfrlinker_file_unregister_sysctls(linker_file_t lf)
30444078Sdfr{
30591040Sarr	struct sysctl_oid **start, **stop, **oidp;
30644078Sdfr
30791040Sarr	KLD_DPF(FILE, ("linker_file_unregister_sysctls: registering SYSCTLs"
30891040Sarr	    " for %s\n", lf->filename));
30944078Sdfr
31091040Sarr	if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
31191040Sarr		return;
31244078Sdfr
313159845Sjhb	mtx_lock(&Giant);
31491040Sarr	for (oidp = start; oidp < stop; oidp++)
31591040Sarr		sysctl_unregister_oid(*oidp);
316159845Sjhb	mtx_unlock(&Giant);
31744078Sdfr}
31844078Sdfr
31959751Speterstatic int
32059751Speterlinker_file_register_modules(linker_file_t lf)
32159751Speter{
32291040Sarr	struct mod_metadata **start, **stop, **mdp;
32391040Sarr	const moduledata_t *moddata;
324146733Spjd	int first_error, error;
32559751Speter
32691040Sarr	KLD_DPF(FILE, ("linker_file_register_modules: registering modules"
32791040Sarr	    " in %s\n", lf->filename));
32859751Speter
32991068Sarr	if (linker_file_lookup_set(lf, "modmetadata_set", &start,
330159841Sjhb	    &stop, NULL) != 0) {
33191040Sarr		/*
33291040Sarr		 * This fallback should be unnecessary, but if we get booted
33391040Sarr		 * from boot2 instead of loader and we are missing our
33491040Sarr		 * metadata then we have to try the best we can.
33591040Sarr		 */
33691040Sarr		if (lf == linker_kernel_file) {
33791040Sarr			start = SET_BEGIN(modmetadata_set);
33891040Sarr			stop = SET_LIMIT(modmetadata_set);
33991040Sarr		} else
34091040Sarr			return (0);
34178161Speter	}
342146733Spjd	first_error = 0;
34391040Sarr	for (mdp = start; mdp < stop; mdp++) {
34491040Sarr		if ((*mdp)->md_type != MDT_MODULE)
34591040Sarr			continue;
34691040Sarr		moddata = (*mdp)->md_data;
34791040Sarr		KLD_DPF(FILE, ("Registering module %s in %s\n",
34891040Sarr		    moddata->name, lf->filename));
34991040Sarr		error = module_register(moddata, lf);
350146730Spjd		if (error) {
35191068Sarr			printf("Module %s failed to register: %d\n",
35291040Sarr			    moddata->name, error);
353146733Spjd			if (first_error == 0)
354146733Spjd				first_error = error;
355146730Spjd		}
35659751Speter	}
357146733Spjd	return (first_error);
35859751Speter}
35959751Speter
36059751Speterstatic void
36159751Speterlinker_init_kernel_modules(void)
36259751Speter{
36391040Sarr
36491040Sarr	linker_file_register_modules(linker_kernel_file);
36559751Speter}
36659751Speter
367177253SrwatsonSYSINIT(linker_kernel, SI_SUB_KLD, SI_ORDER_ANY, linker_init_kernel_modules,
368177253Srwatson    0);
36959751Speter
370101241Smuxstatic int
37191040Sarrlinker_load_file(const char *filename, linker_file_t *result)
37225537Sdfr{
37391040Sarr	linker_class_t lc;
37491040Sarr	linker_file_t lf;
375159585Sjhb	int foundfile, error;
37625537Sdfr
37791040Sarr	/* Refuse to load modules if securelevel raised */
37891040Sarr	if (securelevel > 0)
37991040Sarr		return (EPERM);
38062261Sarchie
381159845Sjhb	KLD_LOCK_ASSERT();
38291040Sarr	lf = linker_find_file_by_name(filename);
38391040Sarr	if (lf) {
38491040Sarr		KLD_DPF(FILE, ("linker_load_file: file %s is already loaded,"
38591040Sarr		    " incrementing refs\n", filename));
38691040Sarr		*result = lf;
38791040Sarr		lf->refs++;
388159585Sjhb		return (0);
38991040Sarr	}
39091040Sarr	foundfile = 0;
391159585Sjhb	error = 0;
39298452Sarr
39398452Sarr	/*
39498452Sarr	 * We do not need to protect (lock) classes here because there is
39598452Sarr	 * no class registration past startup (SI_SUB_KLD, SI_ORDER_ANY)
39698452Sarr	 * and there is no class deregistration mechanism at this time.
39798452Sarr	 */
39891040Sarr	TAILQ_FOREACH(lc, &classes, link) {
39991040Sarr		KLD_DPF(FILE, ("linker_load_file: trying to load %s\n",
40091040Sarr		    filename));
40191040Sarr		error = LINKER_LOAD_FILE(lc, filename, &lf);
40291040Sarr		/*
40391040Sarr		 * If we got something other than ENOENT, then it exists but
40491040Sarr		 * we cannot load it for some other reason.
40591040Sarr		 */
40691040Sarr		if (error != ENOENT)
40791040Sarr			foundfile = 1;
40891040Sarr		if (lf) {
409146730Spjd			error = linker_file_register_modules(lf);
410146730Spjd			if (error == EEXIST) {
411146730Spjd				linker_file_unload(lf, LINKER_UNLOAD_FORCE);
412159585Sjhb				return (error);
413146730Spjd			}
414166921Sjhb			KLD_UNLOCK();
41591040Sarr			linker_file_register_sysctls(lf);
41691040Sarr			linker_file_sysinit(lf);
417166921Sjhb			KLD_LOCK();
41891040Sarr			lf->flags |= LINKER_FILE_LINKED;
41991040Sarr			*result = lf;
420159585Sjhb			return (0);
42191040Sarr		}
42291040Sarr	}
42342755Speter	/*
42491040Sarr	 * Less than ideal, but tells the user whether it failed to load or
42591040Sarr	 * the module was not found.
42642755Speter	 */
427105337Ssam	if (foundfile) {
428105337Ssam		/*
429105337Ssam		 * Format not recognized or otherwise unloadable.
430105337Ssam		 * When loading a module that is statically built into
431105337Ssam		 * the kernel EEXIST percolates back up as the return
432105337Ssam		 * value.  Preserve this so that apps like sysinstall
433105337Ssam		 * can recognize this special case and not post bogus
434105337Ssam		 * dialog boxes.
435105337Ssam		 */
436105337Ssam		if (error != EEXIST)
437105337Ssam			error = ENOEXEC;
438105337Ssam	} else
43991068Sarr		error = ENOENT;		/* Nothing found */
44091040Sarr	return (error);
44125537Sdfr}
44225537Sdfr
44378413Sbrianint
44494321Sbrianlinker_reference_module(const char *modname, struct mod_depend *verinfo,
44594321Sbrian    linker_file_t *result)
44678413Sbrian{
44794321Sbrian	modlist_t mod;
448159804Sjhb	int error;
44994321Sbrian
450159845Sjhb	KLD_LOCK();
45194321Sbrian	if ((mod = modlist_lookup2(modname, verinfo)) != NULL) {
45294321Sbrian		*result = mod->container;
45394321Sbrian		(*result)->refs++;
454159845Sjhb		KLD_UNLOCK();
45594321Sbrian		return (0);
45694321Sbrian	}
45794321Sbrian
458159804Sjhb	error = linker_load_module(NULL, modname, NULL, verinfo, result);
459159845Sjhb	KLD_UNLOCK();
460159804Sjhb	return (error);
46178413Sbrian}
46278413Sbrian
463159804Sjhbint
464159804Sjhblinker_release_module(const char *modname, struct mod_depend *verinfo,
465159804Sjhb    linker_file_t lf)
466159804Sjhb{
467159804Sjhb	modlist_t mod;
468159804Sjhb	int error;
469159804Sjhb
470159845Sjhb	KLD_LOCK();
471159804Sjhb	if (lf == NULL) {
472159804Sjhb		KASSERT(modname != NULL,
473159804Sjhb		    ("linker_release_module: no file or name"));
474159804Sjhb		mod = modlist_lookup2(modname, verinfo);
475159804Sjhb		if (mod == NULL) {
476159845Sjhb			KLD_UNLOCK();
477159804Sjhb			return (ESRCH);
478159804Sjhb		}
479159804Sjhb		lf = mod->container;
480159804Sjhb	} else
481159804Sjhb		KASSERT(modname == NULL && verinfo == NULL,
482159804Sjhb		    ("linker_release_module: both file and name"));
483159804Sjhb	error =	linker_file_unload(lf, LINKER_UNLOAD_NORMAL);
484159845Sjhb	KLD_UNLOCK();
485159804Sjhb	return (error);
486159804Sjhb}
487159804Sjhb
488159800Sjhbstatic linker_file_t
48991040Sarrlinker_find_file_by_name(const char *filename)
49025537Sdfr{
491159585Sjhb	linker_file_t lf;
49291040Sarr	char *koname;
49325537Sdfr
494111119Simp	koname = malloc(strlen(filename) + 4, M_LINKER, M_WAITOK);
49591040Sarr	sprintf(koname, "%s.ko", filename);
49640861Speter
497159845Sjhb	KLD_LOCK_ASSERT();
49891040Sarr	TAILQ_FOREACH(lf, &linker_files, link) {
49992032Sdwmalone		if (strcmp(lf->filename, koname) == 0)
50091040Sarr			break;
50192032Sdwmalone		if (strcmp(lf->filename, filename) == 0)
50291040Sarr			break;
50391040Sarr	}
504159585Sjhb	free(koname, M_LINKER);
50591040Sarr	return (lf);
50625537Sdfr}
50725537Sdfr
508159800Sjhbstatic linker_file_t
50925537Sdfrlinker_find_file_by_id(int fileid)
51025537Sdfr{
511159585Sjhb	linker_file_t lf;
512159845Sjhb
513159845Sjhb	KLD_LOCK_ASSERT();
51491040Sarr	TAILQ_FOREACH(lf, &linker_files, link)
515166921Sjhb		if (lf->id == fileid && lf->flags & LINKER_FILE_LINKED)
51691040Sarr			break;
51791040Sarr	return (lf);
51825537Sdfr}
51925537Sdfr
520159797Sjhbint
521159797Sjhblinker_file_foreach(linker_predicate_t *predicate, void *context)
522159797Sjhb{
523159797Sjhb	linker_file_t lf;
524159797Sjhb	int retval = 0;
525159797Sjhb
526159845Sjhb	KLD_LOCK();
527159797Sjhb	TAILQ_FOREACH(lf, &linker_files, link) {
528159797Sjhb		retval = predicate(lf, context);
529159797Sjhb		if (retval != 0)
530159797Sjhb			break;
531159797Sjhb	}
532159845Sjhb	KLD_UNLOCK();
533159797Sjhb	return (retval);
534159797Sjhb}
535159797Sjhb
53625537Sdfrlinker_file_t
53791040Sarrlinker_make_file(const char *pathname, linker_class_t lc)
53825537Sdfr{
53991040Sarr	linker_file_t lf;
54091040Sarr	const char *filename;
54125537Sdfr
542159845Sjhb	KLD_LOCK_ASSERT();
54391040Sarr	filename = linker_basename(pathname);
54440159Speter
545172862Sjb	KLD_DPF(FILE, ("linker_make_file: new file, filename='%s' for pathname='%s'\n", filename, pathname));
546111119Simp	lf = (linker_file_t)kobj_create((kobj_class_t)lc, M_LINKER, M_WAITOK);
54791040Sarr	if (lf == NULL)
548159585Sjhb		return (NULL);
54991040Sarr	lf->refs = 1;
55091040Sarr	lf->userrefs = 0;
55191040Sarr	lf->flags = 0;
55291040Sarr	lf->filename = linker_strdup(filename);
553172862Sjb	lf->pathname = linker_strdup(pathname);
55491040Sarr	LINKER_GET_NEXT_FILE_ID(lf->id);
55591040Sarr	lf->ndeps = 0;
55691040Sarr	lf->deps = NULL;
557172862Sjb	lf->loadcnt = ++loadcnt;
558172862Sjb	lf->sdt_probes = NULL;
559172862Sjb	lf->sdt_nprobes = 0;
56091040Sarr	STAILQ_INIT(&lf->common);
56191040Sarr	TAILQ_INIT(&lf->modules);
56291040Sarr	TAILQ_INSERT_TAIL(&linker_files, lf, link);
56391040Sarr	return (lf);
56425537Sdfr}
56525537Sdfr
56625537Sdfrint
567132117Sphklinker_file_unload(linker_file_t file, int flags)
56825537Sdfr{
56991040Sarr	module_t mod, next;
57091040Sarr	modlist_t ml, nextml;
57191040Sarr	struct common_symbol *cp;
57291040Sarr	int error, i;
57325537Sdfr
57491040Sarr	/* Refuse to unload modules if securelevel raised. */
57591040Sarr	if (securelevel > 0)
57691040Sarr		return (EPERM);
57725537Sdfr
578159845Sjhb	KLD_LOCK_ASSERT();
57991040Sarr	KLD_DPF(FILE, ("linker_file_unload: lf->refs=%d\n", file->refs));
58091040Sarr
581159584Sjhb	/* Easy case of just dropping a reference. */
582159584Sjhb	if (file->refs > 1) {
583159584Sjhb		file->refs--;
584159584Sjhb		return (0);
585159584Sjhb	}
586159584Sjhb
587159584Sjhb	KLD_DPF(FILE, ("linker_file_unload: file is unloading,"
588159584Sjhb	    " informing modules\n"));
589159584Sjhb
590159584Sjhb	/*
591185635Sjhb	 * Quiesce all the modules to give them a chance to veto the unload.
592159584Sjhb	 */
593185635Sjhb	MOD_SLOCK;
594185635Sjhb	for (mod = TAILQ_FIRST(&file->modules); mod;
595185635Sjhb	     mod = module_getfnext(mod)) {
596185635Sjhb
597185635Sjhb		error = module_quiesce(mod);
598185635Sjhb		if (error != 0 && flags != LINKER_UNLOAD_FORCE) {
599185635Sjhb			KLD_DPF(FILE, ("linker_file_unload: module %s"
600185635Sjhb			    " vetoed unload\n", module_getname(mod)));
601185635Sjhb			/*
602185635Sjhb			 * XXX: Do we need to tell all the quiesced modules
603185635Sjhb			 * that they can resume work now via a new module
604185635Sjhb			 * event?
605185635Sjhb			 */
606185635Sjhb			MOD_SUNLOCK;
607185635Sjhb			return (error);
608185635Sjhb		}
609185635Sjhb	}
610185635Sjhb	MOD_SUNLOCK;
611185635Sjhb
612185635Sjhb	/*
613185635Sjhb	 * Inform any modules associated with this file that they are
614185635Sjhb	 * being be unloaded.
615185635Sjhb	 */
616159584Sjhb	MOD_XLOCK;
617159584Sjhb	for (mod = TAILQ_FIRST(&file->modules); mod; mod = next) {
618159584Sjhb		next = module_getfnext(mod);
619159584Sjhb		MOD_XUNLOCK;
620159584Sjhb
62191040Sarr		/*
622159584Sjhb		 * Give the module a chance to veto the unload.
62391040Sarr		 */
624185635Sjhb		if ((error = module_unload(mod)) != 0) {
625185635Sjhb			KLD_DPF(FILE, ("linker_file_unload: module %s"
626185635Sjhb			    " failed unload\n", mod));
627159584Sjhb			return (error);
628159584Sjhb		}
62992547Sarr		MOD_XLOCK;
630159584Sjhb		module_release(mod);
631159584Sjhb	}
632159584Sjhb	MOD_XUNLOCK;
63391040Sarr
634159586Sjhb	TAILQ_FOREACH_SAFE(ml, &found_modules, link, nextml) {
635128057Speadar		if (ml->container == file) {
63691040Sarr			TAILQ_REMOVE(&found_modules, ml, link);
637128057Speadar			free(ml, M_LINKER);
638128057Speadar		}
63991040Sarr	}
64025537Sdfr
641159840Sjhb	/*
642159840Sjhb	 * Don't try to run SYSUNINITs if we are unloaded due to a
64391040Sarr	 * link error.
64491040Sarr	 */
64591040Sarr	if (file->flags & LINKER_FILE_LINKED) {
64691040Sarr		linker_file_sysuninit(file);
64791040Sarr		linker_file_unregister_sysctls(file);
64825537Sdfr	}
64991040Sarr	TAILQ_REMOVE(&linker_files, file, link);
65025537Sdfr
65191040Sarr	if (file->deps) {
65291040Sarr		for (i = 0; i < file->ndeps; i++)
653132117Sphk			linker_file_unload(file->deps[i], flags);
65491040Sarr		free(file->deps, M_LINKER);
65591040Sarr		file->deps = NULL;
65659751Speter	}
657160245Sjhb	while ((cp = STAILQ_FIRST(&file->common)) != NULL) {
658160245Sjhb		STAILQ_REMOVE_HEAD(&file->common, link);
65991040Sarr		free(cp, M_LINKER);
66091040Sarr	}
66159751Speter
66291040Sarr	LINKER_UNLOAD(file);
66391040Sarr	if (file->filename) {
66491040Sarr		free(file->filename, M_LINKER);
66591040Sarr		file->filename = NULL;
66691040Sarr	}
667172862Sjb	if (file->pathname) {
668172862Sjb		free(file->pathname, M_LINKER);
669172862Sjb		file->pathname = NULL;
670172862Sjb	}
67191040Sarr	kobj_delete((kobj_t) file, M_LINKER);
672159584Sjhb	return (0);
67325537Sdfr}
67425537Sdfr
675179238Sjbint
676179238Sjblinker_ctf_get(linker_file_t file, linker_ctf_t *lc)
677179238Sjb{
678179238Sjb	return (LINKER_CTF_GET(file, lc));
679179238Sjb}
680179238Sjb
681159796Sjhbstatic int
68286469Siedowselinker_file_add_dependency(linker_file_t file, linker_file_t dep)
68325537Sdfr{
68491040Sarr	linker_file_t *newdeps;
68525537Sdfr
686159845Sjhb	KLD_LOCK_ASSERT();
68791040Sarr	newdeps = malloc((file->ndeps + 1) * sizeof(linker_file_t *),
688111119Simp	    M_LINKER, M_WAITOK | M_ZERO);
68991040Sarr	if (newdeps == NULL)
69091040Sarr		return (ENOMEM);
69125537Sdfr
69291040Sarr	if (file->deps) {
69391040Sarr		bcopy(file->deps, newdeps,
69491040Sarr		    file->ndeps * sizeof(linker_file_t *));
69591040Sarr		free(file->deps, M_LINKER);
69691040Sarr	}
69791040Sarr	file->deps = newdeps;
69891040Sarr	file->deps[file->ndeps] = dep;
69991040Sarr	file->ndeps++;
70091040Sarr	return (0);
70125537Sdfr}
70225537Sdfr
70378161Speter/*
70491040Sarr * Locate a linker set and its contents.  This is a helper function to avoid
705159841Sjhb * linker_if.h exposure elsewhere.  Note: firstp and lastp are really void **.
706159841Sjhb * This function is used in this file so we can avoid having lots of (void **)
707159841Sjhb * casts.
70878161Speter */
70978161Speterint
71078161Speterlinker_file_lookup_set(linker_file_t file, const char *name,
71191040Sarr    void *firstp, void *lastp, int *countp)
71278161Speter{
713159845Sjhb	int error, locked;
71478161Speter
715159845Sjhb	locked = KLD_LOCKED();
716159845Sjhb	if (!locked)
717159845Sjhb		KLD_LOCK();
718159845Sjhb	error = LINKER_LOOKUP_SET(file, name, firstp, lastp, countp);
719159845Sjhb	if (!locked)
720159845Sjhb		KLD_UNLOCK();
721159845Sjhb	return (error);
72278161Speter}
72378161Speter
724173714Sjb/*
725173714Sjb * List all functions in a file.
726173714Sjb */
727173714Sjbint
728173714Sjblinker_file_function_listall(linker_file_t lf,
729179238Sjb    linker_function_nameval_callback_t callback_func, void *arg)
730173714Sjb{
731173714Sjb	return (LINKER_EACH_FUNCTION_NAMEVAL(lf, callback_func, arg));
732173714Sjb}
733173714Sjb
73425537Sdfrcaddr_t
73591040Sarrlinker_file_lookup_symbol(linker_file_t file, const char *name, int deps)
73625537Sdfr{
737159845Sjhb	caddr_t sym;
738159845Sjhb	int locked;
739159845Sjhb
740159845Sjhb	locked = KLD_LOCKED();
741159845Sjhb	if (!locked)
742159845Sjhb		KLD_LOCK();
743159845Sjhb	sym = linker_file_lookup_symbol_internal(file, name, deps);
744159845Sjhb	if (!locked)
745159845Sjhb		KLD_UNLOCK();
746159845Sjhb	return (sym);
747159845Sjhb}
748159845Sjhb
749159845Sjhbstatic caddr_t
750159845Sjhblinker_file_lookup_symbol_internal(linker_file_t file, const char *name,
751159845Sjhb    int deps)
752159845Sjhb{
75391040Sarr	c_linker_sym_t sym;
75491040Sarr	linker_symval_t symval;
75591040Sarr	caddr_t address;
75691040Sarr	size_t common_size = 0;
75792032Sdwmalone	int i;
75825537Sdfr
759159845Sjhb	KLD_LOCK_ASSERT();
760109605Sjake	KLD_DPF(SYM, ("linker_file_lookup_symbol: file=%p, name=%s, deps=%d\n",
76191040Sarr	    file, name, deps));
76225537Sdfr
76391040Sarr	if (LINKER_LOOKUP_SYMBOL(file, name, &sym) == 0) {
76491040Sarr		LINKER_SYMBOL_VALUES(file, sym, &symval);
76591040Sarr		if (symval.value == 0)
76691040Sarr			/*
76791040Sarr			 * For commons, first look them up in the
76891040Sarr			 * dependencies and only allocate space if not found
76991040Sarr			 * there.
77091040Sarr			 */
77191040Sarr			common_size = symval.size;
77291040Sarr		else {
77391040Sarr			KLD_DPF(SYM, ("linker_file_lookup_symbol: symbol"
774109605Sjake			    ".value=%p\n", symval.value));
77591040Sarr			return (symval.value);
77691040Sarr		}
77740159Speter	}
77891040Sarr	if (deps) {
77991040Sarr		for (i = 0; i < file->ndeps; i++) {
780159845Sjhb			address = linker_file_lookup_symbol_internal(
781159845Sjhb			    file->deps[i], name, 0);
78291040Sarr			if (address) {
78391040Sarr				KLD_DPF(SYM, ("linker_file_lookup_symbol:"
784109605Sjake				    " deps value=%p\n", address));
78591040Sarr				return (address);
78691040Sarr			}
78791040Sarr		}
78825537Sdfr	}
78991040Sarr	if (common_size > 0) {
79091040Sarr		/*
79191040Sarr		 * This is a common symbol which was not found in the
79291040Sarr		 * dependencies.  We maintain a simple common symbol table in
79391040Sarr		 * the file object.
79491040Sarr		 */
79591040Sarr		struct common_symbol *cp;
79642849Speter
79791040Sarr		STAILQ_FOREACH(cp, &file->common, link) {
79892032Sdwmalone			if (strcmp(cp->name, name) == 0) {
79991040Sarr				KLD_DPF(SYM, ("linker_file_lookup_symbol:"
800109605Sjake				    " old common value=%p\n", cp->address));
80191040Sarr				return (cp->address);
80291040Sarr			}
80391040Sarr		}
80491040Sarr		/*
80591040Sarr		 * Round the symbol size up to align.
80691040Sarr		 */
80791040Sarr		common_size = (common_size + sizeof(int) - 1) & -sizeof(int);
80891040Sarr		cp = malloc(sizeof(struct common_symbol)
80991040Sarr		    + common_size + strlen(name) + 1, M_LINKER,
810111119Simp		    M_WAITOK | M_ZERO);
81191040Sarr		cp->address = (caddr_t)(cp + 1);
81291040Sarr		cp->name = cp->address + common_size;
81391040Sarr		strcpy(cp->name, name);
81491040Sarr		bzero(cp->address, common_size);
81591040Sarr		STAILQ_INSERT_TAIL(&file->common, cp, link);
81625537Sdfr
81791040Sarr		KLD_DPF(SYM, ("linker_file_lookup_symbol: new common"
818109605Sjake		    " value=%p\n", cp->address));
81991040Sarr		return (cp->address);
82040159Speter	}
82191040Sarr	KLD_DPF(SYM, ("linker_file_lookup_symbol: fail\n"));
82291040Sarr	return (0);
82325537Sdfr}
82425537Sdfr
82525537Sdfr/*
826174132Srwatson * Both DDB and stack(9) rely on the kernel linker to provide forward and
827174132Srwatson * backward lookup of symbols.  However, DDB and sometimes stack(9) need to
828174132Srwatson * do this in a lockfree manner.  We provide a set of internal helper
829174132Srwatson * routines to perform these operations without locks, and then wrappers that
830174132Srwatson * optionally lock.
831159840Sjhb *
832174132Srwatson * linker_debug_lookup() is ifdef DDB as currently it's only used by DDB.
83340159Speter */
834174132Srwatson#ifdef DDB
835174132Srwatsonstatic int
836174132Srwatsonlinker_debug_lookup(const char *symstr, c_linker_sym_t *sym)
83740159Speter{
83891040Sarr	linker_file_t lf;
83940159Speter
84091040Sarr	TAILQ_FOREACH(lf, &linker_files, link) {
84191040Sarr		if (LINKER_LOOKUP_SYMBOL(lf, symstr, sym) == 0)
84291040Sarr			return (0);
84391040Sarr	}
84491040Sarr	return (ENOENT);
84540159Speter}
846174132Srwatson#endif
84740159Speter
848174132Srwatsonstatic int
849174132Srwatsonlinker_debug_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp)
85040159Speter{
85191040Sarr	linker_file_t lf;
85291040Sarr	c_linker_sym_t best, es;
85391040Sarr	u_long diff, bestdiff, off;
85440159Speter
85591040Sarr	best = 0;
85691040Sarr	off = (uintptr_t)value;
85791040Sarr	bestdiff = off;
85891040Sarr	TAILQ_FOREACH(lf, &linker_files, link) {
85991040Sarr		if (LINKER_SEARCH_SYMBOL(lf, value, &es, &diff) != 0)
86091040Sarr			continue;
86191040Sarr		if (es != 0 && diff < bestdiff) {
86291040Sarr			best = es;
86391040Sarr			bestdiff = diff;
86491040Sarr		}
86591040Sarr		if (bestdiff == 0)
86691040Sarr			break;
86740159Speter	}
86891040Sarr	if (best) {
86991040Sarr		*sym = best;
87091040Sarr		*diffp = bestdiff;
87191040Sarr		return (0);
87291040Sarr	} else {
87391040Sarr		*sym = 0;
87491040Sarr		*diffp = off;
87591040Sarr		return (ENOENT);
87691040Sarr	}
87740159Speter}
87840159Speter
879174132Srwatsonstatic int
880174132Srwatsonlinker_debug_symbol_values(c_linker_sym_t sym, linker_symval_t *symval)
88140159Speter{
88291040Sarr	linker_file_t lf;
88340159Speter
88491040Sarr	TAILQ_FOREACH(lf, &linker_files, link) {
88591040Sarr		if (LINKER_SYMBOL_VALUES(lf, sym, symval) == 0)
88691040Sarr			return (0);
88791040Sarr	}
88891040Sarr	return (ENOENT);
88940159Speter}
890174132Srwatson
891174132Srwatsonstatic int
892174132Srwatsonlinker_debug_search_symbol_name(caddr_t value, char *buf, u_int buflen,
893174132Srwatson    long *offset)
894174132Srwatson{
895174132Srwatson	linker_symval_t symval;
896174132Srwatson	c_linker_sym_t sym;
897174132Srwatson	int error;
898174132Srwatson
899174132Srwatson	*offset = 0;
900174132Srwatson	error = linker_debug_search_symbol(value, &sym, offset);
901174132Srwatson	if (error)
902174132Srwatson		return (error);
903174132Srwatson	error = linker_debug_symbol_values(sym, &symval);
904174132Srwatson	if (error)
905174132Srwatson		return (error);
906174132Srwatson	strlcpy(buf, symval.name, buflen);
907174132Srwatson	return (0);
908174132Srwatson}
909174132Srwatson
910174132Srwatson#ifdef DDB
911174132Srwatson/*
912174132Srwatson * DDB Helpers.  DDB has to look across multiple files with their own symbol
913174132Srwatson * tables and string tables.
914174132Srwatson *
915174132Srwatson * Note that we do not obey list locking protocols here.  We really don't need
916174132Srwatson * DDB to hang because somebody's got the lock held.  We'll take the chance
917174132Srwatson * that the files list is inconsistant instead.
918174132Srwatson */
919174132Srwatsonint
920174132Srwatsonlinker_ddb_lookup(const char *symstr, c_linker_sym_t *sym)
921174132Srwatson{
922174132Srwatson
923174132Srwatson	return (linker_debug_lookup(symstr, sym));
924174132Srwatson}
925174132Srwatson
926174132Srwatsonint
927174132Srwatsonlinker_ddb_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp)
928174132Srwatson{
929174132Srwatson
930174132Srwatson	return (linker_debug_search_symbol(value, sym, diffp));
931174132Srwatson}
932174132Srwatson
933174132Srwatsonint
934174132Srwatsonlinker_ddb_symbol_values(c_linker_sym_t sym, linker_symval_t *symval)
935174132Srwatson{
936174132Srwatson
937174132Srwatson	return (linker_debug_symbol_values(sym, symval));
938174132Srwatson}
939174132Srwatson
940174132Srwatsonint
941174132Srwatsonlinker_ddb_search_symbol_name(caddr_t value, char *buf, u_int buflen,
942174132Srwatson    long *offset)
943174132Srwatson{
944174132Srwatson
945174132Srwatson	return (linker_debug_search_symbol_name(value, buf, buflen, offset));
946174132Srwatson}
94740159Speter#endif
94840159Speter
94940159Speter/*
950174132Srwatson * stack(9) helper for non-debugging environemnts.  Unlike DDB helpers, we do
951174132Srwatson * obey locking protocols, and offer a significantly less complex interface.
952174132Srwatson */
953174132Srwatsonint
954174132Srwatsonlinker_search_symbol_name(caddr_t value, char *buf, u_int buflen,
955174132Srwatson    long *offset)
956174132Srwatson{
957178380Spjd	int error;
958174132Srwatson
959178380Spjd	KLD_LOCK();
960174132Srwatson	error = linker_debug_search_symbol_name(value, buf, buflen, offset);
961178380Spjd	KLD_UNLOCK();
962174132Srwatson	return (error);
963174132Srwatson}
964174132Srwatson
965174132Srwatson/*
96625537Sdfr * Syscalls.
96725537Sdfr */
96825537Sdfrint
969159588Sjhbkern_kldload(struct thread *td, const char *file, int *fileid)
97025537Sdfr{
971157144Sjkoshy#ifdef HWPMC_HOOKS
972157144Sjkoshy	struct pmckern_map_in pkm;
973157144Sjkoshy#endif
974159588Sjhb	const char *kldname, *modname;
97591040Sarr	linker_file_t lf;
976159588Sjhb	int error;
97725537Sdfr
97893159Sarr	if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
979159588Sjhb		return (error);
98093159Sarr
981164033Srwatson	if ((error = priv_check(td, PRIV_KLD_LOAD)) != 0)
982159588Sjhb		return (error);
98325537Sdfr
98491040Sarr	/*
985159841Sjhb	 * If file does not contain a qualified name or any dot in it
986159841Sjhb	 * (kldname.ko, or kldname.ver.ko) treat it as an interface
98791040Sarr	 * name.
98891040Sarr	 */
989159588Sjhb	if (index(file, '/') || index(file, '.')) {
990159588Sjhb		kldname = file;
99191040Sarr		modname = NULL;
99291040Sarr	} else {
99391040Sarr		kldname = NULL;
994159588Sjhb		modname = file;
99591040Sarr	}
996159588Sjhb
997159845Sjhb	KLD_LOCK();
99891040Sarr	error = linker_load_module(kldname, modname, NULL, NULL, &lf);
99991040Sarr	if (error)
1000159588Sjhb		goto unlock;
1001157144Sjkoshy#ifdef HWPMC_HOOKS
1002157144Sjkoshy	pkm.pm_file = lf->filename;
1003157144Sjkoshy	pkm.pm_address = (uintptr_t) lf->address;
1004157144Sjkoshy	PMC_CALL_HOOK(td, PMC_FN_KLD_LOAD, (void *) &pkm);
1005157144Sjkoshy#endif
100691040Sarr	lf->userrefs++;
1007159588Sjhb	if (fileid != NULL)
1008159588Sjhb		*fileid = lf->id;
1009159588Sjhbunlock:
1010159845Sjhb	KLD_UNLOCK();
101191040Sarr	return (error);
101225537Sdfr}
101325537Sdfr
1014159588Sjhbint
1015159588Sjhbkldload(struct thread *td, struct kldload_args *uap)
1016159588Sjhb{
1017159588Sjhb	char *pathname = NULL;
1018159596Smarcel	int error, fileid;
1019159588Sjhb
1020159588Sjhb	td->td_retval[0] = -1;
1021159588Sjhb
1022159588Sjhb	pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
1023159588Sjhb	error = copyinstr(uap->file, pathname, MAXPATHLEN, NULL);
1024159596Smarcel	if (error == 0) {
1025159596Smarcel		error = kern_kldload(td, pathname, &fileid);
1026159596Smarcel		if (error == 0)
1027159596Smarcel			td->td_retval[0] = fileid;
1028159596Smarcel	}
1029159588Sjhb	free(pathname, M_TEMP);
1030159588Sjhb	return (error);
1031159588Sjhb}
1032159588Sjhb
1033159588Sjhbint
1034132117Sphkkern_kldunload(struct thread *td, int fileid, int flags)
103525537Sdfr{
1036157144Sjkoshy#ifdef HWPMC_HOOKS
1037157144Sjkoshy	struct pmckern_map_out pkm;
1038157144Sjkoshy#endif
103991040Sarr	linker_file_t lf;
104091040Sarr	int error = 0;
104125537Sdfr
104293159Sarr	if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
1043159588Sjhb		return (error);
104493159Sarr
1045164033Srwatson	if ((error = priv_check(td, PRIV_KLD_UNLOAD)) != 0)
1046159588Sjhb		return (error);
104725537Sdfr
1048159845Sjhb	KLD_LOCK();
1049132117Sphk	lf = linker_find_file_by_id(fileid);
105091040Sarr	if (lf) {
105191040Sarr		KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs));
1052172862Sjb
1053172862Sjb		/* Check if there are DTrace probes enabled on this file. */
1054172862Sjb		if (lf->nenabled > 0) {
1055172862Sjb			printf("kldunload: attempt to unload file that has"
1056172862Sjb			    " DTrace probes enabled\n");
1057172862Sjb			error = EBUSY;
1058172862Sjb		} else if (lf->userrefs == 0) {
1059132117Sphk			/*
1060132117Sphk			 * XXX: maybe LINKER_UNLOAD_FORCE should override ?
1061132117Sphk			 */
106291040Sarr			printf("kldunload: attempt to unload file that was"
106391040Sarr			    " loaded by the kernel\n");
1064159840Sjhb			error = EBUSY;
1065159588Sjhb		} else {
1066157144Sjkoshy#ifdef HWPMC_HOOKS
1067159588Sjhb			/* Save data needed by hwpmc(4) before unloading. */
1068159588Sjhb			pkm.pm_address = (uintptr_t) lf->address;
1069159588Sjhb			pkm.pm_size = lf->size;
1070157144Sjkoshy#endif
1071159588Sjhb			lf->userrefs--;
1072159588Sjhb			error = linker_file_unload(lf, flags);
1073159588Sjhb			if (error)
1074159588Sjhb				lf->userrefs++;
1075159588Sjhb		}
107691040Sarr	} else
107791040Sarr		error = ENOENT;
1078157144Sjkoshy
1079157144Sjkoshy#ifdef HWPMC_HOOKS
1080157144Sjkoshy	if (error == 0)
1081157144Sjkoshy		PMC_CALL_HOOK(td, PMC_FN_KLD_UNLOAD, (void *) &pkm);
1082157144Sjkoshy#endif
1083159845Sjhb	KLD_UNLOCK();
108491068Sarr	return (error);
108525537Sdfr}
108625537Sdfr
108725537Sdfrint
1088132117Sphkkldunload(struct thread *td, struct kldunload_args *uap)
1089132117Sphk{
1090132117Sphk
1091132117Sphk	return (kern_kldunload(td, uap->fileid, LINKER_UNLOAD_NORMAL));
1092132117Sphk}
1093132117Sphk
1094132117Sphkint
1095132117Sphkkldunloadf(struct thread *td, struct kldunloadf_args *uap)
1096132117Sphk{
1097132117Sphk
1098132117Sphk	if (uap->flags != LINKER_UNLOAD_NORMAL &&
1099132117Sphk	    uap->flags != LINKER_UNLOAD_FORCE)
1100132117Sphk		return (EINVAL);
1101132117Sphk	return (kern_kldunload(td, uap->fileid, uap->flags));
1102132117Sphk}
1103132117Sphk
1104132117Sphkint
110591040Sarrkldfind(struct thread *td, struct kldfind_args *uap)
110625537Sdfr{
110791040Sarr	char *pathname;
110891040Sarr	const char *filename;
110991040Sarr	linker_file_t lf;
1110159791Sjhb	int error;
111125537Sdfr
1112107089Srwatson#ifdef MAC
1113172930Srwatson	error = mac_kld_check_stat(td->td_ucred);
1114107089Srwatson	if (error)
1115107089Srwatson		return (error);
1116107089Srwatson#endif
1117107089Srwatson
111891040Sarr	td->td_retval[0] = -1;
111982749Sdillon
1120111119Simp	pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
1121107855Salfred	if ((error = copyinstr(uap->file, pathname, MAXPATHLEN, NULL)) != 0)
112291040Sarr		goto out;
112325537Sdfr
112491040Sarr	filename = linker_basename(pathname);
1125159845Sjhb	KLD_LOCK();
112691040Sarr	lf = linker_find_file_by_name(filename);
112791040Sarr	if (lf)
112891040Sarr		td->td_retval[0] = lf->id;
112991040Sarr	else
113091040Sarr		error = ENOENT;
1131159845Sjhb	KLD_UNLOCK();
113225537Sdfrout:
1133159791Sjhb	free(pathname, M_TEMP);
113491040Sarr	return (error);
113525537Sdfr}
113625537Sdfr
113725537Sdfrint
113891040Sarrkldnext(struct thread *td, struct kldnext_args *uap)
113925537Sdfr{
114091040Sarr	linker_file_t lf;
114191040Sarr	int error = 0;
114225537Sdfr
1143107089Srwatson#ifdef MAC
1144172930Srwatson	error = mac_kld_check_stat(td->td_ucred);
1145107089Srwatson	if (error)
1146107089Srwatson		return (error);
1147107089Srwatson#endif
1148107089Srwatson
1149159845Sjhb	KLD_LOCK();
1150166921Sjhb	if (uap->fileid == 0)
1151166921Sjhb		lf = TAILQ_FIRST(&linker_files);
1152166921Sjhb	else {
1153166921Sjhb		lf = linker_find_file_by_id(uap->fileid);
1154166921Sjhb		if (lf == NULL) {
1155166921Sjhb			error = ENOENT;
1156166921Sjhb			goto out;
1157166921Sjhb		}
1158166921Sjhb		lf = TAILQ_NEXT(lf, link);
115991040Sarr	}
1160166921Sjhb
1161166921Sjhb	/* Skip partially loaded files. */
1162166921Sjhb	while (lf != NULL && !(lf->flags & LINKER_FILE_LINKED))
1163166921Sjhb		lf = TAILQ_NEXT(lf, link);
1164166921Sjhb
1165166921Sjhb	if (lf)
1166166921Sjhb		td->td_retval[0] = lf->id;
1167166921Sjhb	else
1168166921Sjhb		td->td_retval[0] = 0;
116982749Sdillonout:
1170159845Sjhb	KLD_UNLOCK();
117191040Sarr	return (error);
117225537Sdfr}
117325537Sdfr
117425537Sdfrint
117591040Sarrkldstat(struct thread *td, struct kldstat_args *uap)
117625537Sdfr{
1177159587Sjhb	struct kld_file_stat stat;
117891040Sarr	linker_file_t lf;
1179172862Sjb	int error, namelen, version, version_num;
118025537Sdfr
1181159587Sjhb	/*
1182159587Sjhb	 * Check the version of the user's structure.
1183159587Sjhb	 */
1184172862Sjb	if ((error = copyin(&uap->stat->version, &version, sizeof(version))) != 0)
1185159587Sjhb		return (error);
1186172862Sjb	if (version == sizeof(struct kld_file_stat_1))
1187172862Sjb		version_num = 1;
1188172862Sjb	else if (version == sizeof(struct kld_file_stat))
1189172862Sjb		version_num = 2;
1190172862Sjb	else
1191159587Sjhb		return (EINVAL);
1192159587Sjhb
1193107089Srwatson#ifdef MAC
1194172930Srwatson	error = mac_kld_check_stat(td->td_ucred);
1195107089Srwatson	if (error)
1196107089Srwatson		return (error);
1197107089Srwatson#endif
1198107089Srwatson
1199159845Sjhb	KLD_LOCK();
1200107849Salfred	lf = linker_find_file_by_id(uap->fileid);
120191040Sarr	if (lf == NULL) {
1202159845Sjhb		KLD_UNLOCK();
1203159587Sjhb		return (ENOENT);
120491040Sarr	}
120525537Sdfr
1206172862Sjb	/* Version 1 fields: */
120791040Sarr	namelen = strlen(lf->filename) + 1;
120891040Sarr	if (namelen > MAXPATHLEN)
120991040Sarr		namelen = MAXPATHLEN;
1210159587Sjhb	bcopy(lf->filename, &stat.name[0], namelen);
1211159587Sjhb	stat.refs = lf->refs;
1212159587Sjhb	stat.id = lf->id;
1213159587Sjhb	stat.address = lf->address;
1214159587Sjhb	stat.size = lf->size;
1215172862Sjb	if (version_num > 1) {
1216172862Sjb		/* Version 2 fields: */
1217172862Sjb		namelen = strlen(lf->pathname) + 1;
1218172862Sjb		if (namelen > MAXPATHLEN)
1219172862Sjb			namelen = MAXPATHLEN;
1220172862Sjb		bcopy(lf->pathname, &stat.pathname[0], namelen);
1221172862Sjb	}
1222159845Sjhb	KLD_UNLOCK();
122325537Sdfr
122491040Sarr	td->td_retval[0] = 0;
1225159587Sjhb
1226172862Sjb	return (copyout(&stat, uap->stat, version));
122725537Sdfr}
122825537Sdfr
122925537Sdfrint
123091040Sarrkldfirstmod(struct thread *td, struct kldfirstmod_args *uap)
123125537Sdfr{
123291040Sarr	linker_file_t lf;
123391040Sarr	module_t mp;
123491040Sarr	int error = 0;
123525537Sdfr
1236107089Srwatson#ifdef MAC
1237172930Srwatson	error = mac_kld_check_stat(td->td_ucred);
1238107089Srwatson	if (error)
1239107089Srwatson		return (error);
1240107089Srwatson#endif
1241107089Srwatson
1242159845Sjhb	KLD_LOCK();
1243107849Salfred	lf = linker_find_file_by_id(uap->fileid);
124491040Sarr	if (lf) {
124592547Sarr		MOD_SLOCK;
124691040Sarr		mp = TAILQ_FIRST(&lf->modules);
124791040Sarr		if (mp != NULL)
124891040Sarr			td->td_retval[0] = module_getid(mp);
124991040Sarr		else
125091040Sarr			td->td_retval[0] = 0;
125192547Sarr		MOD_SUNLOCK;
125291040Sarr	} else
125391040Sarr		error = ENOENT;
1254159845Sjhb	KLD_UNLOCK();
125591040Sarr	return (error);
125625537Sdfr}
125740159Speter
125841090Speterint
125983366Sjuliankldsym(struct thread *td, struct kldsym_args *uap)
126041090Speter{
126191040Sarr	char *symstr = NULL;
126291040Sarr	c_linker_sym_t sym;
126391040Sarr	linker_symval_t symval;
126491040Sarr	linker_file_t lf;
126591040Sarr	struct kld_sym_lookup lookup;
126691040Sarr	int error = 0;
126741090Speter
1268107089Srwatson#ifdef MAC
1269172930Srwatson	error = mac_kld_check_stat(td->td_ucred);
1270107089Srwatson	if (error)
1271107089Srwatson		return (error);
1272107089Srwatson#endif
1273107089Srwatson
1274107849Salfred	if ((error = copyin(uap->data, &lookup, sizeof(lookup))) != 0)
1275159843Sjhb		return (error);
127691068Sarr	if (lookup.version != sizeof(lookup) ||
1277159843Sjhb	    uap->cmd != KLDSYM_LOOKUP)
1278159843Sjhb		return (EINVAL);
1279111119Simp	symstr = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
128091040Sarr	if ((error = copyinstr(lookup.symname, symstr, MAXPATHLEN, NULL)) != 0)
128191040Sarr		goto out;
1282159845Sjhb	KLD_LOCK();
1283107849Salfred	if (uap->fileid != 0) {
1284107849Salfred		lf = linker_find_file_by_id(uap->fileid);
1285159843Sjhb		if (lf == NULL)
128691040Sarr			error = ENOENT;
1287159843Sjhb		else if (LINKER_LOOKUP_SYMBOL(lf, symstr, &sym) == 0 &&
128891040Sarr		    LINKER_SYMBOL_VALUES(lf, sym, &symval) == 0) {
128991040Sarr			lookup.symvalue = (uintptr_t) symval.value;
129091040Sarr			lookup.symsize = symval.size;
1291107855Salfred			error = copyout(&lookup, uap->data, sizeof(lookup));
129291040Sarr		} else
129391040Sarr			error = ENOENT;
129491040Sarr	} else {
129591040Sarr		TAILQ_FOREACH(lf, &linker_files, link) {
129691040Sarr			if (LINKER_LOOKUP_SYMBOL(lf, symstr, &sym) == 0 &&
129791040Sarr			    LINKER_SYMBOL_VALUES(lf, sym, &symval) == 0) {
129891040Sarr				lookup.symvalue = (uintptr_t)symval.value;
129991040Sarr				lookup.symsize = symval.size;
1300107849Salfred				error = copyout(&lookup, uap->data,
130191040Sarr				    sizeof(lookup));
130291068Sarr				break;
130391040Sarr			}
130491040Sarr		}
1305185895Szec#ifndef VIMAGE_GLOBALS
1306185895Szec		/*
1307185895Szec		 * If the symbol is not found in global namespace,
1308185895Szec		 * try to look it up in the current vimage namespace.
1309185895Szec		 */
1310185895Szec		if (lf == NULL) {
1311185895Szec			CURVNET_SET(TD_TO_VNET(td));
1312185895Szec			error = vi_symlookup(&lookup, symstr);
1313185895Szec			CURVNET_RESTORE();
1314185895Szec			if (error == 0)
1315185895Szec				error = copyout(&lookup, uap->data,
1316185895Szec						sizeof(lookup));
1317185895Szec		}
1318185895Szec#else
131991040Sarr		if (lf == NULL)
132091040Sarr			error = ENOENT;
1321185895Szec#endif
132241090Speter	}
1323159845Sjhb	KLD_UNLOCK();
132441090Speterout:
1325159843Sjhb	free(symstr, M_TEMP);
132691040Sarr	return (error);
132741090Speter}
132841090Speter
132940159Speter/*
133040159Speter * Preloaded module support
133140159Speter */
133240159Speter
133359751Speterstatic modlist_t
133474642Sbpmodlist_lookup(const char *name, int ver)
133559751Speter{
133691040Sarr	modlist_t mod;
133759751Speter
133891040Sarr	TAILQ_FOREACH(mod, &found_modules, link) {
133992032Sdwmalone		if (strcmp(mod->name, name) == 0 &&
134092032Sdwmalone		    (ver == 0 || mod->version == ver))
134191040Sarr			return (mod);
134291040Sarr	}
134391040Sarr	return (NULL);
134459751Speter}
134559751Speter
134674642Sbpstatic modlist_t
134783321Spetermodlist_lookup2(const char *name, struct mod_depend *verinfo)
134883321Speter{
134991040Sarr	modlist_t mod, bestmod;
135092032Sdwmalone	int ver;
135183321Speter
135291040Sarr	if (verinfo == NULL)
135391040Sarr		return (modlist_lookup(name, 0));
135491040Sarr	bestmod = NULL;
1355159586Sjhb	TAILQ_FOREACH(mod, &found_modules, link) {
135692032Sdwmalone		if (strcmp(mod->name, name) != 0)
135791040Sarr			continue;
135891040Sarr		ver = mod->version;
135991040Sarr		if (ver == verinfo->md_ver_preferred)
136091040Sarr			return (mod);
136191040Sarr		if (ver >= verinfo->md_ver_minimum &&
136291068Sarr		    ver <= verinfo->md_ver_maximum &&
1363120382Sfjoe		    (bestmod == NULL || ver > bestmod->version))
136491040Sarr			bestmod = mod;
136591040Sarr	}
136691040Sarr	return (bestmod);
136783321Speter}
136883321Speter
136983321Speterstatic modlist_t
137078501Sdesmodlist_newmodule(const char *modname, int version, linker_file_t container)
137174642Sbp{
137291040Sarr	modlist_t mod;
137374642Sbp
137492705Sarr	mod = malloc(sizeof(struct modlist), M_LINKER, M_NOWAIT | M_ZERO);
137591040Sarr	if (mod == NULL)
137691040Sarr		panic("no memory for module list");
137791040Sarr	mod->container = container;
137891040Sarr	mod->name = modname;
137991040Sarr	mod->version = version;
138091040Sarr	TAILQ_INSERT_TAIL(&found_modules, mod, link);
138191040Sarr	return (mod);
138274642Sbp}
138374642Sbp
138440159Speterstatic void
138578161Speterlinker_addmodules(linker_file_t lf, struct mod_metadata **start,
138691040Sarr    struct mod_metadata **stop, int preload)
138774642Sbp{
138891040Sarr	struct mod_metadata *mp, **mdp;
138991040Sarr	const char *modname;
139091040Sarr	int ver;
139174642Sbp
139291040Sarr	for (mdp = start; mdp < stop; mdp++) {
1393109605Sjake		mp = *mdp;
139491040Sarr		if (mp->md_type != MDT_VERSION)
139591040Sarr			continue;
1396109605Sjake		modname = mp->md_cval;
1397109605Sjake		ver = ((struct mod_version *)mp->md_data)->mv_version;
139891040Sarr		if (modlist_lookup(modname, ver) != NULL) {
139991040Sarr			printf("module %s already present!\n", modname);
140091040Sarr			/* XXX what can we do? this is a build error. :-( */
140191040Sarr			continue;
140291040Sarr		}
140391040Sarr		modlist_newmodule(modname, ver, lf);
140474642Sbp	}
140574642Sbp}
140674642Sbp
140774642Sbpstatic void
140891040Sarrlinker_preload(void *arg)
140940159Speter{
141091040Sarr	caddr_t modptr;
141191040Sarr	const char *modname, *nmodname;
141291040Sarr	char *modtype;
1413160244Sjhb	linker_file_t lf, nlf;
141491040Sarr	linker_class_t lc;
141592032Sdwmalone	int error;
141691040Sarr	linker_file_list_t loaded_files;
141791040Sarr	linker_file_list_t depended_files;
141891040Sarr	struct mod_metadata *mp, *nmp;
141991040Sarr	struct mod_metadata **start, **stop, **mdp, **nmdp;
142091040Sarr	struct mod_depend *verinfo;
142191040Sarr	int nver;
142291040Sarr	int resolves;
142391040Sarr	modlist_t mod;
142491040Sarr	struct sysinit **si_start, **si_stop;
142540159Speter
142691040Sarr	TAILQ_INIT(&loaded_files);
142791040Sarr	TAILQ_INIT(&depended_files);
142891040Sarr	TAILQ_INIT(&found_modules);
142991040Sarr	error = 0;
143059751Speter
143191040Sarr	modptr = NULL;
143291040Sarr	while ((modptr = preload_search_next_name(modptr)) != NULL) {
143391040Sarr		modname = (char *)preload_search_info(modptr, MODINFO_NAME);
143491040Sarr		modtype = (char *)preload_search_info(modptr, MODINFO_TYPE);
143591040Sarr		if (modname == NULL) {
143691040Sarr			printf("Preloaded module at %p does not have a"
143791040Sarr			    " name!\n", modptr);
143891040Sarr			continue;
143991040Sarr		}
144091040Sarr		if (modtype == NULL) {
144191040Sarr			printf("Preloaded module at %p does not have a type!\n",
144291040Sarr			    modptr);
144391040Sarr			continue;
144491040Sarr		}
1445131398Sjhb		if (bootverbose)
1446131398Sjhb			printf("Preloaded %s \"%s\" at %p.\n", modtype, modname,
1447131398Sjhb			    modptr);
144840159Speter		lf = NULL;
144991040Sarr		TAILQ_FOREACH(lc, &classes, link) {
145091040Sarr			error = LINKER_LINK_PRELOAD(lc, modname, &lf);
1451134364Siedowse			if (!error)
145291040Sarr				break;
1453134364Siedowse			lf = NULL;
145491040Sarr		}
145591040Sarr		if (lf)
145691040Sarr			TAILQ_INSERT_TAIL(&loaded_files, lf, loaded);
145740159Speter	}
145840159Speter
145991040Sarr	/*
146091040Sarr	 * First get a list of stuff in the kernel.
146191040Sarr	 */
146291040Sarr	if (linker_file_lookup_set(linker_kernel_file, MDT_SETNAME, &start,
146391040Sarr	    &stop, NULL) == 0)
146491040Sarr		linker_addmodules(linker_kernel_file, start, stop, 1);
146559751Speter
146659751Speter	/*
1467167019Sjhb	 * This is a once-off kinky bubble sort to resolve relocation
1468167019Sjhb	 * dependency requirements.
146959751Speter	 */
147091040Sarrrestart:
147191040Sarr	TAILQ_FOREACH(lf, &loaded_files, loaded) {
147291040Sarr		error = linker_file_lookup_set(lf, MDT_SETNAME, &start,
147391040Sarr		    &stop, NULL);
147491040Sarr		/*
147591040Sarr		 * First, look to see if we would successfully link with this
147691040Sarr		 * stuff.
147791040Sarr		 */
147891040Sarr		resolves = 1;	/* unless we know otherwise */
147991040Sarr		if (!error) {
148091040Sarr			for (mdp = start; mdp < stop; mdp++) {
1481109605Sjake				mp = *mdp;
148291040Sarr				if (mp->md_type != MDT_DEPEND)
148391040Sarr					continue;
1484109605Sjake				modname = mp->md_cval;
1485109605Sjake				verinfo = mp->md_data;
148691040Sarr				for (nmdp = start; nmdp < stop; nmdp++) {
1487109605Sjake					nmp = *nmdp;
148891040Sarr					if (nmp->md_type != MDT_VERSION)
148991040Sarr						continue;
1490109605Sjake					nmodname = nmp->md_cval;
149192032Sdwmalone					if (strcmp(modname, nmodname) == 0)
149291040Sarr						break;
149391040Sarr				}
149491040Sarr				if (nmdp < stop)   /* it's a self reference */
149591040Sarr					continue;
1496159840Sjhb
149791040Sarr				/*
149891040Sarr				 * ok, the module isn't here yet, we
149991040Sarr				 * are not finished
150091040Sarr				 */
150191068Sarr				if (modlist_lookup2(modname, verinfo) == NULL)
150291040Sarr					resolves = 0;
150391040Sarr			}
150464143Speter		}
150591040Sarr		/*
150691040Sarr		 * OK, if we found our modules, we can link.  So, "provide"
150791040Sarr		 * the modules inside and add it to the end of the link order
150891040Sarr		 * list.
150991040Sarr		 */
151091040Sarr		if (resolves) {
151191040Sarr			if (!error) {
151291040Sarr				for (mdp = start; mdp < stop; mdp++) {
1513109605Sjake					mp = *mdp;
151491040Sarr					if (mp->md_type != MDT_VERSION)
151591040Sarr						continue;
1516109605Sjake					modname = mp->md_cval;
1517109605Sjake					nver = ((struct mod_version *)
1518109605Sjake					    mp->md_data)->mv_version;
151991040Sarr					if (modlist_lookup(modname,
152091040Sarr					    nver) != NULL) {
152191040Sarr						printf("module %s already"
152291040Sarr						    " present!\n", modname);
1523160244Sjhb						TAILQ_REMOVE(&loaded_files,
1524160244Sjhb						    lf, loaded);
1525132117Sphk						linker_file_unload(lf,
1526132117Sphk						    LINKER_UNLOAD_FORCE);
152791040Sarr						/* we changed tailq next ptr */
152891068Sarr						goto restart;
152991040Sarr					}
153091040Sarr					modlist_newmodule(modname, nver, lf);
153191040Sarr				}
153291040Sarr			}
153391040Sarr			TAILQ_REMOVE(&loaded_files, lf, loaded);
153491040Sarr			TAILQ_INSERT_TAIL(&depended_files, lf, loaded);
153591040Sarr			/*
153691040Sarr			 * Since we provided modules, we need to restart the
153791040Sarr			 * sort so that the previous files that depend on us
153891040Sarr			 * have a chance. Also, we've busted the tailq next
153991040Sarr			 * pointer with the REMOVE.
154091040Sarr			 */
154191040Sarr			goto restart;
154259751Speter		}
154359751Speter	}
154491040Sarr
154559751Speter	/*
154691040Sarr	 * At this point, we check to see what could not be resolved..
154759751Speter	 */
1548160242Sjhb	while ((lf = TAILQ_FIRST(&loaded_files)) != NULL) {
1549160242Sjhb		TAILQ_REMOVE(&loaded_files, lf, loaded);
155091040Sarr		printf("KLD file %s is missing dependencies\n", lf->filename);
1551132117Sphk		linker_file_unload(lf, LINKER_UNLOAD_FORCE);
155240159Speter	}
155359751Speter
155478161Speter	/*
155591040Sarr	 * We made it. Finish off the linking in the order we determined.
155678161Speter	 */
1557160244Sjhb	TAILQ_FOREACH_SAFE(lf, &depended_files, loaded, nlf) {
155891040Sarr		if (linker_kernel_file) {
155991040Sarr			linker_kernel_file->refs++;
156091040Sarr			error = linker_file_add_dependency(lf,
156191040Sarr			    linker_kernel_file);
156291040Sarr			if (error)
156391040Sarr				panic("cannot add dependency");
156491040Sarr		}
156591040Sarr		lf->userrefs++;	/* so we can (try to) kldunload it */
156691040Sarr		error = linker_file_lookup_set(lf, MDT_SETNAME, &start,
156791040Sarr		    &stop, NULL);
156891040Sarr		if (!error) {
156991040Sarr			for (mdp = start; mdp < stop; mdp++) {
1570109605Sjake				mp = *mdp;
157191040Sarr				if (mp->md_type != MDT_DEPEND)
157291040Sarr					continue;
1573109605Sjake				modname = mp->md_cval;
1574109605Sjake				verinfo = mp->md_data;
157591040Sarr				mod = modlist_lookup2(modname, verinfo);
1576151484Sjdp				/* Don't count self-dependencies */
1577151484Sjdp				if (lf == mod->container)
1578151484Sjdp					continue;
157991040Sarr				mod->container->refs++;
158091040Sarr				error = linker_file_add_dependency(lf,
158191040Sarr				    mod->container);
158291040Sarr				if (error)
158391040Sarr					panic("cannot add dependency");
158491040Sarr			}
158591040Sarr		}
158691040Sarr		/*
158791040Sarr		 * Now do relocation etc using the symbol search paths
158891040Sarr		 * established by the dependencies
158991040Sarr		 */
159091040Sarr		error = LINKER_LINK_PRELOAD_FINISH(lf);
159191040Sarr		if (error) {
1592160244Sjhb			TAILQ_REMOVE(&depended_files, lf, loaded);
159391040Sarr			printf("KLD file %s - could not finalize loading\n",
159491040Sarr			    lf->filename);
1595132117Sphk			linker_file_unload(lf, LINKER_UNLOAD_FORCE);
159691040Sarr			continue;
159791040Sarr		}
159891040Sarr		linker_file_register_modules(lf);
159991040Sarr		if (linker_file_lookup_set(lf, "sysinit_set", &si_start,
160091040Sarr		    &si_stop, NULL) == 0)
160191040Sarr			sysinit_add(si_start, si_stop);
160291040Sarr		linker_file_register_sysctls(lf);
160391040Sarr		lf->flags |= LINKER_FILE_LINKED;
160459751Speter	}
160591040Sarr	/* woohoo! we made it! */
160640159Speter}
160740159Speter
1608177253SrwatsonSYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0);
160940159Speter
161040159Speter/*
161140159Speter * Search for a not-loaded module by name.
1612159840Sjhb *
161340159Speter * Modules may be found in the following locations:
1614159840Sjhb *
161591040Sarr * - preloaded (result is just the module name) - on disk (result is full path
161691040Sarr * to module)
1617159840Sjhb *
161891040Sarr * If the module name is qualified in any way (contains path, etc.) the we
161991040Sarr * simply return a copy of it.
1620159840Sjhb *
162140159Speter * The search path can be manipulated via sysctl.  Note that we use the ';'
162240159Speter * character as a separator to be consistent with the bootloader.
162340159Speter */
162440159Speter
162583321Speterstatic char linker_hintfile[] = "linker.hints";
1626111852Srustatic char linker_path[MAXPATHLEN] = "/boot/kernel;/boot/modules";
162740159Speter
162840159SpeterSYSCTL_STRING(_kern, OID_AUTO, module_path, CTLFLAG_RW, linker_path,
162991040Sarr    sizeof(linker_path), "module load search path");
163040159Speter
163177843SpeterTUNABLE_STR("module_path", linker_path, sizeof(linker_path));
163270417Speter
163359751Speterstatic char *linker_ext_list[] = {
163483321Speter	"",
163559751Speter	".ko",
163659751Speter	NULL
163759751Speter};
163859751Speter
163983321Speter/*
164091040Sarr * Check if file actually exists either with or without extension listed in
164191040Sarr * the linker_ext_list. (probably should be generic for the rest of the
164291040Sarr * kernel)
164383321Speter */
164459751Speterstatic char *
164591040Sarrlinker_lookup_file(const char *path, int pathlen, const char *name,
164691040Sarr    int namelen, struct vattr *vap)
164740159Speter{
164891040Sarr	struct nameidata nd;
164991040Sarr	struct thread *td = curthread;	/* XXX */
165091040Sarr	char *result, **cpp, *sep;
1651159808Sjhb	int error, len, extlen, reclen, flags, vfslocked;
165291040Sarr	enum vtype type;
165340159Speter
165491040Sarr	extlen = 0;
165591040Sarr	for (cpp = linker_ext_list; *cpp; cpp++) {
165691040Sarr		len = strlen(*cpp);
165791040Sarr		if (len > extlen)
165891040Sarr			extlen = len;
165991040Sarr	}
166091040Sarr	extlen++;		/* trailing '\0' */
166191040Sarr	sep = (path[pathlen - 1] != '/') ? "/" : "";
166283321Speter
166391040Sarr	reclen = pathlen + strlen(sep) + namelen + extlen + 1;
1664111119Simp	result = malloc(reclen, M_LINKER, M_WAITOK);
166591040Sarr	for (cpp = linker_ext_list; *cpp; cpp++) {
166691040Sarr		snprintf(result, reclen, "%.*s%s%.*s%s", pathlen, path, sep,
166791040Sarr		    namelen, name, *cpp);
166891040Sarr		/*
166991040Sarr		 * Attempt to open the file, and return the path if
167091040Sarr		 * we succeed and it's a regular file.
167191040Sarr		 */
1672159808Sjhb		NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, result, td);
167391040Sarr		flags = FREAD;
1674170152Skib		error = vn_open(&nd, &flags, 0, NULL);
167591040Sarr		if (error == 0) {
1676159808Sjhb			vfslocked = NDHASGIANT(&nd);
167791040Sarr			NDFREE(&nd, NDF_ONLY_PNBUF);
167891040Sarr			type = nd.ni_vp->v_type;
167991040Sarr			if (vap)
1680182371Sattilio				VOP_GETATTR(nd.ni_vp, vap, td->td_ucred);
1681175294Sattilio			VOP_UNLOCK(nd.ni_vp, 0);
168291406Sjhb			vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
1683159808Sjhb			VFS_UNLOCK_GIANT(vfslocked);
168491040Sarr			if (type == VREG)
168591040Sarr				return (result);
168691040Sarr		}
168783321Speter	}
168891040Sarr	free(result, M_LINKER);
168991040Sarr	return (NULL);
169083321Speter}
169183321Speter
169291040Sarr#define	INT_ALIGN(base, ptr)	ptr =					\
169383321Speter	(base) + (((ptr) - (base) + sizeof(int) - 1) & ~(sizeof(int) - 1))
169483321Speter
169583321Speter/*
169691040Sarr * Lookup KLD which contains requested module in the "linker.hints" file. If
169791040Sarr * version specification is available, then try to find the best KLD.
169883321Speter * Otherwise just find the latest one.
169983321Speter */
170083321Speterstatic char *
170191040Sarrlinker_hints_lookup(const char *path, int pathlen, const char *modname,
170291040Sarr    int modnamelen, struct mod_depend *verinfo)
170383321Speter{
170491040Sarr	struct thread *td = curthread;	/* XXX */
170591406Sjhb	struct ucred *cred = td ? td->td_ucred : NULL;
170691040Sarr	struct nameidata nd;
170791040Sarr	struct vattr vattr, mattr;
170891040Sarr	u_char *hints = NULL;
170991040Sarr	u_char *cp, *recptr, *bufend, *result, *best, *pathbuf, *sep;
171091040Sarr	int error, ival, bestver, *intp, reclen, found, flags, clen, blen;
1711159808Sjhb	int vfslocked = 0;
171283321Speter
171391040Sarr	result = NULL;
171491040Sarr	bestver = found = 0;
171583321Speter
171691040Sarr	sep = (path[pathlen - 1] != '/') ? "/" : "";
171791040Sarr	reclen = imax(modnamelen, strlen(linker_hintfile)) + pathlen +
171891040Sarr	    strlen(sep) + 1;
1719111119Simp	pathbuf = malloc(reclen, M_LINKER, M_WAITOK);
172091040Sarr	snprintf(pathbuf, reclen, "%.*s%s%s", pathlen, path, sep,
172191040Sarr	    linker_hintfile);
172283321Speter
1723159808Sjhb	NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_SYSSPACE, pathbuf, td);
172491040Sarr	flags = FREAD;
1725170152Skib	error = vn_open(&nd, &flags, 0, NULL);
172691040Sarr	if (error)
172791040Sarr		goto bad;
1728159808Sjhb	vfslocked = NDHASGIANT(&nd);
172991040Sarr	NDFREE(&nd, NDF_ONLY_PNBUF);
173091040Sarr	if (nd.ni_vp->v_type != VREG)
173191040Sarr		goto bad;
173291040Sarr	best = cp = NULL;
1733182371Sattilio	error = VOP_GETATTR(nd.ni_vp, &vattr, cred);
173491040Sarr	if (error)
173591040Sarr		goto bad;
173691040Sarr	/*
173791040Sarr	 * XXX: we need to limit this number to some reasonable value
173891040Sarr	 */
173991040Sarr	if (vattr.va_size > 100 * 1024) {
174091040Sarr		printf("hints file too large %ld\n", (long)vattr.va_size);
174191040Sarr		goto bad;
174291040Sarr	}
1743111119Simp	hints = malloc(vattr.va_size, M_TEMP, M_WAITOK);
174491040Sarr	if (hints == NULL)
174591040Sarr		goto bad;
174691068Sarr	error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)hints, vattr.va_size, 0,
1747101941Srwatson	    UIO_SYSSPACE, IO_NODELOCKED, cred, NOCRED, &reclen, td);
174891040Sarr	if (error)
174991040Sarr		goto bad;
1750175294Sattilio	VOP_UNLOCK(nd.ni_vp, 0);
175191040Sarr	vn_close(nd.ni_vp, FREAD, cred, td);
1752159808Sjhb	VFS_UNLOCK_GIANT(vfslocked);
175391040Sarr	nd.ni_vp = NULL;
175491040Sarr	if (reclen != 0) {
175591040Sarr		printf("can't read %d\n", reclen);
175691040Sarr		goto bad;
175791040Sarr	}
175891040Sarr	intp = (int *)hints;
175983321Speter	ival = *intp++;
176091040Sarr	if (ival != LINKER_HINTS_VERSION) {
176191040Sarr		printf("hints file version mismatch %d\n", ival);
176291040Sarr		goto bad;
176383321Speter	}
176491040Sarr	bufend = hints + vattr.va_size;
176591040Sarr	recptr = (u_char *)intp;
176691040Sarr	clen = blen = 0;
176791040Sarr	while (recptr < bufend && !found) {
176891040Sarr		intp = (int *)recptr;
176991040Sarr		reclen = *intp++;
177091040Sarr		ival = *intp++;
177191040Sarr		cp = (char *)intp;
177291040Sarr		switch (ival) {
177391040Sarr		case MDT_VERSION:
177491040Sarr			clen = *cp++;
177591040Sarr			if (clen != modnamelen || bcmp(cp, modname, clen) != 0)
177691040Sarr				break;
177791040Sarr			cp += clen;
177891040Sarr			INT_ALIGN(hints, cp);
177991040Sarr			ival = *(int *)cp;
178091040Sarr			cp += sizeof(int);
178191040Sarr			clen = *cp++;
178291040Sarr			if (verinfo == NULL ||
178391040Sarr			    ival == verinfo->md_ver_preferred) {
178491040Sarr				found = 1;
178591040Sarr				break;
178691040Sarr			}
178791040Sarr			if (ival >= verinfo->md_ver_minimum &&
178891040Sarr			    ival <= verinfo->md_ver_maximum &&
178991040Sarr			    ival > bestver) {
179091040Sarr				bestver = ival;
179191040Sarr				best = cp;
179291040Sarr				blen = clen;
179391040Sarr			}
179491040Sarr			break;
179591040Sarr		default:
179691040Sarr			break;
179791040Sarr		}
179891040Sarr		recptr += reclen + sizeof(int);
179991040Sarr	}
180083321Speter	/*
180191040Sarr	 * Finally check if KLD is in the place
180283321Speter	 */
180391040Sarr	if (found)
180491040Sarr		result = linker_lookup_file(path, pathlen, cp, clen, &mattr);
180591040Sarr	else if (best)
180691040Sarr		result = linker_lookup_file(path, pathlen, best, blen, &mattr);
180791040Sarr
180891040Sarr	/*
180991040Sarr	 * KLD is newer than hints file. What we should do now?
181091040Sarr	 */
181191040Sarr	if (result && timespeccmp(&mattr.va_mtime, &vattr.va_mtime, >))
181291040Sarr		printf("warning: KLD '%s' is newer than the linker.hints"
181391040Sarr		    " file\n", result);
181483321Speterbad:
1815105167Sphk	free(pathbuf, M_LINKER);
181691040Sarr	if (hints)
181791040Sarr		free(hints, M_TEMP);
181899553Sjeff	if (nd.ni_vp != NULL) {
1819175294Sattilio		VOP_UNLOCK(nd.ni_vp, 0);
182091040Sarr		vn_close(nd.ni_vp, FREAD, cred, td);
1821159808Sjhb		VFS_UNLOCK_GIANT(vfslocked);
182299553Sjeff	}
182391040Sarr	/*
182491040Sarr	 * If nothing found or hints is absent - fallback to the old
182591040Sarr	 * way by using "kldname[.ko]" as module name.
182691040Sarr	 */
182791040Sarr	if (!found && !bestver && result == NULL)
182891040Sarr		result = linker_lookup_file(path, pathlen, modname,
182991040Sarr		    modnamelen, NULL);
183091040Sarr	return (result);
183183321Speter}
183283321Speter
183383321Speter/*
183483321Speter * Lookup KLD which contains requested module in the all directories.
183583321Speter */
183683321Speterstatic char *
183783321Speterlinker_search_module(const char *modname, int modnamelen,
183891040Sarr    struct mod_depend *verinfo)
183983321Speter{
184091040Sarr	char *cp, *ep, *result;
184183321Speter
184291040Sarr	/*
184391040Sarr	 * traverse the linker path
184491040Sarr	 */
184591040Sarr	for (cp = linker_path; *cp; cp = ep + 1) {
184691040Sarr		/* find the end of this component */
184791040Sarr		for (ep = cp; (*ep != 0) && (*ep != ';'); ep++);
184891068Sarr		result = linker_hints_lookup(cp, ep - cp, modname,
184991068Sarr		    modnamelen, verinfo);
185091040Sarr		if (result != NULL)
185191040Sarr			return (result);
185291040Sarr		if (*ep == 0)
185391040Sarr			break;
185491040Sarr	}
185591040Sarr	return (NULL);
185683321Speter}
185783321Speter
185883321Speter/*
185983321Speter * Search for module in all directories listed in the linker_path.
186083321Speter */
186183321Speterstatic char *
186283321Speterlinker_search_kld(const char *name)
186383321Speter{
1864158972Sdelphij	char *cp, *ep, *result;
1865158972Sdelphij	int len;
186683321Speter
186791040Sarr	/* qualified at all? */
186891040Sarr	if (index(name, '/'))
186991040Sarr		return (linker_strdup(name));
187040159Speter
187191040Sarr	/* traverse the linker path */
187291040Sarr	len = strlen(name);
187391040Sarr	for (ep = linker_path; *ep; ep++) {
187491040Sarr		cp = ep;
187591040Sarr		/* find the end of this component */
187691040Sarr		for (; *ep != 0 && *ep != ';'; ep++);
187791040Sarr		result = linker_lookup_file(cp, ep - cp, name, len, NULL);
187891040Sarr		if (result != NULL)
187991040Sarr			return (result);
188091040Sarr	}
188191040Sarr	return (NULL);
188240159Speter}
188359751Speter
188459751Speterstatic const char *
188591040Sarrlinker_basename(const char *path)
188659751Speter{
188791040Sarr	const char *filename;
188859751Speter
188991040Sarr	filename = rindex(path, '/');
189091040Sarr	if (filename == NULL)
189191040Sarr		return path;
189291040Sarr	if (filename[1])
189391040Sarr		filename++;
189491040Sarr	return (filename);
189559751Speter}
189659751Speter
1897157144Sjkoshy#ifdef HWPMC_HOOKS
1898157144Sjkoshy
1899159797Sjhbstruct hwpmc_context {
1900159797Sjhb	int	nobjects;
1901159797Sjhb	int	nmappings;
1902159797Sjhb	struct pmckern_map_in *kobase;
1903159797Sjhb};
1904159797Sjhb
1905159797Sjhbstatic int
1906159797Sjhblinker_hwpmc_list_object(linker_file_t lf, void *arg)
1907159797Sjhb{
1908159797Sjhb	struct hwpmc_context *hc;
1909159797Sjhb
1910159797Sjhb	hc = arg;
1911159797Sjhb
1912159797Sjhb	/* If we run out of mappings, fail. */
1913159797Sjhb	if (hc->nobjects >= hc->nmappings)
1914159797Sjhb		return (1);
1915159797Sjhb
1916159797Sjhb	/* Save the info for this linker file. */
1917159797Sjhb	hc->kobase[hc->nobjects].pm_file = lf->filename;
1918159797Sjhb	hc->kobase[hc->nobjects].pm_address = (uintptr_t)lf->address;
1919159797Sjhb	hc->nobjects++;
1920159797Sjhb	return (0);
1921159797Sjhb}
1922159797Sjhb
192359751Speter/*
1924157144Sjkoshy * Inform hwpmc about the set of kernel modules currently loaded.
1925157144Sjkoshy */
1926157144Sjkoshyvoid *
1927157144Sjkoshylinker_hwpmc_list_objects(void)
1928157144Sjkoshy{
1929159797Sjhb	struct hwpmc_context hc;
1930157144Sjkoshy
1931159797Sjhb	hc.nmappings = 15;	/* a reasonable default */
1932157144Sjkoshy
1933157144Sjkoshy retry:
1934157144Sjkoshy	/* allocate nmappings+1 entries */
1935184214Sdes	hc.kobase = malloc((hc.nmappings + 1) * sizeof(struct pmckern_map_in),
1936184214Sdes	    M_LINKER, M_WAITOK | M_ZERO);
1937157144Sjkoshy
1938159797Sjhb	hc.nobjects = 0;
1939159797Sjhb	if (linker_file_foreach(linker_hwpmc_list_object, &hc) != 0) {
1940159797Sjhb		hc.nmappings = hc.nobjects;
1941184205Sdes		free(hc.kobase, M_LINKER);
1942157144Sjkoshy		goto retry;
1943157144Sjkoshy	}
1944157144Sjkoshy
1945159797Sjhb	KASSERT(hc.nobjects > 0, ("linker_hpwmc_list_objects: no kernel "
1946159797Sjhb		"objects?"));
1947157144Sjkoshy
1948157144Sjkoshy	/* The last entry of the malloced area comprises of all zeros. */
1949159797Sjhb	KASSERT(hc.kobase[hc.nobjects].pm_file == NULL,
1950157144Sjkoshy	    ("linker_hwpmc_list_objects: last object not NULL"));
1951157144Sjkoshy
1952159797Sjhb	return ((void *)hc.kobase);
1953157144Sjkoshy}
1954157144Sjkoshy#endif
1955157144Sjkoshy
1956157144Sjkoshy/*
195791040Sarr * Find a file which contains given module and load it, if "parent" is not
195891040Sarr * NULL, register a reference to it.
195959751Speter */
1960159796Sjhbstatic int
196183321Speterlinker_load_module(const char *kldname, const char *modname,
196291040Sarr    struct linker_file *parent, struct mod_depend *verinfo,
196391040Sarr    struct linker_file **lfpp)
196459751Speter{
196591040Sarr	linker_file_t lfdep;
196691040Sarr	const char *filename;
196791040Sarr	char *pathname;
196891040Sarr	int error;
196959751Speter
1970159845Sjhb	KLD_LOCK_ASSERT();
197191040Sarr	if (modname == NULL) {
197291040Sarr		/*
197391040Sarr 		 * We have to load KLD
197491040Sarr 		 */
197591068Sarr		KASSERT(verinfo == NULL, ("linker_load_module: verinfo"
197691068Sarr		    " is not NULL"));
197791040Sarr		pathname = linker_search_kld(kldname);
197891040Sarr	} else {
197991040Sarr		if (modlist_lookup2(modname, verinfo) != NULL)
198091040Sarr			return (EEXIST);
198194322Sbrian		if (kldname != NULL)
198294322Sbrian			pathname = linker_strdup(kldname);
198395488Sbrian		else if (rootvnode == NULL)
198494322Sbrian			pathname = NULL;
198594322Sbrian		else
198691040Sarr			/*
198791040Sarr			 * Need to find a KLD with required module
198891040Sarr			 */
198991040Sarr			pathname = linker_search_module(modname,
199091040Sarr			    strlen(modname), verinfo);
199191040Sarr	}
199291040Sarr	if (pathname == NULL)
199391040Sarr		return (ENOENT);
199491040Sarr
199583321Speter	/*
199691040Sarr	 * Can't load more than one file with the same basename XXX:
199791040Sarr	 * Actually it should be possible to have multiple KLDs with
199891040Sarr	 * the same basename but different path because they can
199991040Sarr	 * provide different versions of the same modules.
200083321Speter	 */
200191040Sarr	filename = linker_basename(pathname);
2002159792Sjhb	if (linker_find_file_by_name(filename))
200391040Sarr		error = EEXIST;
2004159792Sjhb	else do {
200591040Sarr		error = linker_load_file(pathname, &lfdep);
200691040Sarr		if (error)
200791040Sarr			break;
200891040Sarr		if (modname && verinfo &&
200991040Sarr		    modlist_lookup2(modname, verinfo) == NULL) {
2010132117Sphk			linker_file_unload(lfdep, LINKER_UNLOAD_FORCE);
201191040Sarr			error = ENOENT;
201291040Sarr			break;
201391040Sarr		}
201491040Sarr		if (parent) {
201591040Sarr			error = linker_file_add_dependency(parent, lfdep);
201691040Sarr			if (error)
201791040Sarr				break;
201891040Sarr		}
201991040Sarr		if (lfpp)
202091040Sarr			*lfpp = lfdep;
202191040Sarr	} while (0);
2022159791Sjhb	free(pathname, M_LINKER);
202391040Sarr	return (error);
202459751Speter}
202559751Speter
202659751Speter/*
202791040Sarr * This routine is responsible for finding dependencies of userland initiated
202891040Sarr * kldload(2)'s of files.
202959751Speter */
203059751Speterint
203186469Siedowselinker_load_dependencies(linker_file_t lf)
203259751Speter{
203391040Sarr	linker_file_t lfdep;
203491040Sarr	struct mod_metadata **start, **stop, **mdp, **nmdp;
203591040Sarr	struct mod_metadata *mp, *nmp;
203691040Sarr	struct mod_depend *verinfo;
203791040Sarr	modlist_t mod;
203891040Sarr	const char *modname, *nmodname;
203992032Sdwmalone	int ver, error = 0, count;
204059751Speter
204191040Sarr	/*
204291040Sarr	 * All files are dependant on /kernel.
204391040Sarr	 */
2044159845Sjhb	KLD_LOCK_ASSERT();
204591040Sarr	if (linker_kernel_file) {
204691040Sarr		linker_kernel_file->refs++;
204791040Sarr		error = linker_file_add_dependency(lf, linker_kernel_file);
204891040Sarr		if (error)
204991040Sarr			return (error);
205059751Speter	}
205191040Sarr	if (linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop,
205291040Sarr	    &count) != 0)
205391040Sarr		return (0);
205491040Sarr	for (mdp = start; mdp < stop; mdp++) {
2055109605Sjake		mp = *mdp;
205691040Sarr		if (mp->md_type != MDT_VERSION)
205791040Sarr			continue;
2058109605Sjake		modname = mp->md_cval;
2059109605Sjake		ver = ((struct mod_version *)mp->md_data)->mv_version;
206091040Sarr		mod = modlist_lookup(modname, ver);
206191040Sarr		if (mod != NULL) {
206291040Sarr			printf("interface %s.%d already present in the KLD"
206391040Sarr			    " '%s'!\n", modname, ver,
206491040Sarr			    mod->container->filename);
206591040Sarr			return (EEXIST);
206691040Sarr		}
206791040Sarr	}
206874642Sbp
206991040Sarr	for (mdp = start; mdp < stop; mdp++) {
2070109605Sjake		mp = *mdp;
207191040Sarr		if (mp->md_type != MDT_DEPEND)
207291040Sarr			continue;
2073109605Sjake		modname = mp->md_cval;
2074109605Sjake		verinfo = mp->md_data;
207591040Sarr		nmodname = NULL;
207691040Sarr		for (nmdp = start; nmdp < stop; nmdp++) {
2077109605Sjake			nmp = *nmdp;
207891040Sarr			if (nmp->md_type != MDT_VERSION)
207991040Sarr				continue;
2080109605Sjake			nmodname = nmp->md_cval;
208192032Sdwmalone			if (strcmp(modname, nmodname) == 0)
208291040Sarr				break;
208391040Sarr		}
208491040Sarr		if (nmdp < stop)/* early exit, it's a self reference */
208591040Sarr			continue;
208691040Sarr		mod = modlist_lookup2(modname, verinfo);
208791040Sarr		if (mod) {	/* woohoo, it's loaded already */
208891040Sarr			lfdep = mod->container;
208991040Sarr			lfdep->refs++;
209091040Sarr			error = linker_file_add_dependency(lf, lfdep);
209191040Sarr			if (error)
209291040Sarr				break;
209391040Sarr			continue;
209491040Sarr		}
209591040Sarr		error = linker_load_module(NULL, modname, lf, verinfo, NULL);
209691040Sarr		if (error) {
209791040Sarr			printf("KLD %s: depends on %s - not available\n",
209891040Sarr			    lf->filename, modname);
209991040Sarr			break;
210091040Sarr		}
210159751Speter	}
210259751Speter
210391040Sarr	if (error)
210491040Sarr		return (error);
210591040Sarr	linker_addmodules(lf, start, stop, 0);
210691040Sarr	return (error);
210759751Speter}
210885736Sgreen
210985736Sgreenstatic int
211085736Sgreensysctl_kern_function_list_iterate(const char *name, void *opaque)
211185736Sgreen{
211285736Sgreen	struct sysctl_req *req;
211385736Sgreen
211485736Sgreen	req = opaque;
211585736Sgreen	return (SYSCTL_OUT(req, name, strlen(name) + 1));
211685736Sgreen}
211785736Sgreen
211885736Sgreen/*
211985736Sgreen * Export a nul-separated, double-nul-terminated list of all function names
212085736Sgreen * in the kernel.
212185736Sgreen */
212285736Sgreenstatic int
212385736Sgreensysctl_kern_function_list(SYSCTL_HANDLER_ARGS)
212485736Sgreen{
212585736Sgreen	linker_file_t lf;
212685736Sgreen	int error;
212785736Sgreen
2128107089Srwatson#ifdef MAC
2129172930Srwatson	error = mac_kld_check_stat(req->td->td_ucred);
2130107089Srwatson	if (error)
2131107089Srwatson		return (error);
2132107089Srwatson#endif
2133126253Struckman	error = sysctl_wire_old_buffer(req, 0);
2134126253Struckman	if (error != 0)
2135126253Struckman		return (error);
2136159845Sjhb	KLD_LOCK();
213785736Sgreen	TAILQ_FOREACH(lf, &linker_files, link) {
213885736Sgreen		error = LINKER_EACH_FUNCTION_NAME(lf,
213985736Sgreen		    sysctl_kern_function_list_iterate, req);
214098452Sarr		if (error) {
2141159845Sjhb			KLD_UNLOCK();
214285736Sgreen			return (error);
214398452Sarr		}
214485736Sgreen	}
2145159845Sjhb	KLD_UNLOCK();
214685736Sgreen	return (SYSCTL_OUT(req, "", 1));
214785736Sgreen}
214885736Sgreen
214985736SgreenSYSCTL_PROC(_kern, OID_AUTO, function_list, CTLFLAG_RD,
215091040Sarr    NULL, 0, sysctl_kern_function_list, "", "kernel function list");
2151