* sysdeps/powerpc/fpu/w_sqrt.c: Add sqrtl alias.
[glibc.git] / elf / dl-lookup.c
blob895b60df7dc1c70e4b62266ac1e68ac5d0d480e7
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
18 02111-1307 USA. */
20 #include <alloca.h>
21 #include <libintl.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <ldsodefs.h>
26 #include "dl-hash.h"
27 #include <dl-machine.h>
28 #include <bits/libc-lock.h>
29 #include <tls.h>
31 #include <assert.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: ";
39 struct sym_val
41 const ElfW(Sym) *s;
42 struct link_map *m;
46 #define make_string(string, rest...) \
47 ({ \
48 const char *all[] = { string, ## rest }; \
49 size_t len, cnt; \
50 char *result, *cp; \
52 len = 1; \
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]); \
60 result; \
63 /* Statistics function. */
64 #ifdef SHARED
65 # define bump_num_relocations() ++GL(dl_num_relocations)
66 #else
67 # define bump_num_relocations() ((void) 0)
68 #endif
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. */
75 #define VERSIONED 0
76 #include "do-lookup.h"
78 #define VERSIONED 1
79 #include "do-lookup.h"
82 /* Add extra dependency on MAP to UNDEF_MAP. */
83 static int
84 internal_function
85 add_dependency (struct link_map *undef_map, struct link_map *map)
87 struct link_map **list;
88 struct link_map *runp;
89 unsigned int act;
90 unsigned int i;
91 int result = 0;
93 /* Avoid self-references. */
94 if (undef_map == map)
95 return 0;
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)
107 if (list[i] == map)
108 goto out;
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)
117 if (list[i] == map)
118 goto out;
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
124 definition. */
125 runp = GL(dl_loaded);
126 while (runp != NULL && runp != map)
127 runp = runp->l_next;
129 if (runp != NULL)
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
136 `realloc'. */
137 void *newp;
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;
146 else
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
156 behaviour. */
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. */
162 ++map->l_opencount;
163 else
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,
175 undef_map->l_name[0]
176 ? undef_map->l_name : rtld_progname);
178 else
179 /* Whoa, that was bad luck. We have to search again. */
180 result = -1;
182 out:
183 /* Release the lock. */
184 __libc_lock_unlock_recursive (GL(dl_load_lock));
186 return result;
189 static int
190 internal_function
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);
195 static int
196 internal_function
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);
203 static void
204 internal_function
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,
209 int protected);
211 /* Search loaded objects' symbol tables for a definition of the symbol
212 UNDEF_NAME. */
214 lookup_t
215 internal_function
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;
223 int protected;
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, &current_value, *scope, 0, flags,
230 NULL, type_class))
231 break;
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]
241 ? reference_name
242 : (rtld_progname ?: "<main program>")),
243 N_("relocation error"),
244 make_string (undefined_msg, undef_name));
245 *ref = NULL;
246 return 0;
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))
259 break;
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
274 runtime lookups. */
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 &current_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. */
299 lookup_t
300 internal_function
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;
309 size_t i;
310 int protected;
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, &current_value, *scope, i,
320 DL_LOOKUP_RETURN_NEWEST, skip_map, 0))
321 while (*++scope)
322 if (_dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, 0,
323 DL_LOOKUP_RETURN_NEWEST, skip_map, 0))
324 break;
326 if (__builtin_expect (current_value.s == NULL, 0))
328 *ref = NULL;
329 return 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))
344 while (*++scope)
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))
348 break;
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 &current_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
369 symbol.
371 XXX We'll see whether we need this separate function. */
372 lookup_t
373 internal_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;
383 int protected;
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, &current_value,
394 *scope, 0, version, NULL, type_class);
395 if (res > 0)
396 break;
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]
406 ? reference_name
407 : (rtld_progname ?: "<main program>")),
408 N_("relocation error"),
409 make_string ("symbol ", undef_name, ", version ",
410 version->name,
411 " not defined in file ",
412 version->filename,
413 " with link time reference",
414 res == -2
415 ? " (no version symbols)" : ""));
416 *ref = NULL;
417 return 0;
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]
430 ? reference_name
431 : (rtld_progname ?: "<main program>")), NULL,
432 make_string (undefined_msg, undef_name,
433 ", version ",
434 version->name ?: NULL));
436 *ref = NULL;
437 return 0;
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))
452 break;
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
467 runtime lookups. */
468 && flags != 0
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,
474 ref, symbol_scope,
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 &current_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. */
490 lookup_t
491 internal_function
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;
503 size_t i;
504 int protected;
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, &current_value,
514 *scope, i, version, skip_map, 0))
515 while (*++scope)
516 if (_dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
517 *scope, 0, version, skip_map, 0))
518 break;
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]
531 ? reference_name
532 : (rtld_progname ?: "<main program>")),
533 NULL, buf);
535 *ref = NULL;
536 return 0;
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))
551 while (*++scope)
552 if (_dl_do_lookup_versioned (undef_name, hash, *ref,
553 &protected_value, *scope, 0, version,
554 skip_map, ELF_RTYPE_CLASS_PLT))
555 break;
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 &current_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. */
576 void
577 internal_function
578 _dl_setup_hash (struct link_map *map)
580 Elf_Symndx *hash;
581 Elf_Symndx nchain;
583 if (!map->l_info[DT_HASH])
584 return;
585 hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);
587 map->l_nbuckets = *hash++;
588 nchain = *hash++;
589 map->l_buckets = hash;
590 hash += map->l_nbuckets;
591 map->l_chain = hash;
595 static void
596 internal_function
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,
601 int protected)
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'",
608 (reference_name[0]
609 ? reference_name
610 : (rtld_progname ?: "<main program>")),
611 value->m->l_name[0]
612 ? value->m->l_name : rtld_progname,
613 protected ? "protected" : "normal",
614 undef_name);
615 if (version)
616 _dl_debug_printf_c (" [%s]\n", version->name);
617 else
618 _dl_debug_printf_c ("\n");
620 #ifdef SHARED
621 if (GL(dl_debug_mask) & DL_DEBUG_PRELINK)
623 int conflict = 0;
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);
632 if (version == 0)
633 _dl_do_lookup (undef_name, hash, *ref, &val,
634 undef_map->l_local_scope[0], 0, 0, NULL,
635 type_class);
636 else
637 _dl_do_lookup_versioned (undef_name, hash, *ref, &val,
638 undef_map->l_local_scope[0], 0, version,
639 NULL, type_class);
641 if (val.s != value->s || val.m != value->m)
642 conflict = 1;
645 if (conflict
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));
659 if (conflict)
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);
669 #endif
672 /* These are here so that we only inline do_lookup{,_versioned} in the common
673 case, not everywhere. */
674 static int __attribute_noinline__
675 internal_function
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,
682 type_class);
685 static int __attribute_noinline__
686 internal_function
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);