Skip to content

Commit

Permalink
Update.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Ulrich Drepper committed Apr 13, 2002
1 parent 61bb2ef commit f9f2a15
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 41 deletions.
17 changes: 17 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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
Expand Down
3 changes: 2 additions & 1 deletion elf/dl-libc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
45 changes: 27 additions & 18 deletions elf/dl-lookup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 };
Expand All @@ -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, &current_value, *scope, 0, NULL,
type_class))
if (do_lookup (undef_name, hash, *ref, &current_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
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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, &current_value, *scope, i,
skip_map, 0))
DL_LOOKUP_RETURN_NEWEST, skip_map, 0))
while (*++scope)
if (_dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, 0,
skip_map, 0))
DL_LOOKUP_RETURN_NEWEST, skip_map, 0))
break;

if (__builtin_expect (current_value.s == NULL, 0))
Expand All @@ -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)
Expand Down Expand Up @@ -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 };
Expand All @@ -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)
{
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}

Expand Down
6 changes: 4 additions & 2 deletions elf/dl-reloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
10 changes: 6 additions & 4 deletions elf/dl-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 6 additions & 4 deletions elf/dl-sym.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
{
Expand Down Expand Up @@ -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))
Expand All @@ -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)
Expand Down
33 changes: 24 additions & 9 deletions elf/do-lookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@

#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
found the symbol, the value 0 if nothing is found and < 0 if
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;
Expand Down Expand Up @@ -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;
}
}
Expand Down
13 changes: 11 additions & 2 deletions sysdeps/generic/ldsodefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion sysdeps/mips/dl-machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down

0 comments on commit f9f2a15

Please sign in to comment.