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 92032 2002-03-10 23:12:43Z dwmalone $ |
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> --- 322 unchanged lines hidden (view full) --- 357 return (linker_load_module(NULL, modname, NULL, NULL, result)); 358} 359 360linker_file_t 361linker_find_file_by_name(const char *filename) 362{ 363 linker_file_t lf = 0; 364 char *koname; |
365 366 koname = malloc(strlen(filename) + 4, M_LINKER, M_WAITOK); 367 if (koname == NULL) 368 goto out; 369 sprintf(koname, "%s.ko", filename); 370 371 lockmgr(&lock, LK_SHARED, 0, curthread); 372 TAILQ_FOREACH(lf, &linker_files, link) { |
373 if (strcmp(lf->filename, koname) == 0) |
374 break; |
375 if (strcmp(lf->filename, filename) == 0) |
376 break; 377 } 378 lockmgr(&lock, LK_RELEASE, 0, curthread); 379out: 380 if (koname) 381 free(koname, M_LINKER); 382 return (lf); 383} --- 157 unchanged lines hidden (view full) --- 541 542caddr_t 543linker_file_lookup_symbol(linker_file_t file, const char *name, int deps) 544{ 545 c_linker_sym_t sym; 546 linker_symval_t symval; 547 caddr_t address; 548 size_t common_size = 0; |
549 int i; |
550 551 KLD_DPF(SYM, ("linker_file_lookup_symbol: file=%x, name=%s, deps=%d\n", 552 file, name, deps)); 553 554 if (LINKER_LOOKUP_SYMBOL(file, name, &sym) == 0) { 555 LINKER_SYMBOL_VALUES(file, sym, &symval); 556 if (symval.value == 0) 557 /* --- 23 unchanged lines hidden (view full) --- 581 /* 582 * This is a common symbol which was not found in the 583 * dependencies. We maintain a simple common symbol table in 584 * the file object. 585 */ 586 struct common_symbol *cp; 587 588 STAILQ_FOREACH(cp, &file->common, link) { |
589 if (strcmp(cp->name, name) == 0) { |
590 KLD_DPF(SYM, ("linker_file_lookup_symbol:" 591 " old common value=%x\n", cp->address)); 592 return (cp->address); 593 } 594 } 595 /* 596 * Round the symbol size up to align. 597 */ --- 376 unchanged lines hidden (view full) --- 974/* 975 * Preloaded module support 976 */ 977 978static modlist_t 979modlist_lookup(const char *name, int ver) 980{ 981 modlist_t mod; |
982 983 TAILQ_FOREACH(mod, &found_modules, link) { |
984 if (strcmp(mod->name, name) == 0 && 985 (ver == 0 || mod->version == ver)) |
986 return (mod); 987 } 988 return (NULL); 989} 990 991static modlist_t 992modlist_lookup2(const char *name, struct mod_depend *verinfo) 993{ 994 modlist_t mod, bestmod; |
995 int ver; |
996 997 if (verinfo == NULL) 998 return (modlist_lookup(name, 0)); 999 bestmod = NULL; 1000 for (mod = TAILQ_FIRST(&found_modules); mod; 1001 mod = TAILQ_NEXT(mod, link)) { |
1002 if (strcmp(mod->name, name) != 0) |
1003 continue; 1004 ver = mod->version; 1005 if (ver == verinfo->md_ver_preferred) 1006 return (mod); 1007 if (ver >= verinfo->md_ver_minimum && 1008 ver <= verinfo->md_ver_maximum && 1009 ver > bestmod->version) 1010 bestmod = mod; --- 89 unchanged lines hidden (view full) --- 1100static void 1101linker_preload(void *arg) 1102{ 1103 caddr_t modptr; 1104 const char *modname, *nmodname; 1105 char *modtype; 1106 linker_file_t lf; 1107 linker_class_t lc; |
1108 int error; |
1109 linker_file_list_t loaded_files; 1110 linker_file_list_t depended_files; 1111 struct mod_metadata *mp, *nmp; 1112 struct mod_metadata **start, **stop, **mdp, **nmdp; 1113 struct mod_depend *verinfo; 1114 int nver; 1115 int resolves; 1116 modlist_t mod; --- 61 unchanged lines hidden (view full) --- 1178 for (nmdp = start; nmdp < stop; nmdp++) { 1179 nmp = linker_reloc_ptr(lf, *nmdp); 1180 if (nmp->md_type != MDT_VERSION) 1181 continue; 1182 linker_mdt_version(lf, nmp, &nmodname, 1183 NULL); 1184 nmodname = linker_reloc_ptr(lf, 1185 nmp->md_cval); |
1186 if (strcmp(modname, nmodname) == 0) |
1187 break; 1188 } 1189 if (nmdp < stop) /* it's a self reference */ 1190 continue; 1191 1192 /* 1193 * ok, the module isn't here yet, we 1194 * are not finished --- 468 unchanged lines hidden (view full) --- 1663linker_load_dependencies(linker_file_t lf) 1664{ 1665 linker_file_t lfdep; 1666 struct mod_metadata **start, **stop, **mdp, **nmdp; 1667 struct mod_metadata *mp, *nmp; 1668 struct mod_depend *verinfo; 1669 modlist_t mod; 1670 const char *modname, *nmodname; |
1671 int ver, error = 0, count; |
1672 1673 /* 1674 * All files are dependant on /kernel. 1675 */ 1676 if (linker_kernel_file) { 1677 linker_kernel_file->refs++; 1678 error = linker_file_add_dependency(lf, linker_kernel_file); 1679 if (error) --- 22 unchanged lines hidden (view full) --- 1702 continue; 1703 linker_mdt_depend(lf, mp, &modname, &verinfo); 1704 nmodname = NULL; 1705 for (nmdp = start; nmdp < stop; nmdp++) { 1706 nmp = linker_reloc_ptr(lf, *nmdp); 1707 if (nmp->md_type != MDT_VERSION) 1708 continue; 1709 nmodname = linker_reloc_ptr(lf, nmp->md_cval); |
1710 if (strcmp(modname, nmodname) == 0) |
1711 break; 1712 } 1713 if (nmdp < stop)/* early exit, it's a self reference */ 1714 continue; 1715 mod = modlist_lookup2(modname, verinfo); 1716 if (mod) { /* woohoo, it's loaded already */ 1717 lfdep = mod->container; 1718 lfdep->refs++; --- 49 unchanged lines hidden --- |