summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--elf/rtld.c57
-rw-r--r--hurd/hurdsig.c52
-rw-r--r--sysdeps/mach/hurd/mmap.c25
4 files changed, 83 insertions, 68 deletions
diff --git a/ChangeLog b/ChangeLog
index 79f7c08062..f7e5ef69ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+Tue Nov 21 14:12:13 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+	* malloc/malloc.c (align): Don't check contiguity and call abort.
+
+	* hurd/hurdsig.c (post_reply): Function removed.
+	(abort_thread, abort_all_rpcs, _hurdsig_abort_rpcs): Don't call it.
+	Take single callback fn arg instead of reply port and type.
+	(_hurd_internal_post_signal): Callers changed.
+	Cache reply stub fn ptr in local var before UNTRACED might be changed.
+
+	* sysdeps/mach/hurd/mmap.c: Cope with a null write memobj for
+	PROT_READ|PROT_WRITE copy mapping.  Pass a proper vm_inherit_t to
+	vm_map.
+
+	* elf/rtld.c (_dl_start): For --list, do output and exit before
+	relocating.
+
 Mon Nov 20 16:19:15 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
 	* intl/Makefile [gettext-srcdir]: Rewrote copying rules to only
diff --git a/elf/rtld.c b/elf/rtld.c
index d0c25b4db4..cf9517d527 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -130,7 +130,6 @@ dl_main (const Elf32_Phdr *phdr,
       const char *interpreter_name;
       int lazy;
       int list_only = 0;
-      __typeof (_exit) *volatile exitfn;
 
       if (*user_entry == (Elf32_Addr) &_start)
 	{
@@ -294,12 +293,35 @@ of this helper program; chances are you did not intend to run this program.\n",
 	    rtld_map.l_next->l_prev = &rtld_map;
 	}
 
-      lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
+      if (list_only)
+	{
+	  /* We were run just to list the shared libraries.  It is
+	     important that we do this before real relocation, because the
+	     functions we call below for output may no longer work properly
+	     after relocation.  */
+
+	  if (! _dl_loaded->l_info[DT_NEEDED])
+	    {
+	      _dl_sysdep_message (_dl_loaded->l_name, ": statically linked\n",
+				  NULL);
+	      _exit (1);
+	    }
+
+	  for (l = _dl_loaded->l_next; l; l = l->l_next)
+	    {
+	      char buf[20], *bp;
+	      buf[sizeof buf - 1] = '\0';
+	      bp = _itoa (l->l_addr, &buf[sizeof buf - 1], 16, 0);
+	      while (&buf[sizeof buf - 1] - bp < sizeof l->l_addr * 2)
+		*--bp = '0';
+	      _dl_sysdep_message ("\t", l->l_libname, " => ", l->l_name,
+				  " (0x", bp, ")\n", NULL);
+	    }
+
+	  _exit (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;
+      lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
 
       /* Do any necessary cleanups for the startup OS interface code.
 	 We do these now so that no calls are made after real relocation
@@ -324,29 +346,6 @@ of this helper program; chances are you did not intend to run this program.\n",
       dl_r_debug.r_map = _dl_loaded;
       dl_r_debug.r_brk = (Elf32_Addr) &_dl_r_debug_state;
 
-      if (list_only)
-	{
-	  if (! _dl_loaded->l_info[DT_NEEDED])
-	    {
-	      _dl_sysdep_message (_dl_loaded->l_name, ": statically linked\n",
-				  NULL);
-	      (*exitfn) (1);
-	    }
-
-	  for (l = _dl_loaded->l_next; l; l = l->l_next)
-	    {
-	      char buf[20], *bp;
-	      buf[sizeof buf - 1] = '\0';
-	      bp = _itoa (l->l_addr, &buf[sizeof buf - 1], 16, 0);
-	      while (&buf[sizeof buf - 1] - bp < sizeof l->l_addr * 2)
-		*--bp = '0';
-	      _dl_sysdep_message ("\t", l->l_libname, " => ", l->l_name,
-				  " (0x", bp, ")\n", NULL);
-	    }
-
-	  (*exitfn) (0);
-	}
-
       if (rtld_map.l_info[DT_INIT])
 	{
 	  /* Call the initializer for the compatibility version of the
diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index 13ffb71822..537ea568d9 100644
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -179,35 +179,15 @@ write_corefile (int signo, long int sigcode, int sigerror)
 }
 
 
-/* Send a sig_post reply message if it hasn't already been sent.  */
-static inline void
-post_reply (mach_port_t *reply_port, mach_msg_type_name_t reply_port_type,
-	    int untraced,
-	    error_t result)
-{
-  error_t err;
-  if (reply_port == NULL || *reply_port == MACH_PORT_NULL)
-    return;
-  err = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply)
-    (*reply_port, reply_port_type, result);
-  *reply_port = MACH_PORT_NULL;
-  if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port.  */
-    assert_perror (err);
-}
-
-
 /* The lowest-numbered thread state flavor value is 1,
    so we use bit 0 in machine_thread_all_state.set to
    record whether we have done thread_abort.  */
 #define THREAD_ABORTED 1
 
-/* SS->thread is suspended.  Abort the thread and get its basic state.  If
-   REPLY_PORT is not NULL, send a reply on *REPLY_PORT after aborting the
-   thread.  */
+/* SS->thread is suspended.  Abort the thread and get its basic state.  */
 static void
 abort_thread (struct hurd_sigstate *ss, struct machine_thread_all_state *state,
-	      mach_port_t *reply_port, mach_msg_type_name_t reply_port_type,
-	      int untraced)
+	      void (*reply) (void))
 {
   if (!(state->set & THREAD_ABORTED))
     {
@@ -218,8 +198,8 @@ abort_thread (struct hurd_sigstate *ss, struct machine_thread_all_state *state,
       state->set = THREAD_ABORTED;
     }
 
-  if (reply_port)
-    post_reply (reply_port, reply_port_type, untraced, 0);
+  if (reply)
+    (*reply) ();
 
   machine_get_basic_state (ss->thread, state);
 }
@@ -274,9 +254,7 @@ interrupted_reply_port_location (struct machine_thread_all_state *thread_state,
 mach_port_t
 _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,
 		     struct machine_thread_all_state *state, int *state_change,
-		     mach_port_t *reply_port,
-		     mach_msg_type_name_t reply_port_type,
-		     int untraced)
+		     void (*reply) (void))
 {
   extern const void _hurd_intr_rpc_msg_in_trap;
   mach_port_t rcv_port = MACH_PORT_NULL;
@@ -291,7 +269,7 @@ _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,
 
   /* Abort the thread's kernel context, so any pending message send or
      receive completes immediately or aborts.  */
-  abort_thread (ss, state, reply_port, reply_port_type, untraced);
+  abort_thread (ss, state, reply);
 
   if (state->basic.PC < (natural_t) &_hurd_intr_rpc_msg_in_trap)
     {
@@ -396,7 +374,7 @@ abort_all_rpcs (int signo, struct machine_thread_all_state *state, int live)
 	   We will wait for all the replies below.  */
 	reply_ports[nthreads++] = _hurdsig_abort_rpcs (ss, signo, 1,
 						       state, &state_changed,
-						       NULL, 0, 0);
+						       NULL);
 	if (state_changed && live)
 	  /* Aborting the RPC needed to change this thread's state,
 	     and it might ever run again.  So write back its state.  */
@@ -452,9 +430,17 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
   int ss_suspended;
 
   /* Reply to this sig_post message.  */
-  inline void reply (void)
+  __typeof (__msg_sig_post_reply) *reply_rpc
+    = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply);
+  void reply (void)
     {
-      post_reply (&reply_port, reply_port_type, untraced, 0);
+      error_t err;
+      if (reply_port == MACH_PORT_NULL)
+	return;
+      err = (*reply_rpc) (reply_port, reply_port_type, 0);
+      reply_port = MACH_PORT_NULL;
+      if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port.  */
+	assert_perror (err);
     }
 
   /* Mark the signal as pending.  */
@@ -746,7 +732,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 	   RPC is in progress, abort_rpcs will do this.  But we must always
 	   do it before fetching the thread's state, because
 	   thread_get_state is never kosher before thread_abort.  */
-	abort_thread (ss, &thread_state, NULL, 0, 0);
+	abort_thread (ss, &thread_state, NULL);
 
 	if (ss->context)
 	  {
@@ -793,7 +779,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 	    wait_for_reply
 	      = (_hurdsig_abort_rpcs (ss, signo, 1,
 				      &thread_state, &state_changed,
-				      &reply_port, reply_port_type, untraced)
+				      &reply)
 		 != MACH_PORT_NULL);
 
 	    if (ss->critical_section)
diff --git a/sysdeps/mach/hurd/mmap.c b/sysdeps/mach/hurd/mmap.c
index 97930778ae..4f9304f4f5 100644
--- a/sysdeps/mach/hurd/mmap.c
+++ b/sysdeps/mach/hurd/mmap.c
@@ -66,16 +66,27 @@ __mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
 	  {
 	  case PROT_READ:
 	    memobj = robj;
-	    __mach_port_deallocate (__mach_task_self (), wobj);
+	    if (wobj != MACH_PORT_NULL)
+	      __mach_port_deallocate (__mach_task_self (), wobj);
 	    break;
 	  case PROT_WRITE:
 	    memobj = wobj;
-	    __mach_port_deallocate (__mach_task_self (), robj);
+	    if (robj != MACH_PORT_NULL)
+	      __mach_port_deallocate (__mach_task_self (), robj);
 	    break;
 	  case PROT_READ|PROT_WRITE:
-	    __mach_port_deallocate (__mach_task_self (), robj);
 	    if (robj == wobj)
-	      memobj = wobj;
+	      {
+		memobj = wobj;
+		/* Remove extra reference.  */
+		__mach_port_deallocate (__mach_task_self (), memobj);
+	      }
+	    else if (wobj == MACH_PORT_NULL && /* Not writable by mapping.  */
+		     (flags & (MAP_COPY|MAP_PRIVATE)))
+	      /* The file can only be mapped for reading.  Since we are
+		 making a private mapping, we will never try to write the
+		 object anyway, so we don't care.  */
+	      memobj = robj;
 	    else
 	      {
 		__mach_port_deallocate (__mach_task_self (), wobj);
@@ -96,7 +107,9 @@ __mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
 		  memobj, (vm_offset_t) offset,
 		  flags & (MAP_COPY|MAP_PRIVATE),
 		  vmprot, VM_PROT_ALL,
-		  flags & MAP_INHERIT);
+		  (flags & MAP_INHERIT) == 0 ? VM_INHERIT_NONE :
+		  (flags & (MAP_COPY|MAP_PRIVATE)) ? VM_INHERIT_COPY :
+		  VM_INHERIT_SHARE);
 
   if (memobj != MACH_PORT_NULL)
     __mach_port_deallocate (__mach_task_self (), memobj);
@@ -105,4 +118,4 @@ __mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
 }
 
 weak_alias (__mmap, mmap)
-	
+