Deleted Added
full compact
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}