Include sys/param.h. (RESOLVE_CONFLICT_FIND_MAP): Cast r_offset to ElfW(Addr).
[glibc.git] / elf / dl-lookup.c
blobae3f0b1e342f2924b6ad4ad3d283b010ed5df06e
1 /* Look up a symbol in the loaded objects.
2 Copyright (C) 1995,96,97,98,99,2000,2001 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 unsigned long int _dl_num_relocations;
66 /* We have two different situations when looking up a simple: with or
67 without versioning. gcc is not able to optimize a single function
68 definition serving for both purposes so we define two functions. */
69 #define VERSIONED 0
70 #include "do-lookup.h"
72 #define VERSIONED 1
73 #include "do-lookup.h"
76 /* Add extra dependency on MAP to UNDEF_MAP. */
77 static int
78 internal_function
79 add_dependency (struct link_map *undef_map, struct link_map *map)
81 struct link_map **list;
82 struct link_map *runp;
83 unsigned int act;
84 unsigned int i;
85 int result = 0;
87 /* Avoid self-references. */
88 if (undef_map == map)
89 return 0;
91 /* Make sure nobody can unload the object while we are at it. */
92 __libc_lock_lock_recursive (_dl_load_lock);
94 /* Determine whether UNDEF_MAP already has a reference to MAP. First
95 look in the normal dependencies. */
96 if (undef_map->l_searchlist.r_list != NULL)
98 list = undef_map->l_initfini;
100 for (i = 0; list[i] != NULL; ++i)
101 if (list[i] == map)
102 goto out;
105 /* No normal dependency. See whether we already had to add it
106 to the special list of dynamic dependencies. */
107 list = undef_map->l_reldeps;
108 act = undef_map->l_reldepsact;
110 for (i = 0; i < act; ++i)
111 if (list[i] == map)
112 goto out;
114 /* The object is not yet in the dependency list. Before we add
115 it make sure just one more time the object we are about to
116 reference is still available. There is a brief period in
117 which the object could have been removed since we found the
118 definition. */
119 runp = _dl_loaded;
120 while (runp != NULL && runp != map)
121 runp = runp->l_next;
123 if (runp != NULL)
125 /* The object is still available. Add the reference now. */
126 if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
128 /* Allocate more memory for the dependency list. Since this
129 can never happen during the startup phase we can use
130 `realloc'. */
131 void *newp;
133 undef_map->l_reldepsmax += 5;
134 newp = realloc (undef_map->l_reldeps,
135 undef_map->l_reldepsmax
136 * sizeof (struct link_map *));
138 if (__builtin_expect (newp != NULL, 1))
139 undef_map->l_reldeps = (struct link_map **) newp;
140 else
141 /* Correct the addition. */
142 undef_map->l_reldepsmax -= 5;
145 /* If we didn't manage to allocate memory for the list this is
146 no fatal mistake. We simply increment the use counter of the
147 referenced object and don't record the dependencies. This
148 means this increment can never be reverted and the object
149 will never be unloaded. This is semantically the correct
150 behaviour. */
151 if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
152 undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
154 if (map->l_searchlist.r_list != NULL)
155 /* And increment the counter in the referenced object. */
156 ++map->l_opencount;
157 else
158 /* We have to bump the counts for all dependencies since so far
159 this object was only a normal or transitive dependency.
160 Now it might be closed with _dl_close() directly. */
161 for (list = map->l_initfini; *list != NULL; ++list)
162 ++(*list)->l_opencount;
164 /* Display information if we are debugging. */
165 if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0))
166 _dl_debug_printf ("\
167 \nfile=%s; needed by %s (relocation dependency)\n\n",
168 map->l_name[0] ? map->l_name : _dl_argv[0],
169 undef_map->l_name[0]
170 ? undef_map->l_name : _dl_argv[0]);
172 else
173 /* Whoa, that was bad luck. We have to search again. */
174 result = -1;
176 out:
177 /* Release the lock. */
178 __libc_lock_unlock_recursive (_dl_load_lock);
180 return result;
183 static int
184 internal_function
185 _dl_do_lookup (const char *undef_name, unsigned long int hash,
186 const ElfW(Sym) *ref, struct sym_val *result,
187 struct r_scope_elem *scope, size_t i,
188 struct link_map *skip, int type_class);
189 static int
190 internal_function
191 _dl_do_lookup_versioned (const char *undef_name, unsigned long int hash,
192 const ElfW(Sym) *ref, struct sym_val *result,
193 struct r_scope_elem *scope, size_t i,
194 const struct r_found_version *const version,
195 struct link_map *skip, int type_class);
197 static void
198 internal_function
199 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
200 const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
201 struct sym_val *value, const struct r_found_version *version,
202 int type_class, int protected);
204 /* Search loaded objects' symbol tables for a definition of the symbol
205 UNDEF_NAME. */
207 lookup_t
208 internal_function
209 _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
210 const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
211 int type_class, int explicit)
213 const unsigned long int hash = _dl_elf_hash (undef_name);
214 struct sym_val current_value = { NULL, NULL };
215 struct r_scope_elem **scope;
216 int protected;
218 ++_dl_num_relocations;
220 /* Search the relevant loaded objects for a definition. */
221 for (scope = symbol_scope; *scope; ++scope)
222 if (do_lookup (undef_name, hash, *ref, &current_value, *scope, 0, NULL,
223 type_class))
225 /* We have to check whether this would bind UNDEF_MAP to an object
226 in the global scope which was dynamically loaded. In this case
227 we have to prevent the latter from being unloaded unless the
228 UNDEF_MAP object is also unloaded. */
229 if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
230 /* Don't do this for explicit lookups as opposed to implicit
231 runtime lookups. */
232 && ! explicit
233 /* Add UNDEF_MAP to the dependencies. */
234 && add_dependency (undef_map, current_value.m) < 0)
235 /* Something went wrong. Perhaps the object we tried to reference
236 was just removed. Try finding another definition. */
237 return _dl_lookup_symbol (undef_name, undef_map, ref, symbol_scope,
238 type_class, 0);
240 break;
243 if (__builtin_expect (current_value.s == NULL, 0))
245 const char *reference_name = undef_map ? undef_map->l_name : NULL;
247 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
248 /* We could find no value for a strong reference. */
249 /* XXX We cannot translate the messages. */
250 _dl_signal_cerror (0, (reference_name[0]
251 ? reference_name
252 : (_dl_argv[0] ?: "<main program>")),
253 N_("relocation error"),
254 make_string (undefined_msg, undef_name));
255 *ref = NULL;
256 return 0;
259 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
260 if (__builtin_expect (protected != 0, 0))
262 /* It is very tricky. We need to figure out what value to
263 return for the protected symbol */
264 struct sym_val protected_value = { NULL, NULL };
266 for (scope = symbol_scope; *scope; ++scope)
267 if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
268 0, NULL, ELF_RTYPE_CLASS_PLT))
269 break;
271 if (protected_value.s != NULL && protected_value.m != undef_map)
273 current_value.s = *ref;
274 current_value.m = undef_map;
278 if (__builtin_expect (_dl_debug_mask
279 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
280 _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
281 &current_value, NULL, type_class, protected);
283 *ref = current_value.s;
284 return LOOKUP_VALUE (current_value.m);
288 /* This function is nearly the same as `_dl_lookup_symbol' but it
289 skips in the first list all objects until SKIP_MAP is found. I.e.,
290 it only considers objects which were loaded after the described
291 object. If there are more search lists the object described by
292 SKIP_MAP is only skipped. */
293 lookup_t
294 internal_function
295 _dl_lookup_symbol_skip (const char *undef_name,
296 struct link_map *undef_map, const ElfW(Sym) **ref,
297 struct r_scope_elem *symbol_scope[],
298 struct link_map *skip_map)
300 const unsigned long int hash = _dl_elf_hash (undef_name);
301 struct sym_val current_value = { NULL, NULL };
302 struct r_scope_elem **scope;
303 size_t i;
304 int protected;
306 ++_dl_num_relocations;
308 /* Search the relevant loaded objects for a definition. */
309 scope = symbol_scope;
310 for (i = 0; (*scope)->r_list[i] != skip_map; ++i)
311 assert (i < (*scope)->r_nlist);
313 if (! _dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, i,
314 skip_map, 0))
315 while (*++scope)
316 if (_dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, 0,
317 skip_map, 0))
318 break;
320 if (__builtin_expect (current_value.s == NULL, 0))
322 *ref = NULL;
323 return 0;
326 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
328 if (__builtin_expect (protected != 0, 0))
330 /* It is very tricky. We need to figure out what value to
331 return for the protected symbol. */
332 struct sym_val protected_value = { NULL, NULL };
334 if (i >= (*scope)->r_nlist
335 || !_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
336 i, skip_map, ELF_RTYPE_CLASS_PLT))
337 while (*++scope)
338 if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
339 0, skip_map, ELF_RTYPE_CLASS_PLT))
340 break;
342 if (protected_value.s != NULL && protected_value.m != undef_map)
344 current_value.s = *ref;
345 current_value.m = undef_map;
349 if (__builtin_expect (_dl_debug_mask
350 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
351 _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
352 &current_value, NULL, 0, protected);
354 *ref = current_value.s;
355 return LOOKUP_VALUE (current_value.m);
359 /* This function works like _dl_lookup_symbol but it takes an
360 additional arguement with the version number of the requested
361 symbol.
363 XXX We'll see whether we need this separate function. */
364 lookup_t
365 internal_function
366 _dl_lookup_versioned_symbol (const char *undef_name,
367 struct link_map *undef_map, const ElfW(Sym) **ref,
368 struct r_scope_elem *symbol_scope[],
369 const struct r_found_version *version,
370 int type_class, int explicit)
372 const unsigned long int hash = _dl_elf_hash (undef_name);
373 struct sym_val current_value = { NULL, NULL };
374 struct r_scope_elem **scope;
375 int protected;
377 ++_dl_num_relocations;
379 /* Search the relevant loaded objects for a definition. */
380 for (scope = symbol_scope; *scope; ++scope)
382 int res = do_lookup_versioned (undef_name, hash, *ref, &current_value,
383 *scope, 0, version, NULL, type_class);
384 if (res > 0)
386 /* We have to check whether this would bind UNDEF_MAP to an object
387 in the global scope which was dynamically loaded. In this case
388 we have to prevent the latter from being unloaded unless the
389 UNDEF_MAP object is also unloaded. */
390 if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
391 /* Don't do this for explicit lookups as opposed to implicit
392 runtime lookups. */
393 && ! explicit
394 /* Add UNDEF_MAP to the dependencies. */
395 && add_dependency (undef_map, current_value.m) < 0)
396 /* Something went wrong. Perhaps the object we tried to reference
397 was just removed. Try finding another definition. */
398 return _dl_lookup_versioned_symbol (undef_name, undef_map, ref,
399 symbol_scope, version,
400 type_class, 0);
402 break;
405 if (__builtin_expect (res, 0) < 0)
407 /* Oh, oh. The file named in the relocation entry does not
408 contain the needed symbol. */
409 const char *reference_name = undef_map ? undef_map->l_name : NULL;
411 /* XXX We cannot translate the message. */
412 _dl_signal_cerror (0, (reference_name[0]
413 ? reference_name
414 : (_dl_argv[0] ?: "<main program>")),
415 N_("relocation error"),
416 make_string ("symbol ", undef_name, ", version ",
417 version->name,
418 " not defined in file ",
419 version->filename,
420 " with link time reference",
421 res == -2
422 ? " (no version symbols)" : ""));
423 *ref = NULL;
424 return 0;
428 if (__builtin_expect (current_value.s == NULL, 0))
430 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
432 /* We could find no value for a strong reference. */
433 const char *reference_name = undef_map ? undef_map->l_name : NULL;
435 /* XXX We cannot translate the message. */
436 _dl_signal_cerror (0, (reference_name[0]
437 ? reference_name
438 : (_dl_argv[0] ?: "<main program>")), NULL,
439 make_string (undefined_msg, undef_name,
440 ", version ",
441 version->name ?: NULL));
443 *ref = NULL;
444 return 0;
447 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
449 if (__builtin_expect (protected != 0, 0))
451 /* It is very tricky. We need to figure out what value to
452 return for the protected symbol */
453 struct sym_val protected_value = { NULL, NULL };
455 for (scope = symbol_scope; *scope; ++scope)
456 if (_dl_do_lookup_versioned (undef_name, hash, *ref, &protected_value,
457 *scope, 0, version, NULL,
458 ELF_RTYPE_CLASS_PLT))
459 break;
461 if (protected_value.s != NULL && protected_value.m != undef_map)
463 current_value.s = *ref;
464 current_value.m = undef_map;
468 if (__builtin_expect (_dl_debug_mask
469 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
470 _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
471 &current_value, version, type_class, protected);
473 *ref = current_value.s;
474 return LOOKUP_VALUE (current_value.m);
478 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
479 with the version we are looking for. */
480 lookup_t
481 internal_function
482 _dl_lookup_versioned_symbol_skip (const char *undef_name,
483 struct link_map *undef_map,
484 const ElfW(Sym) **ref,
485 struct r_scope_elem *symbol_scope[],
486 const struct r_found_version *version,
487 struct link_map *skip_map)
489 const char *reference_name = undef_map->l_name;
490 const unsigned long int hash = _dl_elf_hash (undef_name);
491 struct sym_val current_value = { NULL, NULL };
492 struct r_scope_elem **scope;
493 size_t i;
494 int protected;
496 ++_dl_num_relocations;
498 /* Search the relevant loaded objects for a definition. */
499 scope = symbol_scope;
500 for (i = 0; (*scope)->r_list[i] != skip_map; ++i)
501 assert (i < (*scope)->r_nlist);
503 if (! _dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
504 *scope, i, version, skip_map, 0))
505 while (*++scope)
506 if (_dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
507 *scope, 0, version, skip_map, 0))
508 break;
510 if (__builtin_expect (current_value.s == NULL, 0))
512 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
514 /* We could find no value for a strong reference. */
515 const size_t len = strlen (undef_name);
516 char buf[sizeof undefined_msg + len];
517 __mempcpy (__mempcpy (buf, undefined_msg, sizeof undefined_msg - 1),
518 undef_name, len + 1);
519 /* XXX We cannot translate the messages. */
520 _dl_signal_cerror (0, (reference_name[0]
521 ? reference_name
522 : (_dl_argv[0] ?: "<main program>")),
523 NULL, buf);
525 *ref = NULL;
526 return 0;
529 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
531 if (__builtin_expect (protected != 0, 0))
533 /* It is very tricky. We need to figure out what value to
534 return for the protected symbol */
535 struct sym_val protected_value = { NULL, NULL };
537 if (i >= (*scope)->r_nlist
538 || !_dl_do_lookup_versioned (undef_name, hash, *ref,
539 &protected_value, *scope, i, version,
540 skip_map, ELF_RTYPE_CLASS_PLT))
541 while (*++scope)
542 if (_dl_do_lookup_versioned (undef_name, hash, *ref,
543 &protected_value, *scope, 0, version,
544 skip_map, ELF_RTYPE_CLASS_PLT))
545 break;
547 if (protected_value.s != NULL && protected_value.m != undef_map)
549 current_value.s = *ref;
550 current_value.m = undef_map;
554 if (__builtin_expect (_dl_debug_mask
555 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
556 _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
557 &current_value, version, 0, protected);
559 *ref = current_value.s;
560 return LOOKUP_VALUE (current_value.m);
564 /* Cache the location of MAP's hash table. */
566 void
567 internal_function
568 _dl_setup_hash (struct link_map *map)
570 Elf_Symndx *hash;
571 Elf_Symndx nchain;
573 if (!map->l_info[DT_HASH])
574 return;
575 hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);
577 map->l_nbuckets = *hash++;
578 nchain = *hash++;
579 map->l_buckets = hash;
580 hash += map->l_nbuckets;
581 map->l_chain = hash;
584 static void
585 internal_function
586 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
587 const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
588 struct sym_val *value, const struct r_found_version *version,
589 int type_class, int protected)
591 const char *reference_name = undef_map->l_name;
593 if (_dl_debug_mask & DL_DEBUG_BINDINGS)
595 _dl_debug_printf ("binding file %s to %s: %s symbol `%s'",
596 (reference_name[0]
597 ? reference_name : (_dl_argv[0] ?: "<main program>")),
598 value->m->l_name[0] ? value->m->l_name : _dl_argv[0],
599 protected ? "protected" : "normal",
600 undef_name);
601 if (version)
602 _dl_debug_printf_c (" [%s]\n", version->name);
603 else
604 _dl_debug_printf_c ("\n");
606 #ifdef SHARED
607 if (_dl_debug_mask & DL_DEBUG_PRELINK)
609 int conflict = 0;
610 struct sym_val val = { NULL, NULL };
612 if ((_dl_trace_prelink_map == NULL
613 || _dl_trace_prelink_map == _dl_loaded)
614 && undef_map != _dl_loaded)
616 const unsigned long int hash = _dl_elf_hash (undef_name);
618 if (version == 0)
619 _dl_do_lookup (undef_name, hash, *ref, &val,
620 undef_map->l_local_scope[0], 0, NULL, type_class);
621 else
622 _dl_do_lookup_versioned (undef_name, hash, *ref, &val,
623 undef_map->l_local_scope[0], 0, version,
624 NULL, type_class);
626 if (val.s != value->s || val.m != value->m)
627 conflict = 1;
630 if (conflict
631 || _dl_trace_prelink_map == undef_map
632 || _dl_trace_prelink_map == NULL)
634 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
635 conflict ? "conflict" : "lookup",
636 (int) sizeof (ElfW(Addr)) * 2, undef_map->l_map_start,
637 (int) sizeof (ElfW(Addr)) * 2,
638 ((ElfW(Addr)) *ref) - undef_map->l_map_start,
639 (int) sizeof (ElfW(Addr)) * 2,
640 (ElfW(Addr)) (value->s ? value->m->l_map_start : 0),
641 (int) sizeof (ElfW(Addr)) * 2,
642 (ElfW(Addr)) (value->s ? value->s->st_value : 0));
644 if (conflict)
645 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
646 (int) sizeof (ElfW(Addr)) * 2,
647 (ElfW(Addr)) (val.s ? val.m->l_map_start : 0),
648 (int) sizeof (ElfW(Addr)) * 2,
649 (ElfW(Addr)) (val.s ? val.s->st_value : 0));
651 _dl_printf ("/%x %s\n", type_class, undef_name);
654 #endif
657 /* These are here so that we only inline do_lookup{,_versioned} in the common
658 case, not everywhere. */
659 static int
660 internal_function
661 _dl_do_lookup (const char *undef_name, unsigned long int hash,
662 const ElfW(Sym) *ref, struct sym_val *result,
663 struct r_scope_elem *scope, size_t i,
664 struct link_map *skip, int type_class)
666 return do_lookup (undef_name, hash, ref, result, scope, i, skip,
667 type_class);
670 static int
671 internal_function
672 _dl_do_lookup_versioned (const char *undef_name, unsigned long int hash,
673 const ElfW(Sym) *ref, struct sym_val *result,
674 struct r_scope_elem *scope, size_t i,
675 const struct r_found_version *const version,
676 struct link_map *skip, int type_class)
678 return do_lookup_versioned (undef_name, hash, ref, result, scope, i,
679 version, skip, type_class);