summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--elf/dl-load.c42
-rw-r--r--elf/dl-support.c3
-rw-r--r--elf/ldsodefs.h3
-rw-r--r--elf/rtld.c16
-rwxr-xr-xiconvdata/run-iconv-test.sh18
6 files changed, 78 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index a343d387a5..24c53c7e06 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+1998-05-19 23:08  Ulrich Drepper  <drepper@cygnus.com>
+
+	* elf/rtld.c: Recognize --ignore-rpath argument and set _dl_ignore_path
+	variable using the value.
+	* elf/ldsodefs.h: Declare _dl_ignore_path.
+	* elf/dl-load.c (decompose_rpath): Compare name of handled shared
+	object against list in _dl_ignore_path and ignore RPATH if on the list.
+	* elf/dl-support.c: Define _dl_ignore_path for static binaries.
+	* iconvdata/run-iconv-test.sh: Call ld.so with --ignore-rpath parameter
+	to make sure we get the correct helper libraries loaded.
+
+	* elf/dl-load.c (decompose_rpath): Remove `room' parameter.  Use
+	"RPATH" string in call to fillin_rpath instead.
+	(_dl_init_paths): Remove this parameter from call to decompose_rpath.
+
 1998-05-19  Ulrich Drepper  <drepper@cygnus.com>
 
 	* sysdeps/i386/i486/bits/string.h (__strstr_g): Initialize %edx
diff --git a/elf/dl-load.c b/elf/dl-load.c
index ce29e3c3d5..4fc0a022d6 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -281,16 +281,41 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
 
 static struct r_search_path_elem **
 internal_function
-decompose_rpath (const char *rpath, size_t additional_room,
-		 const char *what, const char *where)
+decompose_rpath (const char *rpath, size_t additional_room, const char *where)
 {
   /* Make a copy we can work with.  */
-  char *copy = local_strdup (rpath);
+  char *copy;
   char *cp;
   struct r_search_path_elem **result;
-  /* First count the number of necessary elements in the result array.  */
-  size_t nelems = 0;
+  size_t nelems;
+
+  /* First see whether we must forget the RPATH from this object.  */
+  if (_dl_ignore_rpath != NULL && !__libc_enable_secure)
+    {
+      const char *found = strstr (_dl_ignore_rpath, where);
+      if (found != NULL)
+	{
+	  size_t len = strlen (where);
+	  if ((found == _dl_ignore_rpath || found[-1] == ':')
+	      && (found[len] == '\0' || found[len] == ':'))
+	    {
+	      /* This object is on the list of objects for which the RPATH
+		 must not be used.  */
+	      result = (struct r_search_path_elem **)
+		malloc ((additional_room + 1) * sizeof (*result));
+	      if (result == NULL)
+		_dl_signal_error (ENOMEM, NULL,
+				  "cannot create cache for search path");
+	      result[0] = NULL;
+
+	      return result;
+	    }
+	}
+    }
 
+  /* Count the number of necessary elements in the result array.  */
+  copy = local_strdup (rpath);
+  nelems = 0;
   for (cp = copy; *cp != '\0'; ++cp)
     if (*cp == ':')
       ++nelems;
@@ -303,7 +328,7 @@ decompose_rpath (const char *rpath, size_t additional_room,
   if (result == NULL)
     _dl_signal_error (ENOMEM, NULL, "cannot create cache for search path");
 
-  return fillin_rpath (copy, result, ":", NULL, what, where);
+  return fillin_rpath (copy, result, ":", NULL, "RPATH", where);
 }
 
 
@@ -399,7 +424,7 @@ _dl_init_paths (const char *llp)
 	    decompose_rpath ((const char *)
 			     (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr
 			      + l->l_info[DT_RPATH]->d_un.d_val),
-			     nllp, "RPATH", l->l_name);
+			     nllp, l->l_name);
 	}
       else
 	{
@@ -1056,8 +1081,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
 				 + l->l_info[DT_STRTAB]->d_un.d_ptr
 				 + l->l_info[DT_RPATH]->d_un.d_val);
 		l->l_rpath_dirs =
-		  decompose_rpath ((const char *) ptrval, 0,
-				   "RPATH", l->l_name);
+		  decompose_rpath ((const char *) ptrval, 0, l->l_name);
 	      }
 
 	    if (l->l_rpath_dirs != (struct r_search_path_elem **) -1l)
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 2702404444..0a14b6d1bd 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -55,6 +55,9 @@ struct r_search_path *_dl_search_paths;
 const char *_dl_profile;
 struct link_map *_dl_profile_map;
 
+/* Names of shared object for which the RPATHs should be ignored.  */
+const char *_dl_ignore_rpath;
+
 
 static void non_dynamic_init (void) __attribute__ ((unused));
 
diff --git a/elf/ldsodefs.h b/elf/ldsodefs.h
index 19d931fd4e..a64f51bca6 100644
--- a/elf/ldsodefs.h
+++ b/elf/ldsodefs.h
@@ -149,6 +149,9 @@ extern unsigned long int _dl_hwcap_mask;
 /* File deccriptor to write debug messages to.  */
 extern int _dl_debug_fd;
 
+/* Names of shared object for which the RPATH should be ignored.  */
+extern const char *_dl_ignore_rpath;
+
 /* OS-dependent function to open the zero-fill device.  */
 extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */
 
diff --git a/elf/rtld.c b/elf/rtld.c
index 75012e3f20..51a295cfb2 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -81,6 +81,8 @@ int _dl_debug_symbols;
 int _dl_debug_versions;
 int _dl_debug_reloc;
 int _dl_debug_files;
+const char *_dl_ignore_rpath;		/* RPATH values which should be
+					   ignored.  */
 
 /* Set nonzero during loading and initialization of executable and
    libraries, cleared before the executable's entry point runs.  This
@@ -334,8 +336,7 @@ dl_main (const ElfW(Phdr) *phdr,
 	    --_dl_argc;
 	    ++_dl_argv;
 	  }
-	else if (! strcmp (_dl_argv[1], "--library-path")
-		 && _dl_argc > 2)
+	else if (! strcmp (_dl_argv[1], "--library-path") && _dl_argc > 2)
 	  {
 	    library_path = _dl_argv[2];
 
@@ -343,6 +344,14 @@ dl_main (const ElfW(Phdr) *phdr,
 	    _dl_argc -= 2;
 	    _dl_argv += 2;
 	  }
+	else if (! strcmp (_dl_argv[1], "--ignore-rpath") && _dl_argc > 2)
+	  {
+	    _dl_ignore_rpath = _dl_argv[2];
+
+	    _dl_skip_args += 2;
+	    _dl_argc -= 2;
+	    _dl_argv += 2;
+	  }
 	else
 	  break;
 
@@ -367,7 +376,8 @@ of this helper program; chances are you did not intend to run this program.\n\
   --verify             verify that given object really is a dynamically linked\n\
                        object we get handle\n\
   --library-path PATH  use given PATH instead of content of the environment\n\
-                       variable LD_LIBRARY_PATH\n",
+                       variable LD_LIBRARY_PATH\n\
+  --ignore-rpath LIST  ignore RPATH information in object names in LIST\n",
 			  NULL);
 
       ++_dl_skip_args;
diff --git a/iconvdata/run-iconv-test.sh b/iconvdata/run-iconv-test.sh
index c28bb02270..90ab8b7fe5 100755
--- a/iconvdata/run-iconv-test.sh
+++ b/iconvdata/run-iconv-test.sh
@@ -36,7 +36,8 @@ export GCONV_PATH
 LIBPATH=$codir:$codir/iconvdata
 
 # How the start the iconv(1) program.
-ICONV="$codir/elf/ld.so --library-path $LIBPATH $codir/iconv/iconv_prog"
+ICONV='$codir/elf/ld.so --library-path $LIBPATH --ignore-rpath ${from}.so \
+       $codir/iconv/iconv_prog'
 
 # We read the file named TESTS.  All non-empty lines not starting with
 # `#' are interpreted as commands.
@@ -45,14 +46,17 @@ while read from to subset targets; do
   # Ignore empty and comment lines.
   if test -z "$targets" || test "$from" = '#'; then continue; fi
 
+  # Expand the variables now.
+  PROG=`eval echo $ICONV`
+
   for t in $targets; do
-    $ICONV -f $from -t $t testdata/$from > $temp1 ||
+    $PROG -f $from -t $t testdata/$from > $temp1 ||
       { echo "*** conversion from $from to $t failed"; failed=1; continue; }
     if test -s testdata/$from..$t; then
       cmp $temp1 testdata/$from..$t > /dev/null 2>&1 ||
 	{ echo "*** $from -> $t conversion failed"; failed=1; continue; }
     fi
-    $ICONV -f $t -t $to -o $temp2 $temp1 ||
+    $PROG -f $t -t $to -o $temp2 $temp1 ||
       { echo "*** conversion from $t to $to failed"; failed=1; continue; }
     test -s $temp1 && cmp testdata/$from $temp2 > /dev/null 2>&1 ||
       { echo "*** $from -> t -> $to conversion failed"; failed=1; continue; }
@@ -62,16 +66,16 @@ while read from to subset targets; do
     # of the coded character set we test we convert the test to this
     # coded character set.  Otherwise we convert to all the TARGETS.
     if test $subset = Y; then
-      $ICONV -f $from -t $t testdata/suntzus |
-      $ICONV -f $t -t $to > $temp1 ||
+      $PROG -f $from -t $t testdata/suntzus |
+      $PROG -f $t -t $to > $temp1 ||
 	{ echo "*** conversion $from->$t->$to of suntzus failed"; failed=1;
 	  continue; }
       cmp testdata/suntzus $temp1 ||
 	{ echo "*** conversion $from->$t->$to of suntzus incorrect";
 	  failed=1; continue; }
     else
-      $ICONV -f ASCII -t $to testdata/suntzus |
-      $ICONV -f $to -t ASCII > $temp1 ||
+      $PROG -f ASCII -t $to testdata/suntzus |
+      $PROG -f $to -t ASCII > $temp1 ||
         { echo "*** conversion ASCII->$to->ASCII of suntzus failed";
 	  failed=1; continue; }
 	cmp testdata/suntzus $temp1 ||