link_elf.c (f94594b37a145b9b3e9ff31af2cd1dc3de8aa4d4) | link_elf.c (cff8c6f2d1f8ee2cfd12b5a6f67d196b7c27194f) |
---|---|
1/*- 2 * Copyright (c) 1998-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 --- 144 unchanged lines hidden (view full) --- 153 void ***, void ***, int *); 154static int link_elf_each_function_name(linker_file_t, 155 int (*)(const char *, void *), void *); 156static int link_elf_each_function_nameval(linker_file_t, 157 linker_function_nameval_callback_t, void *); 158static void link_elf_reloc_local(linker_file_t); 159static long link_elf_symtab_get(linker_file_t, const Elf_Sym **); 160static long link_elf_strtab_get(linker_file_t, caddr_t *); | 1/*- 2 * Copyright (c) 1998-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 --- 144 unchanged lines hidden (view full) --- 153 void ***, void ***, int *); 154static int link_elf_each_function_name(linker_file_t, 155 int (*)(const char *, void *), void *); 156static int link_elf_each_function_nameval(linker_file_t, 157 linker_function_nameval_callback_t, void *); 158static void link_elf_reloc_local(linker_file_t); 159static long link_elf_symtab_get(linker_file_t, const Elf_Sym **); 160static long link_elf_strtab_get(linker_file_t, caddr_t *); |
161static Elf_Addr elf_lookup(linker_file_t, Elf_Size, int); | 161static int elf_lookup(linker_file_t, Elf_Size, int, Elf_Addr *); |
162 163static kobj_method_t link_elf_methods[] = { 164 KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol), 165 KOBJMETHOD(linker_symbol_values, link_elf_symbol_values), 166 KOBJMETHOD(linker_search_symbol, link_elf_search_symbol), 167 KOBJMETHOD(linker_unload, link_elf_unload_file), 168 KOBJMETHOD(linker_load_file, link_elf_load_file), 169 KOBJMETHOD(linker_link_preload, link_elf_link_preload), --- 1373 unchanged lines hidden (view full) --- 1543 1544/* 1545 * Symbol lookup function that can be used when the symbol index is known (ie 1546 * in relocations). It uses the symbol index instead of doing a fully fledged 1547 * hash table based lookup when such is valid. For example for local symbols. 1548 * This is not only more efficient, it's also more correct. It's not always 1549 * the case that the symbol can be found through the hash table. 1550 */ | 162 163static kobj_method_t link_elf_methods[] = { 164 KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol), 165 KOBJMETHOD(linker_symbol_values, link_elf_symbol_values), 166 KOBJMETHOD(linker_search_symbol, link_elf_search_symbol), 167 KOBJMETHOD(linker_unload, link_elf_unload_file), 168 KOBJMETHOD(linker_load_file, link_elf_load_file), 169 KOBJMETHOD(linker_link_preload, link_elf_link_preload), --- 1373 unchanged lines hidden (view full) --- 1543 1544/* 1545 * Symbol lookup function that can be used when the symbol index is known (ie 1546 * in relocations). It uses the symbol index instead of doing a fully fledged 1547 * hash table based lookup when such is valid. For example for local symbols. 1548 * This is not only more efficient, it's also more correct. It's not always 1549 * the case that the symbol can be found through the hash table. 1550 */ |
1551static Elf_Addr 1552elf_lookup(linker_file_t lf, Elf_Size symidx, int deps) | 1551static int 1552elf_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *res) |
1553{ 1554 elf_file_t ef = (elf_file_t)lf; 1555 const Elf_Sym *sym; 1556 const char *symbol; 1557 Elf_Addr addr, start, base; 1558 1559 /* Don't even try to lookup the symbol if the index is bogus. */ | 1553{ 1554 elf_file_t ef = (elf_file_t)lf; 1555 const Elf_Sym *sym; 1556 const char *symbol; 1557 Elf_Addr addr, start, base; 1558 1559 /* Don't even try to lookup the symbol if the index is bogus. */ |
1560 if (symidx >= ef->nchains) 1561 return (0); | 1560 if (symidx >= ef->nchains) { 1561 *res = 0; 1562 return (EINVAL); 1563 } |
1562 1563 sym = ef->symtab + symidx; 1564 1565 /* 1566 * Don't do a full lookup when the symbol is local. It may even 1567 * fail because it may not be found through the hash table. 1568 */ 1569 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) { 1570 /* Force lookup failure when we have an insanity. */ | 1564 1565 sym = ef->symtab + symidx; 1566 1567 /* 1568 * Don't do a full lookup when the symbol is local. It may even 1569 * fail because it may not be found through the hash table. 1570 */ 1571 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) { 1572 /* Force lookup failure when we have an insanity. */ |
1571 if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0) 1572 return (0); 1573 return ((Elf_Addr)ef->address + sym->st_value); | 1573 if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0) { 1574 *res = 0; 1575 return (EINVAL); 1576 } 1577 *res = ((Elf_Addr)ef->address + sym->st_value); 1578 return (0); |
1574 } 1575 1576 /* 1577 * XXX we can avoid doing a hash table based lookup for global 1578 * symbols as well. This however is not always valid, so we'll 1579 * just do it the hard way for now. Performance tweaks can 1580 * always be added. 1581 */ 1582 1583 symbol = ef->strtab + sym->st_name; 1584 1585 /* Force a lookup failure if the symbol name is bogus. */ | 1579 } 1580 1581 /* 1582 * XXX we can avoid doing a hash table based lookup for global 1583 * symbols as well. This however is not always valid, so we'll 1584 * just do it the hard way for now. Performance tweaks can 1585 * always be added. 1586 */ 1587 1588 symbol = ef->strtab + sym->st_name; 1589 1590 /* Force a lookup failure if the symbol name is bogus. */ |
1586 if (*symbol == 0) 1587 return (0); | 1591 if (*symbol == 0) { 1592 *res = 0; 1593 return (EINVAL); 1594 } |
1588 1589 addr = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); 1590 1591 if (elf_set_find(&set_pcpu_list, addr, &start, &base)) 1592 addr = addr - start + base; 1593#ifdef VIMAGE 1594 else if (elf_set_find(&set_vnet_list, addr, &start, &base)) 1595 addr = addr - start + base; 1596#endif | 1595 1596 addr = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps)); 1597 1598 if (elf_set_find(&set_pcpu_list, addr, &start, &base)) 1599 addr = addr - start + base; 1600#ifdef VIMAGE 1601 else if (elf_set_find(&set_vnet_list, addr, &start, &base)) 1602 addr = addr - start + base; 1603#endif |
1597 return addr; | 1604 *res = addr; 1605 return (0); |
1598} 1599 1600static void 1601link_elf_reloc_local(linker_file_t lf) 1602{ 1603 const Elf_Rel *rellim; 1604 const Elf_Rel *rel; 1605 const Elf_Rela *relalim; --- 50 unchanged lines hidden --- | 1606} 1607 1608static void 1609link_elf_reloc_local(linker_file_t lf) 1610{ 1611 const Elf_Rel *rellim; 1612 const Elf_Rel *rel; 1613 const Elf_Rela *relalim; --- 50 unchanged lines hidden --- |