This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

A patch for STV_PROTECTED


This patch may not be 100% correct. But it passed all the visibility
tests in today's binutils from CVS.


-- 
H.J. Lu (hjl@gnu.org)
--
2000-05-21 2000  H.J. Lu  <hjl@gnu.org>

	* elf/do-lookup.h (do_lookup_protected_versioned): New. Used
	by the STV_PROTECTED support.
	(do_lookup_protected): Likewise.

	* elf/dl-lookup.c (_dl_lookup_symbol): 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.

Index: elf/dl-lookup.c
===================================================================
RCS file: /work/cvs/gnu/glibc/elf/dl-lookup.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 dl-lookup.c
--- elf/dl-lookup.c	2000/05/21 21:10:57	1.1.1.1
+++ elf/dl-lookup.c	2000/05/21 21:41:28
@@ -75,9 +75,19 @@ __libc_lock_define (extern, _dl_load_loc
    without versioning.  gcc is not able to optimize a single function
    definition serving for both purposes so we define two functions.  */
 #define VERSIONED	0
+#define PROTECTED	0
 #include "do-lookup.h"
 
+#define VERSIONED	0
+#define PROTECTED	1
+#include "do-lookup.h"
+
+#define VERSIONED	1
+#define PROTECTED	0
+#include "do-lookup.h"
+
 #define VERSIONED	1
+#define PROTECTED	1
 #include "do-lookup.h"
 
 
@@ -194,6 +204,7 @@ _dl_lookup_symbol (const char *undef_nam
   const unsigned long int hash = _dl_elf_hash (undef_name);
   struct sym_val current_value = { NULL, NULL };
   struct r_scope_elem **scope;
+  int protected;
 
   ++_dl_num_relocations;
 
@@ -232,6 +243,8 @@ _dl_lookup_symbol (const char *undef_nam
       return 0;
     }
 
+  protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other)
+		      == STV_PROTECTED;
   if (__builtin_expect (_dl_debug_bindings, 0))
     _dl_debug_message (1, "binding file ",
 		       (reference_name && reference_name[0]
@@ -239,10 +252,34 @@ _dl_lookup_symbol (const char *undef_nam
 			: (_dl_argv[0] ?: "<main program>")),
 		       " to ", current_value.m->l_name[0]
 		       ? current_value.m->l_name : _dl_argv[0],
-		       ": symbol `", undef_name, "'\n", NULL);
+		       ": ", protected ? "protected" : "normal",
+		       " symbol `", undef_name, "'\n", NULL);
+
+  if (__builtin_expect (protected == 0, 1))
+    {
+      *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_protected (undef_name, undef_map, hash, *ref,
+				 &protected_value, *scope, 0, NULL,
+				 reloc_type))
+	  break;
 
-  *ref = current_value.s;
-  return LOOKUP_VALUE (current_value.m);
+      if (protected_value.s == NULL || protected_value.m == undef_map)
+	{
+	  *ref = current_value.s;
+	  return LOOKUP_VALUE (current_value.m);
+	}
+      else
+        return LOOKUP_VALUE (undef_map);
+    }
 }
 
 
@@ -263,6 +300,7 @@ _dl_lookup_symbol_skip (const char *unde
   struct sym_val current_value = { NULL, NULL };
   struct r_scope_elem **scope;
   size_t i;
+  int protected;
 
   ++_dl_num_relocations;
 
@@ -319,6 +357,8 @@ _dl_lookup_symbol_skip (const char *unde
       return 0;
     }
 
+  protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other)
+		      == STV_PROTECTED;
   if (__builtin_expect (_dl_debug_bindings, 0))
     _dl_debug_message (1, "binding file ",
 		       (reference_name && reference_name[0]
@@ -326,10 +366,38 @@ _dl_lookup_symbol_skip (const char *unde
 			: (_dl_argv[0] ?: "<main program>")),
 		       " to ", current_value.m->l_name[0]
 		       ? current_value.m->l_name : _dl_argv[0],
-		       ": symbol `", undef_name, "' (skip)\n", NULL);
+		       ": ", protected ? "protected" : "normal",
+		       " symbol `", undef_name, "'\n", NULL);
+
+  if (__builtin_expect (protected == 0, 1))
+    {
+      *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_protected (undef_name, undef_map, hash, *ref,
+				   &protected_value, *scope, i,
+				   skip_map, 0))
+	while (*++scope)
+	  if (do_lookup_protected (undef_name, undef_map, hash, *ref,
+				   &protected_value, *scope, 0,
+				   skip_map, 0))
+	    break;
 
-  *ref = current_value.s;
-  return LOOKUP_VALUE (current_value.m);
+      if (protected_value.s == NULL || protected_value.m == undef_map)
+	{
+	  *ref = current_value.s;
+	  return LOOKUP_VALUE (current_value.m);
+	}
+      else
+        return LOOKUP_VALUE (undef_map);
+    }
 }
 
 
@@ -350,6 +418,7 @@ _dl_lookup_versioned_symbol (const char 
   const unsigned long int hash = _dl_elf_hash (undef_name);
   struct sym_val current_value = { NULL, NULL };
   struct r_scope_elem **scope;
+  int protected;
 
   ++_dl_num_relocations;
 
@@ -412,6 +481,8 @@ _dl_lookup_versioned_symbol (const char 
       return 0;
     }
 
+  protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other)
+		      == STV_PROTECTED;
   if (__builtin_expect (_dl_debug_bindings, 0))
     _dl_debug_message (1, "binding file ",
 		       (reference_name && reference_name[0]
@@ -419,11 +490,36 @@ _dl_lookup_versioned_symbol (const char 
 			: (_dl_argv[0] ?: "<main program>")),
 		       " to ", current_value.m->l_name[0]
 		       ? current_value.m->l_name : _dl_argv[0],
-		       ": symbol `", undef_name, "' [", version->name,
+		       ": ", protected ? "protected" : "normal",
+		       " symbol `", undef_name, "' [", version->name,
 		       "]\n", NULL);
+
+  if (__builtin_expect (protected == 0, 1))
+    {
+      *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_protected_versioned (undef_name, undef_map, hash,
+					   *ref, &protected_value,
+					   *scope, 0, version, NULL,
+					   reloc_type))
+	  break;
 
-  *ref = current_value.s;
-  return LOOKUP_VALUE (current_value.m);
+      if (protected_value.s == NULL || protected_value.m == undef_map)
+	{
+	  *ref = current_value.s;
+	  return LOOKUP_VALUE (current_value.m);
+	}
+      else
+        return LOOKUP_VALUE (undef_map);
+    }
 }
 
 
@@ -443,6 +539,7 @@ _dl_lookup_versioned_symbol_skip (const 
   struct sym_val current_value = { NULL, NULL };
   struct r_scope_elem **scope;
   size_t i;
+  int protected;
 
   ++_dl_num_relocations;
 
@@ -512,19 +609,50 @@ _dl_lookup_versioned_symbol_skip (const 
       return 0;
     }
 
+  protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other)
+		      == STV_PROTECTED;
   if (__builtin_expect (_dl_debug_bindings, 0))
     _dl_debug_message (1, "binding file ",
 		       (reference_name && reference_name[0]
 			? reference_name
 			: (_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],
-		       ": symbol `", undef_name, "' [", version->name,
-		       "] (skip)\n", NULL);
+		       ": ", protected ? "protected" : "normal",
+		       " symbol `", undef_name, "' [", version->name,
+		       "]\n", NULL);
+
+  if (__builtin_expect (protected == 0, 1))
+    {
+      *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_protected_versioned (undef_name, undef_map,
+					     hash, *ref,
+					     &protected_value, *scope,
+					     i, version, skip_map, 0))
+	while (*++scope)
+	  if (do_lookup_protected_versioned (undef_name, undef_map,
+					     hash, *ref,
+					     &protected_value, *scope,
+					     0, version, skip_map, 0))
+	    break;
 
-  *ref = current_value.s;
-  return LOOKUP_VALUE (current_value.m);
+      if (protected_value.s == NULL || protected_value.m == undef_map)
+	{
+	  *ref = current_value.s;
+	  return LOOKUP_VALUE (current_value.m);
+	}
+      else
+        return LOOKUP_VALUE (undef_map);
+    }
 }
 
 
Index: elf/dl-reloc.c
===================================================================
RCS file: /work/cvs/gnu/glibc/elf/dl-reloc.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 dl-reloc.c
--- elf/dl-reloc.c	2000/05/21 21:10:57	1.1.1.1
+++ elf/dl-reloc.c	2000/05/21 21:35:12
@@ -79,7 +79,7 @@ _dl_relocate_object (struct link_map *l,
 			     (flags)))					      \
      : l)
 #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			      \
 	? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref),    \
 				       scope, (version), (flags))	      \
Index: elf/dl-runtime.c
===================================================================
RCS file: /work/cvs/gnu/glibc/elf/dl-runtime.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 dl-runtime.c
--- elf/dl-runtime.c	2000/05/21 21:10:57	1.1.1.1
+++ elf/dl-runtime.c	2000/05/21 21:36:44
@@ -158,7 +158,7 @@ profile_fixup (
       /* Sanity check that we're really looking at a PLT relocation.  */
       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.  */
       if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
 	{
Index: elf/do-lookup.h
===================================================================
RCS file: /work/cvs/gnu/glibc/elf/do-lookup.h,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 do-lookup.h
--- elf/do-lookup.h	2000/05/21 21:10:58	1.1.1.1
+++ elf/do-lookup.h	2000/05/21 21:26:35
@@ -18,10 +18,18 @@
    Boston, MA 02111-1307, USA.  */
 
 #if VERSIONED
-# define FCT do_lookup_versioned
+# if PROTECTED
+#  define FCT do_lookup_protected_versioned
+# else
+#  define FCT do_lookup_versioned
+# endif
 # define ARG const struct r_found_version *const version,
 #else
-# define FCT do_lookup
+# if PROTECTED
+#  define FCT do_lookup_protected
+# else
+#  define FCT do_lookup
+# endif
 # define ARG
 #endif
 
@@ -56,10 +64,12 @@ FCT (const char *undef_name, struct link
       if (skip != NULL && map == skip)
 	continue;
 
+#if !PROTECTED
       /* Don't search the executable when resolving a copy reloc.  */
       if (elf_machine_lookup_noexec_p (reloc_type)
 	  && map->l_type == lt_executable)
 	continue;
+#endif
 
       /* Print some debugging info if wanted.  */
       if (_dl_debug_symbols)
@@ -80,8 +90,13 @@ FCT (const char *undef_name, struct link
 	  sym = &symtab[symidx];
 
 	  if (sym->st_value == 0 || /* No value.  */
+#if PROTECTED
+	      sym->st_shndx == SHN_UNDEF
+#else
 	      (elf_machine_lookup_noplt_p (reloc_type) /* Reject PLT entry.  */
-	       && sym->st_shndx == SHN_UNDEF))
+	       && sym->st_shndx == SHN_UNDEF)
+#endif
+	     )
 	    continue;
 
 	  if (ELFW(ST_TYPE) (sym->st_info) > STT_FUNC)
@@ -154,12 +169,7 @@ FCT (const char *undef_name, struct link
       sym = num_versions == 1 ? versioned_sym : NULL;
 #endif
 
-      if (sym != NULL
-	  /* Don't allow binding if the symbol is hidden.  When processor
-	     specific definitions for STV_INTERNAL are defined we might
-	     have to extend this conditional.  */
-	  && (ELFW(ST_VISIBILITY) (sym->st_other) != STV_HIDDEN
-	      || map == undef_map))
+      if (sym != NULL)
 	{
 	found_it:
 	  switch (ELFW(ST_BIND) (sym->st_info))
@@ -199,4 +209,5 @@ FCT (const char *undef_name, struct link
 
 #undef FCT
 #undef ARG
+#undef PROTECTED
 #undef VERSIONED

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]