mirror of git://sourceware.org/git/glibc.git
Update.
2000-05-21 H.J. Lu <hjl@gnu.org> * elf/do-lookup.h (do_lookup_versioned): Replace reloc_type parameter with noexec and noplt parameter. (do_lookup): Likewise. * elf/dl-lookup.c (_dl_lookup_symbol): Change for new parameters of do_lookup. Support STV_PROTECTED. (_dl_lookup_symbol_skip): Likewise. (_dl_lookup_versioned_symbol): Likewise. (_dl_lookup_versioned_symbol_skip): Likewise. * elf/dl-reloc.c (RESOLVE): Check STB_LOCAL instead of ST_VISIBILITY. * elf/dl-runtime.c (profile_fixup): Fix a typo in comment.
This commit is contained in:
parent
07d3c1bfc2
commit
6aa29abe9f
16
ChangeLog
16
ChangeLog
|
|
@ -1,3 +1,19 @@
|
||||||
|
2000-05-21 H.J. Lu <hjl@gnu.org>
|
||||||
|
|
||||||
|
* elf/do-lookup.h (do_lookup_versioned): Replace reloc_type parameter
|
||||||
|
with noexec and noplt parameter.
|
||||||
|
(do_lookup): Likewise.
|
||||||
|
|
||||||
|
* elf/dl-lookup.c (_dl_lookup_symbol): Change for new parameters of
|
||||||
|
do_lookup. Support STV_PROTECTED.
|
||||||
|
(_dl_lookup_symbol_skip): Likewise.
|
||||||
|
(_dl_lookup_versioned_symbol): Likewise.
|
||||||
|
(_dl_lookup_versioned_symbol_skip): Likewise.
|
||||||
|
|
||||||
|
* elf/dl-reloc.c (RESOLVE): Check STB_LOCAL instead of ST_VISIBILITY.
|
||||||
|
|
||||||
|
* elf/dl-runtime.c (profile_fixup): Fix a typo in comment.
|
||||||
|
|
||||||
2000-05-21 Jakub Jelinek <jakub@redhat.com>
|
2000-05-21 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* sysdeps/arm/bits/huge_val.h: Prereq gcc 2.96+, not 2.95.
|
* sysdeps/arm/bits/huge_val.h: Prereq gcc 2.96+, not 2.95.
|
||||||
|
|
|
||||||
161
elf/dl-lookup.c
161
elf/dl-lookup.c
|
|
@ -75,9 +75,11 @@ __libc_lock_define (extern, _dl_load_lock)
|
||||||
without versioning. gcc is not able to optimize a single function
|
without versioning. gcc is not able to optimize a single function
|
||||||
definition serving for both purposes so we define two functions. */
|
definition serving for both purposes so we define two functions. */
|
||||||
#define VERSIONED 0
|
#define VERSIONED 0
|
||||||
|
#define PROTECTED 0
|
||||||
#include "do-lookup.h"
|
#include "do-lookup.h"
|
||||||
|
|
||||||
#define VERSIONED 1
|
#define VERSIONED 1
|
||||||
|
#define PROTECTED 0
|
||||||
#include "do-lookup.h"
|
#include "do-lookup.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -194,13 +196,16 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
|
||||||
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 };
|
||||||
struct r_scope_elem **scope;
|
struct r_scope_elem **scope;
|
||||||
|
int protected;
|
||||||
|
int noexec = elf_machine_lookup_noexec_p (reloc_type);
|
||||||
|
int noplt = elf_machine_lookup_noplt_p (reloc_type);
|
||||||
|
|
||||||
++_dl_num_relocations;
|
++_dl_num_relocations;
|
||||||
|
|
||||||
/* 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, undef_map, hash, *ref, ¤t_value,
|
if (do_lookup (undef_name, undef_map, hash, *ref, ¤t_value,
|
||||||
*scope, 0, NULL, reloc_type))
|
*scope, 0, NULL, noexec, noplt))
|
||||||
{
|
{
|
||||||
/* 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
|
||||||
|
|
@ -232,6 +237,8 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
|
||||||
|
|
||||||
if (__builtin_expect (_dl_debug_bindings, 0))
|
if (__builtin_expect (_dl_debug_bindings, 0))
|
||||||
_dl_debug_message (1, "binding file ",
|
_dl_debug_message (1, "binding file ",
|
||||||
(reference_name && reference_name[0]
|
(reference_name && reference_name[0]
|
||||||
|
|
@ -239,10 +246,33 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
|
||||||
: (_dl_argv[0] ?: "<main program>")),
|
: (_dl_argv[0] ?: "<main program>")),
|
||||||
" to ", current_value.m->l_name[0]
|
" to ", current_value.m->l_name[0]
|
||||||
? current_value.m->l_name : _dl_argv[0],
|
? current_value.m->l_name : _dl_argv[0],
|
||||||
": symbol `", undef_name, "'\n", NULL);
|
": ", protected ? "protected" : "normal",
|
||||||
|
" symbol `", undef_name, "'\n", NULL);
|
||||||
|
|
||||||
*ref = current_value.s;
|
if (__builtin_expect (protected == 0, 1))
|
||||||
return LOOKUP_VALUE (current_value.m);
|
{
|
||||||
|
*ref = current_value.s;
|
||||||
|
return LOOKUP_VALUE (current_value.m);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It is very tricky. We need to figure out what value to
|
||||||
|
return for the protected symbol */
|
||||||
|
struct sym_val protected_value = { NULL, NULL };
|
||||||
|
|
||||||
|
for (scope = symbol_scope; *scope; ++scope)
|
||||||
|
if (do_lookup (undef_name, undef_map, hash, *ref,
|
||||||
|
&protected_value, *scope, 0, NULL, 0, 1))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (protected_value.s == NULL || protected_value.m == undef_map)
|
||||||
|
{
|
||||||
|
*ref = current_value.s;
|
||||||
|
return LOOKUP_VALUE (current_value.m);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOOKUP_VALUE (undef_map);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -263,6 +293,7 @@ _dl_lookup_symbol_skip (const char *undef_name,
|
||||||
struct sym_val current_value = { NULL, NULL };
|
struct sym_val current_value = { NULL, NULL };
|
||||||
struct r_scope_elem **scope;
|
struct r_scope_elem **scope;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
int protected;
|
||||||
|
|
||||||
++_dl_num_relocations;
|
++_dl_num_relocations;
|
||||||
|
|
||||||
|
|
@ -273,7 +304,7 @@ _dl_lookup_symbol_skip (const char *undef_name,
|
||||||
|
|
||||||
if (i < (*scope)->r_nlist
|
if (i < (*scope)->r_nlist
|
||||||
&& do_lookup (undef_name, undef_map, hash, *ref, ¤t_value,
|
&& do_lookup (undef_name, undef_map, hash, *ref, ¤t_value,
|
||||||
*scope, i, skip_map, 0))
|
*scope, i, skip_map, 0, 0))
|
||||||
{
|
{
|
||||||
/* 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
|
||||||
|
|
@ -293,7 +324,7 @@ _dl_lookup_symbol_skip (const char *undef_name,
|
||||||
else
|
else
|
||||||
while (*++scope)
|
while (*++scope)
|
||||||
if (do_lookup (undef_name, undef_map, hash, *ref, ¤t_value,
|
if (do_lookup (undef_name, undef_map, hash, *ref, ¤t_value,
|
||||||
*scope, 0, skip_map, 0))
|
*scope, 0, skip_map, 0, 0))
|
||||||
{
|
{
|
||||||
/* 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
|
||||||
|
|
@ -319,6 +350,8 @@ _dl_lookup_symbol_skip (const char *undef_name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
|
||||||
|
|
||||||
if (__builtin_expect (_dl_debug_bindings, 0))
|
if (__builtin_expect (_dl_debug_bindings, 0))
|
||||||
_dl_debug_message (1, "binding file ",
|
_dl_debug_message (1, "binding file ",
|
||||||
(reference_name && reference_name[0]
|
(reference_name && reference_name[0]
|
||||||
|
|
@ -326,10 +359,36 @@ _dl_lookup_symbol_skip (const char *undef_name,
|
||||||
: (_dl_argv[0] ?: "<main program>")),
|
: (_dl_argv[0] ?: "<main program>")),
|
||||||
" to ", current_value.m->l_name[0]
|
" to ", current_value.m->l_name[0]
|
||||||
? current_value.m->l_name : _dl_argv[0],
|
? current_value.m->l_name : _dl_argv[0],
|
||||||
": symbol `", undef_name, "' (skip)\n", NULL);
|
": ", protected ? "protected" : "normal",
|
||||||
|
" symbol `", undef_name, "'\n", NULL);
|
||||||
|
|
||||||
*ref = current_value.s;
|
if (__builtin_expect (protected == 0, 1))
|
||||||
return LOOKUP_VALUE (current_value.m);
|
{
|
||||||
|
*ref = current_value.s;
|
||||||
|
return LOOKUP_VALUE (current_value.m);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It is very tricky. We need to figure out what value to
|
||||||
|
return for the protected symbol */
|
||||||
|
struct sym_val protected_value = { NULL, NULL };
|
||||||
|
|
||||||
|
if (i >= (*scope)->r_nlist
|
||||||
|
|| !do_lookup (undef_name, undef_map, hash, *ref, &protected_value,
|
||||||
|
*scope, i, skip_map, 0, 1))
|
||||||
|
while (*++scope)
|
||||||
|
if (do_lookup (undef_name, undef_map, hash, *ref, &protected_value,
|
||||||
|
*scope, 0, skip_map, 0, 1))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (protected_value.s == NULL || protected_value.m == undef_map)
|
||||||
|
{
|
||||||
|
*ref = current_value.s;
|
||||||
|
return LOOKUP_VALUE (current_value.m);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOOKUP_VALUE (undef_map);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -350,6 +409,9 @@ _dl_lookup_versioned_symbol (const char *undef_name,
|
||||||
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 };
|
||||||
struct r_scope_elem **scope;
|
struct r_scope_elem **scope;
|
||||||
|
int protected;
|
||||||
|
int noexec = elf_machine_lookup_noexec_p (reloc_type);
|
||||||
|
int noplt = elf_machine_lookup_noplt_p (reloc_type);
|
||||||
|
|
||||||
++_dl_num_relocations;
|
++_dl_num_relocations;
|
||||||
|
|
||||||
|
|
@ -358,7 +420,7 @@ _dl_lookup_versioned_symbol (const char *undef_name,
|
||||||
{
|
{
|
||||||
int res = do_lookup_versioned (undef_name, undef_map, hash, *ref,
|
int res = do_lookup_versioned (undef_name, undef_map, hash, *ref,
|
||||||
¤t_value, *scope, 0, version, NULL,
|
¤t_value, *scope, 0, version, NULL,
|
||||||
reloc_type);
|
noexec, noplt);
|
||||||
if (res > 0)
|
if (res > 0)
|
||||||
{
|
{
|
||||||
/* 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
|
||||||
|
|
@ -412,6 +474,8 @@ _dl_lookup_versioned_symbol (const char *undef_name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
|
||||||
|
|
||||||
if (__builtin_expect (_dl_debug_bindings, 0))
|
if (__builtin_expect (_dl_debug_bindings, 0))
|
||||||
_dl_debug_message (1, "binding file ",
|
_dl_debug_message (1, "binding file ",
|
||||||
(reference_name && reference_name[0]
|
(reference_name && reference_name[0]
|
||||||
|
|
@ -419,11 +483,35 @@ _dl_lookup_versioned_symbol (const char *undef_name,
|
||||||
: (_dl_argv[0] ?: "<main program>")),
|
: (_dl_argv[0] ?: "<main program>")),
|
||||||
" to ", current_value.m->l_name[0]
|
" to ", current_value.m->l_name[0]
|
||||||
? current_value.m->l_name : _dl_argv[0],
|
? current_value.m->l_name : _dl_argv[0],
|
||||||
": symbol `", undef_name, "' [", version->name,
|
": ", protected ? "protected" : "normal",
|
||||||
|
" symbol `", undef_name, "' [", version->name,
|
||||||
"]\n", NULL);
|
"]\n", NULL);
|
||||||
|
|
||||||
*ref = current_value.s;
|
if (__builtin_expect (protected == 0, 1))
|
||||||
return LOOKUP_VALUE (current_value.m);
|
{
|
||||||
|
*ref = current_value.s;
|
||||||
|
return LOOKUP_VALUE (current_value.m);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It is very tricky. We need to figure out what value to
|
||||||
|
return for the protected symbol */
|
||||||
|
struct sym_val protected_value = { NULL, NULL };
|
||||||
|
|
||||||
|
for (scope = symbol_scope; *scope; ++scope)
|
||||||
|
if (do_lookup_versioned (undef_name, undef_map, hash, *ref,
|
||||||
|
&protected_value, *scope, 0, version, NULL,
|
||||||
|
0, 1))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (protected_value.s == NULL || protected_value.m == undef_map)
|
||||||
|
{
|
||||||
|
*ref = current_value.s;
|
||||||
|
return LOOKUP_VALUE (current_value.m);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOOKUP_VALUE (undef_map);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -443,6 +531,7 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
|
||||||
struct sym_val current_value = { NULL, NULL };
|
struct sym_val current_value = { NULL, NULL };
|
||||||
struct r_scope_elem **scope;
|
struct r_scope_elem **scope;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
int protected;
|
||||||
|
|
||||||
++_dl_num_relocations;
|
++_dl_num_relocations;
|
||||||
|
|
||||||
|
|
@ -453,7 +542,8 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
|
||||||
|
|
||||||
if (i < (*scope)->r_nlist
|
if (i < (*scope)->r_nlist
|
||||||
&& do_lookup_versioned (undef_name, undef_map, hash, *ref,
|
&& do_lookup_versioned (undef_name, undef_map, hash, *ref,
|
||||||
¤t_value, *scope, i, version, skip_map, 0))
|
¤t_value, *scope, i, version, skip_map,
|
||||||
|
0, 0))
|
||||||
{
|
{
|
||||||
/* 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
|
||||||
|
|
@ -475,7 +565,7 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
|
||||||
while (*++scope)
|
while (*++scope)
|
||||||
if (do_lookup_versioned (undef_name, undef_map, hash, *ref,
|
if (do_lookup_versioned (undef_name, undef_map, hash, *ref,
|
||||||
¤t_value, *scope, 0, version, skip_map,
|
¤t_value, *scope, 0, version, skip_map,
|
||||||
0))
|
0, 0))
|
||||||
{
|
{
|
||||||
/* 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
|
||||||
|
|
@ -512,19 +602,48 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
|
||||||
|
|
||||||
if (__builtin_expect (_dl_debug_bindings, 0))
|
if (__builtin_expect (_dl_debug_bindings, 0))
|
||||||
_dl_debug_message (1, "binding file ",
|
_dl_debug_message (1, "binding file ",
|
||||||
(reference_name && reference_name[0]
|
(reference_name && reference_name[0]
|
||||||
? reference_name
|
? reference_name
|
||||||
: (_dl_argv[0] ?: "<main program>")),
|
: (_dl_argv[0] ?: "<main program>")),
|
||||||
" to ",
|
" to ", current_value.m->l_name[0]
|
||||||
current_value.m->l_name[0]
|
|
||||||
? current_value.m->l_name : _dl_argv[0],
|
? current_value.m->l_name : _dl_argv[0],
|
||||||
": symbol `", undef_name, "' [", version->name,
|
": ", protected ? "protected" : "normal",
|
||||||
"] (skip)\n", NULL);
|
" symbol `", undef_name, "' [", version->name,
|
||||||
|
"]\n", NULL);
|
||||||
|
|
||||||
*ref = current_value.s;
|
if (__builtin_expect (protected == 0, 1))
|
||||||
return LOOKUP_VALUE (current_value.m);
|
{
|
||||||
|
*ref = current_value.s;
|
||||||
|
return LOOKUP_VALUE (current_value.m);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It is very tricky. We need to figure out what value to
|
||||||
|
return for the protected symbol */
|
||||||
|
struct sym_val protected_value = { NULL, NULL };
|
||||||
|
|
||||||
|
if (i >= (*scope)->r_nlist
|
||||||
|
|| !do_lookup_versioned (undef_name, undef_map, hash, *ref,
|
||||||
|
&protected_value, *scope, i, version,
|
||||||
|
skip_map, 0, 1))
|
||||||
|
while (*++scope)
|
||||||
|
if (do_lookup_versioned (undef_name, undef_map, hash, *ref,
|
||||||
|
&protected_value, *scope, 0, version,
|
||||||
|
skip_map, 0, 1))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (protected_value.s == NULL || protected_value.m == undef_map)
|
||||||
|
{
|
||||||
|
*ref = current_value.s;
|
||||||
|
return LOOKUP_VALUE (current_value.m);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOOKUP_VALUE (undef_map);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
(flags))) \
|
(flags))) \
|
||||||
: l)
|
: l)
|
||||||
#define RESOLVE(ref, version, flags) \
|
#define RESOLVE(ref, version, flags) \
|
||||||
(__builtin_expect (ELFW(ST_VISIBILITY) ((*ref)->st_other), 0) == 0 \
|
(ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \
|
||||||
? ((version) != NULL && (version)->hash != 0 \
|
? ((version) != NULL && (version)->hash != 0 \
|
||||||
? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref), \
|
? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref), \
|
||||||
scope, (version), (flags)) \
|
scope, (version), (flags)) \
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ profile_fixup (
|
||||||
/* Sanity check that we're really looking at a PLT relocation. */
|
/* Sanity check that we're really looking at a PLT relocation. */
|
||||||
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
|
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
|
||||||
|
|
||||||
/* Look up the target symbol. If the symbol is marked STV_PROTEXTED
|
/* Look up the target symbol. If the symbol is marked STV_PROTECTED
|
||||||
don't look in the global scope. */
|
don't look in the global scope. */
|
||||||
if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
|
if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue