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
27 #include <dl-machine.h>
28 #include <bits/libc-lock.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: ";
45 #define make_string(string, rest...) \
47 const char *all[] = { string, ## rest }; \
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]); \
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. */
70 #include "do-lookup.h"
73 #include "do-lookup.h"
76 /* Add extra dependency on MAP to UNDEF_MAP. */
79 add_dependency (struct link_map
*undef_map
, struct link_map
*map
)
81 struct link_map
**list
;
82 struct link_map
*runp
;
87 /* Avoid self-references. */
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
)
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
)
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
120 while (runp
!= NULL
&& runp
!= map
)
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
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
;
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
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. */
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))
167 \nfile=%s; needed by %s (relocation dependency)\n\n",
168 map
->l_name
[0] ? map
->l_name
: _dl_argv
[0],
170 ? undef_map
->l_name
: _dl_argv
[0]);
173 /* Whoa, that was bad luck. We have to search again. */
177 /* Release the lock. */
178 __libc_lock_unlock_recursive (_dl_load_lock
);
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
);
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
);
198 /* Search loaded objects' symbol tables for a definition of the symbol
203 _dl_lookup_symbol (const char *undef_name
, struct link_map
*undef_map
,
204 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
205 int type_class
, int explicit)
207 unsigned long int hash
= _dl_elf_hash (undef_name
);
208 struct sym_val current_value
= { NULL
, NULL
};
209 struct r_scope_elem
**scope
;
212 ++_dl_num_relocations
;
214 /* Search the relevant loaded objects for a definition. */
215 for (scope
= symbol_scope
; *scope
; ++scope
)
216 if (do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, 0, NULL
,
219 /* We have to check whether this would bind UNDEF_MAP to an object
220 in the global scope which was dynamically loaded. In this case
221 we have to prevent the latter from being unloaded unless the
222 UNDEF_MAP object is also unloaded. */
223 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
224 /* Don't do this for explicit lookups as opposed to implicit
227 /* Add UNDEF_MAP to the dependencies. */
228 && add_dependency (undef_map
, current_value
.m
) < 0)
229 /* Something went wrong. Perhaps the object we tried to reference
230 was just removed. Try finding another definition. */
231 return _dl_lookup_symbol (undef_name
, undef_map
, ref
, symbol_scope
,
237 if (__builtin_expect (current_value
.s
== NULL
, 0))
239 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
241 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
242 /* We could find no value for a strong reference. */
243 /* XXX We cannot translate the messages. */
244 _dl_signal_cerror (0, (reference_name
&& reference_name
[0]
246 : (_dl_argv
[0] ?: "<main program>")),
247 N_("relocation error"),
248 make_string (undefined_msg
, undef_name
));
253 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
255 if (__builtin_expect (_dl_debug_mask
& DL_DEBUG_BINDINGS
, 0))
257 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
259 _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n",
260 (reference_name
&& reference_name
[0]
261 ? reference_name
: (_dl_argv
[0] ?: "<main program>")),
262 current_value
.m
->l_name
[0]
263 ? current_value
.m
->l_name
: _dl_argv
[0],
264 protected ? "protected" : "normal", undef_name
);
267 if (__builtin_expect (protected == 0, 1))
269 *ref
= current_value
.s
;
270 return LOOKUP_VALUE (current_value
.m
);
274 /* It is very tricky. We need to figure out what value to
275 return for the protected symbol */
276 struct sym_val protected_value
= { NULL
, NULL
};
278 for (scope
= symbol_scope
; *scope
; ++scope
)
279 if (_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
280 0, NULL
, ELF_RTYPE_CLASS_PLT
))
283 if (protected_value
.s
== NULL
|| protected_value
.m
== undef_map
)
285 *ref
= current_value
.s
;
286 return LOOKUP_VALUE (current_value
.m
);
289 return LOOKUP_VALUE (undef_map
);
294 /* This function is nearly the same as `_dl_lookup_symbol' but it
295 skips in the first list all objects until SKIP_MAP is found. I.e.,
296 it only considers objects which were loaded after the described
297 object. If there are more search lists the object described by
298 SKIP_MAP is only skipped. */
301 _dl_lookup_symbol_skip (const char *undef_name
,
302 struct link_map
*undef_map
, const ElfW(Sym
) **ref
,
303 struct r_scope_elem
*symbol_scope
[],
304 struct link_map
*skip_map
)
306 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
307 const unsigned long int hash
= _dl_elf_hash (undef_name
);
308 struct sym_val current_value
= { NULL
, NULL
};
309 struct r_scope_elem
**scope
;
313 ++_dl_num_relocations
;
315 /* Search the relevant loaded objects for a definition. */
316 scope
= symbol_scope
;
317 for (i
= 0; (*scope
)->r_list
[i
] != skip_map
; ++i
)
318 assert (i
< (*scope
)->r_nlist
);
320 if (! _dl_do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, i
,
323 if (_dl_do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, 0,
327 if (__builtin_expect (current_value
.s
== NULL
, 0))
333 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
335 if (__builtin_expect (_dl_debug_mask
& DL_DEBUG_BINDINGS
, 0))
336 _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n",
337 (reference_name
&& reference_name
[0]
338 ? reference_name
: (_dl_argv
[0] ?: "<main program>")),
339 current_value
.m
->l_name
[0]
340 ? current_value
.m
->l_name
: _dl_argv
[0],
341 protected ? "protected" : "normal", undef_name
);
343 if (__builtin_expect (protected == 0, 1))
345 *ref
= current_value
.s
;
346 return LOOKUP_VALUE (current_value
.m
);
350 /* It is very tricky. We need to figure out what value to
351 return for the protected symbol. */
352 struct sym_val protected_value
= { NULL
, NULL
};
354 if (i
>= (*scope
)->r_nlist
355 || !_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
356 i
, skip_map
, ELF_RTYPE_CLASS_PLT
))
358 if (_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
359 0, skip_map
, ELF_RTYPE_CLASS_PLT
))
362 if (protected_value
.s
== NULL
|| protected_value
.m
== undef_map
)
364 *ref
= current_value
.s
;
365 return LOOKUP_VALUE (current_value
.m
);
368 return LOOKUP_VALUE (undef_map
);
373 /* This function works like _dl_lookup_symbol but it takes an
374 additional arguement with the version number of the requested
377 XXX We'll see whether we need this separate function. */
380 _dl_lookup_versioned_symbol (const char *undef_name
,
381 struct link_map
*undef_map
, const ElfW(Sym
) **ref
,
382 struct r_scope_elem
*symbol_scope
[],
383 const struct r_found_version
*version
,
384 int type_class
, int explicit)
386 unsigned long int hash
= _dl_elf_hash (undef_name
);
387 struct sym_val current_value
= { NULL
, NULL
};
388 struct r_scope_elem
**scope
;
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
, type_class
);
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_type
== lt_loaded
, 0)
405 /* Don't do this for explicit lookups as opposed to implicit
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 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
425 /* XXX We cannot translate the message. */
426 _dl_signal_cerror (0, (reference_name
&& reference_name
[0]
428 : (_dl_argv
[0] ?: "<main program>")),
429 N_("relocation error"),
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
)
446 /* We could find no value for a strong reference. */
447 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
449 /* XXX We cannot translate the message. */
450 _dl_signal_cerror (0, (reference_name
&& reference_name
[0]
452 : (_dl_argv
[0] ?: "<main program>")), NULL
,
453 make_string (undefined_msg
, undef_name
,
455 version
->name
?: NULL
));
461 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
463 if (__builtin_expect (_dl_debug_mask
& DL_DEBUG_BINDINGS
, 0))
465 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
467 _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n",
468 (reference_name
&& reference_name
[0]
469 ? reference_name
: (_dl_argv
[0] ?: "<main program>")),
470 current_value
.m
->l_name
[0]
471 ? current_value
.m
->l_name
: _dl_argv
[0],
472 protected ? "protected" : "normal",
473 undef_name
, version
->name
);
476 if (__builtin_expect (protected == 0, 1))
478 *ref
= current_value
.s
;
479 return LOOKUP_VALUE (current_value
.m
);
483 /* It is very tricky. We need to figure out what value to
484 return for the protected symbol */
485 struct sym_val protected_value
= { NULL
, NULL
};
487 for (scope
= symbol_scope
; *scope
; ++scope
)
488 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
, &protected_value
,
489 *scope
, 0, version
, NULL
,
490 ELF_RTYPE_CLASS_PLT
))
493 if (protected_value
.s
== NULL
|| protected_value
.m
== undef_map
)
495 *ref
= current_value
.s
;
496 return LOOKUP_VALUE (current_value
.m
);
499 return LOOKUP_VALUE (undef_map
);
504 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
505 with the version we are looking for. */
508 _dl_lookup_versioned_symbol_skip (const char *undef_name
,
509 struct link_map
*undef_map
,
510 const ElfW(Sym
) **ref
,
511 struct r_scope_elem
*symbol_scope
[],
512 const struct r_found_version
*version
,
513 struct link_map
*skip_map
)
515 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
516 const unsigned long int hash
= _dl_elf_hash (undef_name
);
517 struct sym_val current_value
= { NULL
, NULL
};
518 struct r_scope_elem
**scope
;
522 ++_dl_num_relocations
;
524 /* Search the relevant loaded objects for a definition. */
525 scope
= symbol_scope
;
526 for (i
= 0; (*scope
)->r_list
[i
] != skip_map
; ++i
)
527 assert (i
< (*scope
)->r_nlist
);
529 if (! _dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
530 *scope
, i
, version
, skip_map
, 0))
532 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
533 *scope
, 0, version
, skip_map
, 0))
536 if (__builtin_expect (current_value
.s
== NULL
, 0))
538 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
540 /* We could find no value for a strong reference. */
541 const size_t len
= strlen (undef_name
);
542 char buf
[sizeof undefined_msg
+ len
];
543 __mempcpy (__mempcpy (buf
, undefined_msg
, sizeof undefined_msg
- 1),
544 undef_name
, len
+ 1);
545 /* XXX We cannot translate the messages. */
546 _dl_signal_cerror (0, (reference_name
&& reference_name
[0]
548 : (_dl_argv
[0] ?: "<main program>")),
555 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
557 if (__builtin_expect (_dl_debug_mask
& DL_DEBUG_BINDINGS
, 0))
558 _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n",
559 (reference_name
&& reference_name
[0]
560 ? reference_name
: (_dl_argv
[0] ?: "<main program>")),
561 current_value
.m
->l_name
[0]
562 ? current_value
.m
->l_name
: _dl_argv
[0],
563 protected ? "protected" : "normal",
564 undef_name
, version
->name
);
566 if (__builtin_expect (protected == 0, 1))
568 *ref
= current_value
.s
;
569 return LOOKUP_VALUE (current_value
.m
);
573 /* It is very tricky. We need to figure out what value to
574 return for the protected symbol */
575 struct sym_val protected_value
= { NULL
, NULL
};
577 if (i
>= (*scope
)->r_nlist
578 || !_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
579 &protected_value
, *scope
, i
, version
,
580 skip_map
, ELF_RTYPE_CLASS_PLT
))
582 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
583 &protected_value
, *scope
, 0, version
,
584 skip_map
, ELF_RTYPE_CLASS_PLT
))
587 if (protected_value
.s
== NULL
|| protected_value
.m
== undef_map
)
589 *ref
= current_value
.s
;
590 return LOOKUP_VALUE (current_value
.m
);
593 return LOOKUP_VALUE (undef_map
);
598 /* Cache the location of MAP's hash table. */
602 _dl_setup_hash (struct link_map
*map
)
607 if (!map
->l_info
[DT_HASH
])
609 hash
= (void *)(map
->l_addr
+ map
->l_info
[DT_HASH
]->d_un
.d_ptr
);
611 map
->l_nbuckets
= *hash
++;
613 map
->l_buckets
= hash
;
614 hash
+= map
->l_nbuckets
;
618 /* These are here so that we only inline do_lookup{,_versioned} in the common
619 case, not everywhere. */
622 _dl_do_lookup (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 struct link_map
*skip
, int type_class
)
627 return do_lookup (undef_name
, hash
, ref
, result
, scope
, i
, skip
,
633 _dl_do_lookup_versioned (const char *undef_name
, unsigned long int hash
,
634 const ElfW(Sym
) *ref
, struct sym_val
*result
,
635 struct r_scope_elem
*scope
, size_t i
,
636 const struct r_found_version
*const version
,
637 struct link_map
*skip
, int type_class
)
639 return do_lookup_versioned (undef_name
, hash
, ref
, result
, scope
, i
,
640 version
, skip
, type_class
);