1 /* Look up a symbol in the loaded objects.
2 Copyright (C) 1995-2002, 2003 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 and references to objects which cannot be
98 /* Make sure nobody can unload the object while we are at it. */
99 __rtld_lock_lock_recursive (GL(dl_load_lock
));
101 /* Don't create cross-reference between modules which are
102 dynamically loaded by the same dlopen() call. */
103 if (undef_map
->l_opencount
== 0 && map
->l_opencount
== 0)
106 /* Avoid references to objects which cannot be unloaded anyway. */
107 if (map
->l_type
!= lt_loaded
108 || (map
->l_flags_1
& DF_1_NODELETE
) != 0)
111 /* If the object with the undefined reference cannot be removed ever
112 just make sure the same is true for the object which contains the
114 if (undef_map
->l_type
!= lt_loaded
115 || (undef_map
->l_flags_1
& DF_1_NODELETE
) != 0)
118 map
->l_flags
|= DF_1_NODELETE
;
122 /* Determine whether UNDEF_MAP already has a reference to MAP. First
123 look in the normal dependencies. */
124 if (undef_map
->l_searchlist
.r_list
!= NULL
)
126 list
= undef_map
->l_initfini
;
128 for (i
= 0; list
[i
] != NULL
; ++i
)
133 /* No normal dependency. See whether we already had to add it
134 to the special list of dynamic dependencies. */
135 list
= undef_map
->l_reldeps
;
136 act
= undef_map
->l_reldepsact
;
138 for (i
= 0; i
< act
; ++i
)
142 /* The object is not yet in the dependency list. Before we add
143 it make sure just one more time the object we are about to
144 reference is still available. There is a brief period in
145 which the object could have been removed since we found the
147 runp
= GL(dl_loaded
);
148 while (runp
!= NULL
&& runp
!= map
)
153 /* The object is still available. Add the reference now. */
154 if (__builtin_expect (act
>= undef_map
->l_reldepsmax
, 0))
156 /* Allocate more memory for the dependency list. Since this
157 can never happen during the startup phase we can use
161 undef_map
->l_reldepsmax
+= 5;
162 newp
= realloc (undef_map
->l_reldeps
,
163 undef_map
->l_reldepsmax
164 * sizeof (struct link_map
*));
166 if (__builtin_expect (newp
!= NULL
, 1))
167 undef_map
->l_reldeps
= (struct link_map
**) newp
;
169 /* Correct the addition. */
170 undef_map
->l_reldepsmax
-= 5;
173 /* If we didn't manage to allocate memory for the list this is
174 no fatal mistake. We simply increment the use counter of the
175 referenced object and don't record the dependencies. This
176 means this increment can never be reverted and the object
177 will never be unloaded. This is semantically the correct
179 if (__builtin_expect (act
< undef_map
->l_reldepsmax
, 1))
180 undef_map
->l_reldeps
[undef_map
->l_reldepsact
++] = map
;
182 if (map
->l_searchlist
.r_list
!= NULL
)
183 /* And increment the counter in the referenced object. */
186 /* We have to bump the counts for all dependencies since so far
187 this object was only a normal or transitive dependency.
188 Now it might be closed with _dl_close() directly. */
189 for (list
= map
->l_initfini
; *list
!= NULL
; ++list
)
190 ++(*list
)->l_opencount
;
192 /* Display information if we are debugging. */
193 if (__builtin_expect (GL(dl_debug_mask
) & DL_DEBUG_FILES
, 0))
194 INTUSE(_dl_debug_printf
) ("\
195 \nfile=%s; needed by %s (relocation dependency)\n\n",
196 map
->l_name
[0] ? map
->l_name
: rtld_progname
,
198 ? undef_map
->l_name
: rtld_progname
);
201 /* Whoa, that was bad luck. We have to search again. */
205 /* Release the lock. */
206 __rtld_lock_unlock_recursive (GL(dl_load_lock
));
213 _dl_do_lookup (const char *undef_name
, unsigned long int hash
,
214 const ElfW(Sym
) *ref
, struct sym_val
*result
,
215 struct r_scope_elem
*scope
, size_t i
, int flags
,
216 struct link_map
*skip
, int type_class
);
219 _dl_do_lookup_versioned (const char *undef_name
, unsigned long int hash
,
220 const ElfW(Sym
) *ref
, struct sym_val
*result
,
221 struct r_scope_elem
*scope
, size_t i
,
222 const struct r_found_version
*const version
,
223 struct link_map
*skip
, int type_class
);
227 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
228 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
229 struct sym_val
*value
,
230 const struct r_found_version
*version
, int type_class
,
233 /* Search loaded objects' symbol tables for a definition of the symbol
238 _dl_lookup_symbol (const char *undef_name
, struct link_map
*undef_map
,
239 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
240 int type_class
, int flags
)
242 const unsigned long int hash
= _dl_elf_hash (undef_name
);
243 struct sym_val current_value
= { NULL
, NULL
};
244 struct r_scope_elem
**scope
;
247 bump_num_relocations ();
249 /* Search the relevant loaded objects for a definition. */
250 for (scope
= symbol_scope
; *scope
; ++scope
)
251 if (do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, 0, flags
,
255 if (__builtin_expect (current_value
.s
== NULL
, 0))
257 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
259 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
260 /* We could find no value for a strong reference. */
261 /* XXX We cannot translate the messages. */
262 _dl_signal_cerror (0, (reference_name
[0]
264 : (rtld_progname
?: "<main program>")),
265 N_("relocation error"),
266 make_string (undefined_msg
, undef_name
));
271 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
272 if (__builtin_expect (protected != 0, 0))
274 /* It is very tricky. We need to figure out what value to
275 return for the protected symbol. */
276 if (type_class
== ELF_RTYPE_CLASS_PLT
)
278 if (current_value
.s
!= NULL
&& current_value
.m
!= undef_map
)
280 current_value
.s
= *ref
;
281 current_value
.m
= undef_map
;
286 struct sym_val protected_value
= { NULL
, NULL
};
288 for (scope
= symbol_scope
; *scope
; ++scope
)
289 if (_dl_do_lookup (undef_name
, hash
, *ref
,
290 &protected_value
, *scope
, 0, flags
,
291 NULL
, ELF_RTYPE_CLASS_PLT
))
294 if (protected_value
.s
!= NULL
295 && protected_value
.m
!= undef_map
)
297 current_value
.s
= *ref
;
298 current_value
.m
= undef_map
;
303 /* We have to check whether this would bind UNDEF_MAP to an object
304 in the global scope which was dynamically loaded. In this case
305 we have to prevent the latter from being unloaded unless the
306 UNDEF_MAP object is also unloaded. */
307 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
308 /* Don't do this for explicit lookups as opposed to implicit
310 && (flags
& DL_LOOKUP_ADD_DEPENDENCY
) != 0
311 /* Add UNDEF_MAP to the dependencies. */
312 && add_dependency (undef_map
, current_value
.m
) < 0)
313 /* Something went wrong. Perhaps the object we tried to reference
314 was just removed. Try finding another definition. */
315 return INTUSE(_dl_lookup_symbol
) (undef_name
, undef_map
, ref
,
316 symbol_scope
, type_class
, flags
);
318 if (__builtin_expect (GL(dl_debug_mask
)
319 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
320 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
321 ¤t_value
, NULL
, type_class
, protected);
323 *ref
= current_value
.s
;
324 return LOOKUP_VALUE (current_value
.m
);
326 INTDEF (_dl_lookup_symbol
)
329 /* This function is nearly the same as `_dl_lookup_symbol' but it
330 skips in the first list all objects until SKIP_MAP is found. I.e.,
331 it only considers objects which were loaded after the described
332 object. If there are more search lists the object described by
333 SKIP_MAP is only skipped. */
336 _dl_lookup_symbol_skip (const char *undef_name
,
337 struct link_map
*undef_map
, const ElfW(Sym
) **ref
,
338 struct r_scope_elem
*symbol_scope
[],
339 struct link_map
*skip_map
)
341 const unsigned long int hash
= _dl_elf_hash (undef_name
);
342 struct sym_val current_value
= { NULL
, NULL
};
343 struct r_scope_elem
**scope
;
347 bump_num_relocations ();
349 /* Search the relevant loaded objects for a definition. */
350 scope
= symbol_scope
;
351 for (i
= 0; (*scope
)->r_list
[i
] != skip_map
; ++i
)
352 assert (i
< (*scope
)->r_nlist
);
354 if (! _dl_do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, i
,
355 DL_LOOKUP_RETURN_NEWEST
, skip_map
, 0))
357 if (_dl_do_lookup (undef_name
, hash
, *ref
, ¤t_value
, *scope
, 0,
358 DL_LOOKUP_RETURN_NEWEST
, skip_map
, 0))
361 if (__builtin_expect (current_value
.s
== NULL
, 0))
367 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
369 if (__builtin_expect (protected != 0, 0))
371 /* It is very tricky. We need to figure out what value to
372 return for the protected symbol. */
373 struct sym_val protected_value
= { NULL
, NULL
};
375 if (i
>= (*scope
)->r_nlist
376 || !_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
377 i
, DL_LOOKUP_RETURN_NEWEST
, skip_map
,
378 ELF_RTYPE_CLASS_PLT
))
380 if (_dl_do_lookup (undef_name
, hash
, *ref
, &protected_value
, *scope
,
381 0, DL_LOOKUP_RETURN_NEWEST
, skip_map
,
382 ELF_RTYPE_CLASS_PLT
))
385 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
387 current_value
.s
= *ref
;
388 current_value
.m
= undef_map
;
392 if (__builtin_expect (GL(dl_debug_mask
)
393 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
394 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
395 ¤t_value
, NULL
, 0, protected);
397 *ref
= current_value
.s
;
398 return LOOKUP_VALUE (current_value
.m
);
402 /* This function works like _dl_lookup_symbol but it takes an
403 additional arguement with the version number of the requested
406 XXX We'll see whether we need this separate function. */
409 _dl_lookup_versioned_symbol (const char *undef_name
,
410 struct link_map
*undef_map
, const ElfW(Sym
) **ref
,
411 struct r_scope_elem
*symbol_scope
[],
412 const struct r_found_version
*version
,
413 int type_class
, int flags
)
415 const unsigned long int hash
= _dl_elf_hash (undef_name
);
416 struct sym_val current_value
= { NULL
, NULL
};
417 struct r_scope_elem
**scope
;
420 bump_num_relocations ();
422 /* No other flag than DL_LOOKUP_ADD_DEPENDENCY is allowed. */
423 assert (flags
== 0 || flags
== DL_LOOKUP_ADD_DEPENDENCY
);
425 /* Search the relevant loaded objects for a definition. */
426 for (scope
= symbol_scope
; *scope
; ++scope
)
428 int res
= do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
429 *scope
, 0, version
, NULL
, type_class
);
433 if (__builtin_expect (res
, 0) < 0)
435 /* Oh, oh. The file named in the relocation entry does not
436 contain the needed symbol. */
437 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
439 /* XXX We cannot translate the message. */
440 _dl_signal_cerror (0, (reference_name
[0]
442 : (rtld_progname
?: "<main program>")),
443 N_("relocation error"),
444 make_string ("symbol ", undef_name
, ", version ",
446 " not defined in file ",
448 " with link time reference",
450 ? " (no version symbols)" : ""));
456 if (__builtin_expect (current_value
.s
== NULL
, 0))
458 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
460 /* We could find no value for a strong reference. */
461 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
463 /* XXX We cannot translate the message. */
464 _dl_signal_cerror (0, (reference_name
[0]
466 : (rtld_progname
?: "<main program>")), NULL
,
467 make_string (undefined_msg
, undef_name
,
469 version
->name
?: NULL
));
475 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
477 if (__builtin_expect (protected != 0, 0))
479 /* It is very tricky. We need to figure out what value to
480 return for the protected symbol. */
481 if (type_class
== ELF_RTYPE_CLASS_PLT
)
483 if (current_value
.s
!= NULL
&& current_value
.m
!= undef_map
)
485 current_value
.s
= *ref
;
486 current_value
.m
= undef_map
;
491 struct sym_val protected_value
= { NULL
, NULL
};
493 for (scope
= symbol_scope
; *scope
; ++scope
)
494 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
496 *scope
, 0, version
, NULL
,
497 ELF_RTYPE_CLASS_PLT
))
500 if (protected_value
.s
!= NULL
501 && protected_value
.m
!= undef_map
)
503 current_value
.s
= *ref
;
504 current_value
.m
= undef_map
;
509 /* We have to check whether this would bind UNDEF_MAP to an object
510 in the global scope which was dynamically loaded. In this case
511 we have to prevent the latter from being unloaded unless the
512 UNDEF_MAP object is also unloaded. */
513 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
514 /* Don't do this for explicit lookups as opposed to implicit
517 /* Add UNDEF_MAP to the dependencies. */
518 && add_dependency (undef_map
, current_value
.m
) < 0)
519 /* Something went wrong. Perhaps the object we tried to reference
520 was just removed. Try finding another definition. */
521 return INTUSE(_dl_lookup_versioned_symbol
) (undef_name
, undef_map
,
523 version
, type_class
, flags
);
525 if (__builtin_expect (GL(dl_debug_mask
)
526 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
527 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
528 ¤t_value
, version
, type_class
, protected);
530 *ref
= current_value
.s
;
531 return LOOKUP_VALUE (current_value
.m
);
533 INTDEF (_dl_lookup_versioned_symbol
)
536 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
537 with the version we are looking for. */
540 _dl_lookup_versioned_symbol_skip (const char *undef_name
,
541 struct link_map
*undef_map
,
542 const ElfW(Sym
) **ref
,
543 struct r_scope_elem
*symbol_scope
[],
544 const struct r_found_version
*version
,
545 struct link_map
*skip_map
)
547 const char *reference_name
= undef_map
->l_name
;
548 const unsigned long int hash
= _dl_elf_hash (undef_name
);
549 struct sym_val current_value
= { NULL
, NULL
};
550 struct r_scope_elem
**scope
;
554 bump_num_relocations ();
556 /* Search the relevant loaded objects for a definition. */
557 scope
= symbol_scope
;
558 for (i
= 0; (*scope
)->r_list
[i
] != skip_map
; ++i
)
559 assert (i
< (*scope
)->r_nlist
);
561 if (! _dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
562 *scope
, i
, version
, skip_map
, 0))
564 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
, ¤t_value
,
565 *scope
, 0, version
, skip_map
, 0))
568 if (__builtin_expect (current_value
.s
== NULL
, 0))
570 if (*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
572 /* We could find no value for a strong reference. */
573 const size_t len
= strlen (undef_name
);
574 char buf
[sizeof undefined_msg
+ len
];
575 __mempcpy (__mempcpy (buf
, undefined_msg
, sizeof undefined_msg
- 1),
576 undef_name
, len
+ 1);
577 /* XXX We cannot translate the messages. */
578 _dl_signal_cerror (0, (reference_name
[0]
580 : (rtld_progname
?: "<main program>")),
587 protected = *ref
&& ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
;
589 if (__builtin_expect (protected != 0, 0))
591 /* It is very tricky. We need to figure out what value to
592 return for the protected symbol. */
593 struct sym_val protected_value
= { NULL
, NULL
};
595 if (i
>= (*scope
)->r_nlist
596 || !_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
597 &protected_value
, *scope
, i
, version
,
598 skip_map
, ELF_RTYPE_CLASS_PLT
))
600 if (_dl_do_lookup_versioned (undef_name
, hash
, *ref
,
601 &protected_value
, *scope
, 0, version
,
602 skip_map
, ELF_RTYPE_CLASS_PLT
))
605 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
607 current_value
.s
= *ref
;
608 current_value
.m
= undef_map
;
612 if (__builtin_expect (GL(dl_debug_mask
)
613 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
614 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
615 ¤t_value
, version
, 0, protected);
617 *ref
= current_value
.s
;
618 return LOOKUP_VALUE (current_value
.m
);
622 /* Cache the location of MAP's hash table. */
626 _dl_setup_hash (struct link_map
*map
)
631 if (!map
->l_info
[DT_HASH
])
633 hash
= (void *) D_PTR (map
, l_info
[DT_HASH
]);
635 map
->l_nbuckets
= *hash
++;
637 map
->l_buckets
= hash
;
638 hash
+= map
->l_nbuckets
;
645 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
646 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
647 struct sym_val
*value
,
648 const struct r_found_version
*version
, int type_class
,
651 const char *reference_name
= undef_map
->l_name
;
653 if (GL(dl_debug_mask
) & DL_DEBUG_BINDINGS
)
655 INTUSE(_dl_debug_printf
) ("binding file %s to %s: %s symbol `%s'",
658 : (rtld_progname
?: "<main program>")),
660 ? value
->m
->l_name
: rtld_progname
,
661 protected ? "protected" : "normal",
664 _dl_debug_printf_c (" [%s]\n", version
->name
);
666 _dl_debug_printf_c ("\n");
669 if (GL(dl_debug_mask
) & DL_DEBUG_PRELINK
)
672 struct sym_val val
= { NULL
, NULL
};
674 if ((GL(dl_trace_prelink_map
) == NULL
675 || GL(dl_trace_prelink_map
) == GL(dl_loaded
))
676 && undef_map
!= GL(dl_loaded
))
678 const unsigned long int hash
= _dl_elf_hash (undef_name
);
681 _dl_do_lookup (undef_name
, hash
, *ref
, &val
,
682 undef_map
->l_local_scope
[0], 0, 0, NULL
,
685 _dl_do_lookup_versioned (undef_name
, hash
, *ref
, &val
,
686 undef_map
->l_local_scope
[0], 0, version
,
689 if (val
.s
!= value
->s
|| val
.m
!= value
->m
)
695 && (__builtin_expect (ELFW(ST_TYPE
) (value
->s
->st_info
)
701 || GL(dl_trace_prelink_map
) == undef_map
702 || GL(dl_trace_prelink_map
) == NULL
705 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
706 conflict
? "conflict" : "lookup",
707 (int) sizeof (ElfW(Addr
)) * 2, undef_map
->l_map_start
,
708 (int) sizeof (ElfW(Addr
)) * 2,
709 ((ElfW(Addr
)) *ref
) - undef_map
->l_map_start
,
710 (int) sizeof (ElfW(Addr
)) * 2,
711 (ElfW(Addr
)) (value
->s
? value
->m
->l_map_start
: 0),
712 (int) sizeof (ElfW(Addr
)) * 2,
713 (ElfW(Addr
)) (value
->s
? value
->s
->st_value
: 0));
716 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
717 (int) sizeof (ElfW(Addr
)) * 2,
718 (ElfW(Addr
)) (val
.s
? val
.m
->l_map_start
: 0),
719 (int) sizeof (ElfW(Addr
)) * 2,
720 (ElfW(Addr
)) (val
.s
? val
.s
->st_value
: 0));
722 _dl_printf ("/%x %s\n", type_class
, undef_name
);
728 /* These are here so that we only inline do_lookup{,_versioned} in the common
729 case, not everywhere. */
730 static int __attribute_noinline__
732 _dl_do_lookup (const char *undef_name
, unsigned long int hash
,
733 const ElfW(Sym
) *ref
, struct sym_val
*result
,
734 struct r_scope_elem
*scope
, size_t i
, int flags
,
735 struct link_map
*skip
, int type_class
)
737 return do_lookup (undef_name
, hash
, ref
, result
, scope
, i
, flags
, skip
,
741 static int __attribute_noinline__
743 _dl_do_lookup_versioned (const char *undef_name
, unsigned long int hash
,
744 const ElfW(Sym
) *ref
, struct sym_val
*result
,
745 struct r_scope_elem
*scope
, size_t i
,
746 const struct r_found_version
*const version
,
747 struct link_map
*skip
, int type_class
)
749 return do_lookup_versioned (undef_name
, hash
, ref
, result
, scope
, i
,
750 version
, skip
, type_class
);