• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <common.h>
2 #include <debug.h>
3 #include <libelf.h>
4 #include <hash.h>
5 #include <string.h>
6 
setup_hash(Elf_Data * hash_data,Elf32_Word nbuckets,Elf32_Word nchains)7 void setup_hash(Elf_Data *hash_data,
8                 Elf32_Word nbuckets,
9                 Elf32_Word nchains)
10 {
11     hash_data->d_size  = 2;
12     hash_data->d_size += nbuckets;
13     hash_data->d_size += nchains;
14     hash_data->d_buf   = CALLOC(hash_data->d_size, sizeof(Elf32_Word));
15     hash_data->d_size *= sizeof(Elf32_Word);
16     ((Elf32_Word *)hash_data->d_buf)[0] = nbuckets;
17     ((Elf32_Word *)hash_data->d_buf)[1] = nchains;
18 }
19 
add_to_hash(Elf_Data * hash_data,const char * symbol,int symindex)20 void add_to_hash(Elf_Data *hash_data,
21                  const char *symbol,
22                  int symindex)
23 {
24     Elf32_Word *buckets  = (Elf32_Word *)hash_data->d_buf;
25     Elf32_Word nbuckets  = *buckets++;
26     Elf32_Word *chains   = ++buckets + nbuckets;
27     Elf32_Word last_chain_index;
28     unsigned long bucket = elf_hash(symbol) % nbuckets;
29 
30     ASSERT(symindex != STN_UNDEF);
31 
32     if (buckets[bucket] == STN_UNDEF) {
33         INFO("Adding [%s] to hash at bucket [%ld] (first add)\n",
34              symbol, bucket);
35         buckets[bucket] = symindex;
36     }
37     else {
38         INFO("Collision on adding [%s] to hash at bucket [%ld]\n",
39              symbol, bucket);
40         last_chain_index = buckets[bucket];
41         while (chains[last_chain_index] != STN_UNDEF) {
42             INFO("\ttrying at chain index [%d]...\n", last_chain_index);
43             last_chain_index = chains[last_chain_index];
44         }
45         INFO("\tsuccess at chain index [%d]...\n", last_chain_index);
46         chains[last_chain_index] = symindex;
47     }
48 }
49 
hash_lookup(Elf * elf,section_info_t * hash_info,section_info_t * symtab_info,const char * symname,GElf_Sym * sym_mem)50 int hash_lookup(Elf *elf,
51                 section_info_t *hash_info,
52                 section_info_t *symtab_info,
53                 const char *symname,
54                 GElf_Sym *sym_mem)
55 {
56     Elf32_Word *hash_data = (Elf32_Word *)hash_info->data->d_buf;
57     Elf32_Word index;
58     Elf32_Word nbuckets = *hash_data++;
59     Elf32_Word *buckets = ++hash_data;
60     Elf32_Word *chains  = hash_data + nbuckets;
61 
62     GElf_Sym *sym;
63 
64     index = buckets[elf_hash(symname) % nbuckets];
65     while(index != STN_UNDEF)
66     {
67         sym = gelf_getsymshndx (symtab_info->data, NULL, index, sym_mem, NULL);
68         FAILIF_LIBELF(NULL == sym, gelf_getsymshndx);
69         if (!strcmp(symname,
70                     elf_strptr(elf, symtab_info->hdr->sh_link, sym->st_name)))
71             break;
72         index = chains[index];
73     }
74 
75     return index;
76 }
77