Add more tests of acos.
[glibc.git] / elf / dl-lookup.c
blob5fa76ba675a743866e9995cf9dfd8c15b4dc044c
1 /* Look up a symbol in the loaded objects.
2 Copyright (C) 1995-2015 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, see
17 <http://www.gnu.org/licenses/>. */
19 #include <alloca.h>
20 #include <libintl.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <ldsodefs.h>
25 #include <dl-hash.h>
26 #include <dl-machine.h>
27 #include <sysdep-cancel.h>
28 #include <bits/libc-lock.h>
29 #include <tls.h>
30 #include <atomic.h>
32 #include <assert.h>
34 /* Return nonzero if check_match should consider SYM to fail to match a
35 symbol reference for some machine-specific reason. */
36 #ifndef ELF_MACHINE_SYM_NO_MATCH
37 # define ELF_MACHINE_SYM_NO_MATCH(sym) 0
38 #endif
40 #define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
43 struct sym_val
45 const ElfW(Sym) *s;
46 struct link_map *m;
50 #define make_string(string, rest...) \
51 ({ \
52 const char *all[] = { string, ## rest }; \
53 size_t len, cnt; \
54 char *result, *cp; \
56 len = 1; \
57 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
58 len += strlen (all[cnt]); \
60 cp = result = alloca (len); \
61 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
62 cp = __stpcpy (cp, all[cnt]); \
64 result; \
67 /* Statistics function. */
68 #ifdef SHARED
69 # define bump_num_relocations() ++GL(dl_num_relocations)
70 #else
71 # define bump_num_relocations() ((void) 0)
72 #endif
74 /* Utility function for do_lookup_x. The caller is called with undef_name,
75 ref, version, flags and type_class, and those are passed as the first
76 five arguments. The caller then computes sym, symidx, strtab, and map
77 and passes them as the next four arguments. Lastly the caller passes in
78 versioned_sym and num_versions which are modified by check_match during
79 the checking process. */
80 static const ElfW(Sym) *
81 check_match (const char *const undef_name,
82 const ElfW(Sym) *const ref,
83 const struct r_found_version *const version,
84 const int flags,
85 const int type_class,
86 const ElfW(Sym) *const sym,
87 const Elf_Symndx symidx,
88 const char *const strtab,
89 const struct link_map *const map,
90 const ElfW(Sym) **const versioned_sym,
91 int *const num_versions)
93 unsigned int stt = ELFW(ST_TYPE) (sym->st_info);
94 assert (ELF_RTYPE_CLASS_PLT == 1);
95 if (__glibc_unlikely ((sym->st_value == 0 /* No value. */
96 && stt != STT_TLS)
97 || ELF_MACHINE_SYM_NO_MATCH (sym)
98 || (type_class & (sym->st_shndx == SHN_UNDEF))))
99 return NULL;
101 /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC,
102 STT_COMMON, STT_TLS, and STT_GNU_IFUNC since these are no
103 code/data definitions. */
104 #define ALLOWED_STT \
105 ((1 << STT_NOTYPE) | (1 << STT_OBJECT) | (1 << STT_FUNC) \
106 | (1 << STT_COMMON) | (1 << STT_TLS) | (1 << STT_GNU_IFUNC))
107 if (__glibc_unlikely (((1 << stt) & ALLOWED_STT) == 0))
108 return NULL;
110 if (sym != ref && strcmp (strtab + sym->st_name, undef_name))
111 /* Not the symbol we are looking for. */
112 return NULL;
114 const ElfW(Half) *verstab = map->l_versyms;
115 if (version != NULL)
117 if (__glibc_unlikely (verstab == NULL))
119 /* We need a versioned symbol but haven't found any. If
120 this is the object which is referenced in the verneed
121 entry it is a bug in the library since a symbol must
122 not simply disappear.
124 It would also be a bug in the object since it means that
125 the list of required versions is incomplete and so the
126 tests in dl-version.c haven't found a problem.*/
127 assert (version->filename == NULL
128 || ! _dl_name_match_p (version->filename, map));
130 /* Otherwise we accept the symbol. */
132 else
134 /* We can match the version information or use the
135 default one if it is not hidden. */
136 ElfW(Half) ndx = verstab[symidx] & 0x7fff;
137 if ((map->l_versions[ndx].hash != version->hash
138 || strcmp (map->l_versions[ndx].name, version->name))
139 && (version->hidden || map->l_versions[ndx].hash
140 || (verstab[symidx] & 0x8000)))
141 /* It's not the version we want. */
142 return NULL;
145 else
147 /* No specific version is selected. There are two ways we
148 can got here:
150 - a binary which does not include versioning information
151 is loaded
153 - dlsym() instead of dlvsym() is used to get a symbol which
154 might exist in more than one form
156 If the library does not provide symbol version information
157 there is no problem at all: we simply use the symbol if it
158 is defined.
160 These two lookups need to be handled differently if the
161 library defines versions. In the case of the old
162 unversioned application the oldest (default) version
163 should be used. In case of a dlsym() call the latest and
164 public interface should be returned. */
165 if (verstab != NULL)
167 if ((verstab[symidx] & 0x7fff)
168 >= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3))
170 /* Don't accept hidden symbols. */
171 if ((verstab[symidx] & 0x8000) == 0
172 && (*num_versions)++ == 0)
173 /* No version so far. */
174 *versioned_sym = sym;
176 return NULL;
181 /* There cannot be another entry for this symbol so stop here. */
182 return sym;
185 /* Utility function for do_lookup_unique. Add a symbol to TABLE. */
186 static void
187 enter_unique_sym (struct unique_sym *table, size_t size,
188 unsigned int hash, const char *name,
189 const ElfW(Sym) *sym, const struct link_map *map)
191 size_t idx = hash % size;
192 size_t hash2 = 1 + hash % (size - 2);
193 while (table[idx].name != NULL)
195 idx += hash2;
196 if (idx >= size)
197 idx -= size;
200 table[idx].hashval = hash;
201 table[idx].name = name;
202 table[idx].sym = sym;
203 table[idx].map = map;
206 /* Utility function for do_lookup_x. Lookup an STB_GNU_UNIQUE symbol
207 in the unique symbol table, creating a new entry if necessary.
208 Return the matching symbol in RESULT. */
209 static void
210 do_lookup_unique (const char *undef_name, uint_fast32_t new_hash,
211 const struct link_map *map, struct sym_val *result,
212 int type_class, const ElfW(Sym) *sym, const char *strtab,
213 const ElfW(Sym) *ref, const struct link_map *undef_map)
215 /* We have to determine whether we already found a symbol with this
216 name before. If not then we have to add it to the search table.
217 If we already found a definition we have to use it. */
219 struct unique_sym_table *tab
220 = &GL(dl_ns)[map->l_ns]._ns_unique_sym_table;
222 __rtld_lock_lock_recursive (tab->lock);
224 struct unique_sym *entries = tab->entries;
225 size_t size = tab->size;
226 if (entries != NULL)
228 size_t idx = new_hash % size;
229 size_t hash2 = 1 + new_hash % (size - 2);
230 while (1)
232 if (entries[idx].hashval == new_hash
233 && strcmp (entries[idx].name, undef_name) == 0)
235 if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)
237 /* We possibly have to initialize the central
238 copy from the copy addressed through the
239 relocation. */
240 result->s = sym;
241 result->m = (struct link_map *) map;
243 else
245 result->s = entries[idx].sym;
246 result->m = (struct link_map *) entries[idx].map;
248 __rtld_lock_unlock_recursive (tab->lock);
249 return;
252 if (entries[idx].name == NULL)
253 break;
255 idx += hash2;
256 if (idx >= size)
257 idx -= size;
260 if (size * 3 <= tab->n_elements * 4)
262 /* Expand the table. */
263 #ifdef RTLD_CHECK_FOREIGN_CALL
264 /* This must not happen during runtime relocations. */
265 assert (!RTLD_CHECK_FOREIGN_CALL);
266 #endif
267 size_t newsize = _dl_higher_prime_number (size + 1);
268 struct unique_sym *newentries
269 = calloc (sizeof (struct unique_sym), newsize);
270 if (newentries == NULL)
272 nomem:
273 __rtld_lock_unlock_recursive (tab->lock);
274 _dl_fatal_printf ("out of memory\n");
277 for (idx = 0; idx < size; ++idx)
278 if (entries[idx].name != NULL)
279 enter_unique_sym (newentries, newsize, entries[idx].hashval,
280 entries[idx].name, entries[idx].sym,
281 entries[idx].map);
283 tab->free (entries);
284 tab->size = newsize;
285 size = newsize;
286 entries = tab->entries = newentries;
287 tab->free = free;
290 else
292 #ifdef RTLD_CHECK_FOREIGN_CALL
293 /* This must not happen during runtime relocations. */
294 assert (!RTLD_CHECK_FOREIGN_CALL);
295 #endif
297 #ifdef SHARED
298 /* If tab->entries is NULL, but tab->size is not, it means
299 this is the second, conflict finding, lookup for
300 LD_TRACE_PRELINKING in _dl_debug_bindings. Don't
301 allocate anything and don't enter anything into the
302 hash table. */
303 if (__glibc_unlikely (tab->size))
305 assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK);
306 goto success;
308 #endif
310 #define INITIAL_NUNIQUE_SYM_TABLE 31
311 size = INITIAL_NUNIQUE_SYM_TABLE;
312 entries = calloc (sizeof (struct unique_sym), size);
313 if (entries == NULL)
314 goto nomem;
316 tab->entries = entries;
317 tab->size = size;
318 tab->free = free;
321 if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)
322 enter_unique_sym (entries, size, new_hash, strtab + sym->st_name, ref,
323 undef_map);
324 else
326 enter_unique_sym (entries, size,
327 new_hash, strtab + sym->st_name, sym, map);
329 if (map->l_type == lt_loaded)
330 /* Make sure we don't unload this object by
331 setting the appropriate flag. */
332 ((struct link_map *) map)->l_flags_1 |= DF_1_NODELETE;
334 ++tab->n_elements;
336 #ifdef SHARED
337 success:
338 #endif
339 __rtld_lock_unlock_recursive (tab->lock);
341 result->s = sym;
342 result->m = (struct link_map *) map;
345 /* Inner part of the lookup functions. We return a value > 0 if we
346 found the symbol, the value 0 if nothing is found and < 0 if
347 something bad happened. */
348 static int
349 __attribute_noinline__
350 do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
351 unsigned long int *old_hash, const ElfW(Sym) *ref,
352 struct sym_val *result, struct r_scope_elem *scope, size_t i,
353 const struct r_found_version *const version, int flags,
354 struct link_map *skip, int type_class, struct link_map *undef_map)
356 size_t n = scope->r_nlist;
357 /* Make sure we read the value before proceeding. Otherwise we
358 might use r_list pointing to the initial scope and r_nlist being
359 the value after a resize. That is the only path in dl-open.c not
360 protected by GSCOPE. A read barrier here might be to expensive. */
361 __asm volatile ("" : "+r" (n), "+m" (scope->r_list));
362 struct link_map **list = scope->r_list;
366 const struct link_map *map = list[i]->l_real;
368 /* Here come the extra test needed for `_dl_lookup_symbol_skip'. */
369 if (map == skip)
370 continue;
372 /* Don't search the executable when resolving a copy reloc. */
373 if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable)
374 continue;
376 /* Do not look into objects which are going to be removed. */
377 if (map->l_removed)
378 continue;
380 /* Print some debugging info if wanted. */
381 if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS))
382 _dl_debug_printf ("symbol=%s; lookup in file=%s [%lu]\n",
383 undef_name, DSO_FILENAME (map->l_name),
384 map->l_ns);
386 /* If the hash table is empty there is nothing to do here. */
387 if (map->l_nbuckets == 0)
388 continue;
390 Elf_Symndx symidx;
391 int num_versions = 0;
392 const ElfW(Sym) *versioned_sym = NULL;
394 /* The tables for this map. */
395 const ElfW(Sym) *symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
396 const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
398 const ElfW(Sym) *sym;
399 const ElfW(Addr) *bitmask = map->l_gnu_bitmask;
400 if (__glibc_likely (bitmask != NULL))
402 ElfW(Addr) bitmask_word
403 = bitmask[(new_hash / __ELF_NATIVE_CLASS)
404 & map->l_gnu_bitmask_idxbits];
406 unsigned int hashbit1 = new_hash & (__ELF_NATIVE_CLASS - 1);
407 unsigned int hashbit2 = ((new_hash >> map->l_gnu_shift)
408 & (__ELF_NATIVE_CLASS - 1));
410 if (__glibc_unlikely ((bitmask_word >> hashbit1)
411 & (bitmask_word >> hashbit2) & 1))
413 Elf32_Word bucket = map->l_gnu_buckets[new_hash
414 % map->l_nbuckets];
415 if (bucket != 0)
417 const Elf32_Word *hasharr = &map->l_gnu_chain_zero[bucket];
420 if (((*hasharr ^ new_hash) >> 1) == 0)
422 symidx = hasharr - map->l_gnu_chain_zero;
423 sym = check_match (undef_name, ref, version, flags,
424 type_class, &symtab[symidx], symidx,
425 strtab, map, &versioned_sym,
426 &num_versions);
427 if (sym != NULL)
428 goto found_it;
430 while ((*hasharr++ & 1u) == 0);
433 /* No symbol found. */
434 symidx = SHN_UNDEF;
436 else
438 if (*old_hash == 0xffffffff)
439 *old_hash = _dl_elf_hash (undef_name);
441 /* Use the old SysV-style hash table. Search the appropriate
442 hash bucket in this object's symbol table for a definition
443 for the same symbol name. */
444 for (symidx = map->l_buckets[*old_hash % map->l_nbuckets];
445 symidx != STN_UNDEF;
446 symidx = map->l_chain[symidx])
448 sym = check_match (undef_name, ref, version, flags,
449 type_class, &symtab[symidx], symidx,
450 strtab, map, &versioned_sym,
451 &num_versions);
452 if (sym != NULL)
453 goto found_it;
457 /* If we have seen exactly one versioned symbol while we are
458 looking for an unversioned symbol and the version is not the
459 default version we still accept this symbol since there are
460 no possible ambiguities. */
461 sym = num_versions == 1 ? versioned_sym : NULL;
463 if (sym != NULL)
465 found_it:
466 switch (ELFW(ST_BIND) (sym->st_info))
468 case STB_WEAK:
469 /* Weak definition. Use this value if we don't find another. */
470 if (__glibc_unlikely (GLRO(dl_dynamic_weak)))
472 if (! result->s)
474 result->s = sym;
475 result->m = (struct link_map *) map;
477 break;
479 /* FALLTHROUGH */
480 case STB_GLOBAL:
481 /* Global definition. Just what we need. */
482 result->s = sym;
483 result->m = (struct link_map *) map;
484 return 1;
486 case STB_GNU_UNIQUE:;
487 do_lookup_unique (undef_name, new_hash, map, result, type_class,
488 sym, strtab, ref, undef_map);
489 return 1;
491 default:
492 /* Local symbols are ignored. */
493 break;
497 /* If this current map is the one mentioned in the verneed entry
498 and we have not found a weak entry, it is a bug. */
499 if (symidx == STN_UNDEF && version != NULL && version->filename != NULL
500 && __glibc_unlikely (_dl_name_match_p (version->filename, map)))
501 return -1;
503 while (++i < n);
505 /* We have not found anything until now. */
506 return 0;
510 static uint_fast32_t
511 dl_new_hash (const char *s)
513 uint_fast32_t h = 5381;
514 for (unsigned char c = *s; c != '\0'; c = *++s)
515 h = h * 33 + c;
516 return h & 0xffffffff;
520 /* Add extra dependency on MAP to UNDEF_MAP. */
521 static int
522 internal_function
523 add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
525 struct link_map *runp;
526 unsigned int i;
527 int result = 0;
529 /* Avoid self-references and references to objects which cannot be
530 unloaded anyway. */
531 if (undef_map == map)
532 return 0;
534 /* Avoid references to objects which cannot be unloaded anyway. */
535 assert (map->l_type == lt_loaded);
536 if ((map->l_flags_1 & DF_1_NODELETE) != 0)
537 return 0;
539 struct link_map_reldeps *l_reldeps
540 = atomic_forced_read (undef_map->l_reldeps);
542 /* Make sure l_reldeps is read before l_initfini. */
543 atomic_read_barrier ();
545 /* Determine whether UNDEF_MAP already has a reference to MAP. First
546 look in the normal dependencies. */
547 struct link_map **l_initfini = atomic_forced_read (undef_map->l_initfini);
548 if (l_initfini != NULL)
550 for (i = 0; l_initfini[i] != NULL; ++i)
551 if (l_initfini[i] == map)
552 return 0;
555 /* No normal dependency. See whether we already had to add it
556 to the special list of dynamic dependencies. */
557 unsigned int l_reldepsact = 0;
558 if (l_reldeps != NULL)
560 struct link_map **list = &l_reldeps->list[0];
561 l_reldepsact = l_reldeps->act;
562 for (i = 0; i < l_reldepsact; ++i)
563 if (list[i] == map)
564 return 0;
567 /* Save serial number of the target MAP. */
568 unsigned long long serial = map->l_serial;
570 /* Make sure nobody can unload the object while we are at it. */
571 if (__glibc_unlikely (flags & DL_LOOKUP_GSCOPE_LOCK))
573 /* We can't just call __rtld_lock_lock_recursive (GL(dl_load_lock))
574 here, that can result in ABBA deadlock. */
575 THREAD_GSCOPE_RESET_FLAG ();
576 __rtld_lock_lock_recursive (GL(dl_load_lock));
577 /* While MAP value won't change, after THREAD_GSCOPE_RESET_FLAG ()
578 it can e.g. point to unallocated memory. So avoid the optimizer
579 treating the above read from MAP->l_serial as ensurance it
580 can safely dereference it. */
581 map = atomic_forced_read (map);
583 /* From this point on it is unsafe to dereference MAP, until it
584 has been found in one of the lists. */
586 /* Redo the l_initfini check in case undef_map's l_initfini
587 changed in the mean time. */
588 if (undef_map->l_initfini != l_initfini
589 && undef_map->l_initfini != NULL)
591 l_initfini = undef_map->l_initfini;
592 for (i = 0; l_initfini[i] != NULL; ++i)
593 if (l_initfini[i] == map)
594 goto out_check;
597 /* Redo the l_reldeps check if undef_map's l_reldeps changed in
598 the mean time. */
599 if (undef_map->l_reldeps != NULL)
601 if (undef_map->l_reldeps != l_reldeps)
603 struct link_map **list = &undef_map->l_reldeps->list[0];
604 l_reldepsact = undef_map->l_reldeps->act;
605 for (i = 0; i < l_reldepsact; ++i)
606 if (list[i] == map)
607 goto out_check;
609 else if (undef_map->l_reldeps->act > l_reldepsact)
611 struct link_map **list
612 = &undef_map->l_reldeps->list[0];
613 i = l_reldepsact;
614 l_reldepsact = undef_map->l_reldeps->act;
615 for (; i < l_reldepsact; ++i)
616 if (list[i] == map)
617 goto out_check;
621 else
622 __rtld_lock_lock_recursive (GL(dl_load_lock));
624 /* The object is not yet in the dependency list. Before we add
625 it make sure just one more time the object we are about to
626 reference is still available. There is a brief period in
627 which the object could have been removed since we found the
628 definition. */
629 runp = GL(dl_ns)[undef_map->l_ns]._ns_loaded;
630 while (runp != NULL && runp != map)
631 runp = runp->l_next;
633 if (runp != NULL)
635 /* The object is still available. */
637 /* MAP could have been dlclosed, freed and then some other dlopened
638 library could have the same link_map pointer. */
639 if (map->l_serial != serial)
640 goto out_check;
642 /* Redo the NODELETE check, as when dl_load_lock wasn't held
643 yet this could have changed. */
644 if ((map->l_flags_1 & DF_1_NODELETE) != 0)
645 goto out;
647 /* If the object with the undefined reference cannot be removed ever
648 just make sure the same is true for the object which contains the
649 definition. */
650 if (undef_map->l_type != lt_loaded
651 || (undef_map->l_flags_1 & DF_1_NODELETE) != 0)
653 map->l_flags_1 |= DF_1_NODELETE;
654 goto out;
657 /* Add the reference now. */
658 if (__glibc_unlikely (l_reldepsact >= undef_map->l_reldepsmax))
660 /* Allocate more memory for the dependency list. Since this
661 can never happen during the startup phase we can use
662 `realloc'. */
663 struct link_map_reldeps *newp;
664 unsigned int max
665 = undef_map->l_reldepsmax ? undef_map->l_reldepsmax * 2 : 10;
667 #ifdef RTLD_PREPARE_FOREIGN_CALL
668 RTLD_PREPARE_FOREIGN_CALL;
669 #endif
671 newp = malloc (sizeof (*newp) + max * sizeof (struct link_map *));
672 if (newp == NULL)
674 /* If we didn't manage to allocate memory for the list this is
675 no fatal problem. We simply make sure the referenced object
676 cannot be unloaded. This is semantically the correct
677 behavior. */
678 map->l_flags_1 |= DF_1_NODELETE;
679 goto out;
681 else
683 if (l_reldepsact)
684 memcpy (&newp->list[0], &undef_map->l_reldeps->list[0],
685 l_reldepsact * sizeof (struct link_map *));
686 newp->list[l_reldepsact] = map;
687 newp->act = l_reldepsact + 1;
688 atomic_write_barrier ();
689 void *old = undef_map->l_reldeps;
690 undef_map->l_reldeps = newp;
691 undef_map->l_reldepsmax = max;
692 if (old)
693 _dl_scope_free (old);
696 else
698 undef_map->l_reldeps->list[l_reldepsact] = map;
699 atomic_write_barrier ();
700 undef_map->l_reldeps->act = l_reldepsact + 1;
703 /* Display information if we are debugging. */
704 if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
705 _dl_debug_printf ("\
706 \nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n",
707 DSO_FILENAME (map->l_name),
708 map->l_ns,
709 DSO_FILENAME (undef_map->l_name),
710 undef_map->l_ns);
712 else
713 /* Whoa, that was bad luck. We have to search again. */
714 result = -1;
716 out:
717 /* Release the lock. */
718 __rtld_lock_unlock_recursive (GL(dl_load_lock));
720 if (__glibc_unlikely (flags & DL_LOOKUP_GSCOPE_LOCK))
721 THREAD_GSCOPE_SET_FLAG ();
723 return result;
725 out_check:
726 if (map->l_serial != serial)
727 result = -1;
728 goto out;
731 static void
732 internal_function
733 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
734 const ElfW(Sym) **ref, struct sym_val *value,
735 const struct r_found_version *version, int type_class,
736 int protected);
739 /* Search loaded objects' symbol tables for a definition of the symbol
740 UNDEF_NAME, perhaps with a requested version for the symbol.
742 We must never have calls to the audit functions inside this function
743 or in any function which gets called. If this would happen the audit
744 code might create a thread which can throw off all the scope locking. */
745 lookup_t
746 internal_function
747 _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
748 const ElfW(Sym) **ref,
749 struct r_scope_elem *symbol_scope[],
750 const struct r_found_version *version,
751 int type_class, int flags, struct link_map *skip_map)
753 const uint_fast32_t new_hash = dl_new_hash (undef_name);
754 unsigned long int old_hash = 0xffffffff;
755 struct sym_val current_value = { NULL, NULL };
756 struct r_scope_elem **scope = symbol_scope;
758 bump_num_relocations ();
760 /* No other flag than DL_LOOKUP_ADD_DEPENDENCY or DL_LOOKUP_GSCOPE_LOCK
761 is allowed if we look up a versioned symbol. */
762 assert (version == NULL
763 || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_GSCOPE_LOCK))
764 == 0);
766 size_t i = 0;
767 if (__glibc_unlikely (skip_map != NULL))
768 /* Search the relevant loaded objects for a definition. */
769 while ((*scope)->r_list[i] != skip_map)
770 ++i;
772 /* Search the relevant loaded objects for a definition. */
773 for (size_t start = i; *scope != NULL; start = 0, ++scope)
775 int res = do_lookup_x (undef_name, new_hash, &old_hash, *ref,
776 &current_value, *scope, start, version, flags,
777 skip_map, type_class, undef_map);
778 if (res > 0)
779 break;
781 if (__glibc_unlikely (res < 0) && skip_map == NULL)
783 /* Oh, oh. The file named in the relocation entry does not
784 contain the needed symbol. This code is never reached
785 for unversioned lookups. */
786 assert (version != NULL);
787 const char *reference_name = undef_map ? undef_map->l_name : "";
789 /* XXX We cannot translate the message. */
790 _dl_signal_cerror (0, DSO_FILENAME (reference_name),
791 N_("relocation error"),
792 make_string ("symbol ", undef_name, ", version ",
793 version->name,
794 " not defined in file ",
795 version->filename,
796 " with link time reference",
797 res == -2
798 ? " (no version symbols)" : ""));
799 *ref = NULL;
800 return 0;
804 if (__glibc_unlikely (current_value.s == NULL))
806 if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
807 && skip_map == NULL
808 && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED))
810 /* We could find no value for a strong reference. */
811 const char *reference_name = undef_map ? undef_map->l_name : "";
812 const char *versionstr = version ? ", version " : "";
813 const char *versionname = (version && version->name
814 ? version->name : "");
816 /* XXX We cannot translate the message. */
817 _dl_signal_cerror (0, DSO_FILENAME (reference_name),
818 N_("symbol lookup error"),
819 make_string ("undefined symbol: ", undef_name,
820 versionstr, versionname));
822 *ref = NULL;
823 return 0;
826 int protected = (*ref
827 && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED);
828 if (__glibc_unlikely (protected != 0))
830 /* It is very tricky. We need to figure out what value to
831 return for the protected symbol. */
832 if (type_class == ELF_RTYPE_CLASS_PLT)
834 if (current_value.s != NULL && current_value.m != undef_map)
836 current_value.s = *ref;
837 current_value.m = undef_map;
840 else
842 struct sym_val protected_value = { NULL, NULL };
844 for (scope = symbol_scope; *scope != NULL; i = 0, ++scope)
845 if (do_lookup_x (undef_name, new_hash, &old_hash, *ref,
846 &protected_value, *scope, i, version, flags,
847 skip_map, ELF_RTYPE_CLASS_PLT, NULL) != 0)
848 break;
850 if (protected_value.s != NULL && protected_value.m != undef_map)
852 current_value.s = *ref;
853 current_value.m = undef_map;
858 /* We have to check whether this would bind UNDEF_MAP to an object
859 in the global scope which was dynamically loaded. In this case
860 we have to prevent the latter from being unloaded unless the
861 UNDEF_MAP object is also unloaded. */
862 if (__glibc_unlikely (current_value.m->l_type == lt_loaded)
863 /* Don't do this for explicit lookups as opposed to implicit
864 runtime lookups. */
865 && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
866 /* Add UNDEF_MAP to the dependencies. */
867 && add_dependency (undef_map, current_value.m, flags) < 0)
868 /* Something went wrong. Perhaps the object we tried to reference
869 was just removed. Try finding another definition. */
870 return _dl_lookup_symbol_x (undef_name, undef_map, ref,
871 (flags & DL_LOOKUP_GSCOPE_LOCK)
872 ? undef_map->l_scope : symbol_scope,
873 version, type_class, flags, skip_map);
875 /* The object is used. */
876 if (__glibc_unlikely (current_value.m->l_used == 0))
877 current_value.m->l_used = 1;
879 if (__glibc_unlikely (GLRO(dl_debug_mask)
880 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK)))
881 _dl_debug_bindings (undef_name, undef_map, ref,
882 &current_value, version, type_class, protected);
884 *ref = current_value.s;
885 return LOOKUP_VALUE (current_value.m);
889 /* Cache the location of MAP's hash table. */
891 void
892 internal_function
893 _dl_setup_hash (struct link_map *map)
895 Elf_Symndx *hash;
897 if (__glibc_likely (map->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
898 + DT_THISPROCNUM + DT_VERSIONTAGNUM
899 + DT_EXTRANUM + DT_VALNUM] != NULL))
901 Elf32_Word *hash32
902 = (void *) D_PTR (map, l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
903 + DT_THISPROCNUM + DT_VERSIONTAGNUM
904 + DT_EXTRANUM + DT_VALNUM]);
905 map->l_nbuckets = *hash32++;
906 Elf32_Word symbias = *hash32++;
907 Elf32_Word bitmask_nwords = *hash32++;
908 /* Must be a power of two. */
909 assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
910 map->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
911 map->l_gnu_shift = *hash32++;
913 map->l_gnu_bitmask = (ElfW(Addr) *) hash32;
914 hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;
916 map->l_gnu_buckets = hash32;
917 hash32 += map->l_nbuckets;
918 map->l_gnu_chain_zero = hash32 - symbias;
919 return;
922 if (!map->l_info[DT_HASH])
923 return;
924 hash = (void *) D_PTR (map, l_info[DT_HASH]);
926 map->l_nbuckets = *hash++;
927 /* Skip nchain. */
928 hash++;
929 map->l_buckets = hash;
930 hash += map->l_nbuckets;
931 map->l_chain = hash;
935 static void
936 internal_function
937 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
938 const ElfW(Sym) **ref, struct sym_val *value,
939 const struct r_found_version *version, int type_class,
940 int protected)
942 const char *reference_name = undef_map->l_name;
944 if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
946 _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
947 DSO_FILENAME (reference_name),
948 undef_map->l_ns,
949 DSO_FILENAME (value->m->l_name),
950 value->m->l_ns,
951 protected ? "protected" : "normal", undef_name);
952 if (version)
953 _dl_debug_printf_c (" [%s]\n", version->name);
954 else
955 _dl_debug_printf_c ("\n");
957 #ifdef SHARED
958 if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
960 int conflict = 0;
961 struct sym_val val = { NULL, NULL };
963 if ((GLRO(dl_trace_prelink_map) == NULL
964 || GLRO(dl_trace_prelink_map) == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
965 && undef_map != GL(dl_ns)[LM_ID_BASE]._ns_loaded)
967 const uint_fast32_t new_hash = dl_new_hash (undef_name);
968 unsigned long int old_hash = 0xffffffff;
969 struct unique_sym *saved_entries
970 = GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries;
972 GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = NULL;
973 do_lookup_x (undef_name, new_hash, &old_hash, *ref, &val,
974 undef_map->l_local_scope[0], 0, version, 0, NULL,
975 type_class, undef_map);
976 if (val.s != value->s || val.m != value->m)
977 conflict = 1;
978 else if (__glibc_unlikely (undef_map->l_symbolic_in_local_scope)
979 && val.s
980 && __glibc_unlikely (ELFW(ST_BIND) (val.s->st_info)
981 == STB_GNU_UNIQUE))
983 /* If it is STB_GNU_UNIQUE and undef_map's l_local_scope
984 contains any DT_SYMBOLIC libraries, unfortunately there
985 can be conflicts even if the above is equal. As symbol
986 resolution goes from the last library to the first and
987 if a STB_GNU_UNIQUE symbol is found in some late DT_SYMBOLIC
988 library, it would be the one that is looked up. */
989 struct sym_val val2 = { NULL, NULL };
990 size_t n;
991 struct r_scope_elem *scope = undef_map->l_local_scope[0];
993 for (n = 0; n < scope->r_nlist; n++)
994 if (scope->r_list[n] == val.m)
995 break;
997 for (n++; n < scope->r_nlist; n++)
998 if (scope->r_list[n]->l_info[DT_SYMBOLIC] != NULL
999 && do_lookup_x (undef_name, new_hash, &old_hash, *ref,
1000 &val2,
1001 &scope->r_list[n]->l_symbolic_searchlist,
1002 0, version, 0, NULL, type_class,
1003 undef_map) > 0)
1005 conflict = 1;
1006 val = val2;
1007 break;
1010 GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = saved_entries;
1013 if (value->s)
1015 if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
1016 == STT_TLS))
1017 type_class = 4;
1018 else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
1019 == STT_GNU_IFUNC))
1020 type_class |= 8;
1023 if (conflict
1024 || GLRO(dl_trace_prelink_map) == undef_map
1025 || GLRO(dl_trace_prelink_map) == NULL
1026 || type_class >= 4)
1028 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
1029 conflict ? "conflict" : "lookup",
1030 (int) sizeof (ElfW(Addr)) * 2,
1031 (size_t) undef_map->l_map_start,
1032 (int) sizeof (ElfW(Addr)) * 2,
1033 (size_t) (((ElfW(Addr)) *ref) - undef_map->l_map_start),
1034 (int) sizeof (ElfW(Addr)) * 2,
1035 (size_t) (value->s ? value->m->l_map_start : 0),
1036 (int) sizeof (ElfW(Addr)) * 2,
1037 (size_t) (value->s ? value->s->st_value : 0));
1039 if (conflict)
1040 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
1041 (int) sizeof (ElfW(Addr)) * 2,
1042 (size_t) (val.s ? val.m->l_map_start : 0),
1043 (int) sizeof (ElfW(Addr)) * 2,
1044 (size_t) (val.s ? val.s->st_value : 0));
1046 _dl_printf ("/%x %s\n", type_class, undef_name);
1049 #endif