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. */
26 #include <dl-machine.h>
27 #include <bits/libc-lock.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: ";
44 #define make_string(string, rest...) \
46 const char *all[] = { string, ## rest }; \
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]); \
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. */
79 #include "do-lookup.h"
83 #include "do-lookup.h"
86 /* Add extra dependency on MAP to UNDEF_MAP. */
88 add_dependency (struct link_map *undef_map, struct link_map *map)
90 struct link_map **list;
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)
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)
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
125 struct link_map *runp = _dl_loaded;
127 while (runp != NULL && runp != map)
134 /* The object is still available. Add the reference now. */
135 if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
137 /* Allocate more memory for the dependency list. Since
138 this can never happen during the startup phase we can
142 undef_map->l_reldepsmax += 5;
143 newp = realloc (undef_map->l_reldeps,
144 undef_map->l_reldepsmax
145 * sizeof(struct link_map *));
147 if (__builtin_expect (newp != NULL, 1))
148 undef_map->l_reldeps = (struct link_map **) newp;
150 /* Correct the addition. */
151 undef_map->l_reldepsmax -= 5;
154 /* If we didn't manage to allocate memory for the list this
155 is no fatal mistake. We simply increment the use counter
156 of the referenced object and don't record the dependencies.
157 This means this increment can never be reverted and the
158 object will never be unloaded. This is semantically the
159 correct behaviour. */
160 if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
161 undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
163 /* And increment the counter in the referenced object. */
166 /* Display information if we are debugging. */
167 if (__builtin_expect (_dl_debug_files, 0))
168 _dl_debug_message (1, "\nfile=",
169 map->l_name[0] ? map->l_name : _dl_argv[0],
172 ? undef_map->l_name : _dl_argv[0],
173 " (relocation dependency)\n\n", NULL);
176 /* Whoa, that was bad luck. We have to search again. */
181 /* Release the lock. */
182 __libc_lock_unlock (_dl_load_lock);
188 /* Search loaded objects' symbol tables for a definition of the symbol
193 _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
194 const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
195 int reloc_type, int explicit)
197 const char *reference_name = undef_map ? undef_map->l_name : NULL;
198 const unsigned long int hash = _dl_elf_hash (undef_name);
199 struct sym_val current_value = { NULL, NULL };
200 struct r_scope_elem **scope;
202 int noexec = elf_machine_lookup_noexec_p (reloc_type);
203 int noplt = elf_machine_lookup_noplt_p (reloc_type);
205 ++_dl_num_relocations;
207 /* Search the relevant loaded objects for a definition. */
208 for (scope = symbol_scope; *scope; ++scope)
209 if (do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, NULL,
212 /* We have to check whether this would bind UNDEF_MAP to an object
213 in the global scope which was dynamically loaded. In this case
214 we have to prevent the latter from being unloaded unless the
215 UNDEF_MAP object is also unloaded. */
216 if (__builtin_expect (current_value.m->l_global, 0)
217 && (__builtin_expect (current_value.m->l_type, lt_library)
219 && undef_map != current_value.m
220 /* Don't do this for explicit lookups as opposed to implicit
222 && __builtin_expect (! explicit, 1)
223 /* Add UNDEF_MAP to the dependencies. */
224 && add_dependency (undef_map, current_value.m) < 0)
225 /* Something went wrong. Perhaps the object we tried to reference
226 was just removed. Try finding another definition. */
227 return _dl_lookup_symbol (undef_name, undef_map, ref, symbol_scope,
233 if (__builtin_expect (current_value.s == NULL, 0))
235 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
236 /* We could find no value for a strong reference. */
237 /* XXX We cannot translate the messages. */
238 _dl_signal_cerror (0, (reference_name && reference_name[0]
240 : (_dl_argv[0] ?: "<main program>")),
241 make_string (undefined_msg, undef_name));
246 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
248 if (__builtin_expect (_dl_debug_bindings, 0))
249 _dl_debug_message (1, "binding file ",
250 (reference_name && reference_name[0]
252 : (_dl_argv[0] ?: "<main program>")),
253 " to ", current_value.m->l_name[0]
254 ? current_value.m->l_name : _dl_argv[0],
255 ": ", protected ? "protected" : "normal",
256 " symbol `", undef_name, "'\n", NULL);
258 if (__builtin_expect (protected == 0, 1))
260 *ref = current_value.s;
261 return LOOKUP_VALUE (current_value.m);
265 /* It is very tricky. We need to figure out what value to
266 return for the protected symbol */
267 struct sym_val protected_value = { NULL, NULL };
269 for (scope = symbol_scope; *scope; ++scope)
270 if (do_lookup (undef_name, hash, *ref, &protected_value, *scope, 0,
274 if (protected_value.s == NULL || protected_value.m == undef_map)
276 *ref = current_value.s;
277 return LOOKUP_VALUE (current_value.m);
280 return LOOKUP_VALUE (undef_map);
285 /* This function is nearly the same as `_dl_lookup_symbol' but it
286 skips in the first list all objects until SKIP_MAP is found. I.e.,
287 it only considers objects which were loaded after the described
288 object. If there are more search lists the object described by
289 SKIP_MAP is only skipped. */
292 _dl_lookup_symbol_skip (const char *undef_name,
293 struct link_map *undef_map, const ElfW(Sym) **ref,
294 struct r_scope_elem *symbol_scope[],
295 struct link_map *skip_map)
297 const char *reference_name = undef_map ? undef_map->l_name : NULL;
298 const unsigned long int hash = _dl_elf_hash (undef_name);
299 struct sym_val current_value = { NULL, NULL };
300 struct r_scope_elem **scope;
304 ++_dl_num_relocations;
306 /* Search the relevant loaded objects for a definition. */
307 scope = symbol_scope;
308 for (i = 0; (*scope)->r_duplist[i] != skip_map; ++i)
309 assert (i < (*scope)->r_nduplist);
311 if (i >= (*scope)->r_nlist
312 || ! do_lookup (undef_name, hash, *ref, ¤t_value, *scope, i,
315 if (do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0,
319 if (__builtin_expect (current_value.s == NULL, 0))
325 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
327 if (__builtin_expect (_dl_debug_bindings, 0))
328 _dl_debug_message (1, "binding file ",
329 (reference_name && reference_name[0]
331 : (_dl_argv[0] ?: "<main program>")),
332 " to ", current_value.m->l_name[0]
333 ? current_value.m->l_name : _dl_argv[0],
334 ": ", protected ? "protected" : "normal",
335 " symbol `", undef_name, "'\n", NULL);
337 if (__builtin_expect (protected == 0, 1))
339 *ref = current_value.s;
340 return LOOKUP_VALUE (current_value.m);
344 /* It is very tricky. We need to figure out what value to
345 return for the protected symbol. */
346 struct sym_val protected_value = { NULL, NULL };
348 if (i >= (*scope)->r_nlist
349 || !do_lookup (undef_name, hash, *ref, &protected_value, *scope, i,
352 if (do_lookup (undef_name, hash, *ref, &protected_value, *scope, 0,
356 if (protected_value.s == NULL || protected_value.m == undef_map)
358 *ref = current_value.s;
359 return LOOKUP_VALUE (current_value.m);
362 return LOOKUP_VALUE (undef_map);
367 /* This function works like _dl_lookup_symbol but it takes an
368 additional arguement with the version number of the requested
371 XXX We'll see whether we need this separate function. */
374 _dl_lookup_versioned_symbol (const char *undef_name,
375 struct link_map *undef_map, const ElfW(Sym) **ref,
376 struct r_scope_elem *symbol_scope[],
377 const struct r_found_version *version,
378 int reloc_type, int explicit)
380 const char *reference_name = undef_map ? undef_map->l_name : NULL;
381 const unsigned long int hash = _dl_elf_hash (undef_name);
382 struct sym_val current_value = { NULL, NULL };
383 struct r_scope_elem **scope;
385 int noexec = elf_machine_lookup_noexec_p (reloc_type);
386 int noplt = elf_machine_lookup_noplt_p (reloc_type);
388 ++_dl_num_relocations;
390 /* Search the relevant loaded objects for a definition. */
391 for (scope = symbol_scope; *scope; ++scope)
393 int res = do_lookup_versioned (undef_name, hash, *ref, ¤t_value,
394 *scope, 0, version, NULL, noexec, noplt);
397 /* We have to check whether this would bind UNDEF_MAP to an object
398 in the global scope which was dynamically loaded. In this case
399 we have to prevent the latter from being unloaded unless the
400 UNDEF_MAP object is also unloaded. */
401 if (__builtin_expect (current_value.m->l_global, 0)
402 && (__builtin_expect (current_value.m->l_type, lt_library)
404 && undef_map != current_value.m
405 /* Don't do this for explicit lookups as opposed to implicit
407 && __builtin_expect (! explicit, 1)
408 /* Add UNDEF_MAP to the dependencies. */
409 && add_dependency (undef_map, current_value.m) < 0)
410 /* Something went wrong. Perhaps the object we tried to reference
411 was just removed. Try finding another definition. */
412 return _dl_lookup_versioned_symbol (undef_name, undef_map, ref,
413 symbol_scope, version,
419 if (__builtin_expect (res, 0) < 0)
421 /* Oh, oh. The file named in the relocation entry does not
422 contain the needed symbol. */
423 /* XXX We cannot translate the message. */
424 _dl_signal_cerror (0, (reference_name && reference_name[0]
426 : (_dl_argv[0] ?: "<main program>")),
427 make_string ("symbol ", undef_name, ", version ",
429 " not defined in file ",
431 " with link time reference",
433 ? " (no version symbols)" : ""));
439 if (__builtin_expect (current_value.s == NULL, 0))
441 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
442 /* We could find no value for a strong reference. */
443 /* XXX We cannot translate the message. */
444 _dl_signal_cerror (0, (reference_name && reference_name[0]
446 : (_dl_argv[0] ?: "<main program>")),
447 make_string (undefined_msg, undef_name,
448 ", version ", version->name ?: NULL));
453 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
455 if (__builtin_expect (_dl_debug_bindings, 0))
456 _dl_debug_message (1, "binding file ",
457 (reference_name && reference_name[0]
459 : (_dl_argv[0] ?: "<main program>")),
460 " to ", current_value.m->l_name[0]
461 ? current_value.m->l_name : _dl_argv[0],
462 ": ", protected ? "protected" : "normal",
463 " symbol `", undef_name, "' [", version->name,
466 if (__builtin_expect (protected == 0, 1))
468 *ref = current_value.s;
469 return LOOKUP_VALUE (current_value.m);
473 /* It is very tricky. We need to figure out what value to
474 return for the protected symbol */
475 struct sym_val protected_value = { NULL, NULL };
477 for (scope = symbol_scope; *scope; ++scope)
478 if (do_lookup_versioned (undef_name, hash, *ref, &protected_value,
479 *scope, 0, version, NULL, 0, 1))
482 if (protected_value.s == NULL || protected_value.m == undef_map)
484 *ref = current_value.s;
485 return LOOKUP_VALUE (current_value.m);
488 return LOOKUP_VALUE (undef_map);
493 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
494 with the version we are looking for. */
497 _dl_lookup_versioned_symbol_skip (const char *undef_name,
498 struct link_map *undef_map,
499 const ElfW(Sym) **ref,
500 struct r_scope_elem *symbol_scope[],
501 const struct r_found_version *version,
502 struct link_map *skip_map)
504 const char *reference_name = undef_map ? undef_map->l_name : NULL;
505 const unsigned long int hash = _dl_elf_hash (undef_name);
506 struct sym_val current_value = { NULL, NULL };
507 struct r_scope_elem **scope;
511 ++_dl_num_relocations;
513 /* Search the relevant loaded objects for a definition. */
514 scope = symbol_scope;
515 for (i = 0; (*scope)->r_duplist[i] != skip_map; ++i)
516 assert (i < (*scope)->r_nduplist);
518 if (i >= (*scope)->r_nlist
519 || ! do_lookup_versioned (undef_name, hash, *ref, ¤t_value,
520 *scope, i, version, skip_map, 0, 0))
522 if (do_lookup_versioned (undef_name, hash, *ref, ¤t_value, *scope,
523 0, version, skip_map, 0, 0))
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]
538 : (_dl_argv[0] ?: "<main program>")), buf);
544 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
546 if (__builtin_expect (_dl_debug_bindings, 0))
547 _dl_debug_message (1, "binding file ",
548 (reference_name && reference_name[0]
550 : (_dl_argv[0] ?: "<main program>")),
551 " to ", current_value.m->l_name[0]
552 ? current_value.m->l_name : _dl_argv[0],
553 ": ", protected ? "protected" : "normal",
554 " symbol `", undef_name, "' [", version->name,
557 if (__builtin_expect (protected == 0, 1))
559 *ref = current_value.s;
560 return LOOKUP_VALUE (current_value.m);
564 /* It is very tricky. We need to figure out what value to
565 return for the protected symbol */
566 struct sym_val protected_value = { NULL, NULL };
568 if (i >= (*scope)->r_nlist
569 || !do_lookup_versioned (undef_name, hash, *ref, &protected_value,
570 *scope, i, version, skip_map, 0, 1))
572 if (do_lookup_versioned (undef_name, hash, *ref, &protected_value,
573 *scope, 0, version, skip_map, 0, 1))
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. */
591 _dl_setup_hash (struct link_map *map)
596 if (!map->l_info[DT_HASH])
598 hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);
600 map->l_nbuckets = *hash++;
602 map->l_buckets = hash;
603 hash += map->l_nbuckets;