PATCH: Further optimize protected symbol
H. J. Lu
hjl@lucon.org
Thu Mar 27 19:03:00 GMT 2003
This patch adds some comments on protected symbol handling and optimizes
protected symbol a bit more. As I said yesterday, we still don't handle
protected symbol right when copy relocation is involved.
H.J.
-------------- next part --------------
2003-03-27 H.J. Lu <hjl@gnu.org>
* elf/dl-lookup.c (_dl_lookup_symbol): Stop the search of the
current value is defined. Continue the search for the real
definition instead of starting from scratch if it is undefined.
(_dl_lookup_symbol_skip): Likewise.
(_dl_lookup_versioned_symbol): Likewise.
(_dl_lookup_versioned_symbol_skip): Likewise.
--- elf/dl-lookup.c.protected 2003-03-26 08:22:01.000000000 -0800
+++ elf/dl-lookup.c 2003-03-27 11:01:51.000000000 -0800
@@ -271,9 +271,24 @@ _dl_lookup_symbol (const char *undef_nam
protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
if (__builtin_expect (protected != 0, 0))
{
- /* It is very tricky. We need to figure out what value to
- return for the protected symbol. */
- if (type_class == ELF_RTYPE_CLASS_PLT)
+ /* When we get here, there are 3 possibilities:
+
+ 1. current_value has a real definition.
+ 2. current_value has a definition from a copy relocation.
+ 3. current_value doesn't have any definition, which may be the
+ case for an ELF_RTYPE_CLASS_PLT relocation.
+
+ For the protected symbol, we need to make sure that the
+ definition from undef_map is used.
+
+ If it is defined and not from a copy relocation, we make sure
+ the definition from undef_map is used.
+
+ FIXME: We can't tell if a definition is from a copy relocation
+ or not. */
+ if (type_class == ELF_RTYPE_CLASS_PLT
+ || (current_value.s
+ && current_value.s->st_shndx != SHN_UNDEF))
{
if (current_value.s != NULL && current_value.m != undef_map)
{
@@ -285,7 +300,14 @@ _dl_lookup_symbol (const char *undef_nam
{
struct sym_val protected_value = { NULL, NULL };
- for (scope = symbol_scope; *scope; ++scope)
+ /* Now, current_value is either undefined or from a copy
+ relocation. We continue the search for the real
+ definition, using ELF_RTYPE_CLASS_PLT to skip undefined
+ symbols.
+
+ FIXME: How do we skip a definition from a copy
+ relocation? */
+ for (; *scope; ++scope)
if (_dl_do_lookup (undef_name, hash, *ref,
&protected_value, *scope, 0, flags,
NULL, ELF_RTYPE_CLASS_PLT))
@@ -368,24 +390,53 @@ _dl_lookup_symbol_skip (const char *unde
if (__builtin_expect (protected != 0, 0))
{
- /* 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
- || !_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
- 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, DL_LOOKUP_RETURN_NEWEST, skip_map,
- ELF_RTYPE_CLASS_PLT))
- break;
+ /* When we get here, there are 3 possibilities:
- if (protected_value.s != NULL && protected_value.m != undef_map)
+ 1. current_value has a real definition.
+ 2. current_value has a definition from a copy relocation.
+ 3. current_value doesn't have any definition, which may be the
+ case for an ELF_RTYPE_CLASS_PLT relocation.
+
+ For the protected symbol, we need to make sure that the
+ definition from undef_map is used.
+
+ If it is defined and not from a copy relocation, we make sure
+ the definition from undef_map is used.
+
+ FIXME: We can't tell if a definition is from a copy relocation
+ or not. */
+ if (current_value.s && current_value.s->st_shndx != SHN_UNDEF)
{
- current_value.s = *ref;
- current_value.m = undef_map;
+ if (current_value.s != NULL && current_value.m != undef_map)
+ {
+ current_value.s = *ref;
+ current_value.m = undef_map;
+ }
+ }
+ else
+ {
+ struct sym_val protected_value = { NULL, NULL };
+
+ /* Now, current_value is either undefined or from a copy
+ relocation. We continue the search for the real
+ definition, using ELF_RTYPE_CLASS_PLT to skip undefined
+ symbols.
+
+ FIXME: How do we skip a definition from a copy
+ relocation? */
+ while (*++scope)
+ if (_dl_do_lookup (undef_name, hash, *ref,
+ &protected_value, *scope, 0,
+ DL_LOOKUP_RETURN_NEWEST,
+ skip_map, ELF_RTYPE_CLASS_PLT))
+ break;
+
+ if (protected_value.s != NULL
+ && protected_value.m != undef_map)
+ {
+ current_value.s = *ref;
+ current_value.m = undef_map;
+ }
}
}
@@ -476,9 +527,24 @@ _dl_lookup_versioned_symbol (const char
if (__builtin_expect (protected != 0, 0))
{
- /* It is very tricky. We need to figure out what value to
- return for the protected symbol. */
- if (type_class == ELF_RTYPE_CLASS_PLT)
+ /* When we get here, there are 3 possibilities:
+
+ 1. current_value has a real definition.
+ 2. current_value has a definition from a copy relocation.
+ 3. current_value doesn't have any definition, which may be the
+ case for an ELF_RTYPE_CLASS_PLT relocation.
+
+ For the protected symbol, we need to make sure that the
+ definition from undef_map is used.
+
+ If it is defined and not from a copy relocation, we make sure
+ the definition from undef_map is used.
+
+ FIXME: We can't tell if a definition is from a copy relocation
+ or not. */
+ if (type_class == ELF_RTYPE_CLASS_PLT
+ || (current_value.s
+ && current_value.s->st_shndx != SHN_UNDEF))
{
if (current_value.s != NULL && current_value.m != undef_map)
{
@@ -490,7 +556,14 @@ _dl_lookup_versioned_symbol (const char
{
struct sym_val protected_value = { NULL, NULL };
- for (scope = symbol_scope; *scope; ++scope)
+ /* Now, current_value is either undefined or from a copy
+ relocation. We continue the search for the real
+ definition, using ELF_RTYPE_CLASS_PLT to skip undefined
+ symbols.
+
+ FIXME: How do we skip a definition from a copy
+ relocation? */
+ for (; *scope; ++scope)
if (_dl_do_lookup_versioned (undef_name, hash, *ref,
&protected_value,
*scope, 0, version, NULL,
@@ -588,24 +661,53 @@ _dl_lookup_versioned_symbol_skip (const
if (__builtin_expect (protected != 0, 0))
{
- /* 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
- || !_dl_do_lookup_versioned (undef_name, hash, *ref,
- &protected_value, *scope, i, version,
- skip_map, ELF_RTYPE_CLASS_PLT))
- while (*++scope)
- if (_dl_do_lookup_versioned (undef_name, hash, *ref,
- &protected_value, *scope, 0, version,
- skip_map, ELF_RTYPE_CLASS_PLT))
- break;
+ /* When we get here, there are 3 possibilities:
- if (protected_value.s != NULL && protected_value.m != undef_map)
+ 1. current_value has a real definition.
+ 2. current_value has a definition from a copy relocation.
+ 3. current_value doesn't have any definition, which may be the
+ case for an ELF_RTYPE_CLASS_PLT relocation.
+
+ For the protected symbol, we need to make sure that the
+ definition from undef_map is used.
+
+ If it is defined and not from a copy relocation, we make sure
+ the definition from undef_map is used.
+
+ FIXME: We can't tell if a definition is from a copy relocation
+ or not. */
+ if (current_value.s && current_value.s->st_shndx != SHN_UNDEF)
{
- current_value.s = *ref;
- current_value.m = undef_map;
+ if (current_value.s != NULL && current_value.m != undef_map)
+ {
+ current_value.s = *ref;
+ current_value.m = undef_map;
+ }
+ }
+ else
+ {
+ struct sym_val protected_value = { NULL, NULL };
+
+ /* Now, current_value is either undefined or from a copy
+ relocation. We continue the search for the real
+ definition, using ELF_RTYPE_CLASS_PLT to skip undefined
+ symbols.
+
+ FIXME: How do we skip a definition from a copy
+ relocation? */
+ while (*++scope)
+ if (_dl_do_lookup_versioned (undef_name, hash, *ref,
+ &protected_value, *scope, 0,
+ version, skip_map,
+ ELF_RTYPE_CLASS_PLT))
+ break;
+
+ if (protected_value.s != NULL
+ && protected_value.m != undef_map)
+ {
+ current_value.s = *ref;
+ current_value.m = undef_map;
+ }
}
}
More information about the Libc-alpha
mailing list