summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1999-07-28 18:19:47 +0000
committerRoland McGrath <roland@gnu.org>1999-07-28 18:19:47 +0000
commit83ddec31c69ac3dd3a6c83db8155ac1c63b13178 (patch)
tree578caa1d634b31d2ac66c3fd4bbe443857b10eb7
parent7396d8440b5278c504aa6b1b5ffda53a0d2f98b6 (diff)
downloadglibc-83ddec31c69ac3dd3a6c83db8155ac1c63b13178.tar.gz
glibc-83ddec31c69ac3dd3a6c83db8155ac1c63b13178.tar.xz
glibc-83ddec31c69ac3dd3a6c83db8155ac1c63b13178.zip
1999-07-27 Mark Kettenis <kettenis@gnu.org>
	* sysdeps/mach/hurd/i386/init-first.c (init): Move the inline
	assembler code to switch stacks and call init1 outside this
	function.  Inside `init' the code was optimized away by gcc
	2.95 since it was "clearly" unreachable.
	* sysdeps/mach/hurd/i386/trampoline.c (_hurd_setup_sighandler):
	Do something similar for the trampoline code.
-rw-r--r--sysdeps/mach/hurd/i386/init-first.c56
-rw-r--r--sysdeps/mach/hurd/i386/trampoline.c35
2 files changed, 49 insertions, 42 deletions
diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c
index c18b6a82ac..ee7b90252b 100644
--- a/sysdeps/mach/hurd/i386/init-first.c
+++ b/sysdeps/mach/hurd/i386/init-first.c
@@ -1,5 +1,5 @@
 /* Initialization code run first thing by the ELF startup code.  For i386/Hurd.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 96, 97, 98, 99 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -157,6 +157,8 @@ init (int *data)
       void *newsp = (*_cthread_init_routine) ();
       struct hurd_startup_data *od;
 
+      void switch_stacks (void);
+
       /* Copy per-thread variables from that temporary
 	 area onto the new cthread stack.  */
       memcpy (__hurd_threadvar_location_from_sp (0, newsp),
@@ -181,7 +183,7 @@ init (int *data)
 	 be the return address for `init1'; we will jump there with NEWSP
 	 as the stack pointer.  */
       *--(int *) newsp = data[-1];
-      ((void **) data)[-1] = &&switch_stacks;
+      ((void **) data)[-1] = switch_stacks;
       /* Force NEWSP into %ecx and &init1 into %eax, which are not restored
 	 by function return.  */
       asm volatile ("# a %0 c %1" : : "a" (newsp), "c" (&init1));
@@ -194,6 +196,8 @@ init (int *data)
       unsigned int i;
       int usercode;
 
+      void call_init1 (void);
+
       array = malloc (__hurd_threadvar_max * sizeof (unsigned long int));
       if (array == NULL)
 	__libc_fatal ("Can't allocate single-threaded thread variables.");
@@ -208,33 +212,39 @@ init (int *data)
       /* The argument data is just above the stack frame we will unwind by
 	 returning.  Mutate our own return address to run the code below.  */
       usercode = data[-1];
-      ((void **) data)[-1] = &&call_init1;
+      ((void **) data)[-1] = call_init1;
       /* Force USERCODE into %eax and &init1 into %ecx, which are not
 	 restored by function return.  */
       asm volatile ("# a %0 c %1" : : "a" (usercode), "c" (&init1));
     }
+}
 
-  return;
-
+/* These bits of inline assembler used to be located inside `init'.
+   However they were optimized away by gcc 2.95.  */
+
+/* The return address of `init' above, was redirected to here, so at
+   this point our stack is unwound and callers' registers restored.
+   Only %ecx and %eax are call-clobbered and thus still have the
+   values we set just above.  Fetch from there the new stack pointer
+   we will run on, and jmp to the run-time address of `init1'; when it
+   returns, it will run the user code with the argument data at the
+   top of the stack.  */
+asm ("
  switch_stacks:
-  /* Our return address was redirected to here, so at this point our stack
-     is unwound and callers' registers restored.  Only %ecx and %eax are
-     call-clobbered and thus still have the values we set just above.
-     Fetch from there the new stack pointer we will run on, and jmp to the
-     run-time address of `init1'; when it returns, it will run the user
-     code with the argument data at the top of the stack.  */
-  asm volatile ("movl %eax, %esp; jmp *%ecx");
-  /* NOTREACHED */
-
- call_init1:
-  /* As in the stack-switching case, at this point our stack is unwound and
-     callers' registers restored, and only %ecx and %eax communicate values
-     from the lines above.  In this case we have stashed in %eax the user
-     code return address.  Push it on the top of the stack so it acts as
-     init1's return address, and then jump there.  */
-  asm volatile ("pushl %eax; jmp *%ecx");
-  /* NOTREACHED */
-}
+  movl %eax, %esp
+  jmp *%ecx
+");
+
+/* As in the stack-switching case, at this point our stack is unwound
+   and callers' registers restored, and only %ecx and %eax communicate
+   values from the lines above.  In this case we have stashed in %eax
+   the user code return address.  Push it on the top of the stack so
+   it acts as init1's return address, and then jump there.  */
+asm ("
+  call_init1:
+  push %eax
+  jmp *%ecx
+");
 
 
 #ifdef PIC
diff --git a/sysdeps/mach/hurd/i386/trampoline.c b/sysdeps/mach/hurd/i386/trampoline.c
index 4c1fa60e2e..448b15face 100644
--- a/sysdeps/mach/hurd/i386/trampoline.c
+++ b/sysdeps/mach/hurd/i386/trampoline.c
@@ -1,5 +1,5 @@
 /* Set thread_state for sighandler, and sigcontext to recover.  i386 version.
-   Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1994, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -32,7 +32,9 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
 			volatile int rpc_wait,
 			struct machine_thread_all_state *state)
 {
-  __label__ trampoline, rpc_wait_trampoline, firewall;
+  void trampoline (void);
+  void rpc_wait_trampoline (void);
+  void firewall (void);
   extern const void _hurd_intr_rpc_msg_in_trap;
   extern const void _hurd_intr_rpc_msg_cx_sp;
   extern const void _hurd_intr_rpc_msg_sp_restored;
@@ -140,7 +142,7 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
       stackframe->sigcode = detail->code;
       stackframe->scp = stackframe->return_scp = scp = &stackframe->ctx;
       stackframe->sigreturn_addr = &__sigreturn;
-      stackframe->sigreturn_returns_here = &&firewall; /* Crash on return.  */
+      stackframe->sigreturn_returns_here = firewall; /* Crash on return.  */
 
       /* Set up the sigcontext from the current state of the thread.  */
 
@@ -196,7 +198,7 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
 
       _hurdsig_end_catch_fault ();
 
-      state->basic.eip = (int) &&rpc_wait_trampoline;
+      state->basic.eip = (int) rpc_wait_trampoline;
       /* The reply-receiving trampoline code runs initially on the original
 	 user stack.  We pass it the signal stack pointer in %ebx.  */
       state->basic.uesp = state->basic.esp; /* Restore mach_msg syscall SP.  */
@@ -209,26 +211,26 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
     }
   else
     {
-      state->basic.eip = (int) &&trampoline;
+      state->basic.eip = (int) trampoline;
       state->basic.uesp = (int) sigsp;
     }
   /* We pass the handler function to the trampoline code in %edx.  */
   state->basic.edx = (int) handler;
 
   return scp;
+}
 
-  /* The trampoline code follows.  This is not actually executed as part of
-     this function, it is just convenient to write it that way.  */
+/* The trampoline code follows.  This used to be located inside
+   _hurd_setup_sighandler, but was optimized away by gcc 2.95.  */
 
- rpc_wait_trampoline:
+asm ("rpc_wait_trampoline:\n");
   /* This is the entry point when we have an RPC reply message to receive
      before running the handler.  The MACH_MSG_SEND bit has already been
      cleared in the OPTION argument on our stack.  The interrupted user
      stack pointer has not been changed, so the system call can find its
      arguments; the signal stack pointer is in %ebx.  For our convenience,
      %ecx points to the sc_eax member of the sigcontext.  */
-  asm volatile
-    (/* Retry the interrupted mach_msg system call.  */
+asm (/* Retry the interrupted mach_msg system call.  */
      "movl $-25, %eax\n"	/* mach_msg_trap */
      "lcall $7, $0\n"
      /* When the sigcontext was saved, %eax was MACH_RCV_INTERRUPTED.  But
@@ -241,7 +243,7 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
      /* Switch to the signal stack.  */
      "movl %ebx, %esp\n");
 
- trampoline:
+ asm ("trampoline:\n");
   /* Entry point for running the handler normally.  The arguments to the
      handler function are already on the top of the stack:
 
@@ -249,8 +251,7 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
        4(%esp)	SIGCODE
        8(%esp)	SCP
      */
-  asm volatile
-    ("call *%edx\n"		/* Call the handler function.  */
+asm ("call *%edx\n"		/* Call the handler function.  */
      "addl $12, %esp\n"		/* Pop its args.  */
      /* The word at the top of stack is &__sigreturn; following are a dummy
 	word to fill the slot for the address for __sigreturn to return to,
@@ -258,9 +259,5 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
 	__sigreturn (SCP); this call never returns.  */
      "ret");
 
- firewall:
-  asm volatile ("hlt");
-
-  /* NOTREACHED */
-  return NULL;
-}
+asm ("firewall:\n"
+     "hlt");