about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-lookup.c51
-rw-r--r--elf/dl-reloc.c26
-rw-r--r--elf/do-lookup.h9
3 files changed, 42 insertions, 44 deletions
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 71dda25aff..5fa6b73b50 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -175,14 +175,14 @@ 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 link_map *skip, int noexec, int noplt);
+	       struct link_map *skip, int type_class);
 static int
 internal_function
 _dl_do_lookup_versioned (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,
-			 struct link_map *skip, int noexec, int noplt);
+			 struct link_map *skip, int type_class);
 
 
 /* Search loaded objects' symbol tables for a definition of the symbol
@@ -192,21 +192,19 @@ 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 reloc_type, int explicit)
+		   int type_class, int explicit)
 {
   unsigned long int hash = _dl_elf_hash (undef_name);
   struct sym_val current_value = { NULL, NULL };
   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;
 
   /* 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,
-		   noexec, noplt))
+		   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
@@ -223,7 +221,7 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
 	  /* Something went wrong.  Perhaps the object we tried to reference
 	     was just removed.  Try finding another definition.  */
 	  return _dl_lookup_symbol (undef_name, undef_map, ref, symbol_scope,
-				    reloc_type, 0);
+				    type_class, 0);
 
 	break;
       }
@@ -270,7 +268,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, 0, 1))
+			   0, NULL, ELF_RTYPE_CLASS_PLT))
 	  break;
 
       if (protected_value.s == NULL || protected_value.m == undef_map)
@@ -311,10 +309,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, 0))
+		       skip_map, 0))
     while (*++scope)
       if (_dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, 0,
-			 skip_map, 0, 0))
+			 skip_map, 0))
 	break;
 
   if (__builtin_expect (current_value.s == NULL, 0))
@@ -346,10 +344,10 @@ _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, 0, 1))
+			     i, skip_map, ELF_RTYPE_CLASS_PLT))
 	while (*++scope)
 	  if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
-			     0, skip_map, 0, 1))
+			     0, skip_map, ELF_RTYPE_CLASS_PLT))
 	    break;
 
       if (protected_value.s == NULL || protected_value.m == undef_map)
@@ -374,14 +372,12 @@ _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 reloc_type, int explicit)
+			     int type_class, int explicit)
 {
   unsigned long int hash = _dl_elf_hash (undef_name);
   struct sym_val current_value = { NULL, NULL };
   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;
 
@@ -389,7 +385,7 @@ _dl_lookup_versioned_symbol (const char *undef_name,
   for (scope = symbol_scope; *scope; ++scope)
     {
       int res = do_lookup_versioned (undef_name, hash, *ref, &current_value,
-				     *scope, 0, version, NULL, noexec, noplt);
+				     *scope, 0, version, NULL, type_class);
       if (res > 0)
 	{
 	  /* We have to check whether this would bind UNDEF_MAP to an object
@@ -408,7 +404,7 @@ _dl_lookup_versioned_symbol (const char *undef_name,
 	       was just removed.  Try finding another definition.  */
 	    return _dl_lookup_versioned_symbol (undef_name, undef_map, ref,
 						symbol_scope, version,
-						reloc_type, 0);
+						type_class, 0);
 
 	  break;
 	}
@@ -482,7 +478,8 @@ _dl_lookup_versioned_symbol (const char *undef_name,
 
       for (scope = symbol_scope; *scope; ++scope)
 	if (_dl_do_lookup_versioned (undef_name, hash, *ref, &protected_value,
-				     *scope, 0, version, NULL, 0, 1))
+				     *scope, 0, version, NULL,
+				     ELF_RTYPE_CLASS_PLT))
 	  break;
 
       if (protected_value.s == NULL || protected_value.m == undef_map)
@@ -522,10 +519,10 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
     assert (i < (*scope)->r_nlist);
 
   if (! _dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
-				 *scope, i, version, skip_map, 0, 0))
+				 *scope, i, version, skip_map, 0))
     while (*++scope)
       if (_dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
-				   *scope, 0, version, skip_map, 0, 0))
+				   *scope, 0, version, skip_map, 0))
 	break;
 
   if (__builtin_expect (current_value.s == NULL, 0))
@@ -571,11 +568,11 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
       if (i >= (*scope)->r_nlist
 	  || !_dl_do_lookup_versioned (undef_name, hash, *ref,
 				       &protected_value, *scope, i, version,
-				       skip_map, 0, 1))
+				       skip_map, ELF_RTYPE_CLASS_PLT))
 	while (*++scope)
 	  if (_dl_do_lookup_versioned (undef_name, hash, *ref,
 				       &protected_value, *scope, 0, version,
-				       skip_map, 0, 1))
+				       skip_map, ELF_RTYPE_CLASS_PLT))
 	    break;
 
       if (protected_value.s == NULL || protected_value.m == undef_map)
@@ -616,10 +613,10 @@ 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 link_map *skip, int noexec, int noplt)
+	       struct link_map *skip, int type_class)
 {
-  return do_lookup (undef_name, hash, ref, result, scope, i, skip, noexec,
-		    noplt);
+  return do_lookup (undef_name, hash, ref, result, scope, i, skip,
+		    type_class);
 }
 
 static int
@@ -628,8 +625,8 @@ _dl_do_lookup_versioned (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,
-			 struct link_map *skip, int noexec, int noplt)
+			 struct link_map *skip, int type_class)
 {
   return do_lookup_versioned (undef_name, hash, ref, result, scope, i,
-			      version, skip, noexec, noplt);
+			      version, skip, type_class);
 }
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 276aea094b..6e38648d88 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -75,45 +75,43 @@ cannot make segment writable for relocation"));
     const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
 
     /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
-#define RESOLVE_MAP(ref, version, flags) \
+#define RESOLVE_MAP(ref, version, r_type) \
     (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL			      \
      ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)		      \
-	 && elf_machine_lookup_noexec_p (flags) == l->l_lookup_cache.noexec   \
-	 && elf_machine_lookup_noplt_p (flags) == l->l_lookup_cache.noplt)    \
+	 && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class)  \
 	? (++_dl_num_cache_relocations,					      \
 	   (*ref) = l->l_lookup_cache.ret,				      \
 	   l->l_lookup_cache.value)					      \
 	: ({ lookup_t _lr;						      \
+	     int _tc = elf_machine_type_class (r_type);			      \
+	     l->l_lookup_cache.type_class = _tc;			      \
 	     l->l_lookup_cache.sym = (*ref);				      \
-	     l->l_lookup_cache.noexec = elf_machine_lookup_noexec_p (flags);  \
-	     l->l_lookup_cache.noplt = elf_machine_lookup_noplt_p (flags);    \
 	     _lr = ((version) != NULL && (version)->hash != 0		      \
 		    ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name,  \
 						   l, (ref), scope,	      \
-						   (version), (flags), 0)     \
+						   (version), _tc, 0)	      \
 		    : _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref),  \
-					 scope, (flags), 0));		      \
+					 scope, _tc, 0));		      \
 	     l->l_lookup_cache.ret = (*ref);				      \
 	     l->l_lookup_cache.value = _lr; }))				      \
      : l)
-#define RESOLVE(ref, version, flags) \
+#define RESOLVE(ref, version, r_type) \
     (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL			      \
      ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)		      \
-	 && elf_machine_lookup_noexec_p (flags) == l->l_lookup_cache.noexec   \
-	 && elf_machine_lookup_noplt_p (flags) == l->l_lookup_cache.noplt)    \
+	 && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class)  \
 	? (++_dl_num_cache_relocations,					      \
 	   (*ref) = l->l_lookup_cache.ret,				      \
 	   l->l_lookup_cache.value)					      \
 	: ({ lookup_t _lr;						      \
+	     int _tc = elf_machine_type_class (r_type);			      \
+	     l->l_lookup_cache.type_class = _tc;			      \
 	     l->l_lookup_cache.sym = (*ref);				      \
-	     l->l_lookup_cache.noexec = elf_machine_lookup_noexec_p (flags);  \
-	     l->l_lookup_cache.noplt = elf_machine_lookup_noplt_p (flags);    \
 	     _lr = ((version) != NULL && (version)->hash != 0		      \
 		    ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name,  \
 						   l, (ref), scope,	      \
-						   (version), (flags), 0)     \
+						   (version), _tc, 0)	      \
 		    : _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref),  \
-					 scope, (flags), 0));		      \
+					 scope, _tc, 0));		      \
 	     l->l_lookup_cache.ret = (*ref);				      \
 	     l->l_lookup_cache.value = _lr; }))				      \
      : l->l_addr)
diff --git a/elf/do-lookup.h b/elf/do-lookup.h
index e60e227fcd..b9364b95d1 100644
--- a/elf/do-lookup.h
+++ b/elf/do-lookup.h
@@ -31,7 +31,7 @@
 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 link_map *skip, int noexec, int noplt)
+     struct link_map *skip, int type_class)
 {
   struct link_map **list = scope->r_list;
   size_t n = scope->r_nlist;
@@ -56,7 +56,7 @@ FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref,
 	continue;
 
       /* Don't search the executable when resolving a copy reloc.  */
-      if (noexec && map->l_type == lt_executable)
+      if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable)
 	continue;
 
       /* Print some debugging info if wanted.  */
@@ -76,8 +76,11 @@ FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref,
 	{
 	  sym = &symtab[symidx];
 
+	  assert (ELF_RTYPE_CLASS_PLT == 1);
 	  if (sym->st_value == 0 || /* No value.  */
-	      (noplt && sym->st_shndx == SHN_UNDEF))
+	      /* ((type_class & ELF_RTYPE_CLASS_PLT)
+		  && (sym->st_shndx == SHN_UNDEF)) */
+	      (type_class & (sym->st_shndx == SHN_UNDEF)))
 	    continue;
 
 	  if (ELFW(ST_TYPE) (sym->st_info) > STT_FUNC)