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.
This commit is contained in:
Ulrich Drepper 2000-06-10 04:01:36 +00:00
parent f3863621f6
commit 8e17ea5817
15 changed files with 146 additions and 98 deletions

View File

@ -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> 2000-06-09 David Mosberger-Tang <davidm@hpl.hp.com>
* sysdeps/unix/sysv/linux/ia64/__longjmp.S: new file * sysdeps/unix/sysv/linux/ia64/__longjmp.S: new file

View File

@ -19,6 +19,7 @@
#include <assert.h> #include <assert.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <libintl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <bits/libc-lock.h> #include <bits/libc-lock.h>
@ -36,8 +37,6 @@ typedef void (*fini_t) (void);
protect `dlopen' and `dlclose' in dlclose.c. */ protect `dlopen' and `dlclose' in dlclose.c. */
__libc_lock_define (extern, _dl_load_lock) __libc_lock_define (extern, _dl_load_lock)
#define LOSE(s) _dl_signal_error (0, map->l_name, s)
void void
internal_function internal_function
_dl_close (void *_map) _dl_close (void *_map)
@ -50,7 +49,7 @@ _dl_close (void *_map)
unsigned int i; unsigned int i;
if (map->l_opencount == 0) 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. */ /* Acquire the lock. */
__libc_lock_lock (_dl_load_lock); __libc_lock_lock (_dl_load_lock);

View File

@ -20,6 +20,7 @@
#include <assert.h> #include <assert.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <errno.h> #include <errno.h>
#include <libintl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -102,7 +103,7 @@ struct list
/* DST must not appear in SUID/SGID programs. */ \ /* DST must not appear in SUID/SGID programs. */ \
if (__libc_enable_secure) \ if (__libc_enable_secure) \
_dl_signal_error (0, __str, \ _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), \ __newp = (char *) alloca (DL_DST_REQUIRED (l, __str, strlen (__str), \
__cnt)); \ __cnt)); \
@ -114,8 +115,8 @@ struct list
/* The replacement for the DST is not known. We can't \ /* The replacement for the DST is not known. We can't \
processed. */ \ processed. */ \
if (fatal) \ if (fatal) \
_dl_signal_error (0, __str, \ _dl_signal_error (0, __str, N_("\
"empty dynamics string token substitution"); \ empty dynamics string token substitution")); \
else \ else \
{ \ { \
/* This is for DT_AUXILIARY. */ \ /* 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) else if (d->d_tag == DT_AUXILIARY || d->d_tag == DT_FILTER)
{ {
char *errstring; const char *objname;
const char *errstring;
struct list *newp; struct list *newp;
/* Object name. */ /* Object name. */
const char *name; const char *name;
@ -289,11 +291,11 @@ _dl_map_object_deps (struct link_map *map,
/* We must be prepared that the addressed shared /* We must be prepared that the addressed shared
object is not available. */ 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. */ /* We are not interested in the error message. */
assert (errstring != NULL); assert (errstring != NULL);
free (errstring); free ((char *) errstring);
/* Simply ignore this error and continue the work. */ /* Simply ignore this error and continue the work. */
continue; continue;
@ -452,7 +454,7 @@ _dl_map_object_deps (struct link_map *map,
l->l_initfini = malloc (nneeded * sizeof needed[0]); l->l_initfini = malloc (nneeded * sizeof needed[0]);
if (l->l_initfini == NULL) if (l->l_initfini == NULL)
_dl_signal_error (ENOMEM, map->l_name, _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]); 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 *)); * sizeof (struct link_map *));
if (map->l_searchlist.r_list == NULL) if (map->l_searchlist.r_list == NULL)
_dl_signal_error (ENOMEM, map->l_name, _dl_signal_error (ENOMEM, map->l_name,
"cannot allocate symbol search list"); N_("cannot allocate symbol search list"));
map->l_searchlist.r_nlist = nlist; map->l_searchlist.r_nlist = nlist;
for (nlist = 0, runp = known; runp; runp = runp->unique) for (nlist = 0, runp = known; runp; runp = runp->unique)

View File

@ -17,6 +17,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
#include <libintl.h>
#include <setjmp.h> #include <setjmp.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -28,7 +29,8 @@
_dl_signal_error. */ _dl_signal_error. */
struct catch 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. */ jmp_buf env; /* longjmp here on error. */
}; };
@ -55,34 +57,21 @@ static receiver_fct receiver;
void void
internal_function internal_function
_dl_signal_error (int errcode, _dl_signal_error (int errcode, const char *objname, const char *errstring)
const char *objname,
const char *errstring)
{ {
struct catch *lcatch; struct catch *lcatch;
if (! errstring) if (! errstring)
errstring = "DYNAMIC LINKER BUG!!!"; errstring = N_("DYNAMIC LINKER BUG!!!");
lcatch = tsd_getspecific (); lcatch = tsd_getspecific ();
if (lcatch != NULL) if (lcatch != NULL)
{ {
/* We are inside _dl_catch_error. Return to it. We have to /* We are inside _dl_catch_error. Return to it. We have to
duplicate the error string since it might be allocated on the duplicate the error string since it might be allocated on the
stack. */ stack. The object name is always a string constant. */
size_t objname_len = objname ? strlen (objname) + 2 : 0; lcatch->objname = objname;
size_t errstring_len = strlen (errstring) + 1; lcatch->errstring = strdup (errstring);
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);
}
longjmp (lcatch->env, errcode ?: -1); longjmp (lcatch->env, errcode ?: -1);
} }
else else
@ -120,9 +109,8 @@ _dl_signal_cerror (int errcode,
int int
internal_function internal_function
_dl_catch_error (char **errstring, _dl_catch_error (const char **objname, const char **errstring,
void (*operate) (void *), void (*operate) (void *), void *args)
void *args)
{ {
int errcode; int errcode;
struct catch *volatile old; struct catch *volatile old;
@ -141,12 +129,14 @@ _dl_catch_error (char **errstring,
tsd_setspecific (&c); tsd_setspecific (&c);
(*operate) (args); (*operate) (args);
tsd_setspecific (old); tsd_setspecific (old);
*objname = NULL;
*errstring = NULL; *errstring = NULL;
return 0; return 0;
} }
/* We get here only if we longjmp'd out of OPERATE. */ /* We get here only if we longjmp'd out of OPERATE. */
tsd_setspecific (old); tsd_setspecific (old);
*objname = c.objname;
*errstring = c.errstring; *errstring = c.errstring;
return errcode == -1 ? 0 : errcode; return errcode == -1 ? 0 : errcode;
} }

View File

@ -1,5 +1,5 @@
/* Handle loading and unloading shared objects for internal libc purposes. /* 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. This file is part of the GNU C Library.
Contributed by Zack Weinberg <zack@rabi.columbia.edu>, 1999. Contributed by Zack Weinberg <zack@rabi.columbia.edu>, 1999.
@ -35,14 +35,15 @@ static int
internal_function internal_function
dlerror_run (void (*operate) (void *), void *args) dlerror_run (void (*operate) (void *), void *args)
{ {
char *last_errstring = NULL; const char *objname;
const char *last_errstring = NULL;
int result; int result;
(void) _dl_catch_error (&last_errstring, operate, args); (void) _dl_catch_error (&objname, &last_errstring, operate, args);
result = last_errstring != NULL; result = last_errstring != NULL;
if (result) if (result)
free (last_errstring); free ((char *) last_errstring);
return result; return result;
} }

View File

@ -20,6 +20,7 @@
#include <elf.h> #include <elf.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <libintl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -62,10 +63,8 @@
#include <endian.h> #include <endian.h>
#if BYTE_ORDER == BIG_ENDIAN #if BYTE_ORDER == BIG_ENDIAN
# define byteorder ELFDATA2MSB # define byteorder ELFDATA2MSB
# define byteorder_name "big-endian"
#elif BYTE_ORDER == LITTLE_ENDIAN #elif BYTE_ORDER == LITTLE_ENDIAN
# define byteorder ELFDATA2LSB # define byteorder ELFDATA2LSB
# define byteorder_name "little-endian"
#else #else
# error "Unknown BYTE_ORDER " BYTE_ORDER # error "Unknown BYTE_ORDER " BYTE_ORDER
# define byteorder ELFDATANONE # define byteorder ELFDATANONE
@ -315,7 +314,7 @@ add_name_to_object (struct link_map *l, const char *name)
if (newname == NULL) if (newname == NULL)
{ {
/* No more memory. */ /* No more memory. */
_dl_signal_error (ENOMEM, name, "cannot allocate name record"); _dl_signal_error (ENOMEM, name, N_("cannot allocate name record"));
return; return;
} }
/* The object should have a libname set from _dl_new_object. */ /* 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)); malloc (sizeof (*dirp) + ncapstr * sizeof (enum r_dir_status));
if (dirp == NULL) if (dirp == NULL)
_dl_signal_error (ENOMEM, NULL, _dl_signal_error (ENOMEM, NULL,
"cannot create cache for search path"); N_("cannot create cache for search path"));
dirp->dirname = cp; dirp->dirname = cp;
dirp->dirnamelen = len; dirp->dirnamelen = len;
@ -475,7 +474,7 @@ decompose_rpath (const char *rpath, struct link_map *l, const char *what)
malloc (sizeof (*result)); malloc (sizeof (*result));
if (result == NULL) if (result == NULL)
_dl_signal_error (ENOMEM, NULL, _dl_signal_error (ENOMEM, NULL,
"cannot create cache for search path"); N_("cannot create cache for search path"));
result[0] = NULL; result[0] = NULL;
return result; return result;
@ -487,7 +486,7 @@ decompose_rpath (const char *rpath, struct link_map *l, const char *what)
string tokens. */ string tokens. */
copy = expand_dynamic_string_token (l, rpath); copy = expand_dynamic_string_token (l, rpath);
if (copy == NULL) 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. */ /* Count the number of necessary elements in the result array. */
nelems = 0; 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) result = (struct r_search_path_elem **) malloc ((nelems + 1 + 1)
* sizeof (*result)); * sizeof (*result));
if (result == NULL) 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); 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) malloc ((sizeof (system_dirs_len) / sizeof (system_dirs_len[0]) + 1)
* sizeof (struct r_search_path_elem *)); * sizeof (struct r_search_path_elem *));
if (rtld_search_dirs == NULL) 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 round_size = ((2 * sizeof (struct r_search_path_elem) - 1
+ ncapstr * sizeof (enum r_dir_status)) + ncapstr * sizeof (enum r_dir_status))
@ -540,7 +539,7 @@ _dl_init_paths (const char *llp)
malloc ((sizeof (system_dirs) / sizeof (system_dirs[0])) malloc ((sizeof (system_dirs) / sizeof (system_dirs[0]))
* round_size * sizeof (struct r_search_path_elem)); * round_size * sizeof (struct r_search_path_elem));
if (rtld_search_dirs[0] == NULL) 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]; pelem = all_dirs = rtld_search_dirs[0];
strp = system_dirs; strp = system_dirs;
@ -632,7 +631,7 @@ _dl_init_paths (const char *llp)
malloc ((nllp + 1) * sizeof (struct r_search_path_elem *)); malloc ((nllp + 1) * sizeof (struct r_search_path_elem *));
if (env_path_list == NULL) if (env_path_list == NULL)
_dl_signal_error (ENOMEM, 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, ":;", (void) fillin_rpath (local_strdup (llp), env_path_list, ":;",
__libc_enable_secure, "LD_LIBRARY_PATH", NULL); __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, fixed|MAP_COPY|MAP_FILE,
fd, offset); fd, offset);
if (mapat == MAP_FAILED) 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; return mapat;
} }
@ -735,7 +734,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
/* Get file information. */ /* Get file information. */
if (__fxstat (_STAT_VER, fd, &st) < 0) 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. */ /* Look again to see if the real name matched another already loaded. */
for (l = _dl_loaded; l; l = l->l_next) 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); readbuf = alloca (_dl_pagesize);
readlength = __libc_read (fd, readbuf, _dl_pagesize); readlength = __libc_read (fd, readbuf, _dl_pagesize);
if (readlength < (ssize_t) sizeof (*header)) if (readlength < (ssize_t) sizeof (*header))
LOSE (errno, "cannot read file data"); LOSE (errno, N_("cannot read file data"));
header = (void *) readbuf; header = (void *) readbuf;
/* Check the header for basic validity. */ /* 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))) (ELFMAG3 << (EI_MAG0 * 8)))
#endif #endif
) )
LOSE (0, "invalid ELF header"); LOSE (0, N_("invalid ELF header"));
if (header->e_ident[EI_CLASS] != ELFW(CLASS)) 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) 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) 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 /* XXX We should be able so set system specific versions which are
allowed here. */ allowed here. */
if (!VALID_ELF_OSABI (header->e_ident[EI_OSABI])) 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])) if (!VALID_ELF_ABIVERSION (header->e_ident[EI_ABIVERSION]))
LOSE (0, "ELF file ABI version invalid."); LOSE (0, N_("ELF file ABI version invalid."));
LOSE (0, "internal error"); LOSE (0, N_("internal error"));
} }
if (__builtin_expect (header->e_version, EV_CURRENT) != EV_CURRENT) 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)) 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))) if (__builtin_expect (header->e_phentsize, sizeof (ElfW(Phdr)))
!= 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 #ifndef MAP_ANON
# define MAP_ANON 0 # define MAP_ANON 0
@ -814,7 +823,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname,
if (_dl_zerofd == -1) if (_dl_zerofd == -1)
{ {
__close (fd); __close (fd);
_dl_signal_error (errno, NULL, "cannot open zero fill device"); _dl_signal_error (errno, NULL, N_("cannot open zero fill device"));
} }
} }
#endif #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. */ /* Enter the new object in the list of loaded objects. */
l = _dl_new_object (realname, name, l_type, loader); l = _dl_new_object (realname, name, l_type, loader);
if (__builtin_expect (! l, 0)) if (__builtin_expect (! l, 0))
LOSE (ENOMEM, "cannot create shared object descriptor"); LOSE (ENOMEM, N_("cannot create shared object descriptor"));
l->l_opencount = 1; l->l_opencount = 1;
/* Extract the remaining details we need from the ELF header /* 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); phdr = alloca (maplength);
__lseek (fd, SEEK_SET, header->e_phoff); __lseek (fd, SEEK_SET, header->e_phoff);
if (__libc_read (fd, (void *) phdr, maplength) != maplength) 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. /* A load command tells us to map in part of the file.
We record the load commands and process them all later. */ We record the load commands and process them all later. */
if (ph->p_align % _dl_pagesize != 0) 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) 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++]; struct loadcmd *c = &loadcmds[nloadcmds++];
c->mapstart = ph->p_vaddr & ~(ph->p_align - 1); 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. */ /* Dag nab it. */
if (__mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)), if (__mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)),
_dl_pagesize, c->prot|PROT_WRITE) < 0) _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); memset ((void *) zero, 0, zeropage - zero);
if ((c->prot & PROT_WRITE) == 0) 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, c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED,
ANONFD, 0); ANONFD, 0);
if (mapat == MAP_FAILED) 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 ElfW(Phdr) *newp = (ElfW(Phdr) *) malloc (header->e_phnum
* sizeof (ElfW(Phdr))); * sizeof (ElfW(Phdr)));
if (newp == NULL) 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, l->l_phdr = memcpy (newp, phdr,
(header->e_phnum * sizeof (ElfW(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 (l->l_ld == 0)
{ {
if (type == ET_DYN) if (type == ET_DYN)
LOSE (0, "object file has no dynamic section"); LOSE (0, N_("object file has no dynamic section"));
} }
else else
(ElfW(Addr)) l->l_ld += l->l_addr; (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 *)); (struct link_map **) malloc (sizeof (struct link_map *));
if (l->l_symbolic_searchlist.r_list == NULL) 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_list[0] = l;
l->l_symbolic_searchlist.r_nlist = 1; 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 if ((name_copy = local_strdup (name)) == NULL
|| (l = _dl_new_object (name_copy, name, type, loader)) == NULL) || (l = _dl_new_object (name_copy, name, type, loader)) == NULL)
_dl_signal_error (ENOMEM, name, _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. /* We use an opencount of 0 as a sign for the faked entry.
Since the descriptor is initialized with zero we do not Since the descriptor is initialized with zero we do not
have do this here. have do this here.
@ -1488,7 +1498,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
return l; return l;
} }
else 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); return _dl_map_object_from_fd (name, fd, realname, loader, type);

View File

@ -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) if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
/* We could find no value for a strong reference. */ /* We could find no value for a strong reference. */
/* XXX We cannot translate the messages. */
_dl_signal_cerror (0, (reference_name && reference_name[0] _dl_signal_cerror (0, (reference_name && reference_name[0]
? reference_name ? reference_name
: (_dl_argv[0] ?: "<main program>")), : (_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 /* Oh, oh. The file named in the relocation entry does not
contain the needed symbol. */ contain the needed symbol. */
/* XXX We cannot translate the message. */
_dl_signal_cerror (0, (reference_name && reference_name[0] _dl_signal_cerror (0, (reference_name && reference_name[0]
? reference_name ? reference_name
: (_dl_argv[0] ?: "<main program>")), : (_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) if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
/* We could find no value for a strong reference. */ /* We could find no value for a strong reference. */
/* XXX We cannot translate the message. */
_dl_signal_cerror (0, (reference_name && reference_name[0] _dl_signal_cerror (0, (reference_name && reference_name[0]
? reference_name ? reference_name
: (_dl_argv[0] ?: "<main program>")), : (_dl_argv[0] ?: "<main program>")),
@ -594,6 +597,7 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name,
char buf[sizeof undefined_msg + len]; char buf[sizeof undefined_msg + len];
__mempcpy (__mempcpy (buf, undefined_msg, sizeof undefined_msg - 1), __mempcpy (__mempcpy (buf, undefined_msg, sizeof undefined_msg - 1),
undef_name, len + 1); undef_name, len + 1);
/* XXX We cannot translate the messages. */
_dl_signal_cerror (0, (reference_name && reference_name[0] _dl_signal_cerror (0, (reference_name && reference_name[0]
? reference_name ? reference_name
: (_dl_argv[0] ?: "<main program>")), buf); : (_dl_argv[0] ?: "<main program>")), buf);

View File

@ -102,7 +102,7 @@ dl_open_worker (void *a)
if (__libc_enable_secure) if (__libc_enable_secure)
/* This is an error. */ /* This is an error. */
_dl_signal_error (0, "dlopen", _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. /* We have to find out from which object the caller is calling.
Find the highest-addressed object that ADDRESS is not below. */ 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 the substitution failed don't try to load. */
if (*new_file == '\0') if (*new_file == '\0')
_dl_signal_error (0, "dlopen", _dl_signal_error (0, "dlopen",
"empty dynamic string token substitution"); N_("empty dynamic string token substitution"));
/* Now we have a new file name. */ /* Now we have a new file name. */
file = new_file; file = new_file;
@ -237,7 +237,7 @@ dl_open_worker (void *a)
_dl_global_scope_alloc = 0; _dl_global_scope_alloc = 0;
nomem: nomem:
_dl_signal_error (ENOMEM, new->l_libname->name, _dl_signal_error (ENOMEM, new->l_libname->name,
"cannot extend global scope"); N_("cannot extend global scope"));
return; return;
} }
@ -290,12 +290,13 @@ internal_function
_dl_open (const char *file, int mode, const void *caller) _dl_open (const char *file, int mode, const void *caller)
{ {
struct dl_open_args args; struct dl_open_args args;
char *errstring; const char *objname;
const char *errstring;
int errcode; int errcode;
if ((mode & RTLD_BINDING_MASK) == 0) if ((mode & RTLD_BINDING_MASK) == 0)
/* One of the flags must be set. */ /* 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. */ /* Make sure we are alone. */
__libc_lock_lock (_dl_load_lock); __libc_lock_lock (_dl_load_lock);
@ -304,7 +305,7 @@ _dl_open (const char *file, int mode, const void *caller)
args.mode = mode; args.mode = mode;
args.caller = caller; args.caller = caller;
args.map = NULL; 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 #ifndef MAP_COPY
/* We must munmap() the cache file. */ /* 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 /* Make a local copy of the error string so that we can release the
memory allocated for it. */ memory allocated for it. */
local_errstring = strdupa (errstring); local_errstring = strdupa (errstring);
free (errstring); free ((char *) errstring);
/* Reraise the error. */ /* Reraise the error. */
_dl_signal_error (errcode, NULL, local_errstring); _dl_signal_error (errcode, objname, local_errstring);
} }
return args.map; return args.map;

View File

@ -18,6 +18,7 @@
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
#include <errno.h> #include <errno.h>
#include <libintl.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <ldsodefs.h> #include <ldsodefs.h>
@ -58,8 +59,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
& ~(_dl_pagesize - 1))); & ~(_dl_pagesize - 1)));
if (__mprotect (mapstart, mapend - mapstart, if (__mprotect (mapstart, mapend - mapstart,
PROT_READ|PROT_WRITE) < 0) PROT_READ|PROT_WRITE) < 0)
_dl_signal_error (errno, l->l_name, _dl_signal_error (errno, l->l_name, N_("\
"cannot make segment writable for relocation"); 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) if (__mprotect (mapstart, mapend - mapstart, prot) < 0)
_dl_signal_error (errno, l->l_name, _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 #ifdef CLEAR_CACHE
CLEAR_CACHE (mapstart, mapend); 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[]; extern const char _itoa_lower_digits[];
if (plt) 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 - 3] = DIGIT(type >> 4);
msg[sizeof msg - 2] = DIGIT(type); msg[sizeof msg - 2] = DIGIT(type);
_dl_signal_error (0, map->l_name, msg); _dl_signal_error (0, map->l_name, msg);
} }
else 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 - 3] = DIGIT(type >> 4);
msg[sizeof msg - 2] = DIGIT(type); msg[sizeof msg - 2] = DIGIT(type);
_dl_signal_error (0, map->l_name, msg); _dl_signal_error (0, map->l_name, msg);

View File

@ -21,6 +21,7 @@
rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */ rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */
#include <errno.h> #include <errno.h>
#include <libintl.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <ldsodefs.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. */ /* XXX We don't try to find the capabilities in this case. */
result = (struct r_strlenpair *) malloc (sizeof (*result)); result = (struct r_strlenpair *) malloc (sizeof (*result));
if (result == NULL) 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].str = (char *) result; /* Does not really matter. */
result[0].len = 0; result[0].len = 0;

View File

@ -63,7 +63,7 @@ _dl_sym (void *handle, const char *name, void *who)
else else
{ {
if (! match) if (! match)
_dl_signal_error (0, NULL, _("\ _dl_signal_error (0, NULL, N_("\
RTLD_NEXT used in code not dynamically loaded")); RTLD_NEXT used in code not dynamically loaded"));
l = match; l = match;
@ -113,7 +113,7 @@ _dl_vsym (void *handle, const char *name, const char *version, void *who)
match = l; match = l;
if (! match) if (! match)
_dl_signal_error (0, NULL, _("\ _dl_signal_error (0, NULL, N_("\
RTLD_NEXT used in code not dynamically loaded")); RTLD_NEXT used in code not dynamically loaded"));
l = match; l = match;

View File

@ -20,6 +20,7 @@
#include <elf.h> #include <elf.h>
#include <errno.h> #include <errno.h>
#include <libintl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ldsodefs.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 object was linked against another version of this file. We
only print a message if verbose output is requested. */ only print a message if verbose output is requested. */
if (verbose) if (verbose)
/* XXX We cannot translate the messages. */
_dl_signal_cerror (0, map->l_name, _dl_signal_cerror (0, map->l_name,
make_string ("\ make_string ("\
no version information available (required by ", no version information available (required by ",
@ -112,6 +114,7 @@ no version information available (required by ",
{ {
char buf[20]; char buf[20];
buf[sizeof (buf) - 1] = '\0'; buf[sizeof (buf) - 1] = '\0';
/* XXX We cannot translate the message. */
_dl_signal_error (0, map->l_name, _dl_signal_error (0, map->l_name,
make_string ("unsupported version ", make_string ("unsupported version ",
_itoa_word (def->vd_version, _itoa_word (def->vd_version,
@ -145,6 +148,7 @@ no version information available (required by ",
if (__builtin_expect (weak, 1)) if (__builtin_expect (weak, 1))
{ {
if (verbose) if (verbose)
/* XXX We cannot translate the message. */
_dl_signal_cerror (0, map->l_name, _dl_signal_cerror (0, map->l_name,
make_string ("weak version `", string, make_string ("weak version `", string,
"' not found (required by ", name, "' not found (required by ", name,
@ -152,6 +156,7 @@ no version information available (required by ",
return 0; return 0;
} }
/* XXX We cannot translate the message. */
_dl_signal_cerror (0, map->l_name, _dl_signal_cerror (0, map->l_name,
make_string ("version `", string, make_string ("version `", string,
"' not found (required by ", name, ")")); "' 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]; char buf[20];
buf[sizeof (buf) - 1] = '\0'; buf[sizeof (buf) - 1] = '\0';
/* XXX We cannot translate the message. */
_dl_signal_error (0, (*map->l_name ? map->l_name : _dl_argv[0]), _dl_signal_error (0, (*map->l_name ? map->l_name : _dl_argv[0]),
make_string ("unsupported version ", make_string ("unsupported version ",
_itoa_word (ent->vn_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)) if (__builtin_expect (map->l_versions == NULL, 0))
{ {
_dl_signal_error (ENOMEM, (*map->l_name ? map->l_name : _dl_argv[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; result = 1;
} }
else else

View File

@ -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) if (__builtin_expect (mode, normal) == verify)
{ {
char *err_str = NULL; const char *objname;
const char *err_str = NULL;
struct map_args args; struct map_args args;
args.str = _dl_argv[0]; args.str = _dl_argv[0];
(void) _dl_catch_error (&err_str, map_doit, &args); (void) _dl_catch_error (&objname, &err_str, map_doit, &args);
if (err_str != NULL) if (__builtin_expect (err_str != NULL, 0))
{ {
free (err_str); free ((char *) err_str);
_exit (EXIT_FAILURE); _exit (EXIT_FAILURE);
} }
} }

View File

@ -40,10 +40,11 @@ extern void *_dl_vsym (void *handle, const char *name, const char *version,
/* Call OPERATE, catching errors from `dl_signal_error'. If there is no /* 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 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, 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. points to a malloc'ed string which the caller has to free after use.
ARGS is passed as argument to OPERATE. */ 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 (*operate) (void *),
void *args) void *args)
internal_function; internal_function;

View File

@ -240,8 +240,7 @@ extern int _dl_secure;
zero; OBJECT is the name of the problematical shared object, or null if 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 it is a general problem; ERRSTRING is a string describing the specific
problem. */ problem. */
extern void _dl_signal_error (int errcode, extern void _dl_signal_error (int errcode, const char *object,
const char *object,
const char *errstring) const char *errstring)
internal_function internal_function
__attribute__ ((__noreturn__)); __attribute__ ((__noreturn__));