about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rwxr-xr-xconfigure70
-rw-r--r--elf/dl-deps.c11
-rw-r--r--elf/dl-load.c2
-rw-r--r--elf/rtld.c31
5 files changed, 70 insertions, 53 deletions
diff --git a/ChangeLog b/ChangeLog
index 667df43435..69eb550ebe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 Sat Jun 15 18:13:43 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
 
+	* elf/dl-deps.c (_dl_map_object_deps): Set MAP's mark bit before loop.
+	Set mark bits of deps as opened, instead of as scanned.
+
+	* elf/rtld.c (dl_main): Remove _dl_rtld_map from chain unconditionally.
+	Then if it has a nonzero l_opencount, add it back in search order.
+
+	* elf/dl-load.c (_dl_map_object): Don't use _dl_loaded's DT_RPATH if
+ 	it ain't got one!
+
 	* sysdeps/unix/sysv/linux/Dist: Add sys/klog.h.
 
 	* elf/dl-open.c (_dl_open): Remove PARENT argument, pass null.
diff --git a/configure b/configure
index 6976018cdc..76c58881c9 100755
--- a/configure
+++ b/configure
@@ -745,12 +745,10 @@ esac
 
 
 # Compute the list of sysdep directories for this configuration.
+# This can take a while to compute.
 sysdep_dir=$srcdir/sysdeps
 echo $ac_n "checking sysdep dirs""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'libc_cv_sysdirs'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  # Make sco3.2v4 become sco3.2.4 and sunos4.1.1_U1 become sunos4.1.1.U1.
+# Make sco3.2v4 become sco3.2.4 and sunos4.1.1_U1 become sunos4.1.1.U1.
 os="`echo $os | sed 's/\([0-9A-Z]\)[v_]\([0-9A-Z]\)/\1.\2/g'`"
 
 case "$os" in
@@ -858,15 +856,26 @@ sysnames="`echo $sysnames | sed -e 's@^/@@' -e 's@ /@ @g'`"
 # Expand the list of system names into a full list of directories
 # from each element's parent name and Implies file (if present).
 set $sysnames
+names= seen=
 while test $# -gt 0; do
   name=$1
   shift
 
+  if echo "$seen" | fgrep -x $name >/dev/null; then
+    # Already in the list.
+    continue
+  fi
+
+  # Report each name as we discover it, so there is no long pause in output.
+  echo $ac_n "$name $ac_c" >&6
+
   if test -f $sysdep_dir/$name/Implies; then
     # Collect more names from the `Implies' file (removing comments).
     implied="`sed 's/#.*$//' < $sysdep_dir/$name/Implies`"
     for x in $implied; do
-      test -d $sysdep_dir/$x || echo "Warning: $name implies nonexistent $x">&2
+      test -d $sysdep_dir/$x || {
+        echo "configure: warning: sysdeps/$name/Implies specifies nonexistent $x" 1>&2
+      }
     done
   else
     implied=
@@ -874,6 +883,9 @@ while test $# -gt 0; do
 
   # Add NAME to the list of names.
   names="$names $name"
+  # We maintain a parallel newline-separated list for the fgrep check above.
+  seen="$seen
+$name"
 
   # Find the parent of NAME, using the empty string if it has none.
   parent="`echo $name | sed -n -e '/\//!q' -e 's=/[^/]*$==p'`"
@@ -890,31 +902,13 @@ while test $# -gt 0; do
 done
 
 # Add the default directories.
-names="$names generic stub"
+sysnames="$names generic stub"
+
+# The other names were emitted during the scan.
+echo "$ac_t""generic stub" 1>&6
 
-# Now uniquize the list.
-seen=
-sysnames=
-for name in $names; do
-  if echo "$seen" | fgrep -x $name >/dev/null; then
-    # Already in the list.
-    true;
-  else
-    # A new one.
-    if test -z "$seen"; then
-      seen="$name" sysnames="$name"
-    else
-      seen="$seen
-$name"
-      sysnames="$sysnames $name"
-    fi
-  fi
-done
-libc_cv_sysdirs="$sysnames"
-fi
 
-echo "$ac_t""$libc_cv_sysdirs" 1>&6
- sysnames="$libc_cv_sysdirs"
+### Locate tools.
 
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
@@ -1101,13 +1095,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1105 "configure"
+#line 1099 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1111: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1105: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1116,13 +1110,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1120 "configure"
+#line 1114 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1126: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1120: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1264,7 +1258,7 @@ if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1268 "configure"
+#line 1262 "configure"
 #include "confdefs.h"
 #define __need_size_t
 #define __need_wchar_t
@@ -1280,7 +1274,7 @@ size_t size; wchar_t wchar;
 if (&size == NULL || &wchar == NULL) abort ();
 ; return 0; }
 EOF
-if { (eval echo configure:1284: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1278: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_friendly_stddef=yes
 else
@@ -1387,7 +1381,7 @@ if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1391 "configure"
+#line 1385 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1397,7 +1391,7 @@ asm (".section .init");
 				    asm (".text");
 ; return 0; }
 EOF
-if { (eval echo configure:1401: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1395: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_have_initfini=yes
 else
@@ -1425,7 +1419,7 @@ if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1429 "configure"
+#line 1423 "configure"
 #include "confdefs.h"
 asm ("_glibc_foobar:");
 int main() { return 0; }
@@ -1433,7 +1427,7 @@ int t() {
 glibc_foobar ();
 ; return 0; }
 EOF
-if { (eval echo configure:1437: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:1431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   libc_cv_asm_underscores=yes
 else
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 3e49fcfe01..9fe974d982 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -38,6 +38,10 @@ _dl_map_object_deps (struct link_map *map)
   head.next = NULL;
   nlist = 1;
 
+  /* We use `l_reserved' as a mark bit to detect objects we have already
+     put in the search list and avoid adding duplicate elements later in
+     the list.  */
+  map->l_reserved = 1;
 
   /* Process each element of the search list, loading each of its immediate
      dependencies and appending them to the list as we step through it.
@@ -47,11 +51,6 @@ _dl_map_object_deps (struct link_map *map)
     {
       struct link_map *l = scanp->map;
 
-      /* We use `l_reserved' as a mark bit to detect objects we have
-         already put in the search list and avoid adding duplicate elements
-         later in the list.  */
-      l->l_reserved = 1;
-
       if (l->l_info[DT_NEEDED])
 	{
 	  const char *strtab
@@ -79,6 +78,8 @@ _dl_map_object_deps (struct link_map *map)
 		    tailp->map = dep;
 		    tailp->next = NULL;
 		    ++nlist;
+		    /* Set the mark bit that says it's already in the list.  */
+		    dep->l_reserved = 1;
 		  }
 	      }
 	}
diff --git a/elf/dl-load.c b/elf/dl-load.c
index f947bb8a93..f655fdacef 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -479,7 +479,7 @@ _dl_map_object (struct link_map *loader, const char *name, int type)
 				   l->l_info[DT_RPATH]->d_un.d_val));
       /* If dynamically linked, try the DT_RPATH of the executable itself.  */
       l = _dl_loaded;
-      if (fd == -1 && l && l->l_type != lt_loaded)
+      if (fd == -1 && l && l->l_type != lt_loaded && l->l_info[DT_RPATH])
 	trypath ((const char *) (l->l_addr +
 				 l->l_info[DT_STRTAB]->d_un.d_ptr +
 				 l->l_info[DT_RPATH]->d_un.d_val));
diff --git a/elf/rtld.c b/elf/rtld.c
index fb92809ff5..f20602d090 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -243,17 +243,30 @@ of this helper program; chances are you did not intend to run this program.\n",
   __close (_dl_zerofd);
   _dl_zerofd = -1;
 
-  /* XXX if kept, move it so l_next list is in dep order because
-     it will determine gdb's search order.
-     Perhaps do this always, so later dlopen by name finds it?
-     XXX But then gdb always considers it present.  */
-  if (_dl_rtld_map.l_opencount == 0)
+  /* Remove _dl_rtld_map from the chain.  */
+  _dl_rtld_map.l_prev->l_next = _dl_rtld_map.l_next;
+  if (_dl_rtld_map.l_next)
+    _dl_rtld_map.l_next->l_prev = _dl_rtld_map.l_prev;
+
+  if (_dl_rtld_map.l_opencount)
     {
-      /* No DT_NEEDED entry referred to the interpreter object itself,
-	 so remove it from the list of visible objects.  */
-      _dl_rtld_map.l_prev->l_next = _dl_rtld_map.l_next;
+      /* Some DT_NEEDED entry referred to the interpreter object itself, so
+	 put it back in the list of visible objects.  We insert it into the
+	 chain in symbol search order because gdb uses the chain's order as
+	 its symbol search order.  */
+      unsigned int i = 1;
+      while (l->l_searchlist[i] != &_dl_rtld_map)
+	++i;
+      _dl_rtld_map.l_prev = l->l_searchlist[i - 1];
+      _dl_rtld_map.l_next = (i + 1 < l->l_nsearchlist ?
+			     l->l_searchlist[i + 1] : NULL);
+      assert (_dl_rtld_map.l_prev->l_next == _dl_rtld_map.l_next);
+      _dl_rtld_map.l_prev->l_next = &_dl_rtld_map;
       if (_dl_rtld_map.l_next)
-	_dl_rtld_map.l_next->l_prev = _dl_rtld_map.l_prev;
+	{
+	  assert (_dl_rtld_map.l_next->l_prev == _dl_rtld_map.l_prev);
+	  _dl_rtld_map.l_next->l_prev = &_dl_rtld_map;
+	}
     }
 
   if (list_only)