kern_linker.c (77843) | kern_linker.c (78161) |
---|---|
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 --- 9 unchanged lines hidden (view full) --- 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 * | 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 --- 9 unchanged lines hidden (view full) --- 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 * $FreeBSD: head/sys/kern/kern_linker.c 77843 2001-06-06 22:17:08Z peter $ | 26 * $FreeBSD: head/sys/kern/kern_linker.c 78161 2001-06-13 10:58:39Z peter $ |
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> --- 14 unchanged lines hidden (view full) --- 49 50#ifdef KLD_DEBUG 51int kld_debug = 0; 52#endif 53 54static char *linker_search_path(const char *name); 55static const char *linker_basename(const char* path); 56 | 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> --- 14 unchanged lines hidden (view full) --- 49 50#ifdef KLD_DEBUG 51int kld_debug = 0; 52#endif 53 54static char *linker_search_path(const char *name); 55static const char *linker_basename(const char* path); 56 |
57/* Metadata from the static kernel */ 58SET_DECLARE(modmetadata_set, struct mod_metadata); 59 |
|
57MALLOC_DEFINE(M_LINKER, "linker", "kernel linker"); 58 59linker_file_t linker_kernel_file; 60 61static struct lock lock; /* lock for the file list */ 62static linker_class_list_t classes; 63static linker_file_list_t linker_files; 64static int next_file_id = 1; --- 35 unchanged lines hidden (view full) --- 100 kobj_class_compile((kobj_class_t) lc); 101 TAILQ_INSERT_TAIL(&classes, lc, link); 102 return 0; 103} 104 105static void 106linker_file_sysinit(linker_file_t lf) 107{ | 60MALLOC_DEFINE(M_LINKER, "linker", "kernel linker"); 61 62linker_file_t linker_kernel_file; 63 64static struct lock lock; /* lock for the file list */ 65static linker_class_list_t classes; 66static linker_file_list_t linker_files; 67static int next_file_id = 1; --- 35 unchanged lines hidden (view full) --- 103 kobj_class_compile((kobj_class_t) lc); 104 TAILQ_INSERT_TAIL(&classes, lc, link); 105 return 0; 106} 107 108static void 109linker_file_sysinit(linker_file_t lf) 110{ |
108 struct linker_set* sysinits; | 111 struct sysinit** start, ** stop; |
109 struct sysinit** sipp; 110 struct sysinit** xipp; 111 struct sysinit* save; 112 113 KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n", 114 lf->filename)); 115 | 112 struct sysinit** sipp; 113 struct sysinit** xipp; 114 struct sysinit* save; 115 116 KLD_DPF(FILE, ("linker_file_sysinit: calling SYSINITs for %s\n", 117 lf->filename)); 118 |
116 sysinits = (struct linker_set*) 117 linker_file_lookup_symbol(lf, "sysinit_set", 0); 118 119 KLD_DPF(FILE, ("linker_file_sysinit: SYSINITs %p\n", sysinits)); 120 if (!sysinits) | 119 if (linker_file_lookup_set(lf, "sysinit_set", &start, &stop, NULL) != 0) |
121 return; 122 /* 123 * Perform a bubble sort of the system initialization objects by 124 * their subsystem (primary key) and order (secondary key). 125 * 126 * Since some things care about execution order, this is the 127 * operation which ensures continued function. 128 */ | 120 return; 121 /* 122 * Perform a bubble sort of the system initialization objects by 123 * their subsystem (primary key) and order (secondary key). 124 * 125 * Since some things care about execution order, this is the 126 * operation which ensures continued function. 127 */ |
129 for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) { 130 for (xipp = sipp + 1; *xipp; xipp++) { | 128 for (sipp = start; sipp < stop; sipp++) { 129 for (xipp = sipp + 1; xipp < stop; xipp++) { |
131 if ((*sipp)->subsystem < (*xipp)->subsystem || 132 ((*sipp)->subsystem == (*xipp)->subsystem && 133 (*sipp)->order <= (*xipp)->order)) 134 continue; /* skip*/ 135 save = *sipp; 136 *sipp = *xipp; 137 *xipp = save; 138 } 139 } 140 141 142 /* 143 * Traverse the (now) ordered list of system initialization tasks. 144 * Perform each task, and continue on to the next task. 145 */ | 130 if ((*sipp)->subsystem < (*xipp)->subsystem || 131 ((*sipp)->subsystem == (*xipp)->subsystem && 132 (*sipp)->order <= (*xipp)->order)) 133 continue; /* skip*/ 134 save = *sipp; 135 *sipp = *xipp; 136 *xipp = save; 137 } 138 } 139 140 141 /* 142 * Traverse the (now) ordered list of system initialization tasks. 143 * Perform each task, and continue on to the next task. 144 */ |
146 for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) { | 145 for (sipp = start; sipp < stop; sipp++) { |
147 if ((*sipp)->subsystem == SI_SUB_DUMMY) 148 continue; /* skip dummy task(s)*/ 149 150 /* Call function */ 151 (*((*sipp)->func))((*sipp)->udata); 152 } 153} 154 155static void 156linker_file_sysuninit(linker_file_t lf) 157{ | 146 if ((*sipp)->subsystem == SI_SUB_DUMMY) 147 continue; /* skip dummy task(s)*/ 148 149 /* Call function */ 150 (*((*sipp)->func))((*sipp)->udata); 151 } 152} 153 154static void 155linker_file_sysuninit(linker_file_t lf) 156{ |
158 struct linker_set* sysuninits; | 157 struct sysinit** start, ** stop; |
159 struct sysinit** sipp; 160 struct sysinit** xipp; 161 struct sysinit* save; 162 163 KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n", 164 lf->filename)); 165 | 158 struct sysinit** sipp; 159 struct sysinit** xipp; 160 struct sysinit* save; 161 162 KLD_DPF(FILE, ("linker_file_sysuninit: calling SYSUNINITs for %s\n", 163 lf->filename)); 164 |
166 sysuninits = (struct linker_set*) 167 linker_file_lookup_symbol(lf, "sysuninit_set", 0); 168 169 KLD_DPF(FILE, ("linker_file_sysuninit: SYSUNINITs %p\n", sysuninits)); 170 if (!sysuninits) | 165 if (linker_file_lookup_set(lf, "sysuninit_set", &start, &stop, NULL) != 0) |
171 return; 172 173 /* 174 * Perform a reverse bubble sort of the system initialization objects 175 * by their subsystem (primary key) and order (secondary key). 176 * 177 * Since some things care about execution order, this is the 178 * operation which ensures continued function. 179 */ | 166 return; 167 168 /* 169 * Perform a reverse bubble sort of the system initialization objects 170 * by their subsystem (primary key) and order (secondary key). 171 * 172 * Since some things care about execution order, this is the 173 * operation which ensures continued function. 174 */ |
180 for (sipp = (struct sysinit **)sysuninits->ls_items; *sipp; sipp++) { 181 for (xipp = sipp + 1; *xipp; xipp++) { | 175 for (sipp = start; sipp < stop; sipp++) { 176 for (xipp = sipp + 1; xipp < stop; xipp++) { |
182 if ((*sipp)->subsystem > (*xipp)->subsystem || 183 ((*sipp)->subsystem == (*xipp)->subsystem && 184 (*sipp)->order >= (*xipp)->order)) 185 continue; /* skip*/ 186 save = *sipp; 187 *sipp = *xipp; 188 *xipp = save; 189 } 190 } 191 192 /* 193 * Traverse the (now) ordered list of system initialization tasks. 194 * Perform each task, and continue on to the next task. 195 */ | 177 if ((*sipp)->subsystem > (*xipp)->subsystem || 178 ((*sipp)->subsystem == (*xipp)->subsystem && 179 (*sipp)->order >= (*xipp)->order)) 180 continue; /* skip*/ 181 save = *sipp; 182 *sipp = *xipp; 183 *xipp = save; 184 } 185 } 186 187 /* 188 * Traverse the (now) ordered list of system initialization tasks. 189 * Perform each task, and continue on to the next task. 190 */ |
196 for (sipp = (struct sysinit **)sysuninits->ls_items; *sipp; sipp++) { | 191 for (sipp = start; sipp < stop; sipp++) { |
197 if ((*sipp)->subsystem == SI_SUB_DUMMY) 198 continue; /* skip dummy task(s)*/ 199 200 /* Call function */ 201 (*((*sipp)->func))((*sipp)->udata); 202 } 203} 204 205static void 206linker_file_register_sysctls(linker_file_t lf) 207{ | 192 if ((*sipp)->subsystem == SI_SUB_DUMMY) 193 continue; /* skip dummy task(s)*/ 194 195 /* Call function */ 196 (*((*sipp)->func))((*sipp)->udata); 197 } 198} 199 200static void 201linker_file_register_sysctls(linker_file_t lf) 202{ |
208 struct linker_set* sysctls; | 203 struct sysctl_oid **start, **stop, **oidp; |
209 210 KLD_DPF(FILE, ("linker_file_register_sysctls: registering SYSCTLs for %s\n", 211 lf->filename)); 212 | 204 205 KLD_DPF(FILE, ("linker_file_register_sysctls: registering SYSCTLs for %s\n", 206 lf->filename)); 207 |
213 sysctls = (struct linker_set*) 214 linker_file_lookup_symbol(lf, "sysctl_set", 0); 215 216 KLD_DPF(FILE, ("linker_file_register_sysctls: SYSCTLs %p\n", sysctls)); 217 if (!sysctls) | 208 if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0) |
218 return; 219 | 209 return; 210 |
220 sysctl_register_set(sysctls); | 211 for (oidp = start; oidp < stop; oidp++) 212 sysctl_register_oid(*oidp); |
221} 222 223static void 224linker_file_unregister_sysctls(linker_file_t lf) 225{ | 213} 214 215static void 216linker_file_unregister_sysctls(linker_file_t lf) 217{ |
226 struct linker_set* sysctls; | 218 struct sysctl_oid **start, **stop, **oidp; |
227 228 KLD_DPF(FILE, ("linker_file_unregister_sysctls: registering SYSCTLs for %s\n", 229 lf->filename)); 230 | 219 220 KLD_DPF(FILE, ("linker_file_unregister_sysctls: registering SYSCTLs for %s\n", 221 lf->filename)); 222 |
231 sysctls = (struct linker_set*) 232 linker_file_lookup_symbol(lf, "sysctl_set", 0); 233 234 KLD_DPF(FILE, ("linker_file_unregister_sysctls: SYSCTLs %p\n", sysctls)); 235 if (!sysctls) | 223 if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0) |
236 return; 237 | 224 return; 225 |
238 sysctl_unregister_set(sysctls); | 226 for (oidp = start; oidp < stop; oidp++) 227 sysctl_unregister_oid(*oidp); |
239} 240 | 228} 229 |
241extern struct linker_set modmetadata_set; 242 | |
243static int 244linker_file_register_modules(linker_file_t lf) 245{ 246 int error; | 230static int 231linker_file_register_modules(linker_file_t lf) 232{ 233 int error; |
247 struct linker_set *modules; 248 struct mod_metadata **mdpp; | 234 struct mod_metadata **start, **stop; 235 struct mod_metadata **mdp; |
249 const moduledata_t *moddata; 250 251 KLD_DPF(FILE, ("linker_file_register_modules: registering modules in %s\n", 252 lf->filename)); 253 | 236 const moduledata_t *moddata; 237 238 KLD_DPF(FILE, ("linker_file_register_modules: registering modules in %s\n", 239 lf->filename)); 240 |
254 modules = (struct linker_set*) 255 linker_file_lookup_symbol(lf, "modmetadata_set", 0); 256 257 if (!modules && lf == linker_kernel_file) 258 modules = &modmetadata_set; 259 260 if (modules == NULL) 261 return 0; 262 for (mdpp = (struct mod_metadata**)modules->ls_items; *mdpp; mdpp++) { 263 if ((*mdpp)->md_type != MDT_MODULE) | 241 if (linker_file_lookup_set(lf, "modmetadata_set", &start, &stop, 0) != 0) { 242 /* 243 * This fallback should be unnecessary, but if we get booted from 244 * boot2 instead of loader and we are missing our metadata then 245 * we have to try the best we can. 246 */ 247 if (lf == linker_kernel_file) { 248 start = SET_BEGIN(modmetadata_set); 249 stop = SET_LIMIT(modmetadata_set); 250 } else { 251 return 0; 252 } 253 } 254 for (mdp = start; mdp < stop; mdp++) { 255 if ((*mdp)->md_type != MDT_MODULE) |
264 continue; | 256 continue; |
265 moddata = (*mdpp)->md_data; | 257 moddata = (*mdp)->md_data; |
266 KLD_DPF(FILE, ("Registering module %s in %s\n", 267 moddata->name, lf->filename)); 268 if (module_lookupbyname(moddata->name) != NULL) { 269 printf("Warning: module %s already exists\n", moddata->name); 270 continue; /* or return a error ? */ 271 } 272 error = module_register(moddata, lf); 273 if (error) --- 235 unchanged lines hidden (view full) --- 509 } 510 file->deps = newdeps; 511 file->deps[file->ndeps] = dep; 512 file->ndeps++; 513 514 return 0; 515} 516 | 258 KLD_DPF(FILE, ("Registering module %s in %s\n", 259 moddata->name, lf->filename)); 260 if (module_lookupbyname(moddata->name) != NULL) { 261 printf("Warning: module %s already exists\n", moddata->name); 262 continue; /* or return a error ? */ 263 } 264 error = module_register(moddata, lf); 265 if (error) --- 235 unchanged lines hidden (view full) --- 501 } 502 file->deps = newdeps; 503 file->deps[file->ndeps] = dep; 504 file->ndeps++; 505 506 return 0; 507} 508 |
509/* 510 * Locate a linker set and its contents. 511 * This is a helper function to avoid linker_if.h exposure elsewhere. 512 * Note: firstp and lastp are really void *** 513 */ 514int 515linker_file_lookup_set(linker_file_t file, const char *name, 516 void *firstp, void *lastp, int *countp) 517{ 518 519 return LINKER_LOOKUP_SET(file, name, firstp, lastp, countp); 520} 521 |
|
517caddr_t 518linker_file_lookup_symbol(linker_file_t file, const char* name, int deps) 519{ 520 c_linker_sym_t sym; 521 linker_symval_t symval; 522 caddr_t address; 523 size_t common_size = 0; 524 int i; --- 456 unchanged lines hidden (view full) --- 981 982 if (modname) 983 *modname = linker_reloc_ptr(lf, mp->md_cval); 984 if (verinfo) 985 *verinfo = linker_reloc_ptr(lf, mp->md_data); 986} 987 988static void | 522caddr_t 523linker_file_lookup_symbol(linker_file_t file, const char* name, int deps) 524{ 525 c_linker_sym_t sym; 526 linker_symval_t symval; 527 caddr_t address; 528 size_t common_size = 0; 529 int i; --- 456 unchanged lines hidden (view full) --- 986 987 if (modname) 988 *modname = linker_reloc_ptr(lf, mp->md_cval); 989 if (verinfo) 990 *verinfo = linker_reloc_ptr(lf, mp->md_data); 991} 992 993static void |
989linker_addmodules(linker_file_t lf, struct linker_set *deps, int preload) | 994linker_addmodules(linker_file_t lf, struct mod_metadata **start, 995 struct mod_metadata **stop, int preload) |
990{ | 996{ |
991 struct mod_metadata *mp; | 997 struct mod_metadata *mp, **mdp; |
992 char *modname; | 998 char *modname; |
993 int i, ver; | 999 int ver; |
994 | 1000 |
995 for (i = 0; i < deps->ls_length; i++) { | 1001 for (mdp = start; mdp < stop; mdp++) { |
996 if (preload) | 1002 if (preload) |
997 mp = deps->ls_items[i]; | 1003 mp = *mdp; |
998 else | 1004 else |
999 mp = linker_reloc_ptr(lf, deps->ls_items[i]); | 1005 mp = linker_reloc_ptr(lf, *mdp); |
1000 if (mp->md_type != MDT_VERSION) 1001 continue; 1002 if (preload) { 1003 modname = mp->md_cval; 1004 ver = ((struct mod_version*)mp->md_data)->mv_version; 1005 } else 1006 linker_mdt_version(lf, mp, &modname, &ver); 1007 if (modlist_lookup(modname, ver) != NULL) { --- 9 unchanged lines hidden (view full) --- 1017linker_preload(void* arg) 1018{ 1019 caddr_t modptr; 1020 char *modname, *nmodname; 1021 char *modtype; 1022 linker_file_t lf; 1023 linker_class_t lc; 1024 int error; | 1006 if (mp->md_type != MDT_VERSION) 1007 continue; 1008 if (preload) { 1009 modname = mp->md_cval; 1010 ver = ((struct mod_version*)mp->md_data)->mv_version; 1011 } else 1012 linker_mdt_version(lf, mp, &modname, &ver); 1013 if (modlist_lookup(modname, ver) != NULL) { --- 9 unchanged lines hidden (view full) --- 1023linker_preload(void* arg) 1024{ 1025 caddr_t modptr; 1026 char *modname, *nmodname; 1027 char *modtype; 1028 linker_file_t lf; 1029 linker_class_t lc; 1030 int error; |
1025 struct linker_set *sysinits; | |
1026 linker_file_list_t loaded_files; 1027 linker_file_list_t depended_files; | 1031 linker_file_list_t loaded_files; 1032 linker_file_list_t depended_files; |
1028 struct linker_set *deps; | |
1029 struct mod_metadata *mp, *nmp; | 1033 struct mod_metadata *mp, *nmp; |
1034 struct mod_metadata **start, **stop, **mdp, **nmdp; |
|
1030 struct mod_depend *verinfo; | 1035 struct mod_depend *verinfo; |
1031 int i, j, nver; | 1036 int nver; |
1032 int resolves; 1033 modlist_t mod; | 1037 int resolves; 1038 modlist_t mod; |
1039 struct sysinit **si_start, **si_stop; |
|
1034 1035 TAILQ_INIT(&loaded_files); 1036 TAILQ_INIT(&depended_files); 1037 TAILQ_INIT(&found_modules); 1038 error = 0; 1039 1040 modptr = NULL; 1041 while ((modptr = preload_search_next_name(modptr)) != NULL) { --- 18 unchanged lines hidden (view full) --- 1060 } 1061 if (lf) 1062 TAILQ_INSERT_TAIL(&loaded_files, lf, loaded); 1063 } 1064 1065 /* 1066 * First get a list of stuff in the kernel. 1067 */ | 1040 1041 TAILQ_INIT(&loaded_files); 1042 TAILQ_INIT(&depended_files); 1043 TAILQ_INIT(&found_modules); 1044 error = 0; 1045 1046 modptr = NULL; 1047 while ((modptr = preload_search_next_name(modptr)) != NULL) { --- 18 unchanged lines hidden (view full) --- 1066 } 1067 if (lf) 1068 TAILQ_INSERT_TAIL(&loaded_files, lf, loaded); 1069 } 1070 1071 /* 1072 * First get a list of stuff in the kernel. 1073 */ |
1068 deps = (struct linker_set*) 1069 linker_file_lookup_symbol(linker_kernel_file, MDT_SETNAME, 0); 1070 if (deps) 1071 linker_addmodules(linker_kernel_file, deps, 1); | 1074 if (linker_file_lookup_set(linker_kernel_file, MDT_SETNAME, &start, &stop, 1075 NULL) == 0) 1076 linker_addmodules(linker_kernel_file, start, stop, 1); |
1072 1073 /* 1074 * this is a once-off kinky bubble sort 1075 * resolve relocation dependency requirements 1076 */ 1077restart: 1078 TAILQ_FOREACH(lf, &loaded_files, loaded) { | 1077 1078 /* 1079 * this is a once-off kinky bubble sort 1080 * resolve relocation dependency requirements 1081 */ 1082restart: 1083 TAILQ_FOREACH(lf, &loaded_files, loaded) { |
1079 deps = (struct linker_set*) 1080 linker_file_lookup_symbol(lf, MDT_SETNAME, 0); | 1084 error = linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop, NULL); |
1081 /* 1082 * First, look to see if we would successfully link with this stuff. 1083 */ 1084 resolves = 1; /* unless we know otherwise */ | 1085 /* 1086 * First, look to see if we would successfully link with this stuff. 1087 */ 1088 resolves = 1; /* unless we know otherwise */ |
1085 if (deps) { 1086 for (i = 0; i < deps->ls_length; i++) { 1087 mp = linker_reloc_ptr(lf, deps->ls_items[i]); | 1089 if (!error) { 1090 for (mdp = start; mdp < stop; mdp++) { 1091 mp = linker_reloc_ptr(lf, *mdp); |
1088 if (mp->md_type != MDT_DEPEND) 1089 continue; 1090 linker_mdt_depend(lf, mp, &modname, &verinfo); | 1092 if (mp->md_type != MDT_DEPEND) 1093 continue; 1094 linker_mdt_depend(lf, mp, &modname, &verinfo); |
1091 for (j = 0; j < deps->ls_length; j++) { 1092 nmp = linker_reloc_ptr(lf, deps->ls_items[j]); | 1095 for (nmdp = start; nmdp < stop; nmdp++) { 1096 nmp = linker_reloc_ptr(lf, *nmdp); |
1093 if (nmp->md_type != MDT_VERSION) 1094 continue; 1095 linker_mdt_version(lf, nmp, &nmodname, NULL); 1096 nmodname = linker_reloc_ptr(lf, nmp->md_cval); 1097 if (strcmp(modname, nmodname) == 0) 1098 break; 1099 } | 1097 if (nmp->md_type != MDT_VERSION) 1098 continue; 1099 linker_mdt_version(lf, nmp, &nmodname, NULL); 1100 nmodname = linker_reloc_ptr(lf, nmp->md_cval); 1101 if (strcmp(modname, nmodname) == 0) 1102 break; 1103 } |
1100 if (j < deps->ls_length) /* it's a self reference */ | 1104 if (nmdp < stop) /* it's a self reference */ |
1101 continue; 1102 if (modlist_lookup(modname, 0) == NULL) { 1103 /* ok, the module isn't here yet, we are not finished */ 1104 resolves = 0; 1105 } 1106 } 1107 } 1108 /* 1109 * OK, if we found our modules, we can link. So, "provide" the 1110 * modules inside and add it to the end of the link order list. 1111 */ 1112 if (resolves) { | 1105 continue; 1106 if (modlist_lookup(modname, 0) == NULL) { 1107 /* ok, the module isn't here yet, we are not finished */ 1108 resolves = 0; 1109 } 1110 } 1111 } 1112 /* 1113 * OK, if we found our modules, we can link. So, "provide" the 1114 * modules inside and add it to the end of the link order list. 1115 */ 1116 if (resolves) { |
1113 if (deps) { 1114 for (i = 0; i < deps->ls_length; i++) { 1115 mp = linker_reloc_ptr(lf, deps->ls_items[i]); | 1117 if (!error) { 1118 for (mdp = start; mdp < stop; mdp++) { 1119 mp = linker_reloc_ptr(lf, *mdp); |
1116 if (mp->md_type != MDT_VERSION) 1117 continue; 1118 linker_mdt_version(lf, mp, &modname, &nver); 1119 if (modlist_lookup(modname, nver) != NULL) { 1120 printf("module %s already present!\n", modname); 1121 linker_file_unload(lf); 1122 TAILQ_REMOVE(&loaded_files, lf, loaded); 1123 goto restart; /* we changed the tailq next ptr */ --- 27 unchanged lines hidden (view full) --- 1151 TAILQ_FOREACH(lf, &depended_files, loaded) { 1152 if (linker_kernel_file) { 1153 linker_kernel_file->refs++; 1154 error = linker_file_add_dependancy(lf, linker_kernel_file); 1155 if (error) 1156 panic("cannot add dependency"); 1157 } 1158 lf->userrefs++; /* so we can (try to) kldunload it */ | 1120 if (mp->md_type != MDT_VERSION) 1121 continue; 1122 linker_mdt_version(lf, mp, &modname, &nver); 1123 if (modlist_lookup(modname, nver) != NULL) { 1124 printf("module %s already present!\n", modname); 1125 linker_file_unload(lf); 1126 TAILQ_REMOVE(&loaded_files, lf, loaded); 1127 goto restart; /* we changed the tailq next ptr */ --- 27 unchanged lines hidden (view full) --- 1155 TAILQ_FOREACH(lf, &depended_files, loaded) { 1156 if (linker_kernel_file) { 1157 linker_kernel_file->refs++; 1158 error = linker_file_add_dependancy(lf, linker_kernel_file); 1159 if (error) 1160 panic("cannot add dependency"); 1161 } 1162 lf->userrefs++; /* so we can (try to) kldunload it */ |
1159 deps = (struct linker_set*) 1160 linker_file_lookup_symbol(lf, MDT_SETNAME, 0); 1161 if (deps) { 1162 for (i = 0; i < deps->ls_length; i++) { 1163 mp = linker_reloc_ptr(lf, deps->ls_items[i]); | 1163 error = linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop, NULL); 1164 if (!error) { 1165 for (mdp = start; mdp < stop; mdp++) { 1166 mp = linker_reloc_ptr(lf, *mdp); |
1164 if (mp->md_type != MDT_DEPEND) 1165 continue; 1166 linker_mdt_depend(lf, mp, &modname, &verinfo); 1167 mod = modlist_lookup(modname, 0); 1168 mod->container->refs++; 1169 error = linker_file_add_dependancy(lf, mod->container); 1170 if (error) 1171 panic("cannot add dependency"); 1172 } 1173 } 1174 | 1167 if (mp->md_type != MDT_DEPEND) 1168 continue; 1169 linker_mdt_depend(lf, mp, &modname, &verinfo); 1170 mod = modlist_lookup(modname, 0); 1171 mod->container->refs++; 1172 error = linker_file_add_dependancy(lf, mod->container); 1173 if (error) 1174 panic("cannot add dependency"); 1175 } 1176 } 1177 |
1175 /* Now do relocation etc using the symbol search paths established by the dependencies */ | 1178 /* 1179 * Now do relocation etc using the symbol search paths established by 1180 * the dependencies 1181 */ |
1176 error = LINKER_LINK_PRELOAD_FINISH(lf); 1177 if (error) { 1178 printf("KLD file %s - could not finalize loading\n", lf->filename); 1179 linker_file_unload(lf); 1180 continue; 1181 } 1182 1183 linker_file_register_modules(lf); | 1182 error = LINKER_LINK_PRELOAD_FINISH(lf); 1183 if (error) { 1184 printf("KLD file %s - could not finalize loading\n", lf->filename); 1185 linker_file_unload(lf); 1186 continue; 1187 } 1188 1189 linker_file_register_modules(lf); |
1184 sysinits = (struct linker_set*) 1185 linker_file_lookup_symbol(lf, "sysinit_set", 0); 1186 if (sysinits) 1187 sysinit_add((struct sysinit **)sysinits->ls_items); | 1190 if (linker_file_lookup_set(lf, "sysinit_set", &si_start, &si_stop, NULL) == 0) 1191 sysinit_add(si_start, si_stop); |
1188 linker_file_register_sysctls(lf); 1189 lf->flags |= LINKER_FILE_LINKED; 1190 } 1191 /* woohoo! we made it! */ 1192} 1193 1194SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0); 1195 --- 147 unchanged lines hidden (view full) --- 1343/* 1344 * This routine is responsible for finding dependencies of userland 1345 * initiated kldload(2)'s of files. 1346 */ 1347int 1348linker_load_dependancies(linker_file_t lf) 1349{ 1350 linker_file_t lfdep; | 1192 linker_file_register_sysctls(lf); 1193 lf->flags |= LINKER_FILE_LINKED; 1194 } 1195 /* woohoo! we made it! */ 1196} 1197 1198SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0); 1199 --- 147 unchanged lines hidden (view full) --- 1347/* 1348 * This routine is responsible for finding dependencies of userland 1349 * initiated kldload(2)'s of files. 1350 */ 1351int 1352linker_load_dependancies(linker_file_t lf) 1353{ 1354 linker_file_t lfdep; |
1351 struct linker_set *deps; | 1355 struct mod_metadata **start, **stop, **mdp, **nmdp; |
1352 struct mod_metadata *mp, *nmp; 1353 modlist_t mod; 1354 char *modname, *nmodname; | 1356 struct mod_metadata *mp, *nmp; 1357 modlist_t mod; 1358 char *modname, *nmodname; |
1355 int i, j, ver, error = 0; | 1359 int ver, error = 0, count; |
1356 1357 /* 1358 * All files are dependant on /kernel. 1359 */ 1360 if (linker_kernel_file) { 1361 linker_kernel_file->refs++; 1362 error = linker_file_add_dependancy(lf, linker_kernel_file); 1363 if (error) 1364 return error; 1365 } 1366 | 1360 1361 /* 1362 * All files are dependant on /kernel. 1363 */ 1364 if (linker_kernel_file) { 1365 linker_kernel_file->refs++; 1366 error = linker_file_add_dependancy(lf, linker_kernel_file); 1367 if (error) 1368 return error; 1369 } 1370 |
1367 deps = (struct linker_set*) 1368 linker_file_lookup_symbol(lf, MDT_SETNAME, 0); 1369 if (deps == NULL) | 1371 if (linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop, &count) != 0) |
1370 return 0; | 1372 return 0; |
1371 for (i = 0; i < deps->ls_length; i++) { 1372 mp = linker_reloc_ptr(lf, deps->ls_items[i]); | 1373 for (mdp = start; mdp < stop; mdp++) { 1374 mp = linker_reloc_ptr(lf, *mdp); |
1373 if (mp->md_type != MDT_VERSION) 1374 continue; 1375 linker_mdt_version(lf, mp, &modname, &ver); 1376 mod = modlist_lookup(modname, ver); 1377 if (mod != NULL) { 1378 printf("interface %s.%d already present in the KLD '%s'!\n", 1379 modname, ver, mod->container->filename); 1380 return EEXIST; 1381 } 1382 } 1383 | 1375 if (mp->md_type != MDT_VERSION) 1376 continue; 1377 linker_mdt_version(lf, mp, &modname, &ver); 1378 mod = modlist_lookup(modname, ver); 1379 if (mod != NULL) { 1380 printf("interface %s.%d already present in the KLD '%s'!\n", 1381 modname, ver, mod->container->filename); 1382 return EEXIST; 1383 } 1384 } 1385 |
1384 for (i = 0; i < deps->ls_length; i++) { 1385 mp = linker_reloc_ptr(lf, deps->ls_items[i]); | 1386 for (mdp = start; mdp < stop; mdp++) { 1387 mp = linker_reloc_ptr(lf, *mdp); |
1386 if (mp->md_type != MDT_DEPEND) 1387 continue; 1388 modname = linker_reloc_ptr(lf, mp->md_cval); 1389 nmodname = NULL; | 1388 if (mp->md_type != MDT_DEPEND) 1389 continue; 1390 modname = linker_reloc_ptr(lf, mp->md_cval); 1391 nmodname = NULL; |
1390 for (j = 0; j < deps->ls_length; j++) { 1391 nmp = linker_reloc_ptr(lf, deps->ls_items[j]); | 1392 for (nmdp = start; nmdp < stop; nmdp++) { 1393 nmp = linker_reloc_ptr(lf, *nmdp); |
1392 if (nmp->md_type != MDT_VERSION) 1393 continue; 1394 nmodname = linker_reloc_ptr(lf, nmp->md_cval); 1395 if (strcmp(modname, nmodname) == 0) 1396 break; 1397 } | 1394 if (nmp->md_type != MDT_VERSION) 1395 continue; 1396 nmodname = linker_reloc_ptr(lf, nmp->md_cval); 1397 if (strcmp(modname, nmodname) == 0) 1398 break; 1399 } |
1398 if (j < deps->ls_length) /* early exit, it's a self reference */ | 1400 if (nmdp < stop) /* early exit, it's a self reference */ |
1399 continue; 1400 mod = modlist_lookup(modname, 0); 1401 if (mod) { /* woohoo, it's loaded already */ 1402 lfdep = mod->container; 1403 lfdep->refs++; 1404 error = linker_file_add_dependancy(lf, lfdep); 1405 if (error) 1406 break; --- 4 unchanged lines hidden (view full) --- 1411 printf("KLD %s: depends on %s - not available\n", 1412 lf->filename, modname); 1413 break; 1414 } 1415 } 1416 1417 if (error) 1418 return error; | 1401 continue; 1402 mod = modlist_lookup(modname, 0); 1403 if (mod) { /* woohoo, it's loaded already */ 1404 lfdep = mod->container; 1405 lfdep->refs++; 1406 error = linker_file_add_dependancy(lf, lfdep); 1407 if (error) 1408 break; --- 4 unchanged lines hidden (view full) --- 1413 printf("KLD %s: depends on %s - not available\n", 1414 lf->filename, modname); 1415 break; 1416 } 1417 } 1418 1419 if (error) 1420 return error; |
1419 linker_addmodules(lf, deps, 0); | 1421 linker_addmodules(lf, start, stop, 0); |
1420 return error; 1421} | 1422 return error; 1423} |