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 ---