summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog31
-rw-r--r--Makeconfig9
-rw-r--r--elf/Makefile13
-rw-r--r--elf/dl-load.c5
-rw-r--r--elf/rtld.c51
-rw-r--r--sysdeps/generic/Makefile2
-rw-r--r--sysdeps/generic/make_siglist.c11
-rw-r--r--sysdeps/mach/hurd/dl-sysdep.c23
8 files changed, 111 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 656afec833..568a9553f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+Thu Nov 16 06:07:49 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+	* sysdeps/mach/hurd/dl-sysdep.c (_dl_sysdep_start_cleanup): New
+	function.
+	(_dl_sysdep_start): Move cleanup code there.
+
+	* Makeconfig (default-rpath): New variable.
+	(link-libc): Use it.
+	* elf/Makefile (ld.so): Pass -rpath=$(default-rpath).
+	* elf/rtld.c (_dl_rpath): New variable.
+	(_dl_start): Set it from rtld_map's DT_RPATH.
+	Call _dl_setup_hash on rtld_map.
+	(dl_main): Cache address of _exit in variable before relocating,
+	and use that in later calls.  Call _dl_sysdep_start_cleanup before
+	relocating.  Keep track of dependency order while loading; remove
+	rtld_map from chain, and reinsert in proper order if there is a
+	dependency on it.
+
+	* sysdeps/generic/Makefile (make_siglist): Pass
+	-DSIGNUM_H=... with config's signum.h location.
+	* sysdeps/generic/make_siglist.c: Include SIGNUM_H to define
+	signal numbers.
+	(HAVE_STRSIGNAL, HAVE_PSIGNAL): Define these before including signame.c
+	(main): Deansideclize output.
+
+	* elf/dl-load.c (_dl_map_object): Use _dl_rpath variable in place
+	of DEFAULT_RPATH macro.
+	* elf/Makefile: Undo last change.
+
+	* sysdeps/mach/hurd/dl-sysdep.c (free): Don't abort, just nop.
+
 Wed Nov 15 19:22:07 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
 	* elf/dl-lookup.c (_dl_lookup_symbol): Undefined symbol is no
diff --git a/Makeconfig b/Makeconfig
index e716776cb9..a610d057f5 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -291,8 +291,15 @@ endif
 endif
 ifndef link-libc
 ifeq (yes,$(build-shared))
-link-libc = -Wl,-rpath-link=$(common-objdir) -Wl,-rpath=$(libdir) \
+link-libc = -Wl,-rpath-link=$(common-objdir) -Wl,-rpath=$(default-rpath) \
 	    $(common-objpfx)libc.so $(gnulib)
+# Choose the default search path for the dynamic linker based on
+# where we will install libraries.
+ifneq ($(libdir),$(slibdir))
+default-rpath = $(slibdir):$(libdir)
+else
+default-rpath = $(libdir)
+endif
 else
 link-libc = $(common-objpfx)libc.a $(gnulib) $(common-objpfx)libc.a
 endif
diff --git a/elf/Makefile b/elf/Makefile
index a37e95d2c5..4a1adb8b59 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -50,16 +50,6 @@ endif
 include ../Rules
 
 
-# Choose the default search path for the dynamic linker based on
-# where we will install libraries.
-ifneq ($(libdir),$(slibdir))
-default-rpath = $(slibdir):$(libdir)
-else
-default-rpath = $(libdir)
-endif
-CPPFLAGS += -DDEFAULT_RPATH='"$(default-rpath)"'
-
-
 # Link together the dynamic linker into a single relocatable object.
 # We use this to produce both the ABI-compliant and Linux-compatible
 # dynamic linker shared objects below.
@@ -70,7 +60,8 @@ $(objpfx)librtld.so: $(rtld-routines:%=$(objpfx)%.so) \
 		  '-Wl,-(' $^ -lgcc '-Wl,-)'
 
 $(objpfx)ld.so $(objpfx)ld-linux.so.1: $(objpfx)librtld.so
-	$(LINK.o) -nostdlib -nostartfiles -shared -o $@ $^
+	$(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
+		  -Wl,-rpath=$(default-rpath) $^
 
 # The Linux-compatible dynamic linker shared object is just the same
 # with one object file of compatibility initialization code added.
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 126d6aab5c..88ee318aad 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -139,7 +139,10 @@ _dl_map_object (struct link_map *loader, const char *name)
       if (fd == -1 && ! _dl_secure)
 	trypath (getenv ("LD_LIBRARY_PATH"));
       if (fd == -1)
-	trypath (DEFAULT_RPATH);
+	{
+	  extern const char *_dl_rpath;	/* Set in rtld.c. */
+	  trypath (_dl_rpath);
+	}
     }
   else
     {
diff --git a/elf/rtld.c b/elf/rtld.c
index 88f0d6d804..d0c25b4db4 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -39,10 +39,12 @@ extern Elf32_Addr _dl_sysdep_start (void **start_argptr,
 				    void (*dl_main) (const Elf32_Phdr *phdr,
 						     Elf32_Word phent,
 						     Elf32_Addr *user_entry));
+extern void _dl_sysdep_start_cleanup (void);
 
 int _dl_secure;
 int _dl_argc;
 char **_dl_argv;
+const char *_dl_rpath;
 
 struct r_debug dl_r_debug;
 
@@ -93,7 +95,13 @@ _dl_start (void *arg)
   rtld_map.l_addr = bootstrap_map.l_addr;
   rtld_map.l_ld = bootstrap_map.l_ld;
   memcpy (rtld_map.l_info, bootstrap_map.l_info, sizeof rtld_map.l_info);
+  _dl_setup_hash (&rtld_map);
 
+  /* Cache the DT_RPATH stored in ld.so itself; this will be
+     the default search path.  */
+  _dl_rpath = (void *) (rtld_map.l_addr +
+			rtld_map.l_info[DT_STRTAB]->d_un.d_ptr +
+			rtld_map.l_info[DT_RPATH]->d_un.d_val);
 
   /* Call the OS-dependent function to set up life so we can do things like
      file access.  It will call `dl_main' (below) to do all the real work
@@ -118,10 +126,11 @@ dl_main (const Elf32_Phdr *phdr,
   void doit (void)
     {
       const Elf32_Phdr *ph;
-      struct link_map *l;
+      struct link_map *l, *last, *before_rtld;
       const char *interpreter_name;
       int lazy;
       int list_only = 0;
+      __typeof (_exit) *volatile exitfn;
 
       if (*user_entry == (Elf32_Addr) &_start)
 	{
@@ -248,6 +257,7 @@ of this helper program; chances are you did not intend to run this program.\n",
       /* Now process all the DT_NEEDED entries and map in the objects.
 	 Each new link_map will go on the end of the chain, so we will
 	 come across it later in the loop to map in its dependencies.  */
+      before_rtld = NULL;
       for (l = _dl_loaded; l; l = l->l_next)
 	{
 	  if (l->l_info[DT_NEEDED])
@@ -255,24 +265,47 @@ of this helper program; chances are you did not intend to run this program.\n",
 	      const char *strtab
 		= (void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr;
 	      const Elf32_Dyn *d;
+	      last = l;
 	      for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
 		if (d->d_tag == DT_NEEDED)
-		  _dl_map_object (l, strtab + d->d_un.d_val);
+		  {
+		    struct link_map *new;
+		    new = _dl_map_object (l, strtab + d->d_un.d_val);
+		    if (!before_rtld && new == &rtld_map)
+		      before_rtld = last;
+		    last = new;
+		  }
 	    }
 	  l->l_deps_loaded = 1;
 	}
 
-      if (rtld_map.l_opencount == 0)
+      /* If any DT_NEEDED entry referred to the interpreter object itself,
+	 reorder the list so it appears after its dependent.  If not,
+	 remove it from the maps we will use for symbol resolution.  */
+      rtld_map.l_prev->l_next = rtld_map.l_next;
+      if (rtld_map.l_next)
+	rtld_map.l_next->l_prev = rtld_map.l_prev;
+      if (before_rtld)
 	{
-	  /* No DT_NEEDED entry referred to the interpreter object itself.
-	     Remove it from the maps we will use for symbol resolution.  */
-	  rtld_map.l_prev->l_next = rtld_map.l_next;
+	  rtld_map.l_prev = before_rtld;
+	  rtld_map.l_next = before_rtld->l_next;
+	  before_rtld->l_next = &rtld_map;
 	  if (rtld_map.l_next)
-	    rtld_map.l_next->l_prev = rtld_map.l_prev;
+	    rtld_map.l_next->l_prev = &rtld_map;
 	}
 
       lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
 
+      /* Fetch this value now, before real relocation.  For --list, it will
+	 be called below, and the finally-linked version is not the right
+	 one.  */
+      exitfn = &_exit;
+
+      /* Do any necessary cleanups for the startup OS interface code.
+	 We do these now so that no calls are made after real relocation
+	 which might be resolved to different functions than we expect.  */
+      _dl_sysdep_start_cleanup ();
+
       /* Now we have all the objects loaded.  Relocate them all.
 	 We do this in reverse order so that copy relocs of earlier
 	 objects overwrite the data written by later objects.  */
@@ -297,7 +330,7 @@ of this helper program; chances are you did not intend to run this program.\n",
 	    {
 	      _dl_sysdep_message (_dl_loaded->l_name, ": statically linked\n",
 				  NULL);
-	      _exit (1);
+	      (*exitfn) (1);
 	    }
 
 	  for (l = _dl_loaded->l_next; l; l = l->l_next)
@@ -311,7 +344,7 @@ of this helper program; chances are you did not intend to run this program.\n",
 				  " (0x", bp, ")\n", NULL);
 	    }
 
-	  _exit (0);
+	  (*exitfn) (0);
 	}
 
       if (rtld_map.l_info[DT_INIT])
diff --git a/sysdeps/generic/Makefile b/sysdeps/generic/Makefile
index 1315a26b95..dc31a50fcd 100644
--- a/sysdeps/generic/Makefile
+++ b/sysdeps/generic/Makefile
@@ -53,6 +53,8 @@ $(objpfx)siglist.c: $(objpfx)make_siglist
 
 $(objpfx)make_siglist: $(sysdep_dir)/generic/make_siglist.c
 	$(native-compile)
+	-DSIGNUM_H=\"`cd $(dir $(firstword $(wildcard \
+			 $(+sysdep_dirs:%=%/signum.h)))); pwd`/signum.h\"
 
 generated := $(generated) make_siglist siglist.c
 endif
diff --git a/sysdeps/generic/make_siglist.c b/sysdeps/generic/make_siglist.c
index 34abf80513..a38ab6aa2e 100644
--- a/sysdeps/generic/make_siglist.c
+++ b/sysdeps/generic/make_siglist.c
@@ -15,14 +15,19 @@ You should have received a copy of the GNU General Public License
 along with the GNU C Library; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-#include <signal.h>
 #include <stdio.h>
+#include <signal.h>
 
+/* Get this configuration's defns of the signal numbers.  */
+#define _SIGNAL_H 1
+#include SIGNUM_H
 
 /* Make a definition for sys_siglist.  */
 
 
 #undef	HAVE_SYS_SIGLIST
+#define HAVE_STRSIGNAL
+#define HAVE_PSIGNAL
 #define sys_siglist my_siglist	/* Avoid clash with signal.h.  */
 
 #include "signame.c"
@@ -35,11 +40,11 @@ main()
 
   signame_init ();
 
-  puts ("#include \"ansidecl.h\"\n#include <stddef.h>\n");
+  puts ("#include <stddef.h>\n");
 
   puts ("\n/* This is a list of all known signal numbers.  */");
 
-  puts ("\nCONST char *CONST _sys_siglist[] =\n  {");
+  puts ("\nconst char *const _sys_siglist[] =\n  {");
 
   for (i = 0; i < NSIG; ++i)
     printf ("    \"%s\",\n", sys_siglist[i]);
diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c
index 0144958766..f8997fe025 100644
--- a/sysdeps/mach/hurd/dl-sysdep.c
+++ b/sysdeps/mach/hurd/dl-sysdep.c
@@ -159,12 +159,6 @@ unfmh();			/* XXX */
 		  _dl_hurd_data->phdrsz / sizeof (Elf32_Phdr),
 		  &_dl_hurd_data->user_entry);
 
-      /* Deallocate the reply port and task port rights acquired by
-	 __mach_init.  We are done with them now, and the user will
-	 reacquire them for himself when he wants them.  */
-      __mig_dealloc_reply_port (MACH_PORT_NULL);
-      __mach_port_deallocate (__mach_task_self (), __mach_task_self_);
-
       if (_dl_skip_args && _dl_argv[-_dl_skip_args] == (char *) p)
 	{
 	  /* We are ignoring the first few arguments, but we have no Hurd
@@ -198,6 +192,16 @@ fmh();				/* XXX */
   LOSE;
   abort ();
 }
+
+void
+_dl_sysdep_start_cleanup (void)
+{
+  /* Deallocate the reply port and task port rights acquired by
+     __mach_init.  We are done with them now, and the user will
+     reacquire them for himself when he wants them.  */
+  __mig_dealloc_reply_port (MACH_PORT_NULL);
+  __mach_port_deallocate (__mach_task_self (), __mach_task_self_);
+}
 
 int
 _dl_sysdep_open_zero_fill (void)
@@ -567,13 +571,14 @@ malloc (size_t n)
   ptr += n;
   return block;
 }
-
 weak_symbol (malloc)
 
-/* These should never be called.  */
+/* This should never be called.  */
 void *realloc (void *ptr, size_t n) { ptr += n; abort (); }
-void free (void *ptr) { ptr = ptr; abort (); }
 weak_symbol (realloc)
+
+/* This will rarely be called.  */
+void free (void *ptr) { ptr = ptr; }
 weak_symbol (free)
 
 /* Avoid signal frobnication in setjmp/longjmp.  */