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
);
199 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
200 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
201 struct sym_val
*value
, const struct r_found_version
*version
,
202 int type_class
, int protected);
204 /* Search loaded objects' symbol tables for a definition of the symbol
209 _dl_lookup_symbol (const char *undef_name
, struct link_map
*undef_map
,
210 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
211 int type_class
, int explicit)
213 const unsigned long int hash
= _dl_elf_hash (undef_name
);
214 struct sym_val current_value
= { NULL
, NULL
};
215 struct r_scope_elem
**scope
;
218 ++_dl_num_relocations
;
220 /* Search the relevant loaded objects for a definition. */
221 for (scope
= symbol_scope
; *scope
; ++scope
)
222 if (do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, 0, NULL
,
225 /* We have to check whether this would bind UNDEF_MAP to an object
226 in the global scope which was dynamically loaded. In this case
227 we have to prevent the latter from being unloaded unless the
228 UNDEF_MAP object is also unloaded. */
229 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
230 /* Don't do this for explicit lookups as opposed to implicit
233 /* Add UNDEF_MAP to the dependencies. */
234 && add_dependency (undef_map
, current_value
.m
) < 0)
235 /* Something went wrong. Perhaps the object we tried to reference
236 was just removed. Try finding another definition. */
237 return _dl_lookup_symbol (undef_name
, undef_map
, ref
, symbol_scope
,
243 if (__builtin_expect (current_value
.s
== NULL
, 0))
245 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
247 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
248 /* We could find no value for a strong reference. */
249 /* XXX We cannot translate the messages. */
250 _dl_signal_cerror (0, (reference_name
[0]
252 : (_dl_argv
[0] ?: "<main program>")),
253 N_("relocation error"),
254 make_string (undefined_msg
, undef_name
));
259 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
260 if (__builtin_expect (protected != 0, 0))
262 /* It is very tricky. We need to figure out what value to
263 return for the protected symbol */
264 struct sym_val protected_value
= { NULL
, NULL
};
266 for (scope
= symbol_scope
; *scope
; ++scope
)
267 if (_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
268 0, NULL
, ELF_RTYPE_CLASS_PLT
))
271 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
273 current_value
.s
= *ref
;
274 current_value
.m
= undef_map
;
278 if (__builtin_expect (_dl_debug_mask
279 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
280 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
281 ¤t_value
, NULL
, type_class
, protected);
283 *ref
= current_value
.s
;
284 return LOOKUP_VALUE (current_value
.m
);
288 /* This function is nearly the same as `_dl_lookup_symbol' but it
289 skips in the first list all objects until SKIP_MAP is found. I.e.,
290 it only considers objects which were loaded after the described
291 object. If there are more search lists the object described by
292 SKIP_MAP is only skipped. */
295 _dl_lookup_symbol_skip (const char *undef_name
,
296 struct link_map
*undef_map
, const ElfW(Sym
) **ref
,
297 struct r_scope_elem
*symbol_scope
[],
298 struct link_map
*skip_map
)
300 const unsigned long int hash
= _dl_elf_hash (undef_name
);
301 struct sym_val current_value
= { NULL
, NULL
};
302 struct r_scope_elem
**scope
;
306 ++_dl_num_relocations
;
308 /* Search the relevant loaded objects for a definition. */
309 scope
= symbol_scope
;
310 for (i
= 0; (*scope
)->r_list
[i
] != skip_map
; ++i
)
311 assert (i
< (*scope
)->r_nlist
);
313 if (! _dl_do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, i
,
316 if (_dl_do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, 0,
320 if (__builtin_expect (current_value
.s
== NULL
, 0))
326 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
328 if (__builtin_expect (protected != 0, 0))
330 /* It is very tricky. We need to figure out what value to
331 return for the protected symbol. */
332 struct sym_val protected_value
= { NULL
, NULL
};
334 if (i
>= (*scope
)->r_nlist
335 || !_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
336 i
, skip_map
, ELF_RTYPE_CLASS_PLT
))
338 if (_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
339 0, skip_map
, ELF_RTYPE_CLASS_PLT
))
342 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
344 current_value
.s
= *ref
;
345 current_value
.m
= undef_map
;
349 if (__builtin_expect (_dl_debug_mask
350 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
351 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
352 ¤t_value
, NULL
, 0, protected);
354 *ref
= current_value
.s
;
355 return LOOKUP_VALUE (current_value
.m
);
359 /* This function works like _dl_lookup_symbol but it takes an
360 additional arguement with the version number of the requested
363 XXX We'll see whether we need this separate function. */
366 _dl_lookup_versioned_symbol (const char *undef_name
,
367 struct link_map
*undef_map
, const ElfW(Sym
) **ref
,
368 struct r_scope_elem
*symbol_scope
[],
369 const struct r_found_version
*version
,
370 int type_class
, int explicit)
372 const unsigned long int hash
= _dl_elf_hash (undef_name
);
373 struct sym_val current_value
= { NULL
, NULL
};
374 struct r_scope_elem
**scope
;
377 ++_dl_num_relocations
;
379 /* Search the relevant loaded objects for a definition. */
380 for (scope
= symbol_scope
; *scope
; ++scope
)
382 int res
= do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
383 *scope
, 0, version
, NULL
, type_class
);
386 /* We have to check whether this would bind UNDEF_MAP to an object
387 in the global scope which was dynamically loaded. In this case
388 we have to prevent the latter from being unloaded unless the
389 UNDEF_MAP object is also unloaded. */
390 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
391 /* Don't do this for explicit lookups as opposed to implicit
394 /* Add UNDEF_MAP to the dependencies. */
395 && add_dependency (undef_map
, current_value
.m
) < 0)
396 /* Something went wrong. Perhaps the object we tried to reference
397 was just removed. Try finding another definition. */
398 return _dl_lookup_versioned_symbol (undef_name
, undef_map
, ref
,
399 symbol_scope
, version
,
405 if (__builtin_expect (res
, 0) < 0)
407 /* Oh, oh. The file named in the relocation entry does not
408 contain the needed symbol. */
409 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
411 /* XXX We cannot translate the message. */
412 _dl_signal_cerror (0, (reference_name
[0]
414 : (_dl_argv
[0] ?: "<main program>")),
415 N_("relocation error"),
416 make_string ("symbol ", undef_name
, ", version ",
418 " not defined in file ",
420 " with link time reference",
422 ? " (no version symbols)" : ""));
428 if (__builtin_expect (current_value
.s
== NULL
, 0))
430 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
432 /* We could find no value for a strong reference. */
433 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
435 /* XXX We cannot translate the message. */
436 _dl_signal_cerror (0, (reference_name
[0]
438 : (_dl_argv
[0] ?: "<main program>")), NULL
,
439 make_string (undefined_msg
, undef_name
,
441 version
->name
?: NULL
));
447 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
449 if (__builtin_expect (protected != 0, 0))
451 /* It is very tricky. We need to figure out what value to
452 return for the protected symbol */
453 struct sym_val protected_value
= { NULL
, NULL
};
455 for (scope
= symbol_scope
; *scope
; ++scope
)
456 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
, &protected_value
,
457 *scope
, 0, version
, NULL
,
458 ELF_RTYPE_CLASS_PLT
))
461 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
463 current_value
.s
= *ref
;
464 current_value
.m
= undef_map
;
468 if (__builtin_expect (_dl_debug_mask
469 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
470 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
471 ¤t_value
, version
, type_class
, protected);
473 *ref
= current_value
.s
;
474 return LOOKUP_VALUE (current_value
.m
);
478 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
479 with the version we are looking for. */
482 _dl_lookup_versioned_symbol_skip (const char *undef_name
,
483 struct link_map
*undef_map
,
484 const ElfW(Sym
) **ref
,
485 struct r_scope_elem
*symbol_scope
[],
486 const struct r_found_version
*version
,
487 struct link_map
*skip_map
)
489 const char *reference_name
= undef_map
->l_name
;
490 const unsigned long int hash
= _dl_elf_hash (undef_name
);
491 struct sym_val current_value
= { NULL
, NULL
};
492 struct r_scope_elem
**scope
;
496 ++_dl_num_relocations
;
498 /* Search the relevant loaded objects for a definition. */
499 scope
= symbol_scope
;
500 for (i
= 0; (*scope
)->r_list
[i
] != skip_map
; ++i
)
501 assert (i
< (*scope
)->r_nlist
);
503 if (! _dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
504 *scope
, i
, version
, skip_map
, 0))
506 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
507 *scope
, 0, version
, skip_map
, 0))
510 if (__builtin_expect (current_value
.s
== NULL
, 0))
512 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
514 /* We could find no value for a strong reference. */
515 const size_t len
= strlen (undef_name
);
516 char buf
[sizeof undefined_msg
+ len
];
517 __mempcpy (__mempcpy (buf
, undefined_msg
, sizeof undefined_msg
- 1),
518 undef_name
, len
+ 1);
519 /* XXX We cannot translate the messages. */
520 _dl_signal_cerror (0, (reference_name
[0]
522 : (_dl_argv
[0] ?: "<main program>")),
529 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
531 if (__builtin_expect (protected != 0, 0))
533 /* It is very tricky. We need to figure out what value to
534 return for the protected symbol */
535 struct sym_val protected_value
= { NULL
, NULL
};
537 if (i
>= (*scope
)->r_nlist
538 || !_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
539 &protected_value
, *scope
, i
, version
,
540 skip_map
, ELF_RTYPE_CLASS_PLT
))
542 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
543 &protected_value
, *scope
, 0, version
,
544 skip_map
, ELF_RTYPE_CLASS_PLT
))
547 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
549 current_value
.s
= *ref
;
550 current_value
.m
= undef_map
;
554 if (__builtin_expect (_dl_debug_mask
555 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
556 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
557 ¤t_value
, version
, 0, protected);
559 *ref
= current_value
.s
;
560 return LOOKUP_VALUE (current_value
.m
);
564 /* Cache the location of MAP's hash table. */
568 _dl_setup_hash (struct link_map
*map
)
573 if (!map
->l_info
[DT_HASH
])
575 hash
= (void *)(map
->l_addr
+ map
->l_info
[DT_HASH
]->d_un
.d_ptr
);
577 map
->l_nbuckets
= *hash
++;
579 map
->l_buckets
= hash
;
580 hash
+= map
->l_nbuckets
;
586 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
587 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
588 struct sym_val
*value
, const struct r_found_version
*version
,
589 int type_class
, int protected)
591 const char *reference_name
= undef_map
->l_name
;
593 if (_dl_debug_mask
& DL_DEBUG_BINDINGS
)
595 _dl_debug_printf ("binding file %s to %s: %s symbol `%s'",
597 ? reference_name
: (_dl_argv
[0] ?: "<main program>")),
598 value
->m
->l_name
[0] ? value
->m
->l_name
: _dl_argv
[0],
599 protected ? "protected" : "normal",
602 _dl_debug_printf_c (" [%s]\n", version
->name
);
604 _dl_debug_printf_c ("\n");
607 if (_dl_debug_mask
& DL_DEBUG_PRELINK
)
610 struct sym_val val
= { NULL
, NULL
};
612 if ((_dl_trace_prelink_map
== NULL
613 || _dl_trace_prelink_map
== _dl_loaded
)
614 && undef_map
!= _dl_loaded
)
616 const unsigned long int hash
= _dl_elf_hash (undef_name
);
619 _dl_do_lookup (undef_name
, hash
, *ref
, &val
,
620 undef_map
->l_local_scope
[0], 0, NULL
, type_class
);
622 _dl_do_lookup_versioned (undef_name
, hash
, *ref
, &val
,
623 undef_map
->l_local_scope
[0], 0, version
,
626 if (val
.s
!= value
->s
|| val
.m
!= value
->m
)
631 || _dl_trace_prelink_map
== undef_map
632 || _dl_trace_prelink_map
== NULL
)
634 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
635 conflict
? "conflict" : "lookup",
636 (int) sizeof (ElfW(Addr
)) * 2, undef_map
->l_map_start
,
637 (int) sizeof (ElfW(Addr
)) * 2,
638 ((ElfW(Addr
)) *ref
) - undef_map
->l_map_start
,
639 (int) sizeof (ElfW(Addr
)) * 2,
640 (ElfW(Addr
)) (value
->s
? value
->m
->l_map_start
: 0),
641 (int) sizeof (ElfW(Addr
)) * 2,
642 (ElfW(Addr
)) (value
->s
? value
->s
->st_value
: 0));
645 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
646 (int) sizeof (ElfW(Addr
)) * 2,
647 (ElfW(Addr
)) (val
.s
? val
.m
->l_map_start
: 0),
648 (int) sizeof (ElfW(Addr
)) * 2,
649 (ElfW(Addr
)) (val
.s
? val
.s
->st_value
: 0));
651 _dl_printf ("/%x %s\n", type_class
, undef_name
);
657 /* These are here so that we only inline do_lookup{,_versioned} in the common
658 case, not everywhere. */
661 _dl_do_lookup (const char *undef_name
, unsigned long int hash
,
662 const ElfW(Sym
) *ref
, struct sym_val
*result
,
663 struct r_scope_elem
*scope
, size_t i
,
664 struct link_map
*skip
, int type_class
)
666 return do_lookup (undef_name
, hash
, ref
, result
, scope
, i
, skip
,
672 _dl_do_lookup_versioned (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 const struct r_found_version
*const version
,
676 struct link_map
*skip
, int type_class
)
678 return do_lookup_versioned (undef_name
, hash
, ref
, result
, scope
, i
,
679 version
, skip
, type_class
);