Fix unwind info in x86 memcmp-ssse3.
[glibc.git] / elf / dl-lookup.c
blob763ec16fa431c2a48166ebd01a9d66bc0ab3d984
1 /* Look up a symbol in the loaded objects.
2 Copyright (C) 1995-2005, 2006, 2007, 2009 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #include <alloca.h>
21 #include <libintl.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <ldsodefs.h>
26 #include <dl-hash.h>
27 #include <dl-machine.h>
28 #include <sysdep-cancel.h>
29 #include <bits/libc-lock.h>
30 #include <tls.h>
32 #include <assert.h>
34 #define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
36 /* We need this string more than once. */
37 static const char undefined_msg[] = "undefined symbol: ";
40 struct sym_val
42 const ElfW(Sym) *s;
43 struct link_map *m;
47 #define make_string(string, rest...) \
48 ({ \
49 const char *all[] = { string, ## rest }; \
50 size_t len, cnt; \
51 char *result, *cp; \
53 len = 1; \
54 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
55 len += strlen (all[cnt]); \
57 cp = result = alloca (len); \
58 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
59 cp = __stpcpy (cp, all[cnt]); \
61 result; \
64 /* Statistics function. */
65 #ifdef SHARED
66 # define bump_num_relocations() ++GL(dl_num_relocations)
67 #else
68 # define bump_num_relocations() ((void) 0)
69 #endif
72 /* Inner part of the lookup functions. We return a value > 0 if we
73 found the symbol, the value 0 if nothing is found and < 0 if
74 something bad happened. */
75 static int
76 __attribute_noinline__
77 do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
78 unsigned long int *old_hash, const ElfW(Sym) *ref,
79 struct sym_val *result, struct r_scope_elem *scope, size_t i,
80 const struct r_found_version *const version, int flags,
81 struct link_map *skip, int type_class, struct link_map *undef_map)
83 size_t n = scope->r_nlist;
84 /* Make sure we read the value before proceeding. Otherwise we
85 might use r_list pointing to the initial scope and r_nlist being
86 the value after a resize. That is the only path in dl-open.c not
87 protected by GSCOPE. A read barrier here might be to expensive. */
88 __asm volatile ("" : "+r" (n), "+m" (scope->r_list));
89 struct link_map **list = scope->r_list;
93 /* These variables are used in the nested function. */
94 Elf_Symndx symidx;
95 int num_versions = 0;
96 const ElfW(Sym) *versioned_sym = NULL;
98 const struct link_map *map = list[i]->l_real;
100 /* Here come the extra test needed for `_dl_lookup_symbol_skip'. */
101 if (map == skip)
102 continue;
104 /* Don't search the executable when resolving a copy reloc. */
105 if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable)
106 continue;
108 /* Do not look into objects which are going to be removed. */
109 if (map->l_removed)
110 continue;
112 /* Print some debugging info if wanted. */
113 if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS, 0))
114 _dl_debug_printf ("symbol=%s; lookup in file=%s [%lu]\n",
115 undef_name,
116 map->l_name[0] ? map->l_name : rtld_progname,
117 map->l_ns);
119 /* If the hash table is empty there is nothing to do here. */
120 if (map->l_nbuckets == 0)
121 continue;
123 /* The tables for this map. */
124 const ElfW(Sym) *symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
125 const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
128 /* Nested routine to check whether the symbol matches. */
129 const ElfW(Sym) *
130 __attribute_noinline__
131 check_match (const ElfW(Sym) *sym)
133 unsigned int stt = ELFW(ST_TYPE) (sym->st_info);
134 assert (ELF_RTYPE_CLASS_PLT == 1);
135 if (__builtin_expect ((sym->st_value == 0 /* No value. */
136 && stt != STT_TLS)
137 || (type_class & (sym->st_shndx == SHN_UNDEF)),
139 return NULL;
141 /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC,
142 STT_COMMON, STT_TLS, and STT_GNU_IFUNC since these are no
143 code/data definitions. */
144 #define ALLOWED_STT \
145 ((1 << STT_NOTYPE) | (1 << STT_OBJECT) | (1 << STT_FUNC) \
146 | (1 << STT_COMMON) | (1 << STT_TLS) | (1 << STT_GNU_IFUNC))
147 if (__builtin_expect (((1 << stt) & ALLOWED_STT) == 0, 0))
148 return NULL;
150 if (sym != ref && strcmp (strtab + sym->st_name, undef_name))
151 /* Not the symbol we are looking for. */
152 return NULL;
154 const ElfW(Half) *verstab = map->l_versyms;
155 if (version != NULL)
157 if (__builtin_expect (verstab == NULL, 0))
159 /* We need a versioned symbol but haven't found any. If
160 this is the object which is referenced in the verneed
161 entry it is a bug in the library since a symbol must
162 not simply disappear.
164 It would also be a bug in the object since it means that
165 the list of required versions is incomplete and so the
166 tests in dl-version.c haven't found a problem.*/
167 assert (version->filename == NULL
168 || ! _dl_name_match_p (version->filename, map));
170 /* Otherwise we accept the symbol. */
172 else
174 /* We can match the version information or use the
175 default one if it is not hidden. */
176 ElfW(Half) ndx = verstab[symidx] & 0x7fff;
177 if ((map->l_versions[ndx].hash != version->hash
178 || strcmp (map->l_versions[ndx].name, version->name))
179 && (version->hidden || map->l_versions[ndx].hash
180 || (verstab[symidx] & 0x8000)))
181 /* It's not the version we want. */
182 return NULL;
185 else
187 /* No specific version is selected. There are two ways we
188 can got here:
190 - a binary which does not include versioning information
191 is loaded
193 - dlsym() instead of dlvsym() is used to get a symbol which
194 might exist in more than one form
196 If the library does not provide symbol version information
197 there is no problem at at: we simply use the symbol if it
198 is defined.
200 These two lookups need to be handled differently if the
201 library defines versions. In the case of the old
202 unversioned application the oldest (default) version
203 should be used. In case of a dlsym() call the latest and
204 public interface should be returned. */
205 if (verstab != NULL)
207 if ((verstab[symidx] & 0x7fff)
208 >= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3))
210 /* Don't accept hidden symbols. */
211 if ((verstab[symidx] & 0x8000) == 0
212 && num_versions++ == 0)
213 /* No version so far. */
214 versioned_sym = sym;
216 return NULL;
221 /* There cannot be another entry for this symbol so stop here. */
222 return sym;
225 const ElfW(Sym) *sym;
226 const ElfW(Addr) *bitmask = map->l_gnu_bitmask;
227 if (__builtin_expect (bitmask != NULL, 1))
229 ElfW(Addr) bitmask_word
230 = bitmask[(new_hash / __ELF_NATIVE_CLASS)
231 & map->l_gnu_bitmask_idxbits];
233 unsigned int hashbit1 = new_hash & (__ELF_NATIVE_CLASS - 1);
234 unsigned int hashbit2 = ((new_hash >> map->l_gnu_shift)
235 & (__ELF_NATIVE_CLASS - 1));
237 if (__builtin_expect ((bitmask_word >> hashbit1)
238 & (bitmask_word >> hashbit2) & 1, 0))
240 Elf32_Word bucket = map->l_gnu_buckets[new_hash
241 % map->l_nbuckets];
242 if (bucket != 0)
244 const Elf32_Word *hasharr = &map->l_gnu_chain_zero[bucket];
247 if (((*hasharr ^ new_hash) >> 1) == 0)
249 symidx = hasharr - map->l_gnu_chain_zero;
250 sym = check_match (&symtab[symidx]);
251 if (sym != NULL)
252 goto found_it;
254 while ((*hasharr++ & 1u) == 0);
257 /* No symbol found. */
258 symidx = SHN_UNDEF;
260 else
262 if (*old_hash == 0xffffffff)
263 *old_hash = _dl_elf_hash (undef_name);
265 /* Use the old SysV-style hash table. Search the appropriate
266 hash bucket in this object's symbol table for a definition
267 for the same symbol name. */
268 for (symidx = map->l_buckets[*old_hash % map->l_nbuckets];
269 symidx != STN_UNDEF;
270 symidx = map->l_chain[symidx])
272 sym = check_match (&symtab[symidx]);
273 if (sym != NULL)
274 goto found_it;
278 /* If we have seen exactly one versioned symbol while we are
279 looking for an unversioned symbol and the version is not the
280 default version we still accept this symbol since there are
281 no possible ambiguities. */
282 sym = num_versions == 1 ? versioned_sym : NULL;
284 if (sym != NULL)
286 found_it:
287 switch (__builtin_expect (ELFW(ST_BIND) (sym->st_info), STB_GLOBAL))
289 case STB_WEAK:
290 /* Weak definition. Use this value if we don't find another. */
291 if (__builtin_expect (GLRO(dl_dynamic_weak), 0))
293 if (! result->s)
295 result->s = sym;
296 result->m = (struct link_map *) map;
298 break;
300 /* FALLTHROUGH */
301 case STB_GLOBAL:
302 success:
303 /* Global definition. Just what we need. */
304 result->s = sym;
305 result->m = (struct link_map *) map;
306 return 1;
308 case STB_GNU_UNIQUE:;
309 /* We have to determine whether we already found a
310 symbol with this name before. If not then we have to
311 add it to the search table. If we already found a
312 definition we have to use it. */
313 void enter (struct unique_sym *table, size_t size,
314 unsigned int hash, const char *name,
315 const ElfW(Sym) *sym, struct link_map *map)
317 size_t idx = hash % size;
318 size_t hash2 = 1 + hash % (size - 2);
319 while (1)
321 if (table[idx].name == NULL)
323 table[idx].hashval = hash;
324 table[idx].name = name;
325 if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)
327 table[idx].sym = ref;
328 table[idx].map = undef_map;
330 else
332 table[idx].sym = sym;
333 table[idx].map = map;
335 if (map->l_type == lt_loaded)
336 /* Make sure we don't unload this object by
337 setting the appropriate flag. */
338 map->l_flags_1 |= DF_1_NODELETE;
341 return;
344 idx += hash2;
345 if (idx >= size)
346 idx -= size;
350 struct unique_sym_table *tab
351 = &GL(dl_ns)[map->l_ns]._ns_unique_sym_table;
353 __rtld_lock_lock_recursive (tab->lock);
355 struct unique_sym *entries = tab->entries;
356 size_t size = tab->size;
357 if (entries != NULL)
359 size_t idx = new_hash % size;
360 size_t hash2 = 1 + new_hash % (size - 2);
361 while (1)
363 if (entries[idx].hashval == new_hash
364 && strcmp (entries[idx].name, undef_name) == 0)
366 result->s = entries[idx].sym;
367 result->m = (struct link_map *) entries[idx].map;
368 __rtld_lock_unlock_recursive (tab->lock);
369 return 1;
372 if (entries[idx].name == NULL)
373 break;
375 idx += hash2;
376 if (idx >= size)
377 idx -= size;
380 if (size * 3 <= tab->n_elements * 4)
382 /* Expand the table. */
383 #ifdef RTLD_CHECK_FOREIGN_CALL
384 /* This must not happen during runtime relocations. */
385 assert (!RTLD_CHECK_FOREIGN_CALL);
386 #endif
387 size_t newsize = _dl_higher_prime_number (size + 1);
388 struct unique_sym *newentries
389 = calloc (sizeof (struct unique_sym), newsize);
390 if (newentries == NULL)
392 nomem:
393 __rtld_lock_unlock_recursive (tab->lock);
394 _dl_fatal_printf ("out of memory\n");
397 for (idx = 0; idx < size; ++idx)
398 if (entries[idx].name != NULL)
399 enter (newentries, newsize, entries[idx].hashval,
400 entries[idx].name, entries[idx].sym,
401 entries[idx].map);
403 tab->free (entries);
404 tab->size = newsize;
405 size = newsize;
406 entries = tab->entries = newentries;
407 tab->free = free;
410 else
412 #ifdef RTLD_CHECK_FOREIGN_CALL
413 /* This must not happen during runtime relocations. */
414 assert (!RTLD_CHECK_FOREIGN_CALL);
415 #endif
417 #define INITIAL_NUNIQUE_SYM_TABLE 31
418 size = INITIAL_NUNIQUE_SYM_TABLE;
419 entries = calloc (sizeof (struct unique_sym), size);
420 if (entries == NULL)
421 goto nomem;
423 tab->entries = entries;
424 tab->size = size;
425 tab->free = free;
428 enter (entries, size, new_hash, strtab + sym->st_name, sym,
429 (struct link_map *) map);
430 ++tab->n_elements;
432 __rtld_lock_unlock_recursive (tab->lock);
434 goto success;
436 default:
437 /* Local symbols are ignored. */
438 break;
442 /* If this current map is the one mentioned in the verneed entry
443 and we have not found a weak entry, it is a bug. */
444 if (symidx == STN_UNDEF && version != NULL && version->filename != NULL
445 && __builtin_expect (_dl_name_match_p (version->filename, map), 0))
446 return -1;
448 while (++i < n);
450 /* We have not found anything until now. */
451 return 0;
455 static uint_fast32_t
456 dl_new_hash (const char *s)
458 uint_fast32_t h = 5381;
459 for (unsigned char c = *s; c != '\0'; c = *++s)
460 h = h * 33 + c;
461 return h & 0xffffffff;
465 /* Add extra dependency on MAP to UNDEF_MAP. */
466 static int
467 internal_function
468 add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
470 struct link_map *runp;
471 unsigned int i;
472 int result = 0;
474 /* Avoid self-references and references to objects which cannot be
475 unloaded anyway. */
476 if (undef_map == map)
477 return 0;
479 /* Avoid references to objects which cannot be unloaded anyway. */
480 assert (map->l_type == lt_loaded);
481 if ((map->l_flags_1 & DF_1_NODELETE) != 0)
482 return 0;
484 struct link_map_reldeps *l_reldeps
485 = atomic_forced_read (undef_map->l_reldeps);
487 /* Make sure l_reldeps is read before l_initfini. */
488 atomic_read_barrier ();
490 /* Determine whether UNDEF_MAP already has a reference to MAP. First
491 look in the normal dependencies. */
492 struct link_map **l_initfini = atomic_forced_read (undef_map->l_initfini);
493 if (l_initfini != NULL)
495 for (i = 0; l_initfini[i] != NULL; ++i)
496 if (l_initfini[i] == map)
497 return 0;
500 /* No normal dependency. See whether we already had to add it
501 to the special list of dynamic dependencies. */
502 unsigned int l_reldepsact = 0;
503 if (l_reldeps != NULL)
505 struct link_map **list = &l_reldeps->list[0];
506 l_reldepsact = l_reldeps->act;
507 for (i = 0; i < l_reldepsact; ++i)
508 if (list[i] == map)
509 return 0;
512 /* Save serial number of the target MAP. */
513 unsigned long long serial = map->l_serial;
515 /* Make sure nobody can unload the object while we are at it. */
516 if (__builtin_expect (flags & DL_LOOKUP_GSCOPE_LOCK, 0))
518 /* We can't just call __rtld_lock_lock_recursive (GL(dl_load_lock))
519 here, that can result in ABBA deadlock. */
520 THREAD_GSCOPE_RESET_FLAG ();
521 __rtld_lock_lock_recursive (GL(dl_load_lock));
522 /* While MAP value won't change, after THREAD_GSCOPE_RESET_FLAG ()
523 it can e.g. point to unallocated memory. So avoid the optimizer
524 treating the above read from MAP->l_serial as ensurance it
525 can safely dereference it. */
526 map = atomic_forced_read (map);
528 /* From this point on it is unsafe to dereference MAP, until it
529 has been found in one of the lists. */
531 /* Redo the l_initfini check in case undef_map's l_initfini
532 changed in the mean time. */
533 if (undef_map->l_initfini != l_initfini
534 && undef_map->l_initfini != NULL)
536 l_initfini = undef_map->l_initfini;
537 for (i = 0; l_initfini[i] != NULL; ++i)
538 if (l_initfini[i] == map)
539 goto out_check;
542 /* Redo the l_reldeps check if undef_map's l_reldeps changed in
543 the mean time. */
544 if (undef_map->l_reldeps != NULL)
546 if (undef_map->l_reldeps != l_reldeps)
548 struct link_map **list = &undef_map->l_reldeps->list[0];
549 l_reldepsact = undef_map->l_reldeps->act;
550 for (i = 0; i < l_reldepsact; ++i)
551 if (list[i] == map)
552 goto out_check;
554 else if (undef_map->l_reldeps->act > l_reldepsact)
556 struct link_map **list
557 = &undef_map->l_reldeps->list[0];
558 i = l_reldepsact;
559 l_reldepsact = undef_map->l_reldeps->act;
560 for (; i < l_reldepsact; ++i)
561 if (list[i] == map)
562 goto out_check;
566 else
567 __rtld_lock_lock_recursive (GL(dl_load_lock));
569 /* The object is not yet in the dependency list. Before we add
570 it make sure just one more time the object we are about to
571 reference is still available. There is a brief period in
572 which the object could have been removed since we found the
573 definition. */
574 runp = GL(dl_ns)[undef_map->l_ns]._ns_loaded;
575 while (runp != NULL && runp != map)
576 runp = runp->l_next;
578 if (runp != NULL)
580 /* The object is still available. */
582 /* MAP could have been dlclosed, freed and then some other dlopened
583 library could have the same link_map pointer. */
584 if (map->l_serial != serial)
585 goto out_check;
587 /* Redo the NODELETE check, as when dl_load_lock wasn't held
588 yet this could have changed. */
589 if ((map->l_flags_1 & DF_1_NODELETE) != 0)
590 goto out;
592 /* If the object with the undefined reference cannot be removed ever
593 just make sure the same is true for the object which contains the
594 definition. */
595 if (undef_map->l_type != lt_loaded
596 || (undef_map->l_flags_1 & DF_1_NODELETE) != 0)
598 map->l_flags_1 |= DF_1_NODELETE;
599 goto out;
602 /* Add the reference now. */
603 if (__builtin_expect (l_reldepsact >= undef_map->l_reldepsmax, 0))
605 /* Allocate more memory for the dependency list. Since this
606 can never happen during the startup phase we can use
607 `realloc'. */
608 struct link_map_reldeps *newp;
609 unsigned int max
610 = undef_map->l_reldepsmax ? undef_map->l_reldepsmax * 2 : 10;
612 #ifdef RTLD_PREPARE_FOREIGN_CALL
613 RTLD_PREPARE_FOREIGN_CALL;
614 #endif
616 newp = malloc (sizeof (*newp) + max * sizeof (struct link_map *));
617 if (newp == NULL)
619 /* If we didn't manage to allocate memory for the list this is
620 no fatal problem. We simply make sure the referenced object
621 cannot be unloaded. This is semantically the correct
622 behavior. */
623 map->l_flags_1 |= DF_1_NODELETE;
624 goto out;
626 else
628 if (l_reldepsact)
629 memcpy (&newp->list[0], &undef_map->l_reldeps->list[0],
630 l_reldepsact * sizeof (struct link_map *));
631 newp->list[l_reldepsact] = map;
632 newp->act = l_reldepsact + 1;
633 atomic_write_barrier ();
634 void *old = undef_map->l_reldeps;
635 undef_map->l_reldeps = newp;
636 undef_map->l_reldepsmax = max;
637 if (old)
638 _dl_scope_free (old);
641 else
643 undef_map->l_reldeps->list[l_reldepsact] = map;
644 atomic_write_barrier ();
645 undef_map->l_reldeps->act = l_reldepsact + 1;
648 /* Display information if we are debugging. */
649 if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
650 _dl_debug_printf ("\
651 \nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n",
652 map->l_name[0] ? map->l_name : rtld_progname,
653 map->l_ns,
654 undef_map->l_name[0]
655 ? undef_map->l_name : rtld_progname,
656 undef_map->l_ns);
658 else
659 /* Whoa, that was bad luck. We have to search again. */
660 result = -1;
662 out:
663 /* Release the lock. */
664 __rtld_lock_unlock_recursive (GL(dl_load_lock));
666 if (__builtin_expect (flags & DL_LOOKUP_GSCOPE_LOCK, 0))
667 THREAD_GSCOPE_SET_FLAG ();
669 return result;
671 out_check:
672 if (map->l_serial != serial)
673 result = -1;
674 goto out;
677 static void
678 internal_function
679 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
680 const ElfW(Sym) **ref, struct sym_val *value,
681 const struct r_found_version *version, int type_class,
682 int protected);
685 /* Search loaded objects' symbol tables for a definition of the symbol
686 UNDEF_NAME, perhaps with a requested version for the symbol.
688 We must never have calls to the audit functions inside this function
689 or in any function which gets called. If this would happen the audit
690 code might create a thread which can throw off all the scope locking. */
691 lookup_t
692 internal_function
693 _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
694 const ElfW(Sym) **ref,
695 struct r_scope_elem *symbol_scope[],
696 const struct r_found_version *version,
697 int type_class, int flags, struct link_map *skip_map)
699 const uint_fast32_t new_hash = dl_new_hash (undef_name);
700 unsigned long int old_hash = 0xffffffff;
701 struct sym_val current_value = { NULL, NULL };
702 struct r_scope_elem **scope = symbol_scope;
704 bump_num_relocations ();
706 /* No other flag than DL_LOOKUP_ADD_DEPENDENCY or DL_LOOKUP_GSCOPE_LOCK
707 is allowed if we look up a versioned symbol. */
708 assert (version == NULL
709 || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_GSCOPE_LOCK))
710 == 0);
712 size_t i = 0;
713 if (__builtin_expect (skip_map != NULL, 0))
714 /* Search the relevant loaded objects for a definition. */
715 while ((*scope)->r_list[i] != skip_map)
716 ++i;
718 /* Search the relevant loaded objects for a definition. */
719 for (size_t start = i; *scope != NULL; start = 0, ++scope)
721 int res = do_lookup_x (undef_name, new_hash, &old_hash, *ref,
722 &current_value, *scope, start, version, flags,
723 skip_map, type_class, undef_map);
724 if (res > 0)
725 break;
727 if (__builtin_expect (res, 0) < 0 && skip_map == NULL)
729 /* Oh, oh. The file named in the relocation entry does not
730 contain the needed symbol. This code is never reached
731 for unversioned lookups. */
732 assert (version != NULL);
733 const char *reference_name = undef_map ? undef_map->l_name : NULL;
735 /* XXX We cannot translate the message. */
736 _dl_signal_cerror (0, (reference_name[0]
737 ? reference_name
738 : (rtld_progname ?: "<main program>")),
739 N_("relocation error"),
740 make_string ("symbol ", undef_name, ", version ",
741 version->name,
742 " not defined in file ",
743 version->filename,
744 " with link time reference",
745 res == -2
746 ? " (no version symbols)" : ""));
747 *ref = NULL;
748 return 0;
752 if (__builtin_expect (current_value.s == NULL, 0))
754 if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
755 && skip_map == NULL)
757 /* We could find no value for a strong reference. */
758 const char *reference_name = undef_map ? undef_map->l_name : "";
759 const char *versionstr = version ? ", version " : "";
760 const char *versionname = (version && version->name
761 ? version->name : "");
763 /* XXX We cannot translate the message. */
764 _dl_signal_cerror (0, (reference_name[0]
765 ? reference_name
766 : (rtld_progname ?: "<main program>")),
767 N_("symbol lookup error"),
768 make_string (undefined_msg, undef_name,
769 versionstr, versionname));
771 *ref = NULL;
772 return 0;
775 int protected = (*ref
776 && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED);
777 if (__builtin_expect (protected != 0, 0))
779 /* It is very tricky. We need to figure out what value to
780 return for the protected symbol. */
781 if (type_class == ELF_RTYPE_CLASS_PLT)
783 if (current_value.s != NULL && current_value.m != undef_map)
785 current_value.s = *ref;
786 current_value.m = undef_map;
789 else
791 struct sym_val protected_value = { NULL, NULL };
793 for (scope = symbol_scope; *scope != NULL; i = 0, ++scope)
794 if (do_lookup_x (undef_name, new_hash, &old_hash, *ref,
795 &protected_value, *scope, i, version, flags,
796 skip_map, ELF_RTYPE_CLASS_PLT, NULL) != 0)
797 break;
799 if (protected_value.s != NULL && protected_value.m != undef_map)
801 current_value.s = *ref;
802 current_value.m = undef_map;
807 /* We have to check whether this would bind UNDEF_MAP to an object
808 in the global scope which was dynamically loaded. In this case
809 we have to prevent the latter from being unloaded unless the
810 UNDEF_MAP object is also unloaded. */
811 if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
812 /* Don't do this for explicit lookups as opposed to implicit
813 runtime lookups. */
814 && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
815 /* Add UNDEF_MAP to the dependencies. */
816 && add_dependency (undef_map, current_value.m, flags) < 0)
817 /* Something went wrong. Perhaps the object we tried to reference
818 was just removed. Try finding another definition. */
819 return _dl_lookup_symbol_x (undef_name, undef_map, ref,
820 (flags & DL_LOOKUP_GSCOPE_LOCK)
821 ? undef_map->l_scope : symbol_scope,
822 version, type_class, flags, skip_map);
824 /* The object is used. */
825 if (__builtin_expect (current_value.m->l_used == 0, 0))
826 current_value.m->l_used = 1;
828 if (__builtin_expect (GLRO(dl_debug_mask)
829 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
830 _dl_debug_bindings (undef_name, undef_map, ref,
831 &current_value, version, type_class, protected);
833 *ref = current_value.s;
834 return LOOKUP_VALUE (current_value.m);
838 /* Cache the location of MAP's hash table. */
840 void
841 internal_function
842 _dl_setup_hash (struct link_map *map)
844 Elf_Symndx *hash;
845 Elf_Symndx nchain;
847 if (__builtin_expect (map->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
848 + DT_THISPROCNUM + DT_VERSIONTAGNUM
849 + DT_EXTRANUM + DT_VALNUM] != NULL, 1))
851 Elf32_Word *hash32
852 = (void *) D_PTR (map, l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
853 + DT_THISPROCNUM + DT_VERSIONTAGNUM
854 + DT_EXTRANUM + DT_VALNUM]);
855 map->l_nbuckets = *hash32++;
856 Elf32_Word symbias = *hash32++;
857 Elf32_Word bitmask_nwords = *hash32++;
858 /* Must be a power of two. */
859 assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
860 map->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
861 map->l_gnu_shift = *hash32++;
863 map->l_gnu_bitmask = (ElfW(Addr) *) hash32;
864 hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;
866 map->l_gnu_buckets = hash32;
867 hash32 += map->l_nbuckets;
868 map->l_gnu_chain_zero = hash32 - symbias;
869 return;
872 if (!map->l_info[DT_HASH])
873 return;
874 hash = (void *) D_PTR (map, l_info[DT_HASH]);
876 map->l_nbuckets = *hash++;
877 nchain = *hash++;
878 map->l_buckets = hash;
879 hash += map->l_nbuckets;
880 map->l_chain = hash;
884 static void
885 internal_function
886 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
887 const ElfW(Sym) **ref, struct sym_val *value,
888 const struct r_found_version *version, int type_class,
889 int protected)
891 const char *reference_name = undef_map->l_name;
893 if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
895 _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
896 (reference_name[0]
897 ? reference_name
898 : (rtld_progname ?: "<main program>")),
899 undef_map->l_ns,
900 value->m->l_name[0] ? value->m->l_name : rtld_progname,
901 value->m->l_ns,
902 protected ? "protected" : "normal", undef_name);
903 if (version)
904 _dl_debug_printf_c (" [%s]\n", version->name);
905 else
906 _dl_debug_printf_c ("\n");
908 #ifdef SHARED
909 if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
911 int conflict = 0;
912 struct sym_val val = { NULL, NULL };
914 if ((GLRO(dl_trace_prelink_map) == NULL
915 || GLRO(dl_trace_prelink_map) == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
916 && undef_map != GL(dl_ns)[LM_ID_BASE]._ns_loaded)
918 const uint_fast32_t new_hash = dl_new_hash (undef_name);
919 unsigned long int old_hash = 0xffffffff;
921 do_lookup_x (undef_name, new_hash, &old_hash, *ref, &val,
922 undef_map->l_local_scope[0], 0, version, 0, NULL,
923 type_class, undef_map);
925 if (val.s != value->s || val.m != value->m)
926 conflict = 1;
929 if (value->s)
931 if (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
932 == STT_TLS, 0))
933 type_class = 4;
934 else if (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
935 == STT_GNU_IFUNC, 0))
936 type_class |= 8;
939 if (conflict
940 || GLRO(dl_trace_prelink_map) == undef_map
941 || GLRO(dl_trace_prelink_map) == NULL
942 || type_class >= 4)
944 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
945 conflict ? "conflict" : "lookup",
946 (int) sizeof (ElfW(Addr)) * 2,
947 (size_t) undef_map->l_map_start,
948 (int) sizeof (ElfW(Addr)) * 2,
949 (size_t) (((ElfW(Addr)) *ref) - undef_map->l_map_start),
950 (int) sizeof (ElfW(Addr)) * 2,
951 (size_t) (value->s ? value->m->l_map_start : 0),
952 (int) sizeof (ElfW(Addr)) * 2,
953 (size_t) (value->s ? value->s->st_value : 0));
955 if (conflict)
956 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
957 (int) sizeof (ElfW(Addr)) * 2,
958 (size_t) (val.s ? val.m->l_map_start : 0),
959 (int) sizeof (ElfW(Addr)) * 2,
960 (size_t) (val.s ? val.s->st_value : 0));
962 _dl_printf ("/%x %s\n", type_class, undef_name);
965 #endif