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 86469 2001-11-16 21:08:40Z iedowse $ |
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> --- 458 unchanged lines hidden (view full) --- 493 } 494 kobj_delete((kobj_t) file, M_LINKER); 495 496out: 497 return error; 498} 499 500int |
501linker_file_add_dependency(linker_file_t file, linker_file_t dep) |
502{ 503 linker_file_t* newdeps; 504 505 newdeps = malloc((file->ndeps + 1) * sizeof(linker_file_t*), 506 M_LINKER, M_WAITOK | M_ZERO); 507 if (newdeps == NULL) 508 return ENOMEM; 509 --- 32 unchanged lines hidden (view full) --- 542 543 KLD_DPF(SYM, ("linker_file_lookup_symbol: file=%x, name=%s, deps=%d\n", 544 file, name, deps)); 545 546 if (LINKER_LOOKUP_SYMBOL(file, name, &sym) == 0) { 547 LINKER_SYMBOL_VALUES(file, sym, &symval); 548 if (symval.value == 0) 549 /* |
550 * For commons, first look them up in the dependencies and |
551 * only allocate space if not found there. 552 */ 553 common_size = symval.size; 554 else { 555 KLD_DPF(SYM, ("linker_file_lookup_symbol: symbol.value=%x\n", symval.value)); 556 return symval.value; 557 } 558 } --- 6 unchanged lines hidden (view full) --- 565 return address; 566 } 567 } 568 } 569 570 if (common_size > 0) { 571 /* 572 * This is a common symbol which was not found in the |
573 * dependencies. We maintain a simple common symbol table in |
574 * the file object. 575 */ 576 struct common_symbol* cp; 577 578 STAILQ_FOREACH(cp, &file->common, link) 579 if (!strcmp(cp->name, name)) { 580 KLD_DPF(SYM, ("linker_file_lookup_symbol: old common value=%x\n", cp->address)); 581 return cp->address; --- 640 unchanged lines hidden (view full) --- 1222 } 1223 1224 /* 1225 * We made it. Finish off the linking in the order we determined. 1226 */ 1227 TAILQ_FOREACH(lf, &depended_files, loaded) { 1228 if (linker_kernel_file) { 1229 linker_kernel_file->refs++; |
1230 error = linker_file_add_dependency(lf, linker_kernel_file); |
1231 if (error) 1232 panic("cannot add dependency"); 1233 } 1234 lf->userrefs++; /* so we can (try to) kldunload it */ 1235 error = linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop, NULL); 1236 if (!error) { 1237 for (mdp = start; mdp < stop; mdp++) { 1238 mp = linker_reloc_ptr(lf, *mdp); 1239 if (mp->md_type != MDT_DEPEND) 1240 continue; 1241 linker_mdt_depend(lf, mp, &modname, &verinfo); 1242 mod = modlist_lookup2(modname, verinfo); 1243 mod->container->refs++; |
1244 error = linker_file_add_dependency(lf, mod->container); |
1245 if (error) 1246 panic("cannot add dependency"); 1247 } 1248 } 1249 1250 /* 1251 * Now do relocation etc using the symbol search paths established by 1252 * the dependencies --- 353 unchanged lines hidden (view full) --- 1606 if (error) 1607 break; 1608 if (modname && verinfo && modlist_lookup2(modname, verinfo) == NULL) { 1609 linker_file_unload(lfdep); 1610 error = ENOENT; 1611 break; 1612 } 1613 if (parent) { |
1614 error = linker_file_add_dependency(parent, lfdep); |
1615 if (error) 1616 break; 1617 } 1618 if (lfpp) 1619 *lfpp = lfdep; 1620 } while(0); 1621out: 1622 if (pathname) 1623 free(pathname, M_LINKER); 1624 return error; 1625} 1626 1627/* 1628 * This routine is responsible for finding dependencies of userland 1629 * initiated kldload(2)'s of files. 1630 */ 1631int |
1632linker_load_dependencies(linker_file_t lf) |
1633{ 1634 linker_file_t lfdep; 1635 struct mod_metadata **start, **stop, **mdp, **nmdp; 1636 struct mod_metadata *mp, *nmp; 1637 struct mod_depend *verinfo; 1638 modlist_t mod; 1639 const char *modname, *nmodname; 1640 int ver, error = 0, count; 1641 1642 /* 1643 * All files are dependant on /kernel. 1644 */ 1645 if (linker_kernel_file) { 1646 linker_kernel_file->refs++; |
1647 error = linker_file_add_dependency(lf, linker_kernel_file); |
1648 if (error) 1649 return error; 1650 } 1651 1652 if (linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop, &count) != 0) 1653 return 0; 1654 for (mdp = start; mdp < stop; mdp++) { 1655 mp = linker_reloc_ptr(lf, *mdp); --- 23 unchanged lines hidden (view full) --- 1679 break; 1680 } 1681 if (nmdp < stop) /* early exit, it's a self reference */ 1682 continue; 1683 mod = modlist_lookup2(modname, verinfo); 1684 if (mod) { /* woohoo, it's loaded already */ 1685 lfdep = mod->container; 1686 lfdep->refs++; |
1687 error = linker_file_add_dependency(lf, lfdep); |
1688 if (error) 1689 break; 1690 continue; 1691 } 1692 error = linker_load_module(NULL, modname, lf, verinfo, NULL); 1693 if (error) { 1694 printf("KLD %s: depends on %s - not available\n", 1695 lf->filename, modname); --- 40 unchanged lines hidden --- |