Lines 32-37
Link Here
|
32 |
|
32 |
|
33 |
#define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag)) |
33 |
#define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag)) |
34 |
|
34 |
|
|
|
35 |
#ifndef SUSEIDX |
36 |
# define SUSEIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM + \ |
37 |
DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM + DT_SUSE_TAGIDX (sym)) |
38 |
#endif |
39 |
|
35 |
/* We need this string more than once. */ |
40 |
/* We need this string more than once. */ |
36 |
static const char undefined_msg[] = "undefined symbol: "; |
41 |
static const char undefined_msg[] = "undefined symbol: "; |
37 |
|
42 |
|
Lines 209-214
Link Here
|
209 |
unsigned long int hash; |
214 |
unsigned long int hash; |
210 |
struct sym_val current_value = { NULL, NULL }; |
215 |
struct sym_val current_value = { NULL, NULL }; |
211 |
struct r_scope_elem **scope = symbol_scope; |
216 |
struct r_scope_elem **scope = symbol_scope; |
|
|
217 |
size_t i = 0; |
212 |
|
218 |
|
213 |
/* This sucks mostly - but people sadly don't pass a symtab index, or hashvals ptr in */ |
219 |
/* This sucks mostly - but people sadly don't pass a symtab index, or hashvals ptr in */ |
214 |
const Elf_Symndx *hashvals; |
220 |
const Elf_Symndx *hashvals; |
Lines 244-250
Link Here
|
244 |
up a versioned symbol. */ |
250 |
up a versioned symbol. */ |
245 |
assert (version == NULL || flags == 0 || flags == DL_LOOKUP_ADD_DEPENDENCY); |
251 |
assert (version == NULL || flags == 0 || flags == DL_LOOKUP_ADD_DEPENDENCY); |
246 |
|
252 |
|
247 |
size_t i = 0; |
253 |
if (__builtin_expect (undef_map != NULL, 1) && |
|
|
254 |
__builtin_expect (undef_map->l_dtneeded.r_nlist != NULL, 0) && |
255 |
__builtin_expect (*ref != NULL, 1)) |
256 |
{ |
257 |
unsigned int idx, noffset; |
258 |
const ElfW(Sym) *symtab; |
259 |
ElfW(Addr) direct; |
260 |
|
261 |
/* We need a dynsym index ... */ |
262 |
symtab = (const void *) D_PTR (undef_map, l_info[DT_SYMTAB]); |
263 |
direct = D_PTR (undef_map, l_info[SUSEIDX(DT_SUSE_DIRECT)]); |
264 |
|
265 |
idx = *ref - symtab; |
266 |
if (__builtin_expect ((GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) != 0, 0)) |
267 |
_dl_debug_printf ("dynamic symbol index %u from '%s' for %s base direct 0x%x start 0x%x\n", idx, |
268 |
undef_map->l_name ? undef_map->l_name : "<noname>", |
269 |
undef_name ? undef_name : "<undef>", |
270 |
(int) direct, (int) undef_map->l_map_start); |
271 |
direct += idx * 2; |
272 |
if (direct >= undef_map->l_map_end || direct <= undef_map->l_map_start) |
273 |
_dl_debug_printf ("broken: off end of map 0x%x\n", (int) direct); |
274 |
else |
275 |
{ |
276 |
noffset = *(uint16_t *)direct; |
277 |
if (__builtin_expect ((GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) != 0, 0)) |
278 |
_dl_debug_printf ("dynamic symbol offset %u from 0x%x\n", noffset, (int) direct); |
279 |
if (noffset & DT_SUSE_DIRECT_VAGUE) |
280 |
{ |
281 |
if (__builtin_expect ((GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) != 0, 0)) |
282 |
_dl_debug_printf ("vague symbol\n"); |
283 |
goto normal_lookup; |
284 |
} |
285 |
|
286 |
noffset &= DT_SUSE_DIRECT_MASK; |
287 |
|
288 |
if (__builtin_expect (noffset < undef_map->l_dtneeded.r_nlist, 1)) |
289 |
{ |
290 |
int res; |
291 |
struct r_scope_elem direct_elem; |
292 |
|
293 |
/* FIXME - requires LD_PRELOAD support ... */ |
294 |
direct_elem.r_list = undef_map->l_dtneeded.r_list + noffset; |
295 |
direct_elem.r_nlist = 1; |
296 |
|
297 |
if (direct_elem.r_list[0] == skip_map) |
298 |
goto normal_lookup; /* FIXME - correct ? */ |
299 |
|
300 |
res = do_lookup_x (undef_name, hash, *ref, ¤t_value, &direct_elem, |
301 |
0, version, flags, skip_map, type_class); |
302 |
if (res > 0) |
303 |
{ |
304 |
if (__builtin_expect ((GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) != 0, 0)) |
305 |
_dl_debug_printf ("direct lookup ...\n"); |
306 |
goto match; |
307 |
} |
308 |
else |
309 |
_dl_debug_printf ("Error in lookup %u - missing (?) - fallback " |
310 |
"to deps & then global ? ...\n", res); |
311 |
} |
312 |
else if (noffset == DT_SUSE_DIRECT_UNKNOWN) |
313 |
{ |
314 |
if (__builtin_expect ((GLRO(dl_debug_mask) & DL_DEBUG_DIRECT) != 0, 0)) |
315 |
_dl_debug_printf ("unknown/undefined symbol '%s'\n", |
316 |
undef_name ? undef_name : "<undef>"); |
317 |
} |
318 |
else |
319 |
{ |
320 |
_dl_debug_printf ("Error: foo symbol '%s' 0 < %u < %u\n", |
321 |
undef_name ? undef_name : "<undef>", |
322 |
noffset, undef_map->l_dtneeded.r_nlist); |
323 |
} |
324 |
} |
325 |
} |
326 |
normal_lookup: |
327 |
|
248 |
if (__builtin_expect (skip_map != NULL, 0)) |
328 |
if (__builtin_expect (skip_map != NULL, 0)) |
249 |
{ |
329 |
{ |
250 |
/* Search the relevant loaded objects for a definition. */ |
330 |
/* Search the relevant loaded objects for a definition. */ |
Lines 286-292
Link Here
|
286 |
return 0; |
366 |
return 0; |
287 |
} |
367 |
} |
288 |
} |
368 |
} |
289 |
|
369 |
match: |
290 |
if (__builtin_expect (current_value.s == NULL, 0)) |
370 |
if (__builtin_expect (current_value.s == NULL, 0)) |
291 |
{ |
371 |
{ |
292 |
if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) |
372 |
if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) |