kern_linker.c revision 298433
1214501Srpaulo/*-
2214501Srpaulo * Copyright (c) 1997-2000 Doug Rabson
3346981Scy * All rights reserved.
4214501Srpaulo *
5252726Srpaulo * Redistribution and use in source and binary forms, with or without
6252726Srpaulo * modification, are permitted provided that the following conditions
7214501Srpaulo * are met:
8214501Srpaulo * 1. Redistributions of source code must retain the above copyright
9214501Srpaulo *    notice, this list of conditions and the following disclaimer.
10214501Srpaulo * 2. Redistributions in binary form must reproduce the above copyright
11214501Srpaulo *    notice, this list of conditions and the following disclaimer in the
12214501Srpaulo *    documentation and/or other materials provided with the distribution.
13214501Srpaulo *
14252726Srpaulo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15281806Srpaulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16346981Scy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17214501Srpaulo * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18214501Srpaulo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19252726Srpaulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20289549Srpaulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21346981Scy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22214501Srpaulo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23214501Srpaulo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24214501Srpaulo * SUCH DAMAGE.
25214501Srpaulo */
26252726Srpaulo
27214501Srpaulo#include <sys/cdefs.h>
28214501Srpaulo__FBSDID("$FreeBSD: head/sys/kern/kern_linker.c 298433 2016-04-21 19:57:40Z pfg $");
29214501Srpaulo
30214501Srpaulo#include "opt_ddb.h"
31214501Srpaulo#include "opt_kld.h"
32214501Srpaulo#include "opt_hwpmc_hooks.h"
33252726Srpaulo
34252726Srpaulo#include <sys/param.h>
35252726Srpaulo#include <sys/kernel.h>
36281806Srpaulo#include <sys/systm.h>
37337817Scy#include <sys/malloc.h>
38281806Srpaulo#include <sys/sysproto.h>
39214501Srpaulo#include <sys/sysent.h>
40337817Scy#include <sys/priv.h>
41346981Scy#include <sys/proc.h>
42214501Srpaulo#include <sys/lock.h>
43214501Srpaulo#include <sys/mutex.h>
44214501Srpaulo#include <sys/sx.h>
45214501Srpaulo#include <sys/module.h>
46281806Srpaulo#include <sys/mount.h>
47252726Srpaulo#include <sys/linker.h>
48252726Srpaulo#include <sys/eventhandler.h>
49214501Srpaulo#include <sys/fcntl.h>
50214501Srpaulo#include <sys/jail.h>
51214501Srpaulo#include <sys/libkern.h>
52252726Srpaulo#include <sys/namei.h>
53346981Scy#include <sys/vnode.h>
54214501Srpaulo#include <sys/syscallsubr.h>
55214501Srpaulo#include <sys/sysctl.h>
56214501Srpaulo
57214501Srpaulo#include <net/vnet.h>
58214501Srpaulo
59214501Srpaulo#include <security/mac/mac_framework.h>
60214501Srpaulo
61214501Srpaulo#include "linker_if.h"
62214501Srpaulo
63214501Srpaulo#ifdef HWPMC_HOOKS
64214501Srpaulo#include <sys/pmckern.h>
65214501Srpaulo#endif
66214501Srpaulo
67214501Srpaulo#ifdef KLD_DEBUG
68214501Srpauloint kld_debug = 0;
69214501SrpauloSYSCTL_INT(_debug, OID_AUTO, kld_debug, CTLFLAG_RWTUN,
70214501Srpaulo    &kld_debug, 0, "Set various levels of KLD debug");
71214501Srpaulo#endif
72214501Srpaulo
73214501Srpaulo/* These variables are used by kernel debuggers to enumerate loaded files. */
74214501Srpauloconst int kld_off_address = offsetof(struct linker_file, address);
75214501Srpauloconst int kld_off_filename = offsetof(struct linker_file, filename);
76214501Srpauloconst int kld_off_pathname = offsetof(struct linker_file, pathname);
77214501Srpauloconst int kld_off_next = offsetof(struct linker_file, link.tqe_next);
78214501Srpaulo
79214501Srpaulo/*
80214501Srpaulo * static char *linker_search_path(const char *name, struct mod_depend
81214501Srpaulo * *verinfo);
82281806Srpaulo */
83281806Srpaulostatic const char 	*linker_basename(const char *path);
84281806Srpaulo
85281806Srpaulo/*
86281806Srpaulo * Find a currently loaded file given its filename.
87281806Srpaulo */
88281806Srpaulostatic linker_file_t linker_find_file_by_name(const char* _filename);
89281806Srpaulo
90281806Srpaulo/*
91281806Srpaulo * Find a currently loaded file given its file id.
92281806Srpaulo */
93281806Srpaulostatic linker_file_t linker_find_file_by_id(int _fileid);
94281806Srpaulo
95281806Srpaulo/* Metadata from the static kernel */
96281806SrpauloSET_DECLARE(modmetadata_set, struct mod_metadata);
97281806Srpaulo
98281806SrpauloMALLOC_DEFINE(M_LINKER, "linker", "kernel linker");
99281806Srpaulo
100281806Srpaulolinker_file_t linker_kernel_file;
101281806Srpaulo
102281806Srpaulostatic struct sx kld_sx;	/* kernel linker lock */
103281806Srpaulo
104281806Srpaulo/*
105281806Srpaulo * Load counter used by clients to determine if a linker file has been
106214501Srpaulo * re-loaded. This counter is incremented for each file load.
107214501Srpaulo */
108214501Srpaulostatic int loadcnt;
109214501Srpaulo
110214501Srpaulostatic linker_class_list_t classes;
111214501Srpaulostatic linker_file_list_t linker_files;
112214501Srpaulostatic int next_file_id = 1;
113214501Srpaulostatic int linker_no_more_classes = 0;
114214501Srpaulo
115214501Srpaulo#define	LINKER_GET_NEXT_FILE_ID(a) do {					\
116214501Srpaulo	linker_file_t lftmp;						\
117214501Srpaulo									\
118214501Srpaulo	if (!cold)							\
119214501Srpaulo		sx_assert(&kld_sx, SA_XLOCKED);				\
120214501Srpauloretry:									\
121214501Srpaulo	TAILQ_FOREACH(lftmp, &linker_files, link) {			\
122214501Srpaulo		if (next_file_id == lftmp->id) {			\
123214501Srpaulo			next_file_id++;					\
124214501Srpaulo			goto retry;					\
125214501Srpaulo		}							\
126214501Srpaulo	}								\
127214501Srpaulo	(a) = next_file_id;						\
128214501Srpaulo} while(0)
129214501Srpaulo
130214501Srpaulo
131214501Srpaulo/* XXX wrong name; we're looking at version provision tags here, not modules */
132214501Srpaulotypedef TAILQ_HEAD(, modlist) modlisthead_t;
133214501Srpaulostruct modlist {
134214501Srpaulo	TAILQ_ENTRY(modlist) link;	/* chain together all modules */
135214501Srpaulo	linker_file_t   container;
136214501Srpaulo	const char 	*name;
137214501Srpaulo	int             version;
138214501Srpaulo};
139214501Srpaulotypedef struct modlist *modlist_t;
140214501Srpaulostatic modlisthead_t found_modules;
141214501Srpaulo
142214501Srpaulostatic int	linker_file_add_dependency(linker_file_t file,
143214501Srpaulo		    linker_file_t dep);
144214501Srpaulostatic caddr_t	linker_file_lookup_symbol_internal(linker_file_t file,
145214501Srpaulo		    const char* name, int deps);
146214501Srpaulostatic int	linker_load_module(const char *kldname,
147214501Srpaulo		    const char *modname, struct linker_file *parent,
148214501Srpaulo		    const struct mod_depend *verinfo, struct linker_file **lfpp);
149214501Srpaulostatic modlist_t modlist_lookup2(const char *name, const struct mod_depend *verinfo);
150214501Srpaulo
151214501Srpaulostatic void
152214501Srpaulolinker_init(void *arg)
153214501Srpaulo{
154214501Srpaulo
155281806Srpaulo	sx_init(&kld_sx, "kernel linker");
156281806Srpaulo	TAILQ_INIT(&classes);
157281806Srpaulo	TAILQ_INIT(&linker_files);
158281806Srpaulo}
159281806Srpaulo
160281806SrpauloSYSINIT(linker, SI_SUB_KLD, SI_ORDER_FIRST, linker_init, 0);
161214501Srpaulo
162214501Srpaulostatic void
163214501Srpaulolinker_stop_class_add(void *arg)
164214501Srpaulo{
165214501Srpaulo
166214501Srpaulo	linker_no_more_classes = 1;
167252726Srpaulo}
168252726Srpaulo
169252726SrpauloSYSINIT(linker_class, SI_SUB_KLD, SI_ORDER_ANY, linker_stop_class_add, NULL);
170346981Scy
171281806Srpauloint
172214501Srpaulolinker_add_class(linker_class_t lc)
173281806Srpaulo{
174281806Srpaulo
175281806Srpaulo	/*
176281806Srpaulo	 * We disallow any class registration past SI_ORDER_ANY
177281806Srpaulo	 * of SI_SUB_KLD.  We bump the reference count to keep the
178337817Scy	 * ops from being freed.
179252726Srpaulo	 */
180337817Scy	if (linker_no_more_classes == 1)
181289549Srpaulo		return (EPERM);
182289549Srpaulo	kobj_class_compile((kobj_class_t) lc);
183214501Srpaulo	((kobj_class_t)lc)->refs++;	/* XXX: kobj_mtx */
184214501Srpaulo	TAILQ_INSERT_TAIL(&classes, lc, link);
185214501Srpaulo	return (0);
186214501Srpaulo}
187214501Srpaulo
188214501Srpaulostatic void
189214501Srpaulolinker_file_sysinit(linker_file_t lf)
190214501Srpaulo{
191214501Srpaulo	struct sysinit **start, **stop, **sipp, **xipp, *save;
192214501Srpaulo
193214501Srpaulo	KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n",
194214501Srpaulo	    lf->filename));
195214501Srpaulo
196214501Srpaulo	sx_assert(&kld_sx, SA_XLOCKED);
197214501Srpaulo
198214501Srpaulo	if (linker_file_lookup_set(lf, "sysinit_set", &start, &stop, NULL) != 0)
199214501Srpaulo		return;
200214501Srpaulo	/*
201346981Scy	 * Perform a bubble sort of the system initialization objects by
202346981Scy	 * their subsystem (primary key) and order (secondary key).
203214501Srpaulo	 *
204214501Srpaulo	 * Since some things care about execution order, this is the operation
205214501Srpaulo	 * which ensures continued function.
206214501Srpaulo	 */
207214501Srpaulo	for (sipp = start; sipp < stop; sipp++) {
208214501Srpaulo		for (xipp = sipp + 1; xipp < stop; xipp++) {
209214501Srpaulo			if ((*sipp)->subsystem < (*xipp)->subsystem ||
210346981Scy			    ((*sipp)->subsystem == (*xipp)->subsystem &&
211346981Scy			    (*sipp)->order <= (*xipp)->order))
212214501Srpaulo				continue;	/* skip */
213214501Srpaulo			save = *sipp;
214214501Srpaulo			*sipp = *xipp;
215214501Srpaulo			*xipp = save;
216214501Srpaulo		}
217214501Srpaulo	}
218214501Srpaulo
219214501Srpaulo	/*
220214501Srpaulo	 * Traverse the (now) ordered list of system initialization tasks.
221214501Srpaulo	 * Perform each task, and continue on to the next task.
222214501Srpaulo	 */
223214501Srpaulo	sx_xunlock(&kld_sx);
224214501Srpaulo	mtx_lock(&Giant);
225214501Srpaulo	for (sipp = start; sipp < stop; sipp++) {
226214501Srpaulo		if ((*sipp)->subsystem == SI_SUB_DUMMY)
227214501Srpaulo			continue;	/* skip dummy task(s) */
228214501Srpaulo
229214501Srpaulo		/* Call function */
230214501Srpaulo		(*((*sipp)->func)) ((*sipp)->udata);
231337817Scy	}
232337817Scy	mtx_unlock(&Giant);
233337817Scy	sx_xlock(&kld_sx);
234337817Scy}
235337817Scy
236337817Scystatic void
237337817Scylinker_file_sysuninit(linker_file_t lf)
238281806Srpaulo{
239281806Srpaulo	struct sysinit **start, **stop, **sipp, **xipp, *save;
240281806Srpaulo
241281806Srpaulo	KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n",
242252726Srpaulo	    lf->filename));
243252726Srpaulo
244252726Srpaulo	sx_assert(&kld_sx, SA_XLOCKED);
245252726Srpaulo
246252726Srpaulo	if (linker_file_lookup_set(lf, "sysuninit_set", &start, &stop,
247252726Srpaulo	    NULL) != 0)
248252726Srpaulo		return;
249252726Srpaulo
250252726Srpaulo	/*
251214501Srpaulo	 * Perform a reverse bubble sort of the system initialization objects
252214501Srpaulo	 * by their subsystem (primary key) and order (secondary key).
253214501Srpaulo	 *
254214501Srpaulo	 * Since some things care about execution order, this is the operation
255214501Srpaulo	 * which ensures continued function.
256281806Srpaulo	 */
257281806Srpaulo	for (sipp = start; sipp < stop; sipp++) {
258337817Scy		for (xipp = sipp + 1; xipp < stop; xipp++) {
259281806Srpaulo			if ((*sipp)->subsystem > (*xipp)->subsystem ||
260281806Srpaulo			    ((*sipp)->subsystem == (*xipp)->subsystem &&
261214501Srpaulo			    (*sipp)->order >= (*xipp)->order))
262214501Srpaulo				continue;	/* skip */
263214501Srpaulo			save = *sipp;
264252726Srpaulo			*sipp = *xipp;
265252726Srpaulo			*xipp = save;
266214501Srpaulo		}
267214501Srpaulo	}
268281806Srpaulo
269337817Scy	/*
270281806Srpaulo	 * Traverse the (now) ordered list of system initialization tasks.
271214501Srpaulo	 * Perform each task, and continue on to the next task.
272337817Scy	 */
273214501Srpaulo	sx_xunlock(&kld_sx);
274214501Srpaulo	mtx_lock(&Giant);
275214501Srpaulo	for (sipp = start; sipp < stop; sipp++) {
276281806Srpaulo		if ((*sipp)->subsystem == SI_SUB_DUMMY)
277281806Srpaulo			continue;	/* skip dummy task(s) */
278214501Srpaulo
279214501Srpaulo		/* Call function */
280337817Scy		(*((*sipp)->func)) ((*sipp)->udata);
281337817Scy	}
282337817Scy	mtx_unlock(&Giant);
283337817Scy	sx_xlock(&kld_sx);
284337817Scy}
285337817Scy
286337817Scystatic void
287337817Scylinker_file_register_sysctls(linker_file_t lf)
288337817Scy{
289337817Scy	struct sysctl_oid **start, **stop, **oidp;
290337817Scy
291337817Scy	KLD_DPF(FILE,
292337817Scy	    ("linker_file_register_sysctls: registering SYSCTLs for %s\n",
293337817Scy	    lf->filename));
294337817Scy
295337817Scy	sx_assert(&kld_sx, SA_XLOCKED);
296337817Scy
297337817Scy	if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
298337817Scy		return;
299337817Scy
300337817Scy	sx_xunlock(&kld_sx);
301337817Scy	sysctl_wlock();
302214501Srpaulo	for (oidp = start; oidp < stop; oidp++)
303214501Srpaulo		sysctl_register_oid(*oidp);
304214501Srpaulo	sysctl_wunlock();
305214501Srpaulo	sx_xlock(&kld_sx);
306214501Srpaulo}
307214501Srpaulo
308214501Srpaulostatic void
309252726Srpaulolinker_file_unregister_sysctls(linker_file_t lf)
310252726Srpaulo{
311252726Srpaulo	struct sysctl_oid **start, **stop, **oidp;
312252726Srpaulo
313252726Srpaulo	KLD_DPF(FILE, ("linker_file_unregister_sysctls: unregistering SYSCTLs"
314252726Srpaulo	    " for %s\n", lf->filename));
315252726Srpaulo
316252726Srpaulo	sx_assert(&kld_sx, SA_XLOCKED);
317252726Srpaulo
318252726Srpaulo	if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
319252726Srpaulo		return;
320252726Srpaulo
321252726Srpaulo	sx_xunlock(&kld_sx);
322214501Srpaulo	sysctl_wlock();
323252726Srpaulo	for (oidp = start; oidp < stop; oidp++)
324252726Srpaulo		sysctl_unregister_oid(*oidp);
325346981Scy	sysctl_wunlock();
326289549Srpaulo	sx_xlock(&kld_sx);
327289549Srpaulo}
328289549Srpaulo
329214501Srpaulostatic int
330214501Srpaulolinker_file_register_modules(linker_file_t lf)
331281806Srpaulo{
332346981Scy	struct mod_metadata **start, **stop, **mdp;
333351611Scy	const moduledata_t *moddata;
334252726Srpaulo	int first_error, error;
335252726Srpaulo
336252726Srpaulo	KLD_DPF(FILE, ("linker_file_register_modules: registering modules"
337281806Srpaulo	    " in %s\n", lf->filename));
338346981Scy
339281806Srpaulo	sx_assert(&kld_sx, SA_XLOCKED);
340281806Srpaulo
341214501Srpaulo	if (linker_file_lookup_set(lf, "modmetadata_set", &start,
342281806Srpaulo	    &stop, NULL) != 0) {
343281806Srpaulo		/*
344281806Srpaulo		 * This fallback should be unnecessary, but if we get booted
345281806Srpaulo		 * from boot2 instead of loader and we are missing our
346281806Srpaulo		 * metadata then we have to try the best we can.
347337817Scy		 */
348337817Scy		if (lf == linker_kernel_file) {
349337817Scy			start = SET_BEGIN(modmetadata_set);
350346981Scy			stop = SET_LIMIT(modmetadata_set);
351346981Scy		} else
352346981Scy			return (0);
353346981Scy	}
354346981Scy	first_error = 0;
355346981Scy	for (mdp = start; mdp < stop; mdp++) {
356346981Scy		if ((*mdp)->md_type != MDT_MODULE)
357346981Scy			continue;
358346981Scy		moddata = (*mdp)->md_data;
359346981Scy		KLD_DPF(FILE, ("Registering module %s in %s\n",
360346981Scy		    moddata->name, lf->filename));
361346981Scy		error = module_register(moddata, lf);
362346981Scy		if (error) {
363346981Scy			printf("Module %s failed to register: %d\n",
364346981Scy			    moddata->name, error);
365346981Scy			if (first_error == 0)
366346981Scy				first_error = error;
367346981Scy		}
368346981Scy	}
369346981Scy	return (first_error);
370346981Scy}
371346981Scy
372346981Scystatic void
373346981Scylinker_init_kernel_modules(void)
374346981Scy{
375346981Scy
376346981Scy	sx_xlock(&kld_sx);
377346981Scy	linker_file_register_modules(linker_kernel_file);
378346981Scy	sx_xunlock(&kld_sx);
379346981Scy}
380214501Srpaulo
381214501SrpauloSYSINIT(linker_kernel, SI_SUB_KLD, SI_ORDER_ANY, linker_init_kernel_modules,
382214501Srpaulo    0);
383214501Srpaulo
384214501Srpaulostatic int
385214501Srpaulolinker_load_file(const char *filename, linker_file_t *result)
386214501Srpaulo{
387214501Srpaulo	linker_class_t lc;
388214501Srpaulo	linker_file_t lf;
389214501Srpaulo	int foundfile, error, modules;
390214501Srpaulo
391214501Srpaulo	/* Refuse to load modules if securelevel raised */
392214501Srpaulo	if (prison0.pr_securelevel > 0)
393214501Srpaulo		return (EPERM);
394214501Srpaulo
395214501Srpaulo	sx_assert(&kld_sx, SA_XLOCKED);
396214501Srpaulo	lf = linker_find_file_by_name(filename);
397214501Srpaulo	if (lf) {
398214501Srpaulo		KLD_DPF(FILE, ("linker_load_file: file %s is already loaded,"
399214501Srpaulo		    " incrementing refs\n", filename));
400214501Srpaulo		*result = lf;
401214501Srpaulo		lf->refs++;
402214501Srpaulo		return (0);
403214501Srpaulo	}
404214501Srpaulo	foundfile = 0;
405214501Srpaulo	error = 0;
406214501Srpaulo
407214501Srpaulo	/*
408214501Srpaulo	 * We do not need to protect (lock) classes here because there is
409214501Srpaulo	 * no class registration past startup (SI_SUB_KLD, SI_ORDER_ANY)
410214501Srpaulo	 * and there is no class deregistration mechanism at this time.
411214501Srpaulo	 */
412214501Srpaulo	TAILQ_FOREACH(lc, &classes, link) {
413214501Srpaulo		KLD_DPF(FILE, ("linker_load_file: trying to load %s\n",
414214501Srpaulo		    filename));
415214501Srpaulo		error = LINKER_LOAD_FILE(lc, filename, &lf);
416214501Srpaulo		/*
417281806Srpaulo		 * If we got something other than ENOENT, then it exists but
418214501Srpaulo		 * we cannot load it for some other reason.
419337817Scy		 */
420337817Scy		if (error != ENOENT)
421252726Srpaulo			foundfile = 1;
422214501Srpaulo		if (lf) {
423214501Srpaulo			error = linker_file_register_modules(lf);
424214501Srpaulo			if (error == EEXIST) {
425214501Srpaulo				linker_file_unload(lf, LINKER_UNLOAD_FORCE);
426214501Srpaulo				return (error);
427214501Srpaulo			}
428214501Srpaulo			modules = !TAILQ_EMPTY(&lf->modules);
429214501Srpaulo			linker_file_register_sysctls(lf);
430214501Srpaulo			linker_file_sysinit(lf);
431214501Srpaulo			lf->flags |= LINKER_FILE_LINKED;
432214501Srpaulo
433214501Srpaulo			/*
434252726Srpaulo			 * If all of the modules in this file failed
435252726Srpaulo			 * to load, unload the file and return an
436252726Srpaulo			 * error of ENOEXEC.
437252726Srpaulo			 */
438252726Srpaulo			if (modules && TAILQ_EMPTY(&lf->modules)) {
439252726Srpaulo				linker_file_unload(lf, LINKER_UNLOAD_FORCE);
440252726Srpaulo				return (ENOEXEC);
441214501Srpaulo			}
442252726Srpaulo			EVENTHANDLER_INVOKE(kld_load, lf);
443252726Srpaulo			*result = lf;
444252726Srpaulo			return (0);
445252726Srpaulo		}
446252726Srpaulo	}
447252726Srpaulo	/*
448252726Srpaulo	 * Less than ideal, but tells the user whether it failed to load or
449252726Srpaulo	 * the module was not found.
450252726Srpaulo	 */
451252726Srpaulo	if (foundfile) {
452281806Srpaulo
453281806Srpaulo		/*
454281806Srpaulo		 * If the file type has not been recognized by the last try
455281806Srpaulo		 * printout a message before to fail.
456281806Srpaulo		 */
457281806Srpaulo		if (error == ENOSYS)
458281806Srpaulo			printf("linker_load_file: Unsupported file type\n");
459281806Srpaulo
460281806Srpaulo		/*
461214501Srpaulo		 * Format not recognized or otherwise unloadable.
462252726Srpaulo		 * When loading a module that is statically built into
463252726Srpaulo		 * the kernel EEXIST percolates back up as the return
464252726Srpaulo		 * value.  Preserve this so that apps like sysinstall
465214501Srpaulo		 * can recognize this special case and not post bogus
466252726Srpaulo		 * dialog boxes.
467214501Srpaulo		 */
468252726Srpaulo		if (error != EEXIST)
469252726Srpaulo			error = ENOEXEC;
470252726Srpaulo	} else
471252726Srpaulo		error = ENOENT;		/* Nothing found */
472252726Srpaulo	return (error);
473252726Srpaulo}
474252726Srpaulo
475252726Srpauloint
476252726Srpaulolinker_reference_module(const char *modname, struct mod_depend *verinfo,
477214501Srpaulo    linker_file_t *result)
478214501Srpaulo{
479214501Srpaulo	modlist_t mod;
480214501Srpaulo	int error;
481214501Srpaulo
482252726Srpaulo	sx_xlock(&kld_sx);
483252726Srpaulo	if ((mod = modlist_lookup2(modname, verinfo)) != NULL) {
484252726Srpaulo		*result = mod->container;
485252726Srpaulo		(*result)->refs++;
486214501Srpaulo		sx_xunlock(&kld_sx);
487214501Srpaulo		return (0);
488214501Srpaulo	}
489214501Srpaulo
490214501Srpaulo	error = linker_load_module(NULL, modname, NULL, verinfo, result);
491214501Srpaulo	sx_xunlock(&kld_sx);
492281806Srpaulo	return (error);
493214501Srpaulo}
494252726Srpaulo
495252726Srpauloint
496252726Srpaulolinker_release_module(const char *modname, struct mod_depend *verinfo,
497214501Srpaulo    linker_file_t lf)
498214501Srpaulo{
499214501Srpaulo	modlist_t mod;
500214501Srpaulo	int error;
501214501Srpaulo
502214501Srpaulo	sx_xlock(&kld_sx);
503214501Srpaulo	if (lf == NULL) {
504252726Srpaulo		KASSERT(modname != NULL,
505214501Srpaulo		    ("linker_release_module: no file or name"));
506252726Srpaulo		mod = modlist_lookup2(modname, verinfo);
507252726Srpaulo		if (mod == NULL) {
508214501Srpaulo			sx_xunlock(&kld_sx);
509214501Srpaulo			return (ESRCH);
510214501Srpaulo		}
511346981Scy		lf = mod->container;
512346981Scy	} else
513346981Scy		KASSERT(modname == NULL && verinfo == NULL,
514346981Scy		    ("linker_release_module: both file and name"));
515346981Scy	error =	linker_file_unload(lf, LINKER_UNLOAD_NORMAL);
516346981Scy	sx_xunlock(&kld_sx);
517346981Scy	return (error);
518252726Srpaulo}
519252726Srpaulo
520252726Srpaulostatic linker_file_t
521252726Srpaulolinker_find_file_by_name(const char *filename)
522214501Srpaulo{
523214501Srpaulo	linker_file_t lf;
524252726Srpaulo	char *koname;
525252726Srpaulo
526252726Srpaulo	koname = malloc(strlen(filename) + 4, M_LINKER, M_WAITOK);
527214501Srpaulo	sprintf(koname, "%s.ko", filename);
528281806Srpaulo
529281806Srpaulo	sx_assert(&kld_sx, SA_XLOCKED);
530281806Srpaulo	TAILQ_FOREACH(lf, &linker_files, link) {
531281806Srpaulo		if (strcmp(lf->filename, koname) == 0)
532281806Srpaulo			break;
533214501Srpaulo		if (strcmp(lf->filename, filename) == 0)
534214501Srpaulo			break;
535214501Srpaulo	}
536214501Srpaulo	free(koname, M_LINKER);
537214501Srpaulo	return (lf);
538214501Srpaulo}
539252726Srpaulo
540252726Srpaulostatic linker_file_t
541252726Srpaulolinker_find_file_by_id(int fileid)
542214501Srpaulo{
543214501Srpaulo	linker_file_t lf;
544214501Srpaulo
545214501Srpaulo	sx_assert(&kld_sx, SA_XLOCKED);
546281806Srpaulo	TAILQ_FOREACH(lf, &linker_files, link)
547252726Srpaulo		if (lf->id == fileid && lf->flags & LINKER_FILE_LINKED)
548214501Srpaulo			break;
549214501Srpaulo	return (lf);
550214501Srpaulo}
551214501Srpaulo
552214501Srpauloint
553214501Srpaulolinker_file_foreach(linker_predicate_t *predicate, void *context)
554337817Scy{
555214501Srpaulo	linker_file_t lf;
556214501Srpaulo	int retval = 0;
557214501Srpaulo
558281806Srpaulo	sx_xlock(&kld_sx);
559281806Srpaulo	TAILQ_FOREACH(lf, &linker_files, link) {
560281806Srpaulo		retval = predicate(lf, context);
561214501Srpaulo		if (retval != 0)
562252726Srpaulo			break;
563252726Srpaulo	}
564252726Srpaulo	sx_xunlock(&kld_sx);
565214501Srpaulo	return (retval);
566214501Srpaulo}
567281806Srpaulo
568214501Srpaulolinker_file_t
569214501Srpaulolinker_make_file(const char *pathname, linker_class_t lc)
570214501Srpaulo{
571214501Srpaulo	linker_file_t lf;
572214501Srpaulo	const char *filename;
573252726Srpaulo
574214501Srpaulo	if (!cold)
575214501Srpaulo		sx_assert(&kld_sx, SA_XLOCKED);
576214501Srpaulo	filename = linker_basename(pathname);
577214501Srpaulo
578214501Srpaulo	KLD_DPF(FILE, ("linker_make_file: new file, filename='%s' for pathname='%s'\n", filename, pathname));
579214501Srpaulo	lf = (linker_file_t)kobj_create((kobj_class_t)lc, M_LINKER, M_WAITOK);
580214501Srpaulo	if (lf == NULL)
581214501Srpaulo		return (NULL);
582214501Srpaulo	lf->ctors_addr = 0;
583214501Srpaulo	lf->ctors_size = 0;
584214501Srpaulo	lf->refs = 1;
585214501Srpaulo	lf->userrefs = 0;
586214501Srpaulo	lf->flags = 0;
587214501Srpaulo	lf->filename = strdup(filename, M_LINKER);
588214501Srpaulo	lf->pathname = strdup(pathname, M_LINKER);
589214501Srpaulo	LINKER_GET_NEXT_FILE_ID(lf->id);
590214501Srpaulo	lf->ndeps = 0;
591337817Scy	lf->deps = NULL;
592337817Scy	lf->loadcnt = ++loadcnt;
593252726Srpaulo	STAILQ_INIT(&lf->common);
594252726Srpaulo	TAILQ_INIT(&lf->modules);
595252726Srpaulo	TAILQ_INSERT_TAIL(&linker_files, lf, link);
596252726Srpaulo	return (lf);
597252726Srpaulo}
598252726Srpaulo
599214501Srpauloint
600252726Srpaulolinker_file_unload(linker_file_t file, int flags)
601214501Srpaulo{
602281806Srpaulo	module_t mod, next;
603281806Srpaulo	modlist_t ml, nextml;
604214501Srpaulo	struct common_symbol *cp;
605214501Srpaulo	int error, i;
606214501Srpaulo
607214501Srpaulo	/* Refuse to unload modules if securelevel raised. */
608214501Srpaulo	if (prison0.pr_securelevel > 0)
609214501Srpaulo		return (EPERM);
610214501Srpaulo
611214501Srpaulo	sx_assert(&kld_sx, SA_XLOCKED);
612214501Srpaulo	KLD_DPF(FILE, ("linker_file_unload: lf->refs=%d\n", file->refs));
613214501Srpaulo
614214501Srpaulo	/* Easy case of just dropping a reference. */
615281806Srpaulo	if (file->refs > 1) {
616281806Srpaulo		file->refs--;
617281806Srpaulo		return (0);
618281806Srpaulo	}
619281806Srpaulo
620281806Srpaulo	/* Give eventhandlers a chance to prevent the unload. */
621281806Srpaulo	error = 0;
622281806Srpaulo	EVENTHANDLER_INVOKE(kld_unload_try, file, &error);
623281806Srpaulo	if (error != 0)
624281806Srpaulo		return (EBUSY);
625281806Srpaulo
626281806Srpaulo	KLD_DPF(FILE, ("linker_file_unload: file is unloading,"
627214501Srpaulo	    " informing modules\n"));
628214501Srpaulo
629214501Srpaulo	/*
630214501Srpaulo	 * Quiesce all the modules to give them a chance to veto the unload.
631214501Srpaulo	 */
632214501Srpaulo	MOD_SLOCK;
633214501Srpaulo	for (mod = TAILQ_FIRST(&file->modules); mod;
634214501Srpaulo	     mod = module_getfnext(mod)) {
635214501Srpaulo
636214501Srpaulo		error = module_quiesce(mod);
637214501Srpaulo		if (error != 0 && flags != LINKER_UNLOAD_FORCE) {
638214501Srpaulo			KLD_DPF(FILE, ("linker_file_unload: module %s"
639214501Srpaulo			    " vetoed unload\n", module_getname(mod)));
640214501Srpaulo			/*
641214501Srpaulo			 * XXX: Do we need to tell all the quiesced modules
642214501Srpaulo			 * that they can resume work now via a new module
643214501Srpaulo			 * event?
644214501Srpaulo			 */
645281806Srpaulo			MOD_SUNLOCK;
646281806Srpaulo			return (error);
647346981Scy		}
648281806Srpaulo	}
649281806Srpaulo	MOD_SUNLOCK;
650281806Srpaulo
651337817Scy	/*
652337817Scy	 * Inform any modules associated with this file that they are
653281806Srpaulo	 * being unloaded.
654281806Srpaulo	 */
655281806Srpaulo	MOD_XLOCK;
656281806Srpaulo	for (mod = TAILQ_FIRST(&file->modules); mod; mod = next) {
657281806Srpaulo		next = module_getfnext(mod);
658346981Scy		MOD_XUNLOCK;
659281806Srpaulo
660281806Srpaulo		/*
661281806Srpaulo		 * Give the module a chance to veto the unload.
662281806Srpaulo		 */
663281806Srpaulo		if ((error = module_unload(mod)) != 0) {
664281806Srpaulo#ifdef KLD_DEBUG
665281806Srpaulo			MOD_SLOCK;
666281806Srpaulo			KLD_DPF(FILE, ("linker_file_unload: module %s"
667281806Srpaulo			    " failed unload\n", module_getname(mod)));
668281806Srpaulo			MOD_SUNLOCK;
669281806Srpaulo#endif
670281806Srpaulo			return (error);
671214501Srpaulo		}
672214501Srpaulo		MOD_XLOCK;
673214501Srpaulo		module_release(mod);
674351611Scy	}
675214501Srpaulo	MOD_XUNLOCK;
676214501Srpaulo
677214501Srpaulo	TAILQ_FOREACH_SAFE(ml, &found_modules, link, nextml) {
678214501Srpaulo		if (ml->container == file) {
679214501Srpaulo			TAILQ_REMOVE(&found_modules, ml, link);
680214501Srpaulo			free(ml, M_LINKER);
681214501Srpaulo		}
682214501Srpaulo	}
683214501Srpaulo
684214501Srpaulo	/*
685214501Srpaulo	 * Don't try to run SYSUNINITs if we are unloaded due to a
686214501Srpaulo	 * link error.
687214501Srpaulo	 */
688214501Srpaulo	if (file->flags & LINKER_FILE_LINKED) {
689214501Srpaulo		file->flags &= ~LINKER_FILE_LINKED;
690214501Srpaulo		linker_file_sysuninit(file);
691214501Srpaulo		linker_file_unregister_sysctls(file);
692214501Srpaulo	}
693214501Srpaulo	TAILQ_REMOVE(&linker_files, file, link);
694337817Scy
695337817Scy	if (file->deps) {
696337817Scy		for (i = 0; i < file->ndeps; i++)
697337817Scy			linker_file_unload(file->deps[i], flags);
698214501Srpaulo		free(file->deps, M_LINKER);
699351611Scy		file->deps = NULL;
700351611Scy	}
701351611Scy	while ((cp = STAILQ_FIRST(&file->common)) != NULL) {
702351611Scy		STAILQ_REMOVE_HEAD(&file->common, link);
703351611Scy		free(cp, M_LINKER);
704351611Scy	}
705351611Scy
706351611Scy	LINKER_UNLOAD(file);
707351611Scy
708281806Srpaulo	EVENTHANDLER_INVOKE(kld_unload, file->filename, file->address,
709281806Srpaulo	    file->size);
710281806Srpaulo
711281806Srpaulo	if (file->filename) {
712281806Srpaulo		free(file->filename, M_LINKER);
713281806Srpaulo		file->filename = NULL;
714281806Srpaulo	}
715281806Srpaulo	if (file->pathname) {
716281806Srpaulo		free(file->pathname, M_LINKER);
717214501Srpaulo		file->pathname = NULL;
718214501Srpaulo	}
719214501Srpaulo	kobj_delete((kobj_t) file, M_LINKER);
720214501Srpaulo	return (0);
721214501Srpaulo}
722214501Srpaulo
723214501Srpauloint
724281806Srpaulolinker_ctf_get(linker_file_t file, linker_ctf_t *lc)
725281806Srpaulo{
726214501Srpaulo	return (LINKER_CTF_GET(file, lc));
727337817Scy}
728337817Scy
729337817Scystatic int
730337817Scylinker_file_add_dependency(linker_file_t file, linker_file_t dep)
731337817Scy{
732214501Srpaulo	linker_file_t *newdeps;
733214501Srpaulo
734214501Srpaulo	sx_assert(&kld_sx, SA_XLOCKED);
735214501Srpaulo	file->deps = realloc(file->deps, (file->ndeps + 1) * sizeof(*newdeps),
736214501Srpaulo	    M_LINKER, M_WAITOK | M_ZERO);
737214501Srpaulo	file->deps[file->ndeps] = dep;
738214501Srpaulo	file->ndeps++;
739214501Srpaulo	KLD_DPF(FILE, ("linker_file_add_dependency:"
740281806Srpaulo	    " adding %s as dependency for %s\n",
741281806Srpaulo	    dep->filename, file->filename));
742281806Srpaulo	return (0);
743281806Srpaulo}
744337817Scy
745337817Scy/*
746252726Srpaulo * Locate a linker set and its contents.  This is a helper function to avoid
747214501Srpaulo * linker_if.h exposure elsewhere.  Note: firstp and lastp are really void **.
748337817Scy * This function is used in this file so we can avoid having lots of (void **)
749337817Scy * casts.
750337817Scy */
751214501Srpauloint
752214501Srpaulolinker_file_lookup_set(linker_file_t file, const char *name,
753337817Scy    void *firstp, void *lastp, int *countp)
754214501Srpaulo{
755214501Srpaulo
756214501Srpaulo	sx_assert(&kld_sx, SA_LOCKED);
757214501Srpaulo	return (LINKER_LOOKUP_SET(file, name, firstp, lastp, countp));
758214501Srpaulo}
759214501Srpaulo
760214501Srpaulo/*
761214501Srpaulo * List all functions in a file.
762214501Srpaulo */
763214501Srpauloint
764214501Srpaulolinker_file_function_listall(linker_file_t lf,
765214501Srpaulo    linker_function_nameval_callback_t callback_func, void *arg)
766214501Srpaulo{
767214501Srpaulo	return (LINKER_EACH_FUNCTION_NAMEVAL(lf, callback_func, arg));
768214501Srpaulo}
769214501Srpaulo
770214501Srpaulocaddr_t
771214501Srpaulolinker_file_lookup_symbol(linker_file_t file, const char *name, int deps)
772214501Srpaulo{
773214501Srpaulo	caddr_t sym;
774214501Srpaulo	int locked;
775214501Srpaulo
776214501Srpaulo	locked = sx_xlocked(&kld_sx);
777337817Scy	if (!locked)
778337817Scy		sx_xlock(&kld_sx);
779337817Scy	sym = linker_file_lookup_symbol_internal(file, name, deps);
780337817Scy	if (!locked)
781214501Srpaulo		sx_xunlock(&kld_sx);
782214501Srpaulo	return (sym);
783214501Srpaulo}
784214501Srpaulo
785214501Srpaulostatic caddr_t
786214501Srpaulolinker_file_lookup_symbol_internal(linker_file_t file, const char *name,
787252726Srpaulo    int deps)
788252726Srpaulo{
789252726Srpaulo	c_linker_sym_t sym;
790252726Srpaulo	linker_symval_t symval;
791252726Srpaulo	caddr_t address;
792337817Scy	size_t common_size = 0;
793337817Scy	int i;
794252726Srpaulo
795252726Srpaulo	sx_assert(&kld_sx, SA_XLOCKED);
796252726Srpaulo	KLD_DPF(SYM, ("linker_file_lookup_symbol: file=%p, name=%s, deps=%d\n",
797252726Srpaulo	    file, name, deps));
798252726Srpaulo
799214501Srpaulo	if (LINKER_LOOKUP_SYMBOL(file, name, &sym) == 0) {
800214501Srpaulo		LINKER_SYMBOL_VALUES(file, sym, &symval);
801214501Srpaulo		if (symval.value == 0)
802214501Srpaulo			/*
803214501Srpaulo			 * For commons, first look them up in the
804281806Srpaulo			 * dependencies and only allocate space if not found
805346981Scy			 * there.
806346981Scy			 */
807346981Scy			common_size = symval.size;
808346981Scy		else {
809346981Scy			KLD_DPF(SYM, ("linker_file_lookup_symbol: symbol"
810346981Scy			    ".value=%p\n", symval.value));
811346981Scy			return (symval.value);
812346981Scy		}
813346981Scy	}
814346981Scy	if (deps) {
815252726Srpaulo		for (i = 0; i < file->ndeps; i++) {
816252726Srpaulo			address = linker_file_lookup_symbol_internal(
817252726Srpaulo			    file->deps[i], name, 0);
818252726Srpaulo			if (address) {
819252726Srpaulo				KLD_DPF(SYM, ("linker_file_lookup_symbol:"
820252726Srpaulo				    " deps value=%p\n", address));
821214501Srpaulo				return (address);
822214501Srpaulo			}
823214501Srpaulo		}
824214501Srpaulo	}
825337817Scy	if (common_size > 0) {
826346981Scy		/*
827346981Scy		 * This is a common symbol which was not found in the
828214501Srpaulo		 * dependencies.  We maintain a simple common symbol table in
829252726Srpaulo		 * the file object.
830252726Srpaulo		 */
831252726Srpaulo		struct common_symbol *cp;
832252726Srpaulo
833252726Srpaulo		STAILQ_FOREACH(cp, &file->common, link) {
834252726Srpaulo			if (strcmp(cp->name, name) == 0) {
835214501Srpaulo				KLD_DPF(SYM, ("linker_file_lookup_symbol:"
836214501Srpaulo				    " old common value=%p\n", cp->address));
837214501Srpaulo				return (cp->address);
838252726Srpaulo			}
839252726Srpaulo		}
840252726Srpaulo		/*
841252726Srpaulo		 * Round the symbol size up to align.
842252726Srpaulo		 */
843337817Scy		common_size = (common_size + sizeof(int) - 1) & -sizeof(int);
844337817Scy		cp = malloc(sizeof(struct common_symbol)
845252726Srpaulo		    + common_size + strlen(name) + 1, M_LINKER,
846252726Srpaulo		    M_WAITOK | M_ZERO);
847252726Srpaulo		cp->address = (caddr_t)(cp + 1);
848252726Srpaulo		cp->name = cp->address + common_size;
849252726Srpaulo		strcpy(cp->name, name);
850214501Srpaulo		bzero(cp->address, common_size);
851214501Srpaulo		STAILQ_INSERT_TAIL(&file->common, cp, link);
852214501Srpaulo
853346981Scy		KLD_DPF(SYM, ("linker_file_lookup_symbol: new common"
854346981Scy		    " value=%p\n", cp->address));
855346981Scy		return (cp->address);
856346981Scy	}
857346981Scy	KLD_DPF(SYM, ("linker_file_lookup_symbol: fail\n"));
858346981Scy	return (0);
859346981Scy}
860346981Scy
861214501Srpaulo/*
862214501Srpaulo * Both DDB and stack(9) rely on the kernel linker to provide forward and
863281806Srpaulo * backward lookup of symbols.  However, DDB and sometimes stack(9) need to
864281806Srpaulo * do this in a lockfree manner.  We provide a set of internal helper
865252726Srpaulo * routines to perform these operations without locks, and then wrappers that
866214501Srpaulo * optionally lock.
867252726Srpaulo *
868252726Srpaulo * linker_debug_lookup() is ifdef DDB as currently it's only used by DDB.
869252726Srpaulo */
870252726Srpaulo#ifdef DDB
871252726Srpaulostatic int
872214501Srpaulolinker_debug_lookup(const char *symstr, c_linker_sym_t *sym)
873214501Srpaulo{
874214501Srpaulo	linker_file_t lf;
875214501Srpaulo
876337817Scy	TAILQ_FOREACH(lf, &linker_files, link) {
877214501Srpaulo		if (LINKER_LOOKUP_SYMBOL(lf, symstr, sym) == 0)
878252726Srpaulo			return (0);
879252726Srpaulo	}
880252726Srpaulo	return (ENOENT);
881252726Srpaulo}
882252726Srpaulo#endif
883252726Srpaulo
884214501Srpaulostatic int
885214501Srpaulolinker_debug_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp)
886214501Srpaulo{
887252726Srpaulo	linker_file_t lf;
888252726Srpaulo	c_linker_sym_t best, es;
889252726Srpaulo	u_long diff, bestdiff, off;
890252726Srpaulo
891252726Srpaulo	best = 0;
892252726Srpaulo	off = (uintptr_t)value;
893252726Srpaulo	bestdiff = off;
894252726Srpaulo	TAILQ_FOREACH(lf, &linker_files, link) {
895252726Srpaulo		if (LINKER_SEARCH_SYMBOL(lf, value, &es, &diff) != 0)
896252726Srpaulo			continue;
897252726Srpaulo		if (es != 0 && diff < bestdiff) {
898252726Srpaulo			best = es;
899252726Srpaulo			bestdiff = diff;
900252726Srpaulo		}
901252726Srpaulo		if (bestdiff == 0)
902252726Srpaulo			break;
903252726Srpaulo	}
904337817Scy	if (best) {
905337817Scy		*sym = best;
906337817Scy		*diffp = bestdiff;
907337817Scy		return (0);
908337817Scy	} else {
909337817Scy		*sym = 0;
910337817Scy		*diffp = off;
911337817Scy		return (ENOENT);
912337817Scy	}
913337817Scy}
914337817Scy
915337817Scystatic int
916337817Scylinker_debug_symbol_values(c_linker_sym_t sym, linker_symval_t *symval)
917337817Scy{
918337817Scy	linker_file_t lf;
919337817Scy
920337817Scy	TAILQ_FOREACH(lf, &linker_files, link) {
921337817Scy		if (LINKER_SYMBOL_VALUES(lf, sym, symval) == 0)
922337817Scy			return (0);
923337817Scy	}
924337817Scy	return (ENOENT);
925337817Scy}
926337817Scy
927337817Scystatic int
928337817Scylinker_debug_search_symbol_name(caddr_t value, char *buf, u_int buflen,
929337817Scy    long *offset)
930337817Scy{
931337817Scy	linker_symval_t symval;
932337817Scy	c_linker_sym_t sym;
933337817Scy	int error;
934337817Scy
935337817Scy	*offset = 0;
936337817Scy	error = linker_debug_search_symbol(value, &sym, offset);
937337817Scy	if (error)
938337817Scy		return (error);
939337817Scy	error = linker_debug_symbol_values(sym, &symval);
940337817Scy	if (error)
941337817Scy		return (error);
942337817Scy	strlcpy(buf, symval.name, buflen);
943337817Scy	return (0);
944337817Scy}
945337817Scy
946337817Scy/*
947337817Scy * DDB Helpers.  DDB has to look across multiple files with their own symbol
948337817Scy * tables and string tables.
949337817Scy *
950337817Scy * Note that we do not obey list locking protocols here.  We really don't need
951337817Scy * DDB to hang because somebody's got the lock held.  We'll take the chance
952337817Scy * that the files list is inconsistant instead.
953337817Scy */
954337817Scy#ifdef DDB
955337817Scyint
956337817Scylinker_ddb_lookup(const char *symstr, c_linker_sym_t *sym)
957337817Scy{
958337817Scy
959337817Scy	return (linker_debug_lookup(symstr, sym));
960337817Scy}
961337817Scy#endif
962337817Scy
963337817Scyint
964337817Scylinker_ddb_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp)
965337817Scy{
966337817Scy
967337817Scy	return (linker_debug_search_symbol(value, sym, diffp));
968337817Scy}
969337817Scy
970337817Scyint
971337817Scylinker_ddb_symbol_values(c_linker_sym_t sym, linker_symval_t *symval)
972337817Scy{
973337817Scy
974337817Scy	return (linker_debug_symbol_values(sym, symval));
975337817Scy}
976337817Scy
977337817Scyint
978337817Scylinker_ddb_search_symbol_name(caddr_t value, char *buf, u_int buflen,
979337817Scy    long *offset)
980337817Scy{
981337817Scy
982337817Scy	return (linker_debug_search_symbol_name(value, buf, buflen, offset));
983337817Scy}
984337817Scy
985337817Scy/*
986337817Scy * stack(9) helper for non-debugging environemnts.  Unlike DDB helpers, we do
987337817Scy * obey locking protocols, and offer a significantly less complex interface.
988337817Scy */
989337817Scyint
990337817Scylinker_search_symbol_name(caddr_t value, char *buf, u_int buflen,
991337817Scy    long *offset)
992337817Scy{
993337817Scy	int error;
994337817Scy
995337817Scy	sx_slock(&kld_sx);
996337817Scy	error = linker_debug_search_symbol_name(value, buf, buflen, offset);
997337817Scy	sx_sunlock(&kld_sx);
998337817Scy	return (error);
999337817Scy}
1000337817Scy
1001337817Scy/*
1002337817Scy * Syscalls.
1003337817Scy */
1004337817Scyint
1005337817Scykern_kldload(struct thread *td, const char *file, int *fileid)
1006337817Scy{
1007337817Scy	const char *kldname, *modname;
1008337817Scy	linker_file_t lf;
1009337817Scy	int error;
1010337817Scy
1011337817Scy	if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
1012337817Scy		return (error);
1013337817Scy
1014337817Scy	if ((error = priv_check(td, PRIV_KLD_LOAD)) != 0)
1015337817Scy		return (error);
1016337817Scy
1017337817Scy	/*
1018337817Scy	 * It is possible that kldloaded module will attach a new ifnet,
1019337817Scy	 * so vnet context must be set when this ocurs.
1020337817Scy	 */
1021337817Scy	CURVNET_SET(TD_TO_VNET(td));
1022337817Scy
1023289549Srpaulo	/*
1024214501Srpaulo	 * If file does not contain a qualified name or any dot in it
1025214501Srpaulo	 * (kldname.ko, or kldname.ver.ko) treat it as an interface
1026214501Srpaulo	 * name.
1027214501Srpaulo	 */
1028214501Srpaulo	if (strchr(file, '/') || strchr(file, '.')) {
1029289549Srpaulo		kldname = file;
1030214501Srpaulo		modname = NULL;
1031214501Srpaulo	} else {
1032289549Srpaulo		kldname = NULL;
1033289549Srpaulo		modname = file;
1034214501Srpaulo	}
1035337817Scy
1036337817Scy	sx_xlock(&kld_sx);
1037281806Srpaulo	error = linker_load_module(kldname, modname, NULL, NULL, &lf);
1038214501Srpaulo	if (error) {
1039214501Srpaulo		sx_xunlock(&kld_sx);
1040281806Srpaulo		goto done;
1041281806Srpaulo	}
1042214501Srpaulo	lf->userrefs++;
1043214501Srpaulo	if (fileid != NULL)
1044289549Srpaulo		*fileid = lf->id;
1045289549Srpaulo	sx_xunlock(&kld_sx);
1046289549Srpaulo
1047289549Srpaulodone:
1048289549Srpaulo	CURVNET_RESTORE();
1049289549Srpaulo	return (error);
1050289549Srpaulo}
1051289549Srpaulo
1052214501Srpauloint
1053214501Srpaulosys_kldload(struct thread *td, struct kldload_args *uap)
1054214501Srpaulo{
1055214501Srpaulo	char *pathname = NULL;
1056214501Srpaulo	int error, fileid;
1057281806Srpaulo
1058281806Srpaulo	td->td_retval[0] = -1;
1059337817Scy
1060337817Scy	pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
1061337817Scy	error = copyinstr(uap->file, pathname, MAXPATHLEN, NULL);
1062337817Scy	if (error == 0) {
1063337817Scy		error = kern_kldload(td, pathname, &fileid);
1064337817Scy		if (error == 0)
1065337817Scy			td->td_retval[0] = fileid;
1066214501Srpaulo	}
1067214501Srpaulo	free(pathname, M_TEMP);
1068289549Srpaulo	return (error);
1069289549Srpaulo}
1070289549Srpaulo
1071289549Srpauloint
1072214501Srpaulokern_kldunload(struct thread *td, int fileid, int flags)
1073214501Srpaulo{
1074214501Srpaulo	linker_file_t lf;
1075214501Srpaulo	int error = 0;
1076214501Srpaulo
1077214501Srpaulo	if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
1078214501Srpaulo		return (error);
1079252726Srpaulo
1080214501Srpaulo	if ((error = priv_check(td, PRIV_KLD_UNLOAD)) != 0)
1081214501Srpaulo		return (error);
1082214501Srpaulo
1083214501Srpaulo	CURVNET_SET(TD_TO_VNET(td));
1084214501Srpaulo	sx_xlock(&kld_sx);
1085281806Srpaulo	lf = linker_find_file_by_id(fileid);
1086281806Srpaulo	if (lf) {
1087289549Srpaulo		KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs));
1088281806Srpaulo
1089289549Srpaulo		if (lf->userrefs == 0) {
1090281806Srpaulo			/*
1091214501Srpaulo			 * XXX: maybe LINKER_UNLOAD_FORCE should override ?
1092214501Srpaulo			 */
1093214501Srpaulo			printf("kldunload: attempt to unload file that was"
1094214501Srpaulo			    " loaded by the kernel\n");
1095214501Srpaulo			error = EBUSY;
1096214501Srpaulo		} else {
1097214501Srpaulo			lf->userrefs--;
1098214501Srpaulo			error = linker_file_unload(lf, flags);
1099214501Srpaulo			if (error)
1100214501Srpaulo				lf->userrefs++;
1101214501Srpaulo		}
1102214501Srpaulo	} else
1103281806Srpaulo		error = ENOENT;
1104281806Srpaulo	sx_xunlock(&kld_sx);
1105281806Srpaulo
1106214501Srpaulo	CURVNET_RESTORE();
1107214501Srpaulo	return (error);
1108214501Srpaulo}
1109214501Srpaulo
1110214501Srpauloint
1111214501Srpaulosys_kldunload(struct thread *td, struct kldunload_args *uap)
1112214501Srpaulo{
1113214501Srpaulo
1114214501Srpaulo	return (kern_kldunload(td, uap->fileid, LINKER_UNLOAD_NORMAL));
1115214501Srpaulo}
1116214501Srpaulo
1117214501Srpauloint
1118214501Srpaulosys_kldunloadf(struct thread *td, struct kldunloadf_args *uap)
1119214501Srpaulo{
1120214501Srpaulo
1121214501Srpaulo	if (uap->flags != LINKER_UNLOAD_NORMAL &&
1122214501Srpaulo	    uap->flags != LINKER_UNLOAD_FORCE)
1123214501Srpaulo		return (EINVAL);
1124214501Srpaulo	return (kern_kldunload(td, uap->fileid, uap->flags));
1125214501Srpaulo}
1126214501Srpaulo
1127214501Srpauloint
1128214501Srpaulosys_kldfind(struct thread *td, struct kldfind_args *uap)
1129214501Srpaulo{
1130214501Srpaulo	char *pathname;
1131337817Scy	const char *filename;
1132337817Scy	linker_file_t lf;
1133337817Scy	int error;
1134337817Scy
1135214501Srpaulo#ifdef MAC
1136214501Srpaulo	error = mac_kld_check_stat(td->td_ucred);
1137214501Srpaulo	if (error)
1138214501Srpaulo		return (error);
1139252726Srpaulo#endif
1140252726Srpaulo
1141252726Srpaulo	td->td_retval[0] = -1;
1142214501Srpaulo
1143214501Srpaulo	pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
1144214501Srpaulo	if ((error = copyinstr(uap->file, pathname, MAXPATHLEN, NULL)) != 0)
1145214501Srpaulo		goto out;
1146281806Srpaulo
1147214501Srpaulo	filename = linker_basename(pathname);
1148214501Srpaulo	sx_xlock(&kld_sx);
1149214501Srpaulo	lf = linker_find_file_by_name(filename);
1150214501Srpaulo	if (lf)
1151214501Srpaulo		td->td_retval[0] = lf->id;
1152281806Srpaulo	else
1153281806Srpaulo		error = ENOENT;
1154281806Srpaulo	sx_xunlock(&kld_sx);
1155281806Srpauloout:
1156281806Srpaulo	free(pathname, M_TEMP);
1157281806Srpaulo	return (error);
1158281806Srpaulo}
1159281806Srpaulo
1160281806Srpauloint
1161214501Srpaulosys_kldnext(struct thread *td, struct kldnext_args *uap)
1162214501Srpaulo{
1163214501Srpaulo	linker_file_t lf;
1164214501Srpaulo	int error = 0;
1165214501Srpaulo
1166214501Srpaulo#ifdef MAC
1167214501Srpaulo	error = mac_kld_check_stat(td->td_ucred);
1168214501Srpaulo	if (error)
1169214501Srpaulo		return (error);
1170214501Srpaulo#endif
1171214501Srpaulo
1172214501Srpaulo	sx_xlock(&kld_sx);
1173214501Srpaulo	if (uap->fileid == 0)
1174214501Srpaulo		lf = TAILQ_FIRST(&linker_files);
1175214501Srpaulo	else {
1176214501Srpaulo		lf = linker_find_file_by_id(uap->fileid);
1177214501Srpaulo		if (lf == NULL) {
1178214501Srpaulo			error = ENOENT;
1179214501Srpaulo			goto out;
1180214501Srpaulo		}
1181214501Srpaulo		lf = TAILQ_NEXT(lf, link);
1182214501Srpaulo	}
1183214501Srpaulo
1184214501Srpaulo	/* Skip partially loaded files. */
1185214501Srpaulo	while (lf != NULL && !(lf->flags & LINKER_FILE_LINKED))
1186214501Srpaulo		lf = TAILQ_NEXT(lf, link);
1187214501Srpaulo
1188214501Srpaulo	if (lf)
1189214501Srpaulo		td->td_retval[0] = lf->id;
1190214501Srpaulo	else
1191214501Srpaulo		td->td_retval[0] = 0;
1192346981Scyout:
1193346981Scy	sx_xunlock(&kld_sx);
1194346981Scy	return (error);
1195346981Scy}
1196346981Scy
1197346981Scyint
1198346981Scysys_kldstat(struct thread *td, struct kldstat_args *uap)
1199346981Scy{
1200346981Scy	struct kld_file_stat stat;
1201346981Scy	int error, version;
1202346981Scy
1203346981Scy	/*
1204346981Scy	 * Check the version of the user's structure.
1205346981Scy	 */
1206346981Scy	if ((error = copyin(&uap->stat->version, &version, sizeof(version)))
1207346981Scy	    != 0)
1208346981Scy		return (error);
1209346981Scy	if (version != sizeof(struct kld_file_stat_1) &&
1210346981Scy	    version != sizeof(struct kld_file_stat))
1211346981Scy		return (EINVAL);
1212346981Scy
1213346981Scy	error = kern_kldstat(td, uap->fileid, &stat);
1214346981Scy	if (error != 0)
1215346981Scy		return (error);
1216346981Scy	return (copyout(&stat, uap->stat, version));
1217346981Scy}
1218252726Srpaulo
1219252726Srpauloint
1220252726Srpaulokern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat)
1221252726Srpaulo{
1222281806Srpaulo	linker_file_t lf;
1223252726Srpaulo	int namelen;
1224252726Srpaulo#ifdef MAC
1225281806Srpaulo	int error;
1226252726Srpaulo
1227252726Srpaulo	error = mac_kld_check_stat(td->td_ucred);
1228252726Srpaulo	if (error)
1229252726Srpaulo		return (error);
1230252726Srpaulo#endif
1231281806Srpaulo
1232281806Srpaulo	sx_xlock(&kld_sx);
1233281806Srpaulo	lf = linker_find_file_by_id(fileid);
1234281806Srpaulo	if (lf == NULL) {
1235281806Srpaulo		sx_xunlock(&kld_sx);
1236252726Srpaulo		return (ENOENT);
1237252726Srpaulo	}
1238252726Srpaulo
1239252726Srpaulo	/* Version 1 fields: */
1240252726Srpaulo	namelen = strlen(lf->filename) + 1;
1241252726Srpaulo	if (namelen > MAXPATHLEN)
1242252726Srpaulo		namelen = MAXPATHLEN;
1243281806Srpaulo	bcopy(lf->filename, &stat->name[0], namelen);
1244281806Srpaulo	stat->refs = lf->refs;
1245281806Srpaulo	stat->id = lf->id;
1246281806Srpaulo	stat->address = lf->address;
1247281806Srpaulo	stat->size = lf->size;
1248252726Srpaulo	/* Version 2 fields: */
1249281806Srpaulo	namelen = strlen(lf->pathname) + 1;
1250252726Srpaulo	if (namelen > MAXPATHLEN)
1251281806Srpaulo		namelen = MAXPATHLEN;
1252281806Srpaulo	bcopy(lf->pathname, &stat->pathname[0], namelen);
1253281806Srpaulo	sx_xunlock(&kld_sx);
1254281806Srpaulo
1255252726Srpaulo	td->td_retval[0] = 0;
1256346981Scy	return (0);
1257346981Scy}
1258281806Srpaulo
1259346981Scyint
1260346981Scysys_kldfirstmod(struct thread *td, struct kldfirstmod_args *uap)
1261281806Srpaulo{
1262281806Srpaulo	linker_file_t lf;
1263281806Srpaulo	module_t mp;
1264281806Srpaulo	int error = 0;
1265281806Srpaulo
1266281806Srpaulo#ifdef MAC
1267281806Srpaulo	error = mac_kld_check_stat(td->td_ucred);
1268281806Srpaulo	if (error)
1269281806Srpaulo		return (error);
1270281806Srpaulo#endif
1271346981Scy
1272346981Scy	sx_xlock(&kld_sx);
1273346981Scy	lf = linker_find_file_by_id(uap->fileid);
1274346981Scy	if (lf) {
1275346981Scy		MOD_SLOCK;
1276281806Srpaulo		mp = TAILQ_FIRST(&lf->modules);
1277346981Scy		if (mp != NULL)
1278346981Scy			td->td_retval[0] = module_getid(mp);
1279346981Scy		else
1280252726Srpaulo			td->td_retval[0] = 0;
1281281806Srpaulo		MOD_SUNLOCK;
1282281806Srpaulo	} else
1283346981Scy		error = ENOENT;
1284346981Scy	sx_xunlock(&kld_sx);
1285281806Srpaulo	return (error);
1286281806Srpaulo}
1287252726Srpaulo
1288252726Srpauloint
1289281806Srpaulosys_kldsym(struct thread *td, struct kldsym_args *uap)
1290281806Srpaulo{
1291281806Srpaulo	char *symstr = NULL;
1292252726Srpaulo	c_linker_sym_t sym;
1293289549Srpaulo	linker_symval_t symval;
1294289549Srpaulo	linker_file_t lf;
1295289549Srpaulo	struct kld_sym_lookup lookup;
1296289549Srpaulo	int error = 0;
1297289549Srpaulo
1298289549Srpaulo#ifdef MAC
1299289549Srpaulo	error = mac_kld_check_stat(td->td_ucred);
1300289549Srpaulo	if (error)
1301289549Srpaulo		return (error);
1302289549Srpaulo#endif
1303252726Srpaulo
1304252726Srpaulo	if ((error = copyin(uap->data, &lookup, sizeof(lookup))) != 0)
1305252726Srpaulo		return (error);
1306214501Srpaulo	if (lookup.version != sizeof(lookup) ||
1307214501Srpaulo	    uap->cmd != KLDSYM_LOOKUP)
1308214501Srpaulo		return (EINVAL);
1309337817Scy	symstr = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
1310337817Scy	if ((error = copyinstr(lookup.symname, symstr, MAXPATHLEN, NULL)) != 0)
1311337817Scy		goto out;
1312337817Scy	sx_xlock(&kld_sx);
1313337817Scy	if (uap->fileid != 0) {
1314337817Scy		lf = linker_find_file_by_id(uap->fileid);
1315337817Scy		if (lf == NULL)
1316337817Scy			error = ENOENT;
1317214501Srpaulo		else if (LINKER_LOOKUP_SYMBOL(lf, symstr, &sym) == 0 &&
1318214501Srpaulo		    LINKER_SYMBOL_VALUES(lf, sym, &symval) == 0) {
1319214501Srpaulo			lookup.symvalue = (uintptr_t) symval.value;
1320214501Srpaulo			lookup.symsize = symval.size;
1321214501Srpaulo			error = copyout(&lookup, uap->data, sizeof(lookup));
1322252726Srpaulo		} else
1323214501Srpaulo			error = ENOENT;
1324214501Srpaulo	} else {
1325214501Srpaulo		TAILQ_FOREACH(lf, &linker_files, link) {
1326252726Srpaulo			if (LINKER_LOOKUP_SYMBOL(lf, symstr, &sym) == 0 &&
1327252726Srpaulo			    LINKER_SYMBOL_VALUES(lf, sym, &symval) == 0) {
1328252726Srpaulo				lookup.symvalue = (uintptr_t)symval.value;
1329252726Srpaulo				lookup.symsize = symval.size;
1330337817Scy				error = copyout(&lookup, uap->data,
1331252726Srpaulo				    sizeof(lookup));
1332252726Srpaulo				break;
1333337817Scy			}
1334252726Srpaulo		}
1335214501Srpaulo		if (lf == NULL)
1336252726Srpaulo			error = ENOENT;
1337252726Srpaulo	}
1338214501Srpaulo	sx_xunlock(&kld_sx);
1339252726Srpauloout:
1340346981Scy	free(symstr, M_TEMP);
1341346981Scy	return (error);
1342346981Scy}
1343346981Scy
1344346981Scy/*
1345346981Scy * Preloaded module support
1346346981Scy */
1347346981Scy
1348346981Scystatic modlist_t
1349346981Scymodlist_lookup(const char *name, int ver)
1350346981Scy{
1351346981Scy	modlist_t mod;
1352346981Scy
1353346981Scy	TAILQ_FOREACH(mod, &found_modules, link) {
1354252726Srpaulo		if (strcmp(mod->name, name) == 0 &&
1355252726Srpaulo		    (ver == 0 || mod->version == ver))
1356252726Srpaulo			return (mod);
1357252726Srpaulo	}
1358252726Srpaulo	return (NULL);
1359252726Srpaulo}
1360214501Srpaulo
1361252726Srpaulostatic modlist_t
1362252726Srpaulomodlist_lookup2(const char *name, const struct mod_depend *verinfo)
1363252726Srpaulo{
1364252726Srpaulo	modlist_t mod, bestmod;
1365252726Srpaulo	int ver;
1366252726Srpaulo
1367252726Srpaulo	if (verinfo == NULL)
1368252726Srpaulo		return (modlist_lookup(name, 0));
1369252726Srpaulo	bestmod = NULL;
1370252726Srpaulo	TAILQ_FOREACH(mod, &found_modules, link) {
1371252726Srpaulo		if (strcmp(mod->name, name) != 0)
1372252726Srpaulo			continue;
1373252726Srpaulo		ver = mod->version;
1374252726Srpaulo		if (ver == verinfo->md_ver_preferred)
1375252726Srpaulo			return (mod);
1376252726Srpaulo		if (ver >= verinfo->md_ver_minimum &&
1377252726Srpaulo		    ver <= verinfo->md_ver_maximum &&
1378252726Srpaulo		    (bestmod == NULL || ver > bestmod->version))
1379252726Srpaulo			bestmod = mod;
1380252726Srpaulo	}
1381252726Srpaulo	return (bestmod);
1382252726Srpaulo}
1383252726Srpaulo
1384252726Srpaulostatic modlist_t
1385281806Srpaulomodlist_newmodule(const char *modname, int version, linker_file_t container)
1386281806Srpaulo{
1387337817Scy	modlist_t mod;
1388337817Scy
1389337817Scy	mod = malloc(sizeof(struct modlist), M_LINKER, M_NOWAIT | M_ZERO);
1390337817Scy	if (mod == NULL)
1391337817Scy		panic("no memory for module list");
1392337817Scy	mod->container = container;
1393337817Scy	mod->name = modname;
1394337817Scy	mod->version = version;
1395337817Scy	TAILQ_INSERT_TAIL(&found_modules, mod, link);
1396337817Scy	return (mod);
1397337817Scy}
1398337817Scy
1399337817Scystatic void
1400346981Scylinker_addmodules(linker_file_t lf, struct mod_metadata **start,
1401346981Scy    struct mod_metadata **stop, int preload)
1402346981Scy{
1403346981Scy	struct mod_metadata *mp, **mdp;
1404346981Scy	const char *modname;
1405346981Scy	int ver;
1406346981Scy
1407346981Scy	for (mdp = start; mdp < stop; mdp++) {
1408346981Scy		mp = *mdp;
1409337817Scy		if (mp->md_type != MDT_VERSION)
1410337817Scy			continue;
1411337817Scy		modname = mp->md_cval;
1412281806Srpaulo		ver = ((const struct mod_version *)mp->md_data)->mv_version;
1413281806Srpaulo		if (modlist_lookup(modname, ver) != NULL) {
1414281806Srpaulo			printf("module %s already present!\n", modname);
1415281806Srpaulo			/* XXX what can we do? this is a build error. :-( */
1416281806Srpaulo			continue;
1417346981Scy		}
1418281806Srpaulo		modlist_newmodule(modname, ver, lf);
1419281806Srpaulo	}
1420281806Srpaulo}
1421281806Srpaulo
1422281806Srpaulostatic void
1423281806Srpaulolinker_preload(void *arg)
1424281806Srpaulo{
1425281806Srpaulo	caddr_t modptr;
1426281806Srpaulo	const char *modname, *nmodname;
1427281806Srpaulo	char *modtype;
1428281806Srpaulo	linker_file_t lf, nlf;
1429281806Srpaulo	linker_class_t lc;
1430281806Srpaulo	int error;
1431281806Srpaulo	linker_file_list_t loaded_files;
1432281806Srpaulo	linker_file_list_t depended_files;
1433281806Srpaulo	struct mod_metadata *mp, *nmp;
1434346981Scy	struct mod_metadata **start, **stop, **mdp, **nmdp;
1435281806Srpaulo	const struct mod_depend *verinfo;
1436281806Srpaulo	int nver;
1437281806Srpaulo	int resolves;
1438281806Srpaulo	modlist_t mod;
1439281806Srpaulo	struct sysinit **si_start, **si_stop;
1440281806Srpaulo
1441281806Srpaulo	TAILQ_INIT(&loaded_files);
1442281806Srpaulo	TAILQ_INIT(&depended_files);
1443281806Srpaulo	TAILQ_INIT(&found_modules);
1444346981Scy	error = 0;
1445346981Scy
1446346981Scy	modptr = NULL;
1447346981Scy	sx_xlock(&kld_sx);
1448346981Scy	while ((modptr = preload_search_next_name(modptr)) != NULL) {
1449346981Scy		modname = (char *)preload_search_info(modptr, MODINFO_NAME);
1450346981Scy		modtype = (char *)preload_search_info(modptr, MODINFO_TYPE);
1451346981Scy		if (modname == NULL) {
1452346981Scy			printf("Preloaded module at %p does not have a"
1453346981Scy			    " name!\n", modptr);
1454346981Scy			continue;
1455346981Scy		}
1456346981Scy		if (modtype == NULL) {
1457346981Scy			printf("Preloaded module at %p does not have a type!\n",
1458346981Scy			    modptr);
1459346981Scy			continue;
1460346981Scy		}
1461346981Scy		if (bootverbose)
1462346981Scy			printf("Preloaded %s \"%s\" at %p.\n", modtype, modname,
1463346981Scy			    modptr);
1464346981Scy		lf = NULL;
1465346981Scy		TAILQ_FOREACH(lc, &classes, link) {
1466346981Scy			error = LINKER_LINK_PRELOAD(lc, modname, &lf);
1467346981Scy			if (!error)
1468346981Scy				break;
1469346981Scy			lf = NULL;
1470346981Scy		}
1471346981Scy		if (lf)
1472346981Scy			TAILQ_INSERT_TAIL(&loaded_files, lf, loaded);
1473346981Scy	}
1474346981Scy
1475346981Scy	/*
1476346981Scy	 * First get a list of stuff in the kernel.
1477346981Scy	 */
1478346981Scy	if (linker_file_lookup_set(linker_kernel_file, MDT_SETNAME, &start,
1479346981Scy	    &stop, NULL) == 0)
1480346981Scy		linker_addmodules(linker_kernel_file, start, stop, 1);
1481346981Scy
1482346981Scy	/*
1483346981Scy	 * This is a once-off kinky bubble sort to resolve relocation
1484346981Scy	 * dependency requirements.
1485346981Scy	 */
1486346981Scyrestart:
1487346981Scy	TAILQ_FOREACH(lf, &loaded_files, loaded) {
1488346981Scy		error = linker_file_lookup_set(lf, MDT_SETNAME, &start,
1489		    &stop, NULL);
1490		/*
1491		 * First, look to see if we would successfully link with this
1492		 * stuff.
1493		 */
1494		resolves = 1;	/* unless we know otherwise */
1495		if (!error) {
1496			for (mdp = start; mdp < stop; mdp++) {
1497				mp = *mdp;
1498				if (mp->md_type != MDT_DEPEND)
1499					continue;
1500				modname = mp->md_cval;
1501				verinfo = mp->md_data;
1502				for (nmdp = start; nmdp < stop; nmdp++) {
1503					nmp = *nmdp;
1504					if (nmp->md_type != MDT_VERSION)
1505						continue;
1506					nmodname = nmp->md_cval;
1507					if (strcmp(modname, nmodname) == 0)
1508						break;
1509				}
1510				if (nmdp < stop)   /* it's a self reference */
1511					continue;
1512
1513				/*
1514				 * ok, the module isn't here yet, we
1515				 * are not finished
1516				 */
1517				if (modlist_lookup2(modname, verinfo) == NULL)
1518					resolves = 0;
1519			}
1520		}
1521		/*
1522		 * OK, if we found our modules, we can link.  So, "provide"
1523		 * the modules inside and add it to the end of the link order
1524		 * list.
1525		 */
1526		if (resolves) {
1527			if (!error) {
1528				for (mdp = start; mdp < stop; mdp++) {
1529					mp = *mdp;
1530					if (mp->md_type != MDT_VERSION)
1531						continue;
1532					modname = mp->md_cval;
1533					nver = ((const struct mod_version *)
1534					    mp->md_data)->mv_version;
1535					if (modlist_lookup(modname,
1536					    nver) != NULL) {
1537						printf("module %s already"
1538						    " present!\n", modname);
1539						TAILQ_REMOVE(&loaded_files,
1540						    lf, loaded);
1541						linker_file_unload(lf,
1542						    LINKER_UNLOAD_FORCE);
1543						/* we changed tailq next ptr */
1544						goto restart;
1545					}
1546					modlist_newmodule(modname, nver, lf);
1547				}
1548			}
1549			TAILQ_REMOVE(&loaded_files, lf, loaded);
1550			TAILQ_INSERT_TAIL(&depended_files, lf, loaded);
1551			/*
1552			 * Since we provided modules, we need to restart the
1553			 * sort so that the previous files that depend on us
1554			 * have a chance. Also, we've busted the tailq next
1555			 * pointer with the REMOVE.
1556			 */
1557			goto restart;
1558		}
1559	}
1560
1561	/*
1562	 * At this point, we check to see what could not be resolved..
1563	 */
1564	while ((lf = TAILQ_FIRST(&loaded_files)) != NULL) {
1565		TAILQ_REMOVE(&loaded_files, lf, loaded);
1566		printf("KLD file %s is missing dependencies\n", lf->filename);
1567		linker_file_unload(lf, LINKER_UNLOAD_FORCE);
1568	}
1569
1570	/*
1571	 * We made it. Finish off the linking in the order we determined.
1572	 */
1573	TAILQ_FOREACH_SAFE(lf, &depended_files, loaded, nlf) {
1574		if (linker_kernel_file) {
1575			linker_kernel_file->refs++;
1576			error = linker_file_add_dependency(lf,
1577			    linker_kernel_file);
1578			if (error)
1579				panic("cannot add dependency");
1580		}
1581		lf->userrefs++;	/* so we can (try to) kldunload it */
1582		error = linker_file_lookup_set(lf, MDT_SETNAME, &start,
1583		    &stop, NULL);
1584		if (!error) {
1585			for (mdp = start; mdp < stop; mdp++) {
1586				mp = *mdp;
1587				if (mp->md_type != MDT_DEPEND)
1588					continue;
1589				modname = mp->md_cval;
1590				verinfo = mp->md_data;
1591				mod = modlist_lookup2(modname, verinfo);
1592				if (mod == NULL) {
1593					printf("KLD file %s - cannot find "
1594					    "dependency \"%s\"\n",
1595					    lf->filename, modname);
1596					goto fail;
1597				}
1598				/* Don't count self-dependencies */
1599				if (lf == mod->container)
1600					continue;
1601				mod->container->refs++;
1602				error = linker_file_add_dependency(lf,
1603				    mod->container);
1604				if (error)
1605					panic("cannot add dependency");
1606			}
1607		}
1608		/*
1609		 * Now do relocation etc using the symbol search paths
1610		 * established by the dependencies
1611		 */
1612		error = LINKER_LINK_PRELOAD_FINISH(lf);
1613		if (error) {
1614			printf("KLD file %s - could not finalize loading\n",
1615			    lf->filename);
1616			goto fail;
1617		}
1618		linker_file_register_modules(lf);
1619		if (linker_file_lookup_set(lf, "sysinit_set", &si_start,
1620		    &si_stop, NULL) == 0)
1621			sysinit_add(si_start, si_stop);
1622		linker_file_register_sysctls(lf);
1623		lf->flags |= LINKER_FILE_LINKED;
1624		continue;
1625fail:
1626		TAILQ_REMOVE(&depended_files, lf, loaded);
1627		linker_file_unload(lf, LINKER_UNLOAD_FORCE);
1628	}
1629	sx_xunlock(&kld_sx);
1630	/* woohoo! we made it! */
1631}
1632
1633SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0);
1634
1635/*
1636 * Search for a not-loaded module by name.
1637 *
1638 * Modules may be found in the following locations:
1639 *
1640 * - preloaded (result is just the module name) - on disk (result is full path
1641 * to module)
1642 *
1643 * If the module name is qualified in any way (contains path, etc.) the we
1644 * simply return a copy of it.
1645 *
1646 * The search path can be manipulated via sysctl.  Note that we use the ';'
1647 * character as a separator to be consistent with the bootloader.
1648 */
1649
1650static char linker_hintfile[] = "linker.hints";
1651static char linker_path[MAXPATHLEN] = "/boot/kernel;/boot/modules";
1652
1653SYSCTL_STRING(_kern, OID_AUTO, module_path, CTLFLAG_RWTUN, linker_path,
1654    sizeof(linker_path), "module load search path");
1655
1656TUNABLE_STR("module_path", linker_path, sizeof(linker_path));
1657
1658static char *linker_ext_list[] = {
1659	"",
1660	".ko",
1661	NULL
1662};
1663
1664/*
1665 * Check if file actually exists either with or without extension listed in
1666 * the linker_ext_list. (probably should be generic for the rest of the
1667 * kernel)
1668 */
1669static char *
1670linker_lookup_file(const char *path, int pathlen, const char *name,
1671    int namelen, struct vattr *vap)
1672{
1673	struct nameidata nd;
1674	struct thread *td = curthread;	/* XXX */
1675	char *result, **cpp, *sep;
1676	int error, len, extlen, reclen, flags;
1677	enum vtype type;
1678
1679	extlen = 0;
1680	for (cpp = linker_ext_list; *cpp; cpp++) {
1681		len = strlen(*cpp);
1682		if (len > extlen)
1683			extlen = len;
1684	}
1685	extlen++;		/* trailing '\0' */
1686	sep = (path[pathlen - 1] != '/') ? "/" : "";
1687
1688	reclen = pathlen + strlen(sep) + namelen + extlen + 1;
1689	result = malloc(reclen, M_LINKER, M_WAITOK);
1690	for (cpp = linker_ext_list; *cpp; cpp++) {
1691		snprintf(result, reclen, "%.*s%s%.*s%s", pathlen, path, sep,
1692		    namelen, name, *cpp);
1693		/*
1694		 * Attempt to open the file, and return the path if
1695		 * we succeed and it's a regular file.
1696		 */
1697		NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, result, td);
1698		flags = FREAD;
1699		error = vn_open(&nd, &flags, 0, NULL);
1700		if (error == 0) {
1701			NDFREE(&nd, NDF_ONLY_PNBUF);
1702			type = nd.ni_vp->v_type;
1703			if (vap)
1704				VOP_GETATTR(nd.ni_vp, vap, td->td_ucred);
1705			VOP_UNLOCK(nd.ni_vp, 0);
1706			vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
1707			if (type == VREG)
1708				return (result);
1709		}
1710	}
1711	free(result, M_LINKER);
1712	return (NULL);
1713}
1714
1715#define	INT_ALIGN(base, ptr)	ptr =					\
1716	(base) + roundup2((ptr) - (base), sizeof(int))
1717
1718/*
1719 * Lookup KLD which contains requested module in the "linker.hints" file. If
1720 * version specification is available, then try to find the best KLD.
1721 * Otherwise just find the latest one.
1722 */
1723static char *
1724linker_hints_lookup(const char *path, int pathlen, const char *modname,
1725    int modnamelen, const struct mod_depend *verinfo)
1726{
1727	struct thread *td = curthread;	/* XXX */
1728	struct ucred *cred = td ? td->td_ucred : NULL;
1729	struct nameidata nd;
1730	struct vattr vattr, mattr;
1731	u_char *hints = NULL;
1732	u_char *cp, *recptr, *bufend, *result, *best, *pathbuf, *sep;
1733	int error, ival, bestver, *intp, found, flags, clen, blen;
1734	ssize_t reclen;
1735
1736	result = NULL;
1737	bestver = found = 0;
1738
1739	sep = (path[pathlen - 1] != '/') ? "/" : "";
1740	reclen = imax(modnamelen, strlen(linker_hintfile)) + pathlen +
1741	    strlen(sep) + 1;
1742	pathbuf = malloc(reclen, M_LINKER, M_WAITOK);
1743	snprintf(pathbuf, reclen, "%.*s%s%s", pathlen, path, sep,
1744	    linker_hintfile);
1745
1746	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, pathbuf, td);
1747	flags = FREAD;
1748	error = vn_open(&nd, &flags, 0, NULL);
1749	if (error)
1750		goto bad;
1751	NDFREE(&nd, NDF_ONLY_PNBUF);
1752	if (nd.ni_vp->v_type != VREG)
1753		goto bad;
1754	best = cp = NULL;
1755	error = VOP_GETATTR(nd.ni_vp, &vattr, cred);
1756	if (error)
1757		goto bad;
1758	/*
1759	 * XXX: we need to limit this number to some reasonable value
1760	 */
1761	if (vattr.va_size > LINKER_HINTS_MAX) {
1762		printf("hints file too large %ld\n", (long)vattr.va_size);
1763		goto bad;
1764	}
1765	hints = malloc(vattr.va_size, M_TEMP, M_WAITOK);
1766	error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)hints, vattr.va_size, 0,
1767	    UIO_SYSSPACE, IO_NODELOCKED, cred, NOCRED, &reclen, td);
1768	if (error)
1769		goto bad;
1770	VOP_UNLOCK(nd.ni_vp, 0);
1771	vn_close(nd.ni_vp, FREAD, cred, td);
1772	nd.ni_vp = NULL;
1773	if (reclen != 0) {
1774		printf("can't read %zd\n", reclen);
1775		goto bad;
1776	}
1777	intp = (int *)hints;
1778	ival = *intp++;
1779	if (ival != LINKER_HINTS_VERSION) {
1780		printf("hints file version mismatch %d\n", ival);
1781		goto bad;
1782	}
1783	bufend = hints + vattr.va_size;
1784	recptr = (u_char *)intp;
1785	clen = blen = 0;
1786	while (recptr < bufend && !found) {
1787		intp = (int *)recptr;
1788		reclen = *intp++;
1789		ival = *intp++;
1790		cp = (char *)intp;
1791		switch (ival) {
1792		case MDT_VERSION:
1793			clen = *cp++;
1794			if (clen != modnamelen || bcmp(cp, modname, clen) != 0)
1795				break;
1796			cp += clen;
1797			INT_ALIGN(hints, cp);
1798			ival = *(int *)cp;
1799			cp += sizeof(int);
1800			clen = *cp++;
1801			if (verinfo == NULL ||
1802			    ival == verinfo->md_ver_preferred) {
1803				found = 1;
1804				break;
1805			}
1806			if (ival >= verinfo->md_ver_minimum &&
1807			    ival <= verinfo->md_ver_maximum &&
1808			    ival > bestver) {
1809				bestver = ival;
1810				best = cp;
1811				blen = clen;
1812			}
1813			break;
1814		default:
1815			break;
1816		}
1817		recptr += reclen + sizeof(int);
1818	}
1819	/*
1820	 * Finally check if KLD is in the place
1821	 */
1822	if (found)
1823		result = linker_lookup_file(path, pathlen, cp, clen, &mattr);
1824	else if (best)
1825		result = linker_lookup_file(path, pathlen, best, blen, &mattr);
1826
1827	/*
1828	 * KLD is newer than hints file. What we should do now?
1829	 */
1830	if (result && timespeccmp(&mattr.va_mtime, &vattr.va_mtime, >))
1831		printf("warning: KLD '%s' is newer than the linker.hints"
1832		    " file\n", result);
1833bad:
1834	free(pathbuf, M_LINKER);
1835	if (hints)
1836		free(hints, M_TEMP);
1837	if (nd.ni_vp != NULL) {
1838		VOP_UNLOCK(nd.ni_vp, 0);
1839		vn_close(nd.ni_vp, FREAD, cred, td);
1840	}
1841	/*
1842	 * If nothing found or hints is absent - fallback to the old
1843	 * way by using "kldname[.ko]" as module name.
1844	 */
1845	if (!found && !bestver && result == NULL)
1846		result = linker_lookup_file(path, pathlen, modname,
1847		    modnamelen, NULL);
1848	return (result);
1849}
1850
1851/*
1852 * Lookup KLD which contains requested module in the all directories.
1853 */
1854static char *
1855linker_search_module(const char *modname, int modnamelen,
1856    const struct mod_depend *verinfo)
1857{
1858	char *cp, *ep, *result;
1859
1860	/*
1861	 * traverse the linker path
1862	 */
1863	for (cp = linker_path; *cp; cp = ep + 1) {
1864		/* find the end of this component */
1865		for (ep = cp; (*ep != 0) && (*ep != ';'); ep++);
1866		result = linker_hints_lookup(cp, ep - cp, modname,
1867		    modnamelen, verinfo);
1868		if (result != NULL)
1869			return (result);
1870		if (*ep == 0)
1871			break;
1872	}
1873	return (NULL);
1874}
1875
1876/*
1877 * Search for module in all directories listed in the linker_path.
1878 */
1879static char *
1880linker_search_kld(const char *name)
1881{
1882	char *cp, *ep, *result;
1883	int len;
1884
1885	/* qualified at all? */
1886	if (strchr(name, '/'))
1887		return (strdup(name, M_LINKER));
1888
1889	/* traverse the linker path */
1890	len = strlen(name);
1891	for (ep = linker_path; *ep; ep++) {
1892		cp = ep;
1893		/* find the end of this component */
1894		for (; *ep != 0 && *ep != ';'; ep++);
1895		result = linker_lookup_file(cp, ep - cp, name, len, NULL);
1896		if (result != NULL)
1897			return (result);
1898	}
1899	return (NULL);
1900}
1901
1902static const char *
1903linker_basename(const char *path)
1904{
1905	const char *filename;
1906
1907	filename = strrchr(path, '/');
1908	if (filename == NULL)
1909		return path;
1910	if (filename[1])
1911		filename++;
1912	return (filename);
1913}
1914
1915#ifdef HWPMC_HOOKS
1916/*
1917 * Inform hwpmc about the set of kernel modules currently loaded.
1918 */
1919void *
1920linker_hwpmc_list_objects(void)
1921{
1922	linker_file_t lf;
1923	struct pmckern_map_in *kobase;
1924	int i, nmappings;
1925
1926	nmappings = 0;
1927	sx_slock(&kld_sx);
1928	TAILQ_FOREACH(lf, &linker_files, link)
1929		nmappings++;
1930
1931	/* Allocate nmappings + 1 entries. */
1932	kobase = malloc((nmappings + 1) * sizeof(struct pmckern_map_in),
1933	    M_LINKER, M_WAITOK | M_ZERO);
1934	i = 0;
1935	TAILQ_FOREACH(lf, &linker_files, link) {
1936
1937		/* Save the info for this linker file. */
1938		kobase[i].pm_file = lf->filename;
1939		kobase[i].pm_address = (uintptr_t)lf->address;
1940		i++;
1941	}
1942	sx_sunlock(&kld_sx);
1943
1944	KASSERT(i > 0, ("linker_hpwmc_list_objects: no kernel objects?"));
1945
1946	/* The last entry of the malloced area comprises of all zeros. */
1947	KASSERT(kobase[i].pm_file == NULL,
1948	    ("linker_hwpmc_list_objects: last object not NULL"));
1949
1950	return ((void *)kobase);
1951}
1952#endif
1953
1954/*
1955 * Find a file which contains given module and load it, if "parent" is not
1956 * NULL, register a reference to it.
1957 */
1958static int
1959linker_load_module(const char *kldname, const char *modname,
1960    struct linker_file *parent, const struct mod_depend *verinfo,
1961    struct linker_file **lfpp)
1962{
1963	linker_file_t lfdep;
1964	const char *filename;
1965	char *pathname;
1966	int error;
1967
1968	sx_assert(&kld_sx, SA_XLOCKED);
1969	if (modname == NULL) {
1970		/*
1971 		 * We have to load KLD
1972 		 */
1973		KASSERT(verinfo == NULL, ("linker_load_module: verinfo"
1974		    " is not NULL"));
1975		pathname = linker_search_kld(kldname);
1976	} else {
1977		if (modlist_lookup2(modname, verinfo) != NULL)
1978			return (EEXIST);
1979		if (kldname != NULL)
1980			pathname = strdup(kldname, M_LINKER);
1981		else if (rootvnode == NULL)
1982			pathname = NULL;
1983		else
1984			/*
1985			 * Need to find a KLD with required module
1986			 */
1987			pathname = linker_search_module(modname,
1988			    strlen(modname), verinfo);
1989	}
1990	if (pathname == NULL)
1991		return (ENOENT);
1992
1993	/*
1994	 * Can't load more than one file with the same basename XXX:
1995	 * Actually it should be possible to have multiple KLDs with
1996	 * the same basename but different path because they can
1997	 * provide different versions of the same modules.
1998	 */
1999	filename = linker_basename(pathname);
2000	if (linker_find_file_by_name(filename))
2001		error = EEXIST;
2002	else do {
2003		error = linker_load_file(pathname, &lfdep);
2004		if (error)
2005			break;
2006		if (modname && verinfo &&
2007		    modlist_lookup2(modname, verinfo) == NULL) {
2008			linker_file_unload(lfdep, LINKER_UNLOAD_FORCE);
2009			error = ENOENT;
2010			break;
2011		}
2012		if (parent) {
2013			error = linker_file_add_dependency(parent, lfdep);
2014			if (error)
2015				break;
2016		}
2017		if (lfpp)
2018			*lfpp = lfdep;
2019	} while (0);
2020	free(pathname, M_LINKER);
2021	return (error);
2022}
2023
2024/*
2025 * This routine is responsible for finding dependencies of userland initiated
2026 * kldload(2)'s of files.
2027 */
2028int
2029linker_load_dependencies(linker_file_t lf)
2030{
2031	linker_file_t lfdep;
2032	struct mod_metadata **start, **stop, **mdp, **nmdp;
2033	struct mod_metadata *mp, *nmp;
2034	const struct mod_depend *verinfo;
2035	modlist_t mod;
2036	const char *modname, *nmodname;
2037	int ver, error = 0, count;
2038
2039	/*
2040	 * All files are dependant on /kernel.
2041	 */
2042	sx_assert(&kld_sx, SA_XLOCKED);
2043	if (linker_kernel_file) {
2044		linker_kernel_file->refs++;
2045		error = linker_file_add_dependency(lf, linker_kernel_file);
2046		if (error)
2047			return (error);
2048	}
2049	if (linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop,
2050	    &count) != 0)
2051		return (0);
2052	for (mdp = start; mdp < stop; mdp++) {
2053		mp = *mdp;
2054		if (mp->md_type != MDT_VERSION)
2055			continue;
2056		modname = mp->md_cval;
2057		ver = ((const struct mod_version *)mp->md_data)->mv_version;
2058		mod = modlist_lookup(modname, ver);
2059		if (mod != NULL) {
2060			printf("interface %s.%d already present in the KLD"
2061			    " '%s'!\n", modname, ver,
2062			    mod->container->filename);
2063			return (EEXIST);
2064		}
2065	}
2066
2067	for (mdp = start; mdp < stop; mdp++) {
2068		mp = *mdp;
2069		if (mp->md_type != MDT_DEPEND)
2070			continue;
2071		modname = mp->md_cval;
2072		verinfo = mp->md_data;
2073		nmodname = NULL;
2074		for (nmdp = start; nmdp < stop; nmdp++) {
2075			nmp = *nmdp;
2076			if (nmp->md_type != MDT_VERSION)
2077				continue;
2078			nmodname = nmp->md_cval;
2079			if (strcmp(modname, nmodname) == 0)
2080				break;
2081		}
2082		if (nmdp < stop)/* early exit, it's a self reference */
2083			continue;
2084		mod = modlist_lookup2(modname, verinfo);
2085		if (mod) {	/* woohoo, it's loaded already */
2086			lfdep = mod->container;
2087			lfdep->refs++;
2088			error = linker_file_add_dependency(lf, lfdep);
2089			if (error)
2090				break;
2091			continue;
2092		}
2093		error = linker_load_module(NULL, modname, lf, verinfo, NULL);
2094		if (error) {
2095			printf("KLD %s: depends on %s - not available or"
2096			    " version mismatch\n", lf->filename, modname);
2097			break;
2098		}
2099	}
2100
2101	if (error)
2102		return (error);
2103	linker_addmodules(lf, start, stop, 0);
2104	return (error);
2105}
2106
2107static int
2108sysctl_kern_function_list_iterate(const char *name, void *opaque)
2109{
2110	struct sysctl_req *req;
2111
2112	req = opaque;
2113	return (SYSCTL_OUT(req, name, strlen(name) + 1));
2114}
2115
2116/*
2117 * Export a nul-separated, double-nul-terminated list of all function names
2118 * in the kernel.
2119 */
2120static int
2121sysctl_kern_function_list(SYSCTL_HANDLER_ARGS)
2122{
2123	linker_file_t lf;
2124	int error;
2125
2126#ifdef MAC
2127	error = mac_kld_check_stat(req->td->td_ucred);
2128	if (error)
2129		return (error);
2130#endif
2131	error = sysctl_wire_old_buffer(req, 0);
2132	if (error != 0)
2133		return (error);
2134	sx_xlock(&kld_sx);
2135	TAILQ_FOREACH(lf, &linker_files, link) {
2136		error = LINKER_EACH_FUNCTION_NAME(lf,
2137		    sysctl_kern_function_list_iterate, req);
2138		if (error) {
2139			sx_xunlock(&kld_sx);
2140			return (error);
2141		}
2142	}
2143	sx_xunlock(&kld_sx);
2144	return (SYSCTL_OUT(req, "", 1));
2145}
2146
2147SYSCTL_PROC(_kern, OID_AUTO, function_list, CTLTYPE_OPAQUE | CTLFLAG_RD,
2148    NULL, 0, sysctl_kern_function_list, "", "kernel function list");
2149