about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-06-10 04:01:36 +0000
committerUlrich Drepper <drepper@redhat.com>2000-06-10 04:01:36 +0000
commit8e17ea58173d35e2e5dabfeb9fa5abf2609cfc51 (patch)
treede81e2ebf2b5b32510d511caa07c2496e3d540ba
parentf3863621f617b040c66d635109203c29f35f7331 (diff)
downloadglibc-8e17ea58173d35e2e5dabfeb9fa5abf2609cfc51.tar.gz
glibc-8e17ea58173d35e2e5dabfeb9fa5abf2609cfc51.tar.xz
glibc-8e17ea58173d35e2e5dabfeb9fa5abf2609cfc51.zip
Update.
2000-06-09  Ulrich Drepper  <drepper@redhat.com>

	Rewrite error message handling.
	* elf/dl-deps.c (_dl_map_object_deps): Pass new parameter to
	_dl_catch_error.
	* elf/dl-error (struct catch): Add objname member.
	(_dl_signal_error): Take new parameter with object name.  When
	passing message on simply store object name and duplicate error
	message.
	(_dl_catch_error): Take new parameter.  Store object name in the
	place pointed to.
	* include/dlfcn.h: Adjust _dl_catch_error prototype.
	* sysdeps/generic/ldsodefs.h: Adjust _dl_signal_error prototype.
	* elf/dl-libc.c (dlerror_run): Pass new parameter to _dl_catch_error.
	* elf/dl-open.c (_dl_open): Likewise.
	* elf/rtld.c (dl_main): Likewise.
	* elf/dl-close.c: Mark error messages with N_().
	* elf/dl-deps.c: Likewise.
	* elf/dl-error.c: Likewise.
	* elf/dl-load.c: Likewise.
	* elf/dl-open.c: Likewise.
	* elf/dl-reloc.c: Likewise.
	* elf/dl-support.c: Likewise.
	* elf/dl-sym.c: Likewise.
	* elf/dl-version.c: Likewise.
	* elf/dl-lookup.c: Add comments about problems with error message
	translations.
	* elf/dl-reloc.c: Likewise.
	* elf/dl-version.c: Likewise.
-rw-r--r--ChangeLog30
-rw-r--r--elf/dl-close.c5
-rw-r--r--elf/dl-deps.c18
-rw-r--r--elf/dl-error.c34
-rw-r--r--elf/dl-libc.c9
-rw-r--r--elf/dl-load.c80
-rw-r--r--elf/dl-lookup.c4
-rw-r--r--elf/dl-open.c17
-rw-r--r--elf/dl-reloc.c13
-rw-r--r--elf/dl-support.c3
-rw-r--r--elf/dl-sym.c4
-rw-r--r--elf/dl-version.c8
-rw-r--r--elf/rtld.c9
-rw-r--r--include/dlfcn.h7
-rw-r--r--sysdeps/generic/ldsodefs.h3
15 files changed, 146 insertions, 98 deletions
diff --git a/ChangeLog b/ChangeLog
index f227d660db..aae57faa2d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2000-06-09  Ulrich Drepper  <drepper@redhat.com>
+
+	Rewrite error message handling.
+	* elf/dl-deps.c (_dl_map_object_deps): Pass new parameter to
+	_dl_catch_error.
+	* elf/dl-error (struct catch): Add objname member.
+	(_dl_signal_error): Take new parameter with object name.  When
+	passing message on simply store object name and duplicate error
+	message.
+	(_dl_catch_error): Take new parameter.  Store object name in the
+	place pointed to.
+	* include/dlfcn.h: Adjust _dl_catch_error prototype.
+	* sysdeps/generic/ldsodefs.h: Adjust _dl_signal_error prototype.
+	* elf/dl-libc.c (dlerror_run): Pass new parameter to _dl_catch_error.
+	* elf/dl-open.c (_dl_open): Likewise.
+	* elf/rtld.c (dl_main): Likewise.
+	* elf/dl-close.c: Mark error messages with N_().
+	* elf/dl-deps.c: Likewise.
+	* elf/dl-error.c: Likewise.
+	* elf/dl-load.c: Likewise.
+	* elf/dl-open.c: Likewise.
+	* elf/dl-reloc.c: Likewise.
+	* elf/dl-support.c: Likewise.
+	* elf/dl-sym.c: Likewise.
+	* elf/dl-version.c: Likewise.
+	* elf/dl-lookup.c: Add comments about problems with error message
+	translations.
+	* elf/dl-reloc.c: Likewise.
+	* elf/dl-version.c: Likewise.
+
 2000-06-09  David Mosberger-Tang  <davidm@hpl.hp.com>
 
 	* sysdeps/unix/sysv/linux/ia64/__longjmp.S: new file
diff --git a/elf/dl-close.c b/elf/dl-close.c
index d6f00008b1..ec563ed8d0 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -19,6 +19,7 @@
 
 #include <assert.h>
 #include <dlfcn.h>
+#include <libintl.h>
 #include <stdlib.h>
 #include <string.h>
 #include <bits/libc-lock.h>
@@ -36,8 +37,6 @@ typedef void (*fini_t) (void);
    protect `dlopen' and `dlclose' in dlclose.c.  */
 __libc_lock_define (extern, _dl_load_lock)
 
-#define LOSE(s) _dl_signal_error (0, map->l_name, s)
-
 void
 internal_function
 _dl_close (void *_map)
@@ -50,7 +49,7 @@ _dl_close (void *_map)
   unsigned int i;
 
   if (map->l_opencount == 0)
-    LOSE ("shared object not open");
+    _dl_signal_error (0, map->l_name, N_("shared object not open"));
 
   /* Acquire the lock.  */
   __libc_lock_lock (_dl_load_lock);
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 670b9df8d4..7c7b4b6672 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include <dlfcn.h>
 #include <errno.h>
+#include <libintl.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -102,7 +103,7 @@ struct list
 	/* DST must not appear in SUID/SGID programs.  */		      \
 	if (__libc_enable_secure)					      \
 	  _dl_signal_error (0, __str,					      \
-			    "DST not allowed in SUID/SGID programs");	      \
+			    N_("DST not allowed in SUID/SGID programs"));     \
 									      \
 	__newp = (char *) alloca (DL_DST_REQUIRED (l, __str, strlen (__str),  \
 						   __cnt));		      \
@@ -114,8 +115,8 @@ struct list
 	    /* The replacement for the DST is not known.  We can't	      \
 	       processed.  */						      \
 	    if (fatal)							      \
-	      _dl_signal_error (0, __str,				      \
-				"empty dynamics string token substitution");  \
+	      _dl_signal_error (0, __str, N_("\
+empty dynamics string token substitution"));				      \
 	    else							      \
 	      {								      \
 		/* This is for DT_AUXILIARY.  */			      \
@@ -265,7 +266,8 @@ _dl_map_object_deps (struct link_map *map,
 	      }
 	    else if (d->d_tag == DT_AUXILIARY || d->d_tag == DT_FILTER)
 	      {
-		char *errstring;
+		const char *objname;
+		const char *errstring;
 		struct list *newp;
 		/* Object name.  */
 		const char *name;
@@ -289,11 +291,11 @@ _dl_map_object_deps (struct link_map *map,
 
 		    /* We must be prepared that the addressed shared
 		       object is not available.  */
-		    if (_dl_catch_error (&errstring, openaux, &args))
+		    if (_dl_catch_error (&objname, &errstring, openaux, &args))
 		      {
 			/* We are not interested in the error message.  */
 			assert (errstring != NULL);
-			free (errstring);
+			free ((char *) errstring);
 
 			/* Simply ignore this error and continue the work.  */
 			continue;
@@ -452,7 +454,7 @@ _dl_map_object_deps (struct link_map *map,
 	  l->l_initfini = malloc (nneeded * sizeof needed[0]);
 	  if (l->l_initfini == NULL)
 	    _dl_signal_error (ENOMEM, map->l_name,
-			      "cannot allocate dependency list");
+			      N_("cannot allocate dependency list"));
 	  memcpy (l->l_initfini, needed, nneeded * sizeof needed[0]);
 	}
 
@@ -470,7 +472,7 @@ _dl_map_object_deps (struct link_map *map,
 				     * sizeof (struct link_map *));
   if (map->l_searchlist.r_list == NULL)
     _dl_signal_error (ENOMEM, map->l_name,
-		      "cannot allocate symbol search list");
+		      N_("cannot allocate symbol search list"));
   map->l_searchlist.r_nlist = nlist;
 
   for (nlist = 0, runp = known; runp; runp = runp->unique)
diff --git a/elf/dl-error.c b/elf/dl-error.c
index fbf5fce04f..88ab8e9519 100644
--- a/elf/dl-error.c
+++ b/elf/dl-error.c
@@ -17,6 +17,7 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <libintl.h>
 #include <setjmp.h>
 #include <stdlib.h>
 #include <string.h>
@@ -28,7 +29,8 @@
    _dl_signal_error.  */
 struct catch
   {
-    char *errstring;		/* Error detail filled in here.  */
+    const char *objname;	/* Object/File name.  */
+    const char *errstring;	/* Error detail filled in here.  */
     jmp_buf env;		/* longjmp here on error.  */
   };
 
@@ -55,34 +57,21 @@ static receiver_fct receiver;
 
 void
 internal_function
-_dl_signal_error (int errcode,
-		  const char *objname,
-		  const char *errstring)
+_dl_signal_error (int errcode, const char *objname, const char *errstring)
 {
   struct catch *lcatch;
 
   if (! errstring)
-    errstring = "DYNAMIC LINKER BUG!!!";
+    errstring = N_("DYNAMIC LINKER BUG!!!");
 
   lcatch = tsd_getspecific ();
   if (lcatch != NULL)
     {
       /* We are inside _dl_catch_error.  Return to it.  We have to
 	 duplicate the error string since it might be allocated on the
-	 stack.  */
-      size_t objname_len = objname ? strlen (objname) + 2 : 0;
-      size_t errstring_len = strlen (errstring) + 1;
-      lcatch->errstring = malloc (objname_len + errstring_len);
-      if (lcatch->errstring != NULL)
-	{
-	  char *cp = lcatch->errstring;
-	  if (objname_len > 0)
-	    {
-	      cp = __mempcpy (cp, objname, objname_len - 2);
-	      cp = __mempcpy (cp, ": ", 2);
-	    }
-	  memcpy (cp, errstring, errstring_len);
-	}
+	 stack.  The object name is always a string constant.  */
+      lcatch->objname = objname;
+      lcatch->errstring = strdup (errstring);
       longjmp (lcatch->env, errcode ?: -1);
     }
   else
@@ -120,9 +109,8 @@ _dl_signal_cerror (int errcode,
 
 int
 internal_function
-_dl_catch_error (char **errstring,
-		 void (*operate) (void *),
-		 void *args)
+_dl_catch_error (const char **objname, const char **errstring,
+		 void (*operate) (void *), void *args)
 {
   int errcode;
   struct catch *volatile old;
@@ -141,12 +129,14 @@ _dl_catch_error (char **errstring,
       tsd_setspecific (&c);
       (*operate) (args);
       tsd_setspecific (old);
+      *objname = NULL;
       *errstring = NULL;
       return 0;
     }
 
   /* We get here only if we longjmp'd out of OPERATE.  */
   tsd_setspecific (old);
+  *objname = c.objname;
   *errstring = c.errstring;
   return errcode == -1 ? 0 : errcode;
 }
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
index c95935ff75..38774e50a0 100644
--- a/elf/dl-libc.c
+++ b/elf/dl-libc.c
@@ -1,5 +1,5 @@
 /* Handle loading and unloading shared objects for internal libc purposes.
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Zack Weinberg <zack@rabi.columbia.edu>, 1999.
 
@@ -35,14 +35,15 @@ static int
 internal_function
 dlerror_run (void (*operate) (void *), void *args)
 {
-  char *last_errstring = NULL;
+  const char *objname;
+  const char *last_errstring = NULL;
   int result;
 
-  (void) _dl_catch_error (&last_errstring, operate, args);
+  (void) _dl_catch_error (&objname, &last_errstring, operate, args);
 
   result = last_errstring != NULL;
   if (result)
-    free (last_errstring);
+    free ((char *) last_errstring);
 
   return result;
 }
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 17ce562ddd..2c506b55c1 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -20,6 +20,7 @@
 #include <elf.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <libintl.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -62,10 +63,8 @@
 #include <endian.h>
 #if BYTE_ORDER == BIG_ENDIAN
 # define byteorder ELFDATA2MSB
-# define byteorder_name "big-endian"
 #elif BYTE_ORDER == LITTLE_ENDIAN
 # define byteorder ELFDATA2LSB
-# define byteorder_name "little-endian"
 #else
 # error "Unknown BYTE_ORDER " BYTE_ORDER
 # define byteorder ELFDATANONE
@@ -315,7 +314,7 @@ add_name_to_object (struct link_map *l, const char *name)
   if (newname == NULL)
     {
       /* No more memory.  */
-      _dl_signal_error (ENOMEM, name, "cannot allocate name record");
+      _dl_signal_error (ENOMEM, name, N_("cannot allocate name record"));
       return;
     }
   /* The object should have a libname set from _dl_new_object.  */
@@ -414,7 +413,7 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
 	    malloc (sizeof (*dirp) + ncapstr * sizeof (enum r_dir_status));
 	  if (dirp == NULL)
 	    _dl_signal_error (ENOMEM, NULL,
-			      "cannot create cache for search path");
+			      N_("cannot create cache for search path"));
 
 	  dirp->dirname = cp;
 	  dirp->dirnamelen = len;
@@ -475,7 +474,7 @@ decompose_rpath (const char *rpath, struct link_map *l, const char *what)
 		malloc (sizeof (*result));
 	      if (result == NULL)
 		_dl_signal_error (ENOMEM, NULL,
-				  "cannot create cache for search path");
+				  N_("cannot create cache for search path"));
 	      result[0] = NULL;
 
 	      return result;
@@ -487,7 +486,7 @@ decompose_rpath (const char *rpath, struct link_map *l, const char *what)
      string tokens.  */
   copy = expand_dynamic_string_token (l, rpath);
   if (copy == NULL)
-    _dl_signal_error (ENOMEM, NULL, "cannot create RUNPATH/RPATH copy");
+    _dl_signal_error (ENOMEM, NULL, N_("cannot create RUNPATH/RPATH copy"));
 
   /* Count the number of necessary elements in the result array.  */
   nelems = 0;
@@ -500,7 +499,7 @@ decompose_rpath (const char *rpath, struct link_map *l, const char *what)
   result = (struct r_search_path_elem **) malloc ((nelems + 1 + 1)
 						  * sizeof (*result));
   if (result == NULL)
-    _dl_signal_error (ENOMEM, NULL, "cannot create cache for search path");
+    _dl_signal_error (ENOMEM, NULL, N_("cannot create cache for search path"));
 
   return fillin_rpath (copy, result, ":", 0, what, where);
 }
@@ -530,7 +529,7 @@ _dl_init_paths (const char *llp)
     malloc ((sizeof (system_dirs_len) / sizeof (system_dirs_len[0]) + 1)
 	     * sizeof (struct r_search_path_elem *));
   if (rtld_search_dirs == NULL)
-    _dl_signal_error (ENOMEM, NULL, "cannot create search path array");
+    _dl_signal_error (ENOMEM, NULL, N_("cannot create search path array"));
 
   round_size = ((2 * sizeof (struct r_search_path_elem) - 1
 		 + ncapstr * sizeof (enum r_dir_status))
@@ -540,7 +539,7 @@ _dl_init_paths (const char *llp)
     malloc ((sizeof (system_dirs) / sizeof (system_dirs[0]))
 	    * round_size * sizeof (struct r_search_path_elem));
   if (rtld_search_dirs[0] == NULL)
-    _dl_signal_error (ENOMEM, NULL, "cannot create cache for search path");
+    _dl_signal_error (ENOMEM, NULL, N_("cannot create cache for search path"));
 
   pelem = all_dirs = rtld_search_dirs[0];
   strp = system_dirs;
@@ -632,7 +631,7 @@ _dl_init_paths (const char *llp)
 	malloc ((nllp + 1) * sizeof (struct r_search_path_elem *));
       if (env_path_list == NULL)
 	_dl_signal_error (ENOMEM, NULL,
-			  "cannot create cache for search path");
+			  N_("cannot create cache for search path"));
 
       (void) fillin_rpath (local_strdup (llp), env_path_list, ":;",
 			   __libc_enable_secure, "LD_LIBRARY_PATH", NULL);
@@ -720,7 +719,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
 			      fixed|MAP_COPY|MAP_FILE,
 			      fd, offset);
       if (mapat == MAP_FAILED)
-	LOSE (errno, "failed to map segment from shared object");
+	LOSE (errno, N_("failed to map segment from shared object"));
       return mapat;
     }
 
@@ -735,7 +734,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
 
   /* Get file information.  */
   if (__fxstat (_STAT_VER, fd, &st) < 0)
-    LOSE (errno, "cannot stat shared object");
+    LOSE (errno, N_("cannot stat shared object"));
 
   /* Look again to see if the real name matched another already loaded.  */
   for (l = _dl_loaded; l; l = l->l_next)
@@ -761,7 +760,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
   readbuf = alloca (_dl_pagesize);
   readlength = __libc_read (fd, readbuf, _dl_pagesize);
   if (readlength < (ssize_t) sizeof (*header))
-    LOSE (errno, "cannot read file data");
+    LOSE (errno, N_("cannot read file data"));
   header = (void *) readbuf;
 
   /* Check the header for basic validity.  */
@@ -782,29 +781,39 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
 	   (ELFMAG3 << (EI_MAG0 * 8)))
 #endif
 	  )
-	LOSE (0, "invalid ELF header");
+	LOSE (0, N_("invalid ELF header"));
       if (header->e_ident[EI_CLASS] != ELFW(CLASS))
-	LOSE (0, "ELF file class not " STRING(__ELF_NATIVE_CLASS) "-bit");
+	{
+	  if (__ELF_NATIVE_CLASS == 32)
+	    LOSE (0, N_("ELF file class not 32-bit"));
+	  else
+	    LOSE (0, N_("ELF file class not 64-bit"));
+	}
       if (header->e_ident[EI_DATA] != byteorder)
-	LOSE (0, "ELF file data encoding not " byteorder_name);
+	{
+	  if (BYTE_ORDER == BIG_ENDIAN)
+	    LOSE (0, "ELF file data encoding not big-endian");
+	  else
+	    LOSE (0, "ELF file data encoding not little-endian");
+	}
       if (header->e_ident[EI_VERSION] != EV_CURRENT)
-	LOSE (0, "ELF file version ident not " STRING(EV_CURRENT));
+	LOSE (0, N_("ELF file version ident does not match current one"));
       /* XXX We should be able so set system specific versions which are
 	 allowed here.  */
       if (!VALID_ELF_OSABI (header->e_ident[EI_OSABI]))
-	LOSE (0, "ELF file OS ABI invalid.");
+	LOSE (0, N_("ELF file OS ABI invalid."));
       if (!VALID_ELF_ABIVERSION (header->e_ident[EI_ABIVERSION]))
-	LOSE (0, "ELF file ABI version invalid.");
-      LOSE (0, "internal error");
+	LOSE (0, N_("ELF file ABI version invalid."));
+      LOSE (0, N_("internal error"));
     }
 
   if (__builtin_expect (header->e_version, EV_CURRENT) != EV_CURRENT)
-    LOSE (0, "ELF file version not " STRING(EV_CURRENT));
+    LOSE (0, N_("ELF file version does not not match current one"));
   if (! __builtin_expect (elf_machine_matches_host (header->e_machine), 1))
-    LOSE (0, "ELF file machine architecture not " ELF_MACHINE_NAME);
+    LOSE (0, N_("ELF file machine architecture does not match"));
   if (__builtin_expect (header->e_phentsize, sizeof (ElfW(Phdr)))
       != sizeof (ElfW(Phdr)))
-    LOSE (0, "ELF file's phentsize not the expected size");
+    LOSE (0, N_("ELF file's phentsize not the expected size"));
 
 #ifndef MAP_ANON
 # define MAP_ANON 0
@@ -814,7 +823,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
       if (_dl_zerofd == -1)
 	{
 	  __close (fd);
-	  _dl_signal_error (errno, NULL, "cannot open zero fill device");
+	  _dl_signal_error (errno, NULL, N_("cannot open zero fill device"));
 	}
     }
 #endif
@@ -822,7 +831,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
   /* Enter the new object in the list of loaded objects.  */
   l = _dl_new_object (realname, name, l_type, loader);
   if (__builtin_expect (! l, 0))
-    LOSE (ENOMEM, "cannot create shared object descriptor");
+    LOSE (ENOMEM, N_("cannot create shared object descriptor"));
   l->l_opencount = 1;
 
   /* Extract the remaining details we need from the ELF header
@@ -839,7 +848,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
       phdr = alloca (maplength);
       __lseek (fd, SEEK_SET, header->e_phoff);
       if (__libc_read (fd, (void *) phdr, maplength) != maplength)
-        LOSE (errno, "cannot read file data");
+        LOSE (errno, N_("cannot read file data"));
     }
 
   {
@@ -874,9 +883,10 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
 	  /* A load command tells us to map in part of the file.
 	     We record the load commands and process them all later.  */
 	  if (ph->p_align % _dl_pagesize != 0)
-	    LOSE (0, "ELF load command alignment not page-aligned");
+	    LOSE (0, N_("ELF load command alignment not page-aligned"));
 	  if ((ph->p_vaddr - ph->p_offset) % ph->p_align)
-	    LOSE (0, "ELF load command address/offset not properly aligned");
+	    LOSE (0,
+		  N_("ELF load command address/offset not properly aligned"));
 	  {
 	    struct loadcmd *c = &loadcmds[nloadcmds++];
 	    c->mapstart = ph->p_vaddr & ~(ph->p_align - 1);
@@ -993,7 +1003,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
 		    /* Dag nab it.  */
 		    if (__mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)),
 				    _dl_pagesize, c->prot|PROT_WRITE) < 0)
-		      LOSE (errno, "cannot change memory protections");
+		      LOSE (errno, N_("cannot change memory protections"));
 		  }
 		memset ((void *) zero, 0, zeropage - zero);
 		if ((c->prot & PROT_WRITE) == 0)
@@ -1009,7 +1019,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
 				c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED,
 				ANONFD, 0);
 		if (mapat == MAP_FAILED)
-		  LOSE (errno, "cannot map zero-fill pages");
+		  LOSE (errno, N_("cannot map zero-fill pages"));
 	      }
 	  }
 
@@ -1024,7 +1034,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
 	ElfW(Phdr) *newp = (ElfW(Phdr) *) malloc (header->e_phnum
 						  * sizeof (ElfW(Phdr)));
 	if (newp == NULL)
-	  LOSE (ENOMEM, "cannot allocate memory for program header");
+	  LOSE (ENOMEM, N_("cannot allocate memory for program header"));
 
 	l->l_phdr = memcpy (newp, phdr,
 			    (header->e_phnum * sizeof (ElfW(Phdr))));
@@ -1044,7 +1054,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
   if (l->l_ld == 0)
     {
       if (type == ET_DYN)
-	LOSE (0, "object file has no dynamic section");
+	LOSE (0, N_("object file has no dynamic section"));
     }
   else
     (ElfW(Addr)) l->l_ld += l->l_addr;
@@ -1099,7 +1109,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
 	(struct link_map **) malloc (sizeof (struct link_map *));
 
       if (l->l_symbolic_searchlist.r_list == NULL)
-	LOSE (ENOMEM, "cannot create searchlist");
+	LOSE (ENOMEM, N_("cannot create searchlist"));
 
       l->l_symbolic_searchlist.r_list[0] = l;
       l->l_symbolic_searchlist.r_nlist = 1;
@@ -1475,7 +1485,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
 	  if ((name_copy = local_strdup (name)) == NULL
 	      || (l = _dl_new_object (name_copy, name, type, loader)) == NULL)
 	    _dl_signal_error (ENOMEM, name,
-			      "cannot create shared object descriptor");
+			      N_("cannot create shared object descriptor"));
 	  /* We use an opencount of 0 as a sign for the faked entry.
 	     Since the descriptor is initialized with zero we do not
 	     have do this here.
@@ -1488,7 +1498,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
 	  return l;
 	}
       else
-	_dl_signal_error (errno, name, "cannot open shared object file");
+	_dl_signal_error (errno, name, N_("cannot open shared object file"));
     }
 
   return _dl_map_object_from_fd (name, fd, realname, loader, type);
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index d01fdaa648..f1ec98e74b 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -229,6 +229,7 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
     {
       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
 	/* We could find no value for a strong reference.  */
+	/* XXX We cannot translate the messages.  */
 	_dl_signal_cerror (0, (reference_name && reference_name[0]
 			       ? reference_name
 			       : (_dl_argv[0] ?: "<main program>")),
@@ -446,6 +447,7 @@ _dl_lookup_versioned_symbol (const char *undef_name,
 	{
 	  /* Oh, oh.  The file named in the relocation entry does not
 	     contain the needed symbol.  */
+	  /* XXX We cannot translate the message.  */
 	  _dl_signal_cerror (0, (reference_name && reference_name[0]
 				 ? reference_name
 				 : (_dl_argv[0] ?: "<main program>")),
@@ -465,6 +467,7 @@ _dl_lookup_versioned_symbol (const char *undef_name,
     {
       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
 	/* We could find no value for a strong reference.  */
+	/* XXX We cannot translate the message.  */
 	_dl_signal_cerror (0, (reference_name && reference_name[0]
 			       ? reference_name
 			       : (_dl_argv[0] ?: "<main program>")),
@@ -594,6 +597,7 @@ _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);
+	  /* XXX We cannot translate the messages.  */
 	  _dl_signal_cerror (0, (reference_name && reference_name[0]
 				 ? reference_name
 				 : (_dl_argv[0] ?: "<main program>")), buf);
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 76c36cffc8..17af8842d6 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -102,7 +102,7 @@ dl_open_worker (void *a)
       if (__libc_enable_secure)
 	/* This is an error.  */
 	_dl_signal_error (0, "dlopen",
-			  "DST not allowed in SUID/SGID programs");
+			  N_("DST not allowed in SUID/SGID programs"));
 
       /* We have to find out from which object the caller is calling.
 	 Find the highest-addressed object that ADDRESS is not below.  */
@@ -136,7 +136,7 @@ dl_open_worker (void *a)
       /* If the substitution failed don't try to load.  */
       if (*new_file == '\0')
 	_dl_signal_error (0, "dlopen",
-			  "empty dynamic string token substitution");
+			  N_("empty dynamic string token substitution"));
 
       /* Now we have a new file name.  */
       file = new_file;
@@ -237,7 +237,7 @@ dl_open_worker (void *a)
 	      _dl_global_scope_alloc = 0;
 	    nomem:
 	      _dl_signal_error (ENOMEM, new->l_libname->name,
-				"cannot extend global scope");
+				N_("cannot extend global scope"));
 	      return;
 	    }
 
@@ -290,12 +290,13 @@ internal_function
 _dl_open (const char *file, int mode, const void *caller)
 {
   struct dl_open_args args;
-  char *errstring;
+  const char *objname;
+  const char *errstring;
   int errcode;
 
   if ((mode & RTLD_BINDING_MASK) == 0)
     /* One of the flags must be set.  */
-    _dl_signal_error (EINVAL, file, _("invalid mode for dlopen()"));
+    _dl_signal_error (EINVAL, file, N_("invalid mode for dlopen()"));
 
   /* Make sure we are alone.  */
   __libc_lock_lock (_dl_load_lock);
@@ -304,7 +305,7 @@ _dl_open (const char *file, int mode, const void *caller)
   args.mode = mode;
   args.caller = caller;
   args.map = NULL;
-  errcode = _dl_catch_error (&errstring, dl_open_worker, &args);
+  errcode = _dl_catch_error (&objname, &errstring, dl_open_worker, &args);
 
 #ifndef MAP_COPY
   /* We must munmap() the cache file.  */
@@ -327,10 +328,10 @@ _dl_open (const char *file, int mode, const void *caller)
       /* Make a local copy of the error string so that we can release the
 	 memory allocated for it.  */
       local_errstring = strdupa (errstring);
-      free (errstring);
+      free ((char *) errstring);
 
       /* Reraise the error.  */
-      _dl_signal_error (errcode, NULL, local_errstring);
+      _dl_signal_error (errcode, objname, local_errstring);
     }
 
   return args.map;
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 50bc8e886f..280623153a 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -18,6 +18,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
+#include <libintl.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <ldsodefs.h>
@@ -58,8 +59,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 			       & ~(_dl_pagesize - 1)));
 	    if (__mprotect (mapstart, mapend - mapstart,
 			    PROT_READ|PROT_WRITE) < 0)
-	      _dl_signal_error (errno, l->l_name,
-				"cannot make segment writable for relocation");
+	      _dl_signal_error (errno, l->l_name, N_("\
+cannot make segment writable for relocation"));
 	  }
     }
 
@@ -138,7 +139,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 
 	    if (__mprotect (mapstart, mapend - mapstart, prot) < 0)
 	      _dl_signal_error (errno, l->l_name,
-				"can't restore segment prot after reloc");
+				N_("can't restore segment prot after reloc"));
 
 #ifdef CLEAR_CACHE
 	    CLEAR_CACHE (mapstart, mapend);
@@ -157,14 +158,16 @@ _dl_reloc_bad_type (struct link_map *map, uint_fast8_t type, int plt)
   extern const char _itoa_lower_digits[];
   if (plt)
     {
-      char msg[] = "unexpected PLT reloc type 0x??";
+      /* XXX We cannot translate the message.  */
+      static char msg[] = "unexpected PLT reloc type 0x??";
       msg[sizeof msg - 3] = DIGIT(type >> 4);
       msg[sizeof msg - 2] = DIGIT(type);
       _dl_signal_error (0, map->l_name, msg);
     }
   else
     {
-      char msg[] = "unexpected reloc type 0x??";
+      /* XXX We cannot translate the message.  */
+      static char msg[] = "unexpected reloc type 0x??";
       msg[sizeof msg - 3] = DIGIT(type >> 4);
       msg[sizeof msg - 2] = DIGIT(type);
       _dl_signal_error (0, map->l_name, msg);
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 4006d960dd..8b1103966a 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -21,6 +21,7 @@
    rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking.  */
 
 #include <errno.h>
+#include <libintl.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <ldsodefs.h>
@@ -130,7 +131,7 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
   /* XXX We don't try to find the capabilities in this case.  */
   result = (struct r_strlenpair *) malloc (sizeof (*result));
   if (result == NULL)
-    _dl_signal_error (ENOMEM, NULL, "cannot create capability list");
+    _dl_signal_error (ENOMEM, NULL, N_("cannot create capability list"));
 
   result[0].str = (char *) result;	/* Does not really matter.  */
   result[0].len = 0;
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index d2de7db464..e54ed808b2 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -63,7 +63,7 @@ _dl_sym (void *handle, const char *name, void *who)
       else
 	{
 	  if (! match)
-	    _dl_signal_error (0, NULL, _("\
+	    _dl_signal_error (0, NULL, N_("\
 RTLD_NEXT used in code not dynamically loaded"));
 
 	  l = match;
@@ -113,7 +113,7 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who)
 	  match = l;
 
       if (! match)
-	_dl_signal_error (0, NULL, _("\
+	_dl_signal_error (0, NULL, N_("\
 RTLD_NEXT used in code not dynamically loaded"));
 
       l = match;
diff --git a/elf/dl-version.c b/elf/dl-version.c
index 67104916d6..504287c209 100644
--- a/elf/dl-version.c
+++ b/elf/dl-version.c
@@ -20,6 +20,7 @@
 
 #include <elf.h>
 #include <errno.h>
+#include <libintl.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ldsodefs.h>
@@ -93,6 +94,7 @@ 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)
+	/* XXX We cannot translate the messages.  */
 	_dl_signal_cerror (0, map->l_name,
 			   make_string ("\
 no version information available (required by ",
@@ -112,6 +114,7 @@ no version information available (required by ",
 	{
 	  char buf[20];
 	  buf[sizeof (buf) - 1] = '\0';
+	  /* XXX We cannot translate the message.  */
 	  _dl_signal_error (0, map->l_name,
 			    make_string ("unsupported version ",
 					 _itoa_word (def->vd_version,
@@ -145,6 +148,7 @@ no version information available (required by ",
   if (__builtin_expect (weak, 1))
     {
       if (verbose)
+	/* XXX We cannot translate the message.  */
 	_dl_signal_cerror (0, map->l_name,
 			   make_string ("weak version `", string,
 					"' not found (required by ", name,
@@ -152,6 +156,7 @@ no version information available (required by ",
       return 0;
     }
 
+  /* XXX We cannot translate the message.  */
   _dl_signal_cerror (0, map->l_name,
 		     make_string ("version `", string,
 				  "' not found (required by ", name, ")"));
@@ -192,6 +197,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
 	{
 	  char buf[20];
 	  buf[sizeof (buf) - 1] = '\0';
+	  /* XXX We cannot translate the message.  */
 	  _dl_signal_error (0, (*map->l_name ? map->l_name : _dl_argv[0]),
 			    make_string ("unsupported version ",
 					 _itoa_word (ent->vn_version,
@@ -282,7 +288,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
       if (__builtin_expect (map->l_versions == NULL, 0))
 	{
 	  _dl_signal_error (ENOMEM, (*map->l_name ? map->l_name : _dl_argv[0]),
-			    "cannot allocate version reference table");
+			    N_("cannot allocate version reference table"));
 	  result = 1;
 	}
       else
diff --git a/elf/rtld.c b/elf/rtld.c
index b83eaa61b1..5dbab3a885 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -507,14 +507,15 @@ of this helper program; chances are you did not intend to run this program.\n\
 
       if (__builtin_expect (mode, normal) == verify)
 	{
-	  char *err_str = NULL;
+	  const char *objname;
+	  const char *err_str = NULL;
 	  struct map_args args;
 
 	  args.str = _dl_argv[0];
-	  (void) _dl_catch_error (&err_str, map_doit, &args);
-	  if (err_str != NULL)
+	  (void) _dl_catch_error (&objname, &err_str, map_doit, &args);
+	  if (__builtin_expect (err_str != NULL, 0))
 	    {
-	      free (err_str);
+	      free ((char *) err_str);
 	      _exit (EXIT_FAILURE);
 	    }
 	}
diff --git a/include/dlfcn.h b/include/dlfcn.h
index a2398c4c93..ad445aef28 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -36,14 +36,15 @@ extern void *_dl_sym (void *handle, const char *name, void *who)
 extern void *_dl_vsym (void *handle, const char *name, const char *version,
 		       void *who)
     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,
-   and the error code passed is the return value.  ERRSTRING if nonzero
+   and the error code passed is the return value and *OBJNAME is set to
+   the object name which experienced the problems.  ERRSTRING if nonzero
    points to a malloc'ed string which the caller has to free after use.
    ARGS is passed as argument to OPERATE.  */
-extern int _dl_catch_error (char **errstring,
+extern int _dl_catch_error (const char **objname, const char **errstring,
 			    void (*operate) (void *),
 			    void *args)
      internal_function;
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index e01aed12a3..bba91cacd0 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -240,8 +240,7 @@ extern int _dl_secure;
    zero; OBJECT is the name of the problematical shared object, or null if
    it is a general problem; ERRSTRING is a string describing the specific
    problem.  */
-extern void _dl_signal_error (int errcode,
-			      const char *object,
+extern void _dl_signal_error (int errcode, const char *object,
 			      const char *errstring)
      internal_function
      __attribute__ ((__noreturn__));