Update.
[glibc.git] / elf / dl-lookup.c
blob4f3285fee5b4d8d62645dab1835eff0ab225fafe
1 /* Look up a symbol in the loaded objects.
2 Copyright (C) 1995,96,97,98,99,2000,2001,2002 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 <bits/libc-lock.h>
30 #include <assert.h>
32 #define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
34 /* We need this string more than once. */
35 static const char undefined_msg[] = "undefined symbol: ";
38 struct sym_val
40 const ElfW(Sym) *s;
41 struct link_map *m;
45 #define make_string(string, rest...) \
46 ({ \
47 const char *all[] = { string, ## rest }; \
48 size_t len, cnt; \
49 char *result, *cp; \
51 len = 1; \
52 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
53 len += strlen (all[cnt]); \
55 cp = result = alloca (len); \
56 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
57 cp = __stpcpy (cp, all[cnt]); \
59 result; \
62 /* Statistics function. */
63 #ifdef SHARED
64 # define bump_num_relocations() ++GL(dl_num_relocations)
65 #else
66 # define bump_num_relocations() ((void) 0)
67 #endif
71 /* We have two different situations when looking up a simple: with or
72 without versioning. gcc is not able to optimize a single function
73 definition serving for both purposes so we define two functions. */
74 #define VERSIONED 0
75 #include "do-lookup.h"
77 #define VERSIONED 1
78 #include "do-lookup.h"
81 /* Add extra dependency on MAP to UNDEF_MAP. */
82 static int
83 internal_function
84 add_dependency (struct link_map *undef_map, struct link_map *map)
86 struct link_map **list;
87 struct link_map *runp;
88 unsigned int act;
89 unsigned int i;
90 int result = 0;
92 /* Avoid self-references. */
93 if (undef_map == map)
94 return 0;
96 /* Make sure nobody can unload the object while we are at it. */
97 __libc_lock_lock_recursive (GL(dl_load_lock));
99 /* Determine whether UNDEF_MAP already has a reference to MAP. First
100 look in the normal dependencies. */
101 if (undef_map->l_searchlist.r_list != NULL)
103 list = undef_map->l_initfini;
105 for (i = 0; list[i] != NULL; ++i)
106 if (list[i] == map)
107 goto out;
110 /* No normal dependency. See whether we already had to add it
111 to the special list of dynamic dependencies. */
112 list = undef_map->l_reldeps;
113 act = undef_map->l_reldepsact;
115 for (i = 0; i < act; ++i)
116 if (list[i] == map)
117 goto out;
119 /* The object is not yet in the dependency list. Before we add
120 it make sure just one more time the object we are about to
121 reference is still available. There is a brief period in
122 which the object could have been removed since we found the
123 definition. */
124 runp = GL(dl_loaded);
125 while (runp != NULL && runp != map)
126 runp = runp->l_next;
128 if (runp != NULL)
130 /* The object is still available. Add the reference now. */
131 if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
133 /* Allocate more memory for the dependency list. Since this
134 can never happen during the startup phase we can use
135 `realloc'. */
136 void *newp;
138 undef_map->l_reldepsmax += 5;
139 newp = realloc (undef_map->l_reldeps,
140 undef_map->l_reldepsmax
141 * sizeof (struct link_map *));
143 if (__builtin_expect (newp != NULL, 1))
144 undef_map->l_reldeps = (struct link_map **) newp;
145 else
146 /* Correct the addition. */
147 undef_map->l_reldepsmax -= 5;
150 /* If we didn't manage to allocate memory for the list this is
151 no fatal mistake. We simply increment the use counter of the
152 referenced object and don't record the dependencies. This
153 means this increment can never be reverted and the object
154 will never be unloaded. This is semantically the correct
155 behaviour. */
156 if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
157 undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
159 if (map->l_searchlist.r_list != NULL)
160 /* And increment the counter in the referenced object. */
161 ++map->l_opencount;
162 else
163 /* We have to bump the counts for all dependencies since so far
164 this object was only a normal or transitive dependency.
165 Now it might be closed with _dl_close() directly. */
166 for (list = map->l_initfini; *list != NULL; ++list)
167 ++(*list)->l_opencount;
169 /* Display information if we are debugging. */
170 if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0))
171 _dl_debug_printf ("\
172 \nfile=%s; needed by %s (relocation dependency)\n\n",
173 map->l_name[0] ? map->l_name : _dl_argv[0],
174 undef_map->l_name[0]
175 ? undef_map->l_name : _dl_argv[0]);
177 else
178 /* Whoa, that was bad luck. We have to search again. */
179 result = -1;
181 out:
182 /* Release the lock. */
183 __libc_lock_unlock_recursive (GL(dl_load_lock));
185 return result;
188 static int
189 internal_function
190 _dl_do_lookup (const char *undef_name, unsigned long int hash,
191 const ElfW(Sym) *ref, struct sym_val *result,
192 struct r_scope_elem *scope, size_t i,
193 struct link_map *skip, int type_class);
194 static int
195 internal_function
196 _dl_do_lookup_versioned (const char *undef_name, unsigned long int hash,
197 const ElfW(Sym) *ref, struct sym_val *result,
198 struct r_scope_elem *scope, size_t i,
199 const struct r_found_version *const version,
200 struct link_map *skip, int type_class);
202 static void
203 internal_function
204 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
205 const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
206 struct sym_val *value, const struct r_found_version *version,
207 int type_class, int protected);
209 /* Search loaded objects' symbol tables for a definition of the symbol
210 UNDEF_NAME. */
212 lookup_t
213 internal_function
214 _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
215 const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
216 int type_class, int explicit)
218 const unsigned long int hash = _dl_elf_hash (undef_name);
219 struct sym_val current_value = { NULL, NULL };
220 struct r_scope_elem **scope;
221 int protected;
223 bump_num_relocations ();
225 /* Search the relevant loaded objects for a definition. */
226 for (scope = symbol_scope; *scope; ++scope)
227 if (do_lookup (undef_name, hash, *ref, &current_value, *scope, 0, NULL,
228 type_class))
230 /* We have to check whether this would bind UNDEF_MAP to an object
231 in the global scope which was dynamically loaded. In this case
232 we have to prevent the latter from being unloaded unless the
233 UNDEF_MAP object is also unloaded. */
234 if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
235 /* Don't do this for explicit lookups as opposed to implicit
236 runtime lookups. */
237 && ! explicit
238 /* Add UNDEF_MAP to the dependencies. */
239 && add_dependency (undef_map, current_value.m) < 0)
240 /* Something went wrong. Perhaps the object we tried to reference
241 was just removed. Try finding another definition. */
242 return _dl_lookup_symbol (undef_name, undef_map, ref, symbol_scope,
243 type_class, 0);
245 break;
248 if (__builtin_expect (current_value.s == NULL, 0))
250 const char *reference_name = undef_map ? undef_map->l_name : NULL;
252 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
253 /* We could find no value for a strong reference. */
254 /* XXX We cannot translate the messages. */
255 _dl_signal_cerror (0, (reference_name[0]
256 ? reference_name
257 : (_dl_argv[0] ?: "<main program>")),
258 N_("relocation error"),
259 make_string (undefined_msg, undef_name));
260 *ref = NULL;
261 return 0;
264 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
265 if (__builtin_expect (protected != 0, 0))
267 /* It is very tricky. We need to figure out what value to
268 return for the protected symbol */
269 struct sym_val protected_value = { NULL, NULL };
271 for (scope = symbol_scope; *scope; ++scope)
272 if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
273 0, NULL, ELF_RTYPE_CLASS_PLT))
274 break;
276 if (protected_value.s != NULL && protected_value.m != undef_map)
278 current_value.s = *ref;
279 current_value.m = undef_map;
283 if (__builtin_expect (GL(dl_debug_mask)
284 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
285 _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
286 &current_value, NULL, type_class, protected);
288 *ref = current_value.s;
289 return LOOKUP_VALUE (current_value.m);
293 /* This function is nearly the same as `_dl_lookup_symbol' but it
294 skips in the first list all objects until SKIP_MAP is found. I.e.,
295 it only considers objects which were loaded after the described
296 object. If there are more search lists the object described by
297 SKIP_MAP is only skipped. */
298 lookup_t
299 internal_function
300 _dl_lookup_symbol_skip (const char *undef_name,
301 struct link_map *undef_map, const ElfW(Sym) **ref,
302 struct r_scope_elem *symbol_scope[],
303 struct link_map *skip_map)
305 const unsigned long int hash = _dl_elf_hash (undef_name);
306 struct sym_val current_value = { NULL, NULL };
307 struct r_scope_elem **scope;
308 size_t i;
309 int protected;
311 bump_num_relocations ();
313 /* Search the relevant loaded objects for a definition. */
314 scope = symbol_scope;
315 for (i = 0; (*scope)->r_list[i] != skip_map; ++i)
316 assert (i < (*scope)->r_nlist);
318 if (! _dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, i,
319 skip_map, 0))
320 while (*++scope)
321 if (_dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, 0,
322 skip_map, 0))
323 break;
325 if (__builtin_expect (current_value.s == NULL, 0))
327 *ref = NULL;
328 return 0;
331 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
333 if (__builtin_expect (protected != 0, 0))
335 /* It is very tricky. We need to figure out what value to
336 return for the protected symbol. */
337 struct sym_val protected_value = { NULL, NULL };
339 if (i >= (*scope)->r_nlist
340 || !_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
341 i, skip_map, ELF_RTYPE_CLASS_PLT))
342 while (*++scope)
343 if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
344 0, skip_map, ELF_RTYPE_CLASS_PLT))
345 break;
347 if (protected_value.s != NULL && protected_value.m != undef_map)
349 current_value.s = *ref;
350 current_value.m = undef_map;
354 if (__builtin_expect (GL(dl_debug_mask)
355 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
356 _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
357 &current_value, NULL, 0, protected);
359 *ref = current_value.s;
360 return LOOKUP_VALUE (current_value.m);
364 /* This function works like _dl_lookup_symbol but it takes an
365 additional arguement with the version number of the requested
366 symbol.
368 XXX We'll see whether we need this separate function. */
369 lookup_t
370 internal_function
371 _dl_lookup_versioned_symbol (const char *undef_name,
372 struct link_map *undef_map, const ElfW(Sym) **ref,
373 struct r_scope_elem *symbol_scope[],
374 const struct r_found_version *version,
375 int type_class, int explicit)
377 const unsigned long int hash = _dl_elf_hash (undef_name);
378 struct sym_val current_value = { NULL, NULL };
379 struct r_scope_elem **scope;
380 int protected;
382 bump_num_relocations ();
384 /* Search the relevant loaded objects for a definition. */
385 for (scope = symbol_scope; *scope; ++scope)
387 int res = do_lookup_versioned (undef_name, hash, *ref, &current_value,
388 *scope, 0, version, NULL, type_class);
389 if (res > 0)
391 /* We have to check whether this would bind UNDEF_MAP to an object
392 in the global scope which was dynamically loaded. In this case
393 we have to prevent the latter from being unloaded unless the
394 UNDEF_MAP object is also unloaded. */
395 if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
396 /* Don't do this for explicit lookups as opposed to implicit
397 runtime lookups. */
398 && ! explicit
399 /* Add UNDEF_MAP to the dependencies. */
400 && add_dependency (undef_map, current_value.m) < 0)
401 /* Something went wrong. Perhaps the object we tried to reference
402 was just removed. Try finding another definition. */
403 return _dl_lookup_versioned_symbol (undef_name, undef_map, ref,
404 symbol_scope, version,
405 type_class, 0);
407 break;
410 if (__builtin_expect (res, 0) < 0)
412 /* Oh, oh. The file named in the relocation entry does not
413 contain the needed symbol. */
414 const char *reference_name = undef_map ? undef_map->l_name : NULL;
416 /* XXX We cannot translate the message. */
417 _dl_signal_cerror (0, (reference_name[0]
418 ? reference_name
419 : (_dl_argv[0] ?: "<main program>")),
420 N_("relocation error"),
421 make_string ("symbol ", undef_name, ", version ",
422 version->name,
423 " not defined in file ",
424 version->filename,
425 " with link time reference",
426 res == -2
427 ? " (no version symbols)" : ""));
428 *ref = NULL;
429 return 0;
433 if (__builtin_expect (current_value.s == NULL, 0))
435 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
437 /* We could find no value for a strong reference. */
438 const char *reference_name = undef_map ? undef_map->l_name : NULL;
440 /* XXX We cannot translate the message. */
441 _dl_signal_cerror (0, (reference_name[0]
442 ? reference_name
443 : (_dl_argv[0] ?: "<main program>")), NULL,
444 make_string (undefined_msg, undef_name,
445 ", version ",
446 version->name ?: NULL));
448 *ref = NULL;
449 return 0;
452 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
454 if (__builtin_expect (protected != 0, 0))
456 /* It is very tricky. We need to figure out what value to
457 return for the protected symbol */
458 struct sym_val protected_value = { NULL, NULL };
460 for (scope = symbol_scope; *scope; ++scope)
461 if (_dl_do_lookup_versioned (undef_name, hash, *ref, &protected_value,
462 *scope, 0, version, NULL,
463 ELF_RTYPE_CLASS_PLT))
464 break;
466 if (protected_value.s != NULL && protected_value.m != undef_map)
468 current_value.s = *ref;
469 current_value.m = undef_map;
473 if (__builtin_expect (GL(dl_debug_mask)
474 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
475 _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
476 &current_value, version, type_class, protected);
478 *ref = current_value.s;
479 return LOOKUP_VALUE (current_value.m);
483 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
484 with the version we are looking for. */
485 lookup_t
486 internal_function
487 _dl_lookup_versioned_symbol_skip (const char *undef_name,
488 struct link_map *undef_map,
489 const ElfW(Sym) **ref,
490 struct r_scope_elem *symbol_scope[],
491 const struct r_found_version *version,
492 struct link_map *skip_map)
494 const char *reference_name = undef_map->l_name;
495 const unsigned long int hash = _dl_elf_hash (undef_name);
496 struct sym_val current_value = { NULL, NULL };
497 struct r_scope_elem **scope;
498 size_t i;
499 int protected;
501 bump_num_relocations ();
503 /* Search the relevant loaded objects for a definition. */
504 scope = symbol_scope;
505 for (i = 0; (*scope)->r_list[i] != skip_map; ++i)
506 assert (i < (*scope)->r_nlist);
508 if (! _dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
509 *scope, i, version, skip_map, 0))
510 while (*++scope)
511 if (_dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
512 *scope, 0, version, skip_map, 0))
513 break;
515 if (__builtin_expect (current_value.s == NULL, 0))
517 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
519 /* We could find no value for a strong reference. */
520 const size_t len = strlen (undef_name);
521 char buf[sizeof undefined_msg + len];
522 __mempcpy (__mempcpy (buf, undefined_msg, sizeof undefined_msg - 1),
523 undef_name, len + 1);
524 /* XXX We cannot translate the messages. */
525 _dl_signal_cerror (0, (reference_name[0]
526 ? reference_name
527 : (_dl_argv[0] ?: "<main program>")),
528 NULL, buf);
530 *ref = NULL;
531 return 0;
534 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
536 if (__builtin_expect (protected != 0, 0))
538 /* It is very tricky. We need to figure out what value to
539 return for the protected symbol */
540 struct sym_val protected_value = { NULL, NULL };
542 if (i >= (*scope)->r_nlist
543 || !_dl_do_lookup_versioned (undef_name, hash, *ref,
544 &protected_value, *scope, i, version,
545 skip_map, ELF_RTYPE_CLASS_PLT))
546 while (*++scope)
547 if (_dl_do_lookup_versioned (undef_name, hash, *ref,
548 &protected_value, *scope, 0, version,
549 skip_map, ELF_RTYPE_CLASS_PLT))
550 break;
552 if (protected_value.s != NULL && protected_value.m != undef_map)
554 current_value.s = *ref;
555 current_value.m = undef_map;
559 if (__builtin_expect (GL(dl_debug_mask)
560 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
561 _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
562 &current_value, version, 0, protected);
564 *ref = current_value.s;
565 return LOOKUP_VALUE (current_value.m);
569 /* Cache the location of MAP's hash table. */
571 void
572 internal_function
573 _dl_setup_hash (struct link_map *map)
575 Elf_Symndx *hash;
576 Elf_Symndx nchain;
578 if (!map->l_info[DT_HASH])
579 return;
580 hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);
582 map->l_nbuckets = *hash++;
583 nchain = *hash++;
584 map->l_buckets = hash;
585 hash += map->l_nbuckets;
586 map->l_chain = hash;
589 static void
590 internal_function
591 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
592 const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
593 struct sym_val *value, const struct r_found_version *version,
594 int type_class, int protected)
596 const char *reference_name = undef_map->l_name;
598 if (GL(dl_debug_mask) & DL_DEBUG_BINDINGS)
600 _dl_debug_printf ("binding file %s to %s: %s symbol `%s'",
601 (reference_name[0]
602 ? reference_name : (_dl_argv[0] ?: "<main program>")),
603 value->m->l_name[0] ? value->m->l_name : _dl_argv[0],
604 protected ? "protected" : "normal",
605 undef_name);
606 if (version)
607 _dl_debug_printf_c (" [%s]\n", version->name);
608 else
609 _dl_debug_printf_c ("\n");
611 #ifdef SHARED
612 if (GL(dl_debug_mask) & DL_DEBUG_PRELINK)
614 int conflict = 0;
615 struct sym_val val = { NULL, NULL };
617 if ((GL(dl_trace_prelink_map) == NULL
618 || GL(dl_trace_prelink_map) == GL(dl_loaded))
619 && undef_map != GL(dl_loaded))
621 const unsigned long int hash = _dl_elf_hash (undef_name);
623 if (version == 0)
624 _dl_do_lookup (undef_name, hash, *ref, &val,
625 undef_map->l_local_scope[0], 0, NULL, type_class);
626 else
627 _dl_do_lookup_versioned (undef_name, hash, *ref, &val,
628 undef_map->l_local_scope[0], 0, version,
629 NULL, type_class);
631 if (val.s != value->s || val.m != value->m)
632 conflict = 1;
635 if (conflict
636 || GL(dl_trace_prelink_map) == undef_map
637 || GL(dl_trace_prelink_map) == NULL)
639 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
640 conflict ? "conflict" : "lookup",
641 (int) sizeof (ElfW(Addr)) * 2, undef_map->l_map_start,
642 (int) sizeof (ElfW(Addr)) * 2,
643 ((ElfW(Addr)) *ref) - undef_map->l_map_start,
644 (int) sizeof (ElfW(Addr)) * 2,
645 (ElfW(Addr)) (value->s ? value->m->l_map_start : 0),
646 (int) sizeof (ElfW(Addr)) * 2,
647 (ElfW(Addr)) (value->s ? value->s->st_value : 0));
649 if (conflict)
650 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
651 (int) sizeof (ElfW(Addr)) * 2,
652 (ElfW(Addr)) (val.s ? val.m->l_map_start : 0),
653 (int) sizeof (ElfW(Addr)) * 2,
654 (ElfW(Addr)) (val.s ? val.s->st_value : 0));
656 _dl_printf ("/%x %s\n", type_class, undef_name);
659 #endif
662 /* These are here so that we only inline do_lookup{,_versioned} in the common
663 case, not everywhere. */
664 static int __attribute_noinline__
665 internal_function
666 _dl_do_lookup (const char *undef_name, unsigned long int hash,
667 const ElfW(Sym) *ref, struct sym_val *result,
668 struct r_scope_elem *scope, size_t i,
669 struct link_map *skip, int type_class)
671 return do_lookup (undef_name, hash, ref, result, scope, i, skip,
672 type_class);
675 static int __attribute_noinline__
676 internal_function
677 _dl_do_lookup_versioned (const char *undef_name, unsigned long int hash,
678 const ElfW(Sym) *ref, struct sym_val *result,
679 struct r_scope_elem *scope, size_t i,
680 const struct r_found_version *const version,
681 struct link_map *skip, int type_class)
683 return do_lookup_versioned (undef_name, hash, ref, result, scope, i,
684 version, skip, type_class);