Rev 2981 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2981 | Rev 2998 | ||
---|---|---|---|
Line 40... | Line 40... | ||
40 | 40 | ||
41 | #include <rtld.h> |
41 | #include <rtld.h> |
42 | #include <symbol.h> |
42 | #include <symbol.h> |
43 | #include <elf.h> |
43 | #include <elf.h> |
44 | 44 | ||
- | 45 | /* |
|
- | 46 | * Hash tables are 32-bit (elf_word) even for 64-bit ELF files. |
|
- | 47 | */ |
|
- | 48 | static elf_word elf_hash(const unsigned char *name) |
|
- | 49 | { |
|
- | 50 | elf_word h = 0, g; |
|
- | 51 | ||
- | 52 | while (*name) { |
|
- | 53 | h = (h << 4) + *name++; |
|
- | 54 | g = h & 0xf0000000; |
|
- | 55 | if (g != 0) h ^= g >> 24; |
|
- | 56 | h &= ~g; |
|
- | 57 | } |
|
- | 58 | ||
- | 59 | return h; |
|
- | 60 | } |
|
- | 61 | ||
45 | static elf_symbol_t *def_find_in_module(char *name, module_t *m) |
62 | static elf_symbol_t *def_find_in_module(char *name, module_t *m) |
46 | { |
63 | { |
47 | elf_symbol_t *sym_table; |
64 | elf_symbol_t *sym_table; |
48 | elf_symbol_t *sym; |
65 | elf_symbol_t *s, *sym; |
- | 66 | elf_word nbucket; |
|
49 | elf_word nchain; |
67 | elf_word nchain; |
50 | size_t i; |
68 | elf_word i; |
51 | char *s_name; |
69 | char *s_name; |
52 | char *module_name; |
70 | elf_word bucket; |
53 | 71 | ||
54 | module_name = m->dyn.soname; |
72 | // module_name = m->dyn.soname; |
55 | // printf("def_find_in_module('%s', %s)\n", name, module_name); |
73 | // printf("def_find_in_module('%s', %s)\n", name, module_name); |
56 | 74 | ||
57 | sym_table = m->dyn.sym_tab; |
75 | sym_table = m->dyn.sym_tab; |
- | 76 | nbucket = m->dyn.hash[0]; |
|
58 | nchain = m->dyn.hash[1]; |
77 | nchain = m->dyn.hash[1]; |
59 | 78 | ||
- | 79 | bucket = elf_hash((unsigned char *)name) % nbucket; |
|
- | 80 | i = m->dyn.hash[2 + bucket]; |
|
- | 81 | ||
- | 82 | sym = NULL; |
|
60 | for (i = 0; i < nchain; ++i) { |
83 | while (i != STN_UNDEF) { |
61 | sym = &sym_table[i]; |
84 | s = &sym_table[i]; |
62 | s_name = m->dyn.str_tab + sym->st_name; |
85 | s_name = m->dyn.str_tab + s->st_name; |
63 | // printf("cmp sym '%s'\n", s_name); |
- | |
- | 86 | ||
64 | if (strcmp(name, s_name) == 0) { |
87 | if (strcmp(name, s_name) == 0) { |
65 | // printf("name match\n"); |
- | |
66 | if (sym->st_shndx != SHN_UNDEF) { |
- | |
67 | // printf("definition found. idx=%d\n", i); |
- | |
68 | return sym; |
88 | sym = s; |
69 | } else { |
89 | break; |
70 | // printf("not a definition\n"); |
- | |
71 | } |
- | |
72 | } |
90 | } |
- | 91 | ||
- | 92 | i = m->dyn.hash[2 + nbucket + i]; |
|
73 | } |
93 | } |
74 | 94 | ||
- | 95 | if (!sym) |
|
75 | // printf("not found\n"); |
96 | return NULL; /* Not found */ |
- | 97 | ||
- | 98 | if (sym->st_shndx == SHN_UNDEF) { |
|
- | 99 | /* Not a definition */ |
|
76 | return NULL; |
100 | return NULL; |
- | 101 | } |
|
- | 102 | ||
- | 103 | return sym; /* Found */ |
|
77 | } |
104 | } |
78 | 105 | ||
79 | 106 | ||
80 | elf_symbol_t *symbol_def_find(char *name, module_t **m) |
107 | elf_symbol_t *symbol_def_find(char *name, module_t **m) |
81 | { |
108 | { |
Line 93... | Line 120... | ||
93 | printf("symbol found nowhere\n"); |
120 | printf("symbol found nowhere\n"); |
94 | *m = NULL; |
121 | *m = NULL; |
95 | return NULL; |
122 | return NULL; |
96 | } |
123 | } |
97 | 124 | ||
- | 125 | uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m) |
|
- | 126 | { |
|
- | 127 | if (sym->st_shndx == SHN_ABS) { |
|
- | 128 | /* Do not add bias to absolute symbols */ |
|
- | 129 | return sym->st_value; |
|
- | 130 | } else { |
|
- | 131 | return sym->st_value + m->bias; |
|
- | 132 | } |
|
- | 133 | } |
|
- | 134 | ||
98 | /** @} |
135 | /** @} |
99 | */ |
136 | */ |