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
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. */
78 #include "do-lookup.h"
81 #include "do-lookup.h"
84 /* Add extra dependency on MAP to UNDEF_MAP. */
87 add_dependency (struct link_map
*undef_map
, struct link_map
*map
)
89 struct link_map
**list
;
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
)
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
)
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
123 struct link_map
*runp
= _dl_loaded
;
125 while (runp
!= NULL
&& runp
!= map
)
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
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
;
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. */
162 /* Display information if we are debugging. */
163 if (__builtin_expect (_dl_debug_mask
& DL_DEBUG_FILES
, 0))
165 \nfile=%s; needed by %s (relocation dependency)\n\n",
166 map
->l_name
[0] ? map
->l_name
: _dl_argv
[0],
168 ? undef_map
->l_name
: _dl_argv
[0]);
171 /* Whoa, that was bad luck. We have to search again. */
176 /* Release the lock. */
177 __libc_lock_unlock (_dl_load_lock
);
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
);
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
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
;
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
, ¤t_value
, *scope
, 0, NULL
,
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
)
227 && undef_map
!= current_value
.m
228 /* Don't do this for explicit lookups as opposed to implicit
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
,
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]
248 : (_dl_argv
[0] ?: "<main program>")),
249 make_string (undefined_msg
, undef_name
));
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
);
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
,
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. */
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
;
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
, ¤t_value
, *scope
, i
,
320 if (_dl_do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, 0,
324 if (__builtin_expect (current_value
.s
== NULL
, 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
);
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
,
355 if (_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
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
374 XXX We'll see whether we need this separate 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
;
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
, ¤t_value
,
397 *scope
, 0, version
, NULL
, noexec
, noplt
);
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
)
407 && undef_map
!= current_value
.m
408 /* Don't do this for explicit lookups as opposed to implicit
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
,
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]
429 : (_dl_argv
[0] ?: "<main program>")),
430 make_string ("symbol ", undef_name
, ", version ",
432 " not defined in file ",
434 " with link time reference",
436 ? " (no version symbols)" : ""));
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]
449 : (_dl_argv
[0] ?: "<main program>")),
450 make_string (undefined_msg
, undef_name
,
451 ", version ", version
->name
?: NULL
));
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
);
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))
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. */
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
;
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
, ¤t_value
,
520 *scope
, i
, version
, skip_map
, 0, 0))
522 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
523 *scope
, 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_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
);
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
,
571 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
572 &protected_value
, *scope
, 0, version
,
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
;
607 /* These are here so that we only inline do_lookup{,_versioned} in the common
608 case, not everywhere. */
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
,
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
);