diff mbox series

[v7,56/74] linux-user: Split out sigaction, rt_sigaction

Message ID 20190519203726.20729-57-richard.henderson@linaro.org
State New
Headers show
Series linux-user: Split do_syscall | expand

Commit Message

Richard Henderson May 19, 2019, 8:37 p.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 linux-user/syscall-defs.h    |  10 ++
 linux-user/strace.c          |  14 ---
 linux-user/syscall-sig.inc.c | 172 +++++++++++++++++++++++++++++++++++
 linux-user/syscall.c         | 160 --------------------------------
 linux-user/strace.list       |   6 --
 5 files changed, 182 insertions(+), 180 deletions(-)

-- 
2.17.1
diff mbox series

Patch

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index cd2c127c41..b62bffeb68 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -187,6 +187,13 @@  SYSCALL_DEF(readv, ARG_DEC, ARG_PTR, ARG_DEC);
 #ifdef TARGET_NR_rmdir
 SYSCALL_DEF(rmdir, ARG_STR);
 #endif
+#if defined(TARGET_ALPHA)
+SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, ARG_DEC, ARG_PTR);
+#elif defined(TARGET_SPARC)
+SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, ARG_PTR, ARG_DEC);
+#else
+SYSCALL_DEF(rt_sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR, ARG_DEC);
+#endif
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl)
 SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
@@ -212,6 +219,9 @@  SYSCALL_DEF(shmdt, ARG_PTR);
 #if !defined(SYSCALL_TABLE) || defined(TARGET_NR_shmget)
 SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
 #endif
+#ifdef TARGET_NR_sigaction
+SYSCALL_DEF(sigaction, ARG_SIGNAL, ARG_PTR, ARG_PTR);
+#endif
 #ifdef TARGET_NR_stime
 SYSCALL_DEF(stime, ARG_PTR);
 #endif
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 787bf41307..83dd755c73 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1564,20 +1564,6 @@  print_fstat(const struct syscallname *name,
 #define print_fstat64     print_fstat
 #endif
 
-#ifdef TARGET_NR_rt_sigaction
-static void
-print_rt_sigaction(const struct syscallname *name,
-    abi_long arg0, abi_long arg1, abi_long arg2,
-    abi_long arg3, abi_long arg4, abi_long arg5)
-{
-    print_syscall_prologue(name);
-    print_signal(arg0, 0);
-    print_pointer(arg1, 0);
-    print_pointer(arg2, 1);
-    print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_rt_sigprocmask
 static void
 print_rt_sigprocmask(const struct syscallname *name,
diff --git a/linux-user/syscall-sig.inc.c b/linux-user/syscall-sig.inc.c
index a4fbcc567d..918d58878f 100644
--- a/linux-user/syscall-sig.inc.c
+++ b/linux-user/syscall-sig.inc.c
@@ -39,3 +39,175 @@  SYSCALL_IMPL(pause)
     return -TARGET_EINTR;
 }
 #endif
+
+SYSCALL_IMPL(rt_sigaction)
+{
+    abi_long ret;
+#if defined(TARGET_ALPHA)
+    /*
+     * For Alpha and SPARC this is a 5 argument syscall, with
+     * a 'restorer' parameter which must be copied into the
+     * sa_restorer field of the sigaction struct.
+     * For Alpha that 'restorer' is arg5; for SPARC it is arg4,
+     * and arg5 is the sigsetsize.
+     * Alpha also has a separate rt_sigaction struct that it uses
+     * here; SPARC uses the usual sigaction struct.
+     */
+    struct target_rt_sigaction *rt_act;
+    struct target_sigaction act, oact, *pact = NULL;
+
+    if (arg4 != sizeof(target_sigset_t)) {
+        return -TARGET_EINVAL;
+    }
+    if (arg2) {
+        if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1)) {
+            return -TARGET_EFAULT;
+        }
+        act._sa_handler = rt_act->_sa_handler;
+        act.sa_mask = rt_act->sa_mask;
+        act.sa_flags = rt_act->sa_flags;
+        act.sa_restorer = arg5;
+        unlock_user_struct(rt_act, arg2, 0);
+        pact = &act;
+    }
+    ret = get_errno(do_sigaction(arg1, pact, &oact));
+    if (!is_error(ret) && arg3) {
+        if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0)) {
+            return -TARGET_EFAULT;
+        }
+        rt_act->_sa_handler = oact._sa_handler;
+        rt_act->sa_mask = oact.sa_mask;
+        rt_act->sa_flags = oact.sa_flags;
+        unlock_user_struct(rt_act, arg3, 1);
+    }
+#else
+# ifdef TARGET_SPARC
+    target_ulong restorer = arg4;
+    target_ulong sigsetsize = arg5;
+# else
+    target_ulong sigsetsize = arg4;
+# endif
+    struct target_sigaction act, oact, *pact = NULL;
+
+    if (sigsetsize != sizeof(target_sigset_t)) {
+        return -TARGET_EINVAL;
+    }
+    if (arg2) {
+        if (!lock_user_struct(VERIFY_READ, pact, arg2, 1)) {
+            return -TARGET_EFAULT;
+        }
+        act = *pact;
+        unlock_user_struct(pact, arg2, 0);
+# ifdef TARGET_ARCH_HAS_KA_RESTORER
+        act.ka_restorer = restorer;
+# endif
+        pact = &act;
+    }
+
+    ret = get_errno(do_sigaction(arg1, pact, &oact));
+
+    if (!is_error(ret) && arg3) {
+        if (!lock_user_struct(VERIFY_WRITE, pact, arg3, 0)) {
+            return -TARGET_EFAULT;
+        }
+        *pact = oact;
+        unlock_user_struct(pact, arg3, 1);
+    }
+#endif
+    return ret;
+}
+
+#ifdef TARGET_NR_sigaction
+SYSCALL_IMPL(sigaction)
+{
+    abi_long ret;
+#if defined(TARGET_ALPHA)
+    struct target_sigaction act, oact, *pact = NULL;
+    struct target_old_sigaction *old_act;
+
+    if (arg2) {
+        if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1)) {
+            return -TARGET_EFAULT;
+        }
+        act._sa_handler = old_act->_sa_handler;
+        target_siginitset(&act.sa_mask, old_act->sa_mask);
+        act.sa_flags = old_act->sa_flags;
+        act.sa_restorer = 0;
+        unlock_user_struct(old_act, arg2, 0);
+        pact = &act;
+    }
+
+    ret = get_errno(do_sigaction(arg1, pact, &oact));
+
+    if (!is_error(ret) && arg3) {
+        if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0)) {
+            return -TARGET_EFAULT;
+        }
+        old_act->_sa_handler = oact._sa_handler;
+        old_act->sa_mask = oact.sa_mask.sig[0];
+        old_act->sa_flags = oact.sa_flags;
+        unlock_user_struct(old_act, arg3, 1);
+    }
+#elif defined(TARGET_MIPS)
+    struct target_sigaction act, oact, *pact = NULL, *old_act;
+
+    if (arg2) {
+        if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1)) {
+            return -TARGET_EFAULT;
+        }
+        act._sa_handler = old_act->_sa_handler;
+        target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
+        act.sa_flags = old_act->sa_flags;
+        unlock_user_struct(old_act, arg2, 0);
+        pact = &act;
+    }
+
+    ret = get_errno(do_sigaction(arg1, pact, &oact));
+
+    if (!is_error(ret) && arg3) {
+        if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0)) {
+            return -TARGET_EFAULT;
+        }
+        old_act->_sa_handler = oact._sa_handler;
+        old_act->sa_flags = oact.sa_flags;
+        old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
+        old_act->sa_mask.sig[1] = 0;
+        old_act->sa_mask.sig[2] = 0;
+        old_act->sa_mask.sig[3] = 0;
+        unlock_user_struct(old_act, arg3, 1);
+    }
+#else
+    struct target_old_sigaction *old_act;
+    struct target_sigaction act, oact, *pact = NULL;
+
+    if (arg2) {
+        if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1)) {
+            return -TARGET_EFAULT;
+        }
+        act._sa_handler = old_act->_sa_handler;
+        target_siginitset(&act.sa_mask, old_act->sa_mask);
+        act.sa_flags = old_act->sa_flags;
+        act.sa_restorer = old_act->sa_restorer;
+#ifdef TARGET_ARCH_HAS_KA_RESTORER
+        act.ka_restorer = 0;
+#endif
+        unlock_user_struct(old_act, arg2, 0);
+        pact = &act;
+    }
+
+    ret = get_errno(do_sigaction(arg1, pact, &oact));
+
+    if (!is_error(ret) && arg3) {
+        if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0)) {
+            return -TARGET_EFAULT;
+        }
+        old_act->_sa_handler = oact._sa_handler;
+        old_act->sa_mask = oact.sa_mask.sig[0];
+        old_act->sa_flags = oact.sa_flags;
+        old_act->sa_restorer = oact.sa_restorer;
+        unlock_user_struct(old_act, arg3, 1);
+    }
+#endif
+    return ret;
+}
+#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0e9f4fd5ae..3ef1bfb4ec 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4241,166 +4241,6 @@  static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     void *p;
 
     switch(num) {
-#ifdef TARGET_NR_sigaction
-    case TARGET_NR_sigaction:
-        {
-#if defined(TARGET_ALPHA)
-            struct target_sigaction act, oact, *pact = 0;
-            struct target_old_sigaction *old_act;
-            if (arg2) {
-                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
-                    return -TARGET_EFAULT;
-                act._sa_handler = old_act->_sa_handler;
-                target_siginitset(&act.sa_mask, old_act->sa_mask);
-                act.sa_flags = old_act->sa_flags;
-                act.sa_restorer = 0;
-                unlock_user_struct(old_act, arg2, 0);
-                pact = &act;
-            }
-            ret = get_errno(do_sigaction(arg1, pact, &oact));
-            if (!is_error(ret) && arg3) {
-                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
-                    return -TARGET_EFAULT;
-                old_act->_sa_handler = oact._sa_handler;
-                old_act->sa_mask = oact.sa_mask.sig[0];
-                old_act->sa_flags = oact.sa_flags;
-                unlock_user_struct(old_act, arg3, 1);
-            }
-#elif defined(TARGET_MIPS)
-	    struct target_sigaction act, oact, *pact, *old_act;
-
-	    if (arg2) {
-                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
-                    return -TARGET_EFAULT;
-		act._sa_handler = old_act->_sa_handler;
-		target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
-		act.sa_flags = old_act->sa_flags;
-		unlock_user_struct(old_act, arg2, 0);
-		pact = &act;
-	    } else {
-		pact = NULL;
-	    }
-
-	    ret = get_errno(do_sigaction(arg1, pact, &oact));
-
-	    if (!is_error(ret) && arg3) {
-                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
-                    return -TARGET_EFAULT;
-		old_act->_sa_handler = oact._sa_handler;
-		old_act->sa_flags = oact.sa_flags;
-		old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
-		old_act->sa_mask.sig[1] = 0;
-		old_act->sa_mask.sig[2] = 0;
-		old_act->sa_mask.sig[3] = 0;
-		unlock_user_struct(old_act, arg3, 1);
-	    }
-#else
-            struct target_old_sigaction *old_act;
-            struct target_sigaction act, oact, *pact;
-            if (arg2) {
-                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
-                    return -TARGET_EFAULT;
-                act._sa_handler = old_act->_sa_handler;
-                target_siginitset(&act.sa_mask, old_act->sa_mask);
-                act.sa_flags = old_act->sa_flags;
-                act.sa_restorer = old_act->sa_restorer;
-#ifdef TARGET_ARCH_HAS_KA_RESTORER
-                act.ka_restorer = 0;
-#endif
-                unlock_user_struct(old_act, arg2, 0);
-                pact = &act;
-            } else {
-                pact = NULL;
-            }
-            ret = get_errno(do_sigaction(arg1, pact, &oact));
-            if (!is_error(ret) && arg3) {
-                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
-                    return -TARGET_EFAULT;
-                old_act->_sa_handler = oact._sa_handler;
-                old_act->sa_mask = oact.sa_mask.sig[0];
-                old_act->sa_flags = oact.sa_flags;
-                old_act->sa_restorer = oact.sa_restorer;
-                unlock_user_struct(old_act, arg3, 1);
-            }
-#endif
-        }
-        return ret;
-#endif
-    case TARGET_NR_rt_sigaction:
-        {
-#if defined(TARGET_ALPHA)
-            /* For Alpha and SPARC this is a 5 argument syscall, with
-             * a 'restorer' parameter which must be copied into the
-             * sa_restorer field of the sigaction struct.
-             * For Alpha that 'restorer' is arg5; for SPARC it is arg4,
-             * and arg5 is the sigsetsize.
-             * Alpha also has a separate rt_sigaction struct that it uses
-             * here; SPARC uses the usual sigaction struct.
-             */
-            struct target_rt_sigaction *rt_act;
-            struct target_sigaction act, oact, *pact = 0;
-
-            if (arg4 != sizeof(target_sigset_t)) {
-                return -TARGET_EINVAL;
-            }
-            if (arg2) {
-                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
-                    return -TARGET_EFAULT;
-                act._sa_handler = rt_act->_sa_handler;
-                act.sa_mask = rt_act->sa_mask;
-                act.sa_flags = rt_act->sa_flags;
-                act.sa_restorer = arg5;
-                unlock_user_struct(rt_act, arg2, 0);
-                pact = &act;
-            }
-            ret = get_errno(do_sigaction(arg1, pact, &oact));
-            if (!is_error(ret) && arg3) {
-                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
-                    return -TARGET_EFAULT;
-                rt_act->_sa_handler = oact._sa_handler;
-                rt_act->sa_mask = oact.sa_mask;
-                rt_act->sa_flags = oact.sa_flags;
-                unlock_user_struct(rt_act, arg3, 1);
-            }
-#else
-#ifdef TARGET_SPARC
-            target_ulong restorer = arg4;
-            target_ulong sigsetsize = arg5;
-#else
-            target_ulong sigsetsize = arg4;
-#endif
-            struct target_sigaction *act;
-            struct target_sigaction *oact;
-
-            if (sigsetsize != sizeof(target_sigset_t)) {
-                return -TARGET_EINVAL;
-            }
-            if (arg2) {
-                if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) {
-                    return -TARGET_EFAULT;
-                }
-#ifdef TARGET_ARCH_HAS_KA_RESTORER
-                act->ka_restorer = restorer;
-#endif
-            } else {
-                act = NULL;
-            }
-            if (arg3) {
-                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
-                    ret = -TARGET_EFAULT;
-                    goto rt_sigaction_fail;
-                }
-            } else
-                oact = NULL;
-            ret = get_errno(do_sigaction(arg1, act, oact));
-	rt_sigaction_fail:
-            if (act)
-                unlock_user_struct(act, arg2, 0);
-            if (oact)
-                unlock_user_struct(oact, arg3, 1);
-#endif
-        }
-        return ret;
 #ifdef TARGET_NR_sgetmask /* not on alpha */
     case TARGET_NR_sgetmask:
         {
diff --git a/linux-user/strace.list b/linux-user/strace.list
index bf87a6d4cb..20a71adc21 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -926,9 +926,6 @@ 
 #ifdef TARGET_NR_rmdir
 { TARGET_NR_rmdir, "rmdir" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_rt_sigaction
-{ TARGET_NR_rt_sigaction, "rt_sigaction" , NULL, print_rt_sigaction, NULL },
-#endif
 #ifdef TARGET_NR_rt_sigpending
 { TARGET_NR_rt_sigpending, "rt_sigpending" , NULL, NULL, NULL },
 #endif
@@ -1125,9 +1122,6 @@ 
 #ifdef TARGET_NR_shutdown
 { TARGET_NR_shutdown, "shutdown" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_sigaction
-{ TARGET_NR_sigaction, "sigaction" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_sigaltstack
 { TARGET_NR_sigaltstack, "sigaltstack" , "%s(%p,%p)", NULL, NULL },
 #endif