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>
33 #define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
35 /* We need this string more than once. */
36 static const char undefined_msg
[] = "undefined symbol: ";
46 #define make_string(string, rest...) \
48 const char *all[] = { string, ## rest }; \
53 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
54 len += strlen (all[cnt]); \
56 cp = result = alloca (len); \
57 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
58 cp = __stpcpy (cp, all[cnt]); \
63 /* Statistics function. */
65 # define bump_num_relocations() ++GL(dl_num_relocations)
67 # define bump_num_relocations() ((void) 0)
72 /* We have two different situations when looking up a simple: with or
73 without versioning. gcc is not able to optimize a single function
74 definition serving for both purposes so we define two functions. */
76 #include "do-lookup.h"
79 #include "do-lookup.h"
82 /* Add extra dependency on MAP to UNDEF_MAP. */
85 add_dependency (struct link_map
*undef_map
, struct link_map
*map
)
87 struct link_map
**list
;
88 struct link_map
*runp
;
93 /* Avoid self-references. */
97 /* Make sure nobody can unload the object while we are at it. */
98 __libc_lock_lock_recursive (GL(dl_load_lock
));
100 /* Determine whether UNDEF_MAP already has a reference to MAP. First
101 look in the normal dependencies. */
102 if (undef_map
->l_searchlist
.r_list
!= NULL
)
104 list
= undef_map
->l_initfini
;
106 for (i
= 0; list
[i
] != NULL
; ++i
)
111 /* No normal dependency. See whether we already had to add it
112 to the special list of dynamic dependencies. */
113 list
= undef_map
->l_reldeps
;
114 act
= undef_map
->l_reldepsact
;
116 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 runp
= GL(dl_loaded
);
126 while (runp
!= NULL
&& runp
!= map
)
131 /* The object is still available. Add the reference now. */
132 if (__builtin_expect (act
>= undef_map
->l_reldepsmax
, 0))
134 /* Allocate more memory for the dependency list. Since this
135 can never happen during the startup phase we can use
139 undef_map
->l_reldepsmax
+= 5;
140 newp
= realloc (undef_map
->l_reldeps
,
141 undef_map
->l_reldepsmax
142 * sizeof (struct link_map
*));
144 if (__builtin_expect (newp
!= NULL
, 1))
145 undef_map
->l_reldeps
= (struct link_map
**) newp
;
147 /* Correct the addition. */
148 undef_map
->l_reldepsmax
-= 5;
151 /* If we didn't manage to allocate memory for the list this is
152 no fatal mistake. We simply increment the use counter of the
153 referenced object and don't record the dependencies. This
154 means this increment can never be reverted and the object
155 will never be unloaded. This is semantically the correct
157 if (__builtin_expect (act
< undef_map
->l_reldepsmax
, 1))
158 undef_map
->l_reldeps
[undef_map
->l_reldepsact
++] = map
;
160 if (map
->l_searchlist
.r_list
!= NULL
)
161 /* And increment the counter in the referenced object. */
164 /* We have to bump the counts for all dependencies since so far
165 this object was only a normal or transitive dependency.
166 Now it might be closed with _dl_close() directly. */
167 for (list
= map
->l_initfini
; *list
!= NULL
; ++list
)
168 ++(*list
)->l_opencount
;
170 /* Display information if we are debugging. */
171 if (__builtin_expect (GL(dl_debug_mask
) & DL_DEBUG_FILES
, 0))
172 INTUSE(_dl_debug_printf
) ("\
173 \nfile=%s; needed by %s (relocation dependency)\n\n",
174 map
->l_name
[0] ? map
->l_name
: _dl_argv
[0],
176 ? undef_map
->l_name
: _dl_argv
[0]);
179 /* Whoa, that was bad luck. We have to search again. */
183 /* Release the lock. */
184 __libc_lock_unlock_recursive (GL(dl_load_lock
));
191 _dl_do_lookup (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 struct link_map
*skip
, int type_class
);
197 _dl_do_lookup_versioned (const char *undef_name
, unsigned long int hash
,
198 const ElfW(Sym
) *ref
, struct sym_val
*result
,
199 struct r_scope_elem
*scope
, size_t i
,
200 const struct r_found_version
*const version
,
201 struct link_map
*skip
, int type_class
);
205 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
206 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
207 struct sym_val
*value
,
208 const struct r_found_version
*version
, int type_class
,
211 /* Search loaded objects' symbol tables for a definition of the symbol
216 _dl_lookup_symbol (const char *undef_name
, struct link_map
*undef_map
,
217 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
218 int type_class
, int explicit)
220 const unsigned long int hash
= _dl_elf_hash (undef_name
);
221 struct sym_val current_value
= { NULL
, NULL
};
222 struct r_scope_elem
**scope
;
225 bump_num_relocations ();
227 /* Search the relevant loaded objects for a definition. */
228 for (scope
= symbol_scope
; *scope
; ++scope
)
229 if (do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, 0, NULL
,
232 /* We have to check whether this would bind UNDEF_MAP to an object
233 in the global scope which was dynamically loaded. In this case
234 we have to prevent the latter from being unloaded unless the
235 UNDEF_MAP object is also unloaded. */
236 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
237 /* Don't do this for explicit lookups as opposed to implicit
240 /* Add UNDEF_MAP to the dependencies. */
241 && add_dependency (undef_map
, current_value
.m
) < 0)
242 /* Something went wrong. Perhaps the object we tried to reference
243 was just removed. Try finding another definition. */
244 return INTUSE(_dl_lookup_symbol
) (undef_name
, undef_map
, ref
,
245 symbol_scope
, type_class
, 0);
250 if (__builtin_expect (current_value
.s
== NULL
, 0))
252 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
254 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
255 /* We could find no value for a strong reference. */
256 /* XXX We cannot translate the messages. */
257 _dl_signal_cerror (0, (reference_name
[0]
259 : (_dl_argv
[0] ?: "<main program>")),
260 N_("relocation error"),
261 make_string (undefined_msg
, undef_name
));
266 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
267 if (__builtin_expect (protected != 0, 0))
269 /* It is very tricky. We need to figure out what value to
270 return for the protected symbol */
271 struct sym_val protected_value
= { NULL
, NULL
};
273 for (scope
= symbol_scope
; *scope
; ++scope
)
274 if (_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
275 0, NULL
, ELF_RTYPE_CLASS_PLT
))
278 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
280 current_value
.s
= *ref
;
281 current_value
.m
= undef_map
;
285 if (__builtin_expect (GL(dl_debug_mask
)
286 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
287 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
288 ¤t_value
, NULL
, type_class
, protected);
290 *ref
= current_value
.s
;
291 return LOOKUP_VALUE (current_value
.m
);
293 INTDEF (_dl_lookup_symbol
)
296 /* This function is nearly the same as `_dl_lookup_symbol' but it
297 skips in the first list all objects until SKIP_MAP is found. I.e.,
298 it only considers objects which were loaded after the described
299 object. If there are more search lists the object described by
300 SKIP_MAP is only skipped. */
303 _dl_lookup_symbol_skip (const char *undef_name
,
304 struct link_map
*undef_map
, const ElfW(Sym
) **ref
,
305 struct r_scope_elem
*symbol_scope
[],
306 struct link_map
*skip_map
)
308 const unsigned long int hash
= _dl_elf_hash (undef_name
);
309 struct sym_val current_value
= { NULL
, NULL
};
310 struct r_scope_elem
**scope
;
314 bump_num_relocations ();
316 /* Search the relevant loaded objects for a definition. */
317 scope
= symbol_scope
;
318 for (i
= 0; (*scope
)->r_list
[i
] != skip_map
; ++i
)
319 assert (i
< (*scope
)->r_nlist
);
321 if (! _dl_do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, i
,
324 if (_dl_do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, 0,
328 if (__builtin_expect (current_value
.s
== NULL
, 0))
334 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
336 if (__builtin_expect (protected != 0, 0))
338 /* It is very tricky. We need to figure out what value to
339 return for the protected symbol. */
340 struct sym_val protected_value
= { NULL
, NULL
};
342 if (i
>= (*scope
)->r_nlist
343 || !_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
344 i
, skip_map
, ELF_RTYPE_CLASS_PLT
))
346 if (_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
347 0, skip_map
, ELF_RTYPE_CLASS_PLT
))
350 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
352 current_value
.s
= *ref
;
353 current_value
.m
= undef_map
;
357 if (__builtin_expect (GL(dl_debug_mask
)
358 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
359 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
360 ¤t_value
, NULL
, 0, protected);
362 *ref
= current_value
.s
;
363 return LOOKUP_VALUE (current_value
.m
);
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 type_class
, int explicit)
380 const unsigned long int hash
= _dl_elf_hash (undef_name
);
381 struct sym_val current_value
= { NULL
, NULL
};
382 struct r_scope_elem
**scope
;
385 bump_num_relocations ();
387 /* Search the relevant loaded objects for a definition. */
388 for (scope
= symbol_scope
; *scope
; ++scope
)
390 int res
= do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
391 *scope
, 0, version
, NULL
, type_class
);
394 /* We have to check whether this would bind UNDEF_MAP to an object
395 in the global scope which was dynamically loaded. In this case
396 we have to prevent the latter from being unloaded unless the
397 UNDEF_MAP object is also unloaded. */
398 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
399 /* Don't do this for explicit lookups as opposed to implicit
402 /* Add UNDEF_MAP to the dependencies. */
403 && add_dependency (undef_map
, current_value
.m
) < 0)
404 /* Something went wrong. Perhaps the object we tried to reference
405 was just removed. Try finding another definition. */
406 return INTUSE(_dl_lookup_versioned_symbol
) (undef_name
, undef_map
,
408 version
, type_class
, 0);
413 if (__builtin_expect (res
, 0) < 0)
415 /* Oh, oh. The file named in the relocation entry does not
416 contain the needed symbol. */
417 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
419 /* XXX We cannot translate the message. */
420 _dl_signal_cerror (0, (reference_name
[0]
422 : (_dl_argv
[0] ?: "<main program>")),
423 N_("relocation error"),
424 make_string ("symbol ", undef_name
, ", version ",
426 " not defined in file ",
428 " with link time reference",
430 ? " (no version symbols)" : ""));
436 if (__builtin_expect (current_value
.s
== NULL
, 0))
438 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
440 /* We could find no value for a strong reference. */
441 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
443 /* XXX We cannot translate the message. */
444 _dl_signal_cerror (0, (reference_name
[0]
446 : (_dl_argv
[0] ?: "<main program>")), NULL
,
447 make_string (undefined_msg
, undef_name
,
449 version
->name
?: NULL
));
455 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
457 if (__builtin_expect (protected != 0, 0))
459 /* It is very tricky. We need to figure out what value to
460 return for the protected symbol */
461 struct sym_val protected_value
= { NULL
, NULL
};
463 for (scope
= symbol_scope
; *scope
; ++scope
)
464 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
, &protected_value
,
465 *scope
, 0, version
, NULL
,
466 ELF_RTYPE_CLASS_PLT
))
469 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
471 current_value
.s
= *ref
;
472 current_value
.m
= undef_map
;
476 if (__builtin_expect (GL(dl_debug_mask
)
477 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
478 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
479 ¤t_value
, version
, type_class
, protected);
481 *ref
= current_value
.s
;
482 return LOOKUP_VALUE (current_value
.m
);
484 INTDEF (_dl_lookup_versioned_symbol
)
487 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
488 with the version we are looking for. */
491 _dl_lookup_versioned_symbol_skip (const char *undef_name
,
492 struct link_map
*undef_map
,
493 const ElfW(Sym
) **ref
,
494 struct r_scope_elem
*symbol_scope
[],
495 const struct r_found_version
*version
,
496 struct link_map
*skip_map
)
498 const char *reference_name
= undef_map
->l_name
;
499 const unsigned long int hash
= _dl_elf_hash (undef_name
);
500 struct sym_val current_value
= { NULL
, NULL
};
501 struct r_scope_elem
**scope
;
505 bump_num_relocations ();
507 /* Search the relevant loaded objects for a definition. */
508 scope
= symbol_scope
;
509 for (i
= 0; (*scope
)->r_list
[i
] != skip_map
; ++i
)
510 assert (i
< (*scope
)->r_nlist
);
512 if (! _dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
513 *scope
, i
, version
, skip_map
, 0))
515 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
516 *scope
, 0, version
, skip_map
, 0))
519 if (__builtin_expect (current_value
.s
== NULL
, 0))
521 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
523 /* We could find no value for a strong reference. */
524 const size_t len
= strlen (undef_name
);
525 char buf
[sizeof undefined_msg
+ len
];
526 __mempcpy (__mempcpy (buf
, undefined_msg
, sizeof undefined_msg
- 1),
527 undef_name
, len
+ 1);
528 /* XXX We cannot translate the messages. */
529 _dl_signal_cerror (0, (reference_name
[0]
531 : (_dl_argv
[0] ?: "<main program>")),
538 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
540 if (__builtin_expect (protected != 0, 0))
542 /* It is very tricky. We need to figure out what value to
543 return for the protected symbol */
544 struct sym_val protected_value
= { NULL
, NULL
};
546 if (i
>= (*scope
)->r_nlist
547 || !_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
548 &protected_value
, *scope
, i
, version
,
549 skip_map
, ELF_RTYPE_CLASS_PLT
))
551 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
552 &protected_value
, *scope
, 0, version
,
553 skip_map
, ELF_RTYPE_CLASS_PLT
))
556 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
558 current_value
.s
= *ref
;
559 current_value
.m
= undef_map
;
563 if (__builtin_expect (GL(dl_debug_mask
)
564 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
565 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
566 ¤t_value
, version
, 0, protected);
568 *ref
= current_value
.s
;
569 return LOOKUP_VALUE (current_value
.m
);
573 /* Cache the location of MAP's hash table. */
577 _dl_setup_hash (struct link_map
*map
)
582 if (!map
->l_info
[DT_HASH
])
584 hash
= (void *)(map
->l_addr
+ map
->l_info
[DT_HASH
]->d_un
.d_ptr
);
586 map
->l_nbuckets
= *hash
++;
588 map
->l_buckets
= hash
;
589 hash
+= map
->l_nbuckets
;
595 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
596 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
597 struct sym_val
*value
, const struct r_found_version
*version
,
598 int type_class
, int protected)
600 const char *reference_name
= undef_map
->l_name
;
602 if (GL(dl_debug_mask
) & DL_DEBUG_BINDINGS
)
604 INTUSE(_dl_debug_printf
) ("binding file %s to %s: %s symbol `%s'",
607 : (_dl_argv
[0] ?: "<main program>")),
609 ? value
->m
->l_name
: _dl_argv
[0],
610 protected ? "protected" : "normal",
613 _dl_debug_printf_c (" [%s]\n", version
->name
);
615 _dl_debug_printf_c ("\n");
618 if (GL(dl_debug_mask
) & DL_DEBUG_PRELINK
)
621 struct sym_val val
= { NULL
, NULL
};
623 if ((GL(dl_trace_prelink_map
) == NULL
624 || GL(dl_trace_prelink_map
) == GL(dl_loaded
))
625 && undef_map
!= GL(dl_loaded
))
627 const unsigned long int hash
= _dl_elf_hash (undef_name
);
630 _dl_do_lookup (undef_name
, hash
, *ref
, &val
,
631 undef_map
->l_local_scope
[0], 0, NULL
, type_class
);
633 _dl_do_lookup_versioned (undef_name
, hash
, *ref
, &val
,
634 undef_map
->l_local_scope
[0], 0, version
,
637 if (val
.s
!= value
->s
|| val
.m
!= value
->m
)
642 || GL(dl_trace_prelink_map
) == undef_map
643 || GL(dl_trace_prelink_map
) == NULL
)
645 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
646 conflict
? "conflict" : "lookup",
647 (int) sizeof (ElfW(Addr
)) * 2, undef_map
->l_map_start
,
648 (int) sizeof (ElfW(Addr
)) * 2,
649 ((ElfW(Addr
)) *ref
) - undef_map
->l_map_start
,
650 (int) sizeof (ElfW(Addr
)) * 2,
651 (ElfW(Addr
)) (value
->s
? value
->m
->l_map_start
: 0),
652 (int) sizeof (ElfW(Addr
)) * 2,
653 (ElfW(Addr
)) (value
->s
? value
->s
->st_value
: 0));
656 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
657 (int) sizeof (ElfW(Addr
)) * 2,
658 (ElfW(Addr
)) (val
.s
? val
.m
->l_map_start
: 0),
659 (int) sizeof (ElfW(Addr
)) * 2,
660 (ElfW(Addr
)) (val
.s
? val
.s
->st_value
: 0));
662 _dl_printf ("/%x %s\n", type_class
, undef_name
);
668 /* These are here so that we only inline do_lookup{,_versioned} in the common
669 case, not everywhere. */
670 static int __attribute_noinline__
672 _dl_do_lookup (const char *undef_name
, unsigned long int hash
,
673 const ElfW(Sym
) *ref
, struct sym_val
*result
,
674 struct r_scope_elem
*scope
, size_t i
,
675 struct link_map
*skip
, int type_class
)
677 return do_lookup (undef_name
, hash
, ref
, result
, scope
, i
, skip
,
681 static int __attribute_noinline__
683 _dl_do_lookup_versioned (const char *undef_name
, unsigned long int hash
,
684 const ElfW(Sym
) *ref
, struct sym_val
*result
,
685 struct r_scope_elem
*scope
, size_t i
,
686 const struct r_found_version
*const version
,
687 struct link_map
*skip
, int type_class
)
689 return do_lookup_versioned (undef_name
, hash
, ref
, result
, scope
, i
,
690 version
, skip
, type_class
);