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
: rtld_progname
,
176 ? undef_map
->l_name
: rtld_progname
);
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
, int flags
,
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 flags
)
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, flags
,
233 if (__builtin_expect (current_value
.s
== NULL
, 0))
235 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
237 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
238 /* We could find no value for a strong reference. */
239 /* XXX We cannot translate the messages. */
240 _dl_signal_cerror (0, (reference_name
[0]
242 : (rtld_progname
?: "<main program>")),
243 N_("relocation error"),
244 make_string (undefined_msg
, undef_name
));
249 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
250 if (__builtin_expect (protected != 0, 0))
252 /* It is very tricky. We need to figure out what value to
253 return for the protected symbol. */
254 struct sym_val protected_value
= { NULL
, NULL
};
256 for (scope
= symbol_scope
; *scope
; ++scope
)
257 if (_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
258 0, flags
, NULL
, ELF_RTYPE_CLASS_PLT
))
261 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
263 current_value
.s
= *ref
;
264 current_value
.m
= undef_map
;
268 /* We have to check whether this would bind UNDEF_MAP to an object
269 in the global scope which was dynamically loaded. In this case
270 we have to prevent the latter from being unloaded unless the
271 UNDEF_MAP object is also unloaded. */
272 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
273 /* Don't do this for explicit lookups as opposed to implicit
275 && (flags
& DL_LOOKUP_ADD_DEPENDENCY
) != 0
276 /* Add UNDEF_MAP to the dependencies. */
277 && add_dependency (undef_map
, current_value
.m
) < 0)
278 /* Something went wrong. Perhaps the object we tried to reference
279 was just removed. Try finding another definition. */
280 return INTUSE(_dl_lookup_symbol
) (undef_name
, undef_map
, ref
,
281 symbol_scope
, type_class
, flags
);
283 if (__builtin_expect (GL(dl_debug_mask
)
284 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
285 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
286 ¤t_value
, NULL
, type_class
, protected);
288 *ref
= current_value
.s
;
289 return LOOKUP_VALUE (current_value
.m
);
291 INTDEF (_dl_lookup_symbol
)
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 unsigned long int hash
= _dl_elf_hash (undef_name
);
307 struct sym_val current_value
= { NULL
, NULL
};
308 struct r_scope_elem
**scope
;
312 bump_num_relocations ();
314 /* Search the relevant loaded objects for a definition. */
315 scope
= symbol_scope
;
316 for (i
= 0; (*scope
)->r_list
[i
] != skip_map
; ++i
)
317 assert (i
< (*scope
)->r_nlist
);
319 if (! _dl_do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, i
,
320 DL_LOOKUP_RETURN_NEWEST
, skip_map
, 0))
322 if (_dl_do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, 0,
323 DL_LOOKUP_RETURN_NEWEST
, skip_map
, 0))
326 if (__builtin_expect (current_value
.s
== NULL
, 0))
332 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
334 if (__builtin_expect (protected != 0, 0))
336 /* It is very tricky. We need to figure out what value to
337 return for the protected symbol. */
338 struct sym_val protected_value
= { NULL
, NULL
};
340 if (i
>= (*scope
)->r_nlist
341 || !_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
342 i
, DL_LOOKUP_RETURN_NEWEST
, skip_map
,
343 ELF_RTYPE_CLASS_PLT
))
345 if (_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
346 0, DL_LOOKUP_RETURN_NEWEST
, skip_map
,
347 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 flags
)
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 /* No other flag than DL_LOOKUP_ADD_DEPENDENCY is allowed. */
388 assert (flags
== 0 || flags
== DL_LOOKUP_ADD_DEPENDENCY
);
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
, type_class
);
398 if (__builtin_expect (res
, 0) < 0)
400 /* Oh, oh. The file named in the relocation entry does not
401 contain the needed symbol. */
402 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
404 /* XXX We cannot translate the message. */
405 _dl_signal_cerror (0, (reference_name
[0]
407 : (rtld_progname
?: "<main program>")),
408 N_("relocation error"),
409 make_string ("symbol ", undef_name
, ", version ",
411 " not defined in file ",
413 " with link time reference",
415 ? " (no version symbols)" : ""));
421 if (__builtin_expect (current_value
.s
== NULL
, 0))
423 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
425 /* We could find no value for a strong reference. */
426 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
428 /* XXX We cannot translate the message. */
429 _dl_signal_cerror (0, (reference_name
[0]
431 : (rtld_progname
?: "<main program>")), NULL
,
432 make_string (undefined_msg
, undef_name
,
434 version
->name
?: NULL
));
440 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
442 if (__builtin_expect (protected != 0, 0))
444 /* It is very tricky. We need to figure out what value to
445 return for the protected symbol. */
446 struct sym_val protected_value
= { NULL
, NULL
};
448 for (scope
= symbol_scope
; *scope
; ++scope
)
449 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
, &protected_value
,
450 *scope
, 0, version
, NULL
,
451 ELF_RTYPE_CLASS_PLT
))
454 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
456 current_value
.s
= *ref
;
457 current_value
.m
= undef_map
;
461 /* We have to check whether this would bind UNDEF_MAP to an object
462 in the global scope which was dynamically loaded. In this case
463 we have to prevent the latter from being unloaded unless the
464 UNDEF_MAP object is also unloaded. */
465 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
466 /* Don't do this for explicit lookups as opposed to implicit
469 /* Add UNDEF_MAP to the dependencies. */
470 && add_dependency (undef_map
, current_value
.m
) < 0)
471 /* Something went wrong. Perhaps the object we tried to reference
472 was just removed. Try finding another definition. */
473 return INTUSE(_dl_lookup_versioned_symbol
) (undef_name
, undef_map
,
475 version
, type_class
, flags
);
477 if (__builtin_expect (GL(dl_debug_mask
)
478 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
479 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
480 ¤t_value
, version
, type_class
, protected);
482 *ref
= current_value
.s
;
483 return LOOKUP_VALUE (current_value
.m
);
485 INTDEF (_dl_lookup_versioned_symbol
)
488 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
489 with the version we are looking for. */
492 _dl_lookup_versioned_symbol_skip (const char *undef_name
,
493 struct link_map
*undef_map
,
494 const ElfW(Sym
) **ref
,
495 struct r_scope_elem
*symbol_scope
[],
496 const struct r_found_version
*version
,
497 struct link_map
*skip_map
)
499 const char *reference_name
= undef_map
->l_name
;
500 const unsigned long int hash
= _dl_elf_hash (undef_name
);
501 struct sym_val current_value
= { NULL
, NULL
};
502 struct r_scope_elem
**scope
;
506 bump_num_relocations ();
508 /* Search the relevant loaded objects for a definition. */
509 scope
= symbol_scope
;
510 for (i
= 0; (*scope
)->r_list
[i
] != skip_map
; ++i
)
511 assert (i
< (*scope
)->r_nlist
);
513 if (! _dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
514 *scope
, i
, version
, skip_map
, 0))
516 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
517 *scope
, 0, version
, skip_map
, 0))
520 if (__builtin_expect (current_value
.s
== NULL
, 0))
522 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
524 /* We could find no value for a strong reference. */
525 const size_t len
= strlen (undef_name
);
526 char buf
[sizeof undefined_msg
+ len
];
527 __mempcpy (__mempcpy (buf
, undefined_msg
, sizeof undefined_msg
- 1),
528 undef_name
, len
+ 1);
529 /* XXX We cannot translate the messages. */
530 _dl_signal_cerror (0, (reference_name
[0]
532 : (rtld_progname
?: "<main program>")),
539 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
541 if (__builtin_expect (protected != 0, 0))
543 /* It is very tricky. We need to figure out what value to
544 return for the protected symbol. */
545 struct sym_val protected_value
= { NULL
, NULL
};
547 if (i
>= (*scope
)->r_nlist
548 || !_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
549 &protected_value
, *scope
, i
, version
,
550 skip_map
, ELF_RTYPE_CLASS_PLT
))
552 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
553 &protected_value
, *scope
, 0, version
,
554 skip_map
, ELF_RTYPE_CLASS_PLT
))
557 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
559 current_value
.s
= *ref
;
560 current_value
.m
= undef_map
;
564 if (__builtin_expect (GL(dl_debug_mask
)
565 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
566 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
567 ¤t_value
, version
, 0, protected);
569 *ref
= current_value
.s
;
570 return LOOKUP_VALUE (current_value
.m
);
574 /* Cache the location of MAP's hash table. */
578 _dl_setup_hash (struct link_map
*map
)
583 if (!map
->l_info
[DT_HASH
])
585 hash
= (void *)(map
->l_addr
+ map
->l_info
[DT_HASH
]->d_un
.d_ptr
);
587 map
->l_nbuckets
= *hash
++;
589 map
->l_buckets
= hash
;
590 hash
+= map
->l_nbuckets
;
597 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
598 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
599 struct sym_val
*value
,
600 const struct r_found_version
*version
, int type_class
,
603 const char *reference_name
= undef_map
->l_name
;
605 if (GL(dl_debug_mask
) & DL_DEBUG_BINDINGS
)
607 INTUSE(_dl_debug_printf
) ("binding file %s to %s: %s symbol `%s'",
610 : (rtld_progname
?: "<main program>")),
612 ? value
->m
->l_name
: rtld_progname
,
613 protected ? "protected" : "normal",
616 _dl_debug_printf_c (" [%s]\n", version
->name
);
618 _dl_debug_printf_c ("\n");
621 if (GL(dl_debug_mask
) & DL_DEBUG_PRELINK
)
624 struct sym_val val
= { NULL
, NULL
};
626 if ((GL(dl_trace_prelink_map
) == NULL
627 || GL(dl_trace_prelink_map
) == GL(dl_loaded
))
628 && undef_map
!= GL(dl_loaded
))
630 const unsigned long int hash
= _dl_elf_hash (undef_name
);
633 _dl_do_lookup (undef_name
, hash
, *ref
, &val
,
634 undef_map
->l_local_scope
[0], 0, 0, NULL
,
637 _dl_do_lookup_versioned (undef_name
, hash
, *ref
, &val
,
638 undef_map
->l_local_scope
[0], 0, version
,
641 if (val
.s
!= value
->s
|| val
.m
!= value
->m
)
646 || GL(dl_trace_prelink_map
) == undef_map
647 || GL(dl_trace_prelink_map
) == NULL
)
649 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
650 conflict
? "conflict" : "lookup",
651 (int) sizeof (ElfW(Addr
)) * 2, undef_map
->l_map_start
,
652 (int) sizeof (ElfW(Addr
)) * 2,
653 ((ElfW(Addr
)) *ref
) - undef_map
->l_map_start
,
654 (int) sizeof (ElfW(Addr
)) * 2,
655 (ElfW(Addr
)) (value
->s
? value
->m
->l_map_start
: 0),
656 (int) sizeof (ElfW(Addr
)) * 2,
657 (ElfW(Addr
)) (value
->s
? value
->s
->st_value
: 0));
660 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
661 (int) sizeof (ElfW(Addr
)) * 2,
662 (ElfW(Addr
)) (val
.s
? val
.m
->l_map_start
: 0),
663 (int) sizeof (ElfW(Addr
)) * 2,
664 (ElfW(Addr
)) (val
.s
? val
.s
->st_value
: 0));
666 _dl_printf ("/%x %s\n", type_class
, undef_name
);
672 /* These are here so that we only inline do_lookup{,_versioned} in the common
673 case, not everywhere. */
674 static int __attribute_noinline__
676 _dl_do_lookup (const char *undef_name
, unsigned long int hash
,
677 const ElfW(Sym
) *ref
, struct sym_val
*result
,
678 struct r_scope_elem
*scope
, size_t i
, int flags
,
679 struct link_map
*skip
, int type_class
)
681 return do_lookup (undef_name
, hash
, ref
, result
, scope
, i
, flags
, skip
,
685 static int __attribute_noinline__
687 _dl_do_lookup_versioned (const char *undef_name
, unsigned long int hash
,
688 const ElfW(Sym
) *ref
, struct sym_val
*result
,
689 struct r_scope_elem
*scope
, size_t i
,
690 const struct r_found_version
*const version
,
691 struct link_map
*skip
, int type_class
)
693 return do_lookup_versioned (undef_name
, hash
, ref
, result
, scope
, i
,
694 version
, skip
, type_class
);