X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/545c2f3aef5020e0851a470ed84f64057c8c7583..6ef6faeb19268917889c5a06b0fa523ae6d67ccd:/sys/kern/kern_linker.c diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index d8a33a1a5e..c1159f346b 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/kern/kern_linker.c,v 1.41.2.3 2001/11/21 17:50:35 luigi Exp $ - * $DragonFly: src/sys/kern/kern_linker.c,v 1.33 2007/01/15 20:51:14 dillon Exp $ + * $DragonFly: src/sys/kern/kern_linker.c,v 1.38 2007/06/07 22:58:11 corecode Exp $ */ #include "opt_ddb.h" @@ -47,6 +47,10 @@ #include +#ifdef _KERNEL_VIRTUAL +#include +#endif + #ifdef KLD_DEBUG int kld_debug = 0; #endif @@ -71,7 +75,7 @@ linker_init(void* arg) TAILQ_INIT(&linker_files); } -SYSINIT(linker, SI_SUB_KLD, SI_ORDER_FIRST, linker_init, 0); +SYSINIT(linker, SI_BOOT2_KLD, SI_ORDER_FIRST, linker_init, 0); int linker_add_class(const char* desc, void* priv, @@ -146,7 +150,7 @@ linker_file_sysinit(linker_file_t lf) * Perform each task, and continue on to the next task. */ for (sipp = start; sipp < stop; sipp++) { - if ((*sipp)->subsystem == SI_SUB_DUMMY) + if ((*sipp)->subsystem == SI_SPECIAL_DUMMY) continue; /* skip dummy task(s)*/ /* Call function */ @@ -194,7 +198,7 @@ linker_file_sysuninit(linker_file_t lf) * Perform each task, and continue on to the next task. */ for (sipp = start; sipp < stop; sipp++) { - if ((*sipp)->subsystem == SI_SUB_DUMMY) + if ((*sipp)->subsystem == SI_SPECIAL_DUMMY) continue; /* skip dummy task(s)*/ /* Call function */ @@ -622,6 +626,14 @@ linker_file_lookup_symbol(linker_file_t file, const char* name, int deps, caddr_ return 0; } +#ifdef _KERNEL_VIRTUAL + *raddr = dlsym(RTLD_NEXT, name); + if (*raddr != NULL) { + KLD_DPF(SYM, ("linker_file_lookup_symbol: found dlsym=%x\n", *raddr)); + return 0; + } +#endif + KLD_DPF(SYM, ("linker_file_lookup_symbol: fail\n")); return ENOENT; } @@ -1062,7 +1074,7 @@ linker_preload(void* arg) } } -SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0); +SYSINIT(preload, SI_BOOT2_KLD, SI_ORDER_MIDDLE, linker_preload, 0); /* * Search for a not-loaded module by name. @@ -1079,10 +1091,11 @@ SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0); * character as a separator to be consistent with the bootloader. */ -static char linker_path[MAXPATHLEN] = "/;/boot/;/modules/"; +static char linker_path[MAXPATHLEN] = "/;/boot;/modules"; SYSCTL_STRING(_kern, OID_AUTO, module_path, CTLFLAG_RW, linker_path, sizeof(linker_path), "module load search path"); +TUNABLE_STR("module_path", linker_path, sizeof(linker_path)); static char * linker_strdup(const char *str) @@ -1099,6 +1112,8 @@ linker_search_path(const char *name) { struct nlookupdata nd; char *cp, *ep, *result; + size_t name_len, prefix_len; + int sep; int error; enum vtype type; @@ -1108,17 +1123,28 @@ linker_search_path(const char *name) /* traverse the linker path */ cp = linker_path; + name_len = strlen(name); for (;;) { /* find the end of this component */ for (ep = cp; (*ep != 0) && (*ep != ';'); ep++) ; - result = kmalloc((strlen(name) + (ep - cp) + 1), M_LINKER, M_WAITOK); - if (result == NULL) /* actually ENOMEM */ - return(NULL); + prefix_len = ep - cp; + /* if this component doesn't end with a slash, add one */ + if (ep == cp || *(ep - 1) != '/') + sep = 1; + else + sep = 0; + + /* + * +2 : possible separator, plus terminator. + */ + result = kmalloc(prefix_len + name_len + 2, M_LINKER, M_WAITOK); - strncpy(result, cp, ep - cp); - strcpy(result + (ep - cp), name); + strncpy(result, cp, prefix_len); + if (sep) + result[prefix_len++] = '/'; + strcpy(result + prefix_len, name); /* * Attempt to open the file, and return the path if we succeed and it's