1/* Look up a symbol in the loaded objects.
2 Copyright (C) 1995-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
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.
9
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.
14
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 <https://www.gnu.org/licenses/>. */
18
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 <dl-protected.h>
28#include <sysdep-cancel.h>
29#include <libc-lock.h>
30#include <tls.h>
31#include <atomic.h>
32#include <elf_machine_sym_no_match.h>
33
34#include <assert.h>
35
36#define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
37
38struct sym_val
39 {
40 const ElfW(Sym) *s;
41 struct link_map *m;
42 };
43
44
45/* Statistics function. */
46#ifdef SHARED
47# define bump_num_relocations() ++GL(dl_num_relocations)
48#else
49# define bump_num_relocations() ((void) 0)
50#endif
51
52/* Utility function for do_lookup_x. The caller is called with undef_name,
53 ref, version, flags and type_class, and those are passed as the first
54 five arguments. The caller then computes sym, symidx, strtab, and map
55 and passes them as the next four arguments. Lastly the caller passes in
56 versioned_sym and num_versions which are modified by check_match during
57 the checking process. */
58static const ElfW(Sym) *
59check_match (const char *const undef_name,
60 const ElfW(Sym) *const ref,
61 const struct r_found_version *const version,
62 const int flags,
63 const int type_class,
64 const ElfW(Sym) *const sym,
65 const Elf_Symndx symidx,
66 const char *const strtab,
67 const struct link_map *const map,
68 const ElfW(Sym) **const versioned_sym,
69 int *const num_versions)
70{
71 unsigned int stt = ELFW(ST_TYPE) (sym->st_info);
72 assert (ELF_RTYPE_CLASS_PLT == 1);
73 if (__glibc_unlikely ((sym->st_value == 0 /* No value. */
74 && sym->st_shndx != SHN_ABS
75 && stt != STT_TLS)
76 || elf_machine_sym_no_match (sym)
77 || (type_class & (sym->st_shndx == SHN_UNDEF))))
78 return NULL;
79
80 /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC,
81 STT_COMMON, STT_TLS, and STT_GNU_IFUNC since these are no
82 code/data definitions. */
83#define ALLOWED_STT \
84 ((1 << STT_NOTYPE) | (1 << STT_OBJECT) | (1 << STT_FUNC) \
85 | (1 << STT_COMMON) | (1 << STT_TLS) | (1 << STT_GNU_IFUNC))
86 if (__glibc_unlikely (((1 << stt) & ALLOWED_STT) == 0))
87 return NULL;
88
89 if (sym != ref && strcmp (strtab + sym->st_name, undef_name))
90 /* Not the symbol we are looking for. */
91 return NULL;
92
93 const ElfW(Half) *verstab = map->l_versyms;
94 if (version != NULL)
95 {
96 if (__glibc_unlikely (verstab == NULL))
97 {
98 /* We need a versioned symbol but haven't found any. If
99 this is the object which is referenced in the verneed
100 entry it is a bug in the library since a symbol must
101 not simply disappear.
102
103 It would also be a bug in the object since it means that
104 the list of required versions is incomplete and so the
105 tests in dl-version.c haven't found a problem.*/
106 assert (version->filename == NULL
107 || ! _dl_name_match_p (version->filename, map));
108
109 /* Otherwise we accept the symbol. */
110 }
111 else
112 {
113 /* We can match the version information or use the
114 default one if it is not hidden. */
115 ElfW(Half) ndx = verstab[symidx] & 0x7fff;
116 if ((map->l_versions[ndx].hash != version->hash
117 || strcmp (map->l_versions[ndx].name, version->name))
118 && (version->hidden || map->l_versions[ndx].hash
119 || (verstab[symidx] & 0x8000)))
120 /* It's not the version we want. */
121 return NULL;
122 }
123 }
124 else
125 {
126 /* No specific version is selected. There are two ways we
127 can got here:
128
129 - a binary which does not include versioning information
130 is loaded
131
132 - dlsym() instead of dlvsym() is used to get a symbol which
133 might exist in more than one form
134
135 If the library does not provide symbol version information
136 there is no problem at all: we simply use the symbol if it
137 is defined.
138
139 These two lookups need to be handled differently if the
140 library defines versions. In the case of the old
141 unversioned application the oldest (default) version
142 should be used. In case of a dlsym() call the latest and
143 public interface should be returned. */
144 if (verstab != NULL)
145 {
146 if ((verstab[symidx] & 0x7fff)
147 >= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3))
148 {
149 /* Don't accept hidden symbols. */
150 if ((verstab[symidx] & 0x8000) == 0
151 && (*num_versions)++ == 0)
152 /* No version so far. */
153 *versioned_sym = sym;
154
155 return NULL;
156 }
157 }
158 }
159
160 /* There cannot be another entry for this symbol so stop here. */
161 return sym;
162}
163
164/* Utility function for do_lookup_unique. Add a symbol to TABLE. */
165static void
166enter_unique_sym (struct unique_sym *table, size_t size,
167 unsigned int hash, const char *name,
168 const ElfW(Sym) *sym, const struct link_map *map)
169{
170 size_t idx = hash % size;
171 size_t hash2 = 1 + hash % (size - 2);
172 while (table[idx].name != NULL)
173 {
174 idx += hash2;
175 if (idx >= size)
176 idx -= size;
177 }
178
179 table[idx].hashval = hash;
180 table[idx].name = name;
181 table[idx].sym = sym;
182 table[idx].map = map;
183}
184
185/* Mark MAP as NODELETE according to the lookup mode in FLAGS. During
186 initial relocation, NODELETE state is pending only. */
187static void
188mark_nodelete (struct link_map *map, int flags)
189{
190 if (flags & DL_LOOKUP_FOR_RELOCATE)
191 map->l_nodelete_pending = true;
192 else
193 map->l_nodelete_active = true;
194}
195
196/* Return true if MAP is marked as NODELETE according to the lookup
197 mode in FLAGS> */
198static bool
199is_nodelete (struct link_map *map, int flags)
200{
201 /* Non-pending NODELETE always counts. Pending NODELETE only counts
202 during initial relocation processing. */
203 return map->l_nodelete_active
204 || ((flags & DL_LOOKUP_FOR_RELOCATE) && map->l_nodelete_pending);
205}
206
207/* Utility function for do_lookup_x. Lookup an STB_GNU_UNIQUE symbol
208 in the unique symbol table, creating a new entry if necessary.
209 Return the matching symbol in RESULT. */
210static void
211do_lookup_unique (const char *undef_name, uint_fast32_t new_hash,
212 struct link_map *map, struct sym_val *result,
213 int type_class, const ElfW(Sym) *sym, const char *strtab,
214 const ElfW(Sym) *ref, const struct link_map *undef_map,
215 int flags)
216{
217 /* We have to determine whether we already found a symbol with this
218 name before. If not then we have to add it to the search table.
219 If we already found a definition we have to use it. */
220
221 struct unique_sym_table *tab
222 = &GL(dl_ns)[map->l_ns]._ns_unique_sym_table;
223
224 __rtld_lock_lock_recursive (tab->lock);
225
226 struct unique_sym *entries = tab->entries;
227 size_t size = tab->size;
228 if (entries != NULL)
229 {
230 size_t idx = new_hash % size;
231 size_t hash2 = 1 + new_hash % (size - 2);
232 while (1)
233 {
234 if (entries[idx].hashval == new_hash
235 && strcmp (entries[idx].name, undef_name) == 0)
236 {
237 if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)
238 {
239 /* We possibly have to initialize the central
240 copy from the copy addressed through the
241 relocation. */
242 result->s = sym;
243 result->m = map;
244 }
245 else
246 {
247 result->s = entries[idx].sym;
248 result->m = (struct link_map *) entries[idx].map;
249 }
250 __rtld_lock_unlock_recursive (tab->lock);
251 return;
252 }
253
254 if (entries[idx].name == NULL)
255 break;
256
257 idx += hash2;
258 if (idx >= size)
259 idx -= size;
260 }
261
262 if (size * 3 <= tab->n_elements * 4)
263 {
264 /* Expand the table. */
265#ifdef RTLD_CHECK_FOREIGN_CALL
266 /* This must not happen during runtime relocations. */
267 assert (!RTLD_CHECK_FOREIGN_CALL);
268#endif
269 size_t newsize = _dl_higher_prime_number (n: size + 1);
270 struct unique_sym *newentries
271 = calloc (nmemb: sizeof (struct unique_sym), size: newsize);
272 if (newentries == NULL)
273 {
274 nomem:
275 __rtld_lock_unlock_recursive (tab->lock);
276 _dl_fatal_printf (fmt: "out of memory\n");
277 }
278
279 for (idx = 0; idx < size; ++idx)
280 if (entries[idx].name != NULL)
281 enter_unique_sym (table: newentries, size: newsize, hash: entries[idx].hashval,
282 name: entries[idx].name, sym: entries[idx].sym,
283 map: entries[idx].map);
284
285 tab->free (entries);
286 tab->size = newsize;
287 size = newsize;
288 entries = tab->entries = newentries;
289 tab->free = __rtld_free;
290 }
291 }
292 else
293 {
294#ifdef RTLD_CHECK_FOREIGN_CALL
295 /* This must not happen during runtime relocations. */
296 assert (!RTLD_CHECK_FOREIGN_CALL);
297#endif
298
299#ifdef SHARED
300 /* If tab->entries is NULL, but tab->size is not, it means
301 this is the second, conflict finding, lookup for
302 LD_TRACE_PRELINKING in _dl_debug_bindings. Don't
303 allocate anything and don't enter anything into the
304 hash table. */
305 if (__glibc_unlikely (tab->size))
306 {
307 assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK);
308 goto success;
309 }
310#endif
311
312#define INITIAL_NUNIQUE_SYM_TABLE 31
313 size = INITIAL_NUNIQUE_SYM_TABLE;
314 entries = calloc (nmemb: sizeof (struct unique_sym), size: size);
315 if (entries == NULL)
316 goto nomem;
317
318 tab->entries = entries;
319 tab->size = size;
320 tab->free = __rtld_free;
321 }
322
323 if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)
324 enter_unique_sym (table: entries, size, hash: new_hash, name: strtab + sym->st_name, sym: ref,
325 map: undef_map);
326 else
327 {
328 enter_unique_sym (table: entries, size,
329 hash: new_hash, name: strtab + sym->st_name, sym, map);
330
331 if (map->l_type == lt_loaded && !is_nodelete (map, flags))
332 {
333 /* Make sure we don't unload this object by
334 setting the appropriate flag. */
335 if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS))
336 _dl_debug_printf (fmt: "\
337marking %s [%lu] as NODELETE due to unique symbol\n",
338 map->l_name, map->l_ns);
339 mark_nodelete (map, flags);
340 }
341 }
342 ++tab->n_elements;
343
344#ifdef SHARED
345 success:
346#endif
347 __rtld_lock_unlock_recursive (tab->lock);
348
349 result->s = sym;
350 result->m = (struct link_map *) map;
351}
352
353/* Inner part of the lookup functions. We return a value > 0 if we
354 found the symbol, the value 0 if nothing is found and < 0 if
355 something bad happened. */
356static int
357__attribute_noinline__
358do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
359 unsigned long int *old_hash, const ElfW(Sym) *ref,
360 struct sym_val *result, struct r_scope_elem *scope, size_t i,
361 const struct r_found_version *const version, int flags,
362 struct link_map *skip, int type_class, struct link_map *undef_map)
363{
364 size_t n = scope->r_nlist;
365 /* Make sure we read the value before proceeding. Otherwise we
366 might use r_list pointing to the initial scope and r_nlist being
367 the value after a resize. That is the only path in dl-open.c not
368 protected by GSCOPE. A read barrier here might be to expensive. */
369 __asm volatile ("" : "+r" (n), "+m" (scope->r_list));
370 struct link_map **list = scope->r_list;
371
372 do
373 {
374 const struct link_map *map = list[i]->l_real;
375
376 /* Here come the extra test needed for `_dl_lookup_symbol_skip'. */
377 if (map == skip)
378 continue;
379
380 /* Don't search the executable when resolving a copy reloc. */
381 if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable)
382 continue;
383
384 /* Do not look into objects which are going to be removed. */
385 if (map->l_removed)
386 continue;
387
388 /* Print some debugging info if wanted. */
389 if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS))
390 _dl_debug_printf (fmt: "symbol=%s; lookup in file=%s [%lu]\n",
391 undef_name, DSO_FILENAME (map->l_name),
392 map->l_ns);
393
394 /* If the hash table is empty there is nothing to do here. */
395 if (map->l_nbuckets == 0)
396 continue;
397
398 Elf_Symndx symidx;
399 int num_versions = 0;
400 const ElfW(Sym) *versioned_sym = NULL;
401
402 /* The tables for this map. */
403 const ElfW(Sym) *symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
404 const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
405
406 const ElfW(Sym) *sym;
407 const ElfW(Addr) *bitmask = map->l_gnu_bitmask;
408 if (__glibc_likely (bitmask != NULL))
409 {
410 ElfW(Addr) bitmask_word
411 = bitmask[(new_hash / __ELF_NATIVE_CLASS)
412 & map->l_gnu_bitmask_idxbits];
413
414 unsigned int hashbit1 = new_hash & (__ELF_NATIVE_CLASS - 1);
415 unsigned int hashbit2 = ((new_hash >> map->l_gnu_shift)
416 & (__ELF_NATIVE_CLASS - 1));
417
418 if (__glibc_unlikely ((bitmask_word >> hashbit1)
419 & (bitmask_word >> hashbit2) & 1))
420 {
421 Elf32_Word bucket = map->l_gnu_buckets[new_hash
422 % map->l_nbuckets];
423 if (bucket != 0)
424 {
425 const Elf32_Word *hasharr = &map->l_gnu_chain_zero[bucket];
426
427 do
428 if (((*hasharr ^ new_hash) >> 1) == 0)
429 {
430 symidx = ELF_MACHINE_HASH_SYMIDX (map, hasharr);
431 sym = check_match (undef_name, ref, version, flags,
432 type_class, sym: &symtab[symidx], symidx,
433 strtab, map, versioned_sym: &versioned_sym,
434 num_versions: &num_versions);
435 if (sym != NULL)
436 goto found_it;
437 }
438 while ((*hasharr++ & 1u) == 0);
439 }
440 }
441 /* No symbol found. */
442 symidx = SHN_UNDEF;
443 }
444 else
445 {
446 if (*old_hash == 0xffffffff)
447 *old_hash = _dl_elf_hash (name_arg: undef_name);
448
449 /* Use the old SysV-style hash table. Search the appropriate
450 hash bucket in this object's symbol table for a definition
451 for the same symbol name. */
452 for (symidx = map->l_buckets[*old_hash % map->l_nbuckets];
453 symidx != STN_UNDEF;
454 symidx = map->l_chain[symidx])
455 {
456 sym = check_match (undef_name, ref, version, flags,
457 type_class, sym: &symtab[symidx], symidx,
458 strtab, map, versioned_sym: &versioned_sym,
459 num_versions: &num_versions);
460 if (sym != NULL)
461 goto found_it;
462 }
463 }
464
465 /* If we have seen exactly one versioned symbol while we are
466 looking for an unversioned symbol and the version is not the
467 default version we still accept this symbol since there are
468 no possible ambiguities. */
469 sym = num_versions == 1 ? versioned_sym : NULL;
470
471 if (sym != NULL)
472 {
473 found_it:
474 /* When UNDEF_MAP is NULL, which indicates we are called from
475 do_lookup_x on relocation against protected data, we skip
476 the data definion in the executable from copy reloc. */
477 if (ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA
478 && undef_map == NULL
479 && map->l_type == lt_executable
480 && type_class == ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA)
481 {
482 const ElfW(Sym) *s;
483 unsigned int i;
484
485#if ! ELF_MACHINE_NO_RELA
486 if (map->l_info[DT_RELA] != NULL
487 && map->l_info[DT_RELASZ] != NULL
488 && map->l_info[DT_RELASZ]->d_un.d_val != 0)
489 {
490 const ElfW(Rela) *rela
491 = (const ElfW(Rela) *) D_PTR (map, l_info[DT_RELA]);
492 unsigned int rela_count
493 = map->l_info[DT_RELASZ]->d_un.d_val / sizeof (*rela);
494
495 for (i = 0; i < rela_count; i++, rela++)
496 if (elf_machine_type_class (ELFW(R_TYPE) (rela->r_info))
497 == ELF_RTYPE_CLASS_COPY)
498 {
499 s = &symtab[ELFW(R_SYM) (rela->r_info)];
500 if (!strcmp (strtab + s->st_name, undef_name))
501 goto skip;
502 }
503 }
504#endif
505#if ! ELF_MACHINE_NO_REL
506 if (map->l_info[DT_REL] != NULL
507 && map->l_info[DT_RELSZ] != NULL
508 && map->l_info[DT_RELSZ]->d_un.d_val != 0)
509 {
510 const ElfW(Rel) *rel
511 = (const ElfW(Rel) *) D_PTR (map, l_info[DT_REL]);
512 unsigned int rel_count
513 = map->l_info[DT_RELSZ]->d_un.d_val / sizeof (*rel);
514
515 for (i = 0; i < rel_count; i++, rel++)
516 if (elf_machine_type_class (ELFW(R_TYPE) (rel->r_info))
517 == ELF_RTYPE_CLASS_COPY)
518 {
519 s = &symtab[ELFW(R_SYM) (rel->r_info)];
520 if (!strcmp (strtab + s->st_name, undef_name))
521 goto skip;
522 }
523 }
524#endif
525 }
526
527 /* Hidden and internal symbols are local, ignore them. */
528 if (__glibc_unlikely (dl_symbol_visibility_binds_local_p (sym)))
529 goto skip;
530
531 if (ELFW(ST_VISIBILITY) (sym->st_other) == STV_PROTECTED)
532 _dl_check_protected_symbol (undef_name, undef_map, ref, map,
533 type_class);
534
535 switch (ELFW(ST_BIND) (sym->st_info))
536 {
537 case STB_WEAK:
538 /* Weak definition. Use this value if we don't find another. */
539 if (__glibc_unlikely (GLRO(dl_dynamic_weak)))
540 {
541 if (! result->s)
542 {
543 result->s = sym;
544 result->m = (struct link_map *) map;
545 }
546 break;
547 }
548 /* FALLTHROUGH */
549 case STB_GLOBAL:
550 /* Global definition. Just what we need. */
551 result->s = sym;
552 result->m = (struct link_map *) map;
553 return 1;
554
555 case STB_GNU_UNIQUE:;
556 do_lookup_unique (undef_name, new_hash, map: (struct link_map *) map,
557 result, type_class, sym, strtab, ref,
558 undef_map, flags);
559 return 1;
560
561 default:
562 /* Local symbols are ignored. */
563 break;
564 }
565 }
566
567skip:
568 ;
569 }
570 while (++i < n);
571
572 /* We have not found anything until now. */
573 return 0;
574}
575
576
577static uint_fast32_t
578dl_new_hash (const char *s)
579{
580 uint_fast32_t h = 5381;
581 for (unsigned char c = *s; c != '\0'; c = *++s)
582 h = h * 33 + c;
583 return h & 0xffffffff;
584}
585
586
587/* Add extra dependency on MAP to UNDEF_MAP. */
588static int
589add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
590{
591 struct link_map *runp;
592 unsigned int i;
593 int result = 0;
594
595 /* Avoid self-references and references to objects which cannot be
596 unloaded anyway. */
597 if (undef_map == map)
598 return 0;
599
600 /* Avoid references to objects which cannot be unloaded anyway. We
601 do not need to record dependencies if this object goes away
602 during dlopen failure, either. IFUNC resolvers with relocation
603 dependencies may pick an dependency which can be dlclose'd, but
604 such IFUNC resolvers are undefined anyway. */
605 assert (map->l_type == lt_loaded);
606 if (is_nodelete (map, flags))
607 return 0;
608
609 struct link_map_reldeps *l_reldeps
610 = atomic_forced_read (undef_map->l_reldeps);
611
612 /* Make sure l_reldeps is read before l_initfini. */
613 atomic_read_barrier ();
614
615 /* Determine whether UNDEF_MAP already has a reference to MAP. First
616 look in the normal dependencies. */
617 struct link_map **l_initfini = atomic_forced_read (undef_map->l_initfini);
618 if (l_initfini != NULL)
619 {
620 for (i = 0; l_initfini[i] != NULL; ++i)
621 if (l_initfini[i] == map)
622 return 0;
623 }
624
625 /* No normal dependency. See whether we already had to add it
626 to the special list of dynamic dependencies. */
627 unsigned int l_reldepsact = 0;
628 if (l_reldeps != NULL)
629 {
630 struct link_map **list = &l_reldeps->list[0];
631 l_reldepsact = l_reldeps->act;
632 for (i = 0; i < l_reldepsact; ++i)
633 if (list[i] == map)
634 return 0;
635 }
636
637 /* Save serial number of the target MAP. */
638 unsigned long long serial = map->l_serial;
639
640 /* Make sure nobody can unload the object while we are at it. */
641 if (__glibc_unlikely (flags & DL_LOOKUP_GSCOPE_LOCK))
642 {
643 /* We can't just call __rtld_lock_lock_recursive (GL(dl_load_lock))
644 here, that can result in ABBA deadlock. */
645 THREAD_GSCOPE_RESET_FLAG ();
646 __rtld_lock_lock_recursive (GL(dl_load_lock));
647 /* While MAP value won't change, after THREAD_GSCOPE_RESET_FLAG ()
648 it can e.g. point to unallocated memory. So avoid the optimizer
649 treating the above read from MAP->l_serial as ensurance it
650 can safely dereference it. */
651 map = atomic_forced_read (map);
652
653 /* From this point on it is unsafe to dereference MAP, until it
654 has been found in one of the lists. */
655
656 /* Redo the l_initfini check in case undef_map's l_initfini
657 changed in the mean time. */
658 if (undef_map->l_initfini != l_initfini
659 && undef_map->l_initfini != NULL)
660 {
661 l_initfini = undef_map->l_initfini;
662 for (i = 0; l_initfini[i] != NULL; ++i)
663 if (l_initfini[i] == map)
664 goto out_check;
665 }
666
667 /* Redo the l_reldeps check if undef_map's l_reldeps changed in
668 the mean time. */
669 if (undef_map->l_reldeps != NULL)
670 {
671 if (undef_map->l_reldeps != l_reldeps)
672 {
673 struct link_map **list = &undef_map->l_reldeps->list[0];
674 l_reldepsact = undef_map->l_reldeps->act;
675 for (i = 0; i < l_reldepsact; ++i)
676 if (list[i] == map)
677 goto out_check;
678 }
679 else if (undef_map->l_reldeps->act > l_reldepsact)
680 {
681 struct link_map **list
682 = &undef_map->l_reldeps->list[0];
683 i = l_reldepsact;
684 l_reldepsact = undef_map->l_reldeps->act;
685 for (; i < l_reldepsact; ++i)
686 if (list[i] == map)
687 goto out_check;
688 }
689 }
690 }
691 else
692 __rtld_lock_lock_recursive (GL(dl_load_lock));
693
694 /* The object is not yet in the dependency list. Before we add
695 it make sure just one more time the object we are about to
696 reference is still available. There is a brief period in
697 which the object could have been removed since we found the
698 definition. */
699 runp = GL(dl_ns)[undef_map->l_ns]._ns_loaded;
700 while (runp != NULL && runp != map)
701 runp = runp->l_next;
702
703 if (runp != NULL)
704 {
705 /* The object is still available. */
706
707 /* MAP could have been dlclosed, freed and then some other dlopened
708 library could have the same link_map pointer. */
709 if (map->l_serial != serial)
710 goto out_check;
711
712 /* Redo the NODELETE check, as when dl_load_lock wasn't held
713 yet this could have changed. */
714 if (is_nodelete (map, flags))
715 goto out;
716
717 /* If the object with the undefined reference cannot be removed ever
718 just make sure the same is true for the object which contains the
719 definition. */
720 if (undef_map->l_type != lt_loaded || is_nodelete (map, flags))
721 {
722 if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS)
723 && !is_nodelete (map, flags))
724 {
725 if (undef_map->l_name[0] == '\0')
726 _dl_debug_printf (fmt: "\
727marking %s [%lu] as NODELETE due to reference to main program\n",
728 map->l_name, map->l_ns);
729 else
730 _dl_debug_printf (fmt: "\
731marking %s [%lu] as NODELETE due to reference to %s [%lu]\n",
732 map->l_name, map->l_ns,
733 undef_map->l_name, undef_map->l_ns);
734 }
735 mark_nodelete (map, flags);
736 goto out;
737 }
738
739 /* Add the reference now. */
740 if (__glibc_unlikely (l_reldepsact >= undef_map->l_reldepsmax))
741 {
742 /* Allocate more memory for the dependency list. Since this
743 can never happen during the startup phase we can use
744 `realloc'. */
745 struct link_map_reldeps *newp;
746 unsigned int max
747 = undef_map->l_reldepsmax ? undef_map->l_reldepsmax * 2 : 10;
748
749#ifdef RTLD_PREPARE_FOREIGN_CALL
750 RTLD_PREPARE_FOREIGN_CALL;
751#endif
752
753 newp = malloc (size: sizeof (*newp) + max * sizeof (struct link_map *));
754 if (newp == NULL)
755 {
756 /* If we didn't manage to allocate memory for the list this is
757 no fatal problem. We simply make sure the referenced object
758 cannot be unloaded. This is semantically the correct
759 behavior. */
760 if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_BINDINGS)
761 && !is_nodelete (map, flags))
762 _dl_debug_printf (fmt: "\
763marking %s [%lu] as NODELETE due to memory allocation failure\n",
764 map->l_name, map->l_ns);
765 /* In case of non-lazy binding, we could actually report
766 the memory allocation error, but for now, we use the
767 conservative approximation as well. */
768 mark_nodelete (map, flags);
769 goto out;
770 }
771 else
772 {
773 if (l_reldepsact)
774 memcpy (&newp->list[0], &undef_map->l_reldeps->list[0],
775 l_reldepsact * sizeof (struct link_map *));
776 newp->list[l_reldepsact] = map;
777 newp->act = l_reldepsact + 1;
778 atomic_write_barrier ();
779 void *old = undef_map->l_reldeps;
780 undef_map->l_reldeps = newp;
781 undef_map->l_reldepsmax = max;
782 if (old)
783 _dl_scope_free (old);
784 }
785 }
786 else
787 {
788 undef_map->l_reldeps->list[l_reldepsact] = map;
789 atomic_write_barrier ();
790 undef_map->l_reldeps->act = l_reldepsact + 1;
791 }
792
793 /* Display information if we are debugging. */
794 if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
795 _dl_debug_printf (fmt: "\
796\nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n",
797 DSO_FILENAME (map->l_name),
798 map->l_ns,
799 DSO_FILENAME (undef_map->l_name),
800 undef_map->l_ns);
801 }
802 else
803 /* Whoa, that was bad luck. We have to search again. */
804 result = -1;
805
806 out:
807 /* Release the lock. */
808 __rtld_lock_unlock_recursive (GL(dl_load_lock));
809
810 if (__glibc_unlikely (flags & DL_LOOKUP_GSCOPE_LOCK))
811 THREAD_GSCOPE_SET_FLAG ();
812
813 return result;
814
815 out_check:
816 if (map->l_serial != serial)
817 result = -1;
818 goto out;
819}
820
821static void
822_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
823 const ElfW(Sym) **ref, struct sym_val *value,
824 const struct r_found_version *version, int type_class,
825 int protected);
826
827
828/* Search loaded objects' symbol tables for a definition of the symbol
829 UNDEF_NAME, perhaps with a requested version for the symbol.
830
831 We must never have calls to the audit functions inside this function
832 or in any function which gets called. If this would happen the audit
833 code might create a thread which can throw off all the scope locking. */
834lookup_t
835_dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
836 const ElfW(Sym) **ref,
837 struct r_scope_elem *symbol_scope[],
838 const struct r_found_version *version,
839 int type_class, int flags, struct link_map *skip_map)
840{
841 const uint_fast32_t new_hash = dl_new_hash (s: undef_name);
842 unsigned long int old_hash = 0xffffffff;
843 struct sym_val current_value = { NULL, NULL };
844 struct r_scope_elem **scope = symbol_scope;
845
846 bump_num_relocations ();
847
848 /* DL_LOOKUP_RETURN_NEWEST does not make sense for versioned
849 lookups. */
850 assert (version == NULL || !(flags & DL_LOOKUP_RETURN_NEWEST));
851
852 size_t i = 0;
853 if (__glibc_unlikely (skip_map != NULL))
854 /* Search the relevant loaded objects for a definition. */
855 while ((*scope)->r_list[i] != skip_map)
856 ++i;
857
858 /* Search the relevant loaded objects for a definition. */
859 for (size_t start = i; *scope != NULL; start = 0, ++scope)
860 if (do_lookup_x (undef_name, new_hash, old_hash: &old_hash, ref: *ref,
861 result: &current_value, scope: *scope, i: start, version, flags,
862 skip: skip_map, type_class, undef_map) != 0)
863 break;
864
865 if (__glibc_unlikely (current_value.s == NULL))
866 {
867 if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
868 && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED))
869 {
870 /* We could find no value for a strong reference. */
871 const char *reference_name = undef_map ? undef_map->l_name : "";
872 const char *versionstr = version ? ", version " : "";
873 const char *versionname = (version && version->name
874 ? version->name : "");
875 struct dl_exception exception;
876 /* XXX We cannot translate the message. */
877 _dl_exception_create_format
878 (&exception, DSO_FILENAME (reference_name),
879 fmt: "undefined symbol: %s%s%s",
880 undef_name, versionstr, versionname);
881 _dl_signal_cexception (errcode: 0, exception: &exception, N_("symbol lookup error"));
882 _dl_exception_free (&exception);
883 }
884 *ref = NULL;
885 return 0;
886 }
887
888 int protected = (*ref
889 && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED);
890 if (__glibc_unlikely (protected != 0))
891 {
892 /* It is very tricky. We need to figure out what value to
893 return for the protected symbol. */
894 if (type_class == ELF_RTYPE_CLASS_PLT)
895 {
896 if (current_value.s != NULL && current_value.m != undef_map)
897 {
898 current_value.s = *ref;
899 current_value.m = undef_map;
900 }
901 }
902 else
903 {
904 struct sym_val protected_value = { NULL, NULL };
905
906 for (scope = symbol_scope; *scope != NULL; i = 0, ++scope)
907 if (do_lookup_x (undef_name, new_hash, old_hash: &old_hash, ref: *ref,
908 result: &protected_value, scope: *scope, i, version, flags,
909 skip: skip_map,
910 type_class: (ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA
911 && ELFW(ST_TYPE) ((*ref)->st_info) == STT_OBJECT
912 && type_class == ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA)
913 ? ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA
914 : ELF_RTYPE_CLASS_PLT, NULL) != 0)
915 break;
916
917 if (protected_value.s != NULL && protected_value.m != undef_map)
918 {
919 current_value.s = *ref;
920 current_value.m = undef_map;
921 }
922 }
923 }
924
925 /* We have to check whether this would bind UNDEF_MAP to an object
926 in the global scope which was dynamically loaded. In this case
927 we have to prevent the latter from being unloaded unless the
928 UNDEF_MAP object is also unloaded. */
929 if (__glibc_unlikely (current_value.m->l_type == lt_loaded)
930 /* Don't do this for explicit lookups as opposed to implicit
931 runtime lookups. */
932 && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
933 /* Add UNDEF_MAP to the dependencies. */
934 && add_dependency (undef_map, map: current_value.m, flags) < 0)
935 /* Something went wrong. Perhaps the object we tried to reference
936 was just removed. Try finding another definition. */
937 return _dl_lookup_symbol_x (undef_name, undef_map, ref,
938 symbol_scope: (flags & DL_LOOKUP_GSCOPE_LOCK)
939 ? undef_map->l_scope : symbol_scope,
940 version, type_class, flags, skip_map);
941
942 /* The object is used. */
943 if (__glibc_unlikely (current_value.m->l_used == 0))
944 current_value.m->l_used = 1;
945
946 if (__glibc_unlikely (GLRO(dl_debug_mask)
947 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK)))
948 _dl_debug_bindings (undef_name, undef_map, ref,
949 value: &current_value, version, type_class, protected);
950
951 *ref = current_value.s;
952 return LOOKUP_VALUE (current_value.m);
953}
954
955
956static void
957_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
958 const ElfW(Sym) **ref, struct sym_val *value,
959 const struct r_found_version *version, int type_class,
960 int protected)
961{
962 const char *reference_name = undef_map->l_name;
963
964 if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
965 {
966 _dl_debug_printf (fmt: "binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
967 DSO_FILENAME (reference_name),
968 undef_map->l_ns,
969 DSO_FILENAME (value->m->l_name),
970 value->m->l_ns,
971 protected ? "protected" : "normal", undef_name);
972 if (version)
973 _dl_debug_printf_c (fmt: " [%s]\n", version->name);
974 else
975 _dl_debug_printf_c (fmt: "\n");
976 }
977#ifdef SHARED
978 if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
979 {
980/* ELF_RTYPE_CLASS_XXX must match RTYPE_CLASS_XXX used by prelink with
981 LD_TRACE_PRELINKING. */
982#define RTYPE_CLASS_VALID 8
983#define RTYPE_CLASS_PLT (8|1)
984#define RTYPE_CLASS_COPY (8|2)
985#define RTYPE_CLASS_TLS (8|4)
986#if ELF_RTYPE_CLASS_PLT != 0 && ELF_RTYPE_CLASS_PLT != 1
987# error ELF_RTYPE_CLASS_PLT must be 0 or 1!
988#endif
989#if ELF_RTYPE_CLASS_COPY != 0 && ELF_RTYPE_CLASS_COPY != 2
990# error ELF_RTYPE_CLASS_COPY must be 0 or 2!
991#endif
992 int conflict = 0;
993 struct sym_val val = { NULL, NULL };
994
995 if ((GLRO(dl_trace_prelink_map) == NULL
996 || GLRO(dl_trace_prelink_map) == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
997 && undef_map != GL(dl_ns)[LM_ID_BASE]._ns_loaded)
998 {
999 const uint_fast32_t new_hash = dl_new_hash (undef_name);
1000 unsigned long int old_hash = 0xffffffff;
1001 struct unique_sym *saved_entries
1002 = GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries;
1003
1004 GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = NULL;
1005 do_lookup_x (undef_name, new_hash, &old_hash, *ref, &val,
1006 undef_map->l_local_scope[0], 0, version, 0, NULL,
1007 type_class, undef_map);
1008 if (val.s != value->s || val.m != value->m)
1009 conflict = 1;
1010 else if (__glibc_unlikely (undef_map->l_symbolic_in_local_scope)
1011 && val.s
1012 && __glibc_unlikely (ELFW(ST_BIND) (val.s->st_info)
1013 == STB_GNU_UNIQUE))
1014 {
1015 /* If it is STB_GNU_UNIQUE and undef_map's l_local_scope
1016 contains any DT_SYMBOLIC libraries, unfortunately there
1017 can be conflicts even if the above is equal. As symbol
1018 resolution goes from the last library to the first and
1019 if a STB_GNU_UNIQUE symbol is found in some late DT_SYMBOLIC
1020 library, it would be the one that is looked up. */
1021 struct sym_val val2 = { NULL, NULL };
1022 size_t n;
1023 struct r_scope_elem *scope = undef_map->l_local_scope[0];
1024
1025 for (n = 0; n < scope->r_nlist; n++)
1026 if (scope->r_list[n] == val.m)
1027 break;
1028
1029 for (n++; n < scope->r_nlist; n++)
1030 if (scope->r_list[n]->l_info[DT_SYMBOLIC] != NULL
1031 && do_lookup_x (undef_name, new_hash, &old_hash, *ref,
1032 &val2,
1033 &scope->r_list[n]->l_symbolic_searchlist,
1034 0, version, 0, NULL, type_class,
1035 undef_map) > 0)
1036 {
1037 conflict = 1;
1038 val = val2;
1039 break;
1040 }
1041 }
1042 GL(dl_ns)[LM_ID_BASE]._ns_unique_sym_table.entries = saved_entries;
1043 }
1044
1045 if (value->s)
1046 {
1047 /* Keep only ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY
1048 bits since since prelink only uses them. */
1049 type_class &= ELF_RTYPE_CLASS_PLT | ELF_RTYPE_CLASS_COPY;
1050 if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
1051 == STT_TLS))
1052 /* Clear the RTYPE_CLASS_VALID bit in RTYPE_CLASS_TLS. */
1053 type_class = RTYPE_CLASS_TLS & ~RTYPE_CLASS_VALID;
1054 else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
1055 == STT_GNU_IFUNC))
1056 /* Set the RTYPE_CLASS_VALID bit. */
1057 type_class |= RTYPE_CLASS_VALID;
1058 }
1059
1060 if (conflict
1061 || GLRO(dl_trace_prelink_map) == undef_map
1062 || GLRO(dl_trace_prelink_map) == NULL
1063 || type_class >= 4)
1064 {
1065 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
1066 conflict ? "conflict" : "lookup",
1067 (int) sizeof (ElfW(Addr)) * 2,
1068 (size_t) undef_map->l_map_start,
1069 (int) sizeof (ElfW(Addr)) * 2,
1070 (size_t) (((ElfW(Addr)) *ref) - undef_map->l_map_start),
1071 (int) sizeof (ElfW(Addr)) * 2,
1072 (size_t) (value->s ? value->m->l_map_start : 0),
1073 (int) sizeof (ElfW(Addr)) * 2,
1074 (size_t) (value->s ? value->s->st_value : 0));
1075
1076 if (conflict)
1077 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
1078 (int) sizeof (ElfW(Addr)) * 2,
1079 (size_t) (val.s ? val.m->l_map_start : 0),
1080 (int) sizeof (ElfW(Addr)) * 2,
1081 (size_t) (val.s ? val.s->st_value : 0));
1082
1083 _dl_printf ("/%x %s\n", type_class, undef_name);
1084 }
1085 }
1086#endif
1087}
1088

source code of glibc/elf/dl-lookup.c