kern_linker.c revision 46693
1/*-
2 * Copyright (c) 1997 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 *	$Id: kern_linker.c,v 1.31 1999/04/28 01:04:28 luoqi Exp $
27 */
28
29#include "opt_ddb.h"
30
31#include <sys/param.h>
32#include <sys/kernel.h>
33#include <sys/systm.h>
34#include <sys/malloc.h>
35#include <sys/sysproto.h>
36#include <sys/sysent.h>
37#include <sys/proc.h>
38#include <sys/lock.h>
39#include <machine/cpu.h>
40#include <machine/bootinfo.h>
41#include <sys/module.h>
42#include <sys/linker.h>
43#include <sys/unistd.h>
44#include <sys/fcntl.h>
45#include <sys/libkern.h>
46#include <sys/namei.h>
47#include <sys/vnode.h>
48#include <sys/sysctl.h>
49
50#ifdef KLD_DEBUG
51int kld_debug = 0;
52#endif
53
54MALLOC_DEFINE(M_LINKER, "kld", "kernel linker");
55linker_file_t linker_current_file;
56linker_file_t linker_kernel_file;
57
58static struct lock lock;	/* lock for the file list */
59static linker_class_list_t classes;
60static linker_file_list_t files;
61static int next_file_id = 1;
62
63static void
64linker_init(void* arg)
65{
66    lockinit(&lock, PVM, "klink", 0, 0);
67    TAILQ_INIT(&classes);
68    TAILQ_INIT(&files);
69}
70
71SYSINIT(linker, SI_SUB_KLD, SI_ORDER_FIRST, linker_init, 0);
72
73int
74linker_add_class(const char* desc, void* priv,
75		 struct linker_class_ops* ops)
76{
77    linker_class_t lc;
78
79    lc = malloc(sizeof(struct linker_class), M_LINKER, M_NOWAIT);
80    if (!lc)
81	return ENOMEM;
82    bzero(lc, sizeof(*lc));
83
84    lc->desc = desc;
85    lc->priv = priv;
86    lc->ops = ops;
87    TAILQ_INSERT_HEAD(&classes, lc, link);
88
89    return 0;
90}
91
92static void
93linker_file_sysinit(linker_file_t lf)
94{
95    struct linker_set* sysinits;
96    struct sysinit** sipp;
97    struct sysinit** xipp;
98    struct sysinit* save;
99    const moduledata_t *moddata;
100    int error;
101
102    KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n",
103		   lf->filename));
104
105    sysinits = (struct linker_set*)
106	linker_file_lookup_symbol(lf, "sysinit_set", 0);
107
108    KLD_DPF(FILE, ("linker_file_sysinit: SYSINITs %p\n", sysinits));
109    if (!sysinits)
110	return;
111
112    /* HACK ALERT! */
113    for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) {
114	if ((*sipp)->func == module_register_init) {
115	    moddata = (*sipp)->udata;
116	    error = module_register(moddata, lf);
117	    if (error)
118		printf("linker_file_sysinit \"%s\" failed to register! %d\n",
119		    lf->filename, error);
120	}
121    }
122
123    /*
124     * Perform a bubble sort of the system initialization objects by
125     * their subsystem (primary key) and order (secondary key).
126     *
127     * Since some things care about execution order, this is the
128     * operation which ensures continued function.
129     */
130    for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) {
131	for (xipp = sipp + 1; *xipp; xipp++) {
132	    if ((*sipp)->subsystem <= (*xipp)->subsystem ||
133		 ((*sipp)->subsystem == (*xipp)->subsystem &&
134		  (*sipp)->order <= (*xipp)->order))
135		continue;	/* skip*/
136	    save = *sipp;
137	    *sipp = *xipp;
138	    *xipp = save;
139	}
140    }
141
142
143    /*
144     * Traverse the (now) ordered list of system initialization tasks.
145     * Perform each task, and continue on to the next task.
146     */
147    for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) {
148	if ((*sipp)->subsystem == SI_SUB_DUMMY)
149	    continue;	/* skip dummy task(s)*/
150
151	switch ((*sipp)->type) {
152	case SI_TYPE_DEFAULT:
153	    /* no special processing*/
154	    (*((*sipp)->func))((*sipp)->udata);
155	    break;
156
157	case SI_TYPE_KTHREAD:
158	    /* kernel thread*/
159	    if (fork1(&proc0, RFFDG|RFPROC|RFMEM))
160		panic("fork kernel thread");
161	    cpu_set_fork_handler(pfind(proc0.p_retval[0]),
162		(*sipp)->func, (*sipp)->udata);
163	    break;
164
165	case SI_TYPE_KPROCESS:
166	    /* kernel thread*/
167	    if (fork1(&proc0, RFFDG|RFPROC))
168		panic("fork kernel process");
169	    cpu_set_fork_handler(pfind(proc0.p_retval[0]),
170		(*sipp)->func, (*sipp)->udata);
171	    break;
172
173	default:
174	    panic ("linker_file_sysinit: unrecognized init type");
175	}
176    }
177}
178
179static void
180linker_file_sysuninit(linker_file_t lf)
181{
182    struct linker_set* sysuninits;
183    struct sysinit** sipp;
184    struct sysinit** xipp;
185    struct sysinit* save;
186
187    KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n",
188		   lf->filename));
189
190    sysuninits = (struct linker_set*)
191	linker_file_lookup_symbol(lf, "sysuninit_set", 0);
192
193    KLD_DPF(FILE, ("linker_file_sysuninit: SYSUNINITs %p\n", sysuninits));
194    if (!sysuninits)
195	return;
196
197    /*
198     * Perform a reverse bubble sort of the system initialization objects
199     * by their subsystem (primary key) and order (secondary key).
200     *
201     * Since some things care about execution order, this is the
202     * operation which ensures continued function.
203     */
204    for (sipp = (struct sysinit **)sysuninits->ls_items; *sipp; sipp++) {
205	for (xipp = sipp + 1; *xipp; xipp++) {
206	    if ((*sipp)->subsystem >= (*xipp)->subsystem ||
207		 ((*sipp)->subsystem == (*xipp)->subsystem &&
208		  (*sipp)->order >= (*xipp)->order))
209		continue;	/* skip*/
210	    save = *sipp;
211	    *sipp = *xipp;
212	    *xipp = save;
213	}
214    }
215
216
217    /*
218     * Traverse the (now) ordered list of system initialization tasks.
219     * Perform each task, and continue on to the next task.
220     */
221    for (sipp = (struct sysinit **)sysuninits->ls_items; *sipp; sipp++) {
222	if ((*sipp)->subsystem == SI_SUB_DUMMY)
223	    continue;	/* skip dummy task(s)*/
224
225	switch ((*sipp)->type) {
226	case SI_TYPE_DEFAULT:
227	    /* no special processing*/
228	    (*((*sipp)->func))((*sipp)->udata);
229	    break;
230
231	default:
232	    panic("linker_file_sysuninit: unrecognized uninit type");
233	}
234    }
235}
236
237static void
238linker_file_register_sysctls(linker_file_t lf)
239{
240    struct linker_set* sysctls;
241
242    KLD_DPF(FILE, ("linker_file_register_sysctls: registering SYSCTLs for %s\n",
243		   lf->filename));
244
245    sysctls = (struct linker_set*)
246	linker_file_lookup_symbol(lf, "sysctl_set", 0);
247
248    KLD_DPF(FILE, ("linker_file_register_sysctls: SYSCTLs %p\n", sysctls));
249    if (!sysctls)
250	return;
251
252    sysctl_register_set(sysctls);
253}
254
255static void
256linker_file_unregister_sysctls(linker_file_t lf)
257{
258    struct linker_set* sysctls;
259
260    KLD_DPF(FILE, ("linker_file_unregister_sysctls: registering SYSCTLs for %s\n",
261		   lf->filename));
262
263    sysctls = (struct linker_set*)
264	linker_file_lookup_symbol(lf, "sysctl_set", 0);
265
266    KLD_DPF(FILE, ("linker_file_unregister_sysctls: SYSCTLs %p\n", sysctls));
267    if (!sysctls)
268	return;
269
270    sysctl_unregister_set(sysctls);
271}
272
273int
274linker_load_file(const char* filename, linker_file_t* result)
275{
276    linker_class_t lc;
277    linker_file_t lf;
278    int foundfile, error = 0;
279    char *koname = NULL;
280
281    lf = linker_find_file_by_name(filename);
282    if (lf) {
283	KLD_DPF(FILE, ("linker_load_file: file %s is already loaded, incrementing refs\n", filename));
284	*result = lf;
285	lf->refs++;
286	goto out;
287    }
288
289    koname = malloc(strlen(filename) + 4, M_LINKER, M_WAITOK);
290    if (koname == NULL) {
291	error = ENOMEM;
292	goto out;
293    }
294    sprintf(koname, "%s.ko", filename);
295    lf = NULL;
296    foundfile = 0;
297    for (lc = TAILQ_FIRST(&classes); lc; lc = TAILQ_NEXT(lc, link)) {
298	KLD_DPF(FILE, ("linker_load_file: trying to load %s as %s\n",
299		       filename, lc->desc));
300
301	error = lc->ops->load_file(koname, &lf);	/* First with .ko */
302	if (lf == NULL && error == ENOENT)
303	    error = lc->ops->load_file(filename, &lf);	/* Then try without */
304	/*
305	 * If we got something other than ENOENT, then it exists but we cannot
306	 * load it for some other reason.
307	 */
308	if (error != ENOENT)
309	    foundfile = 1;
310	if (lf) {
311	    linker_file_register_sysctls(lf);
312	    linker_file_sysinit(lf);
313
314	    *result = lf;
315	    error = 0;
316	    goto out;
317	}
318    }
319    /*
320     * Less than ideal, but tells the user whether it failed to load or
321     * the module was not found.
322     */
323    if (foundfile)
324	error = ENOEXEC;	/* Format not recognised (or unloadable) */
325    else
326	error = ENOENT;		/* Nothing found */
327
328out:
329    if (koname)
330	free(koname, M_LINKER);
331    return error;
332}
333
334linker_file_t
335linker_find_file_by_name(const char* filename)
336{
337    linker_file_t lf = 0;
338    char *koname;
339
340    koname = malloc(strlen(filename) + 4, M_LINKER, M_WAITOK);
341    if (koname == NULL)
342	goto out;
343    sprintf(koname, "%s.ko", filename);
344
345    lockmgr(&lock, LK_SHARED, 0, curproc);
346    for (lf = TAILQ_FIRST(&files); lf; lf = TAILQ_NEXT(lf, link)) {
347	if (!strcmp(lf->filename, koname))
348	    break;
349	if (!strcmp(lf->filename, filename))
350	    break;
351    }
352    lockmgr(&lock, LK_RELEASE, 0, curproc);
353
354out:
355    if (koname)
356	free(koname, M_LINKER);
357    return lf;
358}
359
360linker_file_t
361linker_find_file_by_id(int fileid)
362{
363    linker_file_t lf = 0;
364
365    lockmgr(&lock, LK_SHARED, 0, curproc);
366    for (lf = TAILQ_FIRST(&files); lf; lf = TAILQ_NEXT(lf, link))
367	if (lf->id == fileid)
368	    break;
369    lockmgr(&lock, LK_RELEASE, 0, curproc);
370
371    return lf;
372}
373
374linker_file_t
375linker_make_file(const char* pathname, void* priv, struct linker_file_ops* ops)
376{
377    linker_file_t lf = 0;
378    int namelen;
379    const char *filename;
380
381    filename = rindex(pathname, '/');
382    if (filename && filename[1])
383	filename++;
384    else
385	filename = pathname;
386
387    KLD_DPF(FILE, ("linker_make_file: new file, filename=%s\n", filename));
388    lockmgr(&lock, LK_EXCLUSIVE, 0, curproc);
389    namelen = strlen(filename) + 1;
390    lf = malloc(sizeof(struct linker_file) + namelen, M_LINKER, M_WAITOK);
391    if (!lf)
392	goto out;
393    bzero(lf, sizeof(*lf));
394
395    lf->refs = 1;
396    lf->userrefs = 0;
397    lf->flags = 0;
398    lf->filename = (char*) (lf + 1);
399    strcpy(lf->filename, filename);
400    lf->id = next_file_id++;
401    lf->ndeps = 0;
402    lf->deps = NULL;
403    STAILQ_INIT(&lf->common);
404    TAILQ_INIT(&lf->modules);
405
406    lf->priv = priv;
407    lf->ops = ops;
408    TAILQ_INSERT_TAIL(&files, lf, link);
409
410out:
411    lockmgr(&lock, LK_RELEASE, 0, curproc);
412    return lf;
413}
414
415int
416linker_file_unload(linker_file_t file)
417{
418    module_t mod, next;
419    struct common_symbol* cp;
420    int error = 0;
421    int i;
422
423    KLD_DPF(FILE, ("linker_file_unload: lf->refs=%d\n", file->refs));
424    lockmgr(&lock, LK_EXCLUSIVE, 0, curproc);
425    if (file->refs == 1) {
426	KLD_DPF(FILE, ("linker_file_unload: file is unloading, informing modules\n"));
427	/*
428	 * Inform any modules associated with this file.
429	 */
430	for (mod = TAILQ_FIRST(&file->modules); mod; mod = next) {
431	    next = module_getfnext(mod);
432
433	    /*
434	     * Give the module a chance to veto the unload.
435	     */
436	    if ((error = module_unload(mod)) != 0) {
437		KLD_DPF(FILE, ("linker_file_unload: module %x vetoes unload\n",
438			       mod));
439		lockmgr(&lock, LK_RELEASE, 0, curproc);
440		goto out;
441	    }
442
443	    module_release(mod);
444	}
445    }
446
447    file->refs--;
448    if (file->refs > 0) {
449	lockmgr(&lock, LK_RELEASE, 0, curproc);
450	goto out;
451    }
452
453    /* Don't try to run SYSUNINITs if we are unloaded due to a link error */
454    if (file->flags & LINKER_FILE_LINKED) {
455	linker_file_sysuninit(file);
456	linker_file_unregister_sysctls(file);
457    }
458
459    TAILQ_REMOVE(&files, file, link);
460    lockmgr(&lock, LK_RELEASE, 0, curproc);
461
462    for (i = 0; i < file->ndeps; i++)
463	linker_file_unload(file->deps[i]);
464    free(file->deps, M_LINKER);
465
466    for (cp = STAILQ_FIRST(&file->common); cp;
467	 cp = STAILQ_FIRST(&file->common)) {
468	STAILQ_REMOVE(&file->common, cp, common_symbol, link);
469	free(cp, M_LINKER);
470    }
471
472    file->ops->unload(file);
473    free(file, M_LINKER);
474
475out:
476    return error;
477}
478
479int
480linker_file_add_dependancy(linker_file_t file, linker_file_t dep)
481{
482    linker_file_t* newdeps;
483
484    newdeps = malloc((file->ndeps + 1) * sizeof(linker_file_t*),
485		     M_LINKER, M_WAITOK);
486    if (newdeps == NULL)
487	return ENOMEM;
488    bzero(newdeps, (file->ndeps + 1) * sizeof(linker_file_t*));
489
490    if (file->deps) {
491	bcopy(file->deps, newdeps, file->ndeps * sizeof(linker_file_t*));
492	free(file->deps, M_LINKER);
493    }
494    file->deps = newdeps;
495    file->deps[file->ndeps] = dep;
496    file->ndeps++;
497
498    return 0;
499}
500
501caddr_t
502linker_file_lookup_symbol(linker_file_t file, const char* name, int deps)
503{
504    c_linker_sym_t sym;
505    linker_symval_t symval;
506    linker_file_t lf;
507    caddr_t address;
508    size_t common_size = 0;
509    int i;
510
511    KLD_DPF(SYM, ("linker_file_lookup_symbol: file=%x, name=%s, deps=%d\n",
512		  file, name, deps));
513
514    if (file->ops->lookup_symbol(file, name, &sym) == 0) {
515	file->ops->symbol_values(file, sym, &symval);
516	if (symval.value == 0)
517	    /*
518	     * For commons, first look them up in the dependancies and
519	     * only allocate space if not found there.
520	     */
521	    common_size = symval.size;
522	else {
523	    KLD_DPF(SYM, ("linker_file_lookup_symbol: symbol.value=%x\n", symval.value));
524	    return symval.value;
525	}
526    }
527
528    if (deps) {
529	for (i = 0; i < file->ndeps; i++) {
530	    address = linker_file_lookup_symbol(file->deps[i], name, 0);
531	    if (address) {
532		KLD_DPF(SYM, ("linker_file_lookup_symbol: deps value=%x\n", address));
533		return address;
534	    }
535	}
536
537	/* If we have not found it in the dependencies, search globally */
538	for (lf = TAILQ_FIRST(&files); lf; lf = TAILQ_NEXT(lf, link)) {
539	    /* But skip the current file if it's on the list */
540	    if (lf == file)
541		continue;
542	    /* And skip the files we searched above */
543	    for (i = 0; i < file->ndeps; i++)
544		if (lf == file->deps[i])
545		    break;
546	    if (i < file->ndeps)
547		continue;
548	    address = linker_file_lookup_symbol(lf, name, 0);
549	    if (address) {
550		KLD_DPF(SYM, ("linker_file_lookup_symbol: global value=%x\n", address));
551		return address;
552	    }
553	}
554    }
555
556    if (common_size > 0) {
557	/*
558	 * This is a common symbol which was not found in the
559	 * dependancies.  We maintain a simple common symbol table in
560	 * the file object.
561	 */
562	struct common_symbol* cp;
563
564	for (cp = STAILQ_FIRST(&file->common); cp;
565	     cp = STAILQ_NEXT(cp, link))
566	    if (!strcmp(cp->name, name)) {
567		KLD_DPF(SYM, ("linker_file_lookup_symbol: old common value=%x\n", cp->address));
568		return cp->address;
569	    }
570
571	/*
572	 * Round the symbol size up to align.
573	 */
574	common_size = (common_size + sizeof(int) - 1) & -sizeof(int);
575	cp = malloc(sizeof(struct common_symbol)
576		    + common_size
577		    + strlen(name) + 1,
578		    M_LINKER, M_WAITOK);
579	if (!cp) {
580	    KLD_DPF(SYM, ("linker_file_lookup_symbol: nomem\n"));
581	    return 0;
582	}
583	bzero(cp, sizeof(struct common_symbol) + common_size + strlen(name)+ 1);
584
585	cp->address = (caddr_t) (cp + 1);
586	cp->name = cp->address + common_size;
587	strcpy(cp->name, name);
588	bzero(cp->address, common_size);
589	STAILQ_INSERT_TAIL(&file->common, cp, link);
590
591	KLD_DPF(SYM, ("linker_file_lookup_symbol: new common value=%x\n", cp->address));
592	return cp->address;
593    }
594
595    KLD_DPF(SYM, ("linker_file_lookup_symbol: fail\n"));
596    return 0;
597}
598
599#ifdef DDB
600/*
601 * DDB Helpers.  DDB has to look across multiple files with their own
602 * symbol tables and string tables.
603 *
604 * Note that we do not obey list locking protocols here.  We really don't
605 * need DDB to hang because somebody's got the lock held.  We'll take the
606 * chance that the files list is inconsistant instead.
607 */
608
609int
610linker_ddb_lookup(const char *symstr, c_linker_sym_t *sym)
611{
612    linker_file_t lf;
613
614    for (lf = TAILQ_FIRST(&files); lf; lf = TAILQ_NEXT(lf, link)) {
615	if (lf->ops->lookup_symbol(lf, symstr, sym) == 0)
616	    return 0;
617    }
618    return ENOENT;
619}
620
621int
622linker_ddb_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp)
623{
624    linker_file_t lf;
625    u_long off = (u_long)value;
626    u_long diff, bestdiff;
627    c_linker_sym_t best;
628    c_linker_sym_t es;
629
630    best = 0;
631    bestdiff = off;
632    for (lf = TAILQ_FIRST(&files); lf; lf = TAILQ_NEXT(lf, link)) {
633	if (lf->ops->search_symbol(lf, value, &es, &diff) != 0)
634	    continue;
635	if (es != 0 && diff < bestdiff) {
636	    best = es;
637	    bestdiff = diff;
638	}
639	if (bestdiff == 0)
640	    break;
641    }
642    if (best) {
643	*sym = best;
644	*diffp = bestdiff;
645	return 0;
646    } else {
647	*sym = 0;
648	*diffp = off;
649	return ENOENT;
650    }
651}
652
653int
654linker_ddb_symbol_values(c_linker_sym_t sym, linker_symval_t *symval)
655{
656    linker_file_t lf;
657
658    for (lf = TAILQ_FIRST(&files); lf; lf = TAILQ_NEXT(lf, link)) {
659	if (lf->ops->symbol_values(lf, sym, symval) == 0)
660	    return 0;
661    }
662    return ENOENT;
663}
664
665#endif
666
667/*
668 * Syscalls.
669 */
670
671int
672kldload(struct proc* p, struct kldload_args* uap)
673{
674    char* filename = NULL, *modulename;
675    linker_file_t lf;
676    int error = 0;
677
678    p->p_retval[0] = -1;
679
680    if (securelevel > 0)
681	return EPERM;
682
683    if ((error = suser(p)) != 0)
684	return error;
685
686    filename = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
687    if ((error = copyinstr(SCARG(uap, file), filename, MAXPATHLEN, NULL)) != 0)
688	goto out;
689
690    /* Can't load more than one module with the same name */
691    modulename = rindex(filename, '/');
692    if (modulename == NULL)
693	modulename = filename;
694    else
695	modulename++;
696    if (linker_find_file_by_name(modulename)) {
697	error = EEXIST;
698	goto out;
699    }
700
701    if ((error = linker_load_file(filename, &lf)) != 0)
702	goto out;
703
704    lf->userrefs++;
705    p->p_retval[0] = lf->id;
706
707out:
708    if (filename)
709	free(filename, M_TEMP);
710    return error;
711}
712
713int
714kldunload(struct proc* p, struct kldunload_args* uap)
715{
716    linker_file_t lf;
717    int error = 0;
718
719    if (securelevel > 0)
720	return EPERM;
721
722    if ((error = suser(p)) != 0)
723	return error;
724
725    lf = linker_find_file_by_id(SCARG(uap, fileid));
726    if (lf) {
727	KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs));
728	if (lf->userrefs == 0) {
729	    printf("linkerunload: attempt to unload file that was loaded by the kernel\n");
730	    error = EBUSY;
731	    goto out;
732	}
733	lf->userrefs--;
734	error = linker_file_unload(lf);
735	if (error)
736	    lf->userrefs++;
737    } else
738	error = ENOENT;
739
740out:
741    return error;
742}
743
744int
745kldfind(struct proc* p, struct kldfind_args* uap)
746{
747    char* filename = NULL, *modulename;
748    linker_file_t lf;
749    int error = 0;
750
751    p->p_retval[0] = -1;
752
753    filename = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
754    if ((error = copyinstr(SCARG(uap, file), filename, MAXPATHLEN, NULL)) != 0)
755	goto out;
756
757    modulename = rindex(filename, '/');
758    if (modulename == NULL)
759	modulename = filename;
760
761    lf = linker_find_file_by_name(modulename);
762    if (lf)
763	p->p_retval[0] = lf->id;
764    else
765	error = ENOENT;
766
767out:
768    if (filename)
769	free(filename, M_TEMP);
770    return error;
771}
772
773int
774kldnext(struct proc* p, struct kldnext_args* uap)
775{
776    linker_file_t lf;
777    int error = 0;
778
779    if (SCARG(uap, fileid) == 0) {
780	if (TAILQ_FIRST(&files))
781	    p->p_retval[0] = TAILQ_FIRST(&files)->id;
782	else
783	    p->p_retval[0] = 0;
784	return 0;
785    }
786
787    lf = linker_find_file_by_id(SCARG(uap, fileid));
788    if (lf) {
789	if (TAILQ_NEXT(lf, link))
790	    p->p_retval[0] = TAILQ_NEXT(lf, link)->id;
791	else
792	    p->p_retval[0] = 0;
793    } else
794	error = ENOENT;
795
796    return error;
797}
798
799int
800kldstat(struct proc* p, struct kldstat_args* uap)
801{
802    linker_file_t lf;
803    int error = 0;
804    int version;
805    struct kld_file_stat* stat;
806    int namelen;
807
808    lf = linker_find_file_by_id(SCARG(uap, fileid));
809    if (!lf) {
810	error = ENOENT;
811	goto out;
812    }
813
814    stat = SCARG(uap, stat);
815
816    /*
817     * Check the version of the user's structure.
818     */
819    if ((error = copyin(&stat->version, &version, sizeof(version))) != 0)
820	goto out;
821    if (version != sizeof(struct kld_file_stat)) {
822	error = EINVAL;
823	goto out;
824    }
825
826    namelen = strlen(lf->filename) + 1;
827    if (namelen > MAXPATHLEN)
828	namelen = MAXPATHLEN;
829    if ((error = copyout(lf->filename, &stat->name[0], namelen)) != 0)
830	goto out;
831    if ((error = copyout(&lf->refs, &stat->refs, sizeof(int))) != 0)
832	goto out;
833    if ((error = copyout(&lf->id, &stat->id, sizeof(int))) != 0)
834	goto out;
835    if ((error = copyout(&lf->address, &stat->address, sizeof(caddr_t))) != 0)
836	goto out;
837    if ((error = copyout(&lf->size, &stat->size, sizeof(size_t))) != 0)
838	goto out;
839
840    p->p_retval[0] = 0;
841
842out:
843    return error;
844}
845
846int
847kldfirstmod(struct proc* p, struct kldfirstmod_args* uap)
848{
849    linker_file_t lf;
850    int error = 0;
851
852    lf = linker_find_file_by_id(SCARG(uap, fileid));
853    if (lf) {
854	if (TAILQ_FIRST(&lf->modules))
855	    p->p_retval[0] = module_getid(TAILQ_FIRST(&lf->modules));
856	else
857	    p->p_retval[0] = 0;
858    } else
859	error = ENOENT;
860
861    return error;
862}
863
864int
865kldsym(struct proc *p, struct kldsym_args *uap)
866{
867    char *symstr = NULL;
868    c_linker_sym_t sym;
869    linker_symval_t symval;
870    linker_file_t lf;
871    struct kld_sym_lookup lookup;
872    int error = 0;
873
874    if ((error = copyin(SCARG(uap, data), &lookup, sizeof(lookup))) != 0)
875	goto out;
876    if (lookup.version != sizeof(lookup) || SCARG(uap, cmd) != KLDSYM_LOOKUP) {
877	error = EINVAL;
878	goto out;
879    }
880
881    symstr = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
882    if ((error = copyinstr(lookup.symname, symstr, MAXPATHLEN, NULL)) != 0)
883	goto out;
884
885    if (SCARG(uap, fileid) != 0) {
886	lf = linker_find_file_by_id(SCARG(uap, fileid));
887	if (lf == NULL) {
888	    error = ENOENT;
889	    goto out;
890	}
891	if (lf->ops->lookup_symbol(lf, symstr, &sym) == 0 &&
892	    lf->ops->symbol_values(lf, sym, &symval) == 0) {
893	    lookup.symvalue = (u_long)symval.value;
894	    lookup.symsize = symval.size;
895	    error = copyout(&lookup, SCARG(uap, data), sizeof(lookup));
896	} else
897	    error = ENOENT;
898    } else {
899	for (lf = TAILQ_FIRST(&files); lf; lf = TAILQ_NEXT(lf, link)) {
900	    if (lf->ops->lookup_symbol(lf, symstr, &sym) == 0 &&
901		lf->ops->symbol_values(lf, sym, &symval) == 0) {
902		lookup.symvalue = (u_long)symval.value;
903		lookup.symsize = symval.size;
904		error = copyout(&lookup, SCARG(uap, data), sizeof(lookup));
905		break;
906	    }
907	}
908	if (!lf)
909	    error = ENOENT;
910    }
911out:
912    if (symstr)
913	free(symstr, M_TEMP);
914    return error;
915}
916
917/*
918 * Preloaded module support
919 */
920
921static void
922linker_preload(void* arg)
923{
924    caddr_t		modptr;
925    char		*modname;
926    char		*modtype;
927    linker_file_t	lf;
928    linker_class_t	lc;
929    int			error;
930    struct linker_set	*sysinits;
931    struct sysinit	**sipp;
932    const moduledata_t	*moddata;
933
934    modptr = NULL;
935    while ((modptr = preload_search_next_name(modptr)) != NULL) {
936	modname = (char *)preload_search_info(modptr, MODINFO_NAME);
937	modtype = (char *)preload_search_info(modptr, MODINFO_TYPE);
938	if (modname == NULL) {
939	    printf("Preloaded module at %p does not have a name!\n", modptr);
940	    continue;
941	}
942	if (modtype == NULL) {
943	    printf("Preloaded module at %p does not have a type!\n", modptr);
944	    continue;
945	}
946	printf("Preloaded %s \"%s\" at %p.\n", modtype, modname, modptr);
947	lf = linker_find_file_by_name(modname);
948	if (lf) {
949	    lf->userrefs++;
950	    continue;
951	}
952	lf = NULL;
953	for (lc = TAILQ_FIRST(&classes); lc; lc = TAILQ_NEXT(lc, link)) {
954	    error = lc->ops->load_file(modname, &lf);
955	    if (error) {
956		lf = NULL;
957		break;
958	    }
959	}
960	if (lf) {
961	    lf->userrefs++;
962
963	    sysinits = (struct linker_set*)
964		linker_file_lookup_symbol(lf, "sysinit_set", 0);
965	    if (sysinits) {
966		/* HACK ALERT!
967		 * This is to set the sysinit moduledata so that the module
968		 * can attach itself to the correct containing file.
969		 * The sysinit could be run at *any* time.
970		 */
971		for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) {
972		    if ((*sipp)->func == module_register_init) {
973			moddata = (*sipp)->udata;
974			error = module_register(moddata, lf);
975			if (error)
976			    printf("Preloaded %s \"%s\" failed to register: %d\n",
977				modtype, modname, error);
978		    }
979		}
980		sysinit_add((struct sysinit **)sysinits->ls_items);
981	    }
982	    linker_file_register_sysctls(lf);
983	}
984    }
985}
986
987SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0);
988
989/*
990 * Search for a not-loaded module by name.
991 *
992 * Modules may be found in the following locations:
993 *
994 * - preloaded (result is just the module name)
995 * - on disk (result is full path to module)
996 *
997 * If the module name is qualified in any way (contains path, etc.)
998 * the we simply return a copy of it.
999 *
1000 * The search path can be manipulated via sysctl.  Note that we use the ';'
1001 * character as a separator to be consistent with the bootloader.
1002 */
1003
1004static char linker_path[MAXPATHLEN + 1] = "/;/boot/;/modules/";
1005
1006SYSCTL_STRING(_kern, OID_AUTO, module_path, CTLFLAG_RW, linker_path,
1007	      sizeof(linker_path), "module load search path");
1008
1009static char *
1010linker_strdup(const char *str)
1011{
1012    char	*result;
1013
1014    if ((result = malloc((strlen(str) + 1), M_LINKER, M_WAITOK)) != NULL)
1015	strcpy(result, str);
1016    return(result);
1017}
1018
1019char *
1020linker_search_path(const char *name)
1021{
1022    struct nameidata	nd;
1023    struct proc		*p = curproc;	/* XXX */
1024    char		*cp, *ep, *result;
1025    int			error;
1026    enum vtype		type;
1027
1028    /* qualified at all? */
1029    if (index(name, '/'))
1030	return(linker_strdup(name));
1031
1032    /* traverse the linker path */
1033    cp = linker_path;
1034    for (;;) {
1035
1036	/* find the end of this component */
1037	for (ep = cp; (*ep != 0) && (*ep != ';'); ep++)
1038	    ;
1039	result = malloc((strlen(name) + (ep - cp) + 1), M_LINKER, M_WAITOK);
1040	if (result == NULL)	/* actually ENOMEM */
1041	    return(NULL);
1042
1043	strncpy(result, cp, ep - cp);
1044	strcpy(result + (ep - cp), name);
1045
1046	/*
1047	 * Attempt to open the file, and return the path if we succeed and it's
1048	 * a regular file.
1049	 */
1050	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, result, p);
1051	error = vn_open(&nd, FREAD, 0);
1052	if (error == 0) {
1053	    type = nd.ni_vp->v_type;
1054	    VOP_UNLOCK(nd.ni_vp, 0, p);
1055	    vn_close(nd.ni_vp, FREAD, p->p_ucred, p);
1056	    if (type == VREG)
1057		return(result);
1058	}
1059	free(result, M_LINKER);
1060
1061	if (*ep == 0)
1062	    break;
1063	cp = ep + 1;
1064    }
1065    return(NULL);
1066}
1067