xref: /freebsd/sys/kern/kern_linker.c (revision 6e8394b8baa7d5d9153ab90de6824bcd19b3b4e1)
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
51 int kld_debug = 0;
52 #endif
53 
54 MALLOC_DEFINE(M_LINKER, "kld", "kernel linker");
55 linker_file_t linker_current_file;
56 linker_file_t linker_kernel_file;
57 
58 static struct lock lock;	/* lock for the file list */
59 static linker_class_list_t classes;
60 static linker_file_list_t files;
61 static int next_file_id = 1;
62 
63 static void
64 linker_init(void* arg)
65 {
66     lockinit(&lock, PVM, "klink", 0, 0);
67     TAILQ_INIT(&classes);
68     TAILQ_INIT(&files);
69 }
70 
71 SYSINIT(linker, SI_SUB_KLD, SI_ORDER_FIRST, linker_init, 0);
72 
73 int
74 linker_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 
92 static void
93 linker_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 
179 static void
180 linker_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 
237 static void
238 linker_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 
255 static void
256 linker_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 
273 int
274 linker_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 
328 out:
329     if (koname)
330 	free(koname, M_LINKER);
331     return error;
332 }
333 
334 linker_file_t
335 linker_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 
354 out:
355     if (koname)
356 	free(koname, M_LINKER);
357     return lf;
358 }
359 
360 linker_file_t
361 linker_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 
374 linker_file_t
375 linker_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 
410 out:
411     lockmgr(&lock, LK_RELEASE, 0, curproc);
412     return lf;
413 }
414 
415 int
416 linker_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 
475 out:
476     return error;
477 }
478 
479 int
480 linker_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 
501 caddr_t
502 linker_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 
609 int
610 linker_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 
621 int
622 linker_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 
653 int
654 linker_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 
671 int
672 kldload(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 
707 out:
708     if (filename)
709 	free(filename, M_TEMP);
710     return error;
711 }
712 
713 int
714 kldunload(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 
740 out:
741     return error;
742 }
743 
744 int
745 kldfind(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 
767 out:
768     if (filename)
769 	free(filename, M_TEMP);
770     return error;
771 }
772 
773 int
774 kldnext(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 
799 int
800 kldstat(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 
842 out:
843     return error;
844 }
845 
846 int
847 kldfirstmod(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 
864 int
865 kldsym(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     }
911 out:
912     if (symstr)
913 	free(symstr, M_TEMP);
914     return error;
915 }
916 
917 /*
918  * Preloaded module support
919  */
920 
921 static void
922 linker_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 
987 SYSINIT(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 
1004 static char linker_path[MAXPATHLEN + 1] = "/;/boot/;/modules/";
1005 
1006 SYSCTL_STRING(_kern, OID_AUTO, module_path, CTLFLAG_RW, linker_path,
1007 	      sizeof(linker_path), "module load search path");
1008 
1009 static char *
1010 linker_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 
1019 char *
1020 linker_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