mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 17:53:37 +08:00
Update.
2004-03-06 Ulrich Drepper <drepper@redhat.com> * elf/dl-lookup.c: We don't need for specialized lookup functions. Combining the functionality does not slow down relocation processing, it might even speed it up a little. * sysdeps/generic/ldsodefs.h: Adjust prototypes for lookup function. Add only one function pointer to rtlf_global_ro. * elf/do-lookup.h: Replace #ifs with ifs. * elf/dl-libc.c: Adjust _dl_lookup_* callers. * elf/dl-reloc.c: Likewise. * elf/dl-runtime.c: Likewise. * elf/dl-sym.c: Likewise. * elf/rtld.c: Likewise. Adjust _rtld_global_ro initialization. * sysdeps/generic/ldsodefs.h (__rtld_local_attribute__, __rtld_global_attribute__): Undef after use. (_rtld_local_ro): Define __rtld_local_attribute__ with just hidden if available. * sysdeps/alpha/Subdirs: New file. * sysdeps/alpha/soft-fp/Makefile: New file. * sysdeps/alpha/soft-fp/Versions: New file. * sysdeps/alpha/soft-fp/local-soft-fp.h: New file. * sysdeps/alpha/soft-fp/ots_add.c: New file. * sysdeps/alpha/soft-fp/ots_cmp.c: new file. * sysdeps/alpha/soft-fp/ots_cmpe.c: New file. * sysdeps/alpha/soft-fp/ots_cvtqux.c: New file. * sysdeps/alpha/soft-fp/ots_cvtqx.c: New file. * sysdeps/alpha/soft-fp/ots_cvttx.c: New file. * sysdeps/alpha/soft-fp/ots_cvtxq.c: New file. * sysdeps/alpha/soft-fp/ots_cvtxt.c: New file. * sysdeps/alpha/soft-fp/ots_div.c: New file. * sysdeps/alpha/soft-fp/ots_mul.c: New file. * sysdeps/alpha/soft-fp/ots_nintxq.c: New file. * sysdeps/alpha/soft-fp/ots_sub.c: New file.
This commit is contained in:
parent
bdf4a4f1ea
commit
021723ab78
44
ChangeLog
44
ChangeLog
@ -1,17 +1,43 @@
|
||||
2004-03-06 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* elf/dl-lookup.c: We don't need for specialized lookup functions.
|
||||
Combining the functionality does not slow down relocation processing,
|
||||
it might even speed it up a little.
|
||||
* sysdeps/generic/ldsodefs.h: Adjust prototypes for lookup function.
|
||||
Add only one function pointer to rtlf_global_ro.
|
||||
* elf/do-lookup.h: Replace #ifs with ifs.
|
||||
* elf/dl-libc.c: Adjust _dl_lookup_* callers.
|
||||
* elf/dl-reloc.c: Likewise.
|
||||
* elf/dl-runtime.c: Likewise.
|
||||
* elf/dl-sym.c: Likewise.
|
||||
* elf/rtld.c: Likewise. Adjust _rtld_global_ro initialization.
|
||||
|
||||
2004-03-06 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* sysdeps/generic/ldsodefs.h (__rtld_local_attribute__,
|
||||
__rtld_global_attribute__): Undef after use.
|
||||
(_rtld_local_ro): Define __rtld_local_attribute__ with just hidden
|
||||
if available.
|
||||
|
||||
* soft-fp/quad.h (union _FP_UNION_Q): Add longs structure.
|
||||
* sysdeps/alpha/Implies: Add alpha/soft-fp.
|
||||
* sysdeps/alpha/soft-fp/sfp-machine.h: Rewrite for GEM interface.
|
||||
* sysdeps/alpha/Subdirs, sysdeps/alpha/soft-fp/Makefile,
|
||||
sysdeps/alpha/soft-fp/Versions, sysdeps/alpha/soft-fp/local-soft-fp.h,
|
||||
sysdeps/alpha/soft-fp/ots_add.c, sysdeps/alpha/soft-fp/ots_cmp.c,
|
||||
sysdeps/alpha/soft-fp/ots_cmpe.c, sysdeps/alpha/soft-fp/ots_cvtqux.c,
|
||||
sysdeps/alpha/soft-fp/ots_cvtqx.c, sysdeps/alpha/soft-fp/ots_cvttx.c,
|
||||
sysdeps/alpha/soft-fp/ots_cvtxq.c, sysdeps/alpha/soft-fp/ots_cvtxt.c,
|
||||
sysdeps/alpha/soft-fp/ots_div.c, sysdeps/alpha/soft-fp/ots_mul.c,
|
||||
sysdeps/alpha/soft-fp/ots_nintxq.c, sysdeps/alpha/soft-fp/ots_sub.c:
|
||||
New files.
|
||||
* sysdeps/alpha/Subdirs: New file.
|
||||
* sysdeps/alpha/soft-fp/Makefile: New file.
|
||||
* sysdeps/alpha/soft-fp/Versions: New file.
|
||||
* sysdeps/alpha/soft-fp/local-soft-fp.h: New file.
|
||||
* sysdeps/alpha/soft-fp/ots_add.c: New file.
|
||||
* sysdeps/alpha/soft-fp/ots_cmp.c: new file.
|
||||
* sysdeps/alpha/soft-fp/ots_cmpe.c: New file.
|
||||
* sysdeps/alpha/soft-fp/ots_cvtqux.c: New file.
|
||||
* sysdeps/alpha/soft-fp/ots_cvtqx.c: New file.
|
||||
* sysdeps/alpha/soft-fp/ots_cvttx.c: New file.
|
||||
* sysdeps/alpha/soft-fp/ots_cvtxq.c: New file.
|
||||
* sysdeps/alpha/soft-fp/ots_cvtxt.c: New file.
|
||||
* sysdeps/alpha/soft-fp/ots_div.c: New file.
|
||||
* sysdeps/alpha/soft-fp/ots_mul.c: New file.
|
||||
* sysdeps/alpha/soft-fp/ots_nintxq.c: New file.
|
||||
* sysdeps/alpha/soft-fp/ots_sub.c: New file.
|
||||
|
||||
2004-03-06 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
|
@ -85,9 +85,9 @@ do_dlsym (void *ptr)
|
||||
{
|
||||
struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
|
||||
args->ref = NULL;
|
||||
args->loadbase = GLRO(dl_lookup_symbol) (args->name, args->map, &args->ref,
|
||||
args->map->l_local_scope, 0,
|
||||
DL_LOOKUP_RETURN_NEWEST);
|
||||
args->loadbase = GLRO(dl_lookup_symbol_x) (args->name, args->map, &args->ref,
|
||||
args->map->l_local_scope, NULL, 0,
|
||||
DL_LOOKUP_RETURN_NEWEST, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -126,9 +126,8 @@ do_dlsym_private (void *ptr)
|
||||
|
||||
struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
|
||||
args->ref = NULL;
|
||||
l = GLRO(dl_lookup_versioned_symbol) (args->name, args->map,
|
||||
&args->ref, args->map->l_scope,
|
||||
&vers, 0, 0);
|
||||
l = GLRO(dl_lookup_symbol_x) (args->name, args->map, &args->ref,
|
||||
args->map->l_scope, &vers, 0, 0, NULL);
|
||||
args->loadbase = l;
|
||||
}
|
||||
|
||||
|
@ -213,13 +213,15 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
int _tc = elf_machine_type_class (r_type); \
|
||||
l->l_lookup_cache.type_class = _tc; \
|
||||
l->l_lookup_cache.sym = (*ref); \
|
||||
_lr = ((version) != NULL && (version)->hash != 0 \
|
||||
? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, \
|
||||
l, (ref), scope, (version),\
|
||||
_tc, 0) \
|
||||
: _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref), \
|
||||
scope, _tc, \
|
||||
DL_LOOKUP_ADD_DEPENDENCY)); \
|
||||
const struct r_found_version *v = NULL; \
|
||||
int flags = DL_LOOKUP_ADD_DEPENDENCY; \
|
||||
if ((version) != NULL && (version)->hash != 0) \
|
||||
{ \
|
||||
v = (version); \
|
||||
flags = 0; \
|
||||
} \
|
||||
_lr = _dl_lookup_symbol_x (strtab + (*ref)->st_name, l, (ref), \
|
||||
scope, v, _tc, flags, NULL); \
|
||||
l->l_lookup_cache.ret = (*ref); \
|
||||
l->l_lookup_cache.value = _lr; })) \
|
||||
: l)
|
||||
@ -234,13 +236,15 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
int _tc = elf_machine_type_class (r_type); \
|
||||
l->l_lookup_cache.type_class = _tc; \
|
||||
l->l_lookup_cache.sym = (*ref); \
|
||||
_lr = ((version) != NULL && (version)->hash != 0 \
|
||||
? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, \
|
||||
l, (ref), scope, \
|
||||
(version), _tc, 0) \
|
||||
: _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref), \
|
||||
scope, _tc, \
|
||||
DL_LOOKUP_ADD_DEPENDENCY)); \
|
||||
const struct r_found_version *v = NULL; \
|
||||
int flags = DL_LOOKUP_ADD_DEPENDENCY; \
|
||||
if ((version) != NULL && (version)->hash != 0) \
|
||||
{ \
|
||||
v = (version); \
|
||||
flags = 0; \
|
||||
} \
|
||||
_lr = _dl_lookup_symbol_x (strtab + (*ref)->st_name, l, (ref), \
|
||||
scope, v, _tc, flags, NULL); \
|
||||
l->l_lookup_cache.ret = (*ref); \
|
||||
l->l_lookup_cache.value = _lr; })) \
|
||||
: l->l_addr)
|
||||
|
@ -73,30 +73,26 @@ fixup (
|
||||
used don't look in the global scope. */
|
||||
if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
|
||||
{
|
||||
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
|
||||
{
|
||||
default:
|
||||
{
|
||||
const ElfW(Half) *vernum =
|
||||
(const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);
|
||||
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff;
|
||||
const struct r_found_version *version = &l->l_versions[ndx];
|
||||
const struct r_found_version *version = NULL;
|
||||
// XXX Why exactly do we have the differentiation of the flags here?
|
||||
int flags = DL_LOOKUP_ADD_DEPENDENCY;
|
||||
|
||||
if (version->hash != 0)
|
||||
{
|
||||
result = _dl_lookup_versioned_symbol (strtab + sym->st_name,
|
||||
l, &sym, l->l_scope,
|
||||
version,
|
||||
ELF_RTYPE_CLASS_PLT, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
result = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,
|
||||
l->l_scope, ELF_RTYPE_CLASS_PLT,
|
||||
DL_LOOKUP_ADD_DEPENDENCY);
|
||||
if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
|
||||
{
|
||||
const ElfW(Half) *vernum =
|
||||
(const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);
|
||||
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff;
|
||||
version = &l->l_versions[ndx];
|
||||
if (version->hash == 0)
|
||||
version = NULL;
|
||||
else
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
|
||||
l->l_scope, version, ELF_RTYPE_CLASS_PLT,
|
||||
DL_LOOKUP_ADD_DEPENDENCY, NULL);
|
||||
|
||||
/* Currently result contains the base load address (or link map)
|
||||
of the object that defines sym. Now add in the symbol
|
||||
offset. */
|
||||
@ -161,32 +157,27 @@ profile_fixup (
|
||||
don't look in the global scope. */
|
||||
if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
|
||||
{
|
||||
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
|
||||
{
|
||||
default:
|
||||
{
|
||||
const ElfW(Half) *vernum =
|
||||
(const void *) D_PTR (l,l_info[VERSYMIDX (DT_VERSYM)]);
|
||||
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff;
|
||||
const struct r_found_version *version = &l->l_versions[ndx];
|
||||
const struct r_found_version *version = NULL;
|
||||
// XXX Why exactly do we have the differentiation of the flags here?
|
||||
int flags = DL_LOOKUP_ADD_DEPENDENCY;
|
||||
|
||||
if (version->hash != 0)
|
||||
{
|
||||
result = _dl_lookup_versioned_symbol (strtab
|
||||
+ sym->st_name,
|
||||
l, &sym, l->l_scope,
|
||||
version,
|
||||
ELF_RTYPE_CLASS_PLT,
|
||||
0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
result = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,
|
||||
l->l_scope, ELF_RTYPE_CLASS_PLT,
|
||||
DL_LOOKUP_ADD_DEPENDENCY);
|
||||
if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
|
||||
{
|
||||
const ElfW(Half) *vernum =
|
||||
(const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);
|
||||
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff;
|
||||
version = &l->l_versions[ndx];
|
||||
if (version->hash == 0)
|
||||
version = NULL;
|
||||
else
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
|
||||
l->l_scope, version,
|
||||
ELF_RTYPE_CLASS_PLT,
|
||||
DL_LOOKUP_ADD_DEPENDENCY, NULL);
|
||||
|
||||
/* Currently result contains the base load address (or link map)
|
||||
of the object that defines sym. Now add in the symbol
|
||||
offset. */
|
||||
|
32
elf/dl-sym.c
32
elf/dl-sym.c
@ -82,9 +82,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 = GLRO(dl_lookup_symbol) (name, match, &ref, match->l_scope, 0,
|
||||
DL_LOOKUP_RETURN_NEWEST
|
||||
| DL_LOOKUP_ADD_DEPENDENCY);
|
||||
result = GLRO(dl_lookup_symbol_x) (name, match, &ref, match->l_scope, NULL,
|
||||
0, (DL_LOOKUP_RETURN_NEWEST
|
||||
| DL_LOOKUP_ADD_DEPENDENCY), NULL);
|
||||
else
|
||||
{
|
||||
if (handle != RTLD_NEXT)
|
||||
@ -92,9 +92,9 @@ _dl_sym (void *handle, const char *name, void *who)
|
||||
/* Search the scope of the given object. */
|
||||
struct link_map *map = handle;
|
||||
|
||||
result = GLRO(dl_lookup_symbol) (name, match, &ref,
|
||||
map->l_local_scope, 0,
|
||||
DL_LOOKUP_RETURN_NEWEST);
|
||||
result = GLRO(dl_lookup_symbol_x) (name, match, &ref,
|
||||
map->l_local_scope, NULL, 0,
|
||||
DL_LOOKUP_RETURN_NEWEST, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -111,8 +111,8 @@ RTLD_NEXT used in code not dynamically loaded"));
|
||||
while (l->l_loader != NULL)
|
||||
l = l->l_loader;
|
||||
|
||||
result = GLRO(dl_lookup_symbol_skip) (name, l, &ref,
|
||||
l->l_local_scope, match);
|
||||
result = GLRO(dl_lookup_symbol_x) (name, l, &ref, l->l_local_scope,
|
||||
NULL, 0, 0, match);
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,9 +165,9 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who)
|
||||
|
||||
if (handle == RTLD_DEFAULT)
|
||||
/* Search the global scope. */
|
||||
result = GLRO(dl_lookup_versioned_symbol) (name, match, &ref,
|
||||
match->l_scope, &vers, 0,
|
||||
DL_LOOKUP_ADD_DEPENDENCY);
|
||||
result = GLRO(dl_lookup_symbol_x) (name, match, &ref, match->l_scope,
|
||||
&vers, 0, DL_LOOKUP_ADD_DEPENDENCY,
|
||||
NULL);
|
||||
else if (handle == RTLD_NEXT)
|
||||
{
|
||||
if (__builtin_expect (match == GL(dl_loaded), 0))
|
||||
@ -183,17 +183,15 @@ RTLD_NEXT used in code not dynamically loaded"));
|
||||
while (l->l_loader != NULL)
|
||||
l = l->l_loader;
|
||||
|
||||
result = GLRO(dl_lookup_versioned_symbol_skip) (name, l, &ref,
|
||||
l->l_local_scope,
|
||||
&vers, match);
|
||||
result = GLRO(dl_lookup_symbol_x) (name, l, &ref, l->l_local_scope,
|
||||
&vers, 0, 0, match);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Search the scope of the given object. */
|
||||
struct link_map *map = handle;
|
||||
result = GLRO(dl_lookup_versioned_symbol) (name, map, &ref,
|
||||
map->l_local_scope, &vers,
|
||||
0, 0);
|
||||
result = GLRO(dl_lookup_symbol_x) (name, map, &ref, map->l_local_scope,
|
||||
&vers, 0, 0, NULL);
|
||||
}
|
||||
|
||||
if (ref != NULL)
|
||||
|
125
elf/do-lookup.h
125
elf/do-lookup.h
@ -17,21 +17,16 @@
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#if VERSIONED
|
||||
# define FCT do_lookup_versioned
|
||||
# define ARG const struct r_found_version *const version
|
||||
#else
|
||||
# define FCT do_lookup
|
||||
# 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 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 link_map *skip, int type_class)
|
||||
__attribute_noinline__
|
||||
do_lookup_x (const char *undef_name, unsigned long int hash,
|
||||
const ElfW(Sym) *ref, struct sym_val *result,
|
||||
struct r_scope_elem *scope, size_t i,
|
||||
const struct r_found_version *const version, int flags,
|
||||
struct link_map *skip, int type_class)
|
||||
{
|
||||
struct link_map **list = scope->r_list;
|
||||
size_t n = scope->r_nlist;
|
||||
@ -44,10 +39,8 @@ FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref,
|
||||
const ElfW(Half) *verstab;
|
||||
Elf_Symndx symidx;
|
||||
const ElfW(Sym) *sym;
|
||||
#if ! VERSIONED
|
||||
int num_versions = 0;
|
||||
const ElfW(Sym) *versioned_sym = NULL;
|
||||
#endif
|
||||
|
||||
map = list[i];
|
||||
|
||||
@ -100,67 +93,71 @@ FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref,
|
||||
/* Not the symbol we are looking for. */
|
||||
continue;
|
||||
|
||||
#if VERSIONED
|
||||
if (__builtin_expect (verstab == NULL, 0))
|
||||
if (version != NULL)
|
||||
{
|
||||
/* We need a versioned symbol but haven't found any. If
|
||||
this is the object which is referenced in the verneed
|
||||
entry it is a bug in the library since a symbol must
|
||||
not simply disappear.
|
||||
if (__builtin_expect (verstab == NULL, 0))
|
||||
{
|
||||
/* We need a versioned symbol but haven't found any. If
|
||||
this is the object which is referenced in the verneed
|
||||
entry it is a bug in the library since a symbol must
|
||||
not simply disappear.
|
||||
|
||||
It would also be a bug in the object since it means that
|
||||
the list of required versions is incomplete and so the
|
||||
tests in dl-version.c haven't found a problem.*/
|
||||
assert (version->filename == NULL
|
||||
|| ! _dl_name_match_p (version->filename, map));
|
||||
It would also be a bug in the object since it means that
|
||||
the list of required versions is incomplete and so the
|
||||
tests in dl-version.c haven't found a problem.*/
|
||||
assert (version->filename == NULL
|
||||
|| ! _dl_name_match_p (version->filename, map));
|
||||
|
||||
/* Otherwise we accept the symbol. */
|
||||
/* Otherwise we accept the symbol. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We can match the version information or use the
|
||||
default one if it is not hidden. */
|
||||
ElfW(Half) ndx = verstab[symidx] & 0x7fff;
|
||||
if ((map->l_versions[ndx].hash != version->hash
|
||||
|| strcmp (map->l_versions[ndx].name, version->name))
|
||||
&& (version->hidden || map->l_versions[ndx].hash
|
||||
|| (verstab[symidx] & 0x8000)))
|
||||
/* It's not the version we want. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We can match the version information or use the
|
||||
default one if it is not hidden. */
|
||||
ElfW(Half) ndx = verstab[symidx] & 0x7fff;
|
||||
if ((map->l_versions[ndx].hash != version->hash
|
||||
|| strcmp (map->l_versions[ndx].name, version->name))
|
||||
&& (version->hidden || map->l_versions[ndx].hash
|
||||
|| (verstab[symidx] & 0x8000)))
|
||||
/* It's not the version we want. */
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
/* No specific version is selected. There are two ways we
|
||||
can got here:
|
||||
/* No specific version is selected. There are two ways we
|
||||
can got here:
|
||||
|
||||
- a binary which does not include versioning information
|
||||
is loaded
|
||||
- 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
|
||||
- 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.
|
||||
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[symidx] & 0x7fff)
|
||||
>= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3))
|
||||
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)
|
||||
{
|
||||
/* Don't accept hidden symbols. */
|
||||
if ((verstab[symidx] & 0x8000) == 0 && num_versions++ == 0)
|
||||
/* No version so far. */
|
||||
versioned_sym = sym;
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* There cannot be another entry for this symbol so stop here. */
|
||||
goto found_it;
|
||||
@ -170,11 +167,7 @@ FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref,
|
||||
looking for an unversioned symbol and the version is not the
|
||||
default version we still accept this symbol since there are
|
||||
no possible ambiguities. */
|
||||
#if VERSIONED
|
||||
sym = NULL;
|
||||
#else
|
||||
sym = num_versions == 1 ? versioned_sym : NULL;
|
||||
#endif
|
||||
|
||||
if (sym != NULL)
|
||||
{
|
||||
@ -204,13 +197,11 @@ FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref,
|
||||
}
|
||||
}
|
||||
|
||||
#if VERSIONED
|
||||
/* If this current map is the one mentioned in the verneed entry
|
||||
and we have not found a weak entry, it is a bug. */
|
||||
if (symidx == STN_UNDEF && version->filename != NULL
|
||||
if (symidx == STN_UNDEF && version != NULL && version->filename != NULL
|
||||
&& __builtin_expect (_dl_name_match_p (version->filename, map), 0))
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
while (++i < n);
|
||||
|
||||
|
12
elf/rtld.c
12
elf/rtld.c
@ -139,10 +139,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
|
||||
._dl_signal_error = _dl_signal_error,
|
||||
._dl_start_profile = _dl_start_profile,
|
||||
._dl_mcount = _dl_mcount_internal,
|
||||
._dl_lookup_symbol = _dl_lookup_symbol,
|
||||
._dl_lookup_versioned_symbol = _dl_lookup_versioned_symbol,
|
||||
._dl_lookup_symbol_skip = _dl_lookup_symbol_skip,
|
||||
._dl_lookup_versioned_symbol_skip = _dl_lookup_versioned_symbol_skip,
|
||||
._dl_lookup_symbol_x = _dl_lookup_symbol_x,
|
||||
};
|
||||
/* If we would use strong_alias here the compiler would see a
|
||||
non-hidden definition. This would undo the effect of the previous
|
||||
@ -1521,9 +1518,10 @@ cannot allocate TLS data structures for initial thread");
|
||||
ElfW(Addr) loadbase;
|
||||
lookup_t result;
|
||||
|
||||
result = _dl_lookup_symbol (INTUSE(_dl_argv)[i], GL(dl_loaded),
|
||||
&ref, GL(dl_loaded)->l_scope,
|
||||
ELF_RTYPE_CLASS_PLT, 1);
|
||||
result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], GL(dl_loaded),
|
||||
&ref, GL(dl_loaded)->l_scope, NULL,
|
||||
ELF_RTYPE_CLASS_PLT,
|
||||
DL_LOOKUP_ADD_DEPENDENCY, NULL);
|
||||
|
||||
loadbase = LOOKUP_VALUE_ADDRESS (result);
|
||||
|
||||
|
@ -347,8 +347,10 @@ struct rtld_global
|
||||
# define __rtld_local_attribute__
|
||||
# endif
|
||||
extern struct rtld_global _rtld_local __rtld_local_attribute__;
|
||||
# undef __rtld_local_attribute__
|
||||
# endif
|
||||
extern struct rtld_global _rtld_global __rtld_global_attribute__;
|
||||
# undef __rtld_global_attribute__
|
||||
#endif
|
||||
|
||||
#ifndef SHARED
|
||||
@ -478,42 +480,34 @@ struct rtld_global_ro
|
||||
const char *);
|
||||
void (internal_function *_dl_start_profile) (void);
|
||||
void (*_dl_mcount) (ElfW(Addr) frompc, ElfW(Addr) selfpc);
|
||||
lookup_t (internal_function *_dl_lookup_symbol) (const char *,
|
||||
struct link_map *,
|
||||
const ElfW(Sym) **,
|
||||
struct r_scope_elem *[],
|
||||
int, int);
|
||||
lookup_t (internal_function *_dl_lookup_versioned_symbol) (const char *,
|
||||
struct link_map *,
|
||||
const ElfW(Sym) **,
|
||||
struct r_scope_elem *[],
|
||||
const struct r_found_version *,
|
||||
int, int);
|
||||
lookup_t (internal_function *_dl_lookup_symbol_skip) (const char *,
|
||||
struct link_map *,
|
||||
const ElfW(Sym) **,
|
||||
struct r_scope_elem *[],
|
||||
struct link_map *);
|
||||
lookup_t (internal_function *_dl_lookup_versioned_symbol_skip) (const char *,
|
||||
struct link_map *,
|
||||
const ElfW(Sym) **,
|
||||
struct r_scope_elem *[],
|
||||
const struct r_found_version *,
|
||||
struct link_map *);
|
||||
lookup_t (internal_function *_dl_lookup_symbol_x) (const char *,
|
||||
struct link_map *,
|
||||
const ElfW(Sym) **,
|
||||
struct r_scope_elem *[],
|
||||
const struct r_found_version *,
|
||||
int, int,
|
||||
struct link_map *);
|
||||
|
||||
};
|
||||
# define __rtld_global_attribute__
|
||||
# ifdef IS_IN_rtld
|
||||
# ifdef HAVE_VISIBILITY_ATTRIBUTE
|
||||
# define __rtld_local_attribute__ __attribute__ ((visibility ("hidden")))
|
||||
# else
|
||||
# define __rtld_local_attribute__
|
||||
# endif
|
||||
extern struct rtld_global_ro _rtld_local_ro
|
||||
attribute_relro __rtld_local_attribute__;
|
||||
extern struct rtld_global_ro _rtld_global_ro
|
||||
attribute_relro __rtld_global_attribute__;
|
||||
# undef __rtld_local_attribute__
|
||||
# else
|
||||
/* We cheat a bit here. We declare the variable as as const even
|
||||
though it is at startup. */
|
||||
extern const struct rtld_global_ro _rtld_global_ro
|
||||
attribute_relro __rtld_global_attribute__;
|
||||
# endif
|
||||
# undef __rtld_global_attribute__
|
||||
#endif
|
||||
#undef EXTERN
|
||||
|
||||
@ -681,13 +675,6 @@ extern void _dl_rtld_di_serinfo (struct link_map *loader,
|
||||
object) is searched in turn. REFERENCE_NAME should name the object
|
||||
containing the reference; it is used in error messages.
|
||||
TYPE_CLASS describes the type of symbol we are looking for. */
|
||||
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 flags)
|
||||
internal_function attribute_hidden;
|
||||
|
||||
enum
|
||||
{
|
||||
/* If necessary add dependency between user and provider object. */
|
||||
@ -698,31 +685,15 @@ enum
|
||||
};
|
||||
|
||||
/* Lookup versioned symbol. */
|
||||
extern lookup_t _dl_lookup_versioned_symbol (const char *undef,
|
||||
struct link_map *undef_map,
|
||||
const ElfW(Sym) **sym,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
const struct r_found_version *version,
|
||||
int type_class, int explicit)
|
||||
extern lookup_t _dl_lookup_symbol_x (const char *undef,
|
||||
struct link_map *undef_map,
|
||||
const ElfW(Sym) **sym,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
const struct r_found_version *version,
|
||||
int type_class, int explicit,
|
||||
struct link_map *skip_map)
|
||||
internal_function attribute_hidden;
|
||||
|
||||
/* For handling RTLD_NEXT we must be able to skip shared objects. */
|
||||
extern lookup_t _dl_lookup_symbol_skip (const char *undef,
|
||||
struct link_map *undef_map,
|
||||
const ElfW(Sym) **sym,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
struct link_map *skip_this)
|
||||
internal_function;
|
||||
|
||||
/* For handling RTLD_NEXT with versioned symbols we must be able to
|
||||
skip shared objects. */
|
||||
extern lookup_t _dl_lookup_versioned_symbol_skip (const char *undef,
|
||||
struct link_map *undef_map,
|
||||
const ElfW(Sym) **sym,
|
||||
struct r_scope_elem *symbol_scope[],
|
||||
const struct r_found_version *version,
|
||||
struct link_map *skip_this)
|
||||
internal_function;
|
||||
|
||||
/* Look up symbol NAME in MAP's scope and return its run-time address. */
|
||||
extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name)
|
||||
|
Loading…
Reference in New Issue
Block a user