Update.
[glibc.git] / elf / dl-lookup.c
blob2b58ff32aac22d1f6c4a8efae8a5fe16b042f3a9
1 /* Look up a symbol in the loaded objects.
2 Copyright (C) 1995,96,97,98,99,2000 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 #define PROTECTED 0
79 #include "do-lookup.h"
81 #define VERSIONED 1
82 #define PROTECTED 0
83 #include "do-lookup.h"
86 /* Add extra dependency on MAP to UNDEF_MAP. */
87 static int
88 add_dependency (struct link_map *undef_map, struct link_map *map)
90 struct link_map **list;
91 unsigned int act;
92 unsigned int i;
93 int result = 0;
95 /* Make sure nobody can unload the object while we are at it. */
96 __libc_lock_lock (_dl_load_lock);
98 /* Determine whether UNDEF_MAP already has a reference to MAP. First
99 look in the normal dependencies. */
100 list = undef_map->l_searchlist.r_list;
101 act = undef_map->l_searchlist.r_nlist;
103 for (i = 0; i < act; ++i)
104 if (list[i] == map)
105 break;
107 if (__builtin_expect (i == act, 1))
109 /* No normal dependency. See whether we already had to add it
110 to the special list of dynamic dependencies. */
111 list = undef_map->l_reldeps;
112 act = undef_map->l_reldepsact;
114 for (i = 0; i < act; ++i)
115 if (list[i] == map)
116 break;
118 if (i == act)
120 /* The object is not yet in the dependency list. Before we add
121 it make sure just one more time the object we are about to
122 reference is still available. There is a brief period in
123 which the object could have been removed since we found the
124 definition. */
125 struct link_map *runp = _dl_loaded;
127 while (runp != NULL && runp != map)
128 runp = runp->l_next;
130 if (runp != NULL)
132 /* The object is still available. Add the reference now. */
133 if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
135 /* Allocate more memory for the dependency list. Since
136 this can never happen during the startup phase we can
137 use `realloc'. */
138 void *newp;
140 undef_map->l_reldepsmax += 5;
141 newp = realloc (undef_map->l_reldeps,
142 undef_map->l_reldepsmax
143 * sizeof(struct link_map *));
145 if (__builtin_expect (newp != NULL, 1))
146 undef_map->l_reldeps = (struct link_map **) newp;
147 else
148 /* Correct the addition. */
149 undef_map->l_reldepsmax -= 5;
152 /* If we didn't manage to allocate memory for the list this
153 is no fatal mistake. We simply increment the use counter
154 of the referenced object and don't record the dependencies.
155 This means this increment can never be reverted and the
156 object will never be unloaded. This is semantically the
157 correct behaviour. */
158 if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
159 undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
161 /* And increment the counter in the referenced object. */
162 ++map->l_opencount;
164 /* Display information if we are debugging. */
165 if (__builtin_expect (_dl_debug_files, 0))
166 _dl_debug_message (1, "\nfile=",
167 map->l_name[0] ? map->l_name : _dl_argv[0],
168 "; needed by ",
169 undef_map->l_name[0]
170 ? undef_map->l_name : _dl_argv[0],
171 " (relocation dependency)\n\n", NULL);
173 else
174 /* Whoa, that was bad luck. We have to search again. */
175 result = -1;
179 /* Release the lock. */
180 __libc_lock_unlock (_dl_load_lock);
182 return result;
186 /* Search loaded objects' symbol tables for a definition of the symbol
187 UNDEF_NAME. */
189 lookup_t
190 internal_function
191 _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
192 const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
193 int reloc_type, int explicit)
195 const char *reference_name = undef_map ? undef_map->l_name : NULL;
196 const unsigned long int hash = _dl_elf_hash (undef_name);
197 struct sym_val current_value = { NULL, NULL };
198 struct r_scope_elem **scope;
199 int protected;
200 int noexec = elf_machine_lookup_noexec_p (reloc_type);
201 int noplt = elf_machine_lookup_noplt_p (reloc_type);
203 ++_dl_num_relocations;
205 /* Search the relevant loaded objects for a definition. */
206 for (scope = symbol_scope; *scope; ++scope)
207 if (do_lookup (undef_name, hash, *ref, &current_value, *scope, 0, NULL,
208 noexec, noplt))
210 /* We have to check whether this would bind UNDEF_MAP to an object
211 in the global scope which was dynamically loaded. In this case
212 we have to prevent the latter from being unloaded unless the
213 UNDEF_MAP object is also unloaded. */
214 if (__builtin_expect (current_value.m->l_global, 0)
215 && (__builtin_expect (current_value.m->l_type, lt_library)
216 == lt_loaded)
217 && undef_map != current_value.m
218 /* Don't do this for explicit lookups as opposed to implicit
219 runtime lookups. */
220 && __builtin_expect (! explicit, 1)
221 /* Add UNDEF_MAP to the dependencies. */
222 && add_dependency (undef_map, current_value.m) < 0)
223 /* Something went wrong. Perhaps the object we tried to reference
224 was just removed. Try finding another definition. */
225 return _dl_lookup_symbol (undef_name, undef_map, ref, symbol_scope,
226 reloc_type, 0);
228 break;
231 if (__builtin_expect (current_value.s == NULL, 0))
233 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
234 /* We could find no value for a strong reference. */
235 /* XXX We cannot translate the messages. */
236 _dl_signal_cerror (0, (reference_name && reference_name[0]
237 ? reference_name
238 : (_dl_argv[0] ?: "<main program>")),
239 make_string (undefined_msg, undef_name));
240 *ref = NULL;
241 return 0;
244 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
246 if (__builtin_expect (_dl_debug_bindings, 0))
247 _dl_debug_message (1, "binding file ",
248 (reference_name && reference_name[0]
249 ? reference_name
250 : (_dl_argv[0] ?: "<main program>")),
251 " to ", current_value.m->l_name[0]
252 ? current_value.m->l_name : _dl_argv[0],
253 ": ", protected ? "protected" : "normal",
254 " symbol `", undef_name, "'\n", NULL);
256 if (__builtin_expect (protected == 0, 1))
258 *ref = current_value.s;
259 return LOOKUP_VALUE (current_value.m);
261 else
263 /* It is very tricky. We need to figure out what value to
264 return for the protected symbol */
265 struct sym_val protected_value = { NULL, NULL };
267 for (scope = symbol_scope; *scope; ++scope)
268 if (do_lookup (undef_name, hash, *ref, &protected_value, *scope, 0,
269 NULL, 0, 1))
270 break;
272 if (protected_value.s == NULL || protected_value.m == undef_map)
274 *ref = current_value.s;
275 return LOOKUP_VALUE (current_value.m);
278 return LOOKUP_VALUE (undef_map);
283 /* This function is nearly the same as `_dl_lookup_symbol' but it
284 skips in the first list all objects until SKIP_MAP is found. I.e.,
285 it only considers objects which were loaded after the described
286 object. If there are more search lists the object described by
287 SKIP_MAP is only skipped. */
288 lookup_t
289 internal_function
290 _dl_lookup_symbol_skip (const char *undef_name,
291 struct link_map *undef_map, const ElfW(Sym) **ref,
292 struct r_scope_elem *symbol_scope[],
293 struct link_map *skip_map)
295 const char *reference_name = undef_map ? undef_map->l_name : NULL;
296 const unsigned long int hash = _dl_elf_hash (undef_name);
297 struct sym_val current_value = { NULL, NULL };
298 struct r_scope_elem **scope;
299 size_t i;
300 int protected;
302 ++_dl_num_relocations;
304 /* Search the relevant loaded objects for a definition. */
305 scope = symbol_scope;
306 for (i = 0; (*scope)->r_duplist[i] != skip_map; ++i)
307 assert (i < (*scope)->r_nduplist);
309 while (i >= (*scope)->r_nlist
310 || ! do_lookup (undef_name, hash, *ref, &current_value, *scope, i,
311 skip_map, 0, 0))
312 while (*++scope)
313 if (do_lookup (undef_name, hash, *ref, &current_value, *scope, 0,
314 skip_map, 0, 0))
315 break;
317 if (__builtin_expect (current_value.s == NULL, 0))
319 *ref = NULL;
320 return 0;
323 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
325 if (__builtin_expect (_dl_debug_bindings, 0))
326 _dl_debug_message (1, "binding file ",
327 (reference_name && reference_name[0]
328 ? reference_name
329 : (_dl_argv[0] ?: "<main program>")),
330 " to ", current_value.m->l_name[0]
331 ? current_value.m->l_name : _dl_argv[0],
332 ": ", protected ? "protected" : "normal",
333 " symbol `", undef_name, "'\n", NULL);
335 if (__builtin_expect (protected == 0, 1))
337 *ref = current_value.s;
338 return LOOKUP_VALUE (current_value.m);
340 else
342 /* It is very tricky. We need to figure out what value to
343 return for the protected symbol. */
344 struct sym_val protected_value = { NULL, NULL };
346 if (i >= (*scope)->r_nlist
347 || !do_lookup (undef_name, hash, *ref, &protected_value, *scope, i,
348 skip_map, 0, 1))
349 while (*++scope)
350 if (do_lookup (undef_name, hash, *ref, &protected_value, *scope, 0,
351 skip_map, 0, 1))
352 break;
354 if (protected_value.s == NULL || protected_value.m == undef_map)
356 *ref = current_value.s;
357 return LOOKUP_VALUE (current_value.m);
360 return LOOKUP_VALUE (undef_map);
365 /* This function works like _dl_lookup_symbol but it takes an
366 additional arguement with the version number of the requested
367 symbol.
369 XXX We'll see whether we need this separate function. */
370 lookup_t
371 internal_function
372 _dl_lookup_versioned_symbol (const char *undef_name,
373 struct link_map *undef_map, const ElfW(Sym) **ref,
374 struct r_scope_elem *symbol_scope[],
375 const struct r_found_version *version,
376 int reloc_type, int explicit)
378 const char *reference_name = undef_map ? undef_map->l_name : NULL;
379 const unsigned long int hash = _dl_elf_hash (undef_name);
380 struct sym_val current_value = { NULL, NULL };
381 struct r_scope_elem **scope;
382 int protected;
383 int noexec = elf_machine_lookup_noexec_p (reloc_type);
384 int noplt = elf_machine_lookup_noplt_p (reloc_type);
386 ++_dl_num_relocations;
388 /* Search the relevant loaded objects for a definition. */
389 for (scope = symbol_scope; *scope; ++scope)
391 int res = do_lookup_versioned (undef_name, hash, *ref, &current_value,
392 *scope, 0, version, NULL, noexec, noplt);
393 if (res > 0)
395 /* We have to check whether this would bind UNDEF_MAP to an object
396 in the global scope which was dynamically loaded. In this case
397 we have to prevent the latter from being unloaded unless the
398 UNDEF_MAP object is also unloaded. */
399 if (__builtin_expect (current_value.m->l_global, 0)
400 && (__builtin_expect (current_value.m->l_type, lt_library)
401 == lt_loaded)
402 && undef_map != current_value.m
403 /* Don't do this for explicit lookups as opposed to implicit
404 runtime lookups. */
405 && __builtin_expect (! explicit, 1)
406 /* Add UNDEF_MAP to the dependencies. */
407 && add_dependency (undef_map, current_value.m) < 0)
408 /* Something went wrong. Perhaps the object we tried to reference
409 was just removed. Try finding another definition. */
410 return _dl_lookup_versioned_symbol (undef_name, undef_map, ref,
411 symbol_scope, version,
412 reloc_type, 0);
414 break;
417 if (__builtin_expect (res, 0) < 0)
419 /* Oh, oh. The file named in the relocation entry does not
420 contain the needed symbol. */
421 /* XXX We cannot translate the message. */
422 _dl_signal_cerror (0, (reference_name && reference_name[0]
423 ? reference_name
424 : (_dl_argv[0] ?: "<main program>")),
425 make_string ("symbol ", undef_name, ", version ",
426 version->name,
427 " not defined in file ",
428 version->filename,
429 " with link time reference",
430 res == -2
431 ? " (no version symbols)" : ""));
432 *ref = NULL;
433 return 0;
437 if (__builtin_expect (current_value.s == NULL, 0))
439 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
440 /* We could find no value for a strong reference. */
441 /* XXX We cannot translate the message. */
442 _dl_signal_cerror (0, (reference_name && reference_name[0]
443 ? reference_name
444 : (_dl_argv[0] ?: "<main program>")),
445 make_string (undefined_msg, undef_name,
446 ", version ", version->name ?: NULL));
447 *ref = NULL;
448 return 0;
451 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
453 if (__builtin_expect (_dl_debug_bindings, 0))
454 _dl_debug_message (1, "binding file ",
455 (reference_name && reference_name[0]
456 ? reference_name
457 : (_dl_argv[0] ?: "<main program>")),
458 " to ", current_value.m->l_name[0]
459 ? current_value.m->l_name : _dl_argv[0],
460 ": ", protected ? "protected" : "normal",
461 " symbol `", undef_name, "' [", version->name,
462 "]\n", NULL);
464 if (__builtin_expect (protected == 0, 1))
466 *ref = current_value.s;
467 return LOOKUP_VALUE (current_value.m);
469 else
471 /* It is very tricky. We need to figure out what value to
472 return for the protected symbol */
473 struct sym_val protected_value = { NULL, NULL };
475 for (scope = symbol_scope; *scope; ++scope)
476 if (do_lookup_versioned (undef_name, hash, *ref, &protected_value,
477 *scope, 0, version, NULL, 0, 1))
478 break;
480 if (protected_value.s == NULL || protected_value.m == undef_map)
482 *ref = current_value.s;
483 return LOOKUP_VALUE (current_value.m);
486 return LOOKUP_VALUE (undef_map);
491 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
492 with the version we are looking for. */
493 lookup_t
494 internal_function
495 _dl_lookup_versioned_symbol_skip (const char *undef_name,
496 struct link_map *undef_map,
497 const ElfW(Sym) **ref,
498 struct r_scope_elem *symbol_scope[],
499 const struct r_found_version *version,
500 struct link_map *skip_map)
502 const char *reference_name = undef_map ? undef_map->l_name : NULL;
503 const unsigned long int hash = _dl_elf_hash (undef_name);
504 struct sym_val current_value = { NULL, NULL };
505 struct r_scope_elem **scope;
506 size_t i;
507 int protected;
509 ++_dl_num_relocations;
511 /* Search the relevant loaded objects for a definition. */
512 scope = symbol_scope;
513 for (i = 0; (*scope)->r_duplist[i] != skip_map; ++i)
514 assert (i < (*scope)->r_nduplist);
516 if (i >= (*scope)->r_nlist
517 || ! do_lookup_versioned (undef_name, hash, *ref, &current_value,
518 *scope, i, version, skip_map, 0, 0))
519 while (*++scope)
520 if (do_lookup_versioned (undef_name, hash, *ref, &current_value, *scope,
521 0, version, skip_map, 0, 0))
522 break;
524 if (__builtin_expect (current_value.s == NULL, 0))
526 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
528 /* We could find no value for a strong reference. */
529 const size_t len = strlen (undef_name);
530 char buf[sizeof undefined_msg + len];
531 __mempcpy (__mempcpy (buf, undefined_msg, sizeof undefined_msg - 1),
532 undef_name, len + 1);
533 /* XXX We cannot translate the messages. */
534 _dl_signal_cerror (0, (reference_name && reference_name[0]
535 ? reference_name
536 : (_dl_argv[0] ?: "<main program>")), buf);
538 *ref = NULL;
539 return 0;
542 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
544 if (__builtin_expect (_dl_debug_bindings, 0))
545 _dl_debug_message (1, "binding file ",
546 (reference_name && reference_name[0]
547 ? reference_name
548 : (_dl_argv[0] ?: "<main program>")),
549 " to ", current_value.m->l_name[0]
550 ? current_value.m->l_name : _dl_argv[0],
551 ": ", protected ? "protected" : "normal",
552 " symbol `", undef_name, "' [", version->name,
553 "]\n", NULL);
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 || !do_lookup_versioned (undef_name, hash, *ref, &protected_value,
568 *scope, i, version, skip_map, 0, 1))
569 while (*++scope)
570 if (do_lookup_versioned (undef_name, hash, *ref, &protected_value,
571 *scope, 0, version, skip_map, 0, 1))
572 break;
574 if (protected_value.s == NULL || protected_value.m == undef_map)
576 *ref = current_value.s;
577 return LOOKUP_VALUE (current_value.m);
580 return LOOKUP_VALUE (undef_map);
585 /* Cache the location of MAP's hash table. */
587 void
588 internal_function
589 _dl_setup_hash (struct link_map *map)
591 Elf_Symndx *hash;
592 Elf_Symndx nchain;
594 if (!map->l_info[DT_HASH])
595 return;
596 hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);
598 map->l_nbuckets = *hash++;
599 nchain = *hash++;
600 map->l_buckets = hash;
601 hash += map->l_nbuckets;
602 map->l_chain = hash;