Update.
authorUlrich Drepper <drepper@redhat.com>
Sun, 29 Mar 1998 21:14:40 +0000 (21:14 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 29 Mar 1998 21:14:40 +0000 (21:14 +0000)
1998-03-29 20:59  Ulrich Drepper  <drepper@cygnus.com>

* elf/Makefile: Fix typo.
* elf/ldd.bash.in: Collect output of ldd --verify in verify_out.
* elf/ldd.sh.in: Likewise.
* elf/ldsodefs.h: Declare _dl_correct_cache_id.
* elf/rtld.c (dl_main): In --verify mode allow platform specifc action.
Use strsep correctly.
(process_envvars): Allow platform specific variables.
* sysdeps/generic/dl-cache.c (_dl_correct_cache_id): New variable.
(_dl_load_cache_lookup): Test cache IDs found against
_dl_correct_cache_id.
* sysdeps/generic/dl-librecon.h: New file.
* sysdeps/unix/sysv/linux/dl-librecon.h: New file.

* sysdeps/unix/sysv/linux/lddlibc4.c: Include error.h.

* sysdeps/unix/sysv/linux/ldd-rewrite.sed: New file.

ChangeLog
elf/Makefile
elf/ldd.bash.in
elf/ldd.sh.in
elf/ldsodefs.h
elf/rtld.c
sysdeps/generic/dl-cache.c
sysdeps/generic/dl-librecon.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/i386/dl-librecon.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/ldd-rewrite.sed [new file with mode: 0644]
sysdeps/unix/sysv/linux/lddlibc4.c

index 830612b..1d837f5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+1998-03-29 20:59  Ulrich Drepper  <drepper@cygnus.com>
+
+       * elf/Makefile: Fix typo.
+       * elf/ldd.bash.in: Collect output of ldd --verify in verify_out.
+       * elf/ldd.sh.in: Likewise.
+       * elf/ldsodefs.h: Declare _dl_correct_cache_id.
+       * elf/rtld.c (dl_main): In --verify mode allow platform specifc action.
+       Use strsep correctly.
+       (process_envvars): Allow platform specific variables.
+       * sysdeps/generic/dl-cache.c (_dl_correct_cache_id): New variable.
+       (_dl_load_cache_lookup): Test cache IDs found against
+       _dl_correct_cache_id.
+       * sysdeps/generic/dl-librecon.h: New file.
+       * sysdeps/unix/sysv/linux/dl-librecon.h: New file.
+
+       * sysdeps/unix/sysv/linux/lddlibc4.c: Include error.h.
+
 1998-03-29 16:50  Ulrich Drepper  <drepper@cygnus.com>
 
        * config.make.in (ldd-rewrite-script): New variable.
@@ -9,6 +26,7 @@
        * sysdeps/unix/sysv/linux/configure.in: Define ldd_rewrite_script to
        point to sed script for libc4 handling insertion for ix86, m68, SPARC.
        * sysdeps/unix/sysv/linux/i386/Makefile: Add rule to install lddlibc4.
+       * sysdeps/unix/sysv/linux/ldd-rewrite.sed: New file.
 
 1998-03-26 15:20  Zack Weinberg  <zack@rabi.phys.columbia.edu>
 
index 33f60c5..4e5de91 100644 (file)
@@ -171,9 +171,9 @@ bash-ldd-rewrite = $(sh-ldd-rewrite) -e 's%@BASH@%$(BASH)%g' \
                   -e 's%@TEXTDOMAINDIR@%$(localedir)%g'
 
 ifneq ($(have-bash2),yes)
-ldd-shell = bash
-else
 ldd-shell = sh
+else
+ldd-shell = bash
 endif
 
 ifeq ($(ldd-rewrite-script),no)
index 5d4bb3c..9bf88d1 100644 (file)
@@ -115,7 +115,7 @@ case $# in
   elif test -r "$file"; then
     test -x "$file" ||
     echo 'ldd:' $"warning: you do not have execution permission for" "\`$file'"
-    ${RTLD} --verify "$file"
+    verify_out=`${RTLD} --verify "$file"`
     case $? in
     0)
       eval $add_env exec '"$file"' || exit 1
@@ -156,7 +156,7 @@ case $# in
     elif test -r "$file"; then
       test -x "$file" || echo 'ldd:' $"\
 warning: you do not have execution permission for" "\`$file'"
-      ${RTLD} --verify "$file"
+      verify_out=`${RTLD} --verify "$file"`
       case $? in
       0)
        eval $add_env '"$file"' || result=1
index a82deb5..2447a90 100644 (file)
@@ -113,7 +113,7 @@ Try \`ldd --help' for more information."
     if test -r "$file"; then
       test -x "$file" ||
        echo "ldd: warning: you do not have execution permission for \`$file'"
-      ${RTLD} --verify "$file"
+      verify_out=`${RTLD} --verify "$file"`
       case $? in
       0)
        eval $add_env exec '"$file"' || exit 1
@@ -156,7 +156,7 @@ Try \`ldd --help' for more information."
       if test -r "$file"; then
        test -x "$file" || echo "\
 ldd: warning: you do not have execution permission for \`$file'"
-       ${RTLD} --verify "$file"
+       verify_out=`${RTLD} --verify "$file"`
        case $? in
        0)
          eval $add_env '"$file"' || result=1
index f6202ba..3154bf2 100644 (file)
@@ -132,6 +132,9 @@ extern int _dl_debug_versions;
 extern int _dl_debug_reloc;
 extern int _dl_debug_files;
 
+/* Expect cache ID.  */
+extern int _dl_correct_cache_id;
+
 /* File deccriptor to write debug messages to.  */
 extern int _dl_debug_fd;
 
index 13643d1..dae396a 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdio-common/_itoa.h>
 #include <entry.h>
 #include "dynamic-link.h"
+#include "dl-librecon.h"
 
 #include <assert.h>
 
@@ -468,17 +469,30 @@ of this helper program; chances are you did not intend to run this program.\n\
   else
     assert (_dl_rtld_map.l_libname); /* How else did we get here?  */
 
-  if (mode == verify)
-    /* We were called just to verify that this is a dynamic executable
-       using us as the program interpreter.  */
-    _exit (main_map->l_ld == NULL ? 1 : has_interp ? 0 : 2);
-
   /* Extract the contents of the dynamic section for easy access.  */
   elf_get_dynamic_info (main_map->l_ld, main_map->l_info);
   if (main_map->l_info[DT_HASH])
     /* Set up our cache of pointers into the hash table.  */
     _dl_setup_hash (main_map);
 
+  if (mode == verify)
+    {
+      /* We were called just to verify that this is a dynamic
+        executable using us as the program interpreter.  Exit with an
+        error if we were not able to load the binary or no interpreter
+        is specified (i.e., this is no dynamically linked binary.  */
+      if (main_map->l_ld == NULL)
+       _exit (1);
+      if (!has_interp)
+       _exit (2);
+
+      /* We allow here some platform specific code.  */
+#ifdef DISTINGUISH_LIB_VERSIONS
+      DISTINGUISH_LIB_VERSIONS;
+#endif
+      _exit (0);
+    }
+
   if (*user_entry != (ElfW(Addr)) &ENTRY_POINT)
     /* Initialize the data structures for the search paths for shared
        objects.  */
@@ -511,7 +525,8 @@ of this helper program; chances are you did not intend to run this program.\n\
       char *list = strdupa (preloadlist);
       char *p;
       while ((p = strsep (&list, " :")) != NULL)
-       if (! __libc_enable_secure || strchr (p, '/') == NULL)
+       if (p[0] != '\0'
+           && (! __libc_enable_secure || strchr (p, '/') == NULL))
          {
            struct link_map *new_map = _dl_map_object (main_map, p, 1,
                                                       lt_library, 0);
@@ -571,18 +586,16 @@ of this helper program; chances are you did not intend to run this program.\n\
       if (file != problem)
        {
          char *p;
-         runp = file + strspn (file, ": \t\n");
+         runp = file;
          while ((p = strsep (&runp, ": \t\n")) != NULL)
-           {
-             struct link_map *new_map = _dl_map_object (main_map, p, 1,
-                                                        lt_library, 0);
-             if (new_map->l_opencount == 1)
-               /* It is no duplicate.  */
-               ++npreloads;
-
-             if (runp != NULL)
-               runp += strspn (runp, ": \t\n");
-           }
+           if (p[0] != '\0')
+             {
+               struct link_map *new_map = _dl_map_object (main_map, p, 1,
+                                                          lt_library, 0);
+               if (new_map->l_opencount == 1)
+                 /* It is no duplicate.  */
+                 ++npreloads;
+             }
        }
 
       if (problem != NULL)
@@ -1127,6 +1140,14 @@ process_envvars (enum mode *modep, int *lazyp)
          if (memcmp (&envline[3], "TRACE_LOADED_OBJECTS", 20) == 0)
            mode = trace;
          break;
+
+         /* We might have some extra environment variable to handle.  This
+            is tricky due to the pre-processing of the length of the name
+            in the switch statement here.  The code here assumes that added
+            environment variables have a different length.  */
+#ifdef EXTRA_LD_ENVVARS
+         EXTRA_LD_ENVVARS
+#endif
        }
     }
 
index 5aa1ea2..da7d2e4 100644 (file)
@@ -44,6 +44,10 @@ struct cache_file
       } libs[0];
   };
 
+/* This is the cache ID we expect.  Normally it is 3 for glibc linked
+   binaries.  */
+int _dl_correct_cache_id = 3;
+
 /* Look up NAME in ld.so.cache and return the file name stored there,
    or null if none is found.  */
 
@@ -92,12 +96,12 @@ _dl_load_cache_lookup (const char *name)
        ! strcmp (name, ((const char *) &cache->libs[cache->nlibs] +
                         cache->libs[i].key)))
       {
-       if ((best == NULL) || (cache->libs[i].flags == 3))
+       if ((best == NULL) || (cache->libs[i].flags == _dl_correct_cache_id))
          {
            best = ((const char *) &cache->libs[cache->nlibs]
                    + cache->libs[i].value);
 
-           if (cache->libs[i].flags == 3)
+           if (cache->libs[i].flags == _dl_correct_cache_id)
              /* We've found an exact match for the shared object and no
                 general `ELF' release.  Stop searching.  */
              break;
diff --git a/sysdeps/generic/dl-librecon.h b/sysdeps/generic/dl-librecon.h
new file mode 100644 (file)
index 0000000..82bf713
--- /dev/null
@@ -0,0 +1,26 @@
+/* Optional code to distinguish library flavours.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _DL_LIBRECON_H
+#define _DL_LIBRECON_H 1
+
+/* In the general case we don't do anything.  */
+
+#endif /* dl-librecon.h */
diff --git a/sysdeps/unix/sysv/linux/i386/dl-librecon.h b/sysdeps/unix/sysv/linux/i386/dl-librecon.h
new file mode 100644 (file)
index 0000000..ef2c4bb
--- /dev/null
@@ -0,0 +1,57 @@
+/* Optional code to distinguish library flavours.
+   Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _DL_LIBRECON_H
+#define _DL_LIBRECON_H 1
+
+#define DISTINGUISH_LIB_VERSIONS \
+  do                                                                         \
+    {                                                                        \
+      /* We have to find out whether the binary is linked against            \
+        libc 5 or glibc.  We do this by looking at all the DT_NEEDED         \
+        entries.  If one is libc.so.5 this is a libc 5 linked binary.  */    \
+      if (main_map->l_info[DT_NEEDED])                                       \
+       {                                                                     \
+         /* We have dependencies.  */                                        \
+         const char *strtab = ((void *) main_map->l_addr                     \
+                               + main_map->l_info[DT_STRTAB]->d_un.d_ptr);   \
+         const ElfW(Dyn) *d;                                                 \
+                                                                             \
+         for (d = main_map->l_ld; d->d_tag != DT_NULL; ++d)                  \
+           if (d->d_tag == DT_NEEDED                                         \
+               && strcmp (strtab + d->d_un.d_val, "libc.so.5") == 0)         \
+             break;                                                          \
+                                                                             \
+         /* We print a `5' or `6' depending on the outcome.  */              \
+         _dl_sysdep_message (d->d_tag != DT_NULL ? "5\n" : "6\n", NULL);     \
+       }                                                                     \
+    }                                                                        \
+  while (0)
+
+/* Recognizing extra environment variables.  */
+#define EXTRA_LD_ENVVARS \
+  case 15:                                                                   \
+    if (memcmp (&envline[3], "LIBRARY_VERSION", 15) == 0)                    \
+      {                                                                              \
+       _dl_correct_cache_id = envline[19] == '5' ? 2 : 3;                    \
+       break;                                                                \
+      }
+
+#endif /* dl-librecon.h */
diff --git a/sysdeps/unix/sysv/linux/ldd-rewrite.sed b/sysdeps/unix/sysv/linux/ldd-rewrite.sed
new file mode 100644 (file)
index 0000000..efc1b57
--- /dev/null
@@ -0,0 +1,11 @@
+/Maybe extra code for non-ELF binaries/a\
+  file=$1\
+  # Run the ldd stub.\
+  lddlibc4 $file\
+  # Test the result.\
+  if test $? -lt 3; then\
+    exit 0;\
+  fi\
+  # In case of an error punt.
+/LD_TRACE_LOADED_OBJECTS=1/a\
+add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out"
index 9de3dc8..7c00d05 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <a.out.h>
 #include <errno.h>
+#include <error.h>
 #include <libintl.h>
 #include <locale.h>
 #include <stdio.h>