about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/unix/sysv/linux/i386/sigaction.c74
1 files changed, 34 insertions, 40 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c
index 400e54c353..fddb22a4e0 100644
--- a/sysdeps/unix/sysv/linux/i386/sigaction.c
+++ b/sysdeps/unix/sysv/linux/i386/sigaction.c
@@ -45,6 +45,9 @@ extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *,
 int __libc_missing_rt_sigs;
 #endif
 
+static void restore_rt (void) asm ("__restore_rt");
+static void restore (void) asm ("__restore");
+
 
 /* If ACT is not NULL, change the action for SIG to *ACT.
    If OACT is not NULL, put the old action for SIG in *OACT.  */
@@ -72,10 +75,10 @@ __sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
 	{
 	  kact.k_sa_handler = act->sa_handler;
 	  memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
-	  kact.sa_flags = act->sa_flags | SA_RESTORER;
+	  kact.sa_flags = act->sa_flags;
 
-	  kact.sa_restorer = ((act->sa_flags & SA_NOMASK)
-			      ? &&restore_nomask : &&restore);
+	  kact.sa_restorer = ((act->sa_flags & SA_SIGINFO)
+			      ? &restore_rt : &restore);
 	}
 
       /* XXX The size argument hopefully will have to be changed to the
@@ -111,8 +114,7 @@ __sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
       k_newact.sa_mask = act->sa_mask.__val[0];
       k_newact.sa_flags = act->sa_flags | SA_RESTORER;
 
-      k_newact.sa_restorer = ((act->sa_flags & SA_NOMASK)
-			      ? &&restore_nomask : &&restore);
+      k_newact.sa_restorer = &restore;
     }
 
   asm volatile ("pushl %%ebx\n"
@@ -139,41 +141,33 @@ __sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
 
   return 0;
 #endif
-
- restore:
-  asm (
-#ifdef	PIC
-       "	pushl %%ebx\n"
-       "	call 0f\n"
-       "0:	popl %%ebx\n"
-       "	addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %%ebx\n"
-       "	addl $8, %%esp\n"
-       "	call __sigsetmask@PLT\n"
-       "	addl $8, %%esp\n"
-       "	popl %%ebx\n"
-#else
-       "	addl $4, %%esp\n"
-       "	call __sigsetmask\n"
-       "	addl $4, %%esp\n"
-#endif
-       "	popl %%eax\n"
-       "	popl %%ecx\n"
-       "	popl %%edx\n"
-       "	popf\n"
-       "	ret"
-       : : );
-
- restore_nomask:
-  asm ("	addl $4, %%esp\n"
-       "	popl %%eax\n"
-       "	popl %%ecx\n"
-       "	popl %%edx\n"
-       "	popf\n"
-       "	ret"
-       : : );
-
-  /* NOTREACHED */
-  return -1;
 }
 
 weak_alias (__sigaction, sigaction)
+
+#define RESTORE(name, syscall) RESTORE2 (name, syscall)
+#define RESTORE2(name, syscall) \
+asm						\
+  (						\
+   ".align 16\n"				\
+   "__" #name ":\n"					\
+   "	movl $" #syscall ", %eax\n"		\
+   "	int  $0x80"				\
+   );
+
+/* The return code for realtime-signals.  */
+RESTORE (restore_rt, __NR_rt_sigreturn)
+
+/* For the boring old signals.  */
+# undef RESTORE2
+# define RESTORE2(name, syscall) \
+asm						\
+  (						\
+   ".align 8\n"				\
+   "__" #name ":\n"					\
+   "	popl %eax\n"				\
+   "	movl $" #syscall ", %eax\n"		\
+   "	int  $0x80"				\
+   );
+
+RESTORE (restore, __NR_sigreturn)