1 /* Look up a symbol in the loaded objects.
2 Copyright (C) 1995,96,97,98,99,2000,2001,2002 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. */
64 # define bump_num_relocations() ++GL(dl_num_relocations)
66 # define bump_num_relocations() ((void) 0)
71 /* We have two different situations when looking up a simple: with or
72 without versioning. gcc is not able to optimize a single function
73 definition serving for both purposes so we define two functions. */
75 #include "do-lookup.h"
78 #include "do-lookup.h"
81 /* Add extra dependency on MAP to UNDEF_MAP. */
84 add_dependency (struct link_map
*undef_map
, struct link_map
*map
)
86 struct link_map
**list
;
87 struct link_map
*runp
;
92 /* Avoid self-references. */
96 /* Make sure nobody can unload the object while we are at it. */
97 __libc_lock_lock_recursive (GL(dl_load_lock
));
99 /* Determine whether UNDEF_MAP already has a reference to MAP. First
100 look in the normal dependencies. */
101 if (undef_map
->l_searchlist
.r_list
!= NULL
)
103 list
= undef_map
->l_initfini
;
105 for (i
= 0; list
[i
] != NULL
; ++i
)
110 /* No normal dependency. See whether we already had to add it
111 to the special list of dynamic dependencies. */
112 list
= undef_map
->l_reldeps
;
113 act
= undef_map
->l_reldepsact
;
115 for (i
= 0; i
< act
; ++i
)
119 /* The object is not yet in the dependency list. Before we add
120 it make sure just one more time the object we are about to
121 reference is still available. There is a brief period in
122 which the object could have been removed since we found the
124 runp
= GL(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 this
134 can never happen during the startup phase we can use
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 is
151 no fatal mistake. We simply increment the use counter of the
152 referenced object and don't record the dependencies. This
153 means this increment can never be reverted and the object
154 will never be unloaded. This is semantically the correct
156 if (__builtin_expect (act
< undef_map
->l_reldepsmax
, 1))
157 undef_map
->l_reldeps
[undef_map
->l_reldepsact
++] = map
;
159 if (map
->l_searchlist
.r_list
!= NULL
)
160 /* And increment the counter in the referenced object. */
163 /* We have to bump the counts for all dependencies since so far
164 this object was only a normal or transitive dependency.
165 Now it might be closed with _dl_close() directly. */
166 for (list
= map
->l_initfini
; *list
!= NULL
; ++list
)
167 ++(*list
)->l_opencount
;
169 /* Display information if we are debugging. */
170 if (__builtin_expect (GL(dl_debug_mask
) & DL_DEBUG_FILES
, 0))
171 INTUSE(_dl_debug_printf
) ("\
172 \nfile=%s; needed by %s (relocation dependency)\n\n",
173 map
->l_name
[0] ? map
->l_name
: _dl_argv
[0],
175 ? undef_map
->l_name
: _dl_argv
[0]);
178 /* Whoa, that was bad luck. We have to search again. */
182 /* Release the lock. */
183 __libc_lock_unlock_recursive (GL(dl_load_lock
));
190 _dl_do_lookup (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 struct link_map
*skip
, int type_class
);
196 _dl_do_lookup_versioned (const char *undef_name
, unsigned long int hash
,
197 const ElfW(Sym
) *ref
, struct sym_val
*result
,
198 struct r_scope_elem
*scope
, size_t i
,
199 const struct r_found_version
*const version
,
200 struct link_map
*skip
, int type_class
);
204 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
205 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
206 struct sym_val
*value
,
207 const struct r_found_version
*version
, int type_class
,
210 /* Search loaded objects' symbol tables for a definition of the symbol
215 _dl_lookup_symbol (const char *undef_name
, struct link_map
*undef_map
,
216 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
217 int type_class
, int explicit)
219 const unsigned long int hash
= _dl_elf_hash (undef_name
);
220 struct sym_val current_value
= { NULL
, NULL
};
221 struct r_scope_elem
**scope
;
224 bump_num_relocations ();
226 /* Search the relevant loaded objects for a definition. */
227 for (scope
= symbol_scope
; *scope
; ++scope
)
228 if (do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, 0, NULL
,
231 /* We have to check whether this would bind UNDEF_MAP to an object
232 in the global scope which was dynamically loaded. In this case
233 we have to prevent the latter from being unloaded unless the
234 UNDEF_MAP object is also unloaded. */
235 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
236 /* Don't do this for explicit lookups as opposed to implicit
239 /* Add UNDEF_MAP to the dependencies. */
240 && add_dependency (undef_map
, current_value
.m
) < 0)
241 /* Something went wrong. Perhaps the object we tried to reference
242 was just removed. Try finding another definition. */
243 return INTUSE(_dl_lookup_symbol
) (undef_name
, undef_map
, ref
,
244 symbol_scope
, type_class
, 0);
249 if (__builtin_expect (current_value
.s
== NULL
, 0))
251 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
253 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
254 /* We could find no value for a strong reference. */
255 /* XXX We cannot translate the messages. */
256 _dl_signal_cerror (0, (reference_name
[0]
258 : (_dl_argv
[0] ?: "<main program>")),
259 N_("relocation error"),
260 make_string (undefined_msg
, undef_name
));
265 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
266 if (__builtin_expect (protected != 0, 0))
268 /* It is very tricky. We need to figure out what value to
269 return for the protected symbol */
270 struct sym_val protected_value
= { NULL
, NULL
};
272 for (scope
= symbol_scope
; *scope
; ++scope
)
273 if (_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
274 0, NULL
, ELF_RTYPE_CLASS_PLT
))
277 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
279 current_value
.s
= *ref
;
280 current_value
.m
= undef_map
;
284 if (__builtin_expect (GL(dl_debug_mask
)
285 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
286 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
287 ¤t_value
, NULL
, type_class
, protected);
289 *ref
= current_value
.s
;
290 return LOOKUP_VALUE (current_value
.m
);
292 INTDEF (_dl_lookup_symbol
)
295 /* This function is nearly the same as `_dl_lookup_symbol' but it
296 skips in the first list all objects until SKIP_MAP is found. I.e.,
297 it only considers objects which were loaded after the described
298 object. If there are more search lists the object described by
299 SKIP_MAP is only skipped. */
302 _dl_lookup_symbol_skip (const char *undef_name
,
303 struct link_map
*undef_map
, const ElfW(Sym
) **ref
,
304 struct r_scope_elem
*symbol_scope
[],
305 struct link_map
*skip_map
)
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 bump_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 (protected != 0, 0))
337 /* It is very tricky. We need to figure out what value to
338 return for the protected symbol. */
339 struct sym_val protected_value
= { NULL
, NULL
};
341 if (i
>= (*scope
)->r_nlist
342 || !_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
343 i
, skip_map
, ELF_RTYPE_CLASS_PLT
))
345 if (_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
346 0, skip_map
, ELF_RTYPE_CLASS_PLT
))
349 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
351 current_value
.s
= *ref
;
352 current_value
.m
= undef_map
;
356 if (__builtin_expect (GL(dl_debug_mask
)
357 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
358 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
359 ¤t_value
, NULL
, 0, protected);
361 *ref
= current_value
.s
;
362 return LOOKUP_VALUE (current_value
.m
);
366 /* This function works like _dl_lookup_symbol but it takes an
367 additional arguement with the version number of the requested
370 XXX We'll see whether we need this separate function. */
373 _dl_lookup_versioned_symbol (const char *undef_name
,
374 struct link_map
*undef_map
, const ElfW(Sym
) **ref
,
375 struct r_scope_elem
*symbol_scope
[],
376 const struct r_found_version
*version
,
377 int type_class
, int explicit)
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
;
384 bump_num_relocations ();
386 /* Search the relevant loaded objects for a definition. */
387 for (scope
= symbol_scope
; *scope
; ++scope
)
389 int res
= do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
390 *scope
, 0, version
, NULL
, type_class
);
393 /* We have to check whether this would bind UNDEF_MAP to an object
394 in the global scope which was dynamically loaded. In this case
395 we have to prevent the latter from being unloaded unless the
396 UNDEF_MAP object is also unloaded. */
397 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
398 /* Don't do this for explicit lookups as opposed to implicit
401 /* Add UNDEF_MAP to the dependencies. */
402 && add_dependency (undef_map
, current_value
.m
) < 0)
403 /* Something went wrong. Perhaps the object we tried to reference
404 was just removed. Try finding another definition. */
405 return INTUSE(_dl_lookup_versioned_symbol
) (undef_name
, undef_map
,
407 version
, type_class
, 0);
412 if (__builtin_expect (res
, 0) < 0)
414 /* Oh, oh. The file named in the relocation entry does not
415 contain the needed symbol. */
416 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
418 /* XXX We cannot translate the message. */
419 _dl_signal_cerror (0, (reference_name
[0]
421 : (_dl_argv
[0] ?: "<main program>")),
422 N_("relocation error"),
423 make_string ("symbol ", undef_name
, ", version ",
425 " not defined in file ",
427 " with link time reference",
429 ? " (no version symbols)" : ""));
435 if (__builtin_expect (current_value
.s
== NULL
, 0))
437 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
439 /* We could find no value for a strong reference. */
440 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
442 /* XXX We cannot translate the message. */
443 _dl_signal_cerror (0, (reference_name
[0]
445 : (_dl_argv
[0] ?: "<main program>")), NULL
,
446 make_string (undefined_msg
, undef_name
,
448 version
->name
?: NULL
));
454 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
456 if (__builtin_expect (protected != 0, 0))
458 /* It is very tricky. We need to figure out what value to
459 return for the protected symbol */
460 struct sym_val protected_value
= { NULL
, NULL
};
462 for (scope
= symbol_scope
; *scope
; ++scope
)
463 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
, &protected_value
,
464 *scope
, 0, version
, NULL
,
465 ELF_RTYPE_CLASS_PLT
))
468 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
470 current_value
.s
= *ref
;
471 current_value
.m
= undef_map
;
475 if (__builtin_expect (GL(dl_debug_mask
)
476 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
477 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
478 ¤t_value
, version
, type_class
, protected);
480 *ref
= current_value
.s
;
481 return LOOKUP_VALUE (current_value
.m
);
483 INTDEF (_dl_lookup_versioned_symbol
)
486 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
487 with the version we are looking for. */
490 _dl_lookup_versioned_symbol_skip (const char *undef_name
,
491 struct link_map
*undef_map
,
492 const ElfW(Sym
) **ref
,
493 struct r_scope_elem
*symbol_scope
[],
494 const struct r_found_version
*version
,
495 struct link_map
*skip_map
)
497 const char *reference_name
= undef_map
->l_name
;
498 const unsigned long int hash
= _dl_elf_hash (undef_name
);
499 struct sym_val current_value
= { NULL
, NULL
};
500 struct r_scope_elem
**scope
;
504 bump_num_relocations ();
506 /* Search the relevant loaded objects for a definition. */
507 scope
= symbol_scope
;
508 for (i
= 0; (*scope
)->r_list
[i
] != skip_map
; ++i
)
509 assert (i
< (*scope
)->r_nlist
);
511 if (! _dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
512 *scope
, i
, version
, skip_map
, 0))
514 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
515 *scope
, 0, version
, skip_map
, 0))
518 if (__builtin_expect (current_value
.s
== NULL
, 0))
520 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
522 /* We could find no value for a strong reference. */
523 const size_t len
= strlen (undef_name
);
524 char buf
[sizeof undefined_msg
+ len
];
525 __mempcpy (__mempcpy (buf
, undefined_msg
, sizeof undefined_msg
- 1),
526 undef_name
, len
+ 1);
527 /* XXX We cannot translate the messages. */
528 _dl_signal_cerror (0, (reference_name
[0]
530 : (_dl_argv
[0] ?: "<main program>")),
537 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
539 if (__builtin_expect (protected != 0, 0))
541 /* It is very tricky. We need to figure out what value to
542 return for the protected symbol */
543 struct sym_val protected_value
= { NULL
, NULL
};
545 if (i
>= (*scope
)->r_nlist
546 || !_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
547 &protected_value
, *scope
, i
, version
,
548 skip_map
, ELF_RTYPE_CLASS_PLT
))
550 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
551 &protected_value
, *scope
, 0, version
,
552 skip_map
, ELF_RTYPE_CLASS_PLT
))
555 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
557 current_value
.s
= *ref
;
558 current_value
.m
= undef_map
;
562 if (__builtin_expect (GL(dl_debug_mask
)
563 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
564 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
565 ¤t_value
, version
, 0, protected);
567 *ref
= current_value
.s
;
568 return LOOKUP_VALUE (current_value
.m
);
572 /* Cache the location of MAP's hash table. */
576 _dl_setup_hash (struct link_map
*map
)
581 if (!map
->l_info
[DT_HASH
])
583 hash
= (void *)(map
->l_addr
+ map
->l_info
[DT_HASH
]->d_un
.d_ptr
);
585 map
->l_nbuckets
= *hash
++;
587 map
->l_buckets
= hash
;
588 hash
+= map
->l_nbuckets
;
594 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
595 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
596 struct sym_val
*value
, const struct r_found_version
*version
,
597 int type_class
, int protected)
599 const char *reference_name
= undef_map
->l_name
;
601 if (GL(dl_debug_mask
) & DL_DEBUG_BINDINGS
)
603 INTUSE(_dl_debug_printf
) ("binding file %s to %s: %s symbol `%s'",
606 : (_dl_argv
[0] ?: "<main program>")),
608 ? value
->m
->l_name
: _dl_argv
[0],
609 protected ? "protected" : "normal",
612 _dl_debug_printf_c (" [%s]\n", version
->name
);
614 _dl_debug_printf_c ("\n");
617 if (GL(dl_debug_mask
) & DL_DEBUG_PRELINK
)
620 struct sym_val val
= { NULL
, NULL
};
622 if ((GL(dl_trace_prelink_map
) == NULL
623 || GL(dl_trace_prelink_map
) == GL(dl_loaded
))
624 && undef_map
!= GL(dl_loaded
))
626 const unsigned long int hash
= _dl_elf_hash (undef_name
);
629 _dl_do_lookup (undef_name
, hash
, *ref
, &val
,
630 undef_map
->l_local_scope
[0], 0, NULL
, type_class
);
632 _dl_do_lookup_versioned (undef_name
, hash
, *ref
, &val
,
633 undef_map
->l_local_scope
[0], 0, version
,
636 if (val
.s
!= value
->s
|| val
.m
!= value
->m
)
641 || GL(dl_trace_prelink_map
) == undef_map
642 || GL(dl_trace_prelink_map
) == NULL
)
644 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
645 conflict
? "conflict" : "lookup",
646 (int) sizeof (ElfW(Addr
)) * 2, undef_map
->l_map_start
,
647 (int) sizeof (ElfW(Addr
)) * 2,
648 ((ElfW(Addr
)) *ref
) - undef_map
->l_map_start
,
649 (int) sizeof (ElfW(Addr
)) * 2,
650 (ElfW(Addr
)) (value
->s
? value
->m
->l_map_start
: 0),
651 (int) sizeof (ElfW(Addr
)) * 2,
652 (ElfW(Addr
)) (value
->s
? value
->s
->st_value
: 0));
655 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
656 (int) sizeof (ElfW(Addr
)) * 2,
657 (ElfW(Addr
)) (val
.s
? val
.m
->l_map_start
: 0),
658 (int) sizeof (ElfW(Addr
)) * 2,
659 (ElfW(Addr
)) (val
.s
? val
.s
->st_value
: 0));
661 _dl_printf ("/%x %s\n", type_class
, undef_name
);
667 /* These are here so that we only inline do_lookup{,_versioned} in the common
668 case, not everywhere. */
669 static int __attribute_noinline__
671 _dl_do_lookup (const char *undef_name
, unsigned long int hash
,
672 const ElfW(Sym
) *ref
, struct sym_val
*result
,
673 struct r_scope_elem
*scope
, size_t i
,
674 struct link_map
*skip
, int type_class
)
676 return do_lookup (undef_name
, hash
, ref
, result
, scope
, i
, skip
,
680 static int __attribute_noinline__
682 _dl_do_lookup_versioned (const char *undef_name
, unsigned long int hash
,
683 const ElfW(Sym
) *ref
, struct sym_val
*result
,
684 struct r_scope_elem
*scope
, size_t i
,
685 const struct r_found_version
*const version
,
686 struct link_map
*skip
, int type_class
)
688 return do_lookup_versioned (undef_name
, hash
, ref
, result
, scope
, i
,
689 version
, skip
, type_class
);