[BZ #516]
authorUlrich Drepper <drepper@redhat.com>
Mon, 26 Sep 2005 15:58:00 +0000 (15:58 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 26 Sep 2005 15:58:00 +0000 (15:58 +0000)
* elf/dl-load.c: Report failed loading due to ELF class mismatch
with better words.

ChangeLog
elf/dl-load.c

index 7c1cd57..58dfee8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2005-09-26  Ulrich Drepper  <drepper@redhat.com>
 
+       [BZ #516]
+       * elf/dl-load.c: Report failed loading due to ELF class mismatch
+       with better words.
+
        [BZ #162]
        * manual/llio.texi (Waiting for I/O): Correct description of read
        conditions reported by select.
index 9a780be..0ed670d 100644 (file)
@@ -1552,7 +1552,7 @@ print_search_path (struct r_search_path_elem **list,
    user might want to know about this.  */
 static int
 open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
-            int whatcode)
+            int whatcode, bool *found_other_class)
 {
   /* This is the expected ELF header.  */
 #define ELF32_CLASS ELFCLASS32
@@ -1656,10 +1656,13 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
              )
            errstring = N_("invalid ELF header");
          else if (ehdr->e_ident[EI_CLASS] != ELFW(CLASS))
-           /* This is not a fatal error.  On architectures where
-              32-bit and 64-bit binaries can be run this might
-              happen.  */
-           goto close_and_out;
+           {
+             /* This is not a fatal error.  On architectures where
+                32-bit and 64-bit binaries can be run this might
+                happen.  */
+             *found_other_class = true;
+             goto close_and_out;
+           }
          else if (ehdr->e_ident[EI_DATA] != byteorder)
            {
              if (BYTE_ORDER == BIG_ENDIAN)
@@ -1766,7 +1769,8 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
 static int
 open_path (const char *name, size_t namelen, int preloaded,
           struct r_search_path_struct *sps, char **realname,
-          struct filebuf *fbp, struct link_map *loader, int whatcode)
+          struct filebuf *fbp, struct link_map *loader, int whatcode,
+          bool *found_other_class)
 {
   struct r_search_path_elem **dirs = sps->dirs;
   char *buf;
@@ -1815,7 +1819,7 @@ open_path (const char *name, size_t namelen, int preloaded,
          if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
            _dl_debug_printf ("  trying file=%s\n", buf);
 
-         fd = open_verify (buf, fbp, loader, whatcode);
+         fd = open_verify (buf, fbp, loader, whatcode, found_other_class);
          if (this_dir->status[cnt] == unknown)
            {
              if (fd != -1)
@@ -1990,6 +1994,9 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
     }
 #endif
 
+  /* Will be true if we found a DSO which is of the other ELF class.  */
+  bool found_other_class = false;
+
   if (strchr (name, '/') == NULL)
     {
       /* Search for NAME in several places.  */
@@ -2010,7 +2017,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
          for (l = loader; fd == -1 && l; l = l->l_loader)
            if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
              fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
-                             &realname, &fb, loader, LA_SER_RUNPATH);
+                             &realname, &fb, loader, LA_SER_RUNPATH,
+                             &found_other_class);
 
          /* If dynamically linked, try the DT_RPATH of the executable
              itself.  NB: we do this for lookups in any namespace.  */
@@ -2020,7 +2028,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
              if (l && l->l_type != lt_loaded && l != loader
                  && cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
                fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
-                               &realname, &fb, loader ?: l, LA_SER_RUNPATH);
+                               &realname, &fb, loader ?: l, LA_SER_RUNPATH,
+                               &found_other_class);
            }
        }
 
@@ -2029,7 +2038,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
        fd = open_path (name, namelen, preloaded, &env_path_list,
                        &realname, &fb,
                        loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded,
-                       LA_SER_LIBPATH);
+                       LA_SER_LIBPATH, &found_other_class);
 
       /* Look at the RUNPATH information for this binary.  */
       if (fd == -1 && loader != NULL
@@ -2037,7 +2046,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
                          DT_RUNPATH, "RUNPATH"))
        fd = open_path (name, namelen, preloaded,
                        &loader->l_runpath_dirs, &realname, &fb, loader,
-                       LA_SER_RUNPATH);
+                       LA_SER_RUNPATH, &found_other_class);
 
       if (fd == -1
          && (__builtin_expect (! preloaded, 1)
@@ -2087,7 +2096,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
                {
                  fd = open_verify (cached,
                                    &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
-                                   LA_SER_CONFIG);
+                                   LA_SER_CONFIG, &found_other_class);
                  if (__builtin_expect (fd != -1, 1))
                    {
                      realname = local_strdup (cached);
@@ -2107,7 +2116,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
              || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))
          && rtld_search_dirs.dirs != (void *) -1)
        fd = open_path (name, namelen, preloaded, &rtld_search_dirs,
-                       &realname, &fb, l, LA_SER_DEFAULT);
+                       &realname, &fb, l, LA_SER_DEFAULT, &found_other_class);
 
       /* Add another newline when we are tracing the library loading.  */
       if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
@@ -2124,7 +2133,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
       else
        {
          fd = open_verify (realname, &fb,
-                           loader ?: GL(dl_ns)[nsid]._ns_loaded, 0);
+                           loader ?: GL(dl_ns)[nsid]._ns_loaded, 0,
+                           &found_other_class);
          if (__builtin_expect (fd, 0) == -1)
            free (realname);
        }
@@ -2167,6 +2177,11 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
 
          return l;
        }
+      else if (found_other_class)
+       _dl_signal_error (0, name, NULL,
+                         ELFW(CLASS) == ELFCLASS32
+                         ? N_("wrong ELF class: ELFCLASS64")
+                         : N_("wrong ELF class: ELFCLASS32"));
       else
        _dl_signal_error (errno, name, NULL,
                          N_("cannot open shared object file"));