kern_linker.c (74641) | kern_linker.c (74642) |
---|---|
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 74641 2001-03-22 07:55:33Z bp $ | 26 * $FreeBSD: head/sys/kern/kern_linker.c 74642 2001-03-22 08:58:45Z bp $ |
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> --- 29 unchanged lines hidden (view full) --- 64static int next_file_id = 1; 65 66/* XXX wrong name; we're looking at version provision tags here, not modules */ 67typedef TAILQ_HEAD(, modlist) modlisthead_t; 68struct modlist { 69 TAILQ_ENTRY(modlist) link; /* chain together all modules */ 70 linker_file_t container; 71 const char *name; | 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> --- 29 unchanged lines hidden (view full) --- 64static int next_file_id = 1; 65 66/* XXX wrong name; we're looking at version provision tags here, not modules */ 67typedef TAILQ_HEAD(, modlist) modlisthead_t; 68struct modlist { 69 TAILQ_ENTRY(modlist) link; /* chain together all modules */ 70 linker_file_t container; 71 const char *name; |
72 int version; |
|
72}; 73typedef struct modlist *modlist_t; 74static modlisthead_t found_modules; 75 76static char * 77linker_strdup(const char *str) 78{ 79 char *result; --- 832 unchanged lines hidden (view full) --- 912 return error; 913} 914 915/* 916 * Preloaded module support 917 */ 918 919static modlist_t | 73}; 74typedef struct modlist *modlist_t; 75static modlisthead_t found_modules; 76 77static char * 78linker_strdup(const char *str) 79{ 80 char *result; --- 832 unchanged lines hidden (view full) --- 913 return error; 914} 915 916/* 917 * Preloaded module support 918 */ 919 920static modlist_t |
920modlist_lookup(const char *name) | 921modlist_lookup(const char *name, int ver) |
921{ 922 modlist_t mod; 923 924 TAILQ_FOREACH(mod, &found_modules, link) { | 922{ 923 modlist_t mod; 924 925 TAILQ_FOREACH(mod, &found_modules, link) { |
925 if (!strcmp(mod->name, name)) | 926 if (strcmp(mod->name, name) == 0 && (ver == 0 || mod->version == ver)) |
926 return mod; 927 } 928 return NULL; 929} 930 | 927 return mod; 928 } 929 return NULL; 930} 931 |
932static modlist_t 933modlist_newmodule(char *modname, int version, linker_file_t container) 934{ 935 modlist_t mod; 936 937 mod = malloc(sizeof(struct modlist), M_LINKER, M_NOWAIT); 938 if (mod == NULL) 939 panic("no memory for module list"); 940 bzero(mod, sizeof(*mod)); 941 mod->container = container; 942 mod->name = modname; 943 mod->version = version; 944 TAILQ_INSERT_TAIL(&found_modules, mod, link); 945 return mod; 946} 947 |
|
931/* 932 * This routine is cheap and nasty but will work for data pointers. 933 */ 934static void * 935linker_reloc_ptr(linker_file_t lf, void *offset) 936{ 937 return lf->address + (uintptr_t)offset; 938} 939 | 948/* 949 * This routine is cheap and nasty but will work for data pointers. 950 */ 951static void * 952linker_reloc_ptr(linker_file_t lf, void *offset) 953{ 954 return lf->address + (uintptr_t)offset; 955} 956 |
957/* 958 * Dereference MDT_VERSION metadata into module name and version 959 */ |
|
940static void | 960static void |
961linker_mdt_version(linker_file_t lf, struct mod_metadata *mp, 962 char **modname, int *version) 963{ 964 struct mod_version *mvp; 965 966 if (modname) 967 *modname = linker_reloc_ptr(lf, mp->md_cval); 968 if (version) { 969 mvp = linker_reloc_ptr(lf, mp->md_data); 970 *version = mvp->mv_version; 971 } 972} 973 974/* 975 * Dereference MDT_DEPEND metadata into module name and mod_depend structure 976 */ 977static void 978linker_mdt_depend(linker_file_t lf, struct mod_metadata *mp, 979 char **modname, struct mod_depend **verinfo) 980{ 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 989linker_addmodules(linker_file_t lf, struct linker_set *deps, int preload) 990{ 991 struct mod_metadata *mp; 992 char *modname; 993 int i, ver; 994 995 for (i = 0; i < deps->ls_length; i++) { 996 if (preload) 997 mp = deps->ls_items[i]; 998 else 999 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 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) { 1008 printf("module %s already present!\n", modname); 1009 /* XXX what can we do? this is a build error. :-( */ 1010 continue; 1011 } 1012 modlist_newmodule(modname, ver, lf); 1013 } 1014} 1015 1016static void |
|
941linker_preload(void* arg) 942{ 943 caddr_t modptr; 944 char *modname, *nmodname; 945 char *modtype; 946 linker_file_t lf; 947 linker_class_t lc; 948 int error; 949 struct linker_set *sysinits; 950 linker_file_list_t loaded_files; 951 linker_file_list_t depended_files; 952 struct linker_set *deps; 953 struct mod_metadata *mp, *nmp; | 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; 1025 struct linker_set *sysinits; 1026 linker_file_list_t loaded_files; 1027 linker_file_list_t depended_files; 1028 struct linker_set *deps; 1029 struct mod_metadata *mp, *nmp; |
954 int i, j; | 1030 struct mod_depend *verinfo; 1031 int i, j, nver; |
955 int resolves; 956 modlist_t mod; 957 958 TAILQ_INIT(&loaded_files); 959 TAILQ_INIT(&depended_files); 960 TAILQ_INIT(&found_modules); 961 error = 0; 962 --- 22 unchanged lines hidden (view full) --- 985 TAILQ_INSERT_TAIL(&loaded_files, lf, loaded); 986 } 987 988 /* 989 * First get a list of stuff in the kernel. 990 */ 991 deps = (struct linker_set*) 992 linker_file_lookup_symbol(linker_kernel_file, MDT_SETNAME, 0); | 1032 int resolves; 1033 modlist_t mod; 1034 1035 TAILQ_INIT(&loaded_files); 1036 TAILQ_INIT(&depended_files); 1037 TAILQ_INIT(&found_modules); 1038 error = 0; 1039 --- 22 unchanged lines hidden (view full) --- 1062 TAILQ_INSERT_TAIL(&loaded_files, lf, loaded); 1063 } 1064 1065 /* 1066 * First get a list of stuff in the kernel. 1067 */ 1068 deps = (struct linker_set*) 1069 linker_file_lookup_symbol(linker_kernel_file, MDT_SETNAME, 0); |
993 if (deps) { 994 for (i = 0; i < deps->ls_length; i++) { 995 mp = deps->ls_items[i]; 996 if (mp->md_type != MDT_VERSION) 997 continue; 998 modname = mp->md_cval; 999 if (modlist_lookup(modname) != NULL) { 1000 printf("module %s already present!\n", modname); 1001 /* XXX what can we do? this is a build error. :-( */ 1002 continue; 1003 } 1004 mod = malloc(sizeof(struct modlist), M_LINKER, M_NOWAIT|M_ZERO); 1005 if (mod == NULL) 1006 panic("no memory for module list"); 1007 mod->container = linker_kernel_file; 1008 mod->name = modname; 1009 TAILQ_INSERT_TAIL(&found_modules, mod, link); 1010 } 1011 } | 1070 if (deps) 1071 linker_addmodules(linker_kernel_file, deps, 1); |
1012 1013 /* 1014 * this is a once-off kinky bubble sort 1015 * resolve relocation dependency requirements 1016 */ 1017restart: 1018 TAILQ_FOREACH(lf, &loaded_files, loaded) { 1019 deps = (struct linker_set*) 1020 linker_file_lookup_symbol(lf, MDT_SETNAME, 0); 1021 /* 1022 * First, look to see if we would successfully link with this stuff. 1023 */ 1024 resolves = 1; /* unless we know otherwise */ 1025 if (deps) { 1026 for (i = 0; i < deps->ls_length; i++) { 1027 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1028 if (mp->md_type != MDT_DEPEND) 1029 continue; | 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) { 1079 deps = (struct linker_set*) 1080 linker_file_lookup_symbol(lf, MDT_SETNAME, 0); 1081 /* 1082 * First, look to see if we would successfully link with this stuff. 1083 */ 1084 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]); 1088 if (mp->md_type != MDT_DEPEND) 1089 continue; |
1030 modname = linker_reloc_ptr(lf, mp->md_cval); | 1090 linker_mdt_depend(lf, mp, &modname, &verinfo); |
1031 for (j = 0; j < deps->ls_length; j++) { 1032 nmp = linker_reloc_ptr(lf, deps->ls_items[j]); 1033 if (nmp->md_type != MDT_VERSION) 1034 continue; | 1091 for (j = 0; j < deps->ls_length; j++) { 1092 nmp = linker_reloc_ptr(lf, deps->ls_items[j]); 1093 if (nmp->md_type != MDT_VERSION) 1094 continue; |
1095 linker_mdt_version(lf, nmp, &nmodname, NULL); |
|
1035 nmodname = linker_reloc_ptr(lf, nmp->md_cval); 1036 if (strcmp(modname, nmodname) == 0) 1037 break; 1038 } 1039 if (j < deps->ls_length) /* it's a self reference */ 1040 continue; | 1096 nmodname = linker_reloc_ptr(lf, nmp->md_cval); 1097 if (strcmp(modname, nmodname) == 0) 1098 break; 1099 } 1100 if (j < deps->ls_length) /* it's a self reference */ 1101 continue; |
1041 if (modlist_lookup(modname) == NULL) { | 1102 if (modlist_lookup(modname, 0) == NULL) { |
1042 /* ok, the module isn't here yet, we are not finished */ 1043 resolves = 0; 1044 } 1045 } 1046 } 1047 /* 1048 * OK, if we found our modules, we can link. So, "provide" the 1049 * modules inside and add it to the end of the link order list. 1050 */ 1051 if (resolves) { 1052 if (deps) { 1053 for (i = 0; i < deps->ls_length; i++) { 1054 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1055 if (mp->md_type != MDT_VERSION) 1056 continue; | 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) { 1113 if (deps) { 1114 for (i = 0; i < deps->ls_length; i++) { 1115 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1116 if (mp->md_type != MDT_VERSION) 1117 continue; |
1057 modname = linker_reloc_ptr(lf, mp->md_cval); 1058 if (modlist_lookup(modname) != NULL) { | 1118 linker_mdt_version(lf, mp, &modname, &nver); 1119 if (modlist_lookup(modname, nver) != NULL) { |
1059 printf("module %s already present!\n", modname); 1060 linker_file_unload(lf); 1061 TAILQ_REMOVE(&loaded_files, lf, loaded); 1062 goto restart; /* we changed the tailq next ptr */ 1063 } | 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 */ 1124 } |
1064 mod = malloc(sizeof(struct modlist), M_LINKER, 1065 M_NOWAIT|M_ZERO); 1066 if (mod == NULL) 1067 panic("no memory for module list"); 1068 mod->container = lf; 1069 mod->name = modname; 1070 TAILQ_INSERT_TAIL(&found_modules, mod, link); | 1125 modlist_newmodule(modname, nver, lf); |
1071 } 1072 } 1073 TAILQ_REMOVE(&loaded_files, lf, loaded); 1074 TAILQ_INSERT_TAIL(&depended_files, lf, loaded); 1075 /* 1076 * Since we provided modules, we need to restart the sort so 1077 * that the previous files that depend on us have a chance. 1078 * Also, we've busted the tailq next pointer with the REMOVE. --- 24 unchanged lines hidden (view full) --- 1103 lf->userrefs++; /* so we can (try to) kldunload it */ 1104 deps = (struct linker_set*) 1105 linker_file_lookup_symbol(lf, MDT_SETNAME, 0); 1106 if (deps) { 1107 for (i = 0; i < deps->ls_length; i++) { 1108 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1109 if (mp->md_type != MDT_DEPEND) 1110 continue; | 1126 } 1127 } 1128 TAILQ_REMOVE(&loaded_files, lf, loaded); 1129 TAILQ_INSERT_TAIL(&depended_files, lf, loaded); 1130 /* 1131 * Since we provided modules, we need to restart the sort so 1132 * that the previous files that depend on us have a chance. 1133 * Also, we've busted the tailq next pointer with the REMOVE. --- 24 unchanged lines hidden (view full) --- 1158 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]); 1164 if (mp->md_type != MDT_DEPEND) 1165 continue; |
1111 modname = linker_reloc_ptr(lf, mp->md_cval); 1112 mod = modlist_lookup(modname); | 1166 linker_mdt_depend(lf, mp, &modname, &verinfo); 1167 mod = modlist_lookup(modname, 0); |
1113 mod->container->refs++; 1114 error = linker_file_add_dependancy(lf, mod->container); 1115 if (error) 1116 panic("cannot add dependency"); 1117 } 1118 } 1119 1120 /* Now do relocation etc using the symbol search paths established by the dependencies */ --- 173 unchanged lines hidden (view full) --- 1294int 1295linker_load_dependancies(linker_file_t lf) 1296{ 1297 linker_file_t lfdep; 1298 struct linker_set *deps; 1299 struct mod_metadata *mp, *nmp; 1300 modlist_t mod; 1301 char *modname, *nmodname; | 1168 mod->container->refs++; 1169 error = linker_file_add_dependancy(lf, mod->container); 1170 if (error) 1171 panic("cannot add dependency"); 1172 } 1173 } 1174 1175 /* Now do relocation etc using the symbol search paths established by the dependencies */ --- 173 unchanged lines hidden (view full) --- 1349int 1350linker_load_dependancies(linker_file_t lf) 1351{ 1352 linker_file_t lfdep; 1353 struct linker_set *deps; 1354 struct mod_metadata *mp, *nmp; 1355 modlist_t mod; 1356 char *modname, *nmodname; |
1302 int i, j, error = 0; | 1357 int i, j, ver, error = 0; |
1303 1304 /* 1305 * All files are dependant on /kernel. 1306 */ 1307 if (linker_kernel_file) { 1308 linker_kernel_file->refs++; 1309 error = linker_file_add_dependancy(lf, linker_kernel_file); 1310 if (error) 1311 return error; 1312 } 1313 1314 deps = (struct linker_set*) 1315 linker_file_lookup_symbol(lf, MDT_SETNAME, 0); 1316 if (deps == NULL) 1317 return 0; 1318 for (i = 0; i < deps->ls_length; i++) { 1319 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1320 if (mp->md_type != MDT_VERSION) 1321 continue; | 1358 1359 /* 1360 * All files are dependant on /kernel. 1361 */ 1362 if (linker_kernel_file) { 1363 linker_kernel_file->refs++; 1364 error = linker_file_add_dependancy(lf, linker_kernel_file); 1365 if (error) 1366 return error; 1367 } 1368 1369 deps = (struct linker_set*) 1370 linker_file_lookup_symbol(lf, MDT_SETNAME, 0); 1371 if (deps == NULL) 1372 return 0; 1373 for (i = 0; i < deps->ls_length; i++) { 1374 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1375 if (mp->md_type != MDT_VERSION) 1376 continue; |
1322 modname = linker_reloc_ptr(lf, mp->md_cval); 1323 if (modlist_lookup(modname) != NULL) { 1324 printf("module %s already present!\n", modname); | 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); |
1325 return EEXIST; 1326 } 1327 } | 1382 return EEXIST; 1383 } 1384 } |
1385 |
|
1328 for (i = 0; i < deps->ls_length; i++) { 1329 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1330 if (mp->md_type != MDT_DEPEND) 1331 continue; 1332 modname = linker_reloc_ptr(lf, mp->md_cval); 1333 nmodname = NULL; 1334 for (j = 0; j < deps->ls_length; j++) { 1335 nmp = linker_reloc_ptr(lf, deps->ls_items[j]); 1336 if (nmp->md_type != MDT_VERSION) 1337 continue; 1338 nmodname = linker_reloc_ptr(lf, nmp->md_cval); 1339 if (strcmp(modname, nmodname) == 0) 1340 break; 1341 } 1342 if (j < deps->ls_length) /* early exit, it's a self reference */ 1343 continue; | 1386 for (i = 0; i < deps->ls_length; i++) { 1387 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1388 if (mp->md_type != MDT_DEPEND) 1389 continue; 1390 modname = linker_reloc_ptr(lf, mp->md_cval); 1391 nmodname = NULL; 1392 for (j = 0; j < deps->ls_length; j++) { 1393 nmp = linker_reloc_ptr(lf, deps->ls_items[j]); 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 } 1400 if (j < deps->ls_length) /* early exit, it's a self reference */ 1401 continue; |
1344 mod = modlist_lookup(modname); | 1402 mod = modlist_lookup(modname, 0); |
1345 if (mod) { /* woohoo, it's loaded already */ 1346 lfdep = mod->container; 1347 lfdep->refs++; 1348 error = linker_file_add_dependancy(lf, lfdep); 1349 if (error) 1350 break; 1351 continue; 1352 } 1353 error = linker_load_module(modname, lf); 1354 if (error) { 1355 printf("KLD %s: depends on %s - not available\n", 1356 lf->filename, modname); 1357 break; 1358 } 1359 } 1360 1361 if (error) 1362 return error; | 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; 1409 continue; 1410 } 1411 error = linker_load_module(modname, lf); 1412 if (error) { 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; |
1363 for (i = 0; i < deps->ls_length; i++) { 1364 mp = linker_reloc_ptr(lf, deps->ls_items[i]); 1365 if (mp->md_type != MDT_VERSION) 1366 continue; 1367 modname = linker_reloc_ptr(lf, mp->md_cval); 1368 mod = malloc(sizeof(struct modlist), M_LINKER, M_NOWAIT|M_ZERO); 1369 if (mod == NULL) 1370 panic("no memory for module list"); 1371 mod->container = lf; 1372 mod->name = modname; 1373 TAILQ_INSERT_TAIL(&found_modules, mod, link); 1374 } | 1421 linker_addmodules(lf, deps, 0); |
1375 return error; 1376} | 1422 return error; 1423} |