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>
|
||||
|
||||
* 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;
|
||||
args->ref = NULL;
|
||||
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
|
||||
|
@ -190,7 +190,7 @@ static int
|
||||
internal_function
|
||||
_dl_do_lookup (const char *undef_name, unsigned long int hash,
|
||||
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);
|
||||
static int
|
||||
internal_function
|
||||
@ -215,7 +215,7 @@ lookup_t
|
||||
internal_function
|
||||
_dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
|
||||
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);
|
||||
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. */
|
||||
for (scope = symbol_scope; *scope; ++scope)
|
||||
if (do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, NULL,
|
||||
type_class))
|
||||
if (do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, flags,
|
||||
NULL, type_class))
|
||||
{
|
||||
/* We have to check whether this would bind UNDEF_MAP to an object
|
||||
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)
|
||||
/* Don't do this for explicit lookups as opposed to implicit
|
||||
runtime lookups. */
|
||||
&& ! explicit
|
||||
&& (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
|
||||
/* Add UNDEF_MAP to the dependencies. */
|
||||
&& add_dependency (undef_map, current_value.m) < 0)
|
||||
/* 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)
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
if (! _dl_do_lookup (undef_name, hash, *ref, ¤t_value, *scope, i,
|
||||
skip_map, 0))
|
||||
DL_LOOKUP_RETURN_NEWEST, skip_map, 0))
|
||||
while (*++scope)
|
||||
if (_dl_do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0,
|
||||
skip_map, 0))
|
||||
DL_LOOKUP_RETURN_NEWEST, skip_map, 0))
|
||||
break;
|
||||
|
||||
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
|
||||
|| !_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)
|
||||
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;
|
||||
|
||||
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 r_scope_elem *symbol_scope[],
|
||||
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);
|
||||
struct sym_val current_value = { NULL, NULL };
|
||||
@ -384,6 +386,9 @@ _dl_lookup_versioned_symbol (const char *undef_name,
|
||||
|
||||
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. */
|
||||
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)
|
||||
/* Don't do this for explicit lookups as opposed to implicit
|
||||
runtime lookups. */
|
||||
&& ! explicit
|
||||
&& flags != 0
|
||||
/* Add UNDEF_MAP to the dependencies. */
|
||||
&& add_dependency (undef_map, current_value.m) < 0)
|
||||
/* Something went wrong. Perhaps the object we tried to reference
|
||||
was just removed. Try finding another definition. */
|
||||
return INTUSE(_dl_lookup_versioned_symbol) (undef_name, undef_map,
|
||||
ref, symbol_scope,
|
||||
version, type_class, 0);
|
||||
version, type_class,
|
||||
0);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -590,12 +596,14 @@ _dl_setup_hash (struct link_map *map)
|
||||
map->l_chain = hash;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
internal_function
|
||||
_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
|
||||
const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
|
||||
struct sym_val *value, const struct r_found_version *version,
|
||||
int type_class, int protected)
|
||||
struct sym_val *value,
|
||||
const struct r_found_version *version, int type_class,
|
||||
int protected)
|
||||
{
|
||||
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)
|
||||
_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
|
||||
_dl_do_lookup_versioned (undef_name, hash, *ref, &val,
|
||||
undef_map->l_local_scope[0], 0, version,
|
||||
@ -671,10 +680,10 @@ static int __attribute_noinline__
|
||||
internal_function
|
||||
_dl_do_lookup (const char *undef_name, unsigned long int hash,
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
l, (ref), scope, \
|
||||
(version), _tc, 0) \
|
||||
: 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.value = _lr; })) \
|
||||
: l)
|
||||
@ -152,7 +153,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
l, (ref), scope, \
|
||||
(version), _tc, 0) \
|
||||
: 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.value = _lr; })) \
|
||||
: l->l_addr)
|
||||
|
@ -98,7 +98,8 @@ fixup (
|
||||
}
|
||||
case 0:
|
||||
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)
|
||||
@ -192,9 +193,10 @@ profile_fixup (
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
result = INTUSE(_dl_lookup_symbol) (strtab + sym->st_name, l, &sym,
|
||||
l->l_scope, ELF_RTYPE_CLASS_PLT,
|
||||
0);
|
||||
result = INTUSE(_dl_lookup_symbol) (strtab + sym->st_name, l,
|
||||
&sym, l->l_scope,
|
||||
ELF_RTYPE_CLASS_PLT,
|
||||
DL_LOOKUP_ADD_DEPENDENCY);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
/* 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
|
||||
{
|
||||
if (handle != RTLD_NEXT)
|
||||
@ -60,7 +62,7 @@ _dl_sym (void *handle, const char *name, void *who)
|
||||
struct link_map *map = handle;
|
||||
|
||||
result = _dl_lookup_symbol (name, match, &ref, map->l_local_scope,
|
||||
0, 1);
|
||||
0, DL_LOOKUP_RETURN_NEWEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -132,7 +134,7 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who)
|
||||
if (handle == RTLD_DEFAULT)
|
||||
/* Search the global 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)
|
||||
{
|
||||
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. */
|
||||
struct link_map *map = handle;
|
||||
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)
|
||||
|
@ -19,10 +19,10 @@
|
||||
|
||||
#if 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
|
||||
# define FCT do_lookup
|
||||
# define ARG
|
||||
# define ARG int flags
|
||||
#endif
|
||||
|
||||
/* Inner part of the lookup functions. We return a value > 0 if we
|
||||
@ -30,7 +30,7 @@
|
||||
something bad happened. */
|
||||
static inline int
|
||||
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 **list = scope->r_list;
|
||||
@ -129,19 +129,34 @@ FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref,
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
/* No specific version is selected. When the object file
|
||||
also does not define a version we have a match.
|
||||
Otherwise we accept the default version, or in case there
|
||||
is only one version defined, this one version. */
|
||||
/* No specific version is selected. There are two ways we
|
||||
can got here:
|
||||
|
||||
- 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)
|
||||
{
|
||||
ElfW(Half) ndx = verstab[symidx] & 0x7fff;
|
||||
if (ndx >= 2) /* map->l_versions[ndx].hash != 0) */
|
||||
if ((verstab[symidx] & 0x7fff)
|
||||
>= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3))
|
||||
{
|
||||
/* Don't accept hidden symbols. */
|
||||
if ((verstab[symidx] & 0x8000) == 0 && num_versions++ == 0)
|
||||
/* No version so far. */
|
||||
versioned_sym = sym;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -532,15 +532,24 @@ extern lookup_t _dl_lookup_symbol (const char *undef,
|
||||
struct link_map *undef_map,
|
||||
const ElfW(Sym) **sym,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
int type_class, int explicit)
|
||||
int type_class, int flags)
|
||||
internal_function;
|
||||
extern lookup_t _dl_lookup_symbol_internal (const char *undef,
|
||||
struct link_map *undef_map,
|
||||
const ElfW(Sym) **sym,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
int type_class, int explicit)
|
||||
int type_class, int flags)
|
||||
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. */
|
||||
extern lookup_t _dl_lookup_versioned_symbol (const char *undef,
|
||||
struct link_map *undef_map,
|
||||
|
@ -307,7 +307,8 @@ __dl_runtime_resolve (ElfW(Word) sym_index, \
|
||||
} \
|
||||
case 0: \
|
||||
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 \
|
||||
|
Loading…
Reference in New Issue
Block a user