Deleted Added
full compact
kern_linker.c (254810) kern_linker.c (254811)
1/*-
2 * Copyright (c) 1997-2000 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

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1997-2000 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

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/kern/kern_linker.c 254810 2013-08-24 21:07:04Z markj $");
28__FBSDID("$FreeBSD: head/sys/kern/kern_linker.c 254811 2013-08-24 21:08:55Z markj $");
29
30#include "opt_ddb.h"
31#include "opt_kld.h"
32#include "opt_hwpmc_hooks.h"
33
34#include <sys/param.h>
35#include <sys/kernel.h>
36#include <sys/systm.h>

--- 146 unchanged lines hidden (view full) ---

183static void
184linker_file_sysinit(linker_file_t lf)
185{
186 struct sysinit **start, **stop, **sipp, **xipp, *save;
187
188 KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n",
189 lf->filename));
190
29
30#include "opt_ddb.h"
31#include "opt_kld.h"
32#include "opt_hwpmc_hooks.h"
33
34#include <sys/param.h>
35#include <sys/kernel.h>
36#include <sys/systm.h>

--- 146 unchanged lines hidden (view full) ---

183static void
184linker_file_sysinit(linker_file_t lf)
185{
186 struct sysinit **start, **stop, **sipp, **xipp, *save;
187
188 KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n",
189 lf->filename));
190
191 sx_assert(&kld_sx, SA_XLOCKED);
192
191 if (linker_file_lookup_set(lf, "sysinit_set", &start, &stop, NULL) != 0)
192 return;
193 /*
194 * Perform a bubble sort of the system initialization objects by
195 * their subsystem (primary key) and order (secondary key).
196 *
197 * Since some things care about execution order, this is the operation
198 * which ensures continued function.

--- 9 unchanged lines hidden (view full) ---

208 *xipp = save;
209 }
210 }
211
212 /*
213 * Traverse the (now) ordered list of system initialization tasks.
214 * Perform each task, and continue on to the next task.
215 */
193 if (linker_file_lookup_set(lf, "sysinit_set", &start, &stop, NULL) != 0)
194 return;
195 /*
196 * Perform a bubble sort of the system initialization objects by
197 * their subsystem (primary key) and order (secondary key).
198 *
199 * Since some things care about execution order, this is the operation
200 * which ensures continued function.

--- 9 unchanged lines hidden (view full) ---

210 *xipp = save;
211 }
212 }
213
214 /*
215 * Traverse the (now) ordered list of system initialization tasks.
216 * Perform each task, and continue on to the next task.
217 */
218 sx_xunlock(&kld_sx);
216 mtx_lock(&Giant);
217 for (sipp = start; sipp < stop; sipp++) {
218 if ((*sipp)->subsystem == SI_SUB_DUMMY)
219 continue; /* skip dummy task(s) */
220
221 /* Call function */
222 (*((*sipp)->func)) ((*sipp)->udata);
223 }
224 mtx_unlock(&Giant);
219 mtx_lock(&Giant);
220 for (sipp = start; sipp < stop; sipp++) {
221 if ((*sipp)->subsystem == SI_SUB_DUMMY)
222 continue; /* skip dummy task(s) */
223
224 /* Call function */
225 (*((*sipp)->func)) ((*sipp)->udata);
226 }
227 mtx_unlock(&Giant);
228 sx_xlock(&kld_sx);
225}
226
227static void
228linker_file_sysuninit(linker_file_t lf)
229{
230 struct sysinit **start, **stop, **sipp, **xipp, *save;
231
232 KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n",
233 lf->filename));
234
229}
230
231static void
232linker_file_sysuninit(linker_file_t lf)
233{
234 struct sysinit **start, **stop, **sipp, **xipp, *save;
235
236 KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n",
237 lf->filename));
238
239 sx_assert(&kld_sx, SA_XLOCKED);
240
235 if (linker_file_lookup_set(lf, "sysuninit_set", &start, &stop,
236 NULL) != 0)
237 return;
238
239 /*
240 * Perform a reverse bubble sort of the system initialization objects
241 * by their subsystem (primary key) and order (secondary key).
242 *

--- 11 unchanged lines hidden (view full) ---

254 *xipp = save;
255 }
256 }
257
258 /*
259 * Traverse the (now) ordered list of system initialization tasks.
260 * Perform each task, and continue on to the next task.
261 */
241 if (linker_file_lookup_set(lf, "sysuninit_set", &start, &stop,
242 NULL) != 0)
243 return;
244
245 /*
246 * Perform a reverse bubble sort of the system initialization objects
247 * by their subsystem (primary key) and order (secondary key).
248 *

--- 11 unchanged lines hidden (view full) ---

260 *xipp = save;
261 }
262 }
263
264 /*
265 * Traverse the (now) ordered list of system initialization tasks.
266 * Perform each task, and continue on to the next task.
267 */
268 sx_xunlock(&kld_sx);
262 mtx_lock(&Giant);
263 for (sipp = start; sipp < stop; sipp++) {
264 if ((*sipp)->subsystem == SI_SUB_DUMMY)
265 continue; /* skip dummy task(s) */
266
267 /* Call function */
268 (*((*sipp)->func)) ((*sipp)->udata);
269 }
270 mtx_unlock(&Giant);
269 mtx_lock(&Giant);
270 for (sipp = start; sipp < stop; sipp++) {
271 if ((*sipp)->subsystem == SI_SUB_DUMMY)
272 continue; /* skip dummy task(s) */
273
274 /* Call function */
275 (*((*sipp)->func)) ((*sipp)->udata);
276 }
277 mtx_unlock(&Giant);
278 sx_xlock(&kld_sx);
271}
272
273static void
274linker_file_register_sysctls(linker_file_t lf)
275{
276 struct sysctl_oid **start, **stop, **oidp;
277
278 KLD_DPF(FILE,
279 ("linker_file_register_sysctls: registering SYSCTLs for %s\n",
280 lf->filename));
281
279}
280
281static void
282linker_file_register_sysctls(linker_file_t lf)
283{
284 struct sysctl_oid **start, **stop, **oidp;
285
286 KLD_DPF(FILE,
287 ("linker_file_register_sysctls: registering SYSCTLs for %s\n",
288 lf->filename));
289
290 sx_assert(&kld_sx, SA_XLOCKED);
291
282 if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
283 return;
284
292 if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
293 return;
294
295 sx_xunlock(&kld_sx);
285 sysctl_lock();
286 for (oidp = start; oidp < stop; oidp++)
287 sysctl_register_oid(*oidp);
288 sysctl_unlock();
296 sysctl_lock();
297 for (oidp = start; oidp < stop; oidp++)
298 sysctl_register_oid(*oidp);
299 sysctl_unlock();
300 sx_xlock(&kld_sx);
289}
290
291static void
292linker_file_unregister_sysctls(linker_file_t lf)
293{
294 struct sysctl_oid **start, **stop, **oidp;
295
296 KLD_DPF(FILE, ("linker_file_unregister_sysctls: unregistering SYSCTLs"
297 " for %s\n", lf->filename));
298
301}
302
303static void
304linker_file_unregister_sysctls(linker_file_t lf)
305{
306 struct sysctl_oid **start, **stop, **oidp;
307
308 KLD_DPF(FILE, ("linker_file_unregister_sysctls: unregistering SYSCTLs"
309 " for %s\n", lf->filename));
310
311 sx_assert(&kld_sx, SA_XLOCKED);
312
299 if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
300 return;
301
313 if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
314 return;
315
316 sx_xunlock(&kld_sx);
302 sysctl_lock();
303 for (oidp = start; oidp < stop; oidp++)
304 sysctl_unregister_oid(*oidp);
305 sysctl_unlock();
317 sysctl_lock();
318 for (oidp = start; oidp < stop; oidp++)
319 sysctl_unregister_oid(*oidp);
320 sysctl_unlock();
321 sx_xlock(&kld_sx);
306}
307
308static int
309linker_file_register_modules(linker_file_t lf)
310{
311 struct mod_metadata **start, **stop, **mdp;
312 const moduledata_t *moddata;
313 int first_error, error;
314
315 KLD_DPF(FILE, ("linker_file_register_modules: registering modules"
316 " in %s\n", lf->filename));
317
322}
323
324static int
325linker_file_register_modules(linker_file_t lf)
326{
327 struct mod_metadata **start, **stop, **mdp;
328 const moduledata_t *moddata;
329 int first_error, error;
330
331 KLD_DPF(FILE, ("linker_file_register_modules: registering modules"
332 " in %s\n", lf->filename));
333
334 sx_assert(&kld_sx, SA_XLOCKED);
335
318 if (linker_file_lookup_set(lf, "modmetadata_set", &start,
319 &stop, NULL) != 0) {
320 /*
321 * This fallback should be unnecessary, but if we get booted
322 * from boot2 instead of loader and we are missing our
323 * metadata then we have to try the best we can.
324 */
325 if (lf == linker_kernel_file) {

--- 72 unchanged lines hidden (view full) ---

398 foundfile = 1;
399 if (lf) {
400 error = linker_file_register_modules(lf);
401 if (error == EEXIST) {
402 linker_file_unload(lf, LINKER_UNLOAD_FORCE);
403 return (error);
404 }
405 modules = !TAILQ_EMPTY(&lf->modules);
336 if (linker_file_lookup_set(lf, "modmetadata_set", &start,
337 &stop, NULL) != 0) {
338 /*
339 * This fallback should be unnecessary, but if we get booted
340 * from boot2 instead of loader and we are missing our
341 * metadata then we have to try the best we can.
342 */
343 if (lf == linker_kernel_file) {

--- 72 unchanged lines hidden (view full) ---

416 foundfile = 1;
417 if (lf) {
418 error = linker_file_register_modules(lf);
419 if (error == EEXIST) {
420 linker_file_unload(lf, LINKER_UNLOAD_FORCE);
421 return (error);
422 }
423 modules = !TAILQ_EMPTY(&lf->modules);
406 sx_xunlock(&kld_sx);
407 linker_file_register_sysctls(lf);
408 linker_file_sysinit(lf);
424 linker_file_register_sysctls(lf);
425 linker_file_sysinit(lf);
409 sx_xlock(&kld_sx);
410 lf->flags |= LINKER_FILE_LINKED;
411
412 /*
413 * If all of the modules in this file failed
414 * to load, unload the file and return an
415 * error of ENOEXEC.
416 */
417 if (modules && TAILQ_EMPTY(&lf->modules)) {

--- 234 unchanged lines hidden (view full) ---

652 }
653
654 /*
655 * Don't try to run SYSUNINITs if we are unloaded due to a
656 * link error.
657 */
658 if (file->flags & LINKER_FILE_LINKED) {
659 file->flags &= ~LINKER_FILE_LINKED;
426 lf->flags |= LINKER_FILE_LINKED;
427
428 /*
429 * If all of the modules in this file failed
430 * to load, unload the file and return an
431 * error of ENOEXEC.
432 */
433 if (modules && TAILQ_EMPTY(&lf->modules)) {

--- 234 unchanged lines hidden (view full) ---

668 }
669
670 /*
671 * Don't try to run SYSUNINITs if we are unloaded due to a
672 * link error.
673 */
674 if (file->flags & LINKER_FILE_LINKED) {
675 file->flags &= ~LINKER_FILE_LINKED;
660 sx_xunlock(&kld_sx);
661 linker_file_sysuninit(file);
662 linker_file_unregister_sysctls(file);
676 linker_file_sysuninit(file);
677 linker_file_unregister_sysctls(file);
663 sx_xlock(&kld_sx);
664 }
665 TAILQ_REMOVE(&linker_files, file, link);
666
667 if (file->deps) {
668 for (i = 0; i < file->ndeps; i++)
669 linker_file_unload(file->deps[i], flags);
670 free(file->deps, M_LINKER);
671 file->deps = NULL;

--- 52 unchanged lines hidden (view full) ---

724 * linker_if.h exposure elsewhere. Note: firstp and lastp are really void **.
725 * This function is used in this file so we can avoid having lots of (void **)
726 * casts.
727 */
728int
729linker_file_lookup_set(linker_file_t file, const char *name,
730 void *firstp, void *lastp, int *countp)
731{
678 }
679 TAILQ_REMOVE(&linker_files, file, link);
680
681 if (file->deps) {
682 for (i = 0; i < file->ndeps; i++)
683 linker_file_unload(file->deps[i], flags);
684 free(file->deps, M_LINKER);
685 file->deps = NULL;

--- 52 unchanged lines hidden (view full) ---

738 * linker_if.h exposure elsewhere. Note: firstp and lastp are really void **.
739 * This function is used in this file so we can avoid having lots of (void **)
740 * casts.
741 */
742int
743linker_file_lookup_set(linker_file_t file, const char *name,
744 void *firstp, void *lastp, int *countp)
745{
732 int error, locked;
733
746
734 locked = sx_xlocked(&kld_sx);
735 if (!locked)
736 sx_xlock(&kld_sx);
737 error = LINKER_LOOKUP_SET(file, name, firstp, lastp, countp);
738 if (!locked)
739 sx_xunlock(&kld_sx);
740 return (error);
747 sx_assert(&kld_sx, SA_LOCKED);
748 return (LINKER_LOOKUP_SET(file, name, firstp, lastp, countp));
741}
742
743/*
744 * List all functions in a file.
745 */
746int
747linker_file_function_listall(linker_file_t lf,
748 linker_function_nameval_callback_t callback_func, void *arg)

--- 1419 unchanged lines hidden ---
749}
750
751/*
752 * List all functions in a file.
753 */
754int
755linker_file_function_listall(linker_file_t lf,
756 linker_function_nameval_callback_t callback_func, void *arg)

--- 1419 unchanged lines hidden ---