Update.
[glibc.git] / elf / dl-lookup.c
blob3acd71f14c20aefc5ed00698883ade6f65fcf678
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 Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 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 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 #include <alloca.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 <bits/libc-lock.h>
29 #include <assert.h>
31 #define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
33 /* We need this string more than once. */
34 static const char undefined_msg[] = "undefined symbol: ";
37 struct sym_val
39 const ElfW(Sym) *s;
40 struct link_map *m;
44 #define make_string(string, rest...) \
45 ({ \
46 const char *all[] = { string, ## rest }; \
47 size_t len, cnt; \
48 char *result, *cp; \
50 len = 1; \
51 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
52 len += strlen (all[cnt]); \
54 cp = result = alloca (len); \
55 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
56 cp = __stpcpy (cp, all[cnt]); \
58 result; \
61 /* Statistics function. */
62 unsigned long int _dl_num_relocations;
64 /* During the program run we must not modify the global data of
65 loaded shared object simultanously in two threads. Therefore we
66 protect `_dl_open' and `_dl_close' in dl-close.c.
68 This must be a recursive lock since the initializer function of
69 the loaded object might as well require a call to this function.
70 At this time it is not anymore a problem to modify the tables. */
71 __libc_lock_define (extern, _dl_load_lock)
74 /* We have two different situations when looking up a simple: with or
75 without versioning. gcc is not able to optimize a single function
76 definition serving for both purposes so we define two functions. */
77 #define VERSIONED 0
78 #include "do-lookup.h"
80 #define VERSIONED 1
81 #include "do-lookup.h"
84 /* Add extra dependency on MAP to UNDEF_MAP. */
85 static int
86 internal_function
87 add_dependency (struct link_map *undef_map, struct link_map *map)
89 struct link_map **list;
90 unsigned int act;
91 unsigned int i;
92 int result = 0;
94 /* Make sure nobody can unload the object while we are at it. */
95 __libc_lock_lock (_dl_load_lock);
97 /* Determine whether UNDEF_MAP already has a reference to MAP. First
98 look in the normal dependencies. */
99 list = undef_map->l_initfini;
101 for (i = 0; list[i] != NULL; ++i)
102 if (list[i] == map)
103 break;
105 if (__builtin_expect (list[i] == NULL, 1))
107 /* No normal dependency. See whether we already had to add it
108 to the special list of dynamic dependencies. */
109 list = undef_map->l_reldeps;
110 act = undef_map->l_reldepsact;
112 for (i = 0; i < act; ++i)
113 if (list[i] == map)
114 break;
116 if (i == act)
118 /* The object is not yet in the dependency list. Before we add
119 it make sure just one more time the object we are about to
120 reference is still available. There is a brief period in
121 which the object could have been removed since we found the
122 definition. */
123 struct link_map *runp = _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
134 this can never happen during the startup phase we can
135 use `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
151 is no fatal mistake. We simply increment the use counter
152 of the referenced object and don't record the dependencies.
153 This means this increment can never be reverted and the
154 object will never be unloaded. This is semantically the
155 correct behaviour. */
156 if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
157 undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
159 /* And increment the counter in the referenced object. */
160 ++map->l_opencount;
162 /* Display information if we are debugging. */
163 if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0))
164 _dl_debug_printf ("\
165 \nfile=%s; needed by %s (relocation dependency)\n\n",
166 map->l_name[0] ? map->l_name : _dl_argv[0],
167 undef_map->l_name[0]
168 ? undef_map->l_name : _dl_argv[0]);
170 else
171 /* Whoa, that was bad luck. We have to search again. */
172 result = -1;
176 /* Release the lock. */
177 __libc_lock_unlock (_dl_load_lock);
179 return result;
182 static int
183 internal_function
184 _dl_do_lookup (const char *undef_name, unsigned long int hash,
185 const ElfW(Sym) *ref, struct sym_val *result,
186 struct r_scope_elem *scope, size_t i,
187 struct link_map *skip, int noexec, int noplt);
188 static int
189 internal_function
190 _dl_do_lookup_versioned (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 const struct r_found_version *const version,
194 struct link_map *skip, int noexec, int noplt);
196 /* Search loaded objects' symbol tables for a definition of the symbol
197 UNDEF_NAME. */
199 lookup_t
200 internal_function
201 _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
202 const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
203 int reloc_type, int explicit)
205 const char *reference_name = undef_map ? undef_map->l_name : NULL;
206 const unsigned long int hash = _dl_elf_hash (undef_name);
207 struct sym_val current_value = { NULL, NULL };
208 struct r_scope_elem **scope;
209 int protected;
210 int noexec = elf_machine_lookup_noexec_p (reloc_type);
211 int noplt = elf_machine_lookup_noplt_p (reloc_type);
213 ++_dl_num_relocations;
215 /* Search the relevant loaded objects for a definition. */
216 for (scope = symbol_scope; *scope; ++scope)
217 if (do_lookup (undef_name, hash, *ref, &current_value, *scope, 0, NULL,
218 noexec, noplt))
220 /* We have to check whether this would bind UNDEF_MAP to an object
221 in the global scope which was dynamically loaded. In this case
222 we have to prevent the latter from being unloaded unless the
223 UNDEF_MAP object is also unloaded. */
224 if (__builtin_expect (current_value.m->l_global, 0)
225 && (__builtin_expect (current_value.m->l_type, lt_library)
226 == lt_loaded)
227 && undef_map != current_value.m
228 /* Don't do this for explicit lookups as opposed to implicit
229 runtime lookups. */
230 && __builtin_expect (! explicit, 1)
231 /* Add UNDEF_MAP to the dependencies. */
232 && add_dependency (undef_map, current_value.m) < 0)
233 /* Something went wrong. Perhaps the object we tried to reference
234 was just removed. Try finding another definition. */
235 return _dl_lookup_symbol (undef_name, undef_map, ref, symbol_scope,
236 reloc_type, 0);
238 break;
241 if (__builtin_expect (current_value.s == NULL, 0))
243 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
244 /* We could find no value for a strong reference. */
245 /* XXX We cannot translate the messages. */
246 _dl_signal_cerror (0, (reference_name && reference_name[0]
247 ? reference_name
248 : (_dl_argv[0] ?: "<main program>")),
249 make_string (undefined_msg, undef_name));
250 *ref = NULL;
251 return 0;
254 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
256 if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0))
257 _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n",
258 (reference_name && reference_name[0]
259 ? reference_name : (_dl_argv[0] ?: "<main program>")),
260 current_value.m->l_name[0]
261 ? current_value.m->l_name : _dl_argv[0],
262 protected ? "protected" : "normal", undef_name);
264 if (__builtin_expect (protected == 0, 1))
266 *ref = current_value.s;
267 return LOOKUP_VALUE (current_value.m);
269 else
271 /* It is very tricky. We need to figure out what value to
272 return for the protected symbol */
273 struct sym_val protected_value = { NULL, NULL };
275 for (scope = symbol_scope; *scope; ++scope)
276 if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
277 0, NULL, 0, 1))
278 break;
280 if (protected_value.s == NULL || protected_value.m == undef_map)
282 *ref = current_value.s;
283 return LOOKUP_VALUE (current_value.m);
286 return LOOKUP_VALUE (undef_map);
291 /* This function is nearly the same as `_dl_lookup_symbol' but it
292 skips in the first list all objects until SKIP_MAP is found. I.e.,
293 it only considers objects which were loaded after the described
294 object. If there are more search lists the object described by
295 SKIP_MAP is only skipped. */
296 lookup_t
297 internal_function
298 _dl_lookup_symbol_skip (const char *undef_name,
299 struct link_map *undef_map, const ElfW(Sym) **ref,
300 struct r_scope_elem *symbol_scope[],
301 struct link_map *skip_map)
303 const char *reference_name = undef_map ? undef_map->l_name : NULL;
304 const unsigned long int hash = _dl_elf_hash (undef_name);
305 struct sym_val current_value = { NULL, NULL };
306 struct r_scope_elem **scope;
307 size_t i;
308 int protected;
310 ++_dl_num_relocations;
312 /* Search the relevant loaded objects for a definition. */
313 scope = symbol_scope;
314 for (i = 0; (*scope)->r_list[i] != skip_map; ++i)
315 assert (i < (*scope)->r_nlist);
317 if (! _dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, i,
318 skip_map, 0, 0))
319 while (*++scope)
320 if (_dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, 0,
321 skip_map, 0, 0))
322 break;
324 if (__builtin_expect (current_value.s == NULL, 0))
326 *ref = NULL;
327 return 0;
330 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
332 if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0))
333 _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n",
334 (reference_name && reference_name[0]
335 ? reference_name : (_dl_argv[0] ?: "<main program>")),
336 current_value.m->l_name[0]
337 ? current_value.m->l_name : _dl_argv[0],
338 protected ? "protected" : "normal", undef_name);
340 if (__builtin_expect (protected == 0, 1))
342 *ref = current_value.s;
343 return LOOKUP_VALUE (current_value.m);
345 else
347 /* It is very tricky. We need to figure out what value to
348 return for the protected symbol. */
349 struct sym_val protected_value = { NULL, NULL };
351 if (i >= (*scope)->r_nlist
352 || !_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
353 i, skip_map, 0, 1))
354 while (*++scope)
355 if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
356 0, skip_map, 0, 1))
357 break;
359 if (protected_value.s == NULL || protected_value.m == undef_map)
361 *ref = current_value.s;
362 return LOOKUP_VALUE (current_value.m);
365 return LOOKUP_VALUE (undef_map);
370 /* This function works like _dl_lookup_symbol but it takes an
371 additional arguement with the version number of the requested
372 symbol.
374 XXX We'll see whether we need this separate function. */
375 lookup_t
376 internal_function
377 _dl_lookup_versioned_symbol (const char *undef_name,
378 struct link_map *undef_map, const ElfW(Sym) **ref,
379 struct r_scope_elem *symbol_scope[],
380 const struct r_found_version *version,
381 int reloc_type, int explicit)
383 const char *reference_name = undef_map ? undef_map->l_name : NULL;
384 const unsigned long int hash = _dl_elf_hash (undef_name);
385 struct sym_val current_value = { NULL, NULL };
386 struct r_scope_elem **scope;
387 int protected;
388 int noexec = elf_machine_lookup_noexec_p (reloc_type);
389 int noplt = elf_machine_lookup_noplt_p (reloc_type);
391 ++_dl_num_relocations;
393 /* Search the relevant loaded objects for a definition. */
394 for (scope = symbol_scope; *scope; ++scope)
396 int res = do_lookup_versioned (undef_name, hash, *ref, &current_value,
397 *scope, 0, version, NULL, noexec, noplt);
398 if (res > 0)
400 /* We have to check whether this would bind UNDEF_MAP to an object
401 in the global scope which was dynamically loaded. In this case
402 we have to prevent the latter from being unloaded unless the
403 UNDEF_MAP object is also unloaded. */
404 if (__builtin_expect (current_value.m->l_global, 0)
405 && (__builtin_expect (current_value.m->l_type, lt_library)
406 == lt_loaded)
407 && undef_map != current_value.m
408 /* Don't do this for explicit lookups as opposed to implicit
409 runtime lookups. */
410 && __builtin_expect (! explicit, 1)
411 /* Add UNDEF_MAP to the dependencies. */
412 && add_dependency (undef_map, current_value.m) < 0)
413 /* Something went wrong. Perhaps the object we tried to reference
414 was just removed. Try finding another definition. */
415 return _dl_lookup_versioned_symbol (undef_name, undef_map, ref,
416 symbol_scope, version,
417 reloc_type, 0);
419 break;
422 if (__builtin_expect (res, 0) < 0)
424 /* Oh, oh. The file named in the relocation entry does not
425 contain the needed symbol. */
426 /* XXX We cannot translate the message. */
427 _dl_signal_cerror (0, (reference_name && reference_name[0]
428 ? reference_name
429 : (_dl_argv[0] ?: "<main program>")),
430 make_string ("symbol ", undef_name, ", version ",
431 version->name,
432 " not defined in file ",
433 version->filename,
434 " with link time reference",
435 res == -2
436 ? " (no version symbols)" : ""));
437 *ref = NULL;
438 return 0;
442 if (__builtin_expect (current_value.s == NULL, 0))
444 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
445 /* We could find no value for a strong reference. */
446 /* XXX We cannot translate the message. */
447 _dl_signal_cerror (0, (reference_name && reference_name[0]
448 ? reference_name
449 : (_dl_argv[0] ?: "<main program>")),
450 make_string (undefined_msg, undef_name,
451 ", version ", version->name ?: NULL));
452 *ref = NULL;
453 return 0;
456 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
458 if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0))
459 _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n",
460 (reference_name && reference_name[0]
461 ? reference_name : (_dl_argv[0] ?: "<main program>")),
462 current_value.m->l_name[0]
463 ? current_value.m->l_name : _dl_argv[0],
464 protected ? "protected" : "normal",
465 undef_name, version->name);
467 if (__builtin_expect (protected == 0, 1))
469 *ref = current_value.s;
470 return LOOKUP_VALUE (current_value.m);
472 else
474 /* It is very tricky. We need to figure out what value to
475 return for the protected symbol */
476 struct sym_val protected_value = { NULL, NULL };
478 for (scope = symbol_scope; *scope; ++scope)
479 if (_dl_do_lookup_versioned (undef_name, hash, *ref, &protected_value,
480 *scope, 0, version, NULL, 0, 1))
481 break;
483 if (protected_value.s == NULL || protected_value.m == undef_map)
485 *ref = current_value.s;
486 return LOOKUP_VALUE (current_value.m);
489 return LOOKUP_VALUE (undef_map);
494 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
495 with the version we are looking for. */
496 lookup_t
497 internal_function
498 _dl_lookup_versioned_symbol_skip (const char *undef_name,
499 struct link_map *undef_map,
500 const ElfW(Sym) **ref,
501 struct r_scope_elem *symbol_scope[],
502 const struct r_found_version *version,
503 struct link_map *skip_map)
505 const char *reference_name = undef_map ? undef_map->l_name : NULL;
506 const unsigned long int hash = _dl_elf_hash (undef_name);
507 struct sym_val current_value = { NULL, NULL };
508 struct r_scope_elem **scope;
509 size_t i;
510 int protected;
512 ++_dl_num_relocations;
514 /* Search the relevant loaded objects for a definition. */
515 scope = symbol_scope;
516 for (i = 0; (*scope)->r_list[i] != skip_map; ++i)
517 assert (i < (*scope)->r_nlist);
519 if (! _dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
520 *scope, i, version, skip_map, 0, 0))
521 while (*++scope)
522 if (_dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
523 *scope, 0, version, skip_map, 0, 0))
524 break;
526 if (__builtin_expect (current_value.s == NULL, 0))
528 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
530 /* We could find no value for a strong reference. */
531 const size_t len = strlen (undef_name);
532 char buf[sizeof undefined_msg + len];
533 __mempcpy (__mempcpy (buf, undefined_msg, sizeof undefined_msg - 1),
534 undef_name, len + 1);
535 /* XXX We cannot translate the messages. */
536 _dl_signal_cerror (0, (reference_name && reference_name[0]
537 ? reference_name
538 : (_dl_argv[0] ?: "<main program>")), buf);
540 *ref = NULL;
541 return 0;
544 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
546 if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0))
547 _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n",
548 (reference_name && reference_name[0]
549 ? reference_name : (_dl_argv[0] ?: "<main program>")),
550 current_value.m->l_name[0]
551 ? current_value.m->l_name : _dl_argv[0],
552 protected ? "protected" : "normal",
553 undef_name, version->name);
555 if (__builtin_expect (protected == 0, 1))
557 *ref = current_value.s;
558 return LOOKUP_VALUE (current_value.m);
560 else
562 /* It is very tricky. We need to figure out what value to
563 return for the protected symbol */
564 struct sym_val protected_value = { NULL, NULL };
566 if (i >= (*scope)->r_nlist
567 || !_dl_do_lookup_versioned (undef_name, hash, *ref,
568 &protected_value, *scope, i, version,
569 skip_map, 0, 1))
570 while (*++scope)
571 if (_dl_do_lookup_versioned (undef_name, hash, *ref,
572 &protected_value, *scope, 0, version,
573 skip_map, 0, 1))
574 break;
576 if (protected_value.s == NULL || protected_value.m == undef_map)
578 *ref = current_value.s;
579 return LOOKUP_VALUE (current_value.m);
582 return LOOKUP_VALUE (undef_map);
587 /* Cache the location of MAP's hash table. */
589 void
590 internal_function
591 _dl_setup_hash (struct link_map *map)
593 Elf_Symndx *hash;
594 Elf_Symndx nchain;
596 if (!map->l_info[DT_HASH])
597 return;
598 hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);
600 map->l_nbuckets = *hash++;
601 nchain = *hash++;
602 map->l_buckets = hash;
603 hash += map->l_nbuckets;
604 map->l_chain = hash;
607 /* These are here so that we only inline do_lookup{,_versioned} in the common
608 case, not everywhere. */
609 static int
610 internal_function
611 _dl_do_lookup (const char *undef_name, unsigned long int hash,
612 const ElfW(Sym) *ref, struct sym_val *result,
613 struct r_scope_elem *scope, size_t i,
614 struct link_map *skip, int noexec, int noplt)
616 return do_lookup (undef_name, hash, ref, result, scope, i, skip, noexec,
617 noplt);
620 static int
621 internal_function
622 _dl_do_lookup_versioned (const char *undef_name, unsigned long int hash,
623 const ElfW(Sym) *ref, struct sym_val *result,
624 struct r_scope_elem *scope, size_t i,
625 const struct r_found_version *const version,
626 struct link_map *skip, int noexec, int noplt)
628 return do_lookup_versioned (undef_name, hash, ref, result, scope, i,
629 version, skip, noexec, noplt);