mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-03 08:11:08 +00:00
Update.
2002-04-13 Ulrich Drepper <drepper@redhat.com> * elf/do-lookup.h [!VERSIONED]: Add new parameter flags. Use it to check whether the caller prefers getting the most recent version of a symbol of the earliest version. * elf/dl-lookup.c: Adjust all callers of do_lookup. Change _dl_do_lookup to also take the new parameter and pass it on. Change 'explicit' parameter of _dl_lookup_symbol and _dl_lookup_versioned_symbol to flags. Adjust tests. * sysdeps/generic/ldsodefs.h: Adjust prototypes. * elf/dl-libc.c: Adjust all callers of _dl_lookup_symbol and _dl_lookup_versioned_symbol. * elf/dl-reloc.c: Likewise. * elf/dl-runtime.c: Likewise. * elf/dl-sym.c: Likewise. * sysdeps/mips/dl-machine.h: Likewise.
This commit is contained in:
parent
61bb2ef098
commit
f9f2a150e8
17
ChangeLog
17
ChangeLog
@ -1,3 +1,20 @@
|
|||||||
|
2002-04-13 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* elf/do-lookup.h [!VERSIONED]: Add new parameter flags. Use it to
|
||||||
|
check whether the caller prefers getting the most recent version of
|
||||||
|
a symbol of the earliest version.
|
||||||
|
* elf/dl-lookup.c: Adjust all callers of do_lookup. Change
|
||||||
|
_dl_do_lookup to also take the new parameter and pass it on.
|
||||||
|
Change 'explicit' parameter of _dl_lookup_symbol and
|
||||||
|
_dl_lookup_versioned_symbol to flags. Adjust tests.
|
||||||
|
* sysdeps/generic/ldsodefs.h: Adjust prototypes.
|
||||||
|
* elf/dl-libc.c: Adjust all callers of _dl_lookup_symbol and
|
||||||
|
_dl_lookup_versioned_symbol.
|
||||||
|
* elf/dl-reloc.c: Likewise.
|
||||||
|
* elf/dl-runtime.c: Likewise.
|
||||||
|
* elf/dl-sym.c: Likewise.
|
||||||
|
* sysdeps/mips/dl-machine.h: Likewise.
|
||||||
|
|
||||||
2002-04-11 Jakub Jelinek <jakub@redhat.com>
|
2002-04-11 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h (LOC): Don't paste
|
* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h (LOC): Don't paste
|
||||||
|
@ -84,7 +84,8 @@ do_dlsym (void *ptr)
|
|||||||
struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
|
struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
|
||||||
args->ref = NULL;
|
args->ref = NULL;
|
||||||
args->loadbase = _dl_lookup_symbol (args->name, args->map, &args->ref,
|
args->loadbase = _dl_lookup_symbol (args->name, args->map, &args->ref,
|
||||||
args->map->l_local_scope, 0, 1);
|
args->map->l_local_scope, 0,
|
||||||
|
DL_LOOKUP_RETURN_NEWEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -190,7 +190,7 @@ static int
|
|||||||
internal_function
|
internal_function
|
||||||
_dl_do_lookup (const char *undef_name, unsigned long int hash,
|
_dl_do_lookup (const char *undef_name, unsigned long int hash,
|
||||||
const ElfW(Sym) *ref, struct sym_val *result,
|
const ElfW(Sym) *ref, struct sym_val *result,
|
||||||
struct r_scope_elem *scope, size_t i,
|
struct r_scope_elem *scope, size_t i, int flags,
|
||||||
struct link_map *skip, int type_class);
|
struct link_map *skip, int type_class);
|
||||||
static int
|
static int
|
||||||
internal_function
|
internal_function
|
||||||
@ -215,7 +215,7 @@ lookup_t
|
|||||||
internal_function
|
internal_function
|
||||||
_dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
|
_dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
|
||||||
const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
|
const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
|
||||||
int type_class, int explicit)
|
int type_class, int flags)
|
||||||
{
|
{
|
||||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||||
struct sym_val current_value = { NULL, NULL };
|
struct sym_val current_value = { NULL, NULL };
|
||||||
@ -226,8 +226,8 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
|
|||||||
|
|
||||||
/* Search the relevant loaded objects for a definition. */
|
/* Search the relevant loaded objects for a definition. */
|
||||||
for (scope = symbol_scope; *scope; ++scope)
|
for (scope = symbol_scope; *scope; ++scope)
|
||||||
if (do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, NULL,
|
if (do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, flags,
|
||||||
type_class))
|
NULL, type_class))
|
||||||
{
|
{
|
||||||
/* We have to check whether this would bind UNDEF_MAP to an object
|
/* We have to check whether this would bind UNDEF_MAP to an object
|
||||||
in the global scope which was dynamically loaded. In this case
|
in the global scope which was dynamically loaded. In this case
|
||||||
@ -236,7 +236,7 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
|
|||||||
if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
|
if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
|
||||||
/* Don't do this for explicit lookups as opposed to implicit
|
/* Don't do this for explicit lookups as opposed to implicit
|
||||||
runtime lookups. */
|
runtime lookups. */
|
||||||
&& ! explicit
|
&& (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
|
||||||
/* Add UNDEF_MAP to the dependencies. */
|
/* Add UNDEF_MAP to the dependencies. */
|
||||||
&& add_dependency (undef_map, current_value.m) < 0)
|
&& add_dependency (undef_map, current_value.m) < 0)
|
||||||
/* Something went wrong. Perhaps the object we tried to reference
|
/* Something went wrong. Perhaps the object we tried to reference
|
||||||
@ -272,7 +272,7 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
|
|||||||
|
|
||||||
for (scope = symbol_scope; *scope; ++scope)
|
for (scope = symbol_scope; *scope; ++scope)
|
||||||
if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
|
if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
|
||||||
0, NULL, ELF_RTYPE_CLASS_PLT))
|
0, flags, NULL, ELF_RTYPE_CLASS_PLT))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (protected_value.s != NULL && protected_value.m != undef_map)
|
if (protected_value.s != NULL && protected_value.m != undef_map)
|
||||||
@ -319,10 +319,10 @@ _dl_lookup_symbol_skip (const char *undef_name,
|
|||||||
assert (i < (*scope)->r_nlist);
|
assert (i < (*scope)->r_nlist);
|
||||||
|
|
||||||
if (! _dl_do_lookup (undef_name, hash, *ref, ¤t_value, *scope, i,
|
if (! _dl_do_lookup (undef_name, hash, *ref, ¤t_value, *scope, i,
|
||||||
skip_map, 0))
|
DL_LOOKUP_RETURN_NEWEST, skip_map, 0))
|
||||||
while (*++scope)
|
while (*++scope)
|
||||||
if (_dl_do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0,
|
if (_dl_do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0,
|
||||||
skip_map, 0))
|
DL_LOOKUP_RETURN_NEWEST, skip_map, 0))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (__builtin_expect (current_value.s == NULL, 0))
|
if (__builtin_expect (current_value.s == NULL, 0))
|
||||||
@ -341,10 +341,12 @@ _dl_lookup_symbol_skip (const char *undef_name,
|
|||||||
|
|
||||||
if (i >= (*scope)->r_nlist
|
if (i >= (*scope)->r_nlist
|
||||||
|| !_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
|
|| !_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
|
||||||
i, skip_map, ELF_RTYPE_CLASS_PLT))
|
i, DL_LOOKUP_RETURN_NEWEST, skip_map,
|
||||||
|
ELF_RTYPE_CLASS_PLT))
|
||||||
while (*++scope)
|
while (*++scope)
|
||||||
if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
|
if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
|
||||||
0, skip_map, ELF_RTYPE_CLASS_PLT))
|
0, DL_LOOKUP_RETURN_NEWEST, skip_map,
|
||||||
|
ELF_RTYPE_CLASS_PLT))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (protected_value.s != NULL && protected_value.m != undef_map)
|
if (protected_value.s != NULL && protected_value.m != undef_map)
|
||||||
@ -375,7 +377,7 @@ _dl_lookup_versioned_symbol (const char *undef_name,
|
|||||||
struct link_map *undef_map, const ElfW(Sym) **ref,
|
struct link_map *undef_map, const ElfW(Sym) **ref,
|
||||||
struct r_scope_elem *symbol_scope[],
|
struct r_scope_elem *symbol_scope[],
|
||||||
const struct r_found_version *version,
|
const struct r_found_version *version,
|
||||||
int type_class, int explicit)
|
int type_class, int flags)
|
||||||
{
|
{
|
||||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||||
struct sym_val current_value = { NULL, NULL };
|
struct sym_val current_value = { NULL, NULL };
|
||||||
@ -384,6 +386,9 @@ _dl_lookup_versioned_symbol (const char *undef_name,
|
|||||||
|
|
||||||
bump_num_relocations ();
|
bump_num_relocations ();
|
||||||
|
|
||||||
|
/* No other flag than DL_LOOKUP_ADD_DEPENDENCY is allowed. */
|
||||||
|
assert (flags == 0 || flags == DL_LOOKUP_ADD_DEPENDENCY);
|
||||||
|
|
||||||
/* Search the relevant loaded objects for a definition. */
|
/* Search the relevant loaded objects for a definition. */
|
||||||
for (scope = symbol_scope; *scope; ++scope)
|
for (scope = symbol_scope; *scope; ++scope)
|
||||||
{
|
{
|
||||||
@ -398,14 +403,15 @@ _dl_lookup_versioned_symbol (const char *undef_name,
|
|||||||
if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
|
if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
|
||||||
/* Don't do this for explicit lookups as opposed to implicit
|
/* Don't do this for explicit lookups as opposed to implicit
|
||||||
runtime lookups. */
|
runtime lookups. */
|
||||||
&& ! explicit
|
&& flags != 0
|
||||||
/* Add UNDEF_MAP to the dependencies. */
|
/* Add UNDEF_MAP to the dependencies. */
|
||||||
&& add_dependency (undef_map, current_value.m) < 0)
|
&& add_dependency (undef_map, current_value.m) < 0)
|
||||||
/* Something went wrong. Perhaps the object we tried to reference
|
/* Something went wrong. Perhaps the object we tried to reference
|
||||||
was just removed. Try finding another definition. */
|
was just removed. Try finding another definition. */
|
||||||
return INTUSE(_dl_lookup_versioned_symbol) (undef_name, undef_map,
|
return INTUSE(_dl_lookup_versioned_symbol) (undef_name, undef_map,
|
||||||
ref, symbol_scope,
|
ref, symbol_scope,
|
||||||
version, type_class, 0);
|
version, type_class,
|
||||||
|
0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -590,12 +596,14 @@ _dl_setup_hash (struct link_map *map)
|
|||||||
map->l_chain = hash;
|
map->l_chain = hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
internal_function
|
internal_function
|
||||||
_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
|
_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
|
||||||
const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
|
const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
|
||||||
struct sym_val *value, const struct r_found_version *version,
|
struct sym_val *value,
|
||||||
int type_class, int protected)
|
const struct r_found_version *version, int type_class,
|
||||||
|
int protected)
|
||||||
{
|
{
|
||||||
const char *reference_name = undef_map->l_name;
|
const char *reference_name = undef_map->l_name;
|
||||||
|
|
||||||
@ -628,7 +636,8 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
|
|||||||
|
|
||||||
if (version == 0)
|
if (version == 0)
|
||||||
_dl_do_lookup (undef_name, hash, *ref, &val,
|
_dl_do_lookup (undef_name, hash, *ref, &val,
|
||||||
undef_map->l_local_scope[0], 0, NULL, type_class);
|
undef_map->l_local_scope[0], 0, 0, NULL,
|
||||||
|
type_class);
|
||||||
else
|
else
|
||||||
_dl_do_lookup_versioned (undef_name, hash, *ref, &val,
|
_dl_do_lookup_versioned (undef_name, hash, *ref, &val,
|
||||||
undef_map->l_local_scope[0], 0, version,
|
undef_map->l_local_scope[0], 0, version,
|
||||||
@ -671,10 +680,10 @@ static int __attribute_noinline__
|
|||||||
internal_function
|
internal_function
|
||||||
_dl_do_lookup (const char *undef_name, unsigned long int hash,
|
_dl_do_lookup (const char *undef_name, unsigned long int hash,
|
||||||
const ElfW(Sym) *ref, struct sym_val *result,
|
const ElfW(Sym) *ref, struct sym_val *result,
|
||||||
struct r_scope_elem *scope, size_t i,
|
struct r_scope_elem *scope, size_t i, int flags,
|
||||||
struct link_map *skip, int type_class)
|
struct link_map *skip, int type_class)
|
||||||
{
|
{
|
||||||
return do_lookup (undef_name, hash, ref, result, scope, i, skip,
|
return do_lookup (undef_name, hash, ref, result, scope, i, flags, skip,
|
||||||
type_class);
|
type_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
|||||||
l, (ref), scope, \
|
l, (ref), scope, \
|
||||||
(version), _tc, 0) \
|
(version), _tc, 0) \
|
||||||
: INTUSE(_dl_lookup_symbol) (strtab + (*ref)->st_name, l, \
|
: INTUSE(_dl_lookup_symbol) (strtab + (*ref)->st_name, l, \
|
||||||
(ref), scope, _tc, 0)); \
|
(ref), scope, _tc, \
|
||||||
|
DL_LOOKUP_ADD_DEPENDENCY)); \
|
||||||
l->l_lookup_cache.ret = (*ref); \
|
l->l_lookup_cache.ret = (*ref); \
|
||||||
l->l_lookup_cache.value = _lr; })) \
|
l->l_lookup_cache.value = _lr; })) \
|
||||||
: l)
|
: l)
|
||||||
@ -152,7 +153,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
|||||||
l, (ref), scope, \
|
l, (ref), scope, \
|
||||||
(version), _tc, 0) \
|
(version), _tc, 0) \
|
||||||
: INTUSE(_dl_lookup_symbol) (strtab + (*ref)->st_name, l, \
|
: INTUSE(_dl_lookup_symbol) (strtab + (*ref)->st_name, l, \
|
||||||
(ref), scope, _tc, 0)); \
|
(ref), scope, _tc, \
|
||||||
|
DL_LOOKUP_ADD_DEPENDENCY)); \
|
||||||
l->l_lookup_cache.ret = (*ref); \
|
l->l_lookup_cache.ret = (*ref); \
|
||||||
l->l_lookup_cache.value = _lr; })) \
|
l->l_lookup_cache.value = _lr; })) \
|
||||||
: l->l_addr)
|
: l->l_addr)
|
||||||
|
@ -98,7 +98,8 @@ fixup (
|
|||||||
}
|
}
|
||||||
case 0:
|
case 0:
|
||||||
result = INTUSE(_dl_lookup_symbol) (strtab + sym->st_name, l, &sym,
|
result = INTUSE(_dl_lookup_symbol) (strtab + sym->st_name, l, &sym,
|
||||||
l->l_scope, ELF_RTYPE_CLASS_PLT, 0);
|
l->l_scope, ELF_RTYPE_CLASS_PLT,
|
||||||
|
DL_LOOKUP_ADD_DEPENDENCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Currently result contains the base load address (or link map)
|
/* Currently result contains the base load address (or link map)
|
||||||
@ -192,9 +193,10 @@ profile_fixup (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 0:
|
case 0:
|
||||||
result = INTUSE(_dl_lookup_symbol) (strtab + sym->st_name, l, &sym,
|
result = INTUSE(_dl_lookup_symbol) (strtab + sym->st_name, l,
|
||||||
l->l_scope, ELF_RTYPE_CLASS_PLT,
|
&sym, l->l_scope,
|
||||||
0);
|
ELF_RTYPE_CLASS_PLT,
|
||||||
|
DL_LOOKUP_ADD_DEPENDENCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Currently result contains the base load address (or link map)
|
/* Currently result contains the base load address (or link map)
|
||||||
|
10
elf/dl-sym.c
10
elf/dl-sym.c
@ -51,7 +51,9 @@ _dl_sym (void *handle, const char *name, void *who)
|
|||||||
|
|
||||||
if (handle == RTLD_DEFAULT)
|
if (handle == RTLD_DEFAULT)
|
||||||
/* Search the global scope as seen in the caller object. */
|
/* Search the global scope as seen in the caller object. */
|
||||||
result = _dl_lookup_symbol (name, match, &ref, match->l_scope, 0, 0);
|
result = _dl_lookup_symbol (name, match, &ref, match->l_scope, 0,
|
||||||
|
DL_LOOKUP_RETURN_NEWEST
|
||||||
|
| DL_LOOKUP_ADD_DEPENDENCY);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (handle != RTLD_NEXT)
|
if (handle != RTLD_NEXT)
|
||||||
@ -60,7 +62,7 @@ _dl_sym (void *handle, const char *name, void *who)
|
|||||||
struct link_map *map = handle;
|
struct link_map *map = handle;
|
||||||
|
|
||||||
result = _dl_lookup_symbol (name, match, &ref, map->l_local_scope,
|
result = _dl_lookup_symbol (name, match, &ref, map->l_local_scope,
|
||||||
0, 1);
|
0, DL_LOOKUP_RETURN_NEWEST);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -132,7 +134,7 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who)
|
|||||||
if (handle == RTLD_DEFAULT)
|
if (handle == RTLD_DEFAULT)
|
||||||
/* Search the global scope. */
|
/* Search the global scope. */
|
||||||
result = _dl_lookup_versioned_symbol (name, match, &ref, match->l_scope,
|
result = _dl_lookup_versioned_symbol (name, match, &ref, match->l_scope,
|
||||||
&vers, 0, 0);
|
&vers, 0, DL_LOOKUP_ADD_DEPENDENCY);
|
||||||
else if (handle == RTLD_NEXT)
|
else if (handle == RTLD_NEXT)
|
||||||
{
|
{
|
||||||
if (__builtin_expect (match == GL(dl_loaded), 0))
|
if (__builtin_expect (match == GL(dl_loaded), 0))
|
||||||
@ -157,7 +159,7 @@ RTLD_NEXT used in code not dynamically loaded"));
|
|||||||
/* Search the scope of the given object. */
|
/* Search the scope of the given object. */
|
||||||
struct link_map *map = handle;
|
struct link_map *map = handle;
|
||||||
result = _dl_lookup_versioned_symbol (name, map, &ref,
|
result = _dl_lookup_versioned_symbol (name, map, &ref,
|
||||||
map->l_local_scope, &vers, 0, 1);
|
map->l_local_scope, &vers, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ref != NULL)
|
if (ref != NULL)
|
||||||
|
@ -19,10 +19,10 @@
|
|||||||
|
|
||||||
#if VERSIONED
|
#if VERSIONED
|
||||||
# define FCT do_lookup_versioned
|
# define FCT do_lookup_versioned
|
||||||
# define ARG const struct r_found_version *const version,
|
# define ARG const struct r_found_version *const version
|
||||||
#else
|
#else
|
||||||
# define FCT do_lookup
|
# define FCT do_lookup
|
||||||
# define ARG
|
# define ARG int flags
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Inner part of the lookup functions. We return a value > 0 if we
|
/* Inner part of the lookup functions. We return a value > 0 if we
|
||||||
@ -30,7 +30,7 @@
|
|||||||
something bad happened. */
|
something bad happened. */
|
||||||
static inline int
|
static inline int
|
||||||
FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref,
|
FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref,
|
||||||
struct sym_val *result, struct r_scope_elem *scope, size_t i, ARG
|
struct sym_val *result, struct r_scope_elem *scope, size_t i, ARG,
|
||||||
struct link_map *skip, int type_class)
|
struct link_map *skip, int type_class)
|
||||||
{
|
{
|
||||||
struct link_map **list = scope->r_list;
|
struct link_map **list = scope->r_list;
|
||||||
@ -129,19 +129,34 @@ FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* No specific version is selected. When the object file
|
/* No specific version is selected. There are two ways we
|
||||||
also does not define a version we have a match.
|
can got here:
|
||||||
Otherwise we accept the default version, or in case there
|
|
||||||
is only one version defined, this one version. */
|
- a binary which does not include versioning information
|
||||||
|
is loaded
|
||||||
|
|
||||||
|
- dlsym() instead of dlvsym() is used to get a symbol which
|
||||||
|
might exist in more than one form
|
||||||
|
|
||||||
|
If the library does not provide symbol version
|
||||||
|
information there is no problem at at: we simply use the
|
||||||
|
symbol if it is defined.
|
||||||
|
|
||||||
|
These two lookups need to be handled differently if the
|
||||||
|
library defines versions. In the case of the old
|
||||||
|
unversioned application the oldest (default) version
|
||||||
|
should be used. In case of a dlsym() call the latest and
|
||||||
|
public interface should be returned. */
|
||||||
if (verstab != NULL)
|
if (verstab != NULL)
|
||||||
{
|
{
|
||||||
ElfW(Half) ndx = verstab[symidx] & 0x7fff;
|
if ((verstab[symidx] & 0x7fff)
|
||||||
if (ndx >= 2) /* map->l_versions[ndx].hash != 0) */
|
>= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3))
|
||||||
{
|
{
|
||||||
/* Don't accept hidden symbols. */
|
/* Don't accept hidden symbols. */
|
||||||
if ((verstab[symidx] & 0x8000) == 0 && num_versions++ == 0)
|
if ((verstab[symidx] & 0x8000) == 0 && num_versions++ == 0)
|
||||||
/* No version so far. */
|
/* No version so far. */
|
||||||
versioned_sym = sym;
|
versioned_sym = sym;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -532,15 +532,24 @@ extern lookup_t _dl_lookup_symbol (const char *undef,
|
|||||||
struct link_map *undef_map,
|
struct link_map *undef_map,
|
||||||
const ElfW(Sym) **sym,
|
const ElfW(Sym) **sym,
|
||||||
struct r_scope_elem *symbol_scope[],
|
struct r_scope_elem *symbol_scope[],
|
||||||
int type_class, int explicit)
|
int type_class, int flags)
|
||||||
internal_function;
|
internal_function;
|
||||||
extern lookup_t _dl_lookup_symbol_internal (const char *undef,
|
extern lookup_t _dl_lookup_symbol_internal (const char *undef,
|
||||||
struct link_map *undef_map,
|
struct link_map *undef_map,
|
||||||
const ElfW(Sym) **sym,
|
const ElfW(Sym) **sym,
|
||||||
struct r_scope_elem *symbol_scope[],
|
struct r_scope_elem *symbol_scope[],
|
||||||
int type_class, int explicit)
|
int type_class, int flags)
|
||||||
internal_function;
|
internal_function;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
/* If necessary add dependency between user and provider object. */
|
||||||
|
DL_LOOKUP_ADD_DEPENDENCY = 1,
|
||||||
|
/* Return most recent version instead of default version for
|
||||||
|
unversioned lookup. */
|
||||||
|
DL_LOOKUP_RETURN_NEWEST = 2
|
||||||
|
};
|
||||||
|
|
||||||
/* Lookup versioned symbol. */
|
/* Lookup versioned symbol. */
|
||||||
extern lookup_t _dl_lookup_versioned_symbol (const char *undef,
|
extern lookup_t _dl_lookup_versioned_symbol (const char *undef,
|
||||||
struct link_map *undef_map,
|
struct link_map *undef_map,
|
||||||
|
@ -307,7 +307,8 @@ __dl_runtime_resolve (ElfW(Word) sym_index, \
|
|||||||
} \
|
} \
|
||||||
case 0: \
|
case 0: \
|
||||||
value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym, \
|
value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym, \
|
||||||
l->l_scope, ELF_RTYPE_CLASS_PLT, 0); \
|
l->l_scope, ELF_RTYPE_CLASS_PLT, \
|
||||||
|
DL_LOOKUP_ADD_DEPENDENCY); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* Currently value contains the base load address of the object \
|
/* Currently value contains the base load address of the object \
|
||||||
|
Loading…
Reference in New Issue
Block a user