Rev 3686 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3686 | Rev 3689 | ||
---|---|---|---|
Line 68... | Line 68... | ||
68 | elf_word i; |
68 | elf_word i; |
69 | char *s_name; |
69 | char *s_name; |
70 | elf_word bucket; |
70 | elf_word bucket; |
71 | 71 | ||
72 | // module_name = m->dyn.soname; |
72 | // module_name = m->dyn.soname; |
73 | // DPRINTF("def_find_in_module('%s', %s)\n", name, module_name); |
73 | DPRINTF("def_find_in_module('%s', %s)\n", name, module_name); |
74 | 74 | ||
75 | sym_table = m->dyn.sym_tab; |
75 | sym_table = m->dyn.sym_tab; |
76 | nbucket = m->dyn.hash[0]; |
76 | nbucket = m->dyn.hash[0]; |
77 | nchain = m->dyn.hash[1]; |
77 | nchain = m->dyn.hash[1]; |
78 | 78 | ||
Line 101... | Line 101... | ||
101 | } |
101 | } |
102 | 102 | ||
103 | return sym; /* Found */ |
103 | return sym; /* Found */ |
104 | } |
104 | } |
105 | 105 | ||
106 | /** Find the definition of a symbol. |
106 | /** Find the definition of a symbol in a module and its deps. |
107 | * |
107 | * |
108 | * By definition in System V ABI, if module origin has the flag DT_SYMBOLIC, |
- | |
109 | * origin is searched first. Otherwise, or if the symbol hasn't been found, |
108 | * Search the module dependency graph is breadth-first, beginning |
110 | * the module dependency graph is searched breadth-first, beginning |
109 | * from the module @a start. Thus, @start and all its dependencies |
111 | * from the executable program. |
110 | * get searched. |
112 | * |
111 | * |
113 | * @param name Name of the symbol to search for. |
112 | * @param name Name of the symbol to search for. |
114 | * @param origin Module in which the dependency originates. |
113 | * @param start Module in which to start the search.. |
115 | * @param mod (output) Will be filled with a pointer to the module |
114 | * @param mod (output) Will be filled with a pointer to the module |
116 | * that contains the symbol. |
115 | * that contains the symbol. |
117 | */ |
116 | */ |
118 | elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **mod) |
117 | elf_symbol_t *symbol_bfs_find(char *name, module_t *start, module_t **mod) |
119 | { |
118 | { |
120 | module_t *m, *dm; |
119 | module_t *m, *dm; |
121 | elf_symbol_t *sym, *s; |
120 | elf_symbol_t *sym, *s; |
122 | link_t queue_head; |
121 | link_t queue_head; |
123 | size_t i; |
122 | size_t i; |
124 | 123 | ||
125 | if (origin->dyn.symbolic) { |
- | |
126 | /* |
- | |
127 | * Origin module has a DT_SYMBOLIC flag. |
- | |
128 | * Try this module first |
- | |
129 | */ |
- | |
130 | s = def_find_in_module(name, origin); |
- | |
131 | if (s != NULL) { |
- | |
132 | /* Found */ |
- | |
133 | *mod = origin; |
- | |
134 | return s; |
- | |
135 | } |
- | |
136 | } |
- | |
137 | - | ||
138 | /* Otherwise start in the executable program */ |
- | |
139 | - | ||
140 | /* |
124 | /* |
141 | * Do a BFS using the queue_link and bfs_tag fields. |
125 | * Do a BFS using the queue_link and bfs_tag fields. |
142 | * Vertices (modules) are tagged the moment they are inserted |
126 | * Vertices (modules) are tagged the moment they are inserted |
143 | * into the queue. This prevents from visiting the same vertex |
127 | * into the queue. This prevents from visiting the same vertex |
144 | * more times in case of circular dependencies. |
128 | * more times in case of circular dependencies. |
Line 147... | Line 131... | ||
147 | /* Mark all vertices (modules) as unvisited */ |
131 | /* Mark all vertices (modules) as unvisited */ |
148 | modules_untag(); |
132 | modules_untag(); |
149 | 133 | ||
150 | /* Insert root (the program) into the queue and tag it */ |
134 | /* Insert root (the program) into the queue and tag it */ |
151 | list_initialize(&queue_head); |
135 | list_initialize(&queue_head); |
152 | runtime_env->program->bfs_tag = true; |
136 | start->bfs_tag = true; |
153 | list_append(&runtime_env->program->queue_link, &queue_head); |
137 | list_append(&start->queue_link, &queue_head); |
154 | 138 | ||
155 | /* If the symbol is found, it will be stored in 'sym' */ |
139 | /* If the symbol is found, it will be stored in 'sym' */ |
156 | sym = NULL; |
140 | sym = NULL; |
157 | 141 | ||
158 | /* While queue is not empty */ |
142 | /* While queue is not empty */ |
Line 194... | Line 178... | ||
194 | } |
178 | } |
195 | 179 | ||
196 | return sym; /* Symbol found */ |
180 | return sym; /* Symbol found */ |
197 | } |
181 | } |
198 | 182 | ||
- | 183 | ||
- | 184 | /** Find the definition of a symbol.. |
|
- | 185 | * |
|
- | 186 | * By definition in System V ABI, if module origin has the flag DT_SYMBOLIC, |
|
- | 187 | * origin is searched first. Otherwise, or if the symbol hasn't been found, |
|
- | 188 | * the module dependency graph is searched breadth-first, beginning |
|
- | 189 | * from the executable program. |
|
- | 190 | * |
|
- | 191 | * @param name Name of the symbol to search for. |
|
- | 192 | * @param origin Module in which the dependency originates. |
|
- | 193 | * @param mod (output) Will be filled with a pointer to the module |
|
- | 194 | * that contains the symbol. |
|
- | 195 | */ |
|
- | 196 | elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **mod) |
|
- | 197 | { |
|
- | 198 | module_t *m, *dm; |
|
- | 199 | elf_symbol_t *sym, *s; |
|
- | 200 | link_t queue_head; |
|
- | 201 | size_t i; |
|
- | 202 | ||
- | 203 | if (origin->dyn.symbolic) { |
|
- | 204 | /* |
|
- | 205 | * Origin module has a DT_SYMBOLIC flag. |
|
- | 206 | * Try this module first |
|
- | 207 | */ |
|
- | 208 | s = def_find_in_module(name, origin); |
|
- | 209 | if (s != NULL) { |
|
- | 210 | /* Found */ |
|
- | 211 | *mod = origin; |
|
- | 212 | return s; |
|
- | 213 | } |
|
- | 214 | } |
|
- | 215 | ||
- | 216 | /* Otherwise start in the executable program */ |
|
- | 217 | return symbol_bfs_find(name, runtime_env->program, mod); |
|
- | 218 | } |
|
- | 219 | ||
199 | uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m) |
220 | uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m) |
200 | { |
221 | { |
201 | if (sym->st_shndx == SHN_ABS) { |
222 | if (sym->st_shndx == SHN_ABS) { |
202 | /* Do not add bias to absolute symbols */ |
223 | /* Do not add bias to absolute symbols */ |
203 | return sym->st_value; |
224 | return sym->st_value; |