about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-error.c28
-rw-r--r--elf/dl-lookup.c52
-rw-r--r--elf/dl-version.c19
-rw-r--r--elf/ldsodefs.h9
4 files changed, 66 insertions, 42 deletions
diff --git a/elf/dl-error.c b/elf/dl-error.c
index 9ccc193a66..e802c27763 100644
--- a/elf/dl-error.c
+++ b/elf/dl-error.c
@@ -43,7 +43,7 @@ __libc_tsd_define (static, DL_ERROR)
 #define tsd_setspecific(data)	__libc_tsd_set (DL_ERROR, (data))
 
 
-/* This points to a function which is called when an error is
+/* This points to a function which is called when an continuable error is
    received.  Unlike the handling of `catch' this function may return.
    The arguments will be the `errstring' and `objname'.
 
@@ -84,13 +84,6 @@ _dl_signal_error (int errcode,
 	}
       longjmp (lcatch->env, errcode ?: -1);
     }
-  else if (receiver)
-    {
-      /* We are inside _dl_receive_error.  Call the user supplied
-	 handler and resume the work.  The receiver will still be
-	 installed.  */
-      (*receiver) (errcode, objname, errstring);
-    }
   else
     {
       /* Lossage while resolving the program's own symbols is always fatal.  */
@@ -105,6 +98,25 @@ _dl_signal_error (int errcode,
     }
 }
 
+
+void
+internal_function
+_dl_signal_cerror (int errcode,
+		   const char *objname,
+		   const char *errstring)
+{
+  if (receiver)
+    {
+      /* We are inside _dl_receive_error.  Call the user supplied
+	 handler and resume the work.  The receiver will still be
+	 installed.  */
+      (*receiver) (errcode, objname, errstring);
+    }
+  else
+    _dl_signal_error (errcode, objname, errstring);
+}
+
+
 int
 internal_function
 _dl_catch_error (char **errstring,
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 9a691b72b0..16173c9068 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -96,10 +96,10 @@ _dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
     {
       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
 	/* We could find no value for a strong reference.  */
-	_dl_signal_error (0, (reference_name  && reference_name[0]
-			      ? reference_name
-			      : (_dl_argv[0] ?: "<main program>")),
-			  make_string (undefined_msg, undef_name));
+	_dl_signal_cerror (0, (reference_name  && reference_name[0]
+			       ? reference_name
+			       : (_dl_argv[0] ?: "<main program>")),
+			   make_string (undefined_msg, undef_name));
       *ref = NULL;
       return 0;
     }
@@ -199,29 +199,33 @@ _dl_lookup_versioned_symbol (const char *undef_name, const ElfW(Sym) **ref,
 	break;
 
       if (res < 0)
-	/* Oh, oh.  The file named in the relocation entry does not
-	   contain the needed symbol.  */
-	_dl_signal_error (0, (reference_name && reference_name[0]
-			      ? reference_name
-			      : (_dl_argv[0] ?: "<main program>")),
-			  make_string ("symbol ", undef_name, ", version ",
-				       version->name,
-				       " not defined in file ",
-				       version->filename,
-				       " with link time reference",
-				       res == -2
-				       ? " (no version symbols)" : ""));
+	{
+	  /* Oh, oh.  The file named in the relocation entry does not
+	     contain the needed symbol.  */
+	  _dl_signal_cerror (0, (reference_name && reference_name[0]
+				 ? reference_name
+				 : (_dl_argv[0] ?: "<main program>")),
+			     make_string ("symbol ", undef_name, ", version ",
+					  version->name,
+					  " not defined in file ",
+					  version->filename,
+					  " with link time reference",
+					  res == -2
+					  ? " (no version symbols)" : ""));
+	  *ref = NULL;
+	  return 0;
+	}
     }
 
   if (current_value.s == NULL)
     {
       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
 	/* We could find no value for a strong reference.  */
-	_dl_signal_error (0, (reference_name && reference_name[0]
-			      ? reference_name
-			      : (_dl_argv[0] ?: "<main program>")),
-			  make_string (undefined_msg, undef_name,
-				       ", version ", version->name ?: NULL));
+	_dl_signal_cerror (0, (reference_name && reference_name[0]
+			       ? reference_name
+			       : (_dl_argv[0] ?: "<main program>")),
+			   make_string (undefined_msg, undef_name,
+					", version ", version->name ?: NULL));
       *ref = NULL;
       return 0;
     }
@@ -281,9 +285,9 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
 	  char buf[sizeof undefined_msg + len];
 	  __mempcpy (__mempcpy (buf, undefined_msg, sizeof undefined_msg - 1),
 		     undef_name, len + 1);
-	  _dl_signal_error (0, (reference_name && reference_name[0]
-				? reference_name
-				: (_dl_argv[0] ?: "<main program>")), buf);
+	  _dl_signal_cerror (0, (reference_name && reference_name[0]
+				 ? reference_name
+				 : (_dl_argv[0] ?: "<main program>")), buf);
 	}
       *ref = NULL;
       return 0;
diff --git a/elf/dl-version.c b/elf/dl-version.c
index fbc41654ef..8d59fe278f 100644
--- a/elf/dl-version.c
+++ b/elf/dl-version.c
@@ -93,9 +93,10 @@ match_symbol (const char *name, ElfW(Word) hash, const char *string,
 	 object was linked against another version of this file.  We
 	 only print a message if verbose output is requested.  */
       if (verbose)
-	_dl_signal_error (0, map->l_name, make_string ("\
+	_dl_signal_cerror (0, map->l_name,
+			   make_string ("\
 no version information available (required by ",
-						       name, ")"));
+					name, ")"));
       return 0;
     }
 
@@ -143,16 +144,16 @@ no version information available (required by ",
   if (weak)
     {
       if (verbose)
-	_dl_signal_error (0, map->l_name,
-			  make_string ("weak version `", string,
-				       "' not found (required by ", name,
-				       ")"));
+	_dl_signal_cerror (0, map->l_name,
+			   make_string ("weak version `", string,
+					"' not found (required by ", name,
+					")"));
       return 0;
     }
 
-  _dl_signal_error (0, map->l_name,
-		    make_string ("version `", string,
-				 "' not found (required by ", name, ")"));
+  _dl_signal_cerror (0, map->l_name,
+		     make_string ("version `", string,
+				  "' not found (required by ", name, ")"));
   return 1;
 }
 
diff --git a/elf/ldsodefs.h b/elf/ldsodefs.h
index 61652ddde4..392ea1787f 100644
--- a/elf/ldsodefs.h
+++ b/elf/ldsodefs.h
@@ -208,6 +208,13 @@ extern void _dl_signal_error (int errcode,
      internal_function
      __attribute__ ((__noreturn__));
 
+/* Like _dl_signal_error, but may return when called in the context of
+   _dl_receive_error.  */
+extern void _dl_signal_cerror (int errcode,
+			       const char *object,
+			       const char *errstring)
+     internal_function;
+
 /* Call OPERATE, catching errors from `dl_signal_error'.  If there is no
    error, *ERRSTRING is set to null.  If there is an error, *ERRSTRING is
    set to a string constructed from the strings passed to _dl_signal_error,
@@ -219,7 +226,7 @@ extern int _dl_catch_error (char **errstring,
 			    void *args)
      internal_function;
 
-/* Call OPERATE, receiving errors from `dl_signal_error'.  Unlike
+/* Call OPERATE, receiving errors from `dl_signal_cerror'.  Unlike
    `_dl_catch_error' the operation is resumed after the OPERATE
    function returns.
    ARGS is passed as argument to OPERATE.  */