All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall
@ 2018-08-18 19:01 Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 01/16] linux-user: Remove DEBUG Richard Henderson
                   ` (16 more replies)
  0 siblings, 17 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Version 4 continues the split into multiple files, but for
inclusion rather than separate compilation.  This allows us
to get warnings if there are mistakes in the switch statement
that looks up the structures.


r~


Richard Henderson (16):
  linux-user: Remove DEBUG
  linux-user: Split out do_syscall1
  linux-user: Relax single exit from "break"
  linux-user: Propagate goto efault to return
  linux-user: Propagate goto unimplemented_nowarn to return
  linux-user: Propagate goto unimplemented to default
  linux-user: Propagate goto fail to return
  configure: Use -Wunused-const-variable
  linux-user: Setup split syscall infrastructure
  linux-user: Split out some simple file syscalls
  linux-user: Split out preadv, pwritev, readv, writev
  linux-user: Split out pread64, pwrite64
  linux-user: Split out name_to_handle_at, open_by_handle_at
  linux-user: Split out ipc syscalls
  linux-user: Split out memory syscalls
  linux-user: Split out some process syscalls

 linux-user/syscall.h          |  200 ++
 linux-user/strace.c           |  629 +++--
 linux-user/syscall-file.inc.c |  678 ++++++
 linux-user/syscall-ipc.inc.c  | 1085 +++++++++
 linux-user/syscall-mem.inc.c  |  185 ++
 linux-user/syscall-proc.inc.c |  909 ++++++++
 linux-user/syscall.c          | 4060 +++++++--------------------------
 configure                     |    4 +-
 linux-user/strace.list        |  261 ---
 9 files changed, 4127 insertions(+), 3884 deletions(-)
 create mode 100644 linux-user/syscall.h
 create mode 100644 linux-user/syscall-file.inc.c
 create mode 100644 linux-user/syscall-ipc.inc.c
 create mode 100644 linux-user/syscall-mem.inc.c
 create mode 100644 linux-user/syscall-proc.inc.c

-- 
2.17.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 01/16] linux-user: Remove DEBUG
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 02/16] linux-user: Split out do_syscall1 Richard Henderson
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

This is redundant with both -strace and actual tracing.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bb42a225eb..6cd9b33a0d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -163,7 +163,6 @@
  * (The one remaining unallocated bit is 0x1000 which used to be CLONE_PID.)
  */
 
-//#define DEBUG
 /* Define DEBUG_ERESTARTSYS to force every syscall to be restarted
  * once. This exercises the codepaths for restart.
  */
@@ -5778,9 +5777,6 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
         ie++;
     }
     arg_type = ie->arg_type;
-#if defined(DEBUG)
-    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
-#endif
     if (ie->do_ioctl) {
         return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
     } else if (!ie->host_cmd) {
@@ -8026,9 +8022,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     }
 #endif
 
-#ifdef DEBUG
-    gemu_log("syscall %d", num);
-#endif
     trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
     if(do_strace)
         print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
@@ -12843,9 +12836,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
     }
 fail:
-#ifdef DEBUG
-    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
-#endif
     if(do_strace)
         print_syscall_ret(num, ret);
     trace_guest_user_syscall_ret(cpu, num, ret);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 02/16] linux-user: Split out do_syscall1
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 01/16] linux-user: Remove DEBUG Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 03/16] linux-user: Relax single exit from "break" Richard Henderson
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

There was supposed to be a single point of return for do_syscall
so that tracing works properly.  However, there are a few bugs
in that area.  It is significantly simpler to simply split out
an inner function to enforce this.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.c | 77 +++++++++++++++++++++++++++-----------------
 1 file changed, 48 insertions(+), 29 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 6cd9b33a0d..dddd386ec4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7986,13 +7986,15 @@ static int host_to_target_cpu_mask(const unsigned long *host_mask,
     return 0;
 }
 
-/* do_syscall() should always have a single exit point at the end so
-   that actions, such as logging of syscall results, can be performed.
-   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
-abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
-                    abi_long arg2, abi_long arg3, abi_long arg4,
-                    abi_long arg5, abi_long arg6, abi_long arg7,
-                    abi_long arg8)
+/* This is an internal helper for do_syscall so that it is easier
+ * to have a single return point, so that actions, such as logging
+ * of syscall results, can be performed.
+ * All errnos that do_syscall() returns must be -TARGET_<errcode>.
+ */
+static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
+                            abi_long arg2, abi_long arg3, abi_long arg4,
+                            abi_long arg5, abi_long arg6, abi_long arg7,
+                            abi_long arg8)
 {
     CPUState *cpu = ENV_GET_CPU(cpu_env);
     abi_long ret;
@@ -8007,25 +8009,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
     void *p;
 
-#if defined(DEBUG_ERESTARTSYS)
-    /* Debug-only code for exercising the syscall-restart code paths
-     * in the per-architecture cpu main loops: restart every syscall
-     * the guest makes once before letting it through.
-     */
-    {
-        static int flag;
-
-        flag = !flag;
-        if (flag) {
-            return -TARGET_ERESTARTSYS;
-        }
-    }
-#endif
-
-    trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
-    if(do_strace)
-        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
-
     switch(num) {
     case TARGET_NR_exit:
         /* In old applications this may be used to implement _exit(2).
@@ -12836,11 +12819,47 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
     }
 fail:
-    if(do_strace)
-        print_syscall_ret(num, ret);
-    trace_guest_user_syscall_ret(cpu, num, ret);
     return ret;
 efault:
     ret = -TARGET_EFAULT;
     goto fail;
 }
+
+abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
+                    abi_long arg2, abi_long arg3, abi_long arg4,
+                    abi_long arg5, abi_long arg6, abi_long arg7,
+                    abi_long arg8)
+{
+    CPUState *cpu = ENV_GET_CPU(cpu_env);
+    abi_long ret;
+
+#ifdef DEBUG_ERESTARTSYS
+    /* Debug-only code for exercising the syscall-restart code paths
+     * in the per-architecture cpu main loops: restart every syscall
+     * the guest makes once before letting it through.
+     */
+    {
+        static bool flag;
+        flag = !flag;
+        if (flag) {
+            return -TARGET_ERESTARTSYS;
+        }
+    }
+#endif
+
+    trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4,
+                             arg5, arg6, arg7, arg8);
+
+    if (unlikely(do_strace)) {
+        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
+        ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4,
+                          arg5, arg6, arg7, arg8);
+        print_syscall_ret(num, ret);
+    } else {
+        ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4,
+                          arg5, arg6, arg7, arg8);
+    }
+
+    trace_guest_user_syscall_ret(cpu, num, ret);
+    return ret;
+}
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 03/16] linux-user: Relax single exit from "break"
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 01/16] linux-user: Remove DEBUG Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 02/16] linux-user: Split out do_syscall1 Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-21 18:45   ` Philippe Mathieu-Daudé
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 04/16] linux-user: Propagate goto efault to return Richard Henderson
                   ` (13 subsequent siblings)
  16 siblings, 1 reply; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Transform outermost "break" to "return ret".  If the immediately
preceeding statement was an assignment to ret, return the value
directly.

Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.c | 972 +++++++++++++++++--------------------------
 1 file changed, 390 insertions(+), 582 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index dddd386ec4..f92a24f32a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8017,8 +8017,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
            Do thread termination if we have more then one thread.  */
 
         if (block_signals()) {
-            ret = -TARGET_ERESTARTSYS;
-            break;
+            return -TARGET_ERESTARTSYS;
         }
 
         cpu_list_lock();
@@ -8047,12 +8046,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         cpu_list_unlock();
         preexit_cleanup(cpu_env, arg1);
         _exit(arg1);
-        ret = 0; /* avoid warning */
-        break;
+        return 0; /* avoid warning */
     case TARGET_NR_read:
-        if (arg3 == 0)
-            ret = 0;
-        else {
+        if (arg3 == 0) {
+            return 0;
+        } else {
             if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
                 goto efault;
             ret = get_errno(safe_read(arg1, p, arg3));
@@ -8062,7 +8060,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
             unlock_user(p, arg2, ret);
         }
-        break;
+        return ret;
     case TARGET_NR_write:
         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
             goto efault;
@@ -8078,7 +8076,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(safe_write(arg1, p, arg3));
         }
         unlock_user(p, arg2, 0);
-        break;
+        return ret;
+
 #ifdef TARGET_NR_open
     case TARGET_NR_open:
         if (!(p = lock_user_string(arg1)))
@@ -8088,7 +8087,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                                   arg3));
         fd_trans_unregister(ret);
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
     case TARGET_NR_openat:
         if (!(p = lock_user_string(arg2)))
@@ -8098,29 +8097,27 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                                   arg4));
         fd_trans_unregister(ret);
         unlock_user(p, arg2, 0);
-        break;
+        return ret;
 #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
     case TARGET_NR_name_to_handle_at:
         ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5);
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
     case TARGET_NR_open_by_handle_at:
         ret = do_open_by_handle_at(arg1, arg2, arg3);
         fd_trans_unregister(ret);
-        break;
+        return ret;
 #endif
     case TARGET_NR_close:
         fd_trans_unregister(arg1);
-        ret = get_errno(close(arg1));
-        break;
+        return get_errno(close(arg1));
+
     case TARGET_NR_brk:
-        ret = do_brk(arg1);
-        break;
+        return do_brk(arg1);
 #ifdef TARGET_NR_fork
     case TARGET_NR_fork:
-        ret = get_errno(do_fork(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0));
-        break;
+        return get_errno(do_fork(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0));
 #endif
 #ifdef TARGET_NR_waitpid
     case TARGET_NR_waitpid:
@@ -8131,7 +8128,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 && put_user_s32(host_to_target_waitstatus(status), arg2))
                 goto efault;
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_waitid
     case TARGET_NR_waitid:
@@ -8146,7 +8143,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user(p, arg3, sizeof(target_siginfo_t));
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_creat /* not on alpha */
     case TARGET_NR_creat:
@@ -8155,7 +8152,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(creat(p, arg2));
         fd_trans_unregister(ret);
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_link
     case TARGET_NR_link:
@@ -8170,7 +8167,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(p2, arg2, 0);
             unlock_user(p, arg1, 0);
         }
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_linkat)
     case TARGET_NR_linkat:
@@ -8187,7 +8184,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(p, arg2, 0);
             unlock_user(p2, arg4, 0);
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_unlink
     case TARGET_NR_unlink:
@@ -8195,7 +8192,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(unlink(p));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_unlinkat)
     case TARGET_NR_unlinkat:
@@ -8203,7 +8200,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(unlinkat(arg1, p, arg3));
         unlock_user(p, arg2, 0);
-        break;
+        return ret;
 #endif
     case TARGET_NR_execve:
         {
@@ -8301,13 +8298,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             g_free(argp);
             g_free(envp);
         }
-        break;
+        return ret;
     case TARGET_NR_chdir:
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(chdir(p));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #ifdef TARGET_NR_time
     case TARGET_NR_time:
         {
@@ -8318,7 +8315,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 && put_user_sal(host_time, arg1))
                 goto efault;
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_mknod
     case TARGET_NR_mknod:
@@ -8326,7 +8323,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(mknod(p, arg2, arg3));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_mknodat)
     case TARGET_NR_mknodat:
@@ -8334,7 +8331,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(mknodat(arg1, p, arg3, arg4));
         unlock_user(p, arg2, 0);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_chmod
     case TARGET_NR_chmod:
@@ -8342,7 +8339,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(chmod(p, arg2));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_break
     case TARGET_NR_break:
@@ -8354,20 +8351,17 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_lseek
     case TARGET_NR_lseek:
-        ret = get_errno(lseek(arg1, arg2, arg3));
-        break;
+        return get_errno(lseek(arg1, arg2, arg3));
 #endif
 #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
     /* Alpha specific */
     case TARGET_NR_getxpid:
         ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
-        ret = get_errno(getpid());
-        break;
+        return get_errno(getpid());
 #endif
 #ifdef TARGET_NR_getpid
     case TARGET_NR_getpid:
-        ret = get_errno(getpid());
-        break;
+        return get_errno(getpid());
 #endif
     case TARGET_NR_mount:
         {
@@ -8423,14 +8417,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user(p3, arg3, 0);
             }
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_umount
     case TARGET_NR_umount:
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(umount(p));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_stime /* not on alpha */
     case TARGET_NR_stime:
@@ -8438,16 +8432,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             time_t host_time;
             if (get_user_sal(host_time, arg1))
                 goto efault;
-            ret = get_errno(stime(&host_time));
+            return get_errno(stime(&host_time));
         }
-        break;
 #endif
     case TARGET_NR_ptrace:
         goto unimplemented;
 #ifdef TARGET_NR_alarm /* not on alpha */
     case TARGET_NR_alarm:
-        ret = alarm(arg1);
-        break;
+        return alarm(arg1);
 #endif
 #ifdef TARGET_NR_oldfstat
     case TARGET_NR_oldfstat:
@@ -8458,8 +8450,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (!block_signals()) {
             sigsuspend(&((TaskState *)cpu->opaque)->signal_mask);
         }
-        ret = -TARGET_EINTR;
-        break;
+        return -TARGET_EINTR;
 #endif
 #ifdef TARGET_NR_utime
     case TARGET_NR_utime:
@@ -8481,7 +8472,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(utime(p, host_tbuf));
             unlock_user(p, arg1, 0);
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_utimes
     case TARGET_NR_utimes:
@@ -8501,7 +8492,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(utimes(p, tvp));
             unlock_user(p, arg1, 0);
         }
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_futimesat)
     case TARGET_NR_futimesat:
@@ -8521,7 +8512,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(futimesat(arg1, path(p), tvp));
             unlock_user(p, arg2, 0);
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_stty
     case TARGET_NR_stty:
@@ -8537,7 +8528,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(access(path(p), arg2));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
     case TARGET_NR_faccessat:
@@ -8545,12 +8536,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(faccessat(arg1, p, arg3, 0));
         unlock_user(p, arg2, 0);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_nice /* not on alpha */
     case TARGET_NR_nice:
-        ret = get_errno(nice(arg1));
-        break;
+        return get_errno(nice(arg1));
 #endif
 #ifdef TARGET_NR_ftime
     case TARGET_NR_ftime:
@@ -8558,16 +8548,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
     case TARGET_NR_sync:
         sync();
-        ret = 0;
-        break;
+        return 0;
 #if defined(TARGET_NR_syncfs) && defined(CONFIG_SYNCFS)
     case TARGET_NR_syncfs:
-        ret = get_errno(syncfs(arg1));
-        break;
+        return get_errno(syncfs(arg1));
 #endif
     case TARGET_NR_kill:
-        ret = get_errno(safe_kill(arg1, target_to_host_signal(arg2)));
-        break;
+        return get_errno(safe_kill(arg1, target_to_host_signal(arg2)));
 #ifdef TARGET_NR_rename
     case TARGET_NR_rename:
         {
@@ -8581,7 +8568,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(p2, arg2, 0);
             unlock_user(p, arg1, 0);
         }
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_renameat)
     case TARGET_NR_renameat:
@@ -8596,7 +8583,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(p2, arg4, 0);
             unlock_user(p, arg2, 0);
         }
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_renameat2)
     case TARGET_NR_renameat2:
@@ -8612,7 +8599,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(p2, arg4, 0);
             unlock_user(p, arg2, 0);
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_mkdir
     case TARGET_NR_mkdir:
@@ -8620,7 +8607,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(mkdir(p, arg2));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_mkdirat)
     case TARGET_NR_mkdirat:
@@ -8628,7 +8615,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(mkdirat(arg1, p, arg3));
         unlock_user(p, arg2, 0);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_rmdir
     case TARGET_NR_rmdir:
@@ -8636,24 +8623,22 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(rmdir(p));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
     case TARGET_NR_dup:
         ret = get_errno(dup(arg1));
         if (ret >= 0) {
             fd_trans_dup(arg1, ret);
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_pipe
     case TARGET_NR_pipe:
-        ret = do_pipe(cpu_env, arg1, 0, 0);
-        break;
+        return do_pipe(cpu_env, arg1, 0, 0);
 #endif
 #ifdef TARGET_NR_pipe2
     case TARGET_NR_pipe2:
-        ret = do_pipe(cpu_env, arg1,
-                      target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
-        break;
+        return do_pipe(cpu_env, arg1,
+                       target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
 #endif
     case TARGET_NR_times:
         {
@@ -8672,7 +8657,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             if (!is_error(ret))
                 ret = host_to_target_clock_t(ret);
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_prof
     case TARGET_NR_prof:
         goto unimplemented;
@@ -8690,34 +8675,31 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(acct(path(p)));
             unlock_user(p, arg1, 0);
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_umount2
     case TARGET_NR_umount2:
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(umount2(p, arg2));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_lock
     case TARGET_NR_lock:
         goto unimplemented;
 #endif
     case TARGET_NR_ioctl:
-        ret = do_ioctl(arg1, arg2, arg3);
-        break;
+        return do_ioctl(arg1, arg2, arg3);
 #ifdef TARGET_NR_fcntl
     case TARGET_NR_fcntl:
-        ret = do_fcntl(arg1, arg2, arg3);
-        break;
+        return do_fcntl(arg1, arg2, arg3);
 #endif
 #ifdef TARGET_NR_mpx
     case TARGET_NR_mpx:
         goto unimplemented;
 #endif
     case TARGET_NR_setpgid:
-        ret = get_errno(setpgid(arg1, arg2));
-        break;
+        return get_errno(setpgid(arg1, arg2));
 #ifdef TARGET_NR_ulimit
     case TARGET_NR_ulimit:
         goto unimplemented;
@@ -8727,14 +8709,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         goto unimplemented;
 #endif
     case TARGET_NR_umask:
-        ret = get_errno(umask(arg1));
-        break;
+        return get_errno(umask(arg1));
     case TARGET_NR_chroot:
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(chroot(p));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #ifdef TARGET_NR_ustat
     case TARGET_NR_ustat:
         goto unimplemented;
@@ -8745,7 +8726,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (ret >= 0) {
             fd_trans_dup(arg1, arg2);
         }
-        break;
+        return ret;
 #endif
 #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
     case TARGET_NR_dup3:
@@ -8760,22 +8741,19 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (ret >= 0) {
             fd_trans_dup(arg1, arg2);
         }
-        break;
+        return ret;
     }
 #endif
 #ifdef TARGET_NR_getppid /* not on alpha */
     case TARGET_NR_getppid:
-        ret = get_errno(getppid());
-        break;
+        return get_errno(getppid());
 #endif
 #ifdef TARGET_NR_getpgrp
     case TARGET_NR_getpgrp:
-        ret = get_errno(getpgrp());
-        break;
+        return get_errno(getpgrp());
 #endif
     case TARGET_NR_setsid:
-        ret = get_errno(setsid());
-        break;
+        return get_errno(setsid());
 #ifdef TARGET_NR_sigaction
     case TARGET_NR_sigaction:
         {
@@ -8859,7 +8837,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
 #endif
         }
-        break;
+        return ret;
 #endif
     case TARGET_NR_rt_sigaction:
         {
@@ -8876,8 +8854,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct target_sigaction act, oact, *pact = 0;
 
             if (arg4 != sizeof(target_sigset_t)) {
-                ret = -TARGET_EINVAL;
-                break;
+                return -TARGET_EINVAL;
             }
             if (arg2) {
                 if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
@@ -8909,8 +8886,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct target_sigaction *oact;
 
             if (sigsetsize != sizeof(target_sigset_t)) {
-                ret = -TARGET_EINVAL;
-                break;
+                return -TARGET_EINVAL;
             }
             if (arg2) {
                 if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) {
@@ -8937,7 +8913,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user_struct(oact, arg3, 1);
 #endif
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_sgetmask /* not on alpha */
     case TARGET_NR_sgetmask:
         {
@@ -8949,7 +8925,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = target_set;
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_ssetmask /* not on alpha */
     case TARGET_NR_ssetmask:
@@ -8963,7 +8939,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = target_set;
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_sigprocmask
     case TARGET_NR_sigprocmask:
@@ -9033,7 +9009,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
 #endif
         }
-        break;
+        return ret;
 #endif
     case TARGET_NR_rt_sigprocmask:
         {
@@ -9041,8 +9017,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             sigset_t set, oldset, *set_ptr;
 
             if (arg4 != sizeof(target_sigset_t)) {
-                ret = -TARGET_EINVAL;
-                break;
+                return -TARGET_EINVAL;
             }
 
             if (arg2) {
@@ -9077,7 +9052,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user(p, arg3, sizeof(target_sigset_t));
             }
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_sigpending
     case TARGET_NR_sigpending:
         {
@@ -9090,7 +9065,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user(p, arg1, sizeof(target_sigset_t));
             }
         }
-        break;
+        return ret;
 #endif
     case TARGET_NR_rt_sigpending:
         {
@@ -9102,8 +9077,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
              * the old_sigset_t is smaller in size.
              */
             if (arg2 > sizeof(target_sigset_t)) {
-                ret = -TARGET_EINVAL;
-                break;
+                return -TARGET_EINVAL;
             }
 
             ret = get_errno(sigpending(&set));
@@ -9114,7 +9088,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user(p, arg1, sizeof(target_sigset_t));
             }
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_sigsuspend
     case TARGET_NR_sigsuspend:
         {
@@ -9134,15 +9108,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ts->in_sigsuspend = 1;
             }
         }
-        break;
+        return ret;
 #endif
     case TARGET_NR_rt_sigsuspend:
         {
             TaskState *ts = cpu->opaque;
 
             if (arg2 != sizeof(target_sigset_t)) {
-                ret = -TARGET_EINVAL;
-                break;
+                return -TARGET_EINVAL;
             }
             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
                 goto efault;
@@ -9154,7 +9127,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ts->in_sigsuspend = 1;
             }
         }
-        break;
+        return ret;
     case TARGET_NR_rt_sigtimedwait:
         {
             sigset_t set;
@@ -9162,8 +9135,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             siginfo_t uinfo;
 
             if (arg4 != sizeof(target_sigset_t)) {
-                ret = -TARGET_EINVAL;
-                break;
+                return -TARGET_EINVAL;
             }
 
             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
@@ -9191,7 +9163,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = host_to_target_signal(ret);
             }
         }
-        break;
+        return ret;
     case TARGET_NR_rt_sigqueueinfo:
         {
             siginfo_t uinfo;
@@ -9204,7 +9176,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(p, arg3, 0);
             ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
         }
-        break;
+        return ret;
     case TARGET_NR_rt_tgsigqueueinfo:
         {
             siginfo_t uinfo;
@@ -9217,29 +9189,25 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(p, arg4, 0);
             ret = get_errno(sys_rt_tgsigqueueinfo(arg1, arg2, arg3, &uinfo));
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_sigreturn
     case TARGET_NR_sigreturn:
         if (block_signals()) {
-            ret = -TARGET_ERESTARTSYS;
-        } else {
-            ret = do_sigreturn(cpu_env);
+            return -TARGET_ERESTARTSYS;
         }
-        break;
+        return do_sigreturn(cpu_env);
 #endif
     case TARGET_NR_rt_sigreturn:
         if (block_signals()) {
-            ret = -TARGET_ERESTARTSYS;
-        } else {
-            ret = do_rt_sigreturn(cpu_env);
+            return -TARGET_ERESTARTSYS;
         }
-        break;
+        return do_rt_sigreturn(cpu_env);
     case TARGET_NR_sethostname:
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(sethostname(p, arg2));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #ifdef TARGET_NR_setrlimit
     case TARGET_NR_setrlimit:
         {
@@ -9251,9 +9219,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
             rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
             unlock_user_struct(target_rlim, arg2, 0);
-            ret = get_errno(setrlimit(resource, &rlim));
+            return get_errno(setrlimit(resource, &rlim));
         }
-        break;
 #endif
 #ifdef TARGET_NR_getrlimit
     case TARGET_NR_getrlimit:
@@ -9271,7 +9238,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user_struct(target_rlim, arg2, 1);
             }
         }
-        break;
+        return ret;
 #endif
     case TARGET_NR_getrusage:
         {
@@ -9281,7 +9248,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = host_to_target_rusage(arg2, &rusage);
             }
         }
-        break;
+        return ret;
     case TARGET_NR_gettimeofday:
         {
             struct timeval tv;
@@ -9291,7 +9258,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     goto efault;
             }
         }
-        break;
+        return ret;
     case TARGET_NR_settimeofday:
         {
             struct timeval tv, *ptv = NULL;
@@ -9311,9 +9278,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ptz = &tz;
             }
 
-            ret = get_errno(settimeofday(ptv, ptz));
+            return get_errno(settimeofday(ptv, ptz));
         }
-        break;
 #if defined(TARGET_NR_select)
     case TARGET_NR_select:
 #if defined(TARGET_WANT_NI_OLD_SELECT)
@@ -9326,7 +9292,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #else
         ret = do_select(arg1, arg2, arg3, arg4, arg5);
 #endif
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_pselect6
     case TARGET_NR_pselect6:
@@ -9430,7 +9396,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     goto efault;
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_symlink
     case TARGET_NR_symlink:
@@ -9445,7 +9411,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(p2, arg2, 0);
             unlock_user(p, arg1, 0);
         }
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_symlinkat)
     case TARGET_NR_symlinkat:
@@ -9460,7 +9426,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(p2, arg3, 0);
             unlock_user(p, arg1, 0);
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_oldlstat
     case TARGET_NR_oldlstat:
@@ -9496,7 +9462,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(p2, arg2, ret);
             unlock_user(p, arg1, 0);
         }
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_readlinkat)
     case TARGET_NR_readlinkat:
@@ -9517,7 +9483,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(p2, arg3, ret);
             unlock_user(p, arg2, 0);
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_uselib
     case TARGET_NR_uselib:
@@ -9529,7 +9495,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(swapon(p, arg2));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
     case TARGET_NR_reboot:
         if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
@@ -9543,7 +9509,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         } else {
            ret = get_errno(reboot(arg1, arg2, arg3, NULL));
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_readdir
     case TARGET_NR_readdir:
         goto unimplemented;
@@ -9576,22 +9542,20 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                                     arg5,
                                     arg6));
 #endif
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_mmap2
     case TARGET_NR_mmap2:
 #ifndef MMAP_SHIFT
 #define MMAP_SHIFT 12
 #endif
-        ret = get_errno(target_mmap(arg1, arg2, arg3,
-                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
-                                    arg5,
-                                    arg6 << MMAP_SHIFT));
-        break;
+        ret = target_mmap(arg1, arg2, arg3,
+                          target_to_host_bitmask(arg4, mmap_flags_tbl),
+                          arg5, arg6 << MMAP_SHIFT);
+        return get_errno(ret);
 #endif
     case TARGET_NR_munmap:
-        ret = get_errno(target_munmap(arg1, arg2));
-        break;
+        return get_errno(target_munmap(arg1, arg2));
     case TARGET_NR_mprotect:
         {
             TaskState *ts = cpu->opaque;
@@ -9604,38 +9568,31 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 arg1 = ts->info->stack_limit;
             }
         }
-        ret = get_errno(target_mprotect(arg1, arg2, arg3));
-        break;
+        return get_errno(target_mprotect(arg1, arg2, arg3));
 #ifdef TARGET_NR_mremap
     case TARGET_NR_mremap:
-        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
-        break;
+        return get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
 #endif
         /* ??? msync/mlock/munlock are broken for softmmu.  */
 #ifdef TARGET_NR_msync
     case TARGET_NR_msync:
-        ret = get_errno(msync(g2h(arg1), arg2, arg3));
-        break;
+        return get_errno(msync(g2h(arg1), arg2, arg3));
 #endif
 #ifdef TARGET_NR_mlock
     case TARGET_NR_mlock:
-        ret = get_errno(mlock(g2h(arg1), arg2));
-        break;
+        return get_errno(mlock(g2h(arg1), arg2));
 #endif
 #ifdef TARGET_NR_munlock
     case TARGET_NR_munlock:
-        ret = get_errno(munlock(g2h(arg1), arg2));
-        break;
+        return get_errno(munlock(g2h(arg1), arg2));
 #endif
 #ifdef TARGET_NR_mlockall
     case TARGET_NR_mlockall:
-        ret = get_errno(mlockall(target_to_host_mlockall_arg(arg1)));
-        break;
+        return get_errno(mlockall(target_to_host_mlockall_arg(arg1)));
 #endif
 #ifdef TARGET_NR_munlockall
     case TARGET_NR_munlockall:
-        ret = get_errno(munlockall());
-        break;
+        return get_errno(munlockall());
 #endif
 #ifdef TARGET_NR_truncate
     case TARGET_NR_truncate:
@@ -9643,23 +9600,21 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(truncate(p, arg2));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_ftruncate
     case TARGET_NR_ftruncate:
-        ret = get_errno(ftruncate(arg1, arg2));
-        break;
+        return get_errno(ftruncate(arg1, arg2));
 #endif
     case TARGET_NR_fchmod:
-        ret = get_errno(fchmod(arg1, arg2));
-        break;
+        return get_errno(fchmod(arg1, arg2));
 #if defined(TARGET_NR_fchmodat)
     case TARGET_NR_fchmodat:
         if (!(p = lock_user_string(arg2)))
             goto efault;
         ret = get_errno(fchmodat(arg1, p, arg3, 0));
         unlock_user(p, arg2, 0);
-        break;
+        return ret;
 #endif
     case TARGET_NR_getpriority:
         /* Note that negative values are valid for getpriority, so we must
@@ -9667,8 +9622,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         errno = 0;
         ret = getpriority(arg1, arg2);
         if (ret == -1 && errno != 0) {
-            ret = -host_to_target_errno(errno);
-            break;
+            return -host_to_target_errno(errno);
         }
 #ifdef TARGET_ALPHA
         /* Return value is the unbiased priority.  Signal no error.  */
@@ -9677,10 +9631,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         /* Return value is a biased priority to avoid negative numbers.  */
         ret = 20 - ret;
 #endif
-        break;
+        return ret;
     case TARGET_NR_setpriority:
-        ret = get_errno(setpriority(arg1, arg2, arg3));
-        break;
+        return get_errno(setpriority(arg1, arg2, arg3));
 #ifdef TARGET_NR_profil
     case TARGET_NR_profil:
         goto unimplemented;
@@ -9716,7 +9669,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
             unlock_user_struct(target_stfs, arg2, 1);
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_fstatfs
     case TARGET_NR_fstatfs:
@@ -9749,7 +9702,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
             unlock_user_struct(target_stfs, arg3, 1);
         }
-        break;
+        return ret;
     case TARGET_NR_fstatfs64:
         ret = get_errno(fstatfs(arg1, &stfs));
         goto convert_statfs64;
@@ -9760,91 +9713,73 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_socketcall
     case TARGET_NR_socketcall:
-        ret = do_socketcall(arg1, arg2);
-        break;
+        return do_socketcall(arg1, arg2);
 #endif
 #ifdef TARGET_NR_accept
     case TARGET_NR_accept:
-        ret = do_accept4(arg1, arg2, arg3, 0);
-        break;
+        return do_accept4(arg1, arg2, arg3, 0);
 #endif
 #ifdef TARGET_NR_accept4
     case TARGET_NR_accept4:
-        ret = do_accept4(arg1, arg2, arg3, arg4);
-        break;
+        return do_accept4(arg1, arg2, arg3, arg4);
 #endif
 #ifdef TARGET_NR_bind
     case TARGET_NR_bind:
-        ret = do_bind(arg1, arg2, arg3);
-        break;
+        return do_bind(arg1, arg2, arg3);
 #endif
 #ifdef TARGET_NR_connect
     case TARGET_NR_connect:
-        ret = do_connect(arg1, arg2, arg3);
-        break;
+        return do_connect(arg1, arg2, arg3);
 #endif
 #ifdef TARGET_NR_getpeername
     case TARGET_NR_getpeername:
-        ret = do_getpeername(arg1, arg2, arg3);
-        break;
+        return do_getpeername(arg1, arg2, arg3);
 #endif
 #ifdef TARGET_NR_getsockname
     case TARGET_NR_getsockname:
-        ret = do_getsockname(arg1, arg2, arg3);
-        break;
+        return do_getsockname(arg1, arg2, arg3);
 #endif
 #ifdef TARGET_NR_getsockopt
     case TARGET_NR_getsockopt:
-        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
-        break;
+        return do_getsockopt(arg1, arg2, arg3, arg4, arg5);
 #endif
 #ifdef TARGET_NR_listen
     case TARGET_NR_listen:
-        ret = get_errno(listen(arg1, arg2));
-        break;
+        return get_errno(listen(arg1, arg2));
 #endif
 #ifdef TARGET_NR_recv
     case TARGET_NR_recv:
-        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
-        break;
+        return do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
 #endif
 #ifdef TARGET_NR_recvfrom
     case TARGET_NR_recvfrom:
-        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
-        break;
+        return do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
 #endif
 #ifdef TARGET_NR_recvmsg
     case TARGET_NR_recvmsg:
-        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
-        break;
+        return do_sendrecvmsg(arg1, arg2, arg3, 0);
 #endif
 #ifdef TARGET_NR_send
     case TARGET_NR_send:
-        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
-        break;
+        return do_sendto(arg1, arg2, arg3, arg4, 0, 0);
 #endif
 #ifdef TARGET_NR_sendmsg
     case TARGET_NR_sendmsg:
-        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
-        break;
+        return do_sendrecvmsg(arg1, arg2, arg3, 1);
 #endif
 #ifdef TARGET_NR_sendmmsg
     case TARGET_NR_sendmmsg:
-        ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1);
-        break;
+        return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1);
     case TARGET_NR_recvmmsg:
-        ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0);
-        break;
+        return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0);
 #endif
 #ifdef TARGET_NR_sendto
     case TARGET_NR_sendto:
-        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
-        break;
+        return do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
 #endif
 #ifdef TARGET_NR_shutdown
     case TARGET_NR_shutdown:
-        ret = get_errno(shutdown(arg1, arg2));
-        break;
+        return get_errno(shutdown(arg1, arg2));
 #endif
 #if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
     case TARGET_NR_getrandom:
@@ -9854,22 +9789,19 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         }
         ret = get_errno(getrandom(p, arg2, arg3));
         unlock_user(p, arg1, ret);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_socket
     case TARGET_NR_socket:
-        ret = do_socket(arg1, arg2, arg3);
-        break;
+        return do_socket(arg1, arg2, arg3);
 #endif
 #ifdef TARGET_NR_socketpair
     case TARGET_NR_socketpair:
-        ret = do_socketpair(arg1, arg2, arg3, arg4);
-        break;
+        return do_socketpair(arg1, arg2, arg3, arg4);
 #endif
 #ifdef TARGET_NR_setsockopt
     case TARGET_NR_setsockopt:
-        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
-        break;
+        return do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
 #endif
 #if defined(TARGET_NR_syslog)
     case TARGET_NR_syslog:
@@ -9885,10 +9817,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             case TARGET_SYSLOG_ACTION_CONSOLE_LEVEL: /* Set messages level */
             case TARGET_SYSLOG_ACTION_SIZE_UNREAD:   /* Number of chars */
             case TARGET_SYSLOG_ACTION_SIZE_BUFFER:   /* Size of the buffer */
-                {
-                    ret = get_errno(sys_syslog((int)arg1, NULL, (int)arg3));
-                }
-                break;
+                return get_errno(sys_syslog((int)arg1, NULL, (int)arg3));
             case TARGET_SYSLOG_ACTION_READ:          /* Read from log */
             case TARGET_SYSLOG_ACTION_READ_CLEAR:    /* Read/clear msgs */
             case TARGET_SYSLOG_ACTION_READ_ALL:      /* Read last messages */
@@ -9897,9 +9826,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     if (len < 0) {
                         goto fail;
                     }
-                    ret = 0;
                     if (len == 0) {
-                        break;
+                        return 0;
                     }
                     p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
                     if (!p) {
@@ -9909,10 +9837,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
                     unlock_user(p, arg2, arg3);
                 }
-                break;
+                return ret;
             default:
-                ret = -EINVAL;
-                break;
+                return -TARGET_EINVAL;
             }
         }
         break;
@@ -9939,7 +9866,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     goto efault;
             }
         }
-        break;
+        return ret;
     case TARGET_NR_getitimer:
         {
             struct itimerval value;
@@ -9953,7 +9880,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     goto efault;
             }
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_stat
     case TARGET_NR_stat:
         if (!(p = lock_user_string(arg1)))
@@ -9999,7 +9926,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user_struct(target_st, arg2, 1);
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_olduname
     case TARGET_NR_olduname:
@@ -10010,17 +9937,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         goto unimplemented;
 #endif
     case TARGET_NR_vhangup:
-        ret = get_errno(vhangup());
-        break;
+        return get_errno(vhangup());
 #ifdef TARGET_NR_idle
     case TARGET_NR_idle:
         goto unimplemented;
 #endif
 #ifdef TARGET_NR_syscall
     case TARGET_NR_syscall:
-        ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
-                         arg6, arg7, arg8, 0);
-        break;
+        return do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
+                          arg6, arg7, arg8, 0);
 #endif
     case TARGET_NR_wait4:
         {
@@ -10048,14 +9973,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 }
             }
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_swapoff
     case TARGET_NR_swapoff:
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(swapoff(p));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
     case TARGET_NR_sysinfo:
         {
@@ -10083,70 +10008,57 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user_struct(target_value, arg1, 1);
             }
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_ipc
     case TARGET_NR_ipc:
-        ret = do_ipc(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
-        break;
+        return do_ipc(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
 #endif
 #ifdef TARGET_NR_semget
     case TARGET_NR_semget:
-        ret = get_errno(semget(arg1, arg2, arg3));
-        break;
+        return get_errno(semget(arg1, arg2, arg3));
 #endif
 #ifdef TARGET_NR_semop
     case TARGET_NR_semop:
-        ret = do_semop(arg1, arg2, arg3);
-        break;
+        return do_semop(arg1, arg2, arg3);
 #endif
 #ifdef TARGET_NR_semctl
     case TARGET_NR_semctl:
-        ret = do_semctl(arg1, arg2, arg3, arg4);
-        break;
+        return do_semctl(arg1, arg2, arg3, arg4);
 #endif
 #ifdef TARGET_NR_msgctl
     case TARGET_NR_msgctl:
-        ret = do_msgctl(arg1, arg2, arg3);
-        break;
+        return do_msgctl(arg1, arg2, arg3);
 #endif
 #ifdef TARGET_NR_msgget
     case TARGET_NR_msgget:
-        ret = get_errno(msgget(arg1, arg2));
-        break;
+        return get_errno(msgget(arg1, arg2));
 #endif
 #ifdef TARGET_NR_msgrcv
     case TARGET_NR_msgrcv:
-        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
-        break;
+        return do_msgrcv(arg1, arg2, arg3, arg4, arg5);
 #endif
 #ifdef TARGET_NR_msgsnd
     case TARGET_NR_msgsnd:
-        ret = do_msgsnd(arg1, arg2, arg3, arg4);
-        break;
+        return do_msgsnd(arg1, arg2, arg3, arg4);
 #endif
 #ifdef TARGET_NR_shmget
     case TARGET_NR_shmget:
-        ret = get_errno(shmget(arg1, arg2, arg3));
-        break;
+        return get_errno(shmget(arg1, arg2, arg3));
 #endif
 #ifdef TARGET_NR_shmctl
     case TARGET_NR_shmctl:
-        ret = do_shmctl(arg1, arg2, arg3);
-        break;
+        return do_shmctl(arg1, arg2, arg3);
 #endif
 #ifdef TARGET_NR_shmat
     case TARGET_NR_shmat:
-        ret = do_shmat(cpu_env, arg1, arg2, arg3);
-        break;
+        return do_shmat(cpu_env, arg1, arg2, arg3);
 #endif
 #ifdef TARGET_NR_shmdt
     case TARGET_NR_shmdt:
-        ret = do_shmdt(arg1);
-        break;
+        return do_shmdt(arg1);
 #endif
     case TARGET_NR_fsync:
-        ret = get_errno(fsync(arg1));
-        break;
+        return get_errno(fsync(arg1));
     case TARGET_NR_clone:
         /* Linux manages to have three different orderings for its
          * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
@@ -10163,20 +10075,19 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #else
         ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
 #endif
-        break;
+        return ret;
 #ifdef __NR_exit_group
         /* new thread calls */
     case TARGET_NR_exit_group:
         preexit_cleanup(cpu_env, arg1);
-        ret = get_errno(exit_group(arg1));
-        break;
+        return get_errno(exit_group(arg1));
 #endif
     case TARGET_NR_setdomainname:
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(setdomainname(p, arg2));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
     case TARGET_NR_uname:
         /* no need to transcode because we use the linux syscall */
         {
@@ -10198,17 +10109,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
             unlock_user_struct(buf, arg1, 1);
         }
-        break;
+        return ret;
 #ifdef TARGET_I386
     case TARGET_NR_modify_ldt:
-        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
-        break;
+        return do_modify_ldt(cpu_env, arg1, arg2, arg3);
 #if !defined(TARGET_X86_64)
     case TARGET_NR_vm86old:
         goto unimplemented;
     case TARGET_NR_vm86:
-        ret = do_vm86(cpu_env, arg1, arg2);
-        break;
+        return do_vm86(cpu_env, arg1, arg2);
 #endif
 #endif
     case TARGET_NR_adjtimex:
@@ -10225,7 +10134,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 }
             }
         }
-        break;
+        return ret;
 #if defined(TARGET_NR_clock_adjtime) && defined(CONFIG_CLOCK_ADJTIME)
     case TARGET_NR_clock_adjtime:
         {
@@ -10241,7 +10150,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 }
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_create_module
     case TARGET_NR_create_module:
@@ -10255,11 +10164,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_quotactl:
         goto unimplemented;
     case TARGET_NR_getpgid:
-        ret = get_errno(getpgid(arg1));
-        break;
+        return get_errno(getpgid(arg1));
     case TARGET_NR_fchdir:
-        ret = get_errno(fchdir(arg1));
-        break;
+        return get_errno(fchdir(arg1));
 #ifdef TARGET_NR_bdflush /* not on x86_64 */
     case TARGET_NR_bdflush:
         goto unimplemented;
@@ -10269,8 +10176,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         goto unimplemented;
 #endif
     case TARGET_NR_personality:
-        ret = get_errno(personality(arg1));
-        break;
+        return get_errno(personality(arg1));
 #ifdef TARGET_NR_afs_syscall
     case TARGET_NR_afs_syscall:
         goto unimplemented;
@@ -10293,7 +10199,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 goto efault;
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_getdents
     case TARGET_NR_getdents:
@@ -10425,7 +10331,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(dirp, arg2, ret);
         }
 #endif
-        break;
+        return ret;
 #endif /* TARGET_NR_getdents */
 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
     case TARGET_NR_getdents64:
@@ -10453,12 +10359,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
             unlock_user(dirp, arg2, ret);
         }
-        break;
+        return ret;
 #endif /* TARGET_NR_getdents64 */
 #if defined(TARGET_NR__newselect)
     case TARGET_NR__newselect:
-        ret = do_select(arg1, arg2, arg3, arg4, arg5);
-        break;
+        return do_select(arg1, arg2, arg3, arg4, arg5);
 #endif
 #if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
 # ifdef TARGET_NR_poll
@@ -10477,8 +10382,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             target_pfd = NULL;
             if (nfds) {
                 if (nfds > (INT_MAX / sizeof(struct target_pollfd))) {
-                    ret = -TARGET_EINVAL;
-                    break;
+                    return -TARGET_EINVAL;
                 }
 
                 target_pfd = lock_user(VERIFY_WRITE, arg1,
@@ -10514,8 +10418,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (arg4) {
                     if (arg5 != sizeof(target_sigset_t)) {
                         unlock_user(target_pfd, arg1, 0);
-                        ret = -TARGET_EINVAL;
-                        break;
+                        return -TARGET_EINVAL;
                     }
 
                     target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
@@ -10569,13 +10472,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
             unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
         }
-        break;
+        return ret;
 #endif
     case TARGET_NR_flock:
         /* NOTE: the flock constant seems to be the same for every
            Linux platform */
-        ret = get_errno(safe_flock(arg1, arg2));
-        break;
+        return get_errno(safe_flock(arg1, arg2));
     case TARGET_NR_readv:
         {
             struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
@@ -10586,7 +10488,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = -host_to_target_errno(errno);
             }
         }
-        break;
+        return ret;
     case TARGET_NR_writev:
         {
             struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
@@ -10597,7 +10499,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = -host_to_target_errno(errno);
             }
         }
-        break;
+        return ret;
 #if defined(TARGET_NR_preadv)
     case TARGET_NR_preadv:
         {
@@ -10612,7 +10514,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = -host_to_target_errno(errno);
            }
         }
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_pwritev)
     case TARGET_NR_pwritev:
@@ -10628,22 +10530,19 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = -host_to_target_errno(errno);
            }
         }
-        break;
+        return ret;
 #endif
     case TARGET_NR_getsid:
-        ret = get_errno(getsid(arg1));
-        break;
+        return get_errno(getsid(arg1));
 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
     case TARGET_NR_fdatasync:
-        ret = get_errno(fdatasync(arg1));
-        break;
+        return get_errno(fdatasync(arg1));
 #endif
 #ifdef TARGET_NR__sysctl
     case TARGET_NR__sysctl:
         /* We don't implement this, but ENOTDIR is always a safe
            return value. */
-        ret = -TARGET_ENOTDIR;
-        break;
+        return -TARGET_ENOTDIR;
 #endif
     case TARGET_NR_sched_getaffinity:
         {
@@ -10655,8 +10554,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
              * care of mismatches between target ulong and host ulong sizes.
              */
             if (arg2 & (sizeof(abi_ulong) - 1)) {
-                ret = -TARGET_EINVAL;
-                break;
+                return -TARGET_EINVAL;
             }
             mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
 
@@ -10675,8 +10573,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                      */
                     int numcpus = sysconf(_SC_NPROCESSORS_CONF);
                     if (numcpus > arg2 * 8) {
-                        ret = -TARGET_EINVAL;
-                        break;
+                        return -TARGET_EINVAL;
                     }
                     ret = arg2;
                 }
@@ -10686,7 +10583,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 }
             }
         }
-        break;
+        return ret;
     case TARGET_NR_sched_setaffinity:
         {
             unsigned int mask_size;
@@ -10697,20 +10594,18 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
              * care of mismatches between target ulong and host ulong sizes.
              */
             if (arg2 & (sizeof(abi_ulong) - 1)) {
-                ret = -TARGET_EINVAL;
-                break;
+                return -TARGET_EINVAL;
             }
             mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
             mask = alloca(mask_size);
 
             ret = target_to_host_cpu_mask(mask, mask_size, arg3, arg2);
             if (ret) {
-                break;
+                return ret;
             }
 
-            ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
+            return get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
         }
-        break;
     case TARGET_NR_getcpu:
         {
             unsigned cpu, node;
@@ -10727,7 +10622,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 goto efault;
             }
         }
-        break;
+        return ret;
     case TARGET_NR_sched_setparam:
         {
             struct sched_param *target_schp;
@@ -10740,9 +10635,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 goto efault;
             schp.sched_priority = tswap32(target_schp->sched_priority);
             unlock_user_struct(target_schp, arg2, 0);
-            ret = get_errno(sched_setparam(arg1, &schp));
+            return get_errno(sched_setparam(arg1, &schp));
         }
-        break;
     case TARGET_NR_sched_getparam:
         {
             struct sched_param *target_schp;
@@ -10759,7 +10653,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user_struct(target_schp, arg2, 1);
             }
         }
-        break;
+        return ret;
     case TARGET_NR_sched_setscheduler:
         {
             struct sched_param *target_schp;
@@ -10771,21 +10665,16 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 goto efault;
             schp.sched_priority = tswap32(target_schp->sched_priority);
             unlock_user_struct(target_schp, arg3, 0);
-            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
+            return get_errno(sched_setscheduler(arg1, arg2, &schp));
         }
-        break;
     case TARGET_NR_sched_getscheduler:
-        ret = get_errno(sched_getscheduler(arg1));
-        break;
+        return get_errno(sched_getscheduler(arg1));
     case TARGET_NR_sched_yield:
-        ret = get_errno(sched_yield());
-        break;
+        return get_errno(sched_yield());
     case TARGET_NR_sched_get_priority_max:
-        ret = get_errno(sched_get_priority_max(arg1));
-        break;
+        return get_errno(sched_get_priority_max(arg1));
     case TARGET_NR_sched_get_priority_min:
-        ret = get_errno(sched_get_priority_min(arg1));
-        break;
+        return get_errno(sched_get_priority_min(arg1));
     case TARGET_NR_sched_rr_get_interval:
         {
             struct timespec ts;
@@ -10794,7 +10683,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = host_to_target_timespec(arg2, &ts);
             }
         }
-        break;
+        return ret;
     case TARGET_NR_nanosleep:
         {
             struct timespec req, rem;
@@ -10804,7 +10693,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 host_to_target_timespec(arg2, &rem);
             }
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_query_module
     case TARGET_NR_query_module:
         goto unimplemented;
@@ -10823,7 +10712,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 && put_user_ual(deathsig, arg2)) {
                 goto efault;
             }
-            break;
+            return ret;
         }
 #ifdef PR_GET_NAME
         case PR_GET_NAME:
@@ -10835,7 +10724,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(prctl(arg1, (unsigned long)name,
                                   arg3, arg4, arg5));
             unlock_user(name, arg2, 16);
-            break;
+            return ret;
         }
         case PR_SET_NAME:
         {
@@ -10846,7 +10735,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(prctl(arg1, (unsigned long)name,
                                   arg3, arg4, arg5));
             unlock_user(name, arg2, 0);
-            break;
+            return ret;
         }
 #endif
 #ifdef TARGET_AARCH64
@@ -10874,32 +10763,29 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 env->vfp.zcr_el[1] = vq - 1;
                 ret = vq * 16;
             }
-            break;
+            return ret;
         case TARGET_PR_SVE_GET_VL:
             ret = -TARGET_EINVAL;
             if (arm_feature(cpu_env, ARM_FEATURE_SVE)) {
                 CPUARMState *env = cpu_env;
                 ret = ((env->vfp.zcr_el[1] & 0xf) + 1) * 16;
             }
-            break;
+            return ret;
 #endif /* AARCH64 */
         case PR_GET_SECCOMP:
         case PR_SET_SECCOMP:
             /* Disable seccomp to prevent the target disabling syscalls we
              * need. */
-            ret = -TARGET_EINVAL;
-            break;
+            return -TARGET_EINVAL;
         default:
             /* Most prctl options have no pointer arguments */
-            ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
-            break;
+            return get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
         }
         break;
 #ifdef TARGET_NR_arch_prctl
     case TARGET_NR_arch_prctl:
 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
-        ret = do_arch_prctl(cpu_env, arg1, arg2);
-        break;
+        return do_arch_prctl(cpu_env, arg1, arg2);
 #else
         goto unimplemented;
 #endif
@@ -10914,7 +10800,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
         unlock_user(p, arg2, ret);
-        break;
+        return ret;
     case TARGET_NR_pwrite64:
         if (regpairs_aligned(cpu_env, num)) {
             arg4 = arg5;
@@ -10924,14 +10810,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
         unlock_user(p, arg2, 0);
-        break;
+        return ret;
 #endif
     case TARGET_NR_getcwd:
         if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
             goto efault;
         ret = get_errno(sys_getcwd1(p, arg2));
         unlock_user(p, arg1, ret);
-        break;
+        return ret;
     case TARGET_NR_capget:
     case TARGET_NR_capset:
     {
@@ -11000,11 +10886,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user(target_data, arg2, 0);
             }
         }
-        break;
+        return ret;
     }
     case TARGET_NR_sigaltstack:
-        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
-        break;
+        return do_sigaltstack(arg1, arg2,
+                              get_sp_from_cpustate((CPUArchState *)cpu_env));
 
 #ifdef CONFIG_SENDFILE
 #ifdef TARGET_NR_sendfile
@@ -11015,7 +10901,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (arg3) {
             ret = get_user_sal(off, arg3);
             if (is_error(ret)) {
-                break;
+                return ret;
             }
             offp = &off;
         }
@@ -11026,7 +10912,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = ret2;
             }
         }
-        break;
+        return ret;
     }
 #endif
 #ifdef TARGET_NR_sendfile64
@@ -11037,7 +10923,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (arg3) {
             ret = get_user_s64(off, arg3);
             if (is_error(ret)) {
-                break;
+                return ret;
             }
             offp = &off;
         }
@@ -11048,7 +10934,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = ret2;
             }
         }
-        break;
+        return ret;
     }
 #endif
 #else
@@ -11069,10 +10955,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_vfork
     case TARGET_NR_vfork:
-        ret = get_errno(do_fork(cpu_env,
-                        CLONE_VFORK | CLONE_VM | TARGET_SIGCHLD,
-                        0, 0, 0, 0));
-        break;
+        return get_errno(do_fork(cpu_env,
+                         CLONE_VFORK | CLONE_VM | TARGET_SIGCHLD,
+                         0, 0, 0, 0));
 #endif
 #ifdef TARGET_NR_ugetrlimit
     case TARGET_NR_ugetrlimit:
@@ -11088,7 +10973,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 	    target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
             unlock_user_struct(target_rlim, arg2, 1);
 	}
-	break;
+        return ret;
     }
 #endif
 #ifdef TARGET_NR_truncate64
@@ -11097,12 +10982,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
 	ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
         unlock_user(p, arg1, 0);
-	break;
+        return ret;
 #endif
 #ifdef TARGET_NR_ftruncate64
     case TARGET_NR_ftruncate64:
-	ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
-	break;
+        return target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
 #endif
 #ifdef TARGET_NR_stat64
     case TARGET_NR_stat64:
@@ -11112,7 +10996,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         unlock_user(p, arg1, 0);
         if (!is_error(ret))
             ret = host_to_target_stat64(cpu_env, arg2, &st);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_lstat64
     case TARGET_NR_lstat64:
@@ -11122,14 +11006,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         unlock_user(p, arg1, 0);
         if (!is_error(ret))
             ret = host_to_target_stat64(cpu_env, arg2, &st);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_fstat64
     case TARGET_NR_fstat64:
         ret = get_errno(fstat(arg1, &st));
         if (!is_error(ret))
             ret = host_to_target_stat64(cpu_env, arg2, &st);
-        break;
+        return ret;
 #endif
 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
 #ifdef TARGET_NR_fstatat64
@@ -11143,7 +11027,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(fstatat(arg1, path(p), &st, arg4));
         if (!is_error(ret))
             ret = host_to_target_stat64(cpu_env, arg3, &st);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_lchown
     case TARGET_NR_lchown:
@@ -11151,34 +11035,28 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_getuid
     case TARGET_NR_getuid:
-        ret = get_errno(high2lowuid(getuid()));
-        break;
+        return get_errno(high2lowuid(getuid()));
 #endif
 #ifdef TARGET_NR_getgid
     case TARGET_NR_getgid:
-        ret = get_errno(high2lowgid(getgid()));
-        break;
+        return get_errno(high2lowgid(getgid()));
 #endif
 #ifdef TARGET_NR_geteuid
     case TARGET_NR_geteuid:
-        ret = get_errno(high2lowuid(geteuid()));
-        break;
+        return get_errno(high2lowuid(geteuid()));
 #endif
 #ifdef TARGET_NR_getegid
     case TARGET_NR_getegid:
-        ret = get_errno(high2lowgid(getegid()));
-        break;
+        return get_errno(high2lowgid(getegid()));
 #endif
     case TARGET_NR_setreuid:
-        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
-        break;
+        return get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
     case TARGET_NR_setregid:
-        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
-        break;
+        return get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
     case TARGET_NR_getgroups:
         {
             int gidsetsize = arg1;
@@ -11189,7 +11067,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             grouplist = alloca(gidsetsize * sizeof(gid_t));
             ret = get_errno(getgroups(gidsetsize, grouplist));
             if (gidsetsize == 0)
-                break;
+                return ret;
             if (!is_error(ret)) {
                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
                 if (!target_grouplist)
@@ -11199,7 +11077,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
             }
         }
-        break;
+        return ret;
     case TARGET_NR_setgroups:
         {
             int gidsetsize = arg1;
@@ -11218,12 +11096,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 }
                 unlock_user(target_grouplist, arg2, 0);
             }
-            ret = get_errno(setgroups(gidsetsize, grouplist));
+            return get_errno(setgroups(gidsetsize, grouplist));
         }
-        break;
     case TARGET_NR_fchown:
-        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
-        break;
+        return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
 #if defined(TARGET_NR_fchownat)
     case TARGET_NR_fchownat:
         if (!(p = lock_user_string(arg2))) 
@@ -11231,14 +11107,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
                                  low2highgid(arg4), arg5));
         unlock_user(p, arg2, 0);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_setresuid
     case TARGET_NR_setresuid:
-        ret = get_errno(sys_setresuid(low2highuid(arg1),
-                                      low2highuid(arg2),
-                                      low2highuid(arg3)));
-        break;
+        return get_errno(sys_setresuid(low2highuid(arg1),
+                                       low2highuid(arg2),
+                                       low2highuid(arg3)));
 #endif
 #ifdef TARGET_NR_getresuid
     case TARGET_NR_getresuid:
@@ -11252,14 +11127,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     goto efault;
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_getresgid
     case TARGET_NR_setresgid:
-        ret = get_errno(sys_setresgid(low2highgid(arg1),
-                                      low2highgid(arg2),
-                                      low2highgid(arg3)));
-        break;
+        return get_errno(sys_setresgid(low2highgid(arg1),
+                                       low2highgid(arg2),
+                                       low2highgid(arg3)));
 #endif
 #ifdef TARGET_NR_getresgid
     case TARGET_NR_getresgid:
@@ -11273,7 +11147,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     goto efault;
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_chown
     case TARGET_NR_chown:
@@ -11281,20 +11155,16 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
     case TARGET_NR_setuid:
-        ret = get_errno(sys_setuid(low2highuid(arg1)));
-        break;
+        return get_errno(sys_setuid(low2highuid(arg1)));
     case TARGET_NR_setgid:
-        ret = get_errno(sys_setgid(low2highgid(arg1)));
-        break;
+        return get_errno(sys_setgid(low2highgid(arg1)));
     case TARGET_NR_setfsuid:
-        ret = get_errno(setfsuid(arg1));
-        break;
+        return get_errno(setfsuid(arg1));
     case TARGET_NR_setfsgid:
-        ret = get_errno(setfsgid(arg1));
-        break;
+        return get_errno(setfsgid(arg1));
 
 #ifdef TARGET_NR_lchown32
     case TARGET_NR_lchown32:
@@ -11302,12 +11172,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(lchown(p, arg2, arg3));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_getuid32
     case TARGET_NR_getuid32:
-        ret = get_errno(getuid());
-        break;
+        return get_errno(getuid());
 #endif
 
 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
@@ -11318,8 +11187,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             euid=geteuid();
             ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
          }
-        ret = get_errno(getuid());
-        break;
+        return get_errno(getuid());
 #endif
 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
    /* Alpha specific */
@@ -11329,8 +11197,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             egid=getegid();
             ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
          }
-        ret = get_errno(getgid());
-        break;
+        return get_errno(getgid());
 #endif
 #if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
     /* Alpha specific */
@@ -11368,7 +11235,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
              -- Grabs a copy of the HWRPB; surely not used.
           */
         }
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
     /* Alpha specific */
@@ -11459,7 +11326,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
              -- Not implemented in linux kernel
           */
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_osf_sigprocmask
     /* Alpha specific.  */
@@ -11491,33 +11358,28 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = mask;
             }
         }
-        break;
+        return ret;
 #endif
 
 #ifdef TARGET_NR_getgid32
     case TARGET_NR_getgid32:
-        ret = get_errno(getgid());
-        break;
+        return get_errno(getgid());
 #endif
 #ifdef TARGET_NR_geteuid32
     case TARGET_NR_geteuid32:
-        ret = get_errno(geteuid());
-        break;
+        return get_errno(geteuid());
 #endif
 #ifdef TARGET_NR_getegid32
     case TARGET_NR_getegid32:
-        ret = get_errno(getegid());
-        break;
+        return get_errno(getegid());
 #endif
 #ifdef TARGET_NR_setreuid32
     case TARGET_NR_setreuid32:
-        ret = get_errno(setreuid(arg1, arg2));
-        break;
+        return get_errno(setreuid(arg1, arg2));
 #endif
 #ifdef TARGET_NR_setregid32
     case TARGET_NR_setregid32:
-        ret = get_errno(setregid(arg1, arg2));
-        break;
+        return get_errno(setregid(arg1, arg2));
 #endif
 #ifdef TARGET_NR_getgroups32
     case TARGET_NR_getgroups32:
@@ -11530,7 +11392,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             grouplist = alloca(gidsetsize * sizeof(gid_t));
             ret = get_errno(getgroups(gidsetsize, grouplist));
             if (gidsetsize == 0)
-                break;
+                return ret;
             if (!is_error(ret)) {
                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
                 if (!target_grouplist) {
@@ -11542,7 +11404,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user(target_grouplist, arg2, gidsetsize * 4);
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_setgroups32
     case TARGET_NR_setgroups32:
@@ -11561,19 +11423,16 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             for(i = 0;i < gidsetsize; i++)
                 grouplist[i] = tswap32(target_grouplist[i]);
             unlock_user(target_grouplist, arg2, 0);
-            ret = get_errno(setgroups(gidsetsize, grouplist));
+            return get_errno(setgroups(gidsetsize, grouplist));
         }
-        break;
 #endif
 #ifdef TARGET_NR_fchown32
     case TARGET_NR_fchown32:
-        ret = get_errno(fchown(arg1, arg2, arg3));
-        break;
+        return get_errno(fchown(arg1, arg2, arg3));
 #endif
 #ifdef TARGET_NR_setresuid32
     case TARGET_NR_setresuid32:
-        ret = get_errno(sys_setresuid(arg1, arg2, arg3));
-        break;
+        return get_errno(sys_setresuid(arg1, arg2, arg3));
 #endif
 #ifdef TARGET_NR_getresuid32
     case TARGET_NR_getresuid32:
@@ -11587,12 +11446,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     goto efault;
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_setresgid32
     case TARGET_NR_setresgid32:
-        ret = get_errno(sys_setresgid(arg1, arg2, arg3));
-        break;
+        return get_errno(sys_setresgid(arg1, arg2, arg3));
 #endif
 #ifdef TARGET_NR_getresgid32
     case TARGET_NR_getresgid32:
@@ -11606,7 +11464,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     goto efault;
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_chown32
     case TARGET_NR_chown32:
@@ -11614,27 +11472,23 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             goto efault;
         ret = get_errno(chown(p, arg2, arg3));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_setuid32
     case TARGET_NR_setuid32:
-        ret = get_errno(sys_setuid(arg1));
-        break;
+        return get_errno(sys_setuid(arg1));
 #endif
 #ifdef TARGET_NR_setgid32
     case TARGET_NR_setgid32:
-        ret = get_errno(sys_setgid(arg1));
-        break;
+        return get_errno(sys_setgid(arg1));
 #endif
 #ifdef TARGET_NR_setfsuid32
     case TARGET_NR_setfsuid32:
-        ret = get_errno(setfsuid(arg1));
-        break;
+        return get_errno(setfsuid(arg1));
 #endif
 #ifdef TARGET_NR_setfsgid32
     case TARGET_NR_setfsgid32:
-        ret = get_errno(setfsgid(arg1));
-        break;
+        return get_errno(setfsgid(arg1));
 #endif
 
     case TARGET_NR_pivot_root:
@@ -11658,7 +11512,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             mincore_fail:
             unlock_user(a, arg1, 0);
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_arm_fadvise64_64
     case TARGET_NR_arm_fadvise64_64:
@@ -11670,8 +11524,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
          */
         ret = posix_fadvise(arg1, target_offset64(arg3, arg4),
                             target_offset64(arg5, arg6), arg2);
-        ret = -host_to_target_errno(ret);
-        break;
+        return -host_to_target_errno(ret);
 #endif
 
 #if TARGET_ABI_BITS == 32
@@ -11697,11 +11550,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             arg6 = arg7;
         }
 #endif
-        ret = -host_to_target_errno(posix_fadvise(arg1,
-                                                  target_offset64(arg2, arg3),
-                                                  target_offset64(arg4, arg5),
-                                                  arg6));
-        break;
+        ret = posix_fadvise(arg1, target_offset64(arg2, arg3),
+                            target_offset64(arg4, arg5), arg6);
+        return -host_to_target_errno(ret);
 #endif
 
 #ifdef TARGET_NR_fadvise64
@@ -11714,10 +11565,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             arg4 = arg5;
             arg5 = arg6;
         }
-        ret = -host_to_target_errno(posix_fadvise(arg1,
-                                                  target_offset64(arg2, arg3),
-                                                  arg4, arg5));
-        break;
+        ret = posix_fadvise(arg1, target_offset64(arg2, arg3), arg4, arg5);
+        return -host_to_target_errno(ret);
 #endif
 
 #else /* not a 32-bit ABI */
@@ -11737,8 +11586,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         default: break;
         }
 #endif
-        ret = -host_to_target_errno(posix_fadvise(arg1, arg2, arg3, arg4));
-        break;
+        return -host_to_target_errno(posix_fadvise(arg1, arg2, arg3, arg4));
 #endif
 #endif /* end of 64-bit ABI fadvise handling */
 
@@ -11748,8 +11596,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
            turns private file-backed mappings into anonymous mappings.
            This will break MADV_DONTNEED.
            This is a hint, so ignoring and returning success is ok.  */
-        ret = get_errno(0);
-        break;
+        return 0;
 #endif
 #if TARGET_ABI_BITS == 32
     case TARGET_NR_fcntl64:
@@ -11768,8 +11615,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
 	cmd = target_to_host_fcntl_cmd(arg2);
         if (cmd == -TARGET_EINVAL) {
-            ret = cmd;
-            break;
+            return cmd;
         }
 
         switch(arg2) {
@@ -11796,14 +11642,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = do_fcntl(arg1, arg2, arg3);
             break;
         }
-	break;
+        return ret;
     }
 #endif
 #ifdef TARGET_NR_cacheflush
     case TARGET_NR_cacheflush:
         /* self-modifying code is handled automatically, so nothing needed */
-        ret = 0;
-        break;
+        return 0;
 #endif
 #ifdef TARGET_NR_security
     case TARGET_NR_security:
@@ -11811,12 +11656,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_getpagesize
     case TARGET_NR_getpagesize:
-        ret = TARGET_PAGE_SIZE;
-        break;
+        return TARGET_PAGE_SIZE;
 #endif
     case TARGET_NR_gettid:
-        ret = get_errno(gettid());
-        break;
+        return get_errno(gettid());
 #ifdef TARGET_NR_readahead
     case TARGET_NR_readahead:
 #if TARGET_ABI_BITS == 32
@@ -11829,7 +11672,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #else
         ret = get_errno(readahead(arg1, arg2, arg3));
 #endif
-        break;
+        return ret;
 #endif
 #ifdef CONFIG_ATTR
 #ifdef TARGET_NR_setxattr
@@ -11840,8 +11683,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (arg2) {
             b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
             if (!b) {
-                ret = -TARGET_EFAULT;
-                break;
+                return -TARGET_EFAULT;
             }
         }
         p = lock_user_string(arg1);
@@ -11856,7 +11698,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         }
         unlock_user(p, arg1, 0);
         unlock_user(b, arg2, arg3);
-        break;
+        return ret;
     }
     case TARGET_NR_flistxattr:
     {
@@ -11864,13 +11706,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (arg2) {
             b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
             if (!b) {
-                ret = -TARGET_EFAULT;
-                break;
+                return -TARGET_EFAULT;
             }
         }
         ret = get_errno(flistxattr(arg1, b, arg3));
         unlock_user(b, arg2, arg3);
-        break;
+        return ret;
     }
     case TARGET_NR_setxattr:
     case TARGET_NR_lsetxattr:
@@ -11879,8 +11720,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             if (arg3) {
                 v = lock_user(VERIFY_READ, arg3, arg4, 1);
                 if (!v) {
-                    ret = -TARGET_EFAULT;
-                    break;
+                    return -TARGET_EFAULT;
                 }
             }
             p = lock_user_string(arg1);
@@ -11898,15 +11738,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(n, arg2, 0);
             unlock_user(v, arg3, 0);
         }
-        break;
+        return ret;
     case TARGET_NR_fsetxattr:
         {
             void *n, *v = 0;
             if (arg3) {
                 v = lock_user(VERIFY_READ, arg3, arg4, 1);
                 if (!v) {
-                    ret = -TARGET_EFAULT;
-                    break;
+                    return -TARGET_EFAULT;
                 }
             }
             n = lock_user_string(arg2);
@@ -11918,7 +11757,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(n, arg2, 0);
             unlock_user(v, arg3, 0);
         }
-        break;
+        return ret;
     case TARGET_NR_getxattr:
     case TARGET_NR_lgetxattr:
         {
@@ -11926,8 +11765,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             if (arg3) {
                 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
                 if (!v) {
-                    ret = -TARGET_EFAULT;
-                    break;
+                    return -TARGET_EFAULT;
                 }
             }
             p = lock_user_string(arg1);
@@ -11945,15 +11783,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(n, arg2, 0);
             unlock_user(v, arg3, arg4);
         }
-        break;
+        return ret;
     case TARGET_NR_fgetxattr:
         {
             void *n, *v = 0;
             if (arg3) {
                 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
                 if (!v) {
-                    ret = -TARGET_EFAULT;
-                    break;
+                    return -TARGET_EFAULT;
                 }
             }
             n = lock_user_string(arg2);
@@ -11965,7 +11802,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(n, arg2, 0);
             unlock_user(v, arg3, arg4);
         }
-        break;
+        return ret;
     case TARGET_NR_removexattr:
     case TARGET_NR_lremovexattr:
         {
@@ -11984,7 +11821,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(p, arg1, 0);
             unlock_user(n, arg2, 0);
         }
-        break;
+        return ret;
     case TARGET_NR_fremovexattr:
         {
             void *n;
@@ -11996,15 +11833,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
             unlock_user(n, arg2, 0);
         }
-        break;
+        return ret;
 #endif
 #endif /* CONFIG_ATTR */
 #ifdef TARGET_NR_set_thread_area
     case TARGET_NR_set_thread_area:
 #if defined(TARGET_MIPS)
       ((CPUMIPSState *) cpu_env)->active_tc.CP0_UserLocal = arg1;
-      ret = 0;
-      break;
+      return 0;
 #elif defined(TARGET_CRIS)
       if (arg1 & 0xff)
           ret = -TARGET_EINVAL;
@@ -12012,16 +11848,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
           ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
           ret = 0;
       }
-      break;
+      return ret;
 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
-      ret = do_set_thread_area(cpu_env, arg1);
-      break;
+      return do_set_thread_area(cpu_env, arg1);
 #elif defined(TARGET_M68K)
       {
           TaskState *ts = cpu->opaque;
           ts->tp_value = arg1;
-          ret = 0;
-          break;
+          return 0;
       }
 #else
       goto unimplemented_nowarn;
@@ -12030,13 +11864,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_get_thread_area
     case TARGET_NR_get_thread_area:
 #if defined(TARGET_I386) && defined(TARGET_ABI32)
-        ret = do_get_thread_area(cpu_env, arg1);
-        break;
+        return do_get_thread_area(cpu_env, arg1);
 #elif defined(TARGET_M68K)
         {
             TaskState *ts = cpu->opaque;
-            ret = ts->tp_value;
-            break;
+            return ts->tp_value;
         }
 #else
         goto unimplemented_nowarn;
@@ -12056,7 +11888,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (!is_error(ret)) {
             ret = get_errno(clock_settime(arg1, &ts));
         }
-        break;
+        return ret;
     }
 #endif
 #ifdef TARGET_NR_clock_gettime
@@ -12067,7 +11899,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (!is_error(ret)) {
             ret = host_to_target_timespec(arg2, &ts);
         }
-        break;
+        return ret;
     }
 #endif
 #ifdef TARGET_NR_clock_getres
@@ -12078,7 +11910,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (!is_error(ret)) {
             host_to_target_timespec(arg2, &ts);
         }
-        break;
+        return ret;
     }
 #endif
 #ifdef TARGET_NR_clock_nanosleep
@@ -12098,24 +11930,21 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ((CPUPPCState *)cpu_env)->crf[0] |= 1;
         }
 #endif
-        break;
+        return ret;
     }
 #endif
 
 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
     case TARGET_NR_set_tid_address:
-        ret = get_errno(set_tid_address((int *)g2h(arg1)));
-        break;
+        return get_errno(set_tid_address((int *)g2h(arg1)));
 #endif
 
     case TARGET_NR_tkill:
-        ret = get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2)));
-        break;
+        return get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2)));
 
     case TARGET_NR_tgkill:
-        ret = get_errno(safe_tgkill((int)arg1, (int)arg2,
-                        target_to_host_signal(arg3)));
-        break;
+        return get_errno(safe_tgkill((int)arg1, (int)arg2,
+                         target_to_host_signal(arg3)));
 
 #ifdef TARGET_NR_set_robust_list
     case TARGET_NR_set_robust_list:
@@ -12157,18 +11986,17 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user(p, arg2, 0);
             }
         }
-	break;
+        return ret;
 #endif
     case TARGET_NR_futex:
-        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
-        break;
+        return do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
     case TARGET_NR_inotify_init:
         ret = get_errno(sys_inotify_init());
         if (ret >= 0) {
             fd_trans_register(ret, &target_inotify_trans);
         }
-        break;
+        return ret;
 #endif
 #ifdef CONFIG_INOTIFY1
 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
@@ -12178,7 +12006,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (ret >= 0) {
             fd_trans_register(ret, &target_inotify_trans);
         }
-        break;
+        return ret;
 #endif
 #endif
 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
@@ -12186,12 +12014,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         p = lock_user_string(arg2);
         ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
         unlock_user(p, arg2, 0);
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
     case TARGET_NR_inotify_rm_watch:
-        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
-        break;
+        return get_errno(sys_inotify_rm_watch(arg1, arg2));
 #endif
 
 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
@@ -12216,17 +12043,16 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(mq_open(p, host_flags, arg3, pposix_mq_attr));
             unlock_user (p, arg1, 0);
         }
-        break;
+        return ret;
 
     case TARGET_NR_mq_unlink:
         p = lock_user_string(arg1 - 1);
         if (!p) {
-            ret = -TARGET_EFAULT;
-            break;
+            return -TARGET_EFAULT;
         }
         ret = get_errno(mq_unlink(p));
         unlock_user (p, arg1, 0);
-        break;
+        return ret;
 
     case TARGET_NR_mq_timedsend:
         {
@@ -12242,7 +12068,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
             unlock_user (p, arg2, arg3);
         }
-        break;
+        return ret;
 
     case TARGET_NR_mq_timedreceive:
         {
@@ -12263,7 +12089,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             if (arg4 != 0)
                 put_user_u32(prio, arg4);
         }
-        break;
+        return ret;
 
     /* Not implemented for now... */
 /*     case TARGET_NR_mq_notify: */
@@ -12284,7 +12110,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
             }
         }
-        break;
+        return ret;
 #endif
 
 #ifdef CONFIG_SPLICE
@@ -12293,7 +12119,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         {
             ret = get_errno(tee(arg1,arg2,arg3,arg4));
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_splice
     case TARGET_NR_splice:
@@ -12324,7 +12150,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 }
             }
         }
-        break;
+        return ret;
 #endif
 #ifdef TARGET_NR_vmsplice
 	case TARGET_NR_vmsplice:
@@ -12337,7 +12163,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = -host_to_target_errno(errno);
             }
         }
-        break;
+        return ret;
 #endif
 #endif /* CONFIG_SPLICE */
 #ifdef CONFIG_EVENTFD
@@ -12347,7 +12173,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (ret >= 0) {
             fd_trans_register(ret, &target_eventfd_trans);
         }
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_eventfd2)
     case TARGET_NR_eventfd2:
@@ -12363,7 +12189,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (ret >= 0) {
             fd_trans_register(ret, &target_eventfd_trans);
         }
-        break;
+        return ret;
     }
 #endif
 #endif /* CONFIG_EVENTFD  */
@@ -12375,7 +12201,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #else
         ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
 #endif
-        break;
+        return ret;
 #endif
 #if defined(CONFIG_SYNC_FILE_RANGE)
 #if defined(TARGET_NR_sync_file_range)
@@ -12391,7 +12217,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #else
         ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
 #endif
-        break;
+        return ret;
 #endif
 #if defined(TARGET_NR_sync_file_range2)
     case TARGET_NR_sync_file_range2:
@@ -12402,29 +12228,25 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #else
         ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
 #endif
-        break;
+        return ret;
 #endif
 #endif
 #if defined(TARGET_NR_signalfd4)
     case TARGET_NR_signalfd4:
-        ret = do_signalfd4(arg1, arg2, arg4);
-        break;
+        return do_signalfd4(arg1, arg2, arg4);
 #endif
 #if defined(TARGET_NR_signalfd)
     case TARGET_NR_signalfd:
-        ret = do_signalfd4(arg1, arg2, 0);
-        break;
+        return do_signalfd4(arg1, arg2, 0);
 #endif
 #if defined(CONFIG_EPOLL)
 #if defined(TARGET_NR_epoll_create)
     case TARGET_NR_epoll_create:
-        ret = get_errno(epoll_create(arg1));
-        break;
+        return get_errno(epoll_create(arg1));
 #endif
 #if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
     case TARGET_NR_epoll_create1:
-        ret = get_errno(epoll_create1(arg1));
-        break;
+        return get_errno(epoll_create1(arg1));
 #endif
 #if defined(TARGET_NR_epoll_ctl)
     case TARGET_NR_epoll_ctl:
@@ -12445,8 +12267,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user_struct(target_ep, arg4, 0);
             epp = &ep;
         }
-        ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
-        break;
+        return get_errno(epoll_ctl(arg1, arg2, arg3, epp));
     }
 #endif
 
@@ -12465,8 +12286,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         int timeout = arg4;
 
         if (maxevents <= 0 || maxevents > TARGET_EP_MAX_EVENTS) {
-            ret = -TARGET_EINVAL;
-            break;
+            return -TARGET_EINVAL;
         }
 
         target_ep = lock_user(VERIFY_WRITE, arg2,
@@ -12478,8 +12298,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         ep = g_try_new(struct epoll_event, maxevents);
         if (!ep) {
             unlock_user(target_ep, arg2, 0);
-            ret = -TARGET_ENOMEM;
-            break;
+            return -TARGET_ENOMEM;
         }
 
         switch (num) {
@@ -12533,7 +12352,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             unlock_user(target_ep, arg2, 0);
         }
         g_free(ep);
-        break;
+        return ret;
     }
 #endif
 #endif
@@ -12563,7 +12382,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             target_rold->rlim_max = tswap64(rold.rlim_max);
             unlock_user_struct(target_rold, arg4, 1);
         }
-        break;
+        return ret;
     }
 #endif
 #ifdef TARGET_NR_gethostname
@@ -12576,7 +12395,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         } else {
             ret = -TARGET_EFAULT;
         }
-        break;
+        return ret;
     }
 #endif
 #ifdef TARGET_NR_atomic_cmpxchg_32
@@ -12597,17 +12416,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         }
         if (mem_value == arg2)
             put_user_u32(arg1, arg6);
-        ret = mem_value;
-        break;
+        return mem_value;
     }
 #endif
 #ifdef TARGET_NR_atomic_barrier
     case TARGET_NR_atomic_barrier:
-    {
-        /* Like the kernel implementation and the qemu arm barrier, no-op this? */
-        ret = 0;
-        break;
-    }
+        /* Like the kernel implementation and the
+           qemu arm barrier, no-op this? */
+        return 0;
 #endif
 
 #ifdef TARGET_NR_timer_create
@@ -12629,7 +12445,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 phost_sevp = &host_sevp;
                 ret = target_to_host_sigevent(phost_sevp, arg2);
                 if (ret != 0) {
-                    break;
+                    return ret;
                 }
             }
 
@@ -12642,7 +12458,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 }
             }
         }
-        break;
+        return ret;
     }
 #endif
 
@@ -12670,7 +12486,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 goto efault;
             }
         }
-        break;
+        return ret;
     }
 #endif
 
@@ -12693,7 +12509,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = -TARGET_EFAULT;
             }
         }
-        break;
+        return ret;
     }
 #endif
 
@@ -12710,7 +12526,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(timer_getoverrun(htimer));
         }
         fd_trans_unregister(ret);
-        break;
+        return ret;
     }
 #endif
 
@@ -12727,15 +12543,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(timer_delete(htimer));
             g_posix_timers[timerid] = 0;
         }
-        break;
+        return ret;
     }
 #endif
 
 #if defined(TARGET_NR_timerfd_create) && defined(CONFIG_TIMERFD)
     case TARGET_NR_timerfd_create:
-        ret = get_errno(timerfd_create(arg1,
-                target_to_host_bitmask(arg2, fcntl_flags_tbl)));
-        break;
+        return get_errno(timerfd_create(arg1,
+                          target_to_host_bitmask(arg2, fcntl_flags_tbl)));
 #endif
 
 #if defined(TARGET_NR_timerfd_gettime) && defined(CONFIG_TIMERFD)
@@ -12749,7 +12564,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 goto efault;
             }
         }
-        break;
+        return ret;
 #endif
 
 #if defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD)
@@ -12772,41 +12587,35 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 goto efault;
             }
         }
-        break;
+        return ret;
 #endif
 
 #if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
     case TARGET_NR_ioprio_get:
-        ret = get_errno(ioprio_get(arg1, arg2));
-        break;
+        return get_errno(ioprio_get(arg1, arg2));
 #endif
 
 #if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
     case TARGET_NR_ioprio_set:
-        ret = get_errno(ioprio_set(arg1, arg2, arg3));
-        break;
+        return get_errno(ioprio_set(arg1, arg2, arg3));
 #endif
 
 #if defined(TARGET_NR_setns) && defined(CONFIG_SETNS)
     case TARGET_NR_setns:
-        ret = get_errno(setns(arg1, arg2));
-        break;
+        return get_errno(setns(arg1, arg2));
 #endif
 #if defined(TARGET_NR_unshare) && defined(CONFIG_SETNS)
     case TARGET_NR_unshare:
-        ret = get_errno(unshare(arg1));
-        break;
+        return get_errno(unshare(arg1));
 #endif
 #if defined(TARGET_NR_kcmp) && defined(__NR_kcmp)
     case TARGET_NR_kcmp:
-        ret = get_errno(kcmp(arg1, arg2, arg3, arg4, arg5));
-        break;
+        return get_errno(kcmp(arg1, arg2, arg3, arg4, arg5));
 #endif
 #ifdef TARGET_NR_swapcontext
     case TARGET_NR_swapcontext:
         /* PowerPC specific.  */
-        ret = do_swapcontext(cpu_env, arg1, arg2, arg3);
-        break;
+        return do_swapcontext(cpu_env, arg1, arg2, arg3);
 #endif
 
     default:
@@ -12815,8 +12624,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
     unimplemented_nowarn:
 #endif
-        ret = -TARGET_ENOSYS;
-        break;
+        return -TARGET_ENOSYS;
     }
 fail:
     return ret;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 04/16] linux-user: Propagate goto efault to return
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (2 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 03/16] linux-user: Relax single exit from "break" Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 05/16] linux-user: Propagate goto unimplemented_nowarn " Richard Henderson
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.c | 341 ++++++++++++++++++++++---------------------
 1 file changed, 175 insertions(+), 166 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f92a24f32a..23c3cd5ddd 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8052,7 +8052,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             return 0;
         } else {
             if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
-                goto efault;
+                return -TARGET_EFAULT;
             ret = get_errno(safe_read(arg1, p, arg3));
             if (ret >= 0 &&
                 fd_trans_host_to_target_data(arg1)) {
@@ -8063,7 +8063,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         return ret;
     case TARGET_NR_write:
         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
-            goto efault;
+            return -TARGET_EFAULT;
         if (fd_trans_target_to_host_data(arg1)) {
             void *copy = g_malloc(arg3);
             memcpy(copy, p, arg3);
@@ -8081,7 +8081,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_open
     case TARGET_NR_open:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(do_openat(cpu_env, AT_FDCWD, p,
                                   target_to_host_bitmask(arg2, fcntl_flags_tbl),
                                   arg3));
@@ -8091,7 +8091,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
     case TARGET_NR_openat:
         if (!(p = lock_user_string(arg2)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(do_openat(cpu_env, arg1, p,
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
                                   arg4));
@@ -8126,7 +8126,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(safe_wait4(arg1, &status, arg3, 0));
             if (!is_error(ret) && arg2 && ret
                 && put_user_s32(host_to_target_waitstatus(status), arg2))
-                goto efault;
+                return -TARGET_EFAULT;
         }
         return ret;
 #endif
@@ -8138,7 +8138,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(safe_waitid(arg1, arg2, &info, arg4, NULL));
             if (!is_error(ret) && arg3 && info.si_pid != 0) {
                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 host_to_target_siginfo(p, &info);
                 unlock_user(p, arg3, sizeof(target_siginfo_t));
             }
@@ -8148,7 +8148,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_creat /* not on alpha */
     case TARGET_NR_creat:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(creat(p, arg2));
         fd_trans_unregister(ret);
         unlock_user(p, arg1, 0);
@@ -8174,7 +8174,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         {
             void * p2 = NULL;
             if (!arg2 || !arg4)
-                goto efault;
+                return -TARGET_EFAULT;
             p  = lock_user_string(arg2);
             p2 = lock_user_string(arg4);
             if (!p || !p2)
@@ -8189,7 +8189,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_unlink
     case TARGET_NR_unlink:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(unlink(p));
         unlock_user(p, arg1, 0);
         return ret;
@@ -8197,7 +8197,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_NR_unlinkat)
     case TARGET_NR_unlinkat:
         if (!(p = lock_user_string(arg2)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(unlinkat(arg1, p, arg3));
         unlock_user(p, arg2, 0);
         return ret;
@@ -8217,7 +8217,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             guest_argp = arg2;
             for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
                 if (get_user_ual(addr, gp))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 if (!addr)
                     break;
                 argc++;
@@ -8226,7 +8226,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             guest_envp = arg3;
             for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
                 if (get_user_ual(addr, gp))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 if (!addr)
                     break;
                 envc++;
@@ -8301,7 +8301,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         return ret;
     case TARGET_NR_chdir:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(chdir(p));
         unlock_user(p, arg1, 0);
         return ret;
@@ -8313,14 +8313,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             if (!is_error(ret)
                 && arg1
                 && put_user_sal(host_time, arg1))
-                goto efault;
+                return -TARGET_EFAULT;
         }
         return ret;
 #endif
 #ifdef TARGET_NR_mknod
     case TARGET_NR_mknod:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(mknod(p, arg2, arg3));
         unlock_user(p, arg1, 0);
         return ret;
@@ -8328,7 +8328,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_NR_mknodat)
     case TARGET_NR_mknodat:
         if (!(p = lock_user_string(arg2)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(mknodat(arg1, p, arg3, arg4));
         unlock_user(p, arg2, 0);
         return ret;
@@ -8336,7 +8336,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_chmod
     case TARGET_NR_chmod:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(chmod(p, arg2));
         unlock_user(p, arg1, 0);
         return ret;
@@ -8371,7 +8371,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             if (arg1) {
                 p = lock_user_string(arg1);
                 if (!p) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
             } else {
                 p = NULL;
@@ -8382,7 +8382,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (arg1) {
                     unlock_user(p, arg1, 0);
                 }
-                goto efault;
+                return -TARGET_EFAULT;
             }
 
             if (arg3) {
@@ -8392,7 +8392,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                         unlock_user(p, arg1, 0);
                     }
                     unlock_user(p2, arg2, 0);
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
             } else {
                 p3 = NULL;
@@ -8421,7 +8421,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_umount
     case TARGET_NR_umount:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(umount(p));
         unlock_user(p, arg1, 0);
         return ret;
@@ -8431,7 +8431,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         {
             time_t host_time;
             if (get_user_sal(host_time, arg1))
-                goto efault;
+                return -TARGET_EFAULT;
             return get_errno(stime(&host_time));
         }
 #endif
@@ -8459,7 +8459,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct target_utimbuf *target_tbuf;
             if (arg2) {
                 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 tbuf.actime = tswapal(target_tbuf->actime);
                 tbuf.modtime = tswapal(target_tbuf->modtime);
                 unlock_user_struct(target_tbuf, arg2, 0);
@@ -8468,7 +8468,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 host_tbuf = NULL;
             }
             if (!(p = lock_user_string(arg1)))
-                goto efault;
+                return -TARGET_EFAULT;
             ret = get_errno(utime(p, host_tbuf));
             unlock_user(p, arg1, 0);
         }
@@ -8482,13 +8482,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (copy_from_user_timeval(&tv[0], arg2)
                     || copy_from_user_timeval(&tv[1],
                                               arg2 + sizeof(struct target_timeval)))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 tvp = tv;
             } else {
                 tvp = NULL;
             }
             if (!(p = lock_user_string(arg1)))
-                goto efault;
+                return -TARGET_EFAULT;
             ret = get_errno(utimes(p, tvp));
             unlock_user(p, arg1, 0);
         }
@@ -8502,13 +8502,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (copy_from_user_timeval(&tv[0], arg3)
                     || copy_from_user_timeval(&tv[1],
                                               arg3 + sizeof(struct target_timeval)))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 tvp = tv;
             } else {
                 tvp = NULL;
             }
-            if (!(p = lock_user_string(arg2)))
-                goto efault;
+            if (!(p = lock_user_string(arg2))) {
+                return -TARGET_EFAULT;
+            }
             ret = get_errno(futimesat(arg1, path(p), tvp));
             unlock_user(p, arg2, 0);
         }
@@ -8524,16 +8525,18 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_access
     case TARGET_NR_access:
-        if (!(p = lock_user_string(arg1)))
-            goto efault;
+        if (!(p = lock_user_string(arg1))) {
+            return -TARGET_EFAULT;
+        }
         ret = get_errno(access(path(p), arg2));
         unlock_user(p, arg1, 0);
         return ret;
 #endif
 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
     case TARGET_NR_faccessat:
-        if (!(p = lock_user_string(arg2)))
-            goto efault;
+        if (!(p = lock_user_string(arg2))) {
+            return -TARGET_EFAULT;
+        }
         ret = get_errno(faccessat(arg1, p, arg3, 0));
         unlock_user(p, arg2, 0);
         return ret;
@@ -8604,7 +8607,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_mkdir
     case TARGET_NR_mkdir:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(mkdir(p, arg2));
         unlock_user(p, arg1, 0);
         return ret;
@@ -8612,7 +8615,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_NR_mkdirat)
     case TARGET_NR_mkdirat:
         if (!(p = lock_user_string(arg2)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(mkdirat(arg1, p, arg3));
         unlock_user(p, arg2, 0);
         return ret;
@@ -8620,7 +8623,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_rmdir
     case TARGET_NR_rmdir:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(rmdir(p));
         unlock_user(p, arg1, 0);
         return ret;
@@ -8648,7 +8651,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             if (arg1) {
                 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
                 if (!tmsp)
-                    goto efault;
+                    return -TARGET_EFAULT;
                 tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
                 tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
                 tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
@@ -8670,8 +8673,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (arg1 == 0) {
             ret = get_errno(acct(NULL));
         } else {
-            if (!(p = lock_user_string(arg1)))
-                goto efault;
+            if (!(p = lock_user_string(arg1))) {
+                return -TARGET_EFAULT;
+            }
             ret = get_errno(acct(path(p)));
             unlock_user(p, arg1, 0);
         }
@@ -8679,7 +8683,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_umount2
     case TARGET_NR_umount2:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(umount2(p, arg2));
         unlock_user(p, arg1, 0);
         return ret;
@@ -8712,7 +8716,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         return get_errno(umask(arg1));
     case TARGET_NR_chroot:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(chroot(p));
         unlock_user(p, arg1, 0);
         return ret;
@@ -8762,7 +8766,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct target_old_sigaction *old_act;
             if (arg2) {
                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
-                    goto efault;
+                    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;
@@ -8773,7 +8777,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(do_sigaction(arg1, pact, &oact));
             if (!is_error(ret) && arg3) {
                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
-                    goto efault;
+                    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;
@@ -8784,7 +8788,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
 	    if (arg2) {
                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
-                    goto efault;
+                    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;
@@ -8798,7 +8802,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
 	    if (!is_error(ret) && arg3) {
                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
-                    goto efault;
+                    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];
@@ -8812,7 +8816,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct target_sigaction act, oact, *pact;
             if (arg2) {
                 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
-                    goto efault;
+                    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;
@@ -8828,7 +8832,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(do_sigaction(arg1, pact, &oact));
             if (!is_error(ret) && arg3) {
                 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
-                    goto efault;
+                    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;
@@ -8858,7 +8862,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
             if (arg2) {
                 if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 act._sa_handler = rt_act->_sa_handler;
                 act.sa_mask = rt_act->sa_mask;
                 act.sa_flags = rt_act->sa_flags;
@@ -8869,7 +8873,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(do_sigaction(arg1, pact, &oact));
             if (!is_error(ret) && arg3) {
                 if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 rt_act->_sa_handler = oact._sa_handler;
                 rt_act->sa_mask = oact.sa_mask;
                 rt_act->sa_flags = oact.sa_flags;
@@ -8890,7 +8894,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
             if (arg2) {
                 if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
 #ifdef TARGET_ARCH_HAS_KA_RESTORER
                 act->ka_restorer = restorer;
@@ -8992,7 +8996,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     goto fail;
                 }
                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 target_to_host_old_sigset(&set, p);
                 unlock_user(p, arg2, 0);
                 set_ptr = &set;
@@ -9003,7 +9007,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = do_sigprocmask(how, set_ptr, &oldset);
             if (!is_error(ret) && arg3) {
                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 host_to_target_old_sigset(p, &oldset);
                 unlock_user(p, arg3, sizeof(target_sigset_t));
             }
@@ -9036,7 +9040,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     goto fail;
                 }
                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 target_to_host_sigset(&set, p);
                 unlock_user(p, arg2, 0);
                 set_ptr = &set;
@@ -9047,7 +9051,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = do_sigprocmask(how, set_ptr, &oldset);
             if (!is_error(ret) && arg3) {
                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 host_to_target_sigset(p, &oldset);
                 unlock_user(p, arg3, sizeof(target_sigset_t));
             }
@@ -9060,7 +9064,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(sigpending(&set));
             if (!is_error(ret)) {
                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 host_to_target_old_sigset(p, &set);
                 unlock_user(p, arg1, sizeof(target_sigset_t));
             }
@@ -9083,7 +9087,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(sigpending(&set));
             if (!is_error(ret)) {
                 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 host_to_target_sigset(p, &set);
                 unlock_user(p, arg1, sizeof(target_sigset_t));
             }
@@ -9098,7 +9102,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             target_to_host_old_sigset(&ts->sigsuspend_mask, &mask);
 #else
             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
-                goto efault;
+                return -TARGET_EFAULT;
             target_to_host_old_sigset(&ts->sigsuspend_mask, p);
             unlock_user(p, arg1, 0);
 #endif
@@ -9118,7 +9122,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 return -TARGET_EINVAL;
             }
             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
-                goto efault;
+                return -TARGET_EFAULT;
             target_to_host_sigset(&ts->sigsuspend_mask, p);
             unlock_user(p, arg1, 0);
             ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
@@ -9139,7 +9143,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
 
             if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
-                goto efault;
+                return -TARGET_EFAULT;
             target_to_host_sigset(&set, p);
             unlock_user(p, arg1, 0);
             if (arg3) {
@@ -9155,7 +9159,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t),
                                   0);
                     if (!p) {
-                        goto efault;
+                        return -TARGET_EFAULT;
                     }
                     host_to_target_siginfo(p, &uinfo);
                     unlock_user(p, arg2, sizeof(target_siginfo_t));
@@ -9170,7 +9174,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
             p = lock_user(VERIFY_READ, arg3, sizeof(target_siginfo_t), 1);
             if (!p) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             target_to_host_siginfo(&uinfo, p);
             unlock_user(p, arg3, 0);
@@ -9183,7 +9187,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
             p = lock_user(VERIFY_READ, arg4, sizeof(target_siginfo_t), 1);
             if (!p) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             target_to_host_siginfo(&uinfo, p);
             unlock_user(p, arg4, 0);
@@ -9204,7 +9208,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         return do_rt_sigreturn(cpu_env);
     case TARGET_NR_sethostname:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(sethostname(p, arg2));
         unlock_user(p, arg1, 0);
         return ret;
@@ -9215,7 +9219,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct target_rlimit *target_rlim;
             struct rlimit rlim;
             if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
-                goto efault;
+                return -TARGET_EFAULT;
             rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
             rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
             unlock_user_struct(target_rlim, arg2, 0);
@@ -9232,7 +9236,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(getrlimit(resource, &rlim));
             if (!is_error(ret)) {
                 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
                 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
                 unlock_user_struct(target_rlim, arg2, 1);
@@ -9255,7 +9259,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(gettimeofday(&tv, NULL));
             if (!is_error(ret)) {
                 if (copy_to_user_timeval(arg1, &tv))
-                    goto efault;
+                    return -TARGET_EFAULT;
             }
         }
         return ret;
@@ -9266,14 +9270,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
             if (arg1) {
                 if (copy_from_user_timeval(&tv, arg1)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
                 ptv = &tv;
             }
 
             if (arg2) {
                 if (copy_from_user_timezone(&tz, arg2)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
                 ptz = &tz;
             }
@@ -9340,7 +9344,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
              */
             if (ts_addr) {
                 if (target_to_host_timespec(&ts, ts_addr)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
                 ts_ptr = &ts;
             } else {
@@ -9354,7 +9358,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
                 arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
                 if (!arg7) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
                 arg_sigset = tswapal(arg7[0]);
                 arg_sigsize = tswapal(arg7[1]);
@@ -9370,7 +9374,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     target_sigset = lock_user(VERIFY_READ, arg_sigset,
                                               sizeof(*target_sigset), 1);
                     if (!target_sigset) {
-                        goto efault;
+                        return -TARGET_EFAULT;
                     }
                     target_to_host_sigset(&set, target_sigset);
                     unlock_user(target_sigset, arg_sigset, 0);
@@ -9386,14 +9390,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
             if (!is_error(ret)) {
                 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
-                    goto efault;
+                    return -TARGET_EFAULT;
 
                 if (ts_addr && host_to_target_timespec(ts_addr, &ts))
-                    goto efault;
+                    return -TARGET_EFAULT;
             }
         }
         return ret;
@@ -9492,7 +9496,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_swapon
     case TARGET_NR_swapon:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(swapon(p, arg2));
         unlock_user(p, arg1, 0);
         return ret;
@@ -9502,7 +9506,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
            /* arg4 must be ignored in all other cases */
            p = lock_user_string(arg4);
            if (!p) {
-              goto efault;
+               return -TARGET_EFAULT;
            }
            ret = get_errno(reboot(arg1, arg2, arg3, p));
            unlock_user(p, arg4, 0);
@@ -9524,7 +9528,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             abi_ulong *v;
             abi_ulong v1, v2, v3, v4, v5, v6;
             if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
-                goto efault;
+                return -TARGET_EFAULT;
             v1 = tswapal(v[0]);
             v2 = tswapal(v[1]);
             v3 = tswapal(v[2]);
@@ -9597,7 +9601,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_truncate
     case TARGET_NR_truncate:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(truncate(p, arg2));
         unlock_user(p, arg1, 0);
         return ret;
@@ -9611,7 +9615,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_NR_fchmodat)
     case TARGET_NR_fchmodat:
         if (!(p = lock_user_string(arg2)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(fchmodat(arg1, p, arg3, 0));
         unlock_user(p, arg2, 0);
         return ret;
@@ -9640,8 +9644,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_statfs
     case TARGET_NR_statfs:
-        if (!(p = lock_user_string(arg1)))
-            goto efault;
+        if (!(p = lock_user_string(arg1))) {
+            return -TARGET_EFAULT;
+        }
         ret = get_errno(statfs(path(p), &stfs));
         unlock_user(p, arg1, 0);
     convert_statfs:
@@ -9649,7 +9654,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct target_statfs *target_stfs;
 
             if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
-                goto efault;
+                return -TARGET_EFAULT;
             __put_user(stfs.f_type, &target_stfs->f_type);
             __put_user(stfs.f_bsize, &target_stfs->f_bsize);
             __put_user(stfs.f_blocks, &target_stfs->f_blocks);
@@ -9678,8 +9683,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_statfs64
     case TARGET_NR_statfs64:
-        if (!(p = lock_user_string(arg1)))
-            goto efault;
+        if (!(p = lock_user_string(arg1))) {
+            return -TARGET_EFAULT;
+        }
         ret = get_errno(statfs(path(p), &stfs));
         unlock_user(p, arg1, 0);
     convert_statfs64:
@@ -9687,7 +9693,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct target_statfs64 *target_stfs;
 
             if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
-                goto efault;
+                return -TARGET_EFAULT;
             __put_user(stfs.f_type, &target_stfs->f_type);
             __put_user(stfs.f_bsize, &target_stfs->f_bsize);
             __put_user(stfs.f_blocks, &target_stfs->f_blocks);
@@ -9785,7 +9791,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_getrandom:
         p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
         if (!p) {
-            goto efault;
+            return -TARGET_EFAULT;
         }
         ret = get_errno(getrandom(p, arg2, arg3));
         unlock_user(p, arg1, ret);
@@ -9853,7 +9859,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
                     || copy_from_user_timeval(&pvalue->it_value,
                                               arg2 + sizeof(struct target_timeval)))
-                    goto efault;
+                    return -TARGET_EFAULT;
             } else {
                 pvalue = NULL;
             }
@@ -9863,7 +9869,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                                          &ovalue.it_interval)
                     || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
                                             &ovalue.it_value))
-                    goto efault;
+                    return -TARGET_EFAULT;
             }
         }
         return ret;
@@ -9877,22 +9883,24 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                                          &value.it_interval)
                     || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
                                             &value.it_value))
-                    goto efault;
+                    return -TARGET_EFAULT;
             }
         }
         return ret;
 #ifdef TARGET_NR_stat
     case TARGET_NR_stat:
-        if (!(p = lock_user_string(arg1)))
-            goto efault;
+        if (!(p = lock_user_string(arg1))) {
+            return -TARGET_EFAULT;
+        }
         ret = get_errno(stat(path(p), &st));
         unlock_user(p, arg1, 0);
         goto do_stat;
 #endif
 #ifdef TARGET_NR_lstat
     case TARGET_NR_lstat:
-        if (!(p = lock_user_string(arg1)))
-            goto efault;
+        if (!(p = lock_user_string(arg1))) {
+            return -TARGET_EFAULT;
+        }
         ret = get_errno(lstat(path(p), &st));
         unlock_user(p, arg1, 0);
         goto do_stat;
@@ -9908,7 +9916,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 struct target_stat *target_st;
 
                 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 memset(target_st, 0, sizeof(*target_st));
                 __put_user(st.st_dev, &target_st->st_dev);
                 __put_user(st.st_ino, &target_st->st_ino);
@@ -9963,7 +9971,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (status_ptr && ret) {
                     status = host_to_target_waitstatus(status);
                     if (put_user_s32(status, status_ptr))
-                        goto efault;
+                        return -TARGET_EFAULT;
                 }
                 if (target_rusage) {
                     rusage_err = host_to_target_rusage(target_rusage, &rusage);
@@ -9977,7 +9985,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_swapoff
     case TARGET_NR_swapoff:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(swapoff(p));
         unlock_user(p, arg1, 0);
         return ret;
@@ -9990,7 +9998,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             if (!is_error(ret) && arg1)
             {
                 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 __put_user(value.uptime, &target_value->uptime);
                 __put_user(value.loads[0], &target_value->loads[0]);
                 __put_user(value.loads[1], &target_value->loads[1]);
@@ -10084,7 +10092,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
     case TARGET_NR_setdomainname:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(setdomainname(p, arg2));
         unlock_user(p, arg1, 0);
         return ret;
@@ -10094,7 +10102,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct new_utsname * buf;
 
             if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
-                goto efault;
+                return -TARGET_EFAULT;
             ret = get_errno(sys_uname(buf));
             if (!is_error(ret)) {
                 /* Overwrite the native machine name with whatever is being
@@ -10125,12 +10133,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct timex host_buf;
 
             if (target_to_host_timex(&host_buf, arg1) != 0) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             ret = get_errno(adjtimex(&host_buf));
             if (!is_error(ret)) {
                 if (host_to_target_timex(arg1, &host_buf) != 0) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
             }
         }
@@ -10141,12 +10149,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct timex htx, *phtx = &htx;
 
             if (target_to_host_timex(phtx, arg2) != 0) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             ret = get_errno(clock_adjtime(arg1, phtx));
             if (!is_error(ret) && phtx) {
                 if (host_to_target_timex(arg2, phtx) != 0) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
             }
         }
@@ -10196,7 +10204,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
 #endif
             if ((ret == 0) && put_user_s64(res, arg4)) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
         }
         return ret;
@@ -10227,7 +10235,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 		count1 = 0;
                 de = dirp;
                 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
-                    goto efault;
+                    return -TARGET_EFAULT;
 		tde = target_dirp;
                 while (len > 0) {
                     reclen = de->d_reclen;
@@ -10255,7 +10263,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             abi_long count = arg3;
 
             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
-                goto efault;
+                return -TARGET_EFAULT;
             ret = get_errno(sys_getdents(arg1, dirp, count));
             if (!is_error(ret)) {
                 struct linux_dirent *de;
@@ -10284,7 +10292,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
             dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
             if (!dirp) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             ret = get_errno(sys_getdents64(arg1, dirp, count));
             if (!is_error(ret)) {
@@ -10339,7 +10347,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct linux_dirent64 *dirp;
             abi_long count = arg3;
             if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
-                goto efault;
+                return -TARGET_EFAULT;
             ret = get_errno(sys_getdents64(arg1, dirp, count));
             if (!is_error(ret)) {
                 struct linux_dirent64 *de;
@@ -10388,7 +10396,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 target_pfd = lock_user(VERIFY_WRITE, arg1,
                                        sizeof(struct target_pollfd) * nfds, 1);
                 if (!target_pfd) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
 
                 pfd = alloca(sizeof(struct pollfd) * nfds);
@@ -10409,7 +10417,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (arg3) {
                     if (target_to_host_timespec(timeout_ts, arg3)) {
                         unlock_user(target_pfd, arg1, 0);
-                        goto efault;
+                        return -TARGET_EFAULT;
                     }
                 } else {
                     timeout_ts = NULL;
@@ -10424,7 +10432,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
                     if (!target_set) {
                         unlock_user(target_pfd, arg1, 0);
-                        goto efault;
+                        return -TARGET_EFAULT;
                     }
                     target_to_host_sigset(set, target_set);
                 } else {
@@ -10579,7 +10587,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 }
 
                 if (host_to_target_cpu_mask(mask, mask_size, arg3, ret)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
             }
         }
@@ -10616,10 +10624,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 goto fail;
             }
             if (arg1 && put_user_u32(cpu, arg1)) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             if (arg2 && put_user_u32(node, arg2)) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
         }
         return ret;
@@ -10632,7 +10640,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 return -TARGET_EINVAL;
             }
             if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
-                goto efault;
+                return -TARGET_EFAULT;
             schp.sched_priority = tswap32(target_schp->sched_priority);
             unlock_user_struct(target_schp, arg2, 0);
             return get_errno(sched_setparam(arg1, &schp));
@@ -10648,7 +10656,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(sched_getparam(arg1, &schp));
             if (!is_error(ret)) {
                 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
-                    goto efault;
+                    return -TARGET_EFAULT;
                 target_schp->sched_priority = tswap32(schp.sched_priority);
                 unlock_user_struct(target_schp, arg2, 1);
             }
@@ -10662,7 +10670,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 return -TARGET_EINVAL;
             }
             if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
-                goto efault;
+                return -TARGET_EFAULT;
             schp.sched_priority = tswap32(target_schp->sched_priority);
             unlock_user_struct(target_schp, arg3, 0);
             return get_errno(sched_setscheduler(arg1, arg2, &schp));
@@ -10710,7 +10718,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
             if (!is_error(ret) && arg2
                 && put_user_ual(deathsig, arg2)) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             return ret;
         }
@@ -10719,7 +10727,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         {
             void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
             if (!name) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             ret = get_errno(prctl(arg1, (unsigned long)name,
                                   arg3, arg4, arg5));
@@ -10730,7 +10738,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         {
             void *name = lock_user(VERIFY_READ, arg2, 16, 1);
             if (!name) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             ret = get_errno(prctl(arg1, (unsigned long)name,
                                   arg3, arg4, arg5));
@@ -10797,7 +10805,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             arg5 = arg6;
         }
         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
         unlock_user(p, arg2, ret);
         return ret;
@@ -10807,14 +10815,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             arg5 = arg6;
         }
         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
         unlock_user(p, arg2, 0);
         return ret;
 #endif
     case TARGET_NR_getcwd:
         if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(sys_getcwd1(p, arg2));
         unlock_user(p, arg1, ret);
         return ret;
@@ -10830,7 +10838,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         int data_items = 1;
 
         if (!lock_user_struct(VERIFY_WRITE, target_header, arg1, 1)) {
-            goto efault;
+            return -TARGET_EFAULT;
         }
         header.version = tswap32(target_header->version);
         header.pid = tswap32(target_header->pid);
@@ -10850,7 +10858,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
             if (!target_data) {
                 unlock_user_struct(target_header, arg1, 0);
-                goto efault;
+                return -TARGET_EFAULT;
             }
 
             if (num == TARGET_NR_capset) {
@@ -10968,7 +10976,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 	if (!is_error(ret)) {
 	    struct target_rlimit *target_rlim;
             if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
-                goto efault;
+                return -TARGET_EFAULT;
 	    target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
 	    target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
             unlock_user_struct(target_rlim, arg2, 1);
@@ -10979,7 +10987,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_truncate64
     case TARGET_NR_truncate64:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
 	ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
         unlock_user(p, arg1, 0);
         return ret;
@@ -10990,8 +10998,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_stat64
     case TARGET_NR_stat64:
-        if (!(p = lock_user_string(arg1)))
-            goto efault;
+        if (!(p = lock_user_string(arg1))) {
+            return -TARGET_EFAULT;
+        }
         ret = get_errno(stat(path(p), &st));
         unlock_user(p, arg1, 0);
         if (!is_error(ret))
@@ -11000,8 +11009,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_lstat64
     case TARGET_NR_lstat64:
-        if (!(p = lock_user_string(arg1)))
-            goto efault;
+        if (!(p = lock_user_string(arg1))) {
+            return -TARGET_EFAULT;
+        }
         ret = get_errno(lstat(path(p), &st));
         unlock_user(p, arg1, 0);
         if (!is_error(ret))
@@ -11022,9 +11032,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_newfstatat
     case TARGET_NR_newfstatat:
 #endif
-        if (!(p = lock_user_string(arg2)))
-            goto efault;
+        if (!(p = lock_user_string(arg2))) {
+            return -TARGET_EFAULT;
+        }
         ret = get_errno(fstatat(arg1, path(p), &st, arg4));
+        unlock_user(p, arg2, 0);
         if (!is_error(ret))
             ret = host_to_target_stat64(cpu_env, arg3, &st);
         return ret;
@@ -11032,7 +11044,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_lchown
     case TARGET_NR_lchown:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
         unlock_user(p, arg1, 0);
         return ret;
@@ -11071,7 +11083,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             if (!is_error(ret)) {
                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
                 if (!target_grouplist)
-                    goto efault;
+                    return -TARGET_EFAULT;
                 for(i = 0;i < ret; i++)
                     target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
                 unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
@@ -11103,7 +11115,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_NR_fchownat)
     case TARGET_NR_fchownat:
         if (!(p = lock_user_string(arg2))) 
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
                                  low2highgid(arg4), arg5));
         unlock_user(p, arg2, 0);
@@ -11124,7 +11136,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (put_user_id(high2lowuid(ruid), arg1)
                     || put_user_id(high2lowuid(euid), arg2)
                     || put_user_id(high2lowuid(suid), arg3))
-                    goto efault;
+                    return -TARGET_EFAULT;
             }
         }
         return ret;
@@ -11144,7 +11156,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (put_user_id(high2lowgid(rgid), arg1)
                     || put_user_id(high2lowgid(egid), arg2)
                     || put_user_id(high2lowgid(sgid), arg3))
-                    goto efault;
+                    return -TARGET_EFAULT;
             }
         }
         return ret;
@@ -11152,7 +11164,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_chown
     case TARGET_NR_chown:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
         unlock_user(p, arg1, 0);
         return ret;
@@ -11169,7 +11181,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_lchown32
     case TARGET_NR_lchown32:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(lchown(p, arg2, arg3));
         unlock_user(p, arg1, 0);
         return ret;
@@ -11220,7 +11232,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
 
                 if (put_user_u64 (swcr, arg2))
-                        goto efault;
+                        return -TARGET_EFAULT;
                 ret = 0;
             }
             break;
@@ -11247,7 +11259,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 uint64_t swcr, fpcr, orig_fpcr;
 
                 if (get_user_u64 (swcr, arg2)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
                 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
                 fpcr = orig_fpcr & FPCR_DYN_MASK;
@@ -11274,7 +11286,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 int si_code;
 
                 if (get_user_u64(exc, arg2)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
 
                 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
@@ -11443,7 +11455,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (put_user_u32(ruid, arg1)
                     || put_user_u32(euid, arg2)
                     || put_user_u32(suid, arg3))
-                    goto efault;
+                    return -TARGET_EFAULT;
             }
         }
         return ret;
@@ -11461,7 +11473,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (put_user_u32(rgid, arg1)
                     || put_user_u32(egid, arg2)
                     || put_user_u32(sgid, arg3))
-                    goto efault;
+                    return -TARGET_EFAULT;
             }
         }
         return ret;
@@ -11469,7 +11481,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_chown32
     case TARGET_NR_chown32:
         if (!(p = lock_user_string(arg1)))
-            goto efault;
+            return -TARGET_EFAULT;
         ret = get_errno(chown(p, arg2, arg3));
         unlock_user(p, arg1, 0);
         return ret;
@@ -12032,13 +12044,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             pposix_mq_attr = NULL;
             if (arg4) {
                 if (copy_from_user_mq_attr(&posix_mq_attr, arg4) != 0) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
                 pposix_mq_attr = &posix_mq_attr;
             }
             p = lock_user_string(arg1 - 1);
             if (!p) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             ret = get_errno(mq_open(p, host_flags, arg3, pposix_mq_attr));
             unlock_user (p, arg1, 0);
@@ -12128,25 +12140,25 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             loff_t *ploff_in = NULL, *ploff_out = NULL;
             if (arg2) {
                 if (get_user_u64(loff_in, arg2)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
                 ploff_in = &loff_in;
             }
             if (arg4) {
                 if (get_user_u64(loff_out, arg4)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
                 ploff_out = &loff_out;
             }
             ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
             if (arg2) {
                 if (put_user_u64(loff_in, arg2)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
             }
             if (arg4) {
                 if (put_user_u64(loff_out, arg4)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
             }
         }
@@ -12256,7 +12268,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         if (arg4) {
             struct target_epoll_event *target_ep;
             if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             ep.events = tswap32(target_ep->events);
             /* The epoll_data_t union is just opaque data to the kernel,
@@ -12292,7 +12304,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         target_ep = lock_user(VERIFY_WRITE, arg2,
                               maxevents * sizeof(struct target_epoll_event), 1);
         if (!target_ep) {
-            goto efault;
+            return -TARGET_EFAULT;
         }
 
         ep = g_try_new(struct epoll_event, maxevents);
@@ -12365,7 +12377,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         int resource = target_to_host_resource(arg2);
         if (arg3) {
             if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
             rnew.rlim_max = tswap64(target_rnew->rlim_max);
@@ -12376,7 +12388,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(sys_prlimit64(arg1, resource, rnewp, arg4 ? &rold : 0));
         if (!is_error(ret) && arg4) {
             if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             target_rold->rlim_cur = tswap64(rold.rlim_cur);
             target_rold->rlim_max = tswap64(rold.rlim_max);
@@ -12454,7 +12466,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 phtimer = NULL;
             } else {
                 if (put_user(TIMER_MAGIC | timer_index, arg3, target_timer_t)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
             }
         }
@@ -12478,12 +12490,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
 
             if (target_to_host_itimerspec(&hspec_new, arg3)) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
             ret = get_errno(
                           timer_settime(htimer, arg2, &hspec_new, &hspec_old));
             if (arg4 && host_to_target_itimerspec(arg4, &hspec_old)) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
         }
         return ret;
@@ -12561,7 +12573,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(timerfd_gettime(arg1, &its_curr));
 
             if (arg2 && host_to_target_itimerspec(arg2, &its_curr)) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
         }
         return ret;
@@ -12574,7 +12586,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
             if (arg3) {
                 if (target_to_host_itimerspec(&its_new, arg3)) {
-                    goto efault;
+                    return -TARGET_EFAULT;
                 }
                 p_new = &its_new;
             } else {
@@ -12584,7 +12596,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(timerfd_settime(arg1, arg2, p_new, &its_old));
 
             if (arg4 && host_to_target_itimerspec(arg4, &its_old)) {
-                goto efault;
+                return -TARGET_EFAULT;
             }
         }
         return ret;
@@ -12628,9 +12640,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     }
 fail:
     return ret;
-efault:
-    ret = -TARGET_EFAULT;
-    goto fail;
 }
 
 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 05/16] linux-user: Propagate goto unimplemented_nowarn to return
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (3 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 04/16] linux-user: Propagate goto efault to return Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 06/16] linux-user: Propagate goto unimplemented to default Richard Henderson
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 23c3cd5ddd..812fb27fa1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -11870,7 +11870,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
           return 0;
       }
 #else
-      goto unimplemented_nowarn;
+      return -TARGET_ENOSYS;
 #endif
 #endif
 #ifdef TARGET_NR_get_thread_area
@@ -11883,12 +11883,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             return ts->tp_value;
         }
 #else
-        goto unimplemented_nowarn;
+        return -TARGET_ENOSYS;
 #endif
 #endif
 #ifdef TARGET_NR_getdomainname
     case TARGET_NR_getdomainname:
-        goto unimplemented_nowarn;
+        return -TARGET_ENOSYS;
 #endif
 
 #ifdef TARGET_NR_clock_settime
@@ -11973,7 +11973,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
          * holding a mutex that is shared with another process via
          * shared memory).
          */
-        goto unimplemented_nowarn;
+        return -TARGET_ENOSYS;
 #endif
 
 #if defined(TARGET_NR_utimensat)
@@ -12633,9 +12633,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     default:
     unimplemented:
         qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
-#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
-    unimplemented_nowarn:
-#endif
         return -TARGET_ENOSYS;
     }
 fail:
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 06/16] linux-user: Propagate goto unimplemented to default
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (4 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 05/16] linux-user: Propagate goto unimplemented_nowarn " Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-21 16:35   ` Laurent Vivier
  2018-08-21 18:45   ` Philippe Mathieu-Daudé
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 07/16] linux-user: Propagate goto fail to return Richard Henderson
                   ` (10 subsequent siblings)
  16 siblings, 2 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

There is no point in listing a syscall if you want the same effect as
not listing it.  In one less trivial case, the goto was demonstrably
not reachable.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.c | 144 +------------------------------------------
 1 file changed, 1 insertion(+), 143 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 812fb27fa1..ef3b9b623c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8341,14 +8341,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         unlock_user(p, arg1, 0);
         return ret;
 #endif
-#ifdef TARGET_NR_break
-    case TARGET_NR_break:
-        goto unimplemented;
-#endif
-#ifdef TARGET_NR_oldstat
-    case TARGET_NR_oldstat:
-        goto unimplemented;
-#endif
 #ifdef TARGET_NR_lseek
     case TARGET_NR_lseek:
         return get_errno(lseek(arg1, arg2, arg3));
@@ -8435,16 +8427,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             return get_errno(stime(&host_time));
         }
 #endif
-    case TARGET_NR_ptrace:
-        goto unimplemented;
 #ifdef TARGET_NR_alarm /* not on alpha */
     case TARGET_NR_alarm:
         return alarm(arg1);
 #endif
-#ifdef TARGET_NR_oldfstat
-    case TARGET_NR_oldfstat:
-        goto unimplemented;
-#endif
 #ifdef TARGET_NR_pause /* not on alpha */
     case TARGET_NR_pause:
         if (!block_signals()) {
@@ -8515,14 +8501,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         }
         return ret;
 #endif
-#ifdef TARGET_NR_stty
-    case TARGET_NR_stty:
-        goto unimplemented;
-#endif
-#ifdef TARGET_NR_gtty
-    case TARGET_NR_gtty:
-        goto unimplemented;
-#endif
 #ifdef TARGET_NR_access
     case TARGET_NR_access:
         if (!(p = lock_user_string(arg1))) {
@@ -8544,10 +8522,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_nice /* not on alpha */
     case TARGET_NR_nice:
         return get_errno(nice(arg1));
-#endif
-#ifdef TARGET_NR_ftime
-    case TARGET_NR_ftime:
-        goto unimplemented;
 #endif
     case TARGET_NR_sync:
         sync();
@@ -8661,14 +8635,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = host_to_target_clock_t(ret);
         }
         return ret;
-#ifdef TARGET_NR_prof
-    case TARGET_NR_prof:
-        goto unimplemented;
-#endif
-#ifdef TARGET_NR_signal
-    case TARGET_NR_signal:
-        goto unimplemented;
-#endif
     case TARGET_NR_acct:
         if (arg1 == 0) {
             ret = get_errno(acct(NULL));
@@ -8687,31 +8653,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(umount2(p, arg2));
         unlock_user(p, arg1, 0);
         return ret;
-#endif
-#ifdef TARGET_NR_lock
-    case TARGET_NR_lock:
-        goto unimplemented;
 #endif
     case TARGET_NR_ioctl:
         return do_ioctl(arg1, arg2, arg3);
 #ifdef TARGET_NR_fcntl
     case TARGET_NR_fcntl:
         return do_fcntl(arg1, arg2, arg3);
-#endif
-#ifdef TARGET_NR_mpx
-    case TARGET_NR_mpx:
-        goto unimplemented;
 #endif
     case TARGET_NR_setpgid:
         return get_errno(setpgid(arg1, arg2));
-#ifdef TARGET_NR_ulimit
-    case TARGET_NR_ulimit:
-        goto unimplemented;
-#endif
-#ifdef TARGET_NR_oldolduname
-    case TARGET_NR_oldolduname:
-        goto unimplemented;
-#endif
     case TARGET_NR_umask:
         return get_errno(umask(arg1));
     case TARGET_NR_chroot:
@@ -8720,10 +8670,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(chroot(p));
         unlock_user(p, arg1, 0);
         return ret;
-#ifdef TARGET_NR_ustat
-    case TARGET_NR_ustat:
-        goto unimplemented;
-#endif
 #ifdef TARGET_NR_dup2
     case TARGET_NR_dup2:
         ret = get_errno(dup2(arg1, arg2));
@@ -9432,10 +9378,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         }
         return ret;
 #endif
-#ifdef TARGET_NR_oldlstat
-    case TARGET_NR_oldlstat:
-        goto unimplemented;
-#endif
 #ifdef TARGET_NR_readlink
     case TARGET_NR_readlink:
         {
@@ -9489,10 +9431,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         }
         return ret;
 #endif
-#ifdef TARGET_NR_uselib
-    case TARGET_NR_uselib:
-        goto unimplemented;
-#endif
 #ifdef TARGET_NR_swapon
     case TARGET_NR_swapon:
         if (!(p = lock_user_string(arg1)))
@@ -9514,10 +9452,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
            ret = get_errno(reboot(arg1, arg2, arg3, NULL));
         }
         return ret;
-#ifdef TARGET_NR_readdir
-    case TARGET_NR_readdir:
-        goto unimplemented;
-#endif
 #ifdef TARGET_NR_mmap
     case TARGET_NR_mmap:
 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
@@ -9638,10 +9572,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         return ret;
     case TARGET_NR_setpriority:
         return get_errno(setpriority(arg1, arg2, arg3));
-#ifdef TARGET_NR_profil
-    case TARGET_NR_profil:
-        goto unimplemented;
-#endif
 #ifdef TARGET_NR_statfs
     case TARGET_NR_statfs:
         if (!(p = lock_user_string(arg1))) {
@@ -9713,10 +9643,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(fstatfs(arg1, &stfs));
         goto convert_statfs64;
 #endif
-#ifdef TARGET_NR_ioperm
-    case TARGET_NR_ioperm:
-        goto unimplemented;
-#endif
 #ifdef TARGET_NR_socketcall
     case TARGET_NR_socketcall:
         return do_socketcall(arg1, arg2);
@@ -9935,21 +9861,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
         }
         return ret;
-#endif
-#ifdef TARGET_NR_olduname
-    case TARGET_NR_olduname:
-        goto unimplemented;
-#endif
-#ifdef TARGET_NR_iopl
-    case TARGET_NR_iopl:
-        goto unimplemented;
 #endif
     case TARGET_NR_vhangup:
         return get_errno(vhangup());
-#ifdef TARGET_NR_idle
-    case TARGET_NR_idle:
-        goto unimplemented;
-#endif
 #ifdef TARGET_NR_syscall
     case TARGET_NR_syscall:
         return do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
@@ -10122,8 +10036,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_modify_ldt:
         return do_modify_ldt(cpu_env, arg1, arg2, arg3);
 #if !defined(TARGET_X86_64)
-    case TARGET_NR_vm86old:
-        goto unimplemented;
     case TARGET_NR_vm86:
         return do_vm86(cpu_env, arg1, arg2);
 #endif
@@ -10160,35 +10072,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         }
         return ret;
 #endif
-#ifdef TARGET_NR_create_module
-    case TARGET_NR_create_module:
-#endif
-    case TARGET_NR_init_module:
-    case TARGET_NR_delete_module:
-#ifdef TARGET_NR_get_kernel_syms
-    case TARGET_NR_get_kernel_syms:
-#endif
-        goto unimplemented;
-    case TARGET_NR_quotactl:
-        goto unimplemented;
     case TARGET_NR_getpgid:
         return get_errno(getpgid(arg1));
     case TARGET_NR_fchdir:
         return get_errno(fchdir(arg1));
-#ifdef TARGET_NR_bdflush /* not on x86_64 */
-    case TARGET_NR_bdflush:
-        goto unimplemented;
-#endif
-#ifdef TARGET_NR_sysfs
-    case TARGET_NR_sysfs:
-        goto unimplemented;
-#endif
     case TARGET_NR_personality:
         return get_errno(personality(arg1));
-#ifdef TARGET_NR_afs_syscall
-    case TARGET_NR_afs_syscall:
-        goto unimplemented;
-#endif
 #ifdef TARGET_NR__llseek /* Not on alpha */
     case TARGET_NR__llseek:
         {
@@ -10702,14 +10591,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
         }
         return ret;
-#ifdef TARGET_NR_query_module
-    case TARGET_NR_query_module:
-        goto unimplemented;
-#endif
-#ifdef TARGET_NR_nfsservctl
-    case TARGET_NR_nfsservctl:
-        goto unimplemented;
-#endif
     case TARGET_NR_prctl:
         switch (arg1) {
         case PR_GET_PDEATHSIG:
@@ -10795,7 +10676,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
         return do_arch_prctl(cpu_env, arg1, arg2);
 #else
-        goto unimplemented;
+#error unreachable
 #endif
 #endif
 #ifdef TARGET_NR_pread64
@@ -10945,21 +10826,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         return ret;
     }
 #endif
-#else
-    case TARGET_NR_sendfile:
-#ifdef TARGET_NR_sendfile64
-    case TARGET_NR_sendfile64:
-#endif
-        goto unimplemented;
-#endif
-
-#ifdef TARGET_NR_getpmsg
-    case TARGET_NR_getpmsg:
-        goto unimplemented;
-#endif
-#ifdef TARGET_NR_putpmsg
-    case TARGET_NR_putpmsg:
-        goto unimplemented;
 #endif
 #ifdef TARGET_NR_vfork
     case TARGET_NR_vfork:
@@ -11502,9 +11368,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_setfsgid32:
         return get_errno(setfsgid(arg1));
 #endif
-
-    case TARGET_NR_pivot_root:
-        goto unimplemented;
 #ifdef TARGET_NR_mincore
     case TARGET_NR_mincore:
         {
@@ -11662,10 +11525,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         /* self-modifying code is handled automatically, so nothing needed */
         return 0;
 #endif
-#ifdef TARGET_NR_security
-    case TARGET_NR_security:
-        goto unimplemented;
-#endif
 #ifdef TARGET_NR_getpagesize
     case TARGET_NR_getpagesize:
         return TARGET_PAGE_SIZE;
@@ -12631,7 +12490,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
 
     default:
-    unimplemented:
         qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
         return -TARGET_ENOSYS;
     }
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 07/16] linux-user: Propagate goto fail to return
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (5 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 06/16] linux-user: Propagate goto unimplemented to default Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 08/16] configure: Use -Wunused-const-variable Richard Henderson
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.c | 60 ++++++++++++++++----------------------------
 1 file changed, 22 insertions(+), 38 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ef3b9b623c..4ae608fb19 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8910,8 +8910,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 how = SIG_SETMASK;
                 break;
             default:
-                ret = -TARGET_EINVAL;
-                goto fail;
+                return -TARGET_EINVAL;
             }
             mask = arg2;
             target_to_host_old_sigset(&set, &mask);
@@ -8938,8 +8937,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     how = SIG_SETMASK;
                     break;
                 default:
-                    ret = -TARGET_EINVAL;
-                    goto fail;
+                    return -TARGET_EINVAL;
                 }
                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
                     return -TARGET_EFAULT;
@@ -8982,8 +8980,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     how = SIG_SETMASK;
                     break;
                 default:
-                    ret = -TARGET_EINVAL;
-                    goto fail;
+                    return -TARGET_EINVAL;
                 }
                 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
                     return -TARGET_EFAULT;
@@ -9273,15 +9270,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
             ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
             if (ret) {
-                goto fail;
+                return ret;
             }
             ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
             if (ret) {
-                goto fail;
+                return ret;
             }
             ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
             if (ret) {
-                goto fail;
+                return ret;
             }
 
             /*
@@ -9314,8 +9311,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     sig.set = &set;
                     if (arg_sigsize != sizeof(*target_sigset)) {
                         /* Like the kernel, we enforce correct size sigsets */
-                        ret = -TARGET_EINVAL;
-                        goto fail;
+                        return -TARGET_EINVAL;
                     }
                     target_sigset = lock_user(VERIFY_READ, arg_sigset,
                                               sizeof(*target_sigset), 1);
@@ -9754,17 +9750,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             case TARGET_SYSLOG_ACTION_READ_CLEAR:    /* Read/clear msgs */
             case TARGET_SYSLOG_ACTION_READ_ALL:      /* Read last messages */
                 {
-                    ret = -TARGET_EINVAL;
                     if (len < 0) {
-                        goto fail;
+                        return -TARGET_EINVAL;
                     }
                     if (len == 0) {
                         return 0;
                     }
                     p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
                     if (!p) {
-                        ret = -TARGET_EFAULT;
-                        goto fail;
+                        return -TARGET_EFAULT;
                     }
                     ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
                     unlock_user(p, arg2, arg3);
@@ -10109,8 +10103,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
             dirp = g_try_malloc(count);
             if (!dirp) {
-                ret = -TARGET_ENOMEM;
-                goto fail;
+                return -TARGET_ENOMEM;
             }
 
             ret = get_errno(sys_getdents(arg1, dirp, count));
@@ -10510,7 +10503,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                                        arg2 ? &node : NULL,
                                        NULL));
             if (is_error(ret)) {
-                goto fail;
+                return ret;
             }
             if (arg1 && put_user_u32(cpu, arg1)) {
                 return -TARGET_EFAULT;
@@ -10966,8 +10959,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 grouplist = alloca(gidsetsize * sizeof(gid_t));
                 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
                 if (!target_grouplist) {
-                    ret = -TARGET_EFAULT;
-                    goto fail;
+                    return -TARGET_EFAULT;
                 }
                 for (i = 0; i < gidsetsize; i++) {
                     grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
@@ -11225,8 +11217,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 how = SIG_SETMASK;
                 break;
             default:
-                ret = -TARGET_EINVAL;
-                goto fail;
+                return -TARGET_EINVAL;
             }
             mask = arg2;
             target_to_host_old_sigset(&set, &mask);
@@ -11274,8 +11265,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             if (!is_error(ret)) {
                 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
                 if (!target_grouplist) {
-                    ret = -TARGET_EFAULT;
-                    goto fail;
+                    return -TARGET_EFAULT;
                 }
                 for(i = 0;i < ret; i++)
                     target_grouplist[i] = tswap32(grouplist[i]);
@@ -11295,8 +11285,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             grouplist = alloca(gidsetsize * sizeof(gid_t));
             target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
             if (!target_grouplist) {
-                ret = -TARGET_EFAULT;
-                goto fail;
+                return -TARGET_EFAULT;
             }
             for(i = 0;i < gidsetsize; i++)
                 grouplist[i] = tswap32(target_grouplist[i]);
@@ -11371,20 +11360,17 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_mincore
     case TARGET_NR_mincore:
         {
-            void *a;
-            ret = -TARGET_ENOMEM;
-            a = lock_user(VERIFY_READ, arg1, arg2, 0);
+            void *a = lock_user(VERIFY_READ, arg1, arg2, 0);
             if (!a) {
-                goto fail;
+                return -TARGET_ENOMEM;
             }
-            ret = -TARGET_EFAULT;
             p = lock_user_string(arg3);
             if (!p) {
-                goto mincore_fail;
+                ret = -TARGET_EFAULT;
+            } else {
+                ret = get_errno(mincore(a, arg2, p));
+                unlock_user(p, arg3, ret);
             }
-            ret = get_errno(mincore(a, arg2, p));
-            unlock_user(p, arg3, ret);
-            mincore_fail:
             unlock_user(a, arg1, 0);
         }
         return ret;
@@ -11850,8 +11836,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
             else {
                 if (!(p = lock_user_string(arg2))) {
-                    ret = -TARGET_EFAULT;
-                    goto fail;
+                    return -TARGET_EFAULT;
                 }
                 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
                 unlock_user(p, arg2, 0);
@@ -12493,7 +12478,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
         return -TARGET_ENOSYS;
     }
-fail:
     return ret;
 }
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 08/16] configure: Use -Wunused-const-variable
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (6 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 07/16] linux-user: Propagate goto fail to return Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-21 17:29   ` Laurent Vivier
                     ` (2 more replies)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 09/16] linux-user: Setup split syscall infrastructure Richard Henderson
                   ` (8 subsequent siblings)
  16 siblings, 3 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

For the linux-user syscall split, we have static const structs
that must be matched up with a switch statement that uses them.
By default, gcc will not warn for such a variable, but silently
remove them.

For C++, such objects are sometimes declared for their constructor
side effects.  Do not propagate this flag into QEM_CXXFLAGS.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 configure | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index db97930314..86e6e18428 100755
--- a/configure
+++ b/configure
@@ -105,7 +105,8 @@ update_cxxflags() {
     for arg in $QEMU_CFLAGS; do
         case $arg in
             -Wstrict-prototypes|-Wmissing-prototypes|-Wnested-externs|\
-            -Wold-style-declaration|-Wold-style-definition|-Wredundant-decls)
+            -Wold-style-declaration|-Wold-style-definition|-Wredundant-decls|\
+            -Wunused-const-variable)
                 ;;
             *)
                 QEMU_CXXFLAGS=${QEMU_CXXFLAGS:+$QEMU_CXXFLAGS }$arg
@@ -1780,6 +1781,7 @@ gcc_flags="-Wendif-labels -Wno-shift-negative-value $gcc_flags"
 gcc_flags="-Wno-initializer-overrides -Wexpansion-to-defined $gcc_flags"
 gcc_flags="-Wno-string-plus-int $gcc_flags"
 gcc_flags="-Wno-error=address-of-packed-member $gcc_flags"
+gcc_flags="-Wunused-const-variable $gcc_flags"
 # Note that we do not add -Werror to gcc_flags here, because that would
 # enable it for all configure tests. If a configure test failed due
 # to -Werror this would just silently disable some features,
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 09/16] linux-user: Setup split syscall infrastructure
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (7 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 08/16] configure: Use -Wunused-const-variable Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 10/16] linux-user: Split out some simple file syscalls Richard Henderson
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Defines a unified structure for implementation and strace.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.h | 114 +++++++++++++
 linux-user/strace.c  | 386 +++++++++++++++++++++++++++++++------------
 linux-user/syscall.c |  59 ++++++-
 3 files changed, 446 insertions(+), 113 deletions(-)
 create mode 100644 linux-user/syscall.h

diff --git a/linux-user/syscall.h b/linux-user/syscall.h
new file mode 100644
index 0000000000..f84b40d742
--- /dev/null
+++ b/linux-user/syscall.h
@@ -0,0 +1,114 @@
+/*
+ *  Linux syscalls internals
+ *  Copyright (c) 2018 Linaro, Limited.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+typedef struct SyscallDef SyscallDef;
+
+/*
+ * This hook extracts max 6 arguments from max 8 input registers.
+ * In the process, register pairs that store 64-bit arguments are merged.
+ * Finally, syscalls are demultipliexed; e.g. the hook for socketcall will
+ * return the SyscallDef for bind, listen, etc.  In the process the hook
+ * may need to read from guest memory, or otherwise validate operands.
+ * On failure, set errno (to a host value) and return NULL;
+ * the (target adjusted) errno will be returned to the guest.
+ */
+typedef const SyscallDef *SyscallArgsFn(const SyscallDef *, int64_t out[6],
+                                        abi_long in[8]);
+
+/* This hook implements the syscall.  */
+typedef abi_long SyscallImplFn(CPUArchState *, int64_t, int64_t, int64_t,
+                               int64_t, int64_t, int64_t);
+
+/* This hook prints the arguments to the syscall for strace.  */
+typedef void SyscallPrintFn(const SyscallDef *, int64_t arg[6]);
+
+/* This hook print the return value from the syscall for strace.  */
+typedef void SyscallPrintRetFn(const SyscallDef *, abi_long);
+
+/*
+ * These flags describe the arguments for the generic fallback to
+ * SyscallPrintFn.  ARG_NONE indicates that the argument is not present.
+ */
+typedef enum {
+    ARG_NONE = 0,
+
+    /* These print as numbers of abi_long.  */
+    ARG_DEC,
+    ARG_HEX,
+    ARG_OCT,
+
+    /* These print as sets of flags.  */
+    ARG_ATDIRFD,
+    ARG_MODEFLAG,
+    ARG_OPENFLAG,
+
+    /* These are interpreted as pointers.  */
+    ARG_PTR,
+    ARG_STR,
+    ARG_BUF,
+
+    /* For a 32-bit host, force printing as a 64-bit operand.  */
+#if TARGET_ABI_BITS == 32
+    ARG_DEC64,
+#else
+    ARG_DEC64 = ARG_DEC,
+#endif
+} SyscallArgType;
+
+struct SyscallDef {
+    const char *name;
+    SyscallArgsFn *args;
+    SyscallImplFn *impl;
+    SyscallPrintFn *print;
+    SyscallPrintRetFn *print_ret;
+    SyscallArgType arg_type[6];
+};
+
+void print_syscall_def(const SyscallDef *def, int64_t args[6]);
+void print_syscall_def_ret(const SyscallDef *def, abi_long ret);
+void print_syscall_ptr_ret(const SyscallDef *def, abi_long ret);
+
+/* Emit the signature for a SyscallArgsFn.  */
+#define SYSCALL_ARGS(NAME) \
+    static const SyscallDef *args_##NAME(const SyscallDef *def, \
+                                         int64_t out[6], abi_long in[8])
+
+/* Emit the signature for a SyscallImplFn.  */
+#define SYSCALL_IMPL(NAME) \
+    static abi_long impl_##NAME(CPUArchState *cpu_env, int64_t arg1, \
+                                int64_t arg2, int64_t arg3, int64_t arg4, \
+                                int64_t arg5, int64_t arg6)
+
+/*
+ * Emit the definition for a "simple" syscall.  Such does not use
+ * SyscallArgsFn and only uses arg_type for strace.
+ */
+#define SYSCALL_DEF(NAME, ...) \
+    static const SyscallDef def_##NAME = { \
+        .name = #NAME, .impl = impl_##NAME, .arg_type = { __VA_ARGS__ } \
+    }
+
+/*
+ * Emit the definition for a syscall that also has an args hook,
+ * and uses arg_type for strace.
+ */
+#define SYSCALL_DEF_ARGS(NAME, ...) \
+    static const SyscallDef def_##NAME = { \
+        .name = #NAME, .args = args_##NAME, .impl = impl_##NAME, \
+        .arg_type = { __VA_ARGS__ } \
+    }
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 33f4a506a2..792644cc0d 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -10,6 +10,7 @@
 #include <linux/if_packet.h>
 #include <sched.h>
 #include "qemu.h"
+#include "syscall.h"
 
 int do_strace=0;
 
@@ -796,7 +797,7 @@ UNUSED static struct flags unlinkat_flags[] = {
     FLAG_END,
 };
 
-UNUSED static struct flags mode_flags[] = {
+static struct flags const mode_flags[] = {
     FLAG_GENERIC(S_IFSOCK),
     FLAG_GENERIC(S_IFLNK),
     FLAG_GENERIC(S_IFREG),
@@ -807,14 +808,14 @@ UNUSED static struct flags mode_flags[] = {
     FLAG_END,
 };
 
-UNUSED static struct flags open_access_flags[] = {
+static struct flags const open_access_flags[] = {
     FLAG_TARGET(O_RDONLY),
     FLAG_TARGET(O_WRONLY),
     FLAG_TARGET(O_RDWR),
     FLAG_END,
 };
 
-UNUSED static struct flags open_flags[] = {
+static struct flags const open_flags[] = {
     FLAG_TARGET(O_APPEND),
     FLAG_TARGET(O_CREAT),
     FLAG_TARGET(O_DIRECTORY),
@@ -989,84 +990,86 @@ get_comma(int last)
     return ((last) ? "" : ",");
 }
 
+static int add_flags(char *buf, int size, const struct flags *f,
+                     int flags, bool octal)
+{
+    const char *sep = "";
+    int off = 0;
+
+    if (flags == 0 && f->f_value == 0) {
+        return snprintf(buf, size, "%s", f->f_string);
+    }
+
+    for (; f->f_string != NULL; f++) {
+        if (f->f_value != 0 && (flags & f->f_value) == f->f_value) {
+            off += snprintf(buf + off, size - off, "%s%s", sep, f->f_string);
+            flags &= ~f->f_value;
+            sep = "|";
+        }
+    }
+
+    /* Print rest of the flags as numeric.  */
+    if (flags) {
+        if (octal) {
+            off += snprintf(buf + off, size - off, "%s%#o", sep, flags);
+        } else {
+            off += snprintf(buf + off, size - off, "%s%#x", sep, flags);
+        }
+    }
+    return off;
+}
+
 static void
 print_flags(const struct flags *f, abi_long flags, int last)
 {
-    const char *sep = "";
-    int n;
+    char buf[256];
+    add_flags(buf, sizeof(buf), f, flags, false);
+    gemu_log("%s%s", buf, get_comma(last));
+}
 
-    if ((flags == 0) && (f->f_value == 0)) {
-        gemu_log("%s%s", f->f_string, get_comma(last));
-        return;
-    }
-    for (n = 0; f->f_string != NULL; f++) {
-        if ((f->f_value != 0) && ((flags & f->f_value) == f->f_value)) {
-            gemu_log("%s%s", sep, f->f_string);
-            flags &= ~f->f_value;
-            sep = "|";
-            n++;
-        }
-    }
-
-    if (n > 0) {
-        /* print rest of the flags as numeric */
-        if (flags != 0) {
-            gemu_log("%s%#x%s", sep, (unsigned int)flags, get_comma(last));
-        } else {
-            gemu_log("%s", get_comma(last));
-        }
+static int add_atdirfd(char *buf, int size, int fd)
+{
+    if (fd == AT_FDCWD) {
+        return snprintf(buf, size, "AT_FDCWD");
     } else {
-        /* no string version of flags found, print them in hex then */
-        gemu_log("%#x%s", (unsigned int)flags, get_comma(last));
+        return snprintf(buf, size, "%d", fd);
     }
 }
 
 static void
 print_at_dirfd(abi_long dirfd, int last)
 {
-#ifdef AT_FDCWD
-    if (dirfd == AT_FDCWD) {
-        gemu_log("AT_FDCWD%s", get_comma(last));
-        return;
-    }
-#endif
-    gemu_log("%d%s", (int)dirfd, get_comma(last));
+    char buf[16];
+    add_atdirfd(buf, sizeof(buf), dirfd);
+    gemu_log("%s%s", buf, get_comma(last));
 }
 
 static void
 print_file_mode(abi_long mode, int last)
 {
-    const char *sep = "";
-    const struct flags *m;
+    char buf[256];
+    add_flags(buf, sizeof(buf), mode_flags, mode, true);
+    gemu_log("%s%s", buf, get_comma(last));
+}
 
-    for (m = &mode_flags[0]; m->f_string != NULL; m++) {
-        if ((m->f_value & mode) == m->f_value) {
-            gemu_log("%s%s", m->f_string, sep);
-            sep = "|";
-            mode &= ~m->f_value;
-            break;
-        }
+static int add_open_flags(char *buf, int size, int flags)
+{
+    int off = add_flags(buf, size, open_access_flags,
+                        flags & TARGET_O_ACCMODE, false);
+    flags &= ~TARGET_O_ACCMODE;
+    if (flags == 0 || off + 2 >= size) {
+        return off;
     }
-
-    mode &= ~S_IFMT;
-    /* print rest of the mode as octal */
-    if (mode != 0)
-        gemu_log("%s%#o", sep, (unsigned int)mode);
-
-    gemu_log("%s", get_comma(last));
+    buf[off++] = '|';
+    return off + add_flags(buf + off, size - off, open_flags, flags, true);
 }
 
 static void
 print_open_flags(abi_long flags, int last)
 {
-    print_flags(open_access_flags, flags & TARGET_O_ACCMODE, 1);
-    flags &= ~TARGET_O_ACCMODE;
-    if (flags == 0) {
-        gemu_log("%s", get_comma(last));
-        return;
-    }
-    gemu_log("|");
-    print_flags(open_flags, flags, last);
+    char buf[256];
+    add_open_flags(buf, sizeof(buf), flags);
+    gemu_log("%s%s", buf, get_comma(last));
 }
 
 static void
@@ -1083,48 +1086,86 @@ print_syscall_epilogue(const struct syscallname *sc)
     gemu_log(")");
 }
 
-static void
-print_string(abi_long addr, int last)
+static int add_pointer(char *buf, int size, abi_ulong addr)
 {
-    char *s;
-
-    if ((s = lock_user_string(addr)) != NULL) {
-        gemu_log("\"%s\"%s", s, get_comma(last));
-        unlock_user(s, addr, 0);
+    if (addr) {
+        return snprintf(buf, size, "0x" TARGET_ABI_FMT_lx, addr);
     } else {
-        /* can't get string out of it, so print it as pointer */
-        print_pointer(addr, last);
+        return snprintf(buf, size, "NULL");
     }
 }
 
+static int add_string(char *buf, int size, abi_ulong addr)
+{
+    char *s = lock_user_string(addr);
+    if (s) {
+        /* TODO: Escape special characters within the string.  */
+        /* TODO: Limit the string length for logging.  */
+        int len = snprintf(buf, size, "\"%s\"", s);
+        unlock_user(s, addr, 0);
+        return len;
+    }
+    return add_pointer(buf, size, addr);
+}
+
+static void
+print_string(abi_long addr, int last)
+{
+    char buf[256];
+    add_string(buf, sizeof(buf), addr);
+    gemu_log("%s%s", buf, get_comma(last));
+}
+
 #define MAX_PRINT_BUF 40
+
+static int add_buffer(char *buf, int size, abi_long addr, abi_ulong len)
+{
+    unsigned char *p;
+    int off = 0;
+    abi_ulong i;
+
+    p = lock_user(VERIFY_READ, addr, MIN(len, MAX_PRINT_BUF), 1);
+    if (!p) {
+        return add_pointer(buf, size, addr);
+    }
+
+    buf[0] = '"';
+    off = 1;
+
+    for (i = 0; i < MAX_PRINT_BUF; ++i) {
+        int len;
+
+        if (isprint(p[i])) {
+            buf[off] = p[i];
+            len = 1;
+        } else {
+            len = snprintf(buf + off, size - off, "\\%o", p[i]);
+        }
+        off += len;
+        if (off + 2 >= size) {
+            goto overflow;
+        }
+    }
+    unlock_user(p, addr, 0);
+
+    if (i == len && off + 2 < size) {
+        buf[off] = '"';
+        buf[off + 1] = 0;
+        return off + 1;
+    }
+
+ overflow:
+    off = MIN(off, size - 5);
+    strcpy(buf + off, "...\"");
+    return off + 4;
+}
+
 static void
 print_buf(abi_long addr, abi_long len, int last)
 {
-    uint8_t *s;
-    int i;
-
-    s = lock_user(VERIFY_READ, addr, len, 1);
-    if (s) {
-        gemu_log("\"");
-        for (i = 0; i < MAX_PRINT_BUF && i < len; i++) {
-            if (isprint(s[i])) {
-                gemu_log("%c", s[i]);
-            } else {
-                gemu_log("\\%o", s[i]);
-            }
-        }
-        gemu_log("\"");
-        if (i != len) {
-            gemu_log("...");
-        }
-        if (!last) {
-            gemu_log(",");
-        }
-        unlock_user(s, addr, 0);
-    } else {
-        print_pointer(addr, last);
-    }
+    char buf[256];
+    add_buffer(buf, sizeof(buf), addr, len);
+    gemu_log("%s%s", buf, get_comma(last));
 }
 
 /*
@@ -1143,10 +1184,9 @@ print_raw_param(const char *fmt, abi_long param, int last)
 static void
 print_pointer(abi_long p, int last)
 {
-    if (p == 0)
-        gemu_log("NULL%s", get_comma(last));
-    else
-        gemu_log("0x" TARGET_ABI_FMT_lx "%s", p, get_comma(last));
+    char buf[24];
+    add_pointer(buf, sizeof(buf), p);
+    gemu_log("%s%s", buf, get_comma(last));
 }
 
 /*
@@ -2635,32 +2675,168 @@ print_syscall(int num,
     gemu_log("Unknown syscall %d\n", num);
 }
 
+static void print_syscall_def1(const SyscallDef *def, int64_t args[6])
+{
+    char buf[1024], *b = buf;
+    int i, rest = sizeof(buf);
+
+    /* Render the argument list into BUF.  This allows us to log the
+     * entire syscall in one write statement at the end.
+     * While this is still not quite as good as separate files, a-la
+     * strace -ff, it can minimize confusion with a multithreaded guest.
+     */
+    buf[0] = 0;
+    for (i = 0; i < 6; ++i) {
+        SyscallArgType type = def->arg_type[i];
+        int64_t arg = args[i];
+        int len;
+
+        if (type == ARG_NONE) {
+            break;
+        }
+
+        /* Validate remaining space.  */
+        if (rest < 4) {
+            goto overflow;
+        }
+
+        /* Add separator.  */
+        if (i > 0) {
+            b[0] = ',';
+            b[1] = ' ';
+            b += 2;
+            rest -= 2;
+        }
+
+        switch (type) {
+#if TARGET_ABI_BITS == 32
+        /* ??? We don't have TARGET_ABI_FMT_* macros for exactly
+         * what we want here.  For this case it probably makes
+         * most sense to just special case.
+         */
+        case ARG_DEC:
+            len = snprintf(b, rest, "%d", (int32_t)arg);
+            break;
+        case ARG_HEX:
+            len = snprintf(b, rest, "%#x", (uint32_t)arg);
+            break;
+        case ARG_OCT:
+            len = snprintf(b, rest, "%#o", (uint32_t)arg);
+            break;
+        case ARG_DEC64:
+            len = snprintf(b, rest, "%" PRId64, arg);
+            break;
+#else
+        case ARG_DEC:
+            len = snprintf(b, rest, "%" PRId64, arg);
+            break;
+        case ARG_OCT:
+            len = snprintf(b, rest, "%" PRIo64, arg);
+            break;
+        case ARG_HEX:
+            len = snprintf(b, rest, "%" PRIx64, arg);
+            break;
+#endif
+        case ARG_ATDIRFD:
+            len = add_atdirfd(b, rest, arg);
+            break;
+        case ARG_MODEFLAG:
+            len = add_flags(b, rest, mode_flags, arg, true);
+            break;
+        case ARG_OPENFLAG:
+            len = add_open_flags(b, rest, arg);
+            break;
+        case ARG_PTR:
+            len = add_pointer(b, rest, arg);
+            break;
+        case ARG_STR:
+            len = add_string(b, rest, arg);
+            break;
+        case ARG_BUF:
+            len = add_buffer(b, rest, arg, MAX_PRINT_BUF);
+            break;
+        default:
+            g_assert_not_reached();
+        }
+
+        b += len;
+        rest -= len;
+        if (rest == 0) {
+            goto overflow;
+        }
+    }
+    goto done;
+
+ overflow:
+    strcpy(buf + sizeof(buf) - 4, "...");
+ done:
+    gemu_log("%d %s(%s)", getpid(), def->name, buf);
+}
+
+void print_syscall_def(const SyscallDef *def, int64_t args[6])
+{
+    SyscallPrintFn *print = def->print;
+    if (!print) {
+        print = print_syscall_def1;
+    }
+    print(def, args);
+}
+
+static void print_syscall_def_ret1(const SyscallDef *def, abi_long ret)
+{
+    if (is_error(ret)) {
+        const char *errstr = target_strerror(-ret);
+        if (errstr) {
+            gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n",
+                     -ret, errstr);
+        } else {
+            gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld "\n", -ret);
+        }
+    } else {
+        gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
+    }
+}
 
 void
 print_syscall_ret(int num, abi_long ret)
 {
     int i;
-    const char *errstr = NULL;
 
     for(i=0;i<nsyscalls;i++)
         if( scnames[i].nr == num ) {
             if( scnames[i].result != NULL ) {
                 scnames[i].result(&scnames[i],ret);
             } else {
-                if (ret < 0) {
-                    errstr = target_strerror(-ret);
-                }
-                if (errstr) {
-                    gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n",
-                             -ret, errstr);
-                } else {
-                    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
-                }
+                print_syscall_def_ret1(NULL, ret);
             }
             break;
         }
 }
 
+void print_syscall_ptr_ret(const SyscallDef *def, abi_long ret)
+{
+    if (is_error(ret)) {
+        const char *errstr = target_strerror(-ret);
+        if (errstr) {
+            gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n",
+                     -ret, errstr);
+        } else {
+            gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld "\n", -ret);
+        }
+    } else {
+        gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
+    }
+}
+
+void print_syscall_def_ret(const SyscallDef *def, abi_long ret)
+{
+    SyscallPrintRetFn *print = def->print_ret;
+    if (!print) {
+        print = print_syscall_def_ret1;
+    }
+    print(def, ret);
+}
+
 void print_taken_signal(int target_signum, const target_siginfo_t *tinfo)
 {
     /* Print the strace output for a signal being taken:
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 4ae608fb19..3b59f7ed65 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -111,6 +111,7 @@
 #include "uname.h"
 
 #include "qemu.h"
+#include "syscall.h"
 
 #ifndef CLONE_IO
 #define CLONE_IO                0x80000000      /* Clone io context */
@@ -12481,12 +12482,26 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     return ret;
 }
 
+static const SyscallDef *syscall_table(int num)
+{
+#define S(NAME)  case TARGET_NR_##NAME: return &def_##NAME;
+
+    switch (num) {
+    }
+    return NULL;
+
+#undef S
+}
+
 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     abi_long arg2, abi_long arg3, abi_long arg4,
                     abi_long arg5, abi_long arg6, abi_long arg7,
                     abi_long arg8)
 {
     CPUState *cpu = ENV_GET_CPU(cpu_env);
+    const SyscallDef *def, *orig_def;
+    abi_long raw_args[8] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 };
+    int64_t  out_args[6] = { arg1, arg2, arg3, arg4, arg5, arg6 };
     abi_long ret;
 
 #ifdef DEBUG_ERESTARTSYS
@@ -12506,16 +12521,44 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4,
                              arg5, arg6, arg7, arg8);
 
-    if (unlikely(do_strace)) {
-        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
-        ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4,
-                          arg5, arg6, arg7, arg8);
-        print_syscall_ret(num, ret);
-    } else {
-        ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4,
-                          arg5, arg6, arg7, arg8);
+    orig_def = def = syscall_table(num);
+    if (def == NULL) {
+        /* Unconverted.  */
+        if (unlikely(do_strace)) {
+            print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
+            ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4,
+                              arg5, arg6, arg7, arg8);
+            print_syscall_ret(num, ret);
+        } else {
+            ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4,
+                              arg5, arg6, arg7, arg8);
+        }
+        goto fini;
     }
 
+    if (def->args) {
+        def = def->args(def, out_args, raw_args);
+        if (unlikely(def == NULL)) {
+            ret = -host_to_target_errno(errno);
+            if (unlikely(do_strace)) {
+                print_syscall_def(orig_def, out_args);
+                print_syscall_def_ret(orig_def, ret);
+            }
+            goto fini;
+        }
+    }
+
+    if (unlikely(do_strace)) {
+        print_syscall_def(def, out_args);
+        ret = def->impl(cpu_env, out_args[0], out_args[1], out_args[2],
+                        out_args[3], out_args[4], out_args[5]);
+        print_syscall_def_ret(def, ret);
+    } else {
+        ret = def->impl(cpu_env, out_args[0], out_args[1], out_args[2],
+                        out_args[3], out_args[4], out_args[5]);
+    }
+
+ fini:
     trace_guest_user_syscall_ret(cpu, num, ret);
     return ret;
 }
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 10/16] linux-user: Split out some simple file syscalls
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (8 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 09/16] linux-user: Setup split syscall infrastructure Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-22  0:50   ` Laurent Vivier
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 11/16] linux-user: Split out preadv, pwritev, readv, writev Richard Henderson
                   ` (6 subsequent siblings)
  16 siblings, 1 reply; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

This includes close, open, openat, read, readlink, readlinkat, write.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/strace.c           |  64 -----
 linux-user/syscall-file.inc.c | 440 ++++++++++++++++++++++++++++++++++
 linux-user/syscall.c          | 393 ++----------------------------
 linux-user/strace.list        |  21 --
 4 files changed, 463 insertions(+), 455 deletions(-)
 create mode 100644 linux-user/syscall-file.inc.c

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 792644cc0d..11e0c86554 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -2213,41 +2213,6 @@ print_mq_open(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_open
-static void
-print_open(const struct syscallname *name,
-    abi_long arg0, abi_long arg1, abi_long arg2,
-    abi_long arg3, abi_long arg4, abi_long arg5)
-{
-    int is_creat = (arg1 & TARGET_O_CREAT);
-
-    print_syscall_prologue(name);
-    print_string(arg0, 0);
-    print_open_flags(arg1, (is_creat == 0));
-    if (is_creat)
-        print_file_mode(arg2, 1);
-    print_syscall_epilogue(name);
-}
-#endif
-
-#ifdef TARGET_NR_openat
-static void
-print_openat(const struct syscallname *name,
-    abi_long arg0, abi_long arg1, abi_long arg2,
-    abi_long arg3, abi_long arg4, abi_long arg5)
-{
-    int is_creat = (arg2 & TARGET_O_CREAT);
-
-    print_syscall_prologue(name);
-    print_at_dirfd(arg0, 0);
-    print_string(arg1, 0);
-    print_open_flags(arg2, (is_creat == 0));
-    if (is_creat)
-        print_file_mode(arg3, 1);
-    print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_mq_unlink
 static void
 print_mq_unlink(const struct syscallname *name,
@@ -2276,35 +2241,6 @@ print_fstatat64(const struct syscallname *name,
 #define print_newfstatat    print_fstatat64
 #endif
 
-#ifdef TARGET_NR_readlink
-static void
-print_readlink(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_string(arg0, 0);
-    print_pointer(arg1, 0);
-    print_raw_param("%u", arg2, 1);
-    print_syscall_epilogue(name);
-}
-#endif
-
-#ifdef TARGET_NR_readlinkat
-static void
-print_readlinkat(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_at_dirfd(arg0, 0);
-    print_string(arg1, 0);
-    print_pointer(arg2, 0);
-    print_raw_param("%u", arg3, 1);
-    print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_rename
 static void
 print_rename(const struct syscallname *name,
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
new file mode 100644
index 0000000000..aecc63682f
--- /dev/null
+++ b/linux-user/syscall-file.inc.c
@@ -0,0 +1,440 @@
+/*
+ *  Linux file-related syscalls
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*
+ * Helpers for do_openat, manipulating /proc/self/foo.
+ */
+
+static int open_self_cmdline(void *cpu_env, int fd)
+{
+    CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
+    struct linux_binprm *bprm = ((TaskState *)cpu->opaque)->bprm;
+    int i;
+
+    for (i = 0; i < bprm->argc; i++) {
+        size_t len = strlen(bprm->argv[i]) + 1;
+
+        if (write(fd, bprm->argv[i], len) != len) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static int open_self_maps(void *cpu_env, int fd)
+{
+    CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
+    TaskState *ts = cpu->opaque;
+    FILE *fp;
+    char *line = NULL;
+    size_t len = 0;
+    ssize_t read;
+
+    fp = fopen("/proc/self/maps", "r");
+    if (fp == NULL) {
+        return -1;
+    }
+
+    while ((read = getline(&line, &len, fp)) != -1) {
+        int fields, dev_maj, dev_min, inode;
+        uint64_t min, max, offset;
+        char flag_r, flag_w, flag_x, flag_p;
+        char path[512] = "";
+
+        fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"
+                        PRIx64" %x:%x %d %512s",
+                        &min, &max, &flag_r, &flag_w, &flag_x,
+                        &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
+
+        if ((fields < 10) || (fields > 11)) {
+            continue;
+        }
+        if (h2g_valid(min)) {
+            int flags = page_get_flags(h2g(min));
+
+            if (!h2g_valid(max - 1)) {
+                max = (uintptr_t)g2h(GUEST_ADDR_MAX) + 1;
+            }
+            if (page_check_range(h2g(min), max - min, flags) == -1) {
+                continue;
+            }
+            if (h2g(min) == ts->info->stack_limit) {
+                pstrcpy(path, sizeof(path), "      [stack]");
+            }
+            dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
+                    " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
+                    h2g(min), h2g(max - 1) + 1, flag_r, flag_w,
+                    flag_x, flag_p, offset, dev_maj, dev_min, inode,
+                    path[0] ? "         " : "", path);
+        }
+    }
+
+    free(line);
+    fclose(fp);
+
+    return 0;
+}
+
+static int open_self_stat(void *cpu_env, int fd)
+{
+    CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
+    TaskState *ts = cpu->opaque;
+    abi_ulong start_stack = ts->info->start_stack;
+    int i;
+
+    for (i = 0; i < 44; i++) {
+        char buf[128];
+        int len;
+        uint64_t val = 0;
+
+        if (i == 0) {
+            /* pid */
+            val = getpid();
+            snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
+        } else if (i == 1) {
+            /* app name */
+            snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
+        } else if (i == 27) {
+            /* stack bottom */
+            val = start_stack;
+            snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
+        } else {
+            /* for the rest, there is MasterCard */
+            snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
+        }
+
+        len = strlen(buf);
+        if (write(fd, buf, len) != len) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static int open_self_auxv(void *cpu_env, int fd)
+{
+    CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
+    TaskState *ts = cpu->opaque;
+    abi_ulong auxv = ts->info->saved_auxv;
+    abi_ulong len = ts->info->auxv_len;
+    char *ptr;
+
+    /*
+     * Auxiliary vector is stored in target process stack.
+     * read in whole auxv vector and copy it to file
+     */
+    ptr = lock_user(VERIFY_READ, auxv, len, 0);
+    if (ptr != NULL) {
+        while (len > 0) {
+            ssize_t r;
+            r = write(fd, ptr, len);
+            if (r <= 0) {
+                break;
+            }
+            len -= r;
+            ptr += r;
+        }
+        lseek(fd, 0, SEEK_SET);
+        unlock_user(ptr, auxv, len);
+    }
+
+    return 0;
+}
+
+static int is_proc_myself(const char *filename, const char *entry)
+{
+    if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
+        filename += strlen("/proc/");
+        if (!strncmp(filename, "self/", strlen("self/"))) {
+            filename += strlen("self/");
+        } else if (*filename >= '1' && *filename <= '9') {
+            char myself[80];
+            snprintf(myself, sizeof(myself), "%d/", getpid());
+            if (!strncmp(filename, myself, strlen(myself))) {
+                filename += strlen(myself);
+            } else {
+                return 0;
+            }
+        } else {
+            return 0;
+        }
+        if (!strcmp(filename, entry)) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+static int is_proc(const char *filename, const char *entry)
+{
+    return strcmp(filename, entry) == 0;
+}
+
+static int open_net_route(void *cpu_env, int fd)
+{
+    FILE *fp;
+    char *line = NULL;
+    size_t len = 0;
+    ssize_t read;
+
+    fp = fopen("/proc/net/route", "r");
+    if (fp == NULL) {
+        return -1;
+    }
+
+    /* read header */
+
+    read = getline(&line, &len, fp);
+    dprintf(fd, "%s", line);
+
+    /* read routes */
+
+    while ((read = getline(&line, &len, fp)) != -1) {
+        char iface[16];
+        uint32_t dest, gw, mask;
+        unsigned int flags, refcnt, use, metric, mtu, window, irtt;
+        sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
+               iface, &dest, &gw, &flags, &refcnt, &use, &metric,
+               &mask, &mtu, &window, &irtt);
+        dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
+                iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
+                metric, tswap32(mask), mtu, window, irtt);
+    }
+
+    free(line);
+    fclose(fp);
+
+    return 0;
+}
+#endif
+
+static abi_long do_openat(void *cpu_env, int dirfd, abi_ulong target_path,
+                          int target_flags, int mode)
+{
+    struct fake_open {
+        const char *filename;
+        int (*fill)(void *cpu_env, int fd);
+        int (*cmp)(const char *s1, const char *s2);
+    };
+    static const struct fake_open fakes[] = {
+        { "maps", open_self_maps, is_proc_myself },
+        { "stat", open_self_stat, is_proc_myself },
+        { "auxv", open_self_auxv, is_proc_myself },
+        { "cmdline", open_self_cmdline, is_proc_myself },
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+        { "/proc/net/route", open_net_route, is_proc },
+#endif
+    };
+
+    char *pathname = lock_user_string(target_path);
+    int flags = target_to_host_bitmask(target_flags, fcntl_flags_tbl);
+    int i, ret;
+
+    if (!pathname) {
+        return -TARGET_EFAULT;
+    }
+
+    if (is_proc_myself(pathname, "exe")) {
+        ret = qemu_getauxval(AT_EXECFD);
+        if (ret == 0) {
+            ret = get_errno(safe_openat(dirfd, exec_path, flags, mode));
+        }
+        goto done;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(fakes); ++i) {
+        if (fakes[i].cmp(pathname, fakes[i].filename)) {
+            const char *tmpdir;
+            char filename[PATH_MAX];
+            int r;
+
+            /* Create temporary file.  */
+            tmpdir = getenv("TMPDIR");
+            if (!tmpdir) {
+                tmpdir = "/tmp";
+            }
+            snprintf(filename, sizeof(filename),
+                     "%s/qemu-open.XXXXXX", tmpdir);
+            ret = mkstemp(filename);
+            if (ret < 0) {
+                ret = -TARGET_ENOENT;
+                goto done;
+            }
+            unlink(filename);
+
+            /* Add contents to the temporary file.  */
+            r = fakes[i].fill(cpu_env, ret);
+            if (r) {
+                close(ret);
+                ret = -TARGET_ENOENT;
+                goto done;
+            }
+
+            /* Reset pointer to the beginning.  */
+            lseek(ret, 0, SEEK_SET);
+            goto done;
+        }
+    }
+    ret = get_errno(safe_openat(dirfd, path(pathname), flags, mode));
+
+ done:
+    fd_trans_unregister(ret);
+    unlock_user(pathname, target_path, 0);
+    return ret;
+}
+
+SYSCALL_IMPL(close)
+{
+    fd_trans_unregister(arg1);
+    return get_errno(close(arg1));
+}
+SYSCALL_DEF(close, ARG_DEC);
+
+#ifdef TARGET_NR_open
+SYSCALL_IMPL(open)
+{
+    return do_openat(cpu_env, AT_FDCWD, arg1, arg2, arg3);
+}
+SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
+#endif
+
+SYSCALL_IMPL(openat)
+{
+    return do_openat(cpu_env, arg1, arg2, arg3, arg4);
+}
+SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
+
+SYSCALL_IMPL(read)
+{
+    abi_long ret;
+    void *p;
+
+    if (arg3 == 0) {
+        return 0;
+    }
+    p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
+    if (!p) {
+        return -TARGET_EFAULT;
+    }
+    ret = get_errno(safe_read(arg1, p, arg3));
+
+    if (!is_error(ret)) {
+        TargetFdDataFunc trans = fd_trans_host_to_target_data(arg1);
+        if (trans) {
+            ret = trans(p, ret);
+        }
+    }
+    unlock_user(p, arg2, ret);
+    return ret;
+}
+SYSCALL_DEF(read, ARG_DEC, ARG_PTR, ARG_DEC);
+
+static abi_long do_readlink_proc_exe(char *buf, abi_ulong bufsiz)
+{
+    char real[PATH_MAX];
+    char *temp = realpath(exec_path, real);
+    abi_long ret;
+
+    /* Return value is # of bytes that we wrote to the buffer. */
+    if (temp == NULL) {
+        return -host_to_target_errno(errno);
+    }
+    ret = MIN(strlen(real), bufsiz);
+    /* We cannot NUL terminate the string. */
+    memcpy(buf, real, ret);
+    return ret;
+}
+
+#ifdef TARGET_NR_readlink
+SYSCALL_IMPL(readlink)
+{
+    char *p = lock_user_string(arg1);
+    abi_ulong bufsiz = arg3;
+    void *buf = lock_user(VERIFY_WRITE, arg2, bufsiz, 0);
+    abi_long ret;
+
+    if (!p || !buf) {
+        ret = -TARGET_EFAULT;
+    } else if (!bufsiz) {
+        /* Short circuit this for the magic exe check. */
+        ret = -TARGET_EINVAL;
+    } else if (is_proc_myself(p, "exe")) {
+        ret = do_readlink_proc_exe(buf, bufsiz);
+    } else {
+        ret = get_errno(readlink(path(p), buf, bufsiz));
+    }
+    unlock_user(buf, arg2, ret);
+    unlock_user(p, arg1, 0);
+    return ret;
+}
+SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC);
+#endif
+
+#ifdef TARGET_NR_readlinkat
+SYSCALL_IMPL(readlinkat)
+{
+    char *p = lock_user_string(arg2);
+    abi_ulong bufsiz = arg4;
+    void *buf = lock_user(VERIFY_WRITE, arg3, bufsiz, 0);
+    abi_long ret;
+
+    if (!p || !buf) {
+        ret = -TARGET_EFAULT;
+    } else if (!bufsiz) {
+        /* Short circuit this for the magic exe check. */
+        ret = -TARGET_EINVAL;
+    } else if (is_proc_myself(p, "exe")) {
+        ret = do_readlink_proc_exe(buf, bufsiz);
+    } else {
+        ret = get_errno(readlinkat(arg1, path(p), buf, bufsiz));
+    }
+    unlock_user(buf, arg3, ret);
+    unlock_user(p, arg2, 0);
+    return ret;
+}
+SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC);
+#endif
+
+SYSCALL_IMPL(write)
+{
+    TargetFdDataFunc trans = fd_trans_target_to_host_data(arg1);
+    void *p = lock_user(VERIFY_READ, arg2, arg3, 1);
+    abi_long ret;
+
+    if (!p) {
+        return -TARGET_EFAULT;
+    }
+    if (trans) {
+        void *copy = g_malloc(arg3);
+        memcpy(copy, p, arg3);
+        ret = trans(copy, arg3);
+        if (ret >= 0) {
+            ret = get_errno(safe_write(arg1, copy, ret));
+        }
+        g_free(copy);
+    } else {
+        ret = get_errno(safe_write(arg1, p, arg3));
+    }
+    unlock_user(p, arg2, 0);
+    return ret;
+}
+SYSCALL_DEF(write, ARG_DEC, ARG_PTR, ARG_DEC);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3b59f7ed65..f757ae87b0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7589,267 +7589,6 @@ int host_to_target_waitstatus(int status)
     return status;
 }
 
-static int open_self_cmdline(void *cpu_env, int fd)
-{
-    CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
-    struct linux_binprm *bprm = ((TaskState *)cpu->opaque)->bprm;
-    int i;
-
-    for (i = 0; i < bprm->argc; i++) {
-        size_t len = strlen(bprm->argv[i]) + 1;
-
-        if (write(fd, bprm->argv[i], len) != len) {
-            return -1;
-        }
-    }
-
-    return 0;
-}
-
-static int open_self_maps(void *cpu_env, int fd)
-{
-    CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
-    TaskState *ts = cpu->opaque;
-    FILE *fp;
-    char *line = NULL;
-    size_t len = 0;
-    ssize_t read;
-
-    fp = fopen("/proc/self/maps", "r");
-    if (fp == NULL) {
-        return -1;
-    }
-
-    while ((read = getline(&line, &len, fp)) != -1) {
-        int fields, dev_maj, dev_min, inode;
-        uint64_t min, max, offset;
-        char flag_r, flag_w, flag_x, flag_p;
-        char path[512] = "";
-        fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
-                        " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
-                        &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
-
-        if ((fields < 10) || (fields > 11)) {
-            continue;
-        }
-        if (h2g_valid(min)) {
-            int flags = page_get_flags(h2g(min));
-            max = h2g_valid(max - 1) ? max : (uintptr_t)g2h(GUEST_ADDR_MAX) + 1;
-            if (page_check_range(h2g(min), max - min, flags) == -1) {
-                continue;
-            }
-            if (h2g(min) == ts->info->stack_limit) {
-                pstrcpy(path, sizeof(path), "      [stack]");
-            }
-            dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
-                    " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
-                    h2g(min), h2g(max - 1) + 1, flag_r, flag_w,
-                    flag_x, flag_p, offset, dev_maj, dev_min, inode,
-                    path[0] ? "         " : "", path);
-        }
-    }
-
-    free(line);
-    fclose(fp);
-
-    return 0;
-}
-
-static int open_self_stat(void *cpu_env, int fd)
-{
-    CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
-    TaskState *ts = cpu->opaque;
-    abi_ulong start_stack = ts->info->start_stack;
-    int i;
-
-    for (i = 0; i < 44; i++) {
-      char buf[128];
-      int len;
-      uint64_t val = 0;
-
-      if (i == 0) {
-        /* pid */
-        val = getpid();
-        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
-      } else if (i == 1) {
-        /* app name */
-        snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
-      } else if (i == 27) {
-        /* stack bottom */
-        val = start_stack;
-        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
-      } else {
-        /* for the rest, there is MasterCard */
-        snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
-      }
-
-      len = strlen(buf);
-      if (write(fd, buf, len) != len) {
-          return -1;
-      }
-    }
-
-    return 0;
-}
-
-static int open_self_auxv(void *cpu_env, int fd)
-{
-    CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
-    TaskState *ts = cpu->opaque;
-    abi_ulong auxv = ts->info->saved_auxv;
-    abi_ulong len = ts->info->auxv_len;
-    char *ptr;
-
-    /*
-     * Auxiliary vector is stored in target process stack.
-     * read in whole auxv vector and copy it to file
-     */
-    ptr = lock_user(VERIFY_READ, auxv, len, 0);
-    if (ptr != NULL) {
-        while (len > 0) {
-            ssize_t r;
-            r = write(fd, ptr, len);
-            if (r <= 0) {
-                break;
-            }
-            len -= r;
-            ptr += r;
-        }
-        lseek(fd, 0, SEEK_SET);
-        unlock_user(ptr, auxv, len);
-    }
-
-    return 0;
-}
-
-static int is_proc_myself(const char *filename, const char *entry)
-{
-    if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
-        filename += strlen("/proc/");
-        if (!strncmp(filename, "self/", strlen("self/"))) {
-            filename += strlen("self/");
-        } else if (*filename >= '1' && *filename <= '9') {
-            char myself[80];
-            snprintf(myself, sizeof(myself), "%d/", getpid());
-            if (!strncmp(filename, myself, strlen(myself))) {
-                filename += strlen(myself);
-            } else {
-                return 0;
-            }
-        } else {
-            return 0;
-        }
-        if (!strcmp(filename, entry)) {
-            return 1;
-        }
-    }
-    return 0;
-}
-
-#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
-static int is_proc(const char *filename, const char *entry)
-{
-    return strcmp(filename, entry) == 0;
-}
-
-static int open_net_route(void *cpu_env, int fd)
-{
-    FILE *fp;
-    char *line = NULL;
-    size_t len = 0;
-    ssize_t read;
-
-    fp = fopen("/proc/net/route", "r");
-    if (fp == NULL) {
-        return -1;
-    }
-
-    /* read header */
-
-    read = getline(&line, &len, fp);
-    dprintf(fd, "%s", line);
-
-    /* read routes */
-
-    while ((read = getline(&line, &len, fp)) != -1) {
-        char iface[16];
-        uint32_t dest, gw, mask;
-        unsigned int flags, refcnt, use, metric, mtu, window, irtt;
-        sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
-                     iface, &dest, &gw, &flags, &refcnt, &use, &metric,
-                     &mask, &mtu, &window, &irtt);
-        dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
-                iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
-                metric, tswap32(mask), mtu, window, irtt);
-    }
-
-    free(line);
-    fclose(fp);
-
-    return 0;
-}
-#endif
-
-static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, mode_t mode)
-{
-    struct fake_open {
-        const char *filename;
-        int (*fill)(void *cpu_env, int fd);
-        int (*cmp)(const char *s1, const char *s2);
-    };
-    const struct fake_open *fake_open;
-    static const struct fake_open fakes[] = {
-        { "maps", open_self_maps, is_proc_myself },
-        { "stat", open_self_stat, is_proc_myself },
-        { "auxv", open_self_auxv, is_proc_myself },
-        { "cmdline", open_self_cmdline, is_proc_myself },
-#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
-        { "/proc/net/route", open_net_route, is_proc },
-#endif
-        { NULL, NULL, NULL }
-    };
-
-    if (is_proc_myself(pathname, "exe")) {
-        int execfd = qemu_getauxval(AT_EXECFD);
-        return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode);
-    }
-
-    for (fake_open = fakes; fake_open->filename; fake_open++) {
-        if (fake_open->cmp(pathname, fake_open->filename)) {
-            break;
-        }
-    }
-
-    if (fake_open->filename) {
-        const char *tmpdir;
-        char filename[PATH_MAX];
-        int fd, r;
-
-        /* create temporary file to map stat to */
-        tmpdir = getenv("TMPDIR");
-        if (!tmpdir)
-            tmpdir = "/tmp";
-        snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
-        fd = mkstemp(filename);
-        if (fd < 0) {
-            return fd;
-        }
-        unlink(filename);
-
-        if ((r = fake_open->fill(cpu_env, fd))) {
-            int e = errno;
-            close(fd);
-            errno = e;
-            return r;
-        }
-        lseek(fd, 0, SEEK_SET);
-
-        return fd;
-    }
-
-    return safe_openat(dirfd, path(pathname), flags, mode);
-}
-
 #define TIMER_MAGIC 0x0caf0000
 #define TIMER_MAGIC_MASK 0xffff0000
 
@@ -8048,57 +7787,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         preexit_cleanup(cpu_env, arg1);
         _exit(arg1);
         return 0; /* avoid warning */
-    case TARGET_NR_read:
-        if (arg3 == 0) {
-            return 0;
-        } else {
-            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
-                return -TARGET_EFAULT;
-            ret = get_errno(safe_read(arg1, p, arg3));
-            if (ret >= 0 &&
-                fd_trans_host_to_target_data(arg1)) {
-                ret = fd_trans_host_to_target_data(arg1)(p, ret);
-            }
-            unlock_user(p, arg2, ret);
-        }
-        return ret;
-    case TARGET_NR_write:
-        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
-            return -TARGET_EFAULT;
-        if (fd_trans_target_to_host_data(arg1)) {
-            void *copy = g_malloc(arg3);
-            memcpy(copy, p, arg3);
-            ret = fd_trans_target_to_host_data(arg1)(copy, arg3);
-            if (ret >= 0) {
-                ret = get_errno(safe_write(arg1, copy, ret));
-            }
-            g_free(copy);
-        } else {
-            ret = get_errno(safe_write(arg1, p, arg3));
-        }
-        unlock_user(p, arg2, 0);
-        return ret;
-
-#ifdef TARGET_NR_open
-    case TARGET_NR_open:
-        if (!(p = lock_user_string(arg1)))
-            return -TARGET_EFAULT;
-        ret = get_errno(do_openat(cpu_env, AT_FDCWD, p,
-                                  target_to_host_bitmask(arg2, fcntl_flags_tbl),
-                                  arg3));
-        fd_trans_unregister(ret);
-        unlock_user(p, arg1, 0);
-        return ret;
-#endif
-    case TARGET_NR_openat:
-        if (!(p = lock_user_string(arg2)))
-            return -TARGET_EFAULT;
-        ret = get_errno(do_openat(cpu_env, arg1, p,
-                                  target_to_host_bitmask(arg3, fcntl_flags_tbl),
-                                  arg4));
-        fd_trans_unregister(ret);
-        unlock_user(p, arg2, 0);
-        return ret;
 #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
     case TARGET_NR_name_to_handle_at:
         ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5);
@@ -8110,10 +7798,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         fd_trans_unregister(ret);
         return ret;
 #endif
-    case TARGET_NR_close:
-        fd_trans_unregister(arg1);
-        return get_errno(close(arg1));
-
     case TARGET_NR_brk:
         return do_brk(arg1);
 #ifdef TARGET_NR_fork
@@ -9375,59 +9059,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         }
         return ret;
 #endif
-#ifdef TARGET_NR_readlink
-    case TARGET_NR_readlink:
-        {
-            void *p2;
-            p = lock_user_string(arg1);
-            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
-            if (!p || !p2) {
-                ret = -TARGET_EFAULT;
-            } else if (!arg3) {
-                /* Short circuit this for the magic exe check. */
-                ret = -TARGET_EINVAL;
-            } else if (is_proc_myself((const char *)p, "exe")) {
-                char real[PATH_MAX], *temp;
-                temp = realpath(exec_path, real);
-                /* Return value is # of bytes that we wrote to the buffer. */
-                if (temp == NULL) {
-                    ret = get_errno(-1);
-                } else {
-                    /* Don't worry about sign mismatch as earlier mapping
-                     * logic would have thrown a bad address error. */
-                    ret = MIN(strlen(real), arg3);
-                    /* We cannot NUL terminate the string. */
-                    memcpy(p2, real, ret);
-                }
-            } else {
-                ret = get_errno(readlink(path(p), p2, arg3));
-            }
-            unlock_user(p2, arg2, ret);
-            unlock_user(p, arg1, 0);
-        }
-        return ret;
-#endif
-#if defined(TARGET_NR_readlinkat)
-    case TARGET_NR_readlinkat:
-        {
-            void *p2;
-            p  = lock_user_string(arg2);
-            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
-            if (!p || !p2) {
-                ret = -TARGET_EFAULT;
-            } else if (is_proc_myself((const char *)p, "exe")) {
-                char real[PATH_MAX], *temp;
-                temp = realpath(exec_path, real);
-                ret = temp == NULL ? get_errno(-1) : strlen(real) ;
-                snprintf((char *)p2, arg4, "%s", real);
-            } else {
-                ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
-            }
-            unlock_user(p2, arg3, ret);
-            unlock_user(p, arg2, 0);
-        }
-        return ret;
-#endif
 #ifdef TARGET_NR_swapon
     case TARGET_NR_swapon:
         if (!(p = lock_user_string(arg1)))
@@ -12482,11 +12113,33 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     return ret;
 }
 
+#include "syscall-file.inc.c"
+
 static const SyscallDef *syscall_table(int num)
 {
-#define S(NAME)  case TARGET_NR_##NAME: return &def_##NAME;
+#define S(NAME)  case TARGET_NR_##NAME: return &def_##NAME
 
     switch (num) {
+    /*
+     * Unconditional syscalls.
+     */
+    S(close);
+    S(openat);
+    S(read);
+    S(write);
+
+    /*
+     * Conditional syscalls.
+     */
+#ifdef TARGET_NR_open
+    S(open);
+#endif
+#ifdef TARGET_NR_readlink
+    S(readlink);
+#endif
+#ifdef TARGET_NR_readlinkat
+    S(readlinkat);
+#endif
     }
     return NULL;
 
diff --git a/linux-user/strace.list b/linux-user/strace.list
index ff8bb19f5f..f3a1b0fe31 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -97,9 +97,6 @@
 #ifdef TARGET_NR_clone
 { TARGET_NR_clone, "clone" , NULL, print_clone, NULL },
 #endif
-#ifdef TARGET_NR_close
-{ TARGET_NR_close, "close" , "%s(%d)", NULL, NULL },
-#endif
 #ifdef TARGET_NR_connect
 { TARGET_NR_connect, "connect" , "%s(%d,%#x,%d)", NULL, NULL },
 #endif
@@ -677,12 +674,6 @@
 #ifdef TARGET_NR_olduname
 { TARGET_NR_olduname, "olduname" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_open
-{ TARGET_NR_open, "open" , NULL, print_open, NULL },
-#endif
-#ifdef TARGET_NR_openat
-{ TARGET_NR_openat, "openat" , NULL, print_openat, NULL },
-#endif
 #ifdef TARGET_NR_osf_adjtime
 { TARGET_NR_osf_adjtime, "osf_adjtime" , NULL, NULL, NULL },
 #endif
@@ -1076,21 +1067,12 @@
 #ifdef TARGET_NR_quotactl
 { TARGET_NR_quotactl, "quotactl" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_read
-{ TARGET_NR_read, "read" , "%s(%d,%#x,%d)", NULL, NULL },
-#endif
 #ifdef TARGET_NR_readahead
 { TARGET_NR_readahead, "readahead" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_readdir
 { TARGET_NR_readdir, "readdir" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_readlink
-{ TARGET_NR_readlink, "readlink" , NULL, print_readlink, NULL },
-#endif
-#ifdef TARGET_NR_readlinkat
-{ TARGET_NR_readlinkat, "readlinkat" , NULL, print_readlinkat, NULL },
-#endif
 #ifdef TARGET_NR_readv
 { TARGET_NR_readv, "readv" , NULL, NULL, NULL },
 #endif
@@ -1626,9 +1608,6 @@
 #ifdef TARGET_NR_waitpid
 { TARGET_NR_waitpid, "waitpid" , "%s(%d,%p,%#x)", NULL, NULL },
 #endif
-#ifdef TARGET_NR_write
-{ TARGET_NR_write, "write" , "%s(%d,%#x,%d)", NULL, NULL },
-#endif
 #ifdef TARGET_NR_writev
 { TARGET_NR_writev, "writev" , "%s(%d,%p,%#x)", NULL, NULL },
 #endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 11/16] linux-user: Split out preadv, pwritev, readv, writev
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (9 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 10/16] linux-user: Split out some simple file syscalls Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-22 16:03   ` Laurent Vivier
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 12/16] linux-user: Split out pread64, pwrite64 Richard Henderson
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall-file.inc.c | 98 +++++++++++++++++++++++++++++++++++
 linux-user/syscall.c          | 75 ++-------------------------
 linux-user/strace.list        | 12 -----
 3 files changed, 102 insertions(+), 83 deletions(-)

diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index aecc63682f..7eb5b968e2 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -323,6 +323,76 @@ SYSCALL_IMPL(openat)
 }
 SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
 
+/*
+ * Both preadv and pwritev merge args 4/5 into a 64-bit offset.
+ * Moreover, the parts are *always* in little-endian order.
+ */
+#if TARGET_ABI_BITS == 32
+SYSCALL_ARGS(preadv_pwritev)
+{
+    /* We have already assigned out[0-3].  */
+    abi_ulong lo = in[4], hi = in[5];
+    out[4] = ((hi << (TARGET_ABI_BITS - 1)) << 1) | lo;
+    return def;
+}
+#else
+#define args_preadv_pwritev NULL
+#endif
+
+/* Perform the inverse operation for the host.  */
+static inline void host_offset64_low_high(unsigned long *l, unsigned long *h,
+                                          uint64_t off)
+{
+    *l = off;
+    *h = (off >> (HOST_LONG_BITS - 1)) >> 1;
+}
+
+SYSCALL_IMPL(preadv)
+{
+    struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
+    unsigned long lo, hi;
+    abi_long ret;
+
+    if (vec == NULL) {
+        return -host_to_target_errno(errno);
+    }
+
+    host_offset64_low_high(&lo, &hi, arg4);
+    ret = get_errno(safe_preadv(arg1, vec, arg3, lo, hi));
+    unlock_iovec(vec, arg2, arg3, 1);
+    return ret;
+}
+
+static const SyscallDef def_preadv = {
+    .name = "preadv",
+    .args = args_preadv_pwritev,
+    .impl = impl_preadv,
+    .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 }
+};
+
+SYSCALL_IMPL(pwritev)
+{
+    struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
+    unsigned long lo, hi;
+    abi_long ret;
+
+    if (vec == NULL) {
+        ret = -host_to_target_errno(errno);
+    }
+
+    host_offset64_low_high(&lo, &hi, arg4);
+    ret = get_errno(safe_pwritev(arg1, vec, arg3, lo, hi));
+    unlock_iovec(vec, arg2, arg3, 0);
+    return ret;
+}
+
+static const SyscallDef def_pwritev = {
+    .name = "pwritev",
+    .args = args_preadv_pwritev,
+    .impl = impl_pwritev,
+    .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 }
+};
+
 SYSCALL_IMPL(read)
 {
     abi_long ret;
@@ -414,6 +484,20 @@ SYSCALL_IMPL(readlinkat)
 SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC);
 #endif
 
+SYSCALL_IMPL(readv)
+{
+    struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
+    abi_long ret;
+
+    if (vec == NULL) {
+        return -host_to_target_errno(errno);
+    }
+    ret = get_errno(safe_readv(arg1, vec, arg3));
+    unlock_iovec(vec, arg2, arg3, 1);
+    return ret;
+}
+SYSCALL_DEF(readv, ARG_DEC, ARG_PTR, ARG_DEC);
+
 SYSCALL_IMPL(write)
 {
     TargetFdDataFunc trans = fd_trans_target_to_host_data(arg1);
@@ -438,3 +522,17 @@ SYSCALL_IMPL(write)
     return ret;
 }
 SYSCALL_DEF(write, ARG_DEC, ARG_PTR, ARG_DEC);
+
+SYSCALL_IMPL(writev)
+{
+    struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
+    abi_long ret;
+
+    if (vec == NULL) {
+        return -host_to_target_errno(errno);
+    }
+    ret = get_errno(safe_writev(arg1, vec, arg3));
+    unlock_iovec(vec, arg2, arg3, 0);
+    return ret;
+}
+SYSCALL_DEF(writev, ARG_DEC, ARG_PTR, ARG_DEC);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f757ae87b0..16824386fd 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3456,23 +3456,6 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
     return ret;
 }
 
-/* Convert target low/high pair representing file offset into the host
- * low/high pair. This function doesn't handle offsets bigger than 64 bits
- * as the kernel doesn't handle them either.
- */
-static void target_to_host_low_high(abi_ulong tlow,
-                                    abi_ulong thigh,
-                                    unsigned long *hlow,
-                                    unsigned long *hhigh)
-{
-    uint64_t off = tlow |
-        ((unsigned long long)thigh << TARGET_LONG_BITS / 2) <<
-        TARGET_LONG_BITS / 2;
-
-    *hlow = off;
-    *hhigh = (off >> HOST_LONG_BITS / 2) >> HOST_LONG_BITS / 2;
-}
-
 static struct iovec *lock_iovec(int type, abi_ulong target_addr,
                                 abi_ulong count, int copy)
 {
@@ -10000,60 +9983,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         /* NOTE: the flock constant seems to be the same for every
            Linux platform */
         return get_errno(safe_flock(arg1, arg2));
-    case TARGET_NR_readv:
-        {
-            struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
-            if (vec != NULL) {
-                ret = get_errno(safe_readv(arg1, vec, arg3));
-                unlock_iovec(vec, arg2, arg3, 1);
-            } else {
-                ret = -host_to_target_errno(errno);
-            }
-        }
-        return ret;
-    case TARGET_NR_writev:
-        {
-            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
-            if (vec != NULL) {
-                ret = get_errno(safe_writev(arg1, vec, arg3));
-                unlock_iovec(vec, arg2, arg3, 0);
-            } else {
-                ret = -host_to_target_errno(errno);
-            }
-        }
-        return ret;
-#if defined(TARGET_NR_preadv)
-    case TARGET_NR_preadv:
-        {
-            struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
-            if (vec != NULL) {
-                unsigned long low, high;
-
-                target_to_host_low_high(arg4, arg5, &low, &high);
-                ret = get_errno(safe_preadv(arg1, vec, arg3, low, high));
-                unlock_iovec(vec, arg2, arg3, 1);
-            } else {
-                ret = -host_to_target_errno(errno);
-           }
-        }
-        return ret;
-#endif
-#if defined(TARGET_NR_pwritev)
-    case TARGET_NR_pwritev:
-        {
-            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
-            if (vec != NULL) {
-                unsigned long low, high;
-
-                target_to_host_low_high(arg4, arg5, &low, &high);
-                ret = get_errno(safe_pwritev(arg1, vec, arg3, low, high));
-                unlock_iovec(vec, arg2, arg3, 0);
-            } else {
-                ret = -host_to_target_errno(errno);
-           }
-        }
-        return ret;
-#endif
     case TARGET_NR_getsid:
         return get_errno(getsid(arg1));
 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
@@ -12125,8 +12054,12 @@ static const SyscallDef *syscall_table(int num)
      */
     S(close);
     S(openat);
+    S(preadv);
+    S(pwritev);
     S(read);
+    S(readv);
     S(write);
+    S(writev);
 
     /*
      * Conditional syscalls.
diff --git a/linux-user/strace.list b/linux-user/strace.list
index f3a1b0fe31..f41b604c63 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1028,9 +1028,6 @@
 #ifdef TARGET_NR_pread64
 { TARGET_NR_pread64, "pread64" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_preadv
-{ TARGET_NR_preadv, "preadv" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_prlimit64
 { TARGET_NR_prlimit64, "prlimit64" , NULL, NULL, NULL },
 #endif
@@ -1058,9 +1055,6 @@
 #ifdef TARGET_NR_pwrite64
 { TARGET_NR_pwrite64, "pwrite64" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_pwritev
-{ TARGET_NR_pwritev, "pwritev" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_query_module
 { TARGET_NR_query_module, "query_module" , NULL, NULL, NULL },
 #endif
@@ -1073,9 +1067,6 @@
 #ifdef TARGET_NR_readdir
 { TARGET_NR_readdir, "readdir" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_readv
-{ TARGET_NR_readv, "readv" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_reboot
 { TARGET_NR_reboot, "reboot" , NULL, NULL, NULL },
 #endif
@@ -1608,9 +1599,6 @@
 #ifdef TARGET_NR_waitpid
 { TARGET_NR_waitpid, "waitpid" , "%s(%d,%p,%#x)", NULL, NULL },
 #endif
-#ifdef TARGET_NR_writev
-{ TARGET_NR_writev, "writev" , "%s(%d,%p,%#x)", NULL, NULL },
-#endif
 #ifdef TARGET_NR_utimensat
 { TARGET_NR_utimensat, "utimensat", NULL, print_utimensat, NULL },
 #endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 12/16] linux-user: Split out pread64, pwrite64
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (10 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 11/16] linux-user: Split out preadv, pwritev, readv, writev Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 13/16] linux-user: Split out name_to_handle_at, open_by_handle_at Richard Henderson
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.h          | 45 +++++++++++++++++++++
 linux-user/syscall-file.inc.c | 62 ++++++++++++++++++++++++++--
 linux-user/syscall.c          | 76 +++--------------------------------
 linux-user/strace.list        |  6 ---
 4 files changed, 110 insertions(+), 79 deletions(-)

diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index f84b40d742..1d4b7ea915 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -112,3 +112,48 @@ void print_syscall_ptr_ret(const SyscallDef *def, abi_long ret);
         .name = #NAME, .args = args_##NAME, .impl = impl_##NAME, \
         .arg_type = { __VA_ARGS__ } \
     }
+
+/*
+ * Returns true if syscall NUM expects 64bit types aligned even
+ * on pairs of registers.
+ */
+static inline bool regpairs_aligned(void *cpu_env, int num)
+{
+#ifdef TARGET_ARM
+    return ((CPUARMState *)cpu_env)->eabi;
+#elif defined(TARGET_MIPS) && TARGET_ABI_BITS == 32
+    return true;
+#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
+    /* SysV AVI for PPC32 expects 64bit parameters to be passed on
+     * odd/even pairs of registers which translates to the same as
+     * we start with r3 as arg1
+     */
+    return true;
+#elif defined(TARGET_SH4)
+    /* SH4 doesn't align register pairs, except for p{read,write}64 */
+    switch (num) {
+    case TARGET_NR_pread64:
+    case TARGET_NR_pwrite64:
+        return true;
+    default:
+        return false;
+    }
+#elif defined(TARGET_XTENSA)
+    return true;
+#else
+    return false;
+#endif
+}
+
+static inline uint64_t target_offset64(abi_ulong word0, abi_ulong word1)
+{
+#if TARGET_ABI_BITS == 32
+# ifdef TARGET_WORDS_BIGENDIAN
+    return ((uint64_t)word0 << 32) | word1;
+# else
+    return ((uint64_t)word1 << 32) | word0;
+# endif
+#else
+    return word0;
+#endif
+}
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index 7eb5b968e2..c75c5dea9e 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -323,6 +323,62 @@ SYSCALL_IMPL(openat)
 }
 SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
 
+/*
+ * Both pread64 and pwrite64 merge args into a 64-bit offset,
+ * but the input registers and ordering are target specific.
+ */
+#if TARGET_ABI_BITS == 32
+SYSCALL_ARGS(pread64_pwrite64)
+{
+    /* We have already assigned out[0-2].  */
+    int off = regpairs_aligned(cpu_env, TARGET_NR_pread64);
+    out[3] = target_offset64(in[3 + off], in[4 + off]);
+    return def;
+}
+#else
+#define args_pread64_pwrite64 NULL
+#endif
+
+SYSCALL_IMPL(pread64)
+{
+    void *p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
+    abi_long ret;
+
+    if (!p) {
+        return -TARGET_EFAULT;
+    }
+    ret = get_errno(pread64(arg1, p, arg3, arg4));
+    unlock_user(p, arg2, ret);
+    return ret;
+}
+
+static const SyscallDef def_pread64 = {
+    .name = "pread64",
+    .args = args_pread64_pwrite64,
+    .impl = impl_pread64,
+    .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 }
+};
+
+SYSCALL_IMPL(pwrite64)
+{
+    void *p = lock_user(VERIFY_READ, arg2, arg3, 0);
+    abi_long ret;
+
+    if (!p) {
+        return -TARGET_EFAULT;
+    }
+    ret = get_errno(pwrite64(arg1, p, arg3, arg4));
+    unlock_user(p, arg2, 0);
+    return ret;
+}
+
+static const SyscallDef def_pwrite64 = {
+    .name = "pwrite64",
+    .args = args_pread64_pwrite64,
+    .impl = impl_pwrite64,
+    .arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 }
+};
+
 /*
  * Both preadv and pwritev merge args 4/5 into a 64-bit offset.
  * Moreover, the parts are *always* in little-endian order.
@@ -330,9 +386,9 @@ SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
 #if TARGET_ABI_BITS == 32
 SYSCALL_ARGS(preadv_pwritev)
 {
-    /* We have already assigned out[0-3].  */
-    abi_ulong lo = in[4], hi = in[5];
-    out[4] = ((hi << (TARGET_ABI_BITS - 1)) << 1) | lo;
+    /* We have already assigned out[0-2].  */
+    abi_ulong lo = in[3], hi = in[4];
+    out[3] = ((hi << (TARGET_ABI_BITS - 1)) << 1) | lo;
     return def;
 }
 #else
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 16824386fd..eb6c8465b7 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -718,38 +718,6 @@ static inline int next_free_host_timer(void)
 }
 #endif
 
-/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
-#ifdef TARGET_ARM
-static inline int regpairs_aligned(void *cpu_env, int num)
-{
-    return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
-}
-#elif defined(TARGET_MIPS) && (TARGET_ABI_BITS == 32)
-static inline int regpairs_aligned(void *cpu_env, int num) { return 1; }
-#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
-/* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
- * of registers which translates to the same as ARM/MIPS, because we start with
- * r3 as arg1 */
-static inline int regpairs_aligned(void *cpu_env, int num) { return 1; }
-#elif defined(TARGET_SH4)
-/* SH4 doesn't align register pairs, except for p{read,write}64 */
-static inline int regpairs_aligned(void *cpu_env, int num)
-{
-    switch (num) {
-    case TARGET_NR_pread64:
-    case TARGET_NR_pwrite64:
-        return 1;
-
-    default:
-        return 0;
-    }
-}
-#elif defined(TARGET_XTENSA)
-static inline int regpairs_aligned(void *cpu_env, int num) { return 1; }
-#else
-static inline int regpairs_aligned(void *cpu_env, int num) { return 0; }
-#endif
-
 #define ERRNO_TABLE_SIZE 1200
 
 /* target_to_host_errno_table[] is initialized from
@@ -7045,22 +7013,6 @@ void syscall_init(void)
     }
 }
 
-#if TARGET_ABI_BITS == 32
-static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
-    return ((uint64_t)word0 << 32) | word1;
-#else
-    return ((uint64_t)word1 << 32) | word0;
-#endif
-}
-#else /* TARGET_ABI_BITS == 32 */
-static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
-{
-    return word0;
-}
-#endif /* TARGET_ABI_BITS != 32 */
-
 #ifdef TARGET_NR_truncate64
 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
                                          abi_long arg2,
@@ -10232,28 +10184,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #else
 #error unreachable
 #endif
-#endif
-#ifdef TARGET_NR_pread64
-    case TARGET_NR_pread64:
-        if (regpairs_aligned(cpu_env, num)) {
-            arg4 = arg5;
-            arg5 = arg6;
-        }
-        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
-            return -TARGET_EFAULT;
-        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
-        unlock_user(p, arg2, ret);
-        return ret;
-    case TARGET_NR_pwrite64:
-        if (regpairs_aligned(cpu_env, num)) {
-            arg4 = arg5;
-            arg5 = arg6;
-        }
-        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
-            return -TARGET_EFAULT;
-        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
-        unlock_user(p, arg2, 0);
-        return ret;
 #endif
     case TARGET_NR_getcwd:
         if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
@@ -12067,6 +11997,12 @@ static const SyscallDef *syscall_table(int num)
 #ifdef TARGET_NR_open
     S(open);
 #endif
+#ifdef TARGET_NR_pread64
+    S(pread64);
+#endif
+#ifdef TARGET_NR_pwrite64
+    S(pwrite64);
+#endif
 #ifdef TARGET_NR_readlink
     S(readlink);
 #endif
diff --git a/linux-user/strace.list b/linux-user/strace.list
index f41b604c63..586eb55482 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1025,9 +1025,6 @@
 #ifdef TARGET_NR_prctl
 { TARGET_NR_prctl, "prctl" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_pread64
-{ TARGET_NR_pread64, "pread64" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_prlimit64
 { TARGET_NR_prlimit64, "prlimit64" , NULL, NULL, NULL },
 #endif
@@ -1052,9 +1049,6 @@
 #ifdef TARGET_NR_putpmsg
 { TARGET_NR_putpmsg, "putpmsg" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_pwrite64
-{ TARGET_NR_pwrite64, "pwrite64" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_query_module
 { TARGET_NR_query_module, "query_module" , NULL, NULL, NULL },
 #endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 13/16] linux-user: Split out name_to_handle_at, open_by_handle_at
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (11 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 12/16] linux-user: Split out pread64, pwrite64 Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 14/16] linux-user: Split out ipc syscalls Richard Henderson
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.h          |   1 +
 linux-user/strace.c           |   5 +-
 linux-user/syscall-file.inc.c |  84 +++++++++++++++++++++++++++
 linux-user/syscall.c          | 104 ++--------------------------------
 linux-user/strace.list        |   3 -
 5 files changed, 95 insertions(+), 102 deletions(-)

diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index 1d4b7ea915..f9a60f754c 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -54,6 +54,7 @@ typedef enum {
 
     /* These print as sets of flags.  */
     ARG_ATDIRFD,
+    ARG_ATFLAG,
     ARG_MODEFLAG,
     ARG_OPENFLAG,
 
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 11e0c86554..6d63374c1b 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -780,7 +780,7 @@ UNUSED static struct flags access_flags[] = {
     FLAG_END,
 };
 
-UNUSED static struct flags at_file_flags[] = {
+static struct flags const at_file_flags[] = {
 #ifdef AT_EACCESS
     FLAG_GENERIC(AT_EACCESS),
 #endif
@@ -2676,6 +2676,9 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6])
         case ARG_ATDIRFD:
             len = add_atdirfd(b, rest, arg);
             break;
+        case ARG_ATFLAG:
+            len = add_flags(b, rest, at_file_flags, arg, false);
+            break;
         case ARG_MODEFLAG:
             len = add_flags(b, rest, mode_flags, arg, true);
             break;
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index c75c5dea9e..2c984af4cb 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -323,6 +323,90 @@ SYSCALL_IMPL(openat)
 }
 SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
 
+SYSCALL_IMPL(name_to_handle_at)
+{
+    struct file_handle *target_fh;
+    struct file_handle *fh;
+    int mid = 0;
+    abi_long ret;
+    char *name;
+    uint32_t size, total_size;
+
+    if (get_user_s32(size, arg3)) {
+        return -TARGET_EFAULT;
+    }
+    total_size = sizeof(struct file_handle) + size;
+    target_fh = lock_user(VERIFY_WRITE, arg3, total_size, 0);
+    if (!target_fh) {
+        return -TARGET_EFAULT;
+    }
+
+    name = lock_user_string(arg2);
+    if (!name) {
+        unlock_user(target_fh, arg3, 0);
+        return -TARGET_EFAULT;
+    }
+
+
+    fh = g_malloc0(total_size);
+    fh->handle_bytes = size;
+
+    ret = get_errno(safe_name_to_handle_at(arg1, path(name), fh, &mid, arg5));
+    unlock_user(name, arg2, 0);
+
+    /* man name_to_handle_at(2):
+     * Other than the use of the handle_bytes field, the caller should treat
+     * the file_handle structure as an opaque data type
+     */
+    if (!is_error(ret)) {
+        memcpy(target_fh, fh, total_size);
+        target_fh->handle_bytes = tswap32(fh->handle_bytes);
+        target_fh->handle_type = tswap32(fh->handle_type);
+        g_free(fh);
+        unlock_user(target_fh, arg3, total_size);
+
+        if (put_user_s32(mid, arg4)) {
+            return -TARGET_EFAULT;
+        }
+    }
+    return ret;
+}
+SYSCALL_DEF(name_to_handle_at,
+            ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG);
+
+SYSCALL_IMPL(open_by_handle_at)
+{
+    abi_long mount_fd = arg1;
+    abi_long handle = arg2;
+    int host_flags = target_to_host_bitmask(arg3, fcntl_flags_tbl);
+    struct file_handle *target_fh;
+    struct file_handle *fh;
+    unsigned int size, total_size;
+    abi_long ret;
+
+    if (get_user_s32(size, handle)) {
+        return -TARGET_EFAULT;
+    }
+    total_size = sizeof(struct file_handle) + size;
+    target_fh = lock_user(VERIFY_READ, handle, total_size, 1);
+    if (!target_fh) {
+        return -TARGET_EFAULT;
+    }
+
+    fh = g_memdup(target_fh, total_size);
+    fh->handle_bytes = size;
+    fh->handle_type = tswap32(target_fh->handle_type);
+
+    ret = get_errno(safe_open_by_handle_at(mount_fd, fh, host_flags));
+
+    g_free(fh);
+    unlock_user(target_fh, handle, total_size);
+
+    fd_trans_unregister(ret);
+    return ret;
+}
+SYSCALL_DEF(open_by_handle_at, ARG_DEC, ARG_PTR, ARG_OPENFLAG);
+
 /*
  * Both pread64 and pwrite64 merge args into a 64-bit offset,
  * but the input registers and ordering are target specific.
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index eb6c8465b7..c9c9669ae2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1027,6 +1027,10 @@ safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr,
 safe_syscall5(int, mq_timedreceive, int, mqdes, char *, msg_ptr,
               size_t, len, unsigned *, prio, const struct timespec *, timeout)
 #endif
+safe_syscall5(int, name_to_handle_at, int, dirfd, const char *, pathname,
+              struct file_handle *, handle, int *, mount_id, int, flags)
+safe_syscall3(int, open_by_handle_at, int, mount_fd,
+              struct file_handle *, handle, int, flags)
 /* We do ioctl like this rather than via safe_syscall3 to preserve the
  * "third argument might be integer or pointer or not present" behaviour of
  * the libc function.
@@ -7336,93 +7340,6 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
         return -TARGET_ENOSYS;
     }
 }
-#if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
-static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
-                                     abi_long handle, abi_long mount_id,
-                                     abi_long flags)
-{
-    struct file_handle *target_fh;
-    struct file_handle *fh;
-    int mid = 0;
-    abi_long ret;
-    char *name;
-    unsigned int size, total_size;
-
-    if (get_user_s32(size, handle)) {
-        return -TARGET_EFAULT;
-    }
-
-    name = lock_user_string(pathname);
-    if (!name) {
-        return -TARGET_EFAULT;
-    }
-
-    total_size = sizeof(struct file_handle) + size;
-    target_fh = lock_user(VERIFY_WRITE, handle, total_size, 0);
-    if (!target_fh) {
-        unlock_user(name, pathname, 0);
-        return -TARGET_EFAULT;
-    }
-
-    fh = g_malloc0(total_size);
-    fh->handle_bytes = size;
-
-    ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags));
-    unlock_user(name, pathname, 0);
-
-    /* man name_to_handle_at(2):
-     * Other than the use of the handle_bytes field, the caller should treat
-     * the file_handle structure as an opaque data type
-     */
-
-    memcpy(target_fh, fh, total_size);
-    target_fh->handle_bytes = tswap32(fh->handle_bytes);
-    target_fh->handle_type = tswap32(fh->handle_type);
-    g_free(fh);
-    unlock_user(target_fh, handle, total_size);
-
-    if (put_user_s32(mid, mount_id)) {
-        return -TARGET_EFAULT;
-    }
-
-    return ret;
-
-}
-#endif
-
-#if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
-static abi_long do_open_by_handle_at(abi_long mount_fd, abi_long handle,
-                                     abi_long flags)
-{
-    struct file_handle *target_fh;
-    struct file_handle *fh;
-    unsigned int size, total_size;
-    abi_long ret;
-
-    if (get_user_s32(size, handle)) {
-        return -TARGET_EFAULT;
-    }
-
-    total_size = sizeof(struct file_handle) + size;
-    target_fh = lock_user(VERIFY_READ, handle, total_size, 1);
-    if (!target_fh) {
-        return -TARGET_EFAULT;
-    }
-
-    fh = g_memdup(target_fh, total_size);
-    fh->handle_bytes = size;
-    fh->handle_type = tswap32(target_fh->handle_type);
-
-    ret = get_errno(open_by_handle_at(mount_fd, fh,
-                    target_to_host_bitmask(flags, fcntl_flags_tbl)));
-
-    g_free(fh);
-
-    unlock_user(target_fh, handle, total_size);
-
-    return ret;
-}
-#endif
 
 #if defined(TARGET_NR_signalfd) || defined(TARGET_NR_signalfd4)
 
@@ -7722,17 +7639,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         preexit_cleanup(cpu_env, arg1);
         _exit(arg1);
         return 0; /* avoid warning */
-#if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
-    case TARGET_NR_name_to_handle_at:
-        ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5);
-        return ret;
-#endif
-#if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
-    case TARGET_NR_open_by_handle_at:
-        ret = do_open_by_handle_at(arg1, arg2, arg3);
-        fd_trans_unregister(ret);
-        return ret;
-#endif
     case TARGET_NR_brk:
         return do_brk(arg1);
 #ifdef TARGET_NR_fork
@@ -11983,7 +11889,9 @@ static const SyscallDef *syscall_table(int num)
      * Unconditional syscalls.
      */
     S(close);
+    S(name_to_handle_at);
     S(openat);
+    S(open_by_handle_at);
     S(preadv);
     S(pwritev);
     S(read);
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 586eb55482..26ad95dc7e 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -635,9 +635,6 @@
 #ifdef TARGET_NR_munmap
 { TARGET_NR_munmap, "munmap" , NULL, print_munmap, NULL },
 #endif
-#ifdef TARGET_NR_name_to_handle_at
-{ TARGET_NR_name_to_handle_at, "name_to_handle_at" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_nanosleep
 { TARGET_NR_nanosleep, "nanosleep" , NULL, NULL, NULL },
 #endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 14/16] linux-user: Split out ipc syscalls
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (12 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 13/16] linux-user: Split out name_to_handle_at, open_by_handle_at Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 15/16] linux-user: Split out memory syscalls Richard Henderson
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/strace.c          |   83 ---
 linux-user/syscall-ipc.inc.c | 1085 ++++++++++++++++++++++++++++++++++
 linux-user/syscall.c         | 1006 ++-----------------------------
 linux-user/strace.list       |   42 --
 4 files changed, 1122 insertions(+), 1094 deletions(-)
 create mode 100644 linux-user/syscall-ipc.inc.c

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 6d63374c1b..b043dea124 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1,8 +1,4 @@
 #include "qemu/osdep.h"
-#include <sys/ipc.h>
-#include <sys/msg.h>
-#include <sys/sem.h>
-#include <sys/shm.h>
 #include <sys/select.h>
 #include <sys/mount.h>
 #include <arpa/inet.h>
@@ -74,54 +70,6 @@ UNUSED static void print_socket_protocol(int domain, int type, int protocol);
 /*
  * Utility functions
  */
-static void
-print_ipc_cmd(int cmd)
-{
-#define output_cmd(val) \
-if( cmd == val ) { \
-    gemu_log(#val); \
-    return; \
-}
-
-    cmd &= 0xff;
-
-    /* General IPC commands */
-    output_cmd( IPC_RMID );
-    output_cmd( IPC_SET );
-    output_cmd( IPC_STAT );
-    output_cmd( IPC_INFO );
-    /* msgctl() commands */
-    output_cmd( MSG_STAT );
-    output_cmd( MSG_INFO );
-    /* shmctl() commands */
-    output_cmd( SHM_LOCK );
-    output_cmd( SHM_UNLOCK );
-    output_cmd( SHM_STAT );
-    output_cmd( SHM_INFO );
-    /* semctl() commands */
-    output_cmd( GETPID );
-    output_cmd( GETVAL );
-    output_cmd( GETALL );
-    output_cmd( GETNCNT );
-    output_cmd( GETZCNT );
-    output_cmd( SETVAL );
-    output_cmd( SETALL );
-    output_cmd( SEM_STAT );
-    output_cmd( SEM_INFO );
-    output_cmd( IPC_RMID );
-    output_cmd( IPC_RMID );
-    output_cmd( IPC_RMID );
-    output_cmd( IPC_RMID );
-    output_cmd( IPC_RMID );
-    output_cmd( IPC_RMID );
-    output_cmd( IPC_RMID );
-    output_cmd( IPC_RMID );
-    output_cmd( IPC_RMID );
-
-    /* Some value we don't recognize */
-    gemu_log("%d",cmd);
-}
-
 static void
 print_signal(abi_ulong arg, int last)
 {
@@ -620,18 +568,6 @@ print_newselect(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_semctl
-static void
-print_semctl(const struct syscallname *name,
-             abi_long arg1, abi_long arg2, abi_long arg3,
-             abi_long arg4, abi_long arg5, abi_long arg6)
-{
-    gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ",", name->name, arg1, arg2);
-    print_ipc_cmd(arg3);
-    gemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4);
-}
-#endif
-
 static void
 print_execve(const struct syscallname *name,
              abi_long arg1, abi_long arg2, abi_long arg3,
@@ -664,25 +600,6 @@ print_execve(const struct syscallname *name,
     gemu_log("NULL})");
 }
 
-#ifdef TARGET_NR_ipc
-static void
-print_ipc(const struct syscallname *name,
-          abi_long arg1, abi_long arg2, abi_long arg3,
-          abi_long arg4, abi_long arg5, abi_long arg6)
-{
-    switch(arg1) {
-    case IPCOP_semctl:
-        gemu_log("semctl(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ",", arg1, arg2);
-        print_ipc_cmd(arg3);
-        gemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4);
-        break;
-    default:
-        gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ")",
-                 name->name, arg1, arg2, arg3, arg4);
-    }
-}
-#endif
-
 /*
  * Variants for the return value output function
  */
diff --git a/linux-user/syscall-ipc.inc.c b/linux-user/syscall-ipc.inc.c
new file mode 100644
index 0000000000..727cd02e9d
--- /dev/null
+++ b/linux-user/syscall-ipc.inc.c
@@ -0,0 +1,1085 @@
+/*
+ *  Linux ipc-related syscalls
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifdef __NR_msgsnd
+safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
+              int, flags)
+safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
+              long, msgtype, int, flags)
+safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
+              unsigned, nsops, const struct timespec *, timeout)
+#else
+/* This host kernel architecture uses a single ipc syscall; fake up
+ * wrappers for the sub-operations to hide this implementation detail.
+ * Annoyingly we can't include linux/ipc.h to get the constant definitions
+ * for the call parameter because some structs in there conflict with the
+ * sys/ipc.h ones. So we just define them here, and rely on them being
+ * the same for all host architectures.
+ */
+#define Q_SEMTIMEDOP 4
+#define Q_MSGSND 11
+#define Q_MSGRCV 12
+#define Q_IPCCALL(VERSION, OP) ((VERSION) << 16 | (OP))
+
+safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
+              void *, ptr, long, fifth)
+
+static int safe_msgsnd(int msgid, const void *msgp, size_t sz, int flags)
+{
+    return safe_ipc(Q_IPCCALL(0, Q_MSGSND), msgid, sz, flags, (void *)msgp, 0);
+}
+
+static int safe_msgrcv(int msgid, void *msgp, size_t sz, long type, int flags)
+{
+    return safe_ipc(Q_IPCCALL(1, Q_MSGRCV), msgid, sz, flags, msgp, type);
+}
+
+static int safe_semtimedop(int semid, struct sembuf *tsops, unsigned nsops,
+                           const struct timespec *timeout)
+{
+    return safe_ipc(Q_IPCCALL(0, Q_SEMTIMEDOP), semid, nsops, 0, tsops,
+                    (long)timeout);
+}
+#endif
+
+/* See <linux/ipc.h> comment above.  */
+#define SEMOPM  500
+
+#define N_SHM_REGIONS  32
+
+static struct shm_region {
+    abi_ulong start;
+    abi_ulong size;
+    bool in_use;
+} shm_regions[N_SHM_REGIONS];
+
+#ifndef TARGET_SEMID64_DS
+/* asm-generic version of this struct */
+struct target_semid64_ds {
+    struct target_ipc_perm sem_perm;
+    abi_ulong sem_otime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong sem_ctime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong sem_nsems;
+    abi_ulong __unused3;
+    abi_ulong __unused4;
+};
+#endif
+
+static abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
+                                        abi_ulong target_addr)
+{
+    struct target_ipc_perm *target_ip;
+    struct target_semid64_ds *target_sd;
+
+    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) {
+        return -TARGET_EFAULT;
+    }
+    target_ip = &target_sd->sem_perm;
+    host_ip->__key = tswap32(target_ip->__key);
+    host_ip->uid = tswap32(target_ip->uid);
+    host_ip->gid = tswap32(target_ip->gid);
+    host_ip->cuid = tswap32(target_ip->cuid);
+    host_ip->cgid = tswap32(target_ip->cgid);
+#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
+    host_ip->mode = tswap32(target_ip->mode);
+#else
+    host_ip->mode = tswap16(target_ip->mode);
+#endif
+#if defined(TARGET_PPC)
+    host_ip->__seq = tswap32(target_ip->__seq);
+#else
+    host_ip->__seq = tswap16(target_ip->__seq);
+#endif
+    unlock_user_struct(target_sd, target_addr, 0);
+    return 0;
+}
+
+static abi_long host_to_target_ipc_perm(abi_ulong target_addr,
+                                        struct ipc_perm *host_ip)
+{
+    struct target_ipc_perm *target_ip;
+    struct target_semid64_ds *target_sd;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    target_ip = &target_sd->sem_perm;
+    target_ip->__key = tswap32(host_ip->__key);
+    target_ip->uid = tswap32(host_ip->uid);
+    target_ip->gid = tswap32(host_ip->gid);
+    target_ip->cuid = tswap32(host_ip->cuid);
+    target_ip->cgid = tswap32(host_ip->cgid);
+#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
+    target_ip->mode = tswap32(host_ip->mode);
+#else
+    target_ip->mode = tswap16(host_ip->mode);
+#endif
+#if defined(TARGET_PPC)
+    target_ip->__seq = tswap32(host_ip->__seq);
+#else
+    target_ip->__seq = tswap16(host_ip->__seq);
+#endif
+    unlock_user_struct(target_sd, target_addr, 1);
+    return 0;
+}
+
+static abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
+                                        abi_ulong target_addr)
+{
+    struct target_semid64_ds *target_sd;
+
+    if (target_to_host_ipc_perm(&host_sd->sem_perm, target_addr)) {
+        return -TARGET_EFAULT;
+    }
+    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) {
+        return -TARGET_EFAULT;
+    }
+    host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
+    host_sd->sem_otime = tswapal(target_sd->sem_otime);
+    host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
+    unlock_user_struct(target_sd, target_addr, 0);
+    return 0;
+}
+
+static abi_long host_to_target_semid_ds(abi_ulong target_addr,
+                                        struct semid_ds *host_sd)
+{
+    struct target_semid64_ds *target_sd;
+
+    if (host_to_target_ipc_perm(target_addr, &host_sd->sem_perm)) {
+        return -TARGET_EFAULT;
+    }
+    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
+    target_sd->sem_otime = tswapal(host_sd->sem_otime);
+    target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
+    unlock_user_struct(target_sd, target_addr, 1);
+    return 0;
+}
+
+struct target_seminfo {
+    int semmap;
+    int semmni;
+    int semmns;
+    int semmnu;
+    int semmsl;
+    int semopm;
+    int semume;
+    int semusz;
+    int semvmx;
+    int semaem;
+};
+
+static abi_long host_to_target_seminfo(abi_ulong target_addr,
+                                       struct seminfo *host_seminfo)
+{
+    struct target_seminfo *target_seminfo;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
+    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
+    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
+    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
+    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
+    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
+    __put_user(host_seminfo->semume, &target_seminfo->semume);
+    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
+    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
+    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
+    unlock_user_struct(target_seminfo, target_addr, 1);
+    return 0;
+}
+
+union semun {
+    int val;
+    struct semid_ds *buf;
+    unsigned short *array;
+    struct seminfo *__buf;
+};
+
+union target_semun {
+    int val;
+    abi_ulong buf;
+    abi_ulong array;
+    abi_ulong __buf;
+};
+
+static abi_long target_to_host_semarray(int semid,
+                                        unsigned short **host_array,
+                                        abi_ulong target_addr)
+{
+    int nsems;
+    unsigned short *array;
+    union semun semun;
+    struct semid_ds semid_ds;
+    int i, ret;
+
+    semun.buf = &semid_ds;
+
+    ret = semctl(semid, 0, IPC_STAT, semun);
+    if (ret == -1) {
+        return get_errno(ret);
+    }
+
+    nsems = semid_ds.sem_nsems;
+
+    *host_array = g_try_new(unsigned short, nsems);
+    if (!*host_array) {
+        return -TARGET_ENOMEM;
+    }
+    array = lock_user(VERIFY_READ, target_addr,
+                      nsems * sizeof(unsigned short), 1);
+    if (!array) {
+        g_free(*host_array);
+        return -TARGET_EFAULT;
+    }
+    for (i = 0; i < nsems; i++) {
+        __get_user((*host_array)[i], &array[i]);
+    }
+    unlock_user(array, target_addr, 0);
+
+    return 0;
+}
+
+static abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
+                                        unsigned short **host_array)
+{
+    int nsems;
+    unsigned short *array;
+    union semun semun;
+    struct semid_ds semid_ds;
+    int i, ret;
+
+    semun.buf = &semid_ds;
+
+    ret = semctl(semid, 0, IPC_STAT, semun);
+    if (ret == -1) {
+        return get_errno(ret);
+    }
+
+    nsems = semid_ds.sem_nsems;
+
+    array = lock_user(VERIFY_WRITE, target_addr,
+                      nsems * sizeof(unsigned short), 0);
+    if (!array) {
+        return -TARGET_EFAULT;
+    }
+    for (i = 0; i < nsems; i++) {
+        __put_user((*host_array)[i], &array[i]);
+    }
+    g_free(*host_array);
+    unlock_user(array, target_addr, 1);
+
+    return 0;
+}
+
+struct target_sembuf {
+    unsigned short sem_num;
+    short sem_op;
+    short sem_flg;
+};
+
+static abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
+                                      abi_ulong target_addr,
+                                      unsigned nsops)
+{
+    struct target_sembuf *target_sembuf;
+    int i;
+
+    target_sembuf = lock_user(VERIFY_READ, target_addr,
+                              nsops * sizeof(struct target_sembuf), 1);
+    if (!target_sembuf) {
+        return -TARGET_EFAULT;
+    }
+    for (i = 0; i < nsops; i++) {
+        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
+        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
+        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
+    }
+    unlock_user(target_sembuf, target_addr, 0);
+    return 0;
+}
+
+struct target_msqid_ds {
+    struct target_ipc_perm msg_perm;
+    abi_ulong msg_stime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused1;
+#endif
+    abi_ulong msg_rtime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused2;
+#endif
+    abi_ulong msg_ctime;
+#if TARGET_ABI_BITS == 32
+    abi_ulong __unused3;
+#endif
+    abi_ulong __msg_cbytes;
+    abi_ulong msg_qnum;
+    abi_ulong msg_qbytes;
+    abi_ulong msg_lspid;
+    abi_ulong msg_lrpid;
+    abi_ulong __unused4;
+    abi_ulong __unused5;
+};
+
+static abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
+                                        abi_ulong target_addr)
+{
+    struct target_msqid_ds *target_md;
+
+    if (target_to_host_ipc_perm(&host_md->msg_perm, target_addr)) {
+        return -TARGET_EFAULT;
+    }
+    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1)) {
+        return -TARGET_EFAULT;
+    }
+    host_md->msg_stime = tswapal(target_md->msg_stime);
+    host_md->msg_rtime = tswapal(target_md->msg_rtime);
+    host_md->msg_ctime = tswapal(target_md->msg_ctime);
+    host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
+    host_md->msg_qnum = tswapal(target_md->msg_qnum);
+    host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
+    host_md->msg_lspid = tswapal(target_md->msg_lspid);
+    host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
+    unlock_user_struct(target_md, target_addr, 0);
+    return 0;
+}
+
+static abi_long host_to_target_msqid_ds(abi_ulong target_addr,
+                                        struct msqid_ds *host_md)
+{
+    struct target_msqid_ds *target_md;
+
+    if (host_to_target_ipc_perm(target_addr, &host_md->msg_perm)) {
+        return -TARGET_EFAULT;
+    }
+    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    target_md->msg_stime = tswapal(host_md->msg_stime);
+    target_md->msg_rtime = tswapal(host_md->msg_rtime);
+    target_md->msg_ctime = tswapal(host_md->msg_ctime);
+    target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
+    target_md->msg_qnum = tswapal(host_md->msg_qnum);
+    target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
+    target_md->msg_lspid = tswapal(host_md->msg_lspid);
+    target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
+    unlock_user_struct(target_md, target_addr, 1);
+    return 0;
+}
+
+struct target_msginfo {
+    int msgpool;
+    int msgmap;
+    int msgmax;
+    int msgmnb;
+    int msgmni;
+    int msgssz;
+    int msgtql;
+    unsigned short int msgseg;
+};
+
+static abi_long host_to_target_msginfo(abi_ulong target_addr,
+                                       struct msginfo *host_msginfo)
+{
+    struct target_msginfo *target_msginfo;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
+    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
+    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
+    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
+    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
+    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
+    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
+    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
+    unlock_user_struct(target_msginfo, target_addr, 1);
+    return 0;
+}
+
+struct target_msgbuf {
+    abi_long mtype;
+    char mtext[1];
+};
+
+static abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
+                                        abi_ulong target_addr)
+{
+    struct target_shmid_ds *target_sd;
+
+    if (target_to_host_ipc_perm(&host_sd->shm_perm, target_addr)) {
+        return -TARGET_EFAULT;
+    }
+    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) {
+        return -TARGET_EFAULT;
+    }
+    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
+    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
+    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
+    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
+    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
+    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
+    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
+    unlock_user_struct(target_sd, target_addr, 0);
+    return 0;
+}
+
+static abi_long host_to_target_shmid_ds(abi_ulong target_addr,
+                                        struct shmid_ds *host_sd)
+{
+    struct target_shmid_ds *target_sd;
+
+    if (host_to_target_ipc_perm(target_addr, &host_sd->shm_perm)) {
+        return -TARGET_EFAULT;
+    }
+    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
+    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
+    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
+    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
+    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
+    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
+    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
+    unlock_user_struct(target_sd, target_addr, 1);
+    return 0;
+}
+
+struct target_shminfo {
+    abi_ulong shmmax;
+    abi_ulong shmmin;
+    abi_ulong shmmni;
+    abi_ulong shmseg;
+    abi_ulong shmall;
+};
+
+static abi_long host_to_target_shminfo(abi_ulong target_addr,
+                                       struct shminfo *host_shminfo)
+{
+    struct target_shminfo *target_shminfo;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
+    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
+    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
+    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
+    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
+    unlock_user_struct(target_shminfo, target_addr, 1);
+    return 0;
+}
+
+struct target_shm_info {
+    int used_ids;
+    abi_ulong shm_tot;
+    abi_ulong shm_rss;
+    abi_ulong shm_swp;
+    abi_ulong swap_attempts;
+    abi_ulong swap_successes;
+};
+
+static abi_long host_to_target_shm_info(abi_ulong target_addr,
+                                        struct shm_info *host_shm_info)
+{
+    struct target_shm_info *target_shm_info;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
+    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
+    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
+    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
+    __put_user(host_shm_info->swap_attempts,
+               &target_shm_info->swap_attempts);
+    __put_user(host_shm_info->swap_successes,
+               &target_shm_info->swap_successes);
+    unlock_user_struct(target_shm_info, target_addr, 1);
+    return 0;
+}
+
+#ifndef TARGET_FORCE_SHMLBA
+/* For most architectures, SHMLBA is the same as the page size;
+ * some architectures have larger values, in which case they should
+ * define TARGET_FORCE_SHMLBA and provide a target_shmlba() function.
+ * This corresponds to the kernel arch code defining __ARCH_FORCE_SHMLBA
+ * and defining its own value for SHMLBA.
+ *
+ * The kernel also permits SHMLBA to be set by the architecture to a
+ * value larger than the page size without setting __ARCH_FORCE_SHMLBA;
+ * this means that addresses are rounded to the large size if
+ * SHM_RND is set but addresses not aligned to that size are not rejected
+ * as long as they are at least page-aligned. Since the only architecture
+ * which uses this is ia64 this code doesn't provide for that oddity.
+ */
+static abi_ulong target_shmlba(CPUArchState *cpu_env)
+{
+    return TARGET_PAGE_SIZE;
+}
+#endif
+
+
+SYSCALL_IMPL(msgctl)
+{
+    abi_long msgid = arg1;
+    int cmd = arg2 & 0xff;
+    abi_ulong ptr = arg3;
+    struct msqid_ds dsarg;
+    struct msginfo msginfo;
+    abi_long ret;
+
+    switch (cmd) {
+    case IPC_STAT:
+    case IPC_SET:
+    case MSG_STAT:
+        if (target_to_host_msqid_ds(&dsarg, ptr)) {
+            return -TARGET_EFAULT;
+        }
+        ret = get_errno(msgctl(msgid, cmd, &dsarg));
+        if (!is_error(ret) && host_to_target_msqid_ds(ptr, &dsarg)) {
+            return -TARGET_EFAULT;
+        }
+        return ret;
+
+    case IPC_RMID:
+        return get_errno(msgctl(msgid, cmd, NULL));
+
+    case IPC_INFO:
+    case MSG_INFO:
+        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
+        if (host_to_target_msginfo(ptr, &msginfo)) {
+            return -TARGET_EFAULT;
+        }
+        return ret;
+
+    default:
+        return -TARGET_EINVAL;
+    }
+}
+SYSCALL_DEF(msgctl, ARG_DEC, ARG_DEC, ARG_PTR);
+
+SYSCALL_IMPL(msgget)
+{
+    return get_errno(msgget(arg1, arg2));
+}
+SYSCALL_DEF(msgget, ARG_DEC, ARG_DEC);
+
+SYSCALL_IMPL(msgrcv)
+{
+    int msqid = arg1;
+    abi_ulong msgp = arg2;
+    abi_long msgsz = arg3;
+    abi_long msgtyp = arg4;
+    int msgflg = arg5;
+    struct target_msgbuf *target_mb;
+    char *target_mtext;
+    struct msgbuf *host_mb;
+    abi_long ret = 0;
+
+    if (msgsz < 0) {
+        return -TARGET_EINVAL;
+    }
+    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0)) {
+        return -TARGET_EFAULT;
+    }
+
+    host_mb = g_try_malloc(msgsz + sizeof(long));
+    if (!host_mb) {
+        ret = -TARGET_ENOMEM;
+        goto end;
+    }
+    ret = get_errno(safe_msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
+
+    if (ret > 0) {
+        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
+        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
+        if (!target_mtext) {
+            ret = -TARGET_EFAULT;
+            goto end;
+        }
+        memcpy(target_mb->mtext, host_mb->mtext, ret);
+        unlock_user(target_mtext, target_mtext_addr, ret);
+    }
+    target_mb->mtype = tswapal(host_mb->mtype);
+
+ end:
+    unlock_user_struct(target_mb, msgp, 1);
+    g_free(host_mb);
+    return ret;
+}
+SYSCALL_DEF(msgrcv, ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC, ARG_HEX);
+
+SYSCALL_IMPL(msgsnd)
+{
+    int msqid = arg1;
+    abi_ulong msgp = arg2;
+    abi_long msgsz = arg3;
+    int msgflg = arg4;
+    struct target_msgbuf *target_mb;
+    struct msgbuf *host_mb;
+    abi_long ret = 0;
+
+    if (msgsz < 0) {
+        return -TARGET_EINVAL;
+    }
+    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0)) {
+        return -TARGET_EFAULT;
+    }
+    host_mb = g_try_malloc(msgsz + sizeof(long));
+    if (!host_mb) {
+        unlock_user_struct(target_mb, msgp, 0);
+        return -TARGET_ENOMEM;
+    }
+
+    host_mb->mtype = (abi_long)tswapal(target_mb->mtype);
+    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
+    ret = get_errno(safe_msgsnd(msqid, host_mb, msgsz, msgflg));
+
+    g_free(host_mb);
+    unlock_user_struct(target_mb, msgp, 0);
+    return ret;
+}
+SYSCALL_DEF(msgsnd, ARG_DEC, ARG_PTR, ARG_DEC, ARG_HEX);
+
+SYSCALL_IMPL(semctl)
+{
+    abi_long semid = arg1;
+    abi_long semnum = arg2;
+    int cmd = arg3 & 0xff;
+    abi_ulong target_arg = arg4;
+    union target_semun target_su = { .buf = target_arg };
+    union semun arg;
+    struct semid_ds dsarg;
+    unsigned short *array = NULL;
+    struct seminfo seminfo;
+    abi_long ret, err;
+
+    switch (cmd) {
+    case GETVAL:
+    case SETVAL:
+        /* In 64 bit cross-endian situations, we will erroneously pick up
+         * the wrong half of the union for the "val" element.  To rectify
+         * this, the entire 8-byte structure is byteswapped, followed by
+         * a swap of the 4 byte val field. In other cases, the data is
+         * already in proper host byte order. */
+        if (sizeof(target_su.val) != sizeof(target_su.buf)) {
+            target_su.buf = tswapal(target_su.buf);
+            arg.val = tswap32(target_su.val);
+        } else {
+            arg.val = target_su.val;
+        }
+        return get_errno(semctl(semid, semnum, cmd, arg));
+
+    case GETALL:
+    case SETALL:
+        err = target_to_host_semarray(semid, &array, target_su.array);
+        if (err) {
+            return err;
+        }
+        arg.array = array;
+        ret = get_errno(semctl(semid, semnum, cmd, arg));
+        if (!is_error(ret)) {
+            err = host_to_target_semarray(semid, target_su.array, &array);
+            if (err) {
+                return err;
+            }
+        }
+        return ret;
+
+    case IPC_STAT:
+    case IPC_SET:
+    case SEM_STAT:
+        err = target_to_host_semid_ds(&dsarg, target_su.buf);
+        if (err) {
+            return err;
+        }
+        arg.buf = &dsarg;
+        ret = get_errno(semctl(semid, semnum, cmd, arg));
+        if (!is_error(ret)) {
+            err = host_to_target_semid_ds(target_su.buf, &dsarg);
+            if (err) {
+                return err;
+            }
+        }
+        return ret;
+
+    case IPC_INFO:
+    case SEM_INFO:
+        arg.__buf = &seminfo;
+        ret = get_errno(semctl(semid, semnum, cmd, arg));
+        if (!is_error(ret)) {
+            err = host_to_target_seminfo(target_su.__buf, &seminfo);
+            if (err) {
+                return err;
+            }
+        }
+        return ret;
+
+    case IPC_RMID:
+    case GETPID:
+    case GETNCNT:
+    case GETZCNT:
+        return get_errno(semctl(semid, semnum, cmd, NULL));
+
+    default:
+        return -TARGET_EINVAL;
+    }
+}
+SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
+
+SYSCALL_IMPL(semget)
+{
+    return get_errno(semget(arg1, arg2, arg3));
+}
+SYSCALL_DEF(semget, ARG_DEC, ARG_DEC, ARG_HEX);
+
+SYSCALL_IMPL(semop)
+{
+    abi_long semid = arg1;
+    abi_ulong ptr = arg2;
+    abi_ulong nsops = arg3;
+    struct sembuf sops[SEMOPM];
+
+    if (nsops > SEMOPM) {
+        return -TARGET_E2BIG;
+    }
+    if (target_to_host_sembuf(sops, ptr, nsops)) {
+        return -TARGET_EFAULT;
+    }
+    return get_errno(safe_semtimedop(semid, sops, nsops, NULL));
+}
+SYSCALL_DEF(semop, ARG_DEC, ARG_PTR, ARG_DEC);
+
+SYSCALL_IMPL(shmget)
+{
+    return get_errno(shmget(arg1, arg2, arg3));
+}
+SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX);
+
+SYSCALL_IMPL(shmctl)
+{
+    int shmid = arg1;
+    int cmd = arg2 & 0xff;
+    abi_ulong buf = arg3;
+    struct shmid_ds dsarg;
+    struct shminfo shminfo;
+    struct shm_info shm_info;
+    abi_long ret;
+
+    switch (cmd) {
+    case IPC_STAT:
+    case IPC_SET:
+    case SHM_STAT:
+        if (target_to_host_shmid_ds(&dsarg, buf)) {
+            return -TARGET_EFAULT;
+        }
+        ret = get_errno(shmctl(shmid, cmd, &dsarg));
+        if (!is_error(ret) && host_to_target_shmid_ds(buf, &dsarg)) {
+            return -TARGET_EFAULT;
+        }
+        return ret;
+
+    case IPC_INFO:
+        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
+        if (!is_error(ret) && host_to_target_shminfo(buf, &shminfo)) {
+            return -TARGET_EFAULT;
+        }
+        return ret;
+
+    case SHM_INFO:
+        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
+        if (!is_error(ret) && host_to_target_shm_info(buf, &shm_info)) {
+            return -TARGET_EFAULT;
+        }
+        return ret;
+
+    case IPC_RMID:
+    case SHM_LOCK:
+    case SHM_UNLOCK:
+        return get_errno(shmctl(shmid, cmd, NULL));
+
+    default:
+        return -TARGET_EINVAL;
+    }
+}
+SYSCALL_DEF(shmctl, ARG_DEC, ARG_DEC, ARG_PTR);
+
+SYSCALL_IMPL(shmat)
+{
+    int shmid = arg1;
+    abi_ulong shmaddr = arg2;
+    int shmflg = arg3;
+    abi_ulong raddr;
+    void *host_raddr;
+    struct shmid_ds shm_info;
+    int i, ret;
+    abi_ulong shmlba;
+
+    /* Find out the length of the shared memory segment.  */
+    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
+    if (is_error(ret)) {
+        /* can't get length, bail out */
+        return ret;
+    }
+
+    /* Validate memory placement and alignment for the guest.  */
+    shmlba = target_shmlba(cpu_env);
+    if (shmaddr & (shmlba - 1)) {
+        if (shmflg & SHM_RND) {
+            shmaddr &= ~(shmlba - 1);
+        } else {
+            return -TARGET_EINVAL;
+        }
+    }
+    if (!guest_range_valid(shmaddr, shm_info.shm_segsz)) {
+        return -TARGET_EINVAL;
+    }
+
+    mmap_lock();
+
+    if (shmaddr) {
+        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
+    } else {
+        abi_ulong mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
+        if (mmap_start == -1) {
+            errno = ENOMEM;
+            host_raddr = (void *)-1;
+        } else {
+            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
+        }
+    }
+    if (host_raddr == (void *)-1) {
+        mmap_unlock();
+        return get_errno((intptr_t)host_raddr);
+    }
+
+    raddr = h2g((uintptr_t)host_raddr);
+    page_set_flags(raddr, raddr + shm_info.shm_segsz,
+                   PAGE_VALID | PAGE_READ |
+                   (shmflg & SHM_RDONLY ? 0 : PAGE_WRITE));
+
+    for (i = 0; i < N_SHM_REGIONS; i++) {
+        if (!shm_regions[i].in_use) {
+            shm_regions[i].in_use = true;
+            shm_regions[i].start = raddr;
+            shm_regions[i].size = shm_info.shm_segsz;
+            break;
+        }
+    }
+    mmap_unlock();
+    return raddr;
+}
+
+const SyscallDef def_shmat = {
+    .name = "shmat",
+    .impl = impl_shmat,
+    .print_ret = print_syscall_ptr_ret,
+    .arg_type = { ARG_DEC, ARG_PTR, ARG_HEX }
+};
+
+SYSCALL_IMPL(shmdt)
+{
+    abi_ulong shmaddr = arg1;
+    abi_long ret;
+    int i;
+
+    mmap_lock();
+
+    for (i = 0; i < N_SHM_REGIONS; ++i) {
+        if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) {
+            shm_regions[i].in_use = false;
+            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
+            break;
+        }
+    }
+    ret = get_errno(shmdt(g2h(shmaddr)));
+
+    mmap_unlock();
+
+    return ret;
+}
+SYSCALL_DEF(shmdt, ARG_PTR);
+
+#ifdef TARGET_NR_ipc
+/* This differs from normal shmat in returning the result via a pointer.
+ * Here we have shifted that pointer to arg4.
+ */
+SYSCALL_IMPL(ipc_shmat)
+{
+    abi_long ret = impl_shmat(cpu_env, arg1, arg2, arg3, 0, 0, 0);
+
+    if (is_error(ret)) {
+        return ret;
+    }
+    if (put_user_ual(ret, arg4)) {
+        return -TARGET_EFAULT;
+    }
+    return 0;
+}
+
+static const SyscallDef def_ipc_shmat = {
+    .name = "shmat",
+    .impl = impl_ipc_shmat,
+    .arg_type = { ARG_DEC, ARG_PTR, ARG_HEX, ARG_PTR },
+};
+
+/* Demultiplex the IPC syscall and shuffle the arguments around
+ * into the "normal" ordering.
+ */
+SYSCALL_ARGS(ipc)
+{
+    int call = extract32(in[0], 0, 16);
+    int version = extract32(in[0], 16, 16);
+    abi_long first = in[1];
+    abi_long second = in[2];
+    abi_long third = in[3];
+    abi_ulong ptr = in[4];
+    abi_long fifth = in[5];
+    abi_ulong atptr;
+
+    /* IPC_* and SHM_* command values are the same on all linux platforms */
+    switch (call) {
+    case IPCOP_semop:
+        out[0] = first;
+        out[1] = ptr;
+        out[2] = second;
+        return &def_semop;
+
+    case IPCOP_semget:
+        out[0] = first;
+        out[1] = second;
+        out[2] = third;
+        return &def_semget;
+
+    case IPCOP_semctl:
+        /* The semun argument to semctl is passed by value,
+         * so dereference the ptr argument.
+         */
+        if (get_user_ual(atptr, ptr)) {
+            errno = EFAULT;
+            return NULL;
+        }
+        out[0] = first;
+        out[1] = second;
+        out[2] = third;
+        out[3] = atptr;
+        return &def_semctl;
+
+    case IPCOP_msgget:
+        out[0] = first;
+        out[1] = second;
+        return &def_msgget;
+
+    case IPCOP_msgsnd:
+        out[0] = first;
+        out[1] = ptr;
+        out[2] = second;
+        out[3] = third;
+        return &def_msgsnd;
+
+    case IPCOP_msgctl:
+        out[0] = first;
+        out[1] = second;
+        out[2] = ptr;
+        return &def_msgctl;
+
+    case IPCOP_msgrcv:
+        if (version == 0) {
+            struct target_ipc_kludge {
+                abi_long msgp;
+                abi_long msgtyp;
+            } *tmp;
+
+            if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
+                errno = EFAULT;
+                return NULL;
+            }
+            out[0] = first;
+            out[1] = tswapal(tmp->msgp);
+            out[2] = second;
+            out[3] = tswapal(tmp->msgtyp);
+            out[4] = third;
+            unlock_user_struct(tmp, ptr, 0);
+        } else {
+            out[0] = first;
+            out[1] = ptr;
+            out[2] = second;
+            out[3] = fifth;
+            out[4] = third;
+        }
+        return &def_msgrcv;
+
+    case IPCOP_shmat:
+        if (version == 1) {
+            errno = EINVAL;
+            return NULL;
+        }
+        out[0] = first;
+        out[1] = ptr;
+        out[2] = second;
+        out[3] = third;
+        return &def_ipc_shmat;
+
+    case IPCOP_shmdt:
+        out[0] = ptr;
+        return &def_shmdt;
+
+    case IPCOP_shmget:
+        out[0] = first;
+        out[1] = second;
+        out[2] = third;
+        return &def_shmget;
+
+    case IPCOP_shmctl:
+        out[0] = first;
+        out[1] = second;
+        out[2] = ptr;
+        return &def_shmctl;
+
+    default:
+        /* Invalid syscall.  Continue to impl_ipc for logging.  */
+        return def;
+    }
+}
+
+SYSCALL_IMPL(ipc)
+{
+    int call = extract32(arg1, 0, 16);
+    int version = extract32(arg1, 16, 16);
+
+    gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
+    return -TARGET_ENOSYS;
+}
+SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX);
+#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c9c9669ae2..a7d165580f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -984,43 +984,6 @@ safe_syscall2(int, nanosleep, const struct timespec *, req,
 safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
               const struct timespec *, req, struct timespec *, rem)
 #endif
-#ifdef __NR_msgsnd
-safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
-              int, flags)
-safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
-              long, msgtype, int, flags)
-safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
-              unsigned, nsops, const struct timespec *, timeout)
-#else
-/* This host kernel architecture uses a single ipc syscall; fake up
- * wrappers for the sub-operations to hide this implementation detail.
- * Annoyingly we can't include linux/ipc.h to get the constant definitions
- * for the call parameter because some structs in there conflict with the
- * sys/ipc.h ones. So we just define them here, and rely on them being
- * the same for all host architectures.
- */
-#define Q_SEMTIMEDOP 4
-#define Q_MSGSND 11
-#define Q_MSGRCV 12
-#define Q_IPCCALL(VERSION, OP) ((VERSION) << 16 | (OP))
-
-safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
-              void *, ptr, long, fifth)
-static int safe_msgsnd(int msgid, const void *msgp, size_t sz, int flags)
-{
-    return safe_ipc(Q_IPCCALL(0, Q_MSGSND), msgid, sz, flags, (void *)msgp, 0);
-}
-static int safe_msgrcv(int msgid, void *msgp, size_t sz, long type, int flags)
-{
-    return safe_ipc(Q_IPCCALL(1, Q_MSGRCV), msgid, sz, flags, msgp, type);
-}
-static int safe_semtimedop(int semid, struct sembuf *tsops, unsigned nsops,
-                           const struct timespec *timeout)
-{
-    return safe_ipc(Q_IPCCALL(0, Q_SEMTIMEDOP), semid, nsops, 0, tsops,
-                    (long)timeout);
-}
-#endif
 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
 safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr,
               size_t, len, unsigned, prio, const struct timespec *, timeout)
@@ -4234,890 +4197,6 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
 }
 #endif
 
-#define N_SHM_REGIONS	32
-
-static struct shm_region {
-    abi_ulong start;
-    abi_ulong size;
-    bool in_use;
-} shm_regions[N_SHM_REGIONS];
-
-#ifndef TARGET_SEMID64_DS
-/* asm-generic version of this struct */
-struct target_semid64_ds
-{
-  struct target_ipc_perm sem_perm;
-  abi_ulong sem_otime;
-#if TARGET_ABI_BITS == 32
-  abi_ulong __unused1;
-#endif
-  abi_ulong sem_ctime;
-#if TARGET_ABI_BITS == 32
-  abi_ulong __unused2;
-#endif
-  abi_ulong sem_nsems;
-  abi_ulong __unused3;
-  abi_ulong __unused4;
-};
-#endif
-
-static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
-                                               abi_ulong target_addr)
-{
-    struct target_ipc_perm *target_ip;
-    struct target_semid64_ds *target_sd;
-
-    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
-        return -TARGET_EFAULT;
-    target_ip = &(target_sd->sem_perm);
-    host_ip->__key = tswap32(target_ip->__key);
-    host_ip->uid = tswap32(target_ip->uid);
-    host_ip->gid = tswap32(target_ip->gid);
-    host_ip->cuid = tswap32(target_ip->cuid);
-    host_ip->cgid = tswap32(target_ip->cgid);
-#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
-    host_ip->mode = tswap32(target_ip->mode);
-#else
-    host_ip->mode = tswap16(target_ip->mode);
-#endif
-#if defined(TARGET_PPC)
-    host_ip->__seq = tswap32(target_ip->__seq);
-#else
-    host_ip->__seq = tswap16(target_ip->__seq);
-#endif
-    unlock_user_struct(target_sd, target_addr, 0);
-    return 0;
-}
-
-static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
-                                               struct ipc_perm *host_ip)
-{
-    struct target_ipc_perm *target_ip;
-    struct target_semid64_ds *target_sd;
-
-    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
-        return -TARGET_EFAULT;
-    target_ip = &(target_sd->sem_perm);
-    target_ip->__key = tswap32(host_ip->__key);
-    target_ip->uid = tswap32(host_ip->uid);
-    target_ip->gid = tswap32(host_ip->gid);
-    target_ip->cuid = tswap32(host_ip->cuid);
-    target_ip->cgid = tswap32(host_ip->cgid);
-#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
-    target_ip->mode = tswap32(host_ip->mode);
-#else
-    target_ip->mode = tswap16(host_ip->mode);
-#endif
-#if defined(TARGET_PPC)
-    target_ip->__seq = tswap32(host_ip->__seq);
-#else
-    target_ip->__seq = tswap16(host_ip->__seq);
-#endif
-    unlock_user_struct(target_sd, target_addr, 1);
-    return 0;
-}
-
-static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
-                                               abi_ulong target_addr)
-{
-    struct target_semid64_ds *target_sd;
-
-    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
-        return -TARGET_EFAULT;
-    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
-        return -TARGET_EFAULT;
-    host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
-    host_sd->sem_otime = tswapal(target_sd->sem_otime);
-    host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
-    unlock_user_struct(target_sd, target_addr, 0);
-    return 0;
-}
-
-static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
-                                               struct semid_ds *host_sd)
-{
-    struct target_semid64_ds *target_sd;
-
-    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
-        return -TARGET_EFAULT;
-    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
-        return -TARGET_EFAULT;
-    target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
-    target_sd->sem_otime = tswapal(host_sd->sem_otime);
-    target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
-    unlock_user_struct(target_sd, target_addr, 1);
-    return 0;
-}
-
-struct target_seminfo {
-    int semmap;
-    int semmni;
-    int semmns;
-    int semmnu;
-    int semmsl;
-    int semopm;
-    int semume;
-    int semusz;
-    int semvmx;
-    int semaem;
-};
-
-static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
-                                              struct seminfo *host_seminfo)
-{
-    struct target_seminfo *target_seminfo;
-    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
-        return -TARGET_EFAULT;
-    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
-    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
-    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
-    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
-    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
-    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
-    __put_user(host_seminfo->semume, &target_seminfo->semume);
-    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
-    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
-    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
-    unlock_user_struct(target_seminfo, target_addr, 1);
-    return 0;
-}
-
-union semun {
-	int val;
-	struct semid_ds *buf;
-	unsigned short *array;
-	struct seminfo *__buf;
-};
-
-union target_semun {
-	int val;
-	abi_ulong buf;
-	abi_ulong array;
-	abi_ulong __buf;
-};
-
-static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
-                                               abi_ulong target_addr)
-{
-    int nsems;
-    unsigned short *array;
-    union semun semun;
-    struct semid_ds semid_ds;
-    int i, ret;
-
-    semun.buf = &semid_ds;
-
-    ret = semctl(semid, 0, IPC_STAT, semun);
-    if (ret == -1)
-        return get_errno(ret);
-
-    nsems = semid_ds.sem_nsems;
-
-    *host_array = g_try_new(unsigned short, nsems);
-    if (!*host_array) {
-        return -TARGET_ENOMEM;
-    }
-    array = lock_user(VERIFY_READ, target_addr,
-                      nsems*sizeof(unsigned short), 1);
-    if (!array) {
-        g_free(*host_array);
-        return -TARGET_EFAULT;
-    }
-
-    for(i=0; i<nsems; i++) {
-        __get_user((*host_array)[i], &array[i]);
-    }
-    unlock_user(array, target_addr, 0);
-
-    return 0;
-}
-
-static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
-                                               unsigned short **host_array)
-{
-    int nsems;
-    unsigned short *array;
-    union semun semun;
-    struct semid_ds semid_ds;
-    int i, ret;
-
-    semun.buf = &semid_ds;
-
-    ret = semctl(semid, 0, IPC_STAT, semun);
-    if (ret == -1)
-        return get_errno(ret);
-
-    nsems = semid_ds.sem_nsems;
-
-    array = lock_user(VERIFY_WRITE, target_addr,
-                      nsems*sizeof(unsigned short), 0);
-    if (!array)
-        return -TARGET_EFAULT;
-
-    for(i=0; i<nsems; i++) {
-        __put_user((*host_array)[i], &array[i]);
-    }
-    g_free(*host_array);
-    unlock_user(array, target_addr, 1);
-
-    return 0;
-}
-
-static inline abi_long do_semctl(int semid, int semnum, int cmd,
-                                 abi_ulong target_arg)
-{
-    union target_semun target_su = { .buf = target_arg };
-    union semun arg;
-    struct semid_ds dsarg;
-    unsigned short *array = NULL;
-    struct seminfo seminfo;
-    abi_long ret = -TARGET_EINVAL;
-    abi_long err;
-    cmd &= 0xff;
-
-    switch( cmd ) {
-	case GETVAL:
-	case SETVAL:
-            /* In 64 bit cross-endian situations, we will erroneously pick up
-             * the wrong half of the union for the "val" element.  To rectify
-             * this, the entire 8-byte structure is byteswapped, followed by
-	     * a swap of the 4 byte val field. In other cases, the data is
-	     * already in proper host byte order. */
-	    if (sizeof(target_su.val) != (sizeof(target_su.buf))) {
-		target_su.buf = tswapal(target_su.buf);
-		arg.val = tswap32(target_su.val);
-	    } else {
-		arg.val = target_su.val;
-	    }
-            ret = get_errno(semctl(semid, semnum, cmd, arg));
-            break;
-	case GETALL:
-	case SETALL:
-            err = target_to_host_semarray(semid, &array, target_su.array);
-            if (err)
-                return err;
-            arg.array = array;
-            ret = get_errno(semctl(semid, semnum, cmd, arg));
-            err = host_to_target_semarray(semid, target_su.array, &array);
-            if (err)
-                return err;
-            break;
-	case IPC_STAT:
-	case IPC_SET:
-	case SEM_STAT:
-            err = target_to_host_semid_ds(&dsarg, target_su.buf);
-            if (err)
-                return err;
-            arg.buf = &dsarg;
-            ret = get_errno(semctl(semid, semnum, cmd, arg));
-            err = host_to_target_semid_ds(target_su.buf, &dsarg);
-            if (err)
-                return err;
-            break;
-	case IPC_INFO:
-	case SEM_INFO:
-            arg.__buf = &seminfo;
-            ret = get_errno(semctl(semid, semnum, cmd, arg));
-            err = host_to_target_seminfo(target_su.__buf, &seminfo);
-            if (err)
-                return err;
-            break;
-	case IPC_RMID:
-	case GETPID:
-	case GETNCNT:
-	case GETZCNT:
-            ret = get_errno(semctl(semid, semnum, cmd, NULL));
-            break;
-    }
-
-    return ret;
-}
-
-struct target_sembuf {
-    unsigned short sem_num;
-    short sem_op;
-    short sem_flg;
-};
-
-static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
-                                             abi_ulong target_addr,
-                                             unsigned nsops)
-{
-    struct target_sembuf *target_sembuf;
-    int i;
-
-    target_sembuf = lock_user(VERIFY_READ, target_addr,
-                              nsops*sizeof(struct target_sembuf), 1);
-    if (!target_sembuf)
-        return -TARGET_EFAULT;
-
-    for(i=0; i<nsops; i++) {
-        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
-        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
-        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
-    }
-
-    unlock_user(target_sembuf, target_addr, 0);
-
-    return 0;
-}
-
-static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
-{
-    struct sembuf sops[nsops];
-
-    if (target_to_host_sembuf(sops, ptr, nsops))
-        return -TARGET_EFAULT;
-
-    return get_errno(safe_semtimedop(semid, sops, nsops, NULL));
-}
-
-struct target_msqid_ds
-{
-    struct target_ipc_perm msg_perm;
-    abi_ulong msg_stime;
-#if TARGET_ABI_BITS == 32
-    abi_ulong __unused1;
-#endif
-    abi_ulong msg_rtime;
-#if TARGET_ABI_BITS == 32
-    abi_ulong __unused2;
-#endif
-    abi_ulong msg_ctime;
-#if TARGET_ABI_BITS == 32
-    abi_ulong __unused3;
-#endif
-    abi_ulong __msg_cbytes;
-    abi_ulong msg_qnum;
-    abi_ulong msg_qbytes;
-    abi_ulong msg_lspid;
-    abi_ulong msg_lrpid;
-    abi_ulong __unused4;
-    abi_ulong __unused5;
-};
-
-static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
-                                               abi_ulong target_addr)
-{
-    struct target_msqid_ds *target_md;
-
-    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
-        return -TARGET_EFAULT;
-    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
-        return -TARGET_EFAULT;
-    host_md->msg_stime = tswapal(target_md->msg_stime);
-    host_md->msg_rtime = tswapal(target_md->msg_rtime);
-    host_md->msg_ctime = tswapal(target_md->msg_ctime);
-    host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
-    host_md->msg_qnum = tswapal(target_md->msg_qnum);
-    host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
-    host_md->msg_lspid = tswapal(target_md->msg_lspid);
-    host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
-    unlock_user_struct(target_md, target_addr, 0);
-    return 0;
-}
-
-static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
-                                               struct msqid_ds *host_md)
-{
-    struct target_msqid_ds *target_md;
-
-    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
-        return -TARGET_EFAULT;
-    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
-        return -TARGET_EFAULT;
-    target_md->msg_stime = tswapal(host_md->msg_stime);
-    target_md->msg_rtime = tswapal(host_md->msg_rtime);
-    target_md->msg_ctime = tswapal(host_md->msg_ctime);
-    target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
-    target_md->msg_qnum = tswapal(host_md->msg_qnum);
-    target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
-    target_md->msg_lspid = tswapal(host_md->msg_lspid);
-    target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
-    unlock_user_struct(target_md, target_addr, 1);
-    return 0;
-}
-
-struct target_msginfo {
-    int msgpool;
-    int msgmap;
-    int msgmax;
-    int msgmnb;
-    int msgmni;
-    int msgssz;
-    int msgtql;
-    unsigned short int msgseg;
-};
-
-static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
-                                              struct msginfo *host_msginfo)
-{
-    struct target_msginfo *target_msginfo;
-    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
-        return -TARGET_EFAULT;
-    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
-    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
-    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
-    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
-    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
-    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
-    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
-    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
-    unlock_user_struct(target_msginfo, target_addr, 1);
-    return 0;
-}
-
-static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
-{
-    struct msqid_ds dsarg;
-    struct msginfo msginfo;
-    abi_long ret = -TARGET_EINVAL;
-
-    cmd &= 0xff;
-
-    switch (cmd) {
-    case IPC_STAT:
-    case IPC_SET:
-    case MSG_STAT:
-        if (target_to_host_msqid_ds(&dsarg,ptr))
-            return -TARGET_EFAULT;
-        ret = get_errno(msgctl(msgid, cmd, &dsarg));
-        if (host_to_target_msqid_ds(ptr,&dsarg))
-            return -TARGET_EFAULT;
-        break;
-    case IPC_RMID:
-        ret = get_errno(msgctl(msgid, cmd, NULL));
-        break;
-    case IPC_INFO:
-    case MSG_INFO:
-        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
-        if (host_to_target_msginfo(ptr, &msginfo))
-            return -TARGET_EFAULT;
-        break;
-    }
-
-    return ret;
-}
-
-struct target_msgbuf {
-    abi_long mtype;
-    char	mtext[1];
-};
-
-static inline abi_long do_msgsnd(int msqid, abi_long msgp,
-                                 ssize_t msgsz, int msgflg)
-{
-    struct target_msgbuf *target_mb;
-    struct msgbuf *host_mb;
-    abi_long ret = 0;
-
-    if (msgsz < 0) {
-        return -TARGET_EINVAL;
-    }
-
-    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
-        return -TARGET_EFAULT;
-    host_mb = g_try_malloc(msgsz + sizeof(long));
-    if (!host_mb) {
-        unlock_user_struct(target_mb, msgp, 0);
-        return -TARGET_ENOMEM;
-    }
-    host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
-    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
-    ret = get_errno(safe_msgsnd(msqid, host_mb, msgsz, msgflg));
-    g_free(host_mb);
-    unlock_user_struct(target_mb, msgp, 0);
-
-    return ret;
-}
-
-static inline abi_long do_msgrcv(int msqid, abi_long msgp,
-                                 ssize_t msgsz, abi_long msgtyp,
-                                 int msgflg)
-{
-    struct target_msgbuf *target_mb;
-    char *target_mtext;
-    struct msgbuf *host_mb;
-    abi_long ret = 0;
-
-    if (msgsz < 0) {
-        return -TARGET_EINVAL;
-    }
-
-    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
-        return -TARGET_EFAULT;
-
-    host_mb = g_try_malloc(msgsz + sizeof(long));
-    if (!host_mb) {
-        ret = -TARGET_ENOMEM;
-        goto end;
-    }
-    ret = get_errno(safe_msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
-
-    if (ret > 0) {
-        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
-        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
-        if (!target_mtext) {
-            ret = -TARGET_EFAULT;
-            goto end;
-        }
-        memcpy(target_mb->mtext, host_mb->mtext, ret);
-        unlock_user(target_mtext, target_mtext_addr, ret);
-    }
-
-    target_mb->mtype = tswapal(host_mb->mtype);
-
-end:
-    if (target_mb)
-        unlock_user_struct(target_mb, msgp, 1);
-    g_free(host_mb);
-    return ret;
-}
-
-static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
-                                               abi_ulong target_addr)
-{
-    struct target_shmid_ds *target_sd;
-
-    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
-        return -TARGET_EFAULT;
-    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
-        return -TARGET_EFAULT;
-    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
-    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
-    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
-    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
-    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
-    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
-    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
-    unlock_user_struct(target_sd, target_addr, 0);
-    return 0;
-}
-
-static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
-                                               struct shmid_ds *host_sd)
-{
-    struct target_shmid_ds *target_sd;
-
-    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
-        return -TARGET_EFAULT;
-    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
-        return -TARGET_EFAULT;
-    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
-    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
-    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
-    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
-    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
-    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
-    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
-    unlock_user_struct(target_sd, target_addr, 1);
-    return 0;
-}
-
-struct  target_shminfo {
-    abi_ulong shmmax;
-    abi_ulong shmmin;
-    abi_ulong shmmni;
-    abi_ulong shmseg;
-    abi_ulong shmall;
-};
-
-static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
-                                              struct shminfo *host_shminfo)
-{
-    struct target_shminfo *target_shminfo;
-    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
-        return -TARGET_EFAULT;
-    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
-    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
-    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
-    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
-    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
-    unlock_user_struct(target_shminfo, target_addr, 1);
-    return 0;
-}
-
-struct target_shm_info {
-    int used_ids;
-    abi_ulong shm_tot;
-    abi_ulong shm_rss;
-    abi_ulong shm_swp;
-    abi_ulong swap_attempts;
-    abi_ulong swap_successes;
-};
-
-static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
-                                               struct shm_info *host_shm_info)
-{
-    struct target_shm_info *target_shm_info;
-    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
-        return -TARGET_EFAULT;
-    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
-    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
-    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
-    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
-    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
-    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
-    unlock_user_struct(target_shm_info, target_addr, 1);
-    return 0;
-}
-
-static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
-{
-    struct shmid_ds dsarg;
-    struct shminfo shminfo;
-    struct shm_info shm_info;
-    abi_long ret = -TARGET_EINVAL;
-
-    cmd &= 0xff;
-
-    switch(cmd) {
-    case IPC_STAT:
-    case IPC_SET:
-    case SHM_STAT:
-        if (target_to_host_shmid_ds(&dsarg, buf))
-            return -TARGET_EFAULT;
-        ret = get_errno(shmctl(shmid, cmd, &dsarg));
-        if (host_to_target_shmid_ds(buf, &dsarg))
-            return -TARGET_EFAULT;
-        break;
-    case IPC_INFO:
-        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
-        if (host_to_target_shminfo(buf, &shminfo))
-            return -TARGET_EFAULT;
-        break;
-    case SHM_INFO:
-        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
-        if (host_to_target_shm_info(buf, &shm_info))
-            return -TARGET_EFAULT;
-        break;
-    case IPC_RMID:
-    case SHM_LOCK:
-    case SHM_UNLOCK:
-        ret = get_errno(shmctl(shmid, cmd, NULL));
-        break;
-    }
-
-    return ret;
-}
-
-#ifndef TARGET_FORCE_SHMLBA
-/* For most architectures, SHMLBA is the same as the page size;
- * some architectures have larger values, in which case they should
- * define TARGET_FORCE_SHMLBA and provide a target_shmlba() function.
- * This corresponds to the kernel arch code defining __ARCH_FORCE_SHMLBA
- * and defining its own value for SHMLBA.
- *
- * The kernel also permits SHMLBA to be set by the architecture to a
- * value larger than the page size without setting __ARCH_FORCE_SHMLBA;
- * this means that addresses are rounded to the large size if
- * SHM_RND is set but addresses not aligned to that size are not rejected
- * as long as they are at least page-aligned. Since the only architecture
- * which uses this is ia64 this code doesn't provide for that oddity.
- */
-static inline abi_ulong target_shmlba(CPUArchState *cpu_env)
-{
-    return TARGET_PAGE_SIZE;
-}
-#endif
-
-static inline abi_ulong do_shmat(CPUArchState *cpu_env,
-                                 int shmid, abi_ulong shmaddr, int shmflg)
-{
-    abi_long raddr;
-    void *host_raddr;
-    struct shmid_ds shm_info;
-    int i,ret;
-    abi_ulong shmlba;
-
-    /* find out the length of the shared memory segment */
-    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
-    if (is_error(ret)) {
-        /* can't get length, bail out */
-        return ret;
-    }
-
-    shmlba = target_shmlba(cpu_env);
-
-    if (shmaddr & (shmlba - 1)) {
-        if (shmflg & SHM_RND) {
-            shmaddr &= ~(shmlba - 1);
-        } else {
-            return -TARGET_EINVAL;
-        }
-    }
-    if (!guest_range_valid(shmaddr, shm_info.shm_segsz)) {
-        return -TARGET_EINVAL;
-    }
-
-    mmap_lock();
-
-    if (shmaddr)
-        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
-    else {
-        abi_ulong mmap_start;
-
-        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
-
-        if (mmap_start == -1) {
-            errno = ENOMEM;
-            host_raddr = (void *)-1;
-        } else
-            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
-    }
-
-    if (host_raddr == (void *)-1) {
-        mmap_unlock();
-        return get_errno((long)host_raddr);
-    }
-    raddr=h2g((unsigned long)host_raddr);
-
-    page_set_flags(raddr, raddr + shm_info.shm_segsz,
-                   PAGE_VALID | PAGE_READ |
-                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
-
-    for (i = 0; i < N_SHM_REGIONS; i++) {
-        if (!shm_regions[i].in_use) {
-            shm_regions[i].in_use = true;
-            shm_regions[i].start = raddr;
-            shm_regions[i].size = shm_info.shm_segsz;
-            break;
-        }
-    }
-
-    mmap_unlock();
-    return raddr;
-
-}
-
-static inline abi_long do_shmdt(abi_ulong shmaddr)
-{
-    int i;
-    abi_long rv;
-
-    mmap_lock();
-
-    for (i = 0; i < N_SHM_REGIONS; ++i) {
-        if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) {
-            shm_regions[i].in_use = false;
-            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
-            break;
-        }
-    }
-    rv = get_errno(shmdt(g2h(shmaddr)));
-
-    mmap_unlock();
-
-    return rv;
-}
-
-#ifdef TARGET_NR_ipc
-/* ??? This only works with linear mappings.  */
-/* do_ipc() must return target values and target errnos. */
-static abi_long do_ipc(CPUArchState *cpu_env,
-                       unsigned int call, abi_long first,
-                       abi_long second, abi_long third,
-                       abi_long ptr, abi_long fifth)
-{
-    int version;
-    abi_long ret = 0;
-
-    version = call >> 16;
-    call &= 0xffff;
-
-    switch (call) {
-    case IPCOP_semop:
-        ret = do_semop(first, ptr, second);
-        break;
-
-    case IPCOP_semget:
-        ret = get_errno(semget(first, second, third));
-        break;
-
-    case IPCOP_semctl: {
-        /* The semun argument to semctl is passed by value, so dereference the
-         * ptr argument. */
-        abi_ulong atptr;
-        get_user_ual(atptr, ptr);
-        ret = do_semctl(first, second, third, atptr);
-        break;
-    }
-
-    case IPCOP_msgget:
-        ret = get_errno(msgget(first, second));
-        break;
-
-    case IPCOP_msgsnd:
-        ret = do_msgsnd(first, ptr, second, third);
-        break;
-
-    case IPCOP_msgctl:
-        ret = do_msgctl(first, second, ptr);
-        break;
-
-    case IPCOP_msgrcv:
-        switch (version) {
-        case 0:
-            {
-                struct target_ipc_kludge {
-                    abi_long msgp;
-                    abi_long msgtyp;
-                } *tmp;
-
-                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
-                    ret = -TARGET_EFAULT;
-                    break;
-                }
-
-                ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third);
-
-                unlock_user_struct(tmp, ptr, 0);
-                break;
-            }
-        default:
-            ret = do_msgrcv(first, ptr, second, fifth, third);
-        }
-        break;
-
-    case IPCOP_shmat:
-        switch (version) {
-        default:
-        {
-            abi_ulong raddr;
-            raddr = do_shmat(cpu_env, first, ptr, second);
-            if (is_error(raddr))
-                return get_errno(raddr);
-            if (put_user_ual(raddr, third))
-                return -TARGET_EFAULT;
-            break;
-        }
-        case 1:
-            ret = -TARGET_EINVAL;
-            break;
-        }
-	break;
-    case IPCOP_shmdt:
-        ret = do_shmdt(ptr);
-	break;
-
-    case IPCOP_shmget:
-	/* IPC_* flag values are the same on all linux platforms */
-	ret = get_errno(shmget(first, second, third));
-	break;
-
-	/* IPC_* and SHM_* command values are the same on all linux platforms */
-    case IPCOP_shmctl:
-        ret = do_shmctl(first, second, ptr);
-        break;
-    default:
-	gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
-	ret = -TARGET_ENOSYS;
-	break;
-    }
-    return ret;
-}
-#endif
-
 /* kernel structure types definitions */
 
 #define STRUCT(name, ...) STRUCT_ ## name,
@@ -9398,54 +8477,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
         }
         return ret;
-#ifdef TARGET_NR_ipc
-    case TARGET_NR_ipc:
-        return do_ipc(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
-#endif
-#ifdef TARGET_NR_semget
-    case TARGET_NR_semget:
-        return get_errno(semget(arg1, arg2, arg3));
-#endif
-#ifdef TARGET_NR_semop
-    case TARGET_NR_semop:
-        return do_semop(arg1, arg2, arg3);
-#endif
-#ifdef TARGET_NR_semctl
-    case TARGET_NR_semctl:
-        return do_semctl(arg1, arg2, arg3, arg4);
-#endif
-#ifdef TARGET_NR_msgctl
-    case TARGET_NR_msgctl:
-        return do_msgctl(arg1, arg2, arg3);
-#endif
-#ifdef TARGET_NR_msgget
-    case TARGET_NR_msgget:
-        return get_errno(msgget(arg1, arg2));
-#endif
-#ifdef TARGET_NR_msgrcv
-    case TARGET_NR_msgrcv:
-        return do_msgrcv(arg1, arg2, arg3, arg4, arg5);
-#endif
-#ifdef TARGET_NR_msgsnd
-    case TARGET_NR_msgsnd:
-        return do_msgsnd(arg1, arg2, arg3, arg4);
-#endif
-#ifdef TARGET_NR_shmget
-    case TARGET_NR_shmget:
-        return get_errno(shmget(arg1, arg2, arg3));
-#endif
-#ifdef TARGET_NR_shmctl
-    case TARGET_NR_shmctl:
-        return do_shmctl(arg1, arg2, arg3);
-#endif
-#ifdef TARGET_NR_shmat
-    case TARGET_NR_shmat:
-        return do_shmat(cpu_env, arg1, arg2, arg3);
-#endif
-#ifdef TARGET_NR_shmdt
-    case TARGET_NR_shmdt:
-        return do_shmdt(arg1);
-#endif
     case TARGET_NR_fsync:
         return get_errno(fsync(arg1));
     case TARGET_NR_clone:
@@ -11879,6 +10910,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 }
 
 #include "syscall-file.inc.c"
+#include "syscall-ipc.inc.c"
 
 static const SyscallDef *syscall_table(int num)
 {
@@ -11902,6 +10934,21 @@ static const SyscallDef *syscall_table(int num)
     /*
      * Conditional syscalls.
      */
+#ifdef TARGET_NR_ipc
+    S(ipc);
+#endif
+#ifdef TARGET_NR_msgctl
+    S(msgctl);
+#endif
+#ifdef TARGET_NR_msgget
+    S(msgget);
+#endif
+#ifdef TARGET_NR_msgrcv
+    S(msgrcv);
+#endif
+#ifdef TARGET_NR_msgsnd
+    S(msgsnd);
+#endif
 #ifdef TARGET_NR_open
     S(open);
 #endif
@@ -11916,6 +10963,27 @@ static const SyscallDef *syscall_table(int num)
 #endif
 #ifdef TARGET_NR_readlinkat
     S(readlinkat);
+#endif
+#ifdef TARGET_NR_semctl
+    S(semctl);
+#endif
+#ifdef TARGET_NR_semget
+    S(semget);
+#endif
+#ifdef TARGET_NR_semop
+    S(semop);
+#endif
+#ifdef TARGET_NR_shmat
+    S(shmat);
+#endif
+#ifdef TARGET_NR_shmctl
+    S(shmctl);
+#endif
+#ifdef TARGET_NR_shmdt
+    S(shmdt);
+#endif
+#ifdef TARGET_NR_shmget
+    S(shmget);
 #endif
     }
     return NULL;
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 26ad95dc7e..15dc0e9087 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -452,9 +452,6 @@
 #ifdef TARGET_NR_io_submit
 { TARGET_NR_io_submit, "io_submit" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_ipc
-{ TARGET_NR_ipc, "ipc" , NULL, print_ipc, NULL },
-#endif
 #ifdef TARGET_NR_kcmp
 { TARGET_NR_kcmp, "kcmp" , NULL, NULL, NULL },
 #endif
@@ -608,18 +605,6 @@
 #ifdef TARGET_NR_mremap
 { TARGET_NR_mremap, "mremap" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_msgctl
-{ TARGET_NR_msgctl, "msgctl" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_msgget
-{ TARGET_NR_msgget, "msgget" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_msgrcv
-{ TARGET_NR_msgrcv, "msgrcv" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_msgsnd
-{ TARGET_NR_msgsnd, "msgsnd" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_msync
 { TARGET_NR_msync, "msync" , NULL, NULL, NULL },
 #endif
@@ -917,9 +902,6 @@
 #ifdef TARGET_NR_osf_settimeofday
 { TARGET_NR_osf_settimeofday, "osf_settimeofday" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_osf_shmat
-{ TARGET_NR_osf_shmat, "osf_shmat" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_osf_signal
 { TARGET_NR_osf_signal, "osf_signal" , NULL, NULL, NULL },
 #endif
@@ -1184,18 +1166,6 @@
 #ifdef TARGET_NR_select
 { TARGET_NR_select, "select" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_semctl
-{ TARGET_NR_semctl, "semctl" , NULL, print_semctl, NULL },
-#endif
-#ifdef TARGET_NR_semget
-{ TARGET_NR_semget, "semget" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_semop
-{ TARGET_NR_semop, "semop" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_semtimedop
-{ TARGET_NR_semtimedop, "semtimedop" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_send
 { TARGET_NR_send, "send" , NULL, NULL, NULL },
 #endif
@@ -1323,18 +1293,6 @@
 #ifdef TARGET_NR_sgetmask
 { TARGET_NR_sgetmask, "sgetmask" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_shmat
-{ TARGET_NR_shmat, "shmat" , NULL, NULL, print_syscall_ret_addr },
-#endif
-#ifdef TARGET_NR_shmctl
-{ TARGET_NR_shmctl, "shmctl" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_shmdt
-{ TARGET_NR_shmdt, "shmdt" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_shmget
-{ TARGET_NR_shmget, "shmget" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_shutdown
 { TARGET_NR_shutdown, "shutdown" , NULL, NULL, NULL },
 #endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 15/16] linux-user: Split out memory syscalls
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (13 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 14/16] linux-user: Split out ipc syscalls Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 16/16] linux-user: Split out some process syscalls Richard Henderson
  2018-08-21 17:33 ` [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Laurent Vivier
  16 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

This includes mmap, mmap2, munmap, mlock, mlockall, munlock,
munlockall, mprotect, mremap, msync.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.h         |   2 +
 linux-user/strace.c          |  55 ++---------
 linux-user/syscall-mem.inc.c | 185 +++++++++++++++++++++++++++++++++++
 linux-user/syscall.c         | 133 +++----------------------
 linux-user/strace.list       |  33 -------
 5 files changed, 210 insertions(+), 198 deletions(-)
 create mode 100644 linux-user/syscall-mem.inc.c

diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index f9a60f754c..117f025d20 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -55,6 +55,8 @@ typedef enum {
     /* These print as sets of flags.  */
     ARG_ATDIRFD,
     ARG_ATFLAG,
+    ARG_MMAPFLAG,
+    ARG_MMAPPROT,
     ARG_MODEFLAG,
     ARG_OPENFLAG,
 
diff --git a/linux-user/strace.c b/linux-user/strace.c
index b043dea124..0d7195b3f7 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -801,7 +801,7 @@ UNUSED static struct flags umount2_flags[] = {
     FLAG_END,
 };
 
-UNUSED static struct flags mmap_prot_flags[] = {
+static struct flags const mmap_prot_flags[] = {
     FLAG_GENERIC(PROT_NONE),
     FLAG_GENERIC(PROT_EXEC),
     FLAG_GENERIC(PROT_READ),
@@ -812,7 +812,7 @@ UNUSED static struct flags mmap_prot_flags[] = {
     FLAG_END,
 };
 
-UNUSED static struct flags mmap_flags[] = {
+static struct flags const mmap_flags[] = {
     FLAG_TARGET(MAP_SHARED),
     FLAG_TARGET(MAP_PRIVATE),
     FLAG_TARGET(MAP_ANONYMOUS),
@@ -2347,51 +2347,6 @@ print_utimensat(const struct syscallname *name,
 }
 #endif
 
-#if defined(TARGET_NR_mmap) || defined(TARGET_NR_mmap2)
-static void
-print_mmap(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_pointer(arg0, 0);
-    print_raw_param("%d", arg1, 0);
-    print_flags(mmap_prot_flags, arg2, 0);
-    print_flags(mmap_flags, arg3, 0);
-    print_raw_param("%d", arg4, 0);
-    print_raw_param("%#x", arg5, 1);
-    print_syscall_epilogue(name);
-}
-#define print_mmap2     print_mmap
-#endif
-
-#ifdef TARGET_NR_mprotect
-static void
-print_mprotect(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_pointer(arg0, 0);
-    print_raw_param("%d", arg1, 0);
-    print_flags(mmap_prot_flags, arg2, 1);
-    print_syscall_epilogue(name);
-}
-#endif
-
-#ifdef TARGET_NR_munmap
-static void
-print_munmap(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_pointer(arg0, 0);
-    print_raw_param("%d", arg1, 1);
-    print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_futex
 static void print_futex_op(abi_long tflag, int last)
 {
@@ -2596,6 +2551,12 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6])
         case ARG_ATFLAG:
             len = add_flags(b, rest, at_file_flags, arg, false);
             break;
+        case ARG_MMAPFLAG:
+            len = add_flags(b, rest, mmap_flags, arg, false);
+            break;
+        case ARG_MMAPPROT:
+            len = add_flags(b, rest, mmap_prot_flags, arg, false);
+            break;
         case ARG_MODEFLAG:
             len = add_flags(b, rest, mode_flags, arg, true);
             break;
diff --git a/linux-user/syscall-mem.inc.c b/linux-user/syscall-mem.inc.c
new file mode 100644
index 0000000000..856cddf2f2
--- /dev/null
+++ b/linux-user/syscall-mem.inc.c
@@ -0,0 +1,185 @@
+/*
+ *  Linux memory-related syscalls
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+static bitmask_transtbl const mmap_flags_tbl[] = {
+    { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
+    { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
+    { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
+    { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS,
+      MAP_ANONYMOUS, MAP_ANONYMOUS },
+    { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN,
+      MAP_GROWSDOWN, MAP_GROWSDOWN },
+    { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE,
+      MAP_DENYWRITE, MAP_DENYWRITE },
+    { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE,
+      MAP_EXECUTABLE, MAP_EXECUTABLE },
+    { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
+    { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE,
+      MAP_NORESERVE, MAP_NORESERVE },
+    { TARGET_MAP_HUGETLB, TARGET_MAP_HUGETLB, MAP_HUGETLB, MAP_HUGETLB },
+    /* MAP_STACK had been ignored by the kernel for quite some time.
+       Recognize it for the target insofar as we do not want to pass
+       it through to the host.  */
+    { TARGET_MAP_STACK, TARGET_MAP_STACK, 0, 0 },
+    { 0, 0, 0, 0 }
+};
+
+
+SYSCALL_IMPL(mlock)
+{
+    return get_errno(mlock(g2h(arg1), arg2));
+}
+SYSCALL_DEF(mlock, ARG_PTR, ARG_DEC);
+
+SYSCALL_IMPL(mlockall)
+{
+    int host_flag = 0;
+    if (arg1 & TARGET_MLOCKALL_MCL_CURRENT) {
+        host_flag |= MCL_CURRENT;
+    }
+    if (arg1 & TARGET_MLOCKALL_MCL_FUTURE) {
+        host_flag |= MCL_FUTURE;
+    }
+    return get_errno(mlockall(host_flag));
+}
+SYSCALL_DEF(mlockall, ARG_HEX);
+
+#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
+    (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
+    defined(TARGET_M68K) || defined(TARGET_CRIS) || \
+    defined(TARGET_MICROBLAZE) || defined(TARGET_S390X)
+SYSCALL_ARGS(mmap)
+{
+    abi_ulong ptr = in[0];
+    abi_long *v = lock_user(VERIFY_READ, ptr, 6 * sizeof(abi_long), 1);
+    if (v == NULL) {
+        errno = EFAULT;
+        return NULL;
+    }
+    out[0] = tswapal(v[0]);
+    out[1] = tswapal(v[1]);
+    out[2] = tswapal(v[2]);
+    out[3] = tswapal(v[3]);
+    out[4] = tswapal(v[4]);
+    out[5] = tswapal(v[5]);
+    unlock_user(v, ptr, 0);
+    return def;
+}
+#else
+# define args_mmap NULL
+#endif
+
+SYSCALL_IMPL(mmap)
+{
+    int host_flags = target_to_host_bitmask(arg4, mmap_flags_tbl);
+    return get_errno(target_mmap(arg1, arg2, arg3, host_flags, arg5, arg6));
+}
+
+#ifdef TARGET_NR_mmap
+static const SyscallDef def_mmap = {
+    .name = "mmap",
+    .args = args_mmap,
+    .impl = impl_mmap,
+    .print_ret = print_syscall_ptr_ret,
+    .arg_type = { ARG_PTR, ARG_DEC, ARG_MMAPPROT,
+                  ARG_MMAPFLAG, ARG_DEC, ARG_DEC }
+};
+#endif
+
+#ifdef TARGET_NR_mmap2
+/* Define mmap2 in terms of mmap.  */
+/* Note that there is a fundamental problem here in that
+ * target_mmap has an offset parameter that is abi_ulong
+ * and not off_t.  This means that we cannot actually pass
+ * through a 64-bit file offset as intended.
+ */
+
+#ifndef MMAP_SHIFT
+# define MMAP_SHIFT 12
+#endif
+
+SYSCALL_ARGS(mmap2)
+{
+    /* We have already assigned out[0-4].  */
+    out[5] = (uint64_t)(abi_ulong)in[5] << MMAP_SHIFT;
+    return def;
+}
+
+static const SyscallDef def_mmap2 = {
+    .name = "mmap2",
+    .args = args_mmap2,
+    .impl = impl_mmap,
+    .print_ret = print_syscall_ptr_ret,
+    .arg_type = { ARG_PTR, ARG_DEC, ARG_MMAPPROT,
+                  ARG_MMAPFLAG, ARG_DEC, ARG_DEC64 },
+};
+#endif
+
+SYSCALL_IMPL(mprotect)
+{
+    CPUState *cpu = ENV_GET_CPU(cpu_env);
+    TaskState *ts = cpu->opaque;
+
+    /* Special hack to detect libc making the stack executable.  */
+    if ((arg3 & PROT_GROWSDOWN)
+        && arg1 >= ts->info->stack_limit
+        && arg1 <= ts->info->start_stack) {
+        arg3 &= ~PROT_GROWSDOWN;
+        arg2 = arg2 + arg1 - ts->info->stack_limit;
+        arg1 = ts->info->stack_limit;
+    }
+    return get_errno(target_mprotect(arg1, arg2, arg3));
+}
+SYSCALL_DEF(mprotect, ARG_PTR, ARG_DEC, ARG_MMAPPROT);
+
+SYSCALL_IMPL(mremap)
+{
+    return get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
+}
+
+static const SyscallDef def_mremap = {
+    .name = "mremap",
+    .impl = impl_mremap,
+    .print_ret = print_syscall_ptr_ret,
+    .arg_type = { ARG_PTR, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR }
+};
+
+SYSCALL_IMPL(msync)
+{
+    return get_errno(msync(g2h(arg1), arg2, arg3));
+}
+SYSCALL_DEF(msync, ARG_PTR, ARG_DEC, ARG_HEX);
+
+SYSCALL_IMPL(munlock)
+{
+    return get_errno(munlock(g2h(arg1), arg2));
+}
+SYSCALL_DEF(munlock, ARG_PTR, ARG_DEC);
+
+SYSCALL_IMPL(munlockall)
+{
+    return get_errno(munlockall());
+}
+SYSCALL_DEF(munlockall);
+
+SYSCALL_IMPL(munmap)
+{
+    return get_errno(target_munmap(arg1, arg2));
+}
+SYSCALL_DEF(munmap, ARG_PTR, ARG_DEC);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index a7d165580f..f4556124e5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5054,29 +5054,6 @@ static const StructEntry struct_termios_def = {
     .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
 };
 
-static bitmask_transtbl mmap_flags_tbl[] = {
-    { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
-    { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
-    { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
-    { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS,
-      MAP_ANONYMOUS, MAP_ANONYMOUS },
-    { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN,
-      MAP_GROWSDOWN, MAP_GROWSDOWN },
-    { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE,
-      MAP_DENYWRITE, MAP_DENYWRITE },
-    { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE,
-      MAP_EXECUTABLE, MAP_EXECUTABLE },
-    { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
-    { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE,
-      MAP_NORESERVE, MAP_NORESERVE },
-    { TARGET_MAP_HUGETLB, TARGET_MAP_HUGETLB, MAP_HUGETLB, MAP_HUGETLB },
-    /* MAP_STACK had been ignored by the kernel for quite some time.
-       Recognize it for the target insofar as we do not want to pass
-       it through to the host.  */
-    { TARGET_MAP_STACK, TARGET_MAP_STACK, 0, 0 },
-    { 0, 0, 0, 0 }
-};
-
 #if defined(TARGET_I386)
 
 /* NOTE: there is really one LDT for all the threads */
@@ -6286,21 +6263,6 @@ static inline abi_long target_to_host_sigevent(struct sigevent *host_sevp,
     return 0;
 }
 
-#if defined(TARGET_NR_mlockall)
-static inline int target_to_host_mlockall_arg(int arg)
-{
-    int result = 0;
-
-    if (arg & TARGET_MLOCKALL_MCL_CURRENT) {
-        result |= MCL_CURRENT;
-    }
-    if (arg & TARGET_MLOCKALL_MCL_FUTURE) {
-        result |= MCL_FUTURE;
-    }
-    return result;
-}
-#endif
-
 #if (defined(TARGET_NR_stat64) || defined(TARGET_NR_lstat64) ||     \
      defined(TARGET_NR_fstat64) || defined(TARGET_NR_fstatat64) ||  \
      defined(TARGET_NR_newfstatat))
@@ -8000,86 +7962,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
            ret = get_errno(reboot(arg1, arg2, arg3, NULL));
         }
         return ret;
-#ifdef TARGET_NR_mmap
-    case TARGET_NR_mmap:
-#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
-    (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
-    defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
-    || defined(TARGET_S390X)
-        {
-            abi_ulong *v;
-            abi_ulong v1, v2, v3, v4, v5, v6;
-            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
-                return -TARGET_EFAULT;
-            v1 = tswapal(v[0]);
-            v2 = tswapal(v[1]);
-            v3 = tswapal(v[2]);
-            v4 = tswapal(v[3]);
-            v5 = tswapal(v[4]);
-            v6 = tswapal(v[5]);
-            unlock_user(v, arg1, 0);
-            ret = get_errno(target_mmap(v1, v2, v3,
-                                        target_to_host_bitmask(v4, mmap_flags_tbl),
-                                        v5, v6));
-        }
-#else
-        ret = get_errno(target_mmap(arg1, arg2, arg3,
-                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
-                                    arg5,
-                                    arg6));
-#endif
-        return ret;
-#endif
-#ifdef TARGET_NR_mmap2
-    case TARGET_NR_mmap2:
-#ifndef MMAP_SHIFT
-#define MMAP_SHIFT 12
-#endif
-        ret = target_mmap(arg1, arg2, arg3,
-                          target_to_host_bitmask(arg4, mmap_flags_tbl),
-                          arg5, arg6 << MMAP_SHIFT);
-        return get_errno(ret);
-#endif
-    case TARGET_NR_munmap:
-        return get_errno(target_munmap(arg1, arg2));
-    case TARGET_NR_mprotect:
-        {
-            TaskState *ts = cpu->opaque;
-            /* Special hack to detect libc making the stack executable.  */
-            if ((arg3 & PROT_GROWSDOWN)
-                && arg1 >= ts->info->stack_limit
-                && arg1 <= ts->info->start_stack) {
-                arg3 &= ~PROT_GROWSDOWN;
-                arg2 = arg2 + arg1 - ts->info->stack_limit;
-                arg1 = ts->info->stack_limit;
-            }
-        }
-        return get_errno(target_mprotect(arg1, arg2, arg3));
-#ifdef TARGET_NR_mremap
-    case TARGET_NR_mremap:
-        return get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
-#endif
-        /* ??? msync/mlock/munlock are broken for softmmu.  */
-#ifdef TARGET_NR_msync
-    case TARGET_NR_msync:
-        return get_errno(msync(g2h(arg1), arg2, arg3));
-#endif
-#ifdef TARGET_NR_mlock
-    case TARGET_NR_mlock:
-        return get_errno(mlock(g2h(arg1), arg2));
-#endif
-#ifdef TARGET_NR_munlock
-    case TARGET_NR_munlock:
-        return get_errno(munlock(g2h(arg1), arg2));
-#endif
-#ifdef TARGET_NR_mlockall
-    case TARGET_NR_mlockall:
-        return get_errno(mlockall(target_to_host_mlockall_arg(arg1)));
-#endif
-#ifdef TARGET_NR_munlockall
-    case TARGET_NR_munlockall:
-        return get_errno(munlockall());
-#endif
 #ifdef TARGET_NR_truncate
     case TARGET_NR_truncate:
         if (!(p = lock_user_string(arg1)))
@@ -10911,6 +10793,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
 #include "syscall-file.inc.c"
 #include "syscall-ipc.inc.c"
+#include "syscall-mem.inc.c"
 
 static const SyscallDef *syscall_table(int num)
 {
@@ -10921,6 +10804,14 @@ static const SyscallDef *syscall_table(int num)
      * Unconditional syscalls.
      */
     S(close);
+    S(mlock);
+    S(mlockall);
+    S(mprotect);
+    S(mremap);
+    S(msync);
+    S(munlock);
+    S(munlockall);
+    S(munmap);
     S(name_to_handle_at);
     S(openat);
     S(open_by_handle_at);
@@ -10937,6 +10828,12 @@ static const SyscallDef *syscall_table(int num)
 #ifdef TARGET_NR_ipc
     S(ipc);
 #endif
+#ifdef TARGET_NR_mmap
+    S(mmap);
+#endif
+#ifdef TARGET_NR_mmap2
+    S(mmap2);
+#endif
 #ifdef TARGET_NR_msgctl
     S(msgctl);
 #endif
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 15dc0e9087..d0160f841f 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -554,21 +554,6 @@
 #ifdef TARGET_NR_mknodat
 { TARGET_NR_mknodat, "mknodat" , NULL, print_mknodat, NULL },
 #endif
-#ifdef TARGET_NR_mlock
-{ TARGET_NR_mlock, "mlock" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_mlock2
-{ TARGET_NR_mlock2, "mlock2" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_mlockall
-{ TARGET_NR_mlockall, "mlockall" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_mmap
-{ TARGET_NR_mmap, "mmap" , NULL, print_mmap, print_syscall_ret_addr },
-#endif
-#ifdef TARGET_NR_mmap2
-{ TARGET_NR_mmap2, "mmap2" , NULL, print_mmap2, print_syscall_ret_addr },
-#endif
 #ifdef TARGET_NR_modify_ldt
 { TARGET_NR_modify_ldt, "modify_ldt" , NULL, NULL, NULL },
 #endif
@@ -578,9 +563,6 @@
 #ifdef TARGET_NR_move_pages
 { TARGET_NR_move_pages, "move_pages" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_mprotect
-{ TARGET_NR_mprotect, "mprotect" , NULL, print_mprotect, NULL },
-#endif
 #ifdef TARGET_NR_mpx
 { TARGET_NR_mpx, "mpx" , NULL, NULL, NULL },
 #endif
@@ -602,24 +584,9 @@
 #ifdef TARGET_NR_mq_unlink
 { TARGET_NR_mq_unlink, "mq_unlink" , NULL, print_mq_unlink, NULL },
 #endif
-#ifdef TARGET_NR_mremap
-{ TARGET_NR_mremap, "mremap" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_msync
-{ TARGET_NR_msync, "msync" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_multiplexer
 { TARGET_NR_multiplexer, "multiplexer" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_munlock
-{ TARGET_NR_munlock, "munlock" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_munlockall
-{ TARGET_NR_munlockall, "munlockall" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_munmap
-{ TARGET_NR_munmap, "munmap" , NULL, print_munmap, NULL },
-#endif
 #ifdef TARGET_NR_nanosleep
 { TARGET_NR_nanosleep, "nanosleep" , NULL, NULL, NULL },
 #endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH v4 16/16] linux-user: Split out some process syscalls
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (14 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 15/16] linux-user: Split out memory syscalls Richard Henderson
@ 2018-08-18 19:01 ` Richard Henderson
  2018-08-21 17:33 ` [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Laurent Vivier
  16 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-18 19:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

This includes clone, getgroups, gettid, setfsgid, setfsuid,
setgroups, setsid, setuid, fork, getegid, getegid32, geteuid,
geteuid32, getgid, getgid32, getgroups32, getpgrp, getpid,
getppid, getresgid, getresgid32, getresuid, getresuid32,
getuid, getuid32, getxgid, getxpid, getxuid, setfsgid32,
setgsuid32, setgid32, setgroups32, setregid, setregid32,
setresgid, setresgid32, setresuid, setresuid32, setreuid,
setreuid32, setuid32, vfork.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.h          |  38 ++
 linux-user/strace.c           |  36 +-
 linux-user/syscall-proc.inc.c | 909 ++++++++++++++++++++++++++++++++++
 linux-user/syscall.c          | 861 +++++---------------------------
 linux-user/strace.list        | 144 ------
 5 files changed, 1070 insertions(+), 918 deletions(-)
 create mode 100644 linux-user/syscall-proc.inc.c

diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index 117f025d20..71c5c0cba0 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -55,6 +55,7 @@ typedef enum {
     /* These print as sets of flags.  */
     ARG_ATDIRFD,
     ARG_ATFLAG,
+    ARG_CLONEFLAG,
     ARG_MMAPFLAG,
     ARG_MMAPPROT,
     ARG_MODEFLAG,
@@ -160,3 +161,40 @@ static inline uint64_t target_offset64(abi_ulong word0, abi_ulong word1)
     return word0;
 #endif
 }
+
+#ifdef USE_UID16
+static inline int high2lowuid(int uid)
+{
+    return MAX(uid, 65534);
+}
+
+static inline int high2lowgid(int gid)
+{
+    return MAX(gid, 65534);
+}
+
+static inline int low2highuid(int uid)
+{
+    return (int16_t)uid == -1 ? -1 : uid;
+}
+
+static inline int low2highgid(int gid)
+{
+    return (int16_t)gid == -1 ? -1 : gid;
+}
+
+static inline int tswapid(int id)
+{
+    return tswap16(id);
+}
+
+#define put_user_id(x, gaddr) put_user_u16(x, gaddr)
+#else
+static inline int high2lowuid(int uid) { return uid; }
+static inline int high2lowgid(int gid) { return gid; }
+static inline int low2highuid(int uid) { return uid; }
+static inline int low2highgid(int gid) { return gid; }
+static inline int tswapid(int id) { return tswap32(id); }
+
+#define put_user_id(x, gaddr) put_user_u32(x, gaddr)
+#endif /* USE_UID16 */
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 0d7195b3f7..d752b21bbb 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -836,7 +836,7 @@ static struct flags const mmap_flags[] = {
     FLAG_END,
 };
 
-UNUSED static struct flags clone_flags[] = {
+static struct flags const clone_flags[] = {
     FLAG_GENERIC(CLONE_VM),
     FLAG_GENERIC(CLONE_FS),
     FLAG_GENERIC(CLONE_FILES),
@@ -1218,37 +1218,6 @@ print_clock_adjtime(const struct syscallname *name,
 }
 #endif
 
-#ifdef TARGET_NR_clone
-static void do_print_clone(unsigned int flags, abi_ulong newsp,
-                           abi_ulong parent_tidptr, target_ulong newtls,
-                           abi_ulong child_tidptr)
-{
-    print_flags(clone_flags, flags, 0);
-    print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, newsp, 0);
-    print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, parent_tidptr, 0);
-    print_raw_param("tls=0x" TARGET_ABI_FMT_lx, newtls, 0);
-    print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, child_tidptr, 1);
-}
-
-static void
-print_clone(const struct syscallname *name,
-    abi_long arg1, abi_long arg2, abi_long arg3,
-    abi_long arg4, abi_long arg5, abi_long arg6)
-{
-    print_syscall_prologue(name);
-#if defined(TARGET_MICROBLAZE)
-    do_print_clone(arg1, arg2, arg4, arg6, arg5);
-#elif defined(TARGET_CLONE_BACKWARDS)
-    do_print_clone(arg1, arg2, arg3, arg4, arg5);
-#elif defined(TARGET_CLONE_BACKWARDS2)
-    do_print_clone(arg2, arg1, arg3, arg5, arg4);
-#else
-    do_print_clone(arg1, arg2, arg3, arg5, arg4);
-#endif
-    print_syscall_epilogue(name);
-}
-#endif
-
 #ifdef TARGET_NR_creat
 static void
 print_creat(const struct syscallname *name,
@@ -2551,6 +2520,9 @@ static void print_syscall_def1(const SyscallDef *def, int64_t args[6])
         case ARG_ATFLAG:
             len = add_flags(b, rest, at_file_flags, arg, false);
             break;
+        case ARG_CLONEFLAG:
+            len = add_flags(b, rest, clone_flags, arg, false);
+            break;
         case ARG_MMAPFLAG:
             len = add_flags(b, rest, mmap_flags, arg, false);
             break;
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
new file mode 100644
index 0000000000..cdca552e0a
--- /dev/null
+++ b/linux-user/syscall-proc.inc.c
@@ -0,0 +1,909 @@
+/*
+ *  Linux process related syscalls
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*
+ * We must do direct syscalls for setting UID/GID, because we want to
+ * implement the Linux system call semantics of "change only for this thread",
+ * not the libc/POSIX semantics of "change for all threads in process".
+ * (See http://ewontfix.com/17/ for more details.)
+ * We use the 32-bit version of the syscalls if present; if it is not
+ * then either the host architecture supports 32-bit UIDs natively with
+ * the standard syscall, or the 16-bit UID is the best we can do.
+ */
+#ifdef __NR_setuid32
+#define __NR_sys_setuid __NR_setuid32
+#else
+#define __NR_sys_setuid __NR_setuid
+#endif
+#ifdef __NR_setgid32
+#define __NR_sys_setgid __NR_setgid32
+#else
+#define __NR_sys_setgid __NR_setgid
+#endif
+#ifdef __NR_setresuid32
+#define __NR_sys_setresuid __NR_setresuid32
+#else
+#define __NR_sys_setresuid __NR_setresuid
+#endif
+#ifdef __NR_setresgid32
+#define __NR_sys_setresgid __NR_setresgid32
+#else
+#define __NR_sys_setresgid __NR_setresgid
+#endif
+
+_syscall1(int, sys_setuid, uid_t, uid)
+_syscall1(int, sys_setgid, gid_t, gid)
+_syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
+_syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
+
+#ifndef __NR_gettid
+#define __NR_gettid  -1
+#endif
+_syscall0(int, gettid)
+
+#ifndef __NR_set_tid_address
+#define __NR_set_tid_address  -1
+#endif
+_syscall1(int, set_tid_address, int *, tidptr)
+
+
+/*
+ * CLONE_VFORK is special cased early in do_fork(). The other flag bits
+ * have almost all been allocated. We cannot support any of
+ * CLONE_NEWNS, CLONE_NEWCGROUP, CLONE_NEWUTS, CLONE_NEWIPC,
+ * CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET, CLONE_PTRACE, CLONE_UNTRACED.
+ * The checks against the invalid thread masks above will catch these.
+ * (The one remaining unallocated bit is 0x1000 which used to be CLONE_PID.)
+ */
+
+#ifndef CLONE_IO
+#define CLONE_IO                0x80000000      /* Clone io context */
+#endif
+
+/*
+ * We can't directly call the host clone syscall, because this will
+ * badly confuse libc (breaking mutexes, for example). So we must
+ * divide clone flags into:
+ *  * flag combinations that look like pthread_create()
+ *  * flag combinations that look like fork()
+ *  * flags we can implement within QEMU itself
+ *  * flags we can't support and will return an error for
+ *
+ * For thread creation, all these flags must be present; for
+ * fork, none must be present.
+ */
+#define CLONE_THREAD_FLAGS                              \
+    (CLONE_VM | CLONE_FS | CLONE_FILES |                \
+     CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM)
+
+/*
+ * These flags are ignored:
+ * CLONE_DETACHED is now ignored by the kernel;
+ * CLONE_IO is just an optimisation hint to the I/O scheduler
+ */
+#define CLONE_IGNORED_FLAGS                     \
+    (CLONE_DETACHED | CLONE_IO)
+
+/* Flags for fork which we can implement within QEMU itself */
+#define CLONE_OPTIONAL_FORK_FLAGS               \
+    (CLONE_SETTLS | CLONE_PARENT_SETTID |       \
+     CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID)
+
+/* Flags for thread creation which we can implement within QEMU itself */
+#define CLONE_OPTIONAL_THREAD_FLAGS                             \
+    (CLONE_SETTLS | CLONE_PARENT_SETTID |                       \
+     CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_PARENT)
+
+#define CLONE_INVALID_FORK_FLAGS                                        \
+    (~(CSIGNAL | CLONE_OPTIONAL_FORK_FLAGS | CLONE_IGNORED_FLAGS))
+
+#define CLONE_INVALID_THREAD_FLAGS                                      \
+    (~(CSIGNAL | CLONE_THREAD_FLAGS | CLONE_OPTIONAL_THREAD_FLAGS |     \
+       CLONE_IGNORED_FLAGS))
+
+#define NEW_STACK_SIZE 0x40000
+
+static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
+typedef struct {
+    CPUArchState *env;
+    pthread_mutex_t mutex;
+    pthread_cond_t cond;
+    pthread_t thread;
+    uint32_t tid;
+    abi_ulong child_tidptr;
+    abi_ulong parent_tidptr;
+    sigset_t sigmask;
+} new_thread_info;
+
+static void *clone_func(void *arg)
+{
+    new_thread_info *info = arg;
+    CPUArchState *env = info->env;
+    CPUState *cpu = ENV_GET_CPU(env);
+    TaskState *ts = (TaskState *)cpu->opaque;
+
+    rcu_register_thread();
+    tcg_register_thread();
+    thread_cpu = cpu;
+    info->tid = gettid();
+    task_settid(ts);
+    if (info->child_tidptr) {
+        put_user_u32(info->tid, info->child_tidptr);
+    }
+    if (info->parent_tidptr) {
+        put_user_u32(info->tid, info->parent_tidptr);
+    }
+    /* Enable signals.  */
+    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
+    /* Signal to the parent that we're ready.  */
+    pthread_mutex_lock(&info->mutex);
+    pthread_cond_broadcast(&info->cond);
+    pthread_mutex_unlock(&info->mutex);
+    /* Wait until the parent has finished initializing the tls state.  */
+    pthread_mutex_lock(&clone_lock);
+    pthread_mutex_unlock(&clone_lock);
+    cpu_loop(env);
+    /* never exits */
+    return NULL;
+}
+
+static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
+                   abi_ulong parent_tidptr, abi_ulong child_tidptr,
+                   target_ulong newtls)
+{
+    CPUState *cpu = ENV_GET_CPU(env);
+    int ret;
+    TaskState *ts;
+    CPUState *new_cpu;
+    CPUArchState *new_env;
+    sigset_t sigmask;
+
+    flags &= ~CLONE_IGNORED_FLAGS;
+
+    /* Emulate vfork() with fork() */
+    if (flags & CLONE_VFORK) {
+        flags &= ~(CLONE_VFORK | CLONE_VM);
+    }
+
+    if (flags & CLONE_VM) {
+        TaskState *parent_ts = (TaskState *)cpu->opaque;
+        new_thread_info info;
+        pthread_attr_t attr;
+
+        if (((flags & CLONE_THREAD_FLAGS) != CLONE_THREAD_FLAGS) ||
+            (flags & CLONE_INVALID_THREAD_FLAGS)) {
+            return -TARGET_EINVAL;
+        }
+
+        ts = g_new0(TaskState, 1);
+        init_task_state(ts);
+
+        /* Grab a mutex so that thread setup appears atomic.  */
+        pthread_mutex_lock(&clone_lock);
+
+        /* we create a new CPU instance. */
+        new_env = cpu_copy(env);
+        /* Init regs that differ from the parent.  */
+        cpu_clone_regs(new_env, newsp);
+        new_cpu = ENV_GET_CPU(new_env);
+        new_cpu->opaque = ts;
+        ts->bprm = parent_ts->bprm;
+        ts->info = parent_ts->info;
+        ts->signal_mask = parent_ts->signal_mask;
+
+        if (flags & CLONE_CHILD_CLEARTID) {
+            ts->child_tidptr = child_tidptr;
+        }
+
+        if (flags & CLONE_SETTLS) {
+            cpu_set_tls(new_env, newtls);
+        }
+
+        memset(&info, 0, sizeof(info));
+        pthread_mutex_init(&info.mutex, NULL);
+        pthread_mutex_lock(&info.mutex);
+        pthread_cond_init(&info.cond, NULL);
+        info.env = new_env;
+        if (flags & CLONE_CHILD_SETTID) {
+            info.child_tidptr = child_tidptr;
+        }
+        if (flags & CLONE_PARENT_SETTID) {
+            info.parent_tidptr = parent_tidptr;
+        }
+
+        ret = pthread_attr_init(&attr);
+        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
+        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+        /* It is not safe to deliver signals until the child has finished
+           initializing, so temporarily block all signals.  */
+        sigfillset(&sigmask);
+        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
+
+        /* If this is our first additional thread, we need to ensure we
+         * generate code for parallel execution and flush old translations.
+         */
+        if (!parallel_cpus) {
+            parallel_cpus = true;
+            tb_flush(cpu);
+        }
+
+        ret = pthread_create(&info.thread, &attr, clone_func, &info);
+
+        /* TODO: Free new CPU state if thread creation failed.  */
+
+        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
+        pthread_attr_destroy(&attr);
+        if (ret == 0) {
+            /* Wait for the child to initialize.  */
+            pthread_cond_wait(&info.cond, &info.mutex);
+            ret = info.tid;
+        } else {
+            ret = -host_to_target_errno(ret);
+        }
+        pthread_mutex_unlock(&info.mutex);
+        pthread_cond_destroy(&info.cond);
+        pthread_mutex_destroy(&info.mutex);
+        pthread_mutex_unlock(&clone_lock);
+    } else {
+        /* if no CLONE_VM, we consider it is a fork */
+        if (flags & CLONE_INVALID_FORK_FLAGS) {
+            return -TARGET_EINVAL;
+        }
+
+        /* We can't support custom termination signals */
+        if ((flags & CSIGNAL) != TARGET_SIGCHLD) {
+            return -TARGET_EINVAL;
+        }
+
+        if (block_signals()) {
+            return -TARGET_ERESTARTSYS;
+        }
+
+        fork_start();
+        ret = fork();
+        if (ret < 0) {
+            return get_errno(-1);
+        }
+        if (ret == 0) {
+            /* Child Process.  */
+            cpu_clone_regs(env, newsp);
+            fork_end(1);
+            /* There is a race condition here.  The parent process could
+               theoretically read the TID in the child process before the child
+               tid is set.  This would require using either ptrace
+               (not implemented) or having *_tidptr to point at a shared memory
+               mapping.  We can't repeat the spinlock hack used above because
+               the child process gets its own copy of the lock.  */
+            if (flags & CLONE_CHILD_SETTID) {
+                put_user_u32(gettid(), child_tidptr);
+            }
+            if (flags & CLONE_PARENT_SETTID) {
+                put_user_u32(gettid(), parent_tidptr);
+            }
+            ts = (TaskState *)cpu->opaque;
+            if (flags & CLONE_SETTLS) {
+                cpu_set_tls(env, newtls);
+            }
+            if (flags & CLONE_CHILD_CLEARTID) {
+                ts->child_tidptr = child_tidptr;
+            }
+        } else {
+            fork_end(0);
+        }
+    }
+    return ret;
+}
+
+SYSCALL_ARGS(clone)
+{
+    abi_ulong fl, sp, ptid, ctid, tls;
+
+    /* Linux manages to have three different orderings for its
+     * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
+     * match the kernel's CONFIG_CLONE_* settings.
+     * Microblaze is further special in that it uses a sixth
+     * implicit argument to clone for the TLS pointer.
+     */
+#if defined(TARGET_MICROBLAZE)
+    fl = in[0], sp = in[1], ptid = in[3], ctid = in[4], tls = in[5];
+#elif defined(TARGET_CLONE_BACKWARDS)
+    fl = in[0], sp = in[1], ptid = in[2], tls = in[3], ctid = in[4];
+#elif defined(TARGET_CLONE_BACKWARDS2)
+    sp = in[0], fl = in[1], ptid = in[2], ctid = in[3], tls = in[4];
+#else
+    fl = in[0], sp = in[1], ptid = in[2], ctid = in[3], tls = in[4];
+#endif
+    out[0] = fl, out[1] = sp, out[2] = ptid, out[3] = ctid, out[4] = tls;
+    return def;
+}
+
+SYSCALL_IMPL(clone)
+{
+    /* We've done all of the odd ABI adjustment above.  */
+    return do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5);
+}
+SYSCALL_DEF_ARGS(clone, ARG_CLONEFLAG, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR);
+
+#ifdef TARGET_NR_fork
+SYSCALL_IMPL(fork)
+{
+    return do_fork(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0);
+}
+SYSCALL_DEF(fork);
+#endif
+
+#ifdef TARGET_NR_vfork
+SYSCALL_IMPL(vfork)
+{
+    return do_fork(cpu_env, CLONE_VFORK | CLONE_VM | TARGET_SIGCHLD,
+                   0, 0, 0, 0);
+}
+SYSCALL_DEF(vfork);
+#endif
+
+#ifdef TARGET_NR_getegid
+SYSCALL_IMPL(getegid)
+{
+    return get_errno(high2lowgid(getegid()));
+}
+SYSCALL_DEF(getegid);
+#endif
+
+#ifdef TARGET_NR_getegid32
+SYSCALL_IMPL(getegid32)
+{
+    return get_errno(getegid());
+}
+SYSCALL_DEF(getegid32);
+#endif
+
+#ifdef TARGET_NR_geteuid
+SYSCALL_IMPL(geteuid)
+{
+    return get_errno(high2lowuid(geteuid()));
+}
+SYSCALL_DEF(geteuid);
+#endif
+
+#ifdef TARGET_NR_geteuid32
+SYSCALL_IMPL(geteuid32)
+{
+    return get_errno(geteuid());
+}
+SYSCALL_DEF(geteuid32);
+#endif
+
+#ifdef TARGET_NR_getgid
+SYSCALL_IMPL(getgid)
+{
+    return get_errno(high2lowgid(getgid()));
+}
+SYSCALL_DEF(getgid);
+#endif
+
+#ifdef TARGET_NR_getgid32
+SYSCALL_IMPL(getgid32)
+{
+    return get_errno(getgid());
+}
+SYSCALL_DEF(getgid32);
+#endif
+
+SYSCALL_IMPL(getgroups)
+{
+    int gidsetsize = arg1;
+    gid_t *grouplist;
+    abi_long ret;
+
+    grouplist = g_try_new(gid_t, gidsetsize);
+    if (!grouplist) {
+        return -TARGET_ENOMEM;
+    }
+    ret = get_errno(getgroups(gidsetsize, grouplist));
+
+    if (!is_error(ret) && gidsetsize != 0) {
+        size_t target_grouplist_size = gidsetsize * sizeof(target_id);
+        target_id *target_grouplist
+            = lock_user(VERIFY_WRITE, arg2, target_grouplist_size, 0);
+        if (target_grouplist) {
+            int i;
+            for (i = 0; i < ret; i++) {
+                target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
+            }
+            unlock_user(target_grouplist, arg2, target_grouplist_size);
+        } else {
+            ret = -TARGET_EFAULT;
+        }
+    }
+    g_free(grouplist);
+    return ret;
+}
+SYSCALL_DEF(getgroups, ARG_DEC, ARG_PTR);
+
+#ifdef TARGET_NR_getgroups32
+SYSCALL_IMPL(getgroups32)
+{
+    int gidsetsize = arg1;
+    gid_t *grouplist;
+    abi_long ret;
+
+    grouplist = g_try_new(gid_t, gidsetsize);
+    if (!grouplist) {
+        return -TARGET_ENOMEM;
+    }
+    ret = get_errno(getgroups(gidsetsize, grouplist));
+
+    if (!is_error(ret) && gidsetsize != 0) {
+        uint32_t *target_grouplist
+            = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
+        if (target_grouplist) {
+            int i;
+            for (i = 0; i < ret; i++) {
+                target_grouplist[i] = tswap32(grouplist[i]);
+            }
+            unlock_user(target_grouplist, arg2, gidsetsize * 4);
+        } else {
+            ret = -TARGET_EFAULT;
+        }
+    }
+    return ret;
+}
+SYSCALL_DEF(getgroups32, ARG_DEC, ARG_PTR);
+#endif
+
+#ifdef TARGET_NR_getresgid
+SYSCALL_IMPL(getresgid)
+{
+    gid_t rgid, egid, sgid;
+    abi_long ret = get_errno(getresgid(&rgid, &egid, &sgid));
+
+    if (!is_error(ret) &&
+        (put_user_id(high2lowgid(rgid), arg1) ||
+         put_user_id(high2lowgid(egid), arg2) ||
+         put_user_id(high2lowgid(sgid), arg3))) {
+        return -TARGET_EFAULT;
+    }
+    return ret;
+}
+SYSCALL_DEF(getresgid, ARG_PTR, ARG_PTR, ARG_PTR);
+#endif
+
+#ifdef TARGET_NR_getresgid32
+SYSCALL_IMPL(getresgid32)
+{
+    gid_t rgid, egid, sgid;
+    abi_long ret = get_errno(getresgid(&rgid, &egid, &sgid));
+
+    if (!is_error(ret) &&
+        (put_user_u32(rgid, arg1) ||
+         put_user_u32(egid, arg2) ||
+         put_user_u32(sgid, arg3))) {
+        return -TARGET_EFAULT;
+    }
+    return ret;
+}
+SYSCALL_DEF(getresgid32, ARG_PTR, ARG_PTR, ARG_PTR);
+#endif
+
+#ifdef TARGET_NR_getresuid
+SYSCALL_IMPL(getresuid)
+{
+    uid_t ruid, euid, suid;
+    abi_long ret = get_errno(getresuid(&ruid, &euid, &suid));
+
+    if (!is_error(ret) &&
+        (put_user_id(high2lowuid(ruid), arg1) ||
+         put_user_id(high2lowuid(euid), arg2) ||
+         put_user_id(high2lowuid(suid), arg3))) {
+        return -TARGET_EFAULT;
+    }
+    return ret;
+}
+SYSCALL_DEF(getresuid, ARG_PTR, ARG_PTR, ARG_PTR);
+#endif
+
+#ifdef TARGET_NR_getresuid32
+SYSCALL_IMPL(getresuid32)
+{
+    uid_t ruid, euid, suid;
+    abi_long ret = get_errno(getresuid(&ruid, &euid, &suid));
+
+    if (!is_error(ret) &&
+        (put_user_u32(ruid, arg1) ||
+         put_user_u32(euid, arg2) ||
+         put_user_u32(suid, arg3))) {
+        return -TARGET_EFAULT;
+    }
+    return ret;
+}
+SYSCALL_DEF(getresuid32, ARG_PTR, ARG_PTR, ARG_PTR);
+#endif
+
+#ifdef TARGET_NR_getpgrp
+SYSCALL_IMPL(getpgrp)
+{
+    return get_errno(getpgrp());
+}
+SYSCALL_DEF(getpgrp);
+#endif
+
+#ifdef TARGET_NR_getpid
+SYSCALL_IMPL(getpid)
+{
+    return get_errno(getpid());
+}
+SYSCALL_DEF(getpid);
+#endif
+
+#ifdef TARGET_NR_getppid
+SYSCALL_IMPL(getppid)
+{
+    return get_errno(getppid());
+}
+SYSCALL_DEF(getppid);
+#endif
+
+SYSCALL_IMPL(gettid)
+{
+    return get_errno(gettid());
+}
+SYSCALL_DEF(gettid);
+
+#ifdef TARGET_NR_getuid
+SYSCALL_IMPL(getuid)
+{
+    return get_errno(high2lowuid(getuid()));
+}
+SYSCALL_DEF(getuid);
+#endif
+
+#ifdef TARGET_NR_getuid32
+SYSCALL_IMPL(getuid32)
+{
+    return get_errno(getuid());
+}
+SYSCALL_DEF(getuid32);
+#endif
+
+#ifdef TARGET_NR_getxgid
+SYSCALL_IMPL(getxgid)
+{
+    /* Alpha specific */
+    cpu_env->ir[IR_A4] = getegid();
+    return get_errno(getgid());
+}
+SYSCALL_DEF(getxgid);
+#endif
+
+#ifdef TARGET_NR_getxpid
+SYSCALL_IMPL(getxpid)
+{
+    /* Alpha specific */
+    cpu_env->ir[IR_A4] = getppid();
+    return get_errno(getpid());
+}
+SYSCALL_DEF(getxpid);
+#endif
+
+#ifdef TARGET_NR_getxuid
+SYSCALL_IMPL(getxuid)
+{
+    /* Alpha specific */
+    cpu_env->ir[IR_A4] = geteuid();
+    return get_errno(getuid());
+}
+SYSCALL_DEF(getxuid);
+#endif
+
+SYSCALL_IMPL(setfsgid)
+{
+    return get_errno(setfsgid(arg1));
+}
+SYSCALL_DEF(setfsgid, ARG_DEC);
+
+#ifdef TARGET_NR_setfsgid32
+SYSCALL_IMPL(setfsgid32)
+{
+    return get_errno(setfsgid(arg1));
+}
+SYSCALL_DEF(setfsgid32, ARG_DEC);
+#endif
+
+SYSCALL_IMPL(setfsuid)
+{
+    return get_errno(setfsuid(arg1));
+}
+SYSCALL_DEF(setfsuid, ARG_DEC);
+
+#ifdef TARGET_NR_setfsuid32
+SYSCALL_IMPL(setfsuid32)
+{
+    return get_errno(setfsuid(arg1));
+}
+SYSCALL_DEF(setfsuid32, ARG_DEC);
+#endif
+
+SYSCALL_IMPL(setgid)
+{
+    return get_errno(sys_setgid(low2highgid(arg1)));
+}
+SYSCALL_DEF(setgid, ARG_DEC);
+
+#ifdef TARGET_NR_setgid32
+SYSCALL_IMPL(setgid32)
+{
+    return get_errno(sys_setgid(arg1));
+}
+SYSCALL_DEF(setgid32, ARG_DEC);
+#endif
+
+SYSCALL_IMPL(setgroups)
+{
+    int gidsetsize = arg1;
+    gid_t *grouplist = NULL;
+    abi_long ret;
+
+    if (gidsetsize != 0) {
+        size_t target_grouplist_size = gidsetsize * sizeof(target_id);
+        target_id *target_grouplist
+            = lock_user(VERIFY_READ, arg2, target_grouplist_size, 1);
+        int i;
+
+        if (!target_grouplist) {
+            return -TARGET_EFAULT;
+        }
+        grouplist = g_try_new(gid_t, gidsetsize);
+        if (!grouplist) {
+            unlock_user(target_grouplist, arg2, 0);
+            return -TARGET_ENOMEM;
+        }
+
+        for (i = 0; i < gidsetsize; i++) {
+            grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
+        }
+        unlock_user(target_grouplist, arg2, 0);
+    }
+    ret = get_errno(setgroups(gidsetsize, grouplist));
+    g_free(grouplist);
+    return ret;
+}
+SYSCALL_DEF(setgroups, ARG_DEC, ARG_PTR);
+
+#ifdef TARGET_NR_setgroups32
+SYSCALL_IMPL(setgroups32)
+{
+    int gidsetsize = arg1;
+    gid_t *grouplist = NULL;
+    abi_long ret;
+
+    if (gidsetsize != 0) {
+        uint32_t *target_grouplist
+            = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
+        int i;
+
+        if (!target_grouplist) {
+            return -TARGET_EFAULT;
+        }
+        grouplist = g_try_new(gid_t, gidsetsize);
+        if (!grouplist) {
+            unlock_user(target_grouplist, arg2, 0);
+            return -TARGET_ENOMEM;
+        }
+
+        for (i = 0; i < gidsetsize; i++) {
+            grouplist[i] = tswap32(target_grouplist[i]);
+        }
+        unlock_user(target_grouplist, arg2, 0);
+    }
+    ret = get_errno(setgroups(gidsetsize, grouplist));
+    g_free(grouplist);
+    return ret;
+}
+SYSCALL_DEF(setgroups32, ARG_DEC, ARG_PTR);
+#endif
+
+SYSCALL_IMPL(setregid)
+{
+    return get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
+}
+SYSCALL_DEF(setregid, ARG_DEC, ARG_DEC);
+
+#ifdef TARGET_NR_setregid32
+SYSCALL_IMPL(setregid32)
+{
+    return get_errno(setregid(arg1, arg2));
+}
+SYSCALL_DEF(setregid32, ARG_DEC, ARG_DEC);
+#endif
+
+#ifdef TARGET_NR_setresgid
+SYSCALL_IMPL(setresgid)
+{
+    return get_errno(sys_setresgid(low2highgid(arg1),
+                                   low2highgid(arg2),
+                                   low2highgid(arg3)));
+}
+SYSCALL_DEF(setresgid, ARG_DEC, ARG_DEC, ARG_DEC);
+#endif
+
+#ifdef TARGET_NR_setresgid32
+SYSCALL_IMPL(setresgid32)
+{
+    return get_errno(sys_setresgid(arg1, arg2, arg3));
+}
+SYSCALL_DEF(setresgid32, ARG_DEC, ARG_DEC, ARG_DEC);
+#endif
+
+#ifdef TARGET_NR_setresuid
+SYSCALL_IMPL(setresuid)
+{
+    return get_errno(sys_setresuid(low2highuid(arg1),
+                                   low2highuid(arg2),
+                                   low2highuid(arg3)));
+}
+SYSCALL_DEF(setresuid, ARG_DEC, ARG_DEC, ARG_DEC);
+#endif
+
+#ifdef TARGET_NR_setresuid32
+SYSCALL_IMPL(setresuid32)
+{
+    return get_errno(sys_setresuid(arg1, arg2, arg3));
+}
+SYSCALL_DEF(setresuid32, ARG_DEC, ARG_DEC, ARG_DEC);
+#endif
+
+SYSCALL_IMPL(setreuid)
+{
+    return get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
+}
+SYSCALL_DEF(setreuid, ARG_DEC, ARG_DEC);
+
+#ifdef TARGET_NR_setreuid32
+SYSCALL_IMPL(setreuid32)
+{
+    return get_errno(setreuid(arg1, arg2));
+}
+SYSCALL_DEF(setreuid32, ARG_DEC, ARG_DEC);
+#endif
+
+SYSCALL_IMPL(setsid)
+{
+    return get_errno(setsid());
+}
+SYSCALL_DEF(setsid);
+
+SYSCALL_IMPL(setuid)
+{
+    return get_errno(sys_setuid(low2highuid(arg1)));
+}
+SYSCALL_DEF(setuid, ARG_DEC);
+
+#ifdef TARGET_NR_setuid32
+SYSCALL_IMPL(setuid32)
+{
+    return get_errno(sys_setuid(arg1));
+}
+SYSCALL_DEF(setuid32, ARG_DEC);
+#endif
+
+#ifdef TARGET_NR_get_thread_area
+#if defined(TARGET_I386) && defined(TARGET_ABI32)
+static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
+{
+    struct target_modify_ldt_ldt_s *target_ldt_info;
+    uint64_t *gdt_table = g2h(env->gdt.base);
+    uint32_t base_addr, limit, flags;
+    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
+    int seg_not_present, useable, lm;
+    uint32_t *lp, entry_1, entry_2;
+
+    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
+    if (!target_ldt_info) {
+        return -TARGET_EFAULT;
+    }
+    idx = tswap32(target_ldt_info->entry_number);
+    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
+        idx > TARGET_GDT_ENTRY_TLS_MAX) {
+        unlock_user_struct(target_ldt_info, ptr, 1);
+        return -TARGET_EINVAL;
+    }
+    lp = (uint32_t *)(gdt_table + idx);
+    entry_1 = tswap32(lp[0]);
+    entry_2 = tswap32(lp[1]);
+
+    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
+    contents = (entry_2 >> 10) & 3;
+    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
+    seg_32bit = (entry_2 >> 22) & 1;
+    limit_in_pages = (entry_2 >> 23) & 1;
+    useable = (entry_2 >> 20) & 1;
+#ifdef TARGET_ABI32
+    lm = 0;
+#else
+    lm = (entry_2 >> 21) & 1;
+#endif
+    flags = (seg_32bit << 0) | (contents << 1) |
+        (read_exec_only << 3) | (limit_in_pages << 4) |
+        (seg_not_present << 5) | (useable << 6) | (lm << 7);
+    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
+    base_addr = (entry_1 >> 16) |
+        (entry_2 & 0xff000000) |
+        ((entry_2 & 0xff) << 16);
+    target_ldt_info->base_addr = tswapal(base_addr);
+    target_ldt_info->limit = tswap32(limit);
+    target_ldt_info->flags = tswap32(flags);
+    unlock_user_struct(target_ldt_info, ptr, 1);
+    return 0;
+}
+#endif
+
+SYSCALL_IMPL(get_thread_area)
+{
+#if defined(TARGET_I386) && defined(TARGET_ABI32)
+    return do_get_thread_area(cpu_env, arg1);
+#elif defined(TARGET_M68K)
+    CPUState *cpu = ENV_GET_CPU(cpu_env);
+    TaskState *ts = cpu->opaque;
+    return ts->tp_value;
+#else
+    return -TARGET_ENOSYS;
+#endif
+}
+
+static const SyscallDef def_get_thread_area = {
+    .name = "get_thread_area",
+    .impl = impl_get_thread_area,
+    .print_ret = print_syscall_ptr_ret,
+#if defined(TARGET_I386) && defined(TARGET_ABI32)
+    .arg_type = { ARG_PTR }
+#endif
+};
+#endif
+
+#ifdef TARGET_NR_set_thread_area
+SYSCALL_IMPL(set_thread_area)
+{
+#if defined(TARGET_MIPS)
+    cpu_env->active_tc.CP0_UserLocal = arg1;
+    return 0;
+#elif defined(TARGET_CRIS)
+    if (arg1 & 0xff) {
+        return -TARGET_EINVAL;
+    }
+    cpu_env->pregs[PR_PID] = arg1;
+    return 0;
+#elif defined(TARGET_I386) && defined(TARGET_ABI32)
+    return do_set_thread_area(cpu_env, arg1);
+#elif defined(TARGET_M68K)
+    CPUState *cpu = ENV_GET_CPU(cpu_env);
+    TaskState *ts = cpu->opaque;
+    ts->tp_value = arg1;
+    return 0;
+#else
+    return -TARGET_ENOSYS;
+#endif
+}
+SYSCALL_DEF(set_thread_area, ARG_PTR);
+#endif
+
+SYSCALL_IMPL(set_tid_address)
+{
+    return get_errno(set_tid_address((int *)g2h(arg1)));
+}
+SYSCALL_DEF(set_tid_address, ARG_PTR);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f4556124e5..381a79d97f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -113,57 +113,6 @@
 #include "qemu.h"
 #include "syscall.h"
 
-#ifndef CLONE_IO
-#define CLONE_IO                0x80000000      /* Clone io context */
-#endif
-
-/* We can't directly call the host clone syscall, because this will
- * badly confuse libc (breaking mutexes, for example). So we must
- * divide clone flags into:
- *  * flag combinations that look like pthread_create()
- *  * flag combinations that look like fork()
- *  * flags we can implement within QEMU itself
- *  * flags we can't support and will return an error for
- */
-/* For thread creation, all these flags must be present; for
- * fork, none must be present.
- */
-#define CLONE_THREAD_FLAGS                              \
-    (CLONE_VM | CLONE_FS | CLONE_FILES |                \
-     CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM)
-
-/* These flags are ignored:
- * CLONE_DETACHED is now ignored by the kernel;
- * CLONE_IO is just an optimisation hint to the I/O scheduler
- */
-#define CLONE_IGNORED_FLAGS                     \
-    (CLONE_DETACHED | CLONE_IO)
-
-/* Flags for fork which we can implement within QEMU itself */
-#define CLONE_OPTIONAL_FORK_FLAGS               \
-    (CLONE_SETTLS | CLONE_PARENT_SETTID |       \
-     CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID)
-
-/* Flags for thread creation which we can implement within QEMU itself */
-#define CLONE_OPTIONAL_THREAD_FLAGS                             \
-    (CLONE_SETTLS | CLONE_PARENT_SETTID |                       \
-     CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_PARENT)
-
-#define CLONE_INVALID_FORK_FLAGS                                        \
-    (~(CSIGNAL | CLONE_OPTIONAL_FORK_FLAGS | CLONE_IGNORED_FLAGS))
-
-#define CLONE_INVALID_THREAD_FLAGS                                      \
-    (~(CSIGNAL | CLONE_THREAD_FLAGS | CLONE_OPTIONAL_THREAD_FLAGS |     \
-       CLONE_IGNORED_FLAGS))
-
-/* CLONE_VFORK is special cased early in do_fork(). The other flag bits
- * have almost all been allocated. We cannot support any of
- * CLONE_NEWNS, CLONE_NEWCGROUP, CLONE_NEWUTS, CLONE_NEWIPC,
- * CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET, CLONE_PTRACE, CLONE_UNTRACED.
- * The checks against the invalid thread masks above will catch these.
- * (The one remaining unallocated bit is 0x1000 which used to be CLONE_PID.)
- */
-
 /* Define DEBUG_ERESTARTSYS to force every syscall to be restarted
  * once. This exercises the codepaths for restart.
  */
@@ -250,16 +199,6 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,	\
 #define TARGET_NR__llseek TARGET_NR_llseek
 #endif
 
-#ifdef __NR_gettid
-_syscall0(int, gettid)
-#else
-/* This is a replacement for the host gettid() and must return a host
-   errno. */
-static int gettid(void) {
-    return -ENOSYS;
-}
-#endif
-
 /* For the 64-bit guest on 32-bit host case we must emulate
  * getdents using getdents64, because otherwise the host
  * might hand us back more dirent records than we can fit
@@ -289,9 +228,6 @@ _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
 #ifdef __NR_exit_group
 _syscall1(int,exit_group,int,error_code)
 #endif
-#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
-_syscall1(int,set_tid_address,int *,tidptr)
-#endif
 #if defined(TARGET_NR_futex) && defined(__NR_futex)
 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
           const struct timespec *,timeout,int *,uaddr2,int,val3)
@@ -5278,53 +5214,6 @@ install:
     lp[1] = tswap32(entry_2);
     return 0;
 }
-
-static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
-{
-    struct target_modify_ldt_ldt_s *target_ldt_info;
-    uint64_t *gdt_table = g2h(env->gdt.base);
-    uint32_t base_addr, limit, flags;
-    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
-    int seg_not_present, useable, lm;
-    uint32_t *lp, entry_1, entry_2;
-
-    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
-    if (!target_ldt_info)
-        return -TARGET_EFAULT;
-    idx = tswap32(target_ldt_info->entry_number);
-    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
-        idx > TARGET_GDT_ENTRY_TLS_MAX) {
-        unlock_user_struct(target_ldt_info, ptr, 1);
-        return -TARGET_EINVAL;
-    }
-    lp = (uint32_t *)(gdt_table + idx);
-    entry_1 = tswap32(lp[0]);
-    entry_2 = tswap32(lp[1]);
-    
-    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
-    contents = (entry_2 >> 10) & 3;
-    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
-    seg_32bit = (entry_2 >> 22) & 1;
-    limit_in_pages = (entry_2 >> 23) & 1;
-    useable = (entry_2 >> 20) & 1;
-#ifdef TARGET_ABI32
-    lm = 0;
-#else
-    lm = (entry_2 >> 21) & 1;
-#endif
-    flags = (seg_32bit << 0) | (contents << 1) |
-        (read_exec_only << 3) | (limit_in_pages << 4) |
-        (seg_not_present << 5) | (useable << 6) | (lm << 7);
-    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
-    base_addr = (entry_1 >> 16) | 
-        (entry_2 & 0xff000000) | 
-        ((entry_2 & 0xff) << 16);
-    target_ldt_info->base_addr = tswapal(base_addr);
-    target_ldt_info->limit = tswap32(limit);
-    target_ldt_info->flags = tswap32(flags);
-    unlock_user_struct(target_ldt_info, ptr, 1);
-    return 0;
-}
 #endif /* TARGET_I386 && TARGET_ABI32 */
 
 #ifndef TARGET_ABI32
@@ -5364,194 +5253,6 @@ abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
 
 #endif /* defined(TARGET_I386) */
 
-#define NEW_STACK_SIZE 0x40000
-
-
-static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
-typedef struct {
-    CPUArchState *env;
-    pthread_mutex_t mutex;
-    pthread_cond_t cond;
-    pthread_t thread;
-    uint32_t tid;
-    abi_ulong child_tidptr;
-    abi_ulong parent_tidptr;
-    sigset_t sigmask;
-} new_thread_info;
-
-static void *clone_func(void *arg)
-{
-    new_thread_info *info = arg;
-    CPUArchState *env;
-    CPUState *cpu;
-    TaskState *ts;
-
-    rcu_register_thread();
-    tcg_register_thread();
-    env = info->env;
-    cpu = ENV_GET_CPU(env);
-    thread_cpu = cpu;
-    ts = (TaskState *)cpu->opaque;
-    info->tid = gettid();
-    task_settid(ts);
-    if (info->child_tidptr)
-        put_user_u32(info->tid, info->child_tidptr);
-    if (info->parent_tidptr)
-        put_user_u32(info->tid, info->parent_tidptr);
-    /* Enable signals.  */
-    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
-    /* Signal to the parent that we're ready.  */
-    pthread_mutex_lock(&info->mutex);
-    pthread_cond_broadcast(&info->cond);
-    pthread_mutex_unlock(&info->mutex);
-    /* Wait until the parent has finished initializing the tls state.  */
-    pthread_mutex_lock(&clone_lock);
-    pthread_mutex_unlock(&clone_lock);
-    cpu_loop(env);
-    /* never exits */
-    return NULL;
-}
-
-/* do_fork() Must return host values and target errnos (unlike most
-   do_*() functions). */
-static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
-                   abi_ulong parent_tidptr, target_ulong newtls,
-                   abi_ulong child_tidptr)
-{
-    CPUState *cpu = ENV_GET_CPU(env);
-    int ret;
-    TaskState *ts;
-    CPUState *new_cpu;
-    CPUArchState *new_env;
-    sigset_t sigmask;
-
-    flags &= ~CLONE_IGNORED_FLAGS;
-
-    /* Emulate vfork() with fork() */
-    if (flags & CLONE_VFORK)
-        flags &= ~(CLONE_VFORK | CLONE_VM);
-
-    if (flags & CLONE_VM) {
-        TaskState *parent_ts = (TaskState *)cpu->opaque;
-        new_thread_info info;
-        pthread_attr_t attr;
-
-        if (((flags & CLONE_THREAD_FLAGS) != CLONE_THREAD_FLAGS) ||
-            (flags & CLONE_INVALID_THREAD_FLAGS)) {
-            return -TARGET_EINVAL;
-        }
-
-        ts = g_new0(TaskState, 1);
-        init_task_state(ts);
-
-        /* Grab a mutex so that thread setup appears atomic.  */
-        pthread_mutex_lock(&clone_lock);
-
-        /* we create a new CPU instance. */
-        new_env = cpu_copy(env);
-        /* Init regs that differ from the parent.  */
-        cpu_clone_regs(new_env, newsp);
-        new_cpu = ENV_GET_CPU(new_env);
-        new_cpu->opaque = ts;
-        ts->bprm = parent_ts->bprm;
-        ts->info = parent_ts->info;
-        ts->signal_mask = parent_ts->signal_mask;
-
-        if (flags & CLONE_CHILD_CLEARTID) {
-            ts->child_tidptr = child_tidptr;
-        }
-
-        if (flags & CLONE_SETTLS) {
-            cpu_set_tls (new_env, newtls);
-        }
-
-        memset(&info, 0, sizeof(info));
-        pthread_mutex_init(&info.mutex, NULL);
-        pthread_mutex_lock(&info.mutex);
-        pthread_cond_init(&info.cond, NULL);
-        info.env = new_env;
-        if (flags & CLONE_CHILD_SETTID) {
-            info.child_tidptr = child_tidptr;
-        }
-        if (flags & CLONE_PARENT_SETTID) {
-            info.parent_tidptr = parent_tidptr;
-        }
-
-        ret = pthread_attr_init(&attr);
-        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
-        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-        /* It is not safe to deliver signals until the child has finished
-           initializing, so temporarily block all signals.  */
-        sigfillset(&sigmask);
-        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
-
-        /* If this is our first additional thread, we need to ensure we
-         * generate code for parallel execution and flush old translations.
-         */
-        if (!parallel_cpus) {
-            parallel_cpus = true;
-            tb_flush(cpu);
-        }
-
-        ret = pthread_create(&info.thread, &attr, clone_func, &info);
-        /* TODO: Free new CPU state if thread creation failed.  */
-
-        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
-        pthread_attr_destroy(&attr);
-        if (ret == 0) {
-            /* Wait for the child to initialize.  */
-            pthread_cond_wait(&info.cond, &info.mutex);
-            ret = info.tid;
-        } else {
-            ret = -1;
-        }
-        pthread_mutex_unlock(&info.mutex);
-        pthread_cond_destroy(&info.cond);
-        pthread_mutex_destroy(&info.mutex);
-        pthread_mutex_unlock(&clone_lock);
-    } else {
-        /* if no CLONE_VM, we consider it is a fork */
-        if (flags & CLONE_INVALID_FORK_FLAGS) {
-            return -TARGET_EINVAL;
-        }
-
-        /* We can't support custom termination signals */
-        if ((flags & CSIGNAL) != TARGET_SIGCHLD) {
-            return -TARGET_EINVAL;
-        }
-
-        if (block_signals()) {
-            return -TARGET_ERESTARTSYS;
-        }
-
-        fork_start();
-        ret = fork();
-        if (ret == 0) {
-            /* Child Process.  */
-            cpu_clone_regs(env, newsp);
-            fork_end(1);
-            /* There is a race condition here.  The parent process could
-               theoretically read the TID in the child process before the child
-               tid is set.  This would require using either ptrace
-               (not implemented) or having *_tidptr to point at a shared memory
-               mapping.  We can't repeat the spinlock hack used above because
-               the child process gets its own copy of the lock.  */
-            if (flags & CLONE_CHILD_SETTID)
-                put_user_u32(gettid(), child_tidptr);
-            if (flags & CLONE_PARENT_SETTID)
-                put_user_u32(gettid(), parent_tidptr);
-            ts = (TaskState *)cpu->opaque;
-            if (flags & CLONE_SETTLS)
-                cpu_set_tls (env, newtls);
-            if (flags & CLONE_CHILD_CLEARTID)
-                ts->child_tidptr = child_tidptr;
-        } else {
-            fork_end(0);
-        }
-    }
-    return ret;
-}
-
 /* warning : doesn't handle linux specific flags... */
 static int target_to_host_fcntl_cmd(int cmd)
 {
@@ -5921,106 +5622,6 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
     return ret;
 }
 
-#ifdef USE_UID16
-
-static inline int high2lowuid(int uid)
-{
-    if (uid > 65535)
-        return 65534;
-    else
-        return uid;
-}
-
-static inline int high2lowgid(int gid)
-{
-    if (gid > 65535)
-        return 65534;
-    else
-        return gid;
-}
-
-static inline int low2highuid(int uid)
-{
-    if ((int16_t)uid == -1)
-        return -1;
-    else
-        return uid;
-}
-
-static inline int low2highgid(int gid)
-{
-    if ((int16_t)gid == -1)
-        return -1;
-    else
-        return gid;
-}
-static inline int tswapid(int id)
-{
-    return tswap16(id);
-}
-
-#define put_user_id(x, gaddr) put_user_u16(x, gaddr)
-
-#else /* !USE_UID16 */
-static inline int high2lowuid(int uid)
-{
-    return uid;
-}
-static inline int high2lowgid(int gid)
-{
-    return gid;
-}
-static inline int low2highuid(int uid)
-{
-    return uid;
-}
-static inline int low2highgid(int gid)
-{
-    return gid;
-}
-static inline int tswapid(int id)
-{
-    return tswap32(id);
-}
-
-#define put_user_id(x, gaddr) put_user_u32(x, gaddr)
-
-#endif /* USE_UID16 */
-
-/* We must do direct syscalls for setting UID/GID, because we want to
- * implement the Linux system call semantics of "change only for this thread",
- * not the libc/POSIX semantics of "change for all threads in process".
- * (See http://ewontfix.com/17/ for more details.)
- * We use the 32-bit version of the syscalls if present; if it is not
- * then either the host architecture supports 32-bit UIDs natively with
- * the standard syscall, or the 16-bit UID is the best we can do.
- */
-#ifdef __NR_setuid32
-#define __NR_sys_setuid __NR_setuid32
-#else
-#define __NR_sys_setuid __NR_setuid
-#endif
-#ifdef __NR_setgid32
-#define __NR_sys_setgid __NR_setgid32
-#else
-#define __NR_sys_setgid __NR_setgid
-#endif
-#ifdef __NR_setresuid32
-#define __NR_sys_setresuid __NR_setresuid32
-#else
-#define __NR_sys_setresuid __NR_setresuid
-#endif
-#ifdef __NR_setresgid32
-#define __NR_sys_setresgid __NR_setresgid32
-#else
-#define __NR_sys_setresgid __NR_setresgid
-#endif
-
-_syscall1(int, sys_setuid, uid_t, uid)
-_syscall1(int, sys_setgid, gid_t, gid)
-_syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
-_syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
-
 void syscall_init(void)
 {
     IOCTLEntry *ie;
@@ -6682,10 +6283,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         return 0; /* avoid warning */
     case TARGET_NR_brk:
         return do_brk(arg1);
-#ifdef TARGET_NR_fork
-    case TARGET_NR_fork:
-        return get_errno(do_fork(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0));
-#endif
 #ifdef TARGET_NR_waitpid
     case TARGET_NR_waitpid:
         {
@@ -6911,16 +6508,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_lseek
     case TARGET_NR_lseek:
         return get_errno(lseek(arg1, arg2, arg3));
-#endif
-#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
-    /* Alpha specific */
-    case TARGET_NR_getxpid:
-        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
-        return get_errno(getpid());
-#endif
-#ifdef TARGET_NR_getpid
-    case TARGET_NR_getpid:
-        return get_errno(getpid());
 #endif
     case TARGET_NR_mount:
         {
@@ -7261,16 +6848,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         return ret;
     }
 #endif
-#ifdef TARGET_NR_getppid /* not on alpha */
-    case TARGET_NR_getppid:
-        return get_errno(getppid());
-#endif
-#ifdef TARGET_NR_getpgrp
-    case TARGET_NR_getpgrp:
-        return get_errno(getpgrp());
-#endif
-    case TARGET_NR_setsid:
-        return get_errno(setsid());
 #ifdef TARGET_NR_sigaction
     case TARGET_NR_sigaction:
         {
@@ -8361,23 +7938,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         return ret;
     case TARGET_NR_fsync:
         return get_errno(fsync(arg1));
-    case TARGET_NR_clone:
-        /* Linux manages to have three different orderings for its
-         * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
-         * match the kernel's CONFIG_CLONE_* settings.
-         * Microblaze is further special in that it uses a sixth
-         * implicit argument to clone for the TLS pointer.
-         */
-#if defined(TARGET_MICROBLAZE)
-        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
-#elif defined(TARGET_CLONE_BACKWARDS)
-        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
-#elif defined(TARGET_CLONE_BACKWARDS2)
-        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
-#else
-        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
-#endif
-        return ret;
 #ifdef __NR_exit_group
         /* new thread calls */
     case TARGET_NR_exit_group:
@@ -9130,12 +8690,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     }
 #endif
 #endif
-#ifdef TARGET_NR_vfork
-    case TARGET_NR_vfork:
-        return get_errno(do_fork(cpu_env,
-                         CLONE_VFORK | CLONE_VM | TARGET_SIGCHLD,
-                         0, 0, 0, 0));
-#endif
 #ifdef TARGET_NR_ugetrlimit
     case TARGET_NR_ugetrlimit:
     {
@@ -9218,66 +8772,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         unlock_user(p, arg1, 0);
         return ret;
 #endif
-#ifdef TARGET_NR_getuid
-    case TARGET_NR_getuid:
-        return get_errno(high2lowuid(getuid()));
-#endif
-#ifdef TARGET_NR_getgid
-    case TARGET_NR_getgid:
-        return get_errno(high2lowgid(getgid()));
-#endif
-#ifdef TARGET_NR_geteuid
-    case TARGET_NR_geteuid:
-        return get_errno(high2lowuid(geteuid()));
-#endif
-#ifdef TARGET_NR_getegid
-    case TARGET_NR_getegid:
-        return get_errno(high2lowgid(getegid()));
-#endif
-    case TARGET_NR_setreuid:
-        return get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
-    case TARGET_NR_setregid:
-        return get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
-    case TARGET_NR_getgroups:
-        {
-            int gidsetsize = arg1;
-            target_id *target_grouplist;
-            gid_t *grouplist;
-            int i;
-
-            grouplist = alloca(gidsetsize * sizeof(gid_t));
-            ret = get_errno(getgroups(gidsetsize, grouplist));
-            if (gidsetsize == 0)
-                return ret;
-            if (!is_error(ret)) {
-                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
-                if (!target_grouplist)
-                    return -TARGET_EFAULT;
-                for(i = 0;i < ret; i++)
-                    target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
-                unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
-            }
-        }
-        return ret;
-    case TARGET_NR_setgroups:
-        {
-            int gidsetsize = arg1;
-            target_id *target_grouplist;
-            gid_t *grouplist = NULL;
-            int i;
-            if (gidsetsize) {
-                grouplist = alloca(gidsetsize * sizeof(gid_t));
-                target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
-                if (!target_grouplist) {
-                    return -TARGET_EFAULT;
-                }
-                for (i = 0; i < gidsetsize; i++) {
-                    grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
-                }
-                unlock_user(target_grouplist, arg2, 0);
-            }
-            return get_errno(setgroups(gidsetsize, grouplist));
-        }
     case TARGET_NR_fchown:
         return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
 #if defined(TARGET_NR_fchownat)
@@ -9289,46 +8783,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         unlock_user(p, arg2, 0);
         return ret;
 #endif
-#ifdef TARGET_NR_setresuid
-    case TARGET_NR_setresuid:
-        return get_errno(sys_setresuid(low2highuid(arg1),
-                                       low2highuid(arg2),
-                                       low2highuid(arg3)));
-#endif
-#ifdef TARGET_NR_getresuid
-    case TARGET_NR_getresuid:
-        {
-            uid_t ruid, euid, suid;
-            ret = get_errno(getresuid(&ruid, &euid, &suid));
-            if (!is_error(ret)) {
-                if (put_user_id(high2lowuid(ruid), arg1)
-                    || put_user_id(high2lowuid(euid), arg2)
-                    || put_user_id(high2lowuid(suid), arg3))
-                    return -TARGET_EFAULT;
-            }
-        }
-        return ret;
-#endif
-#ifdef TARGET_NR_getresgid
-    case TARGET_NR_setresgid:
-        return get_errno(sys_setresgid(low2highgid(arg1),
-                                       low2highgid(arg2),
-                                       low2highgid(arg3)));
-#endif
-#ifdef TARGET_NR_getresgid
-    case TARGET_NR_getresgid:
-        {
-            gid_t rgid, egid, sgid;
-            ret = get_errno(getresgid(&rgid, &egid, &sgid));
-            if (!is_error(ret)) {
-                if (put_user_id(high2lowgid(rgid), arg1)
-                    || put_user_id(high2lowgid(egid), arg2)
-                    || put_user_id(high2lowgid(sgid), arg3))
-                    return -TARGET_EFAULT;
-            }
-        }
-        return ret;
-#endif
 #ifdef TARGET_NR_chown
     case TARGET_NR_chown:
         if (!(p = lock_user_string(arg1)))
@@ -9337,15 +8791,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         unlock_user(p, arg1, 0);
         return ret;
 #endif
-    case TARGET_NR_setuid:
-        return get_errno(sys_setuid(low2highuid(arg1)));
-    case TARGET_NR_setgid:
-        return get_errno(sys_setgid(low2highgid(arg1)));
-    case TARGET_NR_setfsuid:
-        return get_errno(setfsuid(arg1));
-    case TARGET_NR_setfsgid:
-        return get_errno(setfsgid(arg1));
-
 #ifdef TARGET_NR_lchown32
     case TARGET_NR_lchown32:
         if (!(p = lock_user_string(arg1)))
@@ -9354,31 +8799,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         unlock_user(p, arg1, 0);
         return ret;
 #endif
-#ifdef TARGET_NR_getuid32
-    case TARGET_NR_getuid32:
-        return get_errno(getuid());
-#endif
-
-#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
-   /* Alpha specific */
-    case TARGET_NR_getxuid:
-         {
-            uid_t euid;
-            euid=geteuid();
-            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
-         }
-        return get_errno(getuid());
-#endif
-#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
-   /* Alpha specific */
-    case TARGET_NR_getxgid:
-         {
-            uid_t egid;
-            egid=getegid();
-            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
-         }
-        return get_errno(getgid());
-#endif
 #if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
     /* Alpha specific */
     case TARGET_NR_osf_getsysinfo:
@@ -9539,110 +8959,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         }
         return ret;
 #endif
-
-#ifdef TARGET_NR_getgid32
-    case TARGET_NR_getgid32:
-        return get_errno(getgid());
-#endif
-#ifdef TARGET_NR_geteuid32
-    case TARGET_NR_geteuid32:
-        return get_errno(geteuid());
-#endif
-#ifdef TARGET_NR_getegid32
-    case TARGET_NR_getegid32:
-        return get_errno(getegid());
-#endif
-#ifdef TARGET_NR_setreuid32
-    case TARGET_NR_setreuid32:
-        return get_errno(setreuid(arg1, arg2));
-#endif
-#ifdef TARGET_NR_setregid32
-    case TARGET_NR_setregid32:
-        return get_errno(setregid(arg1, arg2));
-#endif
-#ifdef TARGET_NR_getgroups32
-    case TARGET_NR_getgroups32:
-        {
-            int gidsetsize = arg1;
-            uint32_t *target_grouplist;
-            gid_t *grouplist;
-            int i;
-
-            grouplist = alloca(gidsetsize * sizeof(gid_t));
-            ret = get_errno(getgroups(gidsetsize, grouplist));
-            if (gidsetsize == 0)
-                return ret;
-            if (!is_error(ret)) {
-                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
-                if (!target_grouplist) {
-                    return -TARGET_EFAULT;
-                }
-                for(i = 0;i < ret; i++)
-                    target_grouplist[i] = tswap32(grouplist[i]);
-                unlock_user(target_grouplist, arg2, gidsetsize * 4);
-            }
-        }
-        return ret;
-#endif
-#ifdef TARGET_NR_setgroups32
-    case TARGET_NR_setgroups32:
-        {
-            int gidsetsize = arg1;
-            uint32_t *target_grouplist;
-            gid_t *grouplist;
-            int i;
-
-            grouplist = alloca(gidsetsize * sizeof(gid_t));
-            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
-            if (!target_grouplist) {
-                return -TARGET_EFAULT;
-            }
-            for(i = 0;i < gidsetsize; i++)
-                grouplist[i] = tswap32(target_grouplist[i]);
-            unlock_user(target_grouplist, arg2, 0);
-            return get_errno(setgroups(gidsetsize, grouplist));
-        }
-#endif
 #ifdef TARGET_NR_fchown32
     case TARGET_NR_fchown32:
         return get_errno(fchown(arg1, arg2, arg3));
 #endif
-#ifdef TARGET_NR_setresuid32
-    case TARGET_NR_setresuid32:
-        return get_errno(sys_setresuid(arg1, arg2, arg3));
-#endif
-#ifdef TARGET_NR_getresuid32
-    case TARGET_NR_getresuid32:
-        {
-            uid_t ruid, euid, suid;
-            ret = get_errno(getresuid(&ruid, &euid, &suid));
-            if (!is_error(ret)) {
-                if (put_user_u32(ruid, arg1)
-                    || put_user_u32(euid, arg2)
-                    || put_user_u32(suid, arg3))
-                    return -TARGET_EFAULT;
-            }
-        }
-        return ret;
-#endif
-#ifdef TARGET_NR_setresgid32
-    case TARGET_NR_setresgid32:
-        return get_errno(sys_setresgid(arg1, arg2, arg3));
-#endif
-#ifdef TARGET_NR_getresgid32
-    case TARGET_NR_getresgid32:
-        {
-            gid_t rgid, egid, sgid;
-            ret = get_errno(getresgid(&rgid, &egid, &sgid));
-            if (!is_error(ret)) {
-                if (put_user_u32(rgid, arg1)
-                    || put_user_u32(egid, arg2)
-                    || put_user_u32(sgid, arg3))
-                    return -TARGET_EFAULT;
-            }
-        }
-        return ret;
-#endif
 #ifdef TARGET_NR_chown32
     case TARGET_NR_chown32:
         if (!(p = lock_user_string(arg1)))
@@ -9651,22 +8971,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         unlock_user(p, arg1, 0);
         return ret;
 #endif
-#ifdef TARGET_NR_setuid32
-    case TARGET_NR_setuid32:
-        return get_errno(sys_setuid(arg1));
-#endif
-#ifdef TARGET_NR_setgid32
-    case TARGET_NR_setgid32:
-        return get_errno(sys_setgid(arg1));
-#endif
-#ifdef TARGET_NR_setfsuid32
-    case TARGET_NR_setfsuid32:
-        return get_errno(setfsuid(arg1));
-#endif
-#ifdef TARGET_NR_setfsgid32
-    case TARGET_NR_setfsgid32:
-        return get_errno(setfsgid(arg1));
-#endif
 #ifdef TARGET_NR_mincore
     case TARGET_NR_mincore:
         {
@@ -9825,8 +9129,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_getpagesize:
         return TARGET_PAGE_SIZE;
 #endif
-    case TARGET_NR_gettid:
-        return get_errno(gettid());
 #ifdef TARGET_NR_readahead
     case TARGET_NR_readahead:
 #if TARGET_ABI_BITS == 32
@@ -10003,44 +9305,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         return ret;
 #endif
 #endif /* CONFIG_ATTR */
-#ifdef TARGET_NR_set_thread_area
-    case TARGET_NR_set_thread_area:
-#if defined(TARGET_MIPS)
-      ((CPUMIPSState *) cpu_env)->active_tc.CP0_UserLocal = arg1;
-      return 0;
-#elif defined(TARGET_CRIS)
-      if (arg1 & 0xff)
-          ret = -TARGET_EINVAL;
-      else {
-          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
-          ret = 0;
-      }
-      return ret;
-#elif defined(TARGET_I386) && defined(TARGET_ABI32)
-      return do_set_thread_area(cpu_env, arg1);
-#elif defined(TARGET_M68K)
-      {
-          TaskState *ts = cpu->opaque;
-          ts->tp_value = arg1;
-          return 0;
-      }
-#else
-      return -TARGET_ENOSYS;
-#endif
-#endif
-#ifdef TARGET_NR_get_thread_area
-    case TARGET_NR_get_thread_area:
-#if defined(TARGET_I386) && defined(TARGET_ABI32)
-        return do_get_thread_area(cpu_env, arg1);
-#elif defined(TARGET_M68K)
-        {
-            TaskState *ts = cpu->opaque;
-            return ts->tp_value;
-        }
-#else
-        return -TARGET_ENOSYS;
-#endif
-#endif
 #ifdef TARGET_NR_getdomainname
     case TARGET_NR_getdomainname:
         return -TARGET_ENOSYS;
@@ -10100,12 +9364,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         return ret;
     }
 #endif
-
-#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
-    case TARGET_NR_set_tid_address:
-        return get_errno(set_tid_address((int *)g2h(arg1)));
-#endif
-
     case TARGET_NR_tkill:
         return get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2)));
 
@@ -10794,6 +10052,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #include "syscall-file.inc.c"
 #include "syscall-ipc.inc.c"
 #include "syscall-mem.inc.c"
+#include "syscall-proc.inc.c"
 
 static const SyscallDef *syscall_table(int num)
 {
@@ -10803,7 +10062,10 @@ static const SyscallDef *syscall_table(int num)
     /*
      * Unconditional syscalls.
      */
+    S(clone);
     S(close);
+    S(getgroups);
+    S(gettid);
     S(mlock);
     S(mlockall);
     S(mprotect);
@@ -10819,12 +10081,82 @@ static const SyscallDef *syscall_table(int num)
     S(pwritev);
     S(read);
     S(readv);
+    S(setfsgid);
+    S(setfsuid);
+    S(setgid);
+    S(setgroups);
+    S(setsid);
+    S(setuid);
+    S(set_tid_address);
     S(write);
     S(writev);
 
     /*
      * Conditional syscalls.
      */
+#ifdef TARGET_NR_fork
+    S(fork);
+#endif
+#ifdef TARGET_NR_getegid
+    S(getegid);
+#endif
+#ifdef TARGET_NR_getegid32
+    S(getegid32);
+#endif
+#ifdef TARGET_NR_geteuid
+    S(geteuid);
+#endif
+#ifdef TARGET_NR_geteuid32
+    S(geteuid32);
+#endif
+#ifdef TARGET_NR_getgid
+    S(getgid);
+#endif
+#ifdef TARGET_NR_getgid32
+    S(getgid32);
+#endif
+#ifdef TARGET_NR_getgroups32
+    S(getgroups32);
+#endif
+#ifdef TARGET_NR_getpgrp
+    S(getpgrp);
+#endif
+#ifdef TARGET_NR_getpid
+    S(getpid);
+#endif
+#ifdef TARGET_NR_getppid
+    S(getppid);
+#endif
+#ifdef TARGET_NR_getresgid
+    S(getresgid);
+#endif
+#ifdef TARGET_NR_getresgid32
+    S(getresgid32);
+#endif
+#ifdef TARGET_NR_getresuid
+    S(getresuid);
+#endif
+#ifdef TARGET_NR_getresuid32
+    S(getresuid32);
+#endif
+#ifdef TARGET_NR_getuid
+    S(getuid);
+#endif
+#ifdef TARGET_NR_getuid32
+    S(getuid32);
+#endif
+#ifdef TARGET_NR_getxgid
+    S(getxgid);
+#endif
+#ifdef TARGET_NR_getxpid
+    S(getxpid);
+#endif
+#ifdef TARGET_NR_getxuid
+    S(getxuid);
+#endif
+#ifdef TARGET_NR_get_thread_area
+    S(get_thread_area);
+#endif
 #ifdef TARGET_NR_ipc
     S(ipc);
 #endif
@@ -10870,6 +10202,48 @@ static const SyscallDef *syscall_table(int num)
 #ifdef TARGET_NR_semop
     S(semop);
 #endif
+#ifdef TARGET_NR_setfsgid32
+    S(setfsgid32);
+#endif
+#ifdef TARGET_NR_setfsuid32
+    S(setfsuid32);
+#endif
+#ifdef TARGET_NR_setgid32
+    S(setgid32);
+#endif
+#ifdef TARGET_NR_setgroups32
+    S(setgroups32);
+#endif
+#ifdef TARGET_NR_setregid
+    S(setregid);
+#endif
+#ifdef TARGET_NR_setregid32
+    S(setregid32);
+#endif
+#ifdef TARGET_NR_setresgid
+    S(setresgid);
+#endif
+#ifdef TARGET_NR_setresgid32
+    S(setresgid32);
+#endif
+#ifdef TARGET_NR_setresuid
+    S(setresuid);
+#endif
+#ifdef TARGET_NR_setresuid32
+    S(setresuid32);
+#endif
+#ifdef TARGET_NR_setreuid
+    S(setreuid);
+#endif
+#ifdef TARGET_NR_setreuid32
+    S(setreuid32);
+#endif
+#ifdef TARGET_NR_setuid32
+    S(setuid32);
+#endif
+#ifdef TARGET_NR_set_thread_area
+    S(set_thread_area);
+#endif
 #ifdef TARGET_NR_shmat
     S(shmat);
 #endif
@@ -10881,6 +10255,9 @@ static const SyscallDef *syscall_table(int num)
 #endif
 #ifdef TARGET_NR_shmget
     S(shmget);
+#endif
+#ifdef TARGET_NR_vfork
+    S(vfork);
 #endif
     }
     return NULL;
diff --git a/linux-user/strace.list b/linux-user/strace.list
index d0160f841f..f19f27e4b6 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -94,9 +94,6 @@
 #ifdef TARGET_NR_clock_settime
 { TARGET_NR_clock_settime, "clock_settime" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_clone
-{ TARGET_NR_clone, "clone" , NULL, print_clone, NULL },
-#endif
 #ifdef TARGET_NR_connect
 { TARGET_NR_connect, "connect" , "%s(%d,%#x,%d)", NULL, NULL },
 #endif
@@ -223,9 +220,6 @@
 #ifdef TARGET_NR_flock
 { TARGET_NR_flock, "flock" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_fork
-{ TARGET_NR_fork, "fork" , "%s()", NULL, NULL },
-#endif
 #ifdef TARGET_NR_fremovexattr
 { TARGET_NR_fremovexattr, "fremovexattr" , NULL, NULL, NULL },
 #endif
@@ -280,30 +274,6 @@
 #ifdef TARGET_NR_getdtablesize
 { TARGET_NR_getdtablesize, "getdtablesize" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getegid
-{ TARGET_NR_getegid, "getegid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getegid32
-{ TARGET_NR_getegid32, "getegid32" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_geteuid
-{ TARGET_NR_geteuid, "geteuid" , "%s()", NULL, NULL },
-#endif
-#ifdef TARGET_NR_geteuid32
-{ TARGET_NR_geteuid32, "geteuid32" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getgid
-{ TARGET_NR_getgid, "getgid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getgid32
-{ TARGET_NR_getgid32, "getgid32" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getgroups
-{ TARGET_NR_getgroups, "getgroups" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getgroups32
-{ TARGET_NR_getgroups32, "getgroups32" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_gethostname
 { TARGET_NR_gethostname, "gethostname" , NULL, NULL, NULL },
 #endif
@@ -322,39 +292,15 @@
 #ifdef TARGET_NR_getpeername
 { TARGET_NR_getpeername, "getpeername" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getpgid
-{ TARGET_NR_getpgid, "getpgid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getpgrp
-{ TARGET_NR_getpgrp, "getpgrp" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getpid
-{ TARGET_NR_getpid, "getpid" , "%s()", NULL, NULL },
-#endif
 #ifdef TARGET_NR_getpmsg
 { TARGET_NR_getpmsg, "getpmsg" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getppid
-{ TARGET_NR_getppid, "getppid" , "%s()", NULL, NULL },
-#endif
 #ifdef TARGET_NR_getpriority
 { TARGET_NR_getpriority, "getpriority", "%s(%#x,%#x)", NULL, NULL },
 #endif
 #ifdef TARGET_NR_getrandom
 { TARGET_NR_getrandom, "getrandom", NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getresgid
-{ TARGET_NR_getresgid, "getresgid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getresgid32
-{ TARGET_NR_getresgid32, "getresgid32" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getresuid
-{ TARGET_NR_getresuid, "getresuid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getresuid32
-{ TARGET_NR_getresuid32, "getresuid32" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_getrlimit
 { TARGET_NR_getrlimit, "getrlimit" , NULL, NULL, NULL },
 #endif
@@ -364,9 +310,6 @@
 #ifdef TARGET_NR_getrusage
 { TARGET_NR_getrusage, "getrusage" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getsid
-{ TARGET_NR_getsid, "getsid" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_getsockname
 { TARGET_NR_getsockname, "getsockname" , NULL, NULL, NULL },
 #endif
@@ -377,30 +320,12 @@
 { TARGET_NR_get_thread_area, "get_thread_area", "%s(0x"TARGET_ABI_FMT_lx")",
   NULL, NULL },
 #endif
-#ifdef TARGET_NR_gettid
-{ TARGET_NR_gettid, "gettid" , "%s()", NULL, NULL },
-#endif
 #ifdef TARGET_NR_gettimeofday
 { TARGET_NR_gettimeofday, "gettimeofday" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getuid
-{ TARGET_NR_getuid, "getuid" , "%s()", NULL, NULL },
-#endif
-#ifdef TARGET_NR_getuid32
-{ TARGET_NR_getuid32, "getuid32" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_getxattr
 { TARGET_NR_getxattr, "getxattr" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_getxgid
-{ TARGET_NR_getxgid, "getxgid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getxpid
-{ TARGET_NR_getxpid, "getxpid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_getxuid
-{ TARGET_NR_getxuid, "getxuid" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_gtty
 { TARGET_NR_gtty, "gtty" , NULL, NULL, NULL },
 #endif
@@ -632,9 +557,6 @@
 #ifdef TARGET_NR_osf_alt_plock
 { TARGET_NR_osf_alt_plock, "osf_alt_plock" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_osf_alt_setsid
-{ TARGET_NR_osf_alt_setsid, "osf_alt_setsid" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_osf_alt_sigpending
 { TARGET_NR_osf_alt_sigpending, "osf_alt_sigpending" , NULL, NULL, NULL },
 #endif
@@ -1154,30 +1076,6 @@
 #ifdef TARGET_NR_setdomainname
 { TARGET_NR_setdomainname, "setdomainname" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_setfsgid
-{ TARGET_NR_setfsgid, "setfsgid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setfsgid32
-{ TARGET_NR_setfsgid32, "setfsgid32" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setfsuid
-{ TARGET_NR_setfsuid, "setfsuid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setfsuid32
-{ TARGET_NR_setfsuid32, "setfsuid32" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setgid
-{ TARGET_NR_setgid, "setgid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setgid32
-{ TARGET_NR_setgid32, "setgid32" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setgroups
-{ TARGET_NR_setgroups, "setgroups" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setgroups32
-{ TARGET_NR_setgroups32, "setgroups32" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_sethae
 { TARGET_NR_sethae, "sethae" , NULL, NULL, NULL },
 #endif
@@ -1193,48 +1091,15 @@
 #ifdef TARGET_NR_setns
 { TARGET_NR_setns, "setns" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_setpgid
-{ TARGET_NR_setpgid, "setpgid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setpgrp
-{ TARGET_NR_setpgrp, "setpgrp" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_setpriority
 { TARGET_NR_setpriority, "setpriority" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_setregid
-{ TARGET_NR_setregid, "setregid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setregid32
-{ TARGET_NR_setregid32, "setregid32" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setresgid
-{ TARGET_NR_setresgid, "setresgid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setresgid32
-{ TARGET_NR_setresgid32, "setresgid32" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setresuid
-{ TARGET_NR_setresuid, "setresuid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setresuid32
-{ TARGET_NR_setresuid32, "setresuid32" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setreuid
-{ TARGET_NR_setreuid, "setreuid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setreuid32
-{ TARGET_NR_setreuid32, "setreuid32" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_setrlimit
 { TARGET_NR_setrlimit, "setrlimit" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_set_robust_list
 { TARGET_NR_set_robust_list, "set_robust_list" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_setsid
-{ TARGET_NR_setsid, "setsid" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_setsockopt
 { TARGET_NR_setsockopt, "setsockopt" , NULL, NULL, NULL },
 #endif
@@ -1248,12 +1113,6 @@
 #ifdef TARGET_NR_settimeofday
 { TARGET_NR_settimeofday, "settimeofday" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_setuid
-{ TARGET_NR_setuid, "setuid" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_setuid32
-{ TARGET_NR_setuid32, "setuid32" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_setxattr
 { TARGET_NR_setxattr, "setxattr" , NULL, NULL, NULL },
 #endif
@@ -1488,9 +1347,6 @@
 #ifdef TARGET_NR_utrap_install
 { TARGET_NR_utrap_install, "utrap_install" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_vfork
-{ TARGET_NR_vfork, "vfork" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_vhangup
 { TARGET_NR_vhangup, "vhangup" , NULL, NULL, NULL },
 #endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v4 06/16] linux-user: Propagate goto unimplemented to default
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 06/16] linux-user: Propagate goto unimplemented to default Richard Henderson
@ 2018-08-21 16:35   ` Laurent Vivier
  2018-08-21 18:45   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 29+ messages in thread
From: Laurent Vivier @ 2018-08-21 16:35 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 18/08/2018 à 21:01, Richard Henderson a écrit :
> There is no point in listing a syscall if you want the same effect as
> not listing it.  In one less trivial case, the goto was demonstrably
> not reachable.
> 
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/syscall.c | 144 +------------------------------------------
>  1 file changed, 1 insertion(+), 143 deletions(-)
> 

Reviewed-by: Laurent Vivier <laurent@vivier.eu>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v4 08/16] configure: Use -Wunused-const-variable
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 08/16] configure: Use -Wunused-const-variable Richard Henderson
@ 2018-08-21 17:29   ` Laurent Vivier
  2018-08-21 17:34   ` Laurent Vivier
  2018-08-22  1:06   ` Laurent Vivier
  2 siblings, 0 replies; 29+ messages in thread
From: Laurent Vivier @ 2018-08-21 17:29 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 18/08/2018 à 21:01, Richard Henderson a écrit :
> For the linux-user syscall split, we have static const structs
> that must be matched up with a switch statement that uses them.
> By default, gcc will not warn for such a variable, but silently
> remove them.
> 
> For C++, such objects are sometimes declared for their constructor
> side effects.  Do not propagate this flag into QEM_CXXFLAGS.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  configure | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)

Reviewed-by: Laurent Vivier <laurent@vivier.eu>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall
  2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
                   ` (15 preceding siblings ...)
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 16/16] linux-user: Split out some process syscalls Richard Henderson
@ 2018-08-21 17:33 ` Laurent Vivier
  2018-08-21 17:36   ` Richard Henderson
  16 siblings, 1 reply; 29+ messages in thread
From: Laurent Vivier @ 2018-08-21 17:33 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 18/08/2018 à 21:01, Richard Henderson a écrit :
> Version 4 continues the split into multiple files, but for
> inclusion rather than separate compilation.  This allows us
> to get warnings if there are mistakes in the switch statement
> that looks up the structures.
> 
> 
> r~
> 
> 
> Richard Henderson (16):
>   linux-user: Remove DEBUG
>   linux-user: Split out do_syscall1
>   linux-user: Relax single exit from "break"
>   linux-user: Propagate goto efault to return
>   linux-user: Propagate goto unimplemented_nowarn to return
>   linux-user: Propagate goto unimplemented to default
>   linux-user: Propagate goto fail to return
...

Richard,

if you want I can include patches 1 to 7 in my next pull request, this
will avoid you to rebase them for every new version of the series.

Thanks,
Laurent

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v4 08/16] configure: Use -Wunused-const-variable
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 08/16] configure: Use -Wunused-const-variable Richard Henderson
  2018-08-21 17:29   ` Laurent Vivier
@ 2018-08-21 17:34   ` Laurent Vivier
  2018-08-22  1:06   ` Laurent Vivier
  2 siblings, 0 replies; 29+ messages in thread
From: Laurent Vivier @ 2018-08-21 17:34 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 18/08/2018 à 21:01, Richard Henderson a écrit :
> For the linux-user syscall split, we have static const structs
> that must be matched up with a switch statement that uses them.
> By default, gcc will not warn for such a variable, but silently
> remove them.
> 
> For C++, such objects are sometimes declared for their constructor
> side effects.  Do not propagate this flag into QEM_CXXFLAGS.

s/QEM_CXXFLAGS/QEMU_CXXFLAGS/

Laurent

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall
  2018-08-21 17:33 ` [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Laurent Vivier
@ 2018-08-21 17:36   ` Richard Henderson
  0 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2018-08-21 17:36 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel

On 08/21/2018 10:33 AM, Laurent Vivier wrote:
> if you want I can include patches 1 to 7 in my next pull request, this
> will avoid you to rebase them for every new version of the series.

That would be great, thanks.


r~

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v4 03/16] linux-user: Relax single exit from "break"
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 03/16] linux-user: Relax single exit from "break" Richard Henderson
@ 2018-08-21 18:45   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 29+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-08-21 18:45 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 08/18/2018 04:01 PM, Richard Henderson wrote:
> Transform outermost "break" to "return ret".  If the immediately
> preceeding statement was an assignment to ret, return the value
> directly.
> 
> Reviewed-by: Laurent Vivier <laurent@vivier.eu>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/syscall.c | 972 +++++++++++++++++--------------------------
>  1 file changed, 390 insertions(+), 582 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index dddd386ec4..f92a24f32a 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8017,8 +8017,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>             Do thread termination if we have more then one thread.  */
>  
>          if (block_signals()) {
> -            ret = -TARGET_ERESTARTSYS;
> -            break;
> +            return -TARGET_ERESTARTSYS;
>          }
>  
>          cpu_list_lock();
> @@ -8047,12 +8046,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          cpu_list_unlock();
>          preexit_cleanup(cpu_env, arg1);
>          _exit(arg1);
> -        ret = 0; /* avoid warning */
> -        break;
> +        return 0; /* avoid warning */
>      case TARGET_NR_read:
> -        if (arg3 == 0)
> -            ret = 0;
> -        else {
> +        if (arg3 == 0) {
> +            return 0;
> +        } else {
>              if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
>                  goto efault;
>              ret = get_errno(safe_read(arg1, p, arg3));
> @@ -8062,7 +8060,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              }
>              unlock_user(p, arg2, ret);
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_write:
>          if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
>              goto efault;
> @@ -8078,7 +8076,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              ret = get_errno(safe_write(arg1, p, arg3));
>          }
>          unlock_user(p, arg2, 0);
> -        break;
> +        return ret;
> +
>  #ifdef TARGET_NR_open
>      case TARGET_NR_open:
>          if (!(p = lock_user_string(arg1)))
> @@ -8088,7 +8087,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                                    arg3));
>          fd_trans_unregister(ret);
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_openat:
>          if (!(p = lock_user_string(arg2)))
> @@ -8098,29 +8097,27 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                                    arg4));
>          fd_trans_unregister(ret);
>          unlock_user(p, arg2, 0);
> -        break;
> +        return ret;
>  #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
>      case TARGET_NR_name_to_handle_at:
>          ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5);
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
>      case TARGET_NR_open_by_handle_at:
>          ret = do_open_by_handle_at(arg1, arg2, arg3);
>          fd_trans_unregister(ret);
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_close:
>          fd_trans_unregister(arg1);
> -        ret = get_errno(close(arg1));
> -        break;
> +        return get_errno(close(arg1));
> +
>      case TARGET_NR_brk:
> -        ret = do_brk(arg1);
> -        break;
> +        return do_brk(arg1);
>  #ifdef TARGET_NR_fork
>      case TARGET_NR_fork:
> -        ret = get_errno(do_fork(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0));
> -        break;
> +        return get_errno(do_fork(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0));
>  #endif
>  #ifdef TARGET_NR_waitpid
>      case TARGET_NR_waitpid:
> @@ -8131,7 +8128,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  && put_user_s32(host_to_target_waitstatus(status), arg2))
>                  goto efault;
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_waitid
>      case TARGET_NR_waitid:
> @@ -8146,7 +8143,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user(p, arg3, sizeof(target_siginfo_t));
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_creat /* not on alpha */
>      case TARGET_NR_creat:
> @@ -8155,7 +8152,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          ret = get_errno(creat(p, arg2));
>          fd_trans_unregister(ret);
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_link
>      case TARGET_NR_link:
> @@ -8170,7 +8167,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(p2, arg2, 0);
>              unlock_user(p, arg1, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_linkat)
>      case TARGET_NR_linkat:
> @@ -8187,7 +8184,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(p, arg2, 0);
>              unlock_user(p2, arg4, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_unlink
>      case TARGET_NR_unlink:
> @@ -8195,7 +8192,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(unlink(p));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_unlinkat)
>      case TARGET_NR_unlinkat:
> @@ -8203,7 +8200,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(unlinkat(arg1, p, arg3));
>          unlock_user(p, arg2, 0);
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_execve:
>          {
> @@ -8301,13 +8298,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              g_free(argp);
>              g_free(envp);
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_chdir:
>          if (!(p = lock_user_string(arg1)))
>              goto efault;
>          ret = get_errno(chdir(p));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_time
>      case TARGET_NR_time:
>          {
> @@ -8318,7 +8315,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  && put_user_sal(host_time, arg1))
>                  goto efault;
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_mknod
>      case TARGET_NR_mknod:
> @@ -8326,7 +8323,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(mknod(p, arg2, arg3));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_mknodat)
>      case TARGET_NR_mknodat:
> @@ -8334,7 +8331,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(mknodat(arg1, p, arg3, arg4));
>          unlock_user(p, arg2, 0);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_chmod
>      case TARGET_NR_chmod:
> @@ -8342,7 +8339,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(chmod(p, arg2));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_break
>      case TARGET_NR_break:
> @@ -8354,20 +8351,17 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #endif
>  #ifdef TARGET_NR_lseek
>      case TARGET_NR_lseek:
> -        ret = get_errno(lseek(arg1, arg2, arg3));
> -        break;
> +        return get_errno(lseek(arg1, arg2, arg3));
>  #endif
>  #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
>      /* Alpha specific */
>      case TARGET_NR_getxpid:
>          ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
> -        ret = get_errno(getpid());
> -        break;
> +        return get_errno(getpid());
>  #endif
>  #ifdef TARGET_NR_getpid
>      case TARGET_NR_getpid:
> -        ret = get_errno(getpid());
> -        break;
> +        return get_errno(getpid());
>  #endif
>      case TARGET_NR_mount:
>          {
> @@ -8423,14 +8417,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user(p3, arg3, 0);
>              }
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_umount
>      case TARGET_NR_umount:
>          if (!(p = lock_user_string(arg1)))
>              goto efault;
>          ret = get_errno(umount(p));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_stime /* not on alpha */
>      case TARGET_NR_stime:
           {
>              time_t host_time;
>              if (get_user_sal(host_time, arg1))
>                  goto efault;
> -            ret = get_errno(stime(&host_time));
> +            return get_errno(stime(&host_time));
>          }
> -        break;

This looked weird on the mail diff ;)

>  #endif
>      case TARGET_NR_ptrace:
>          goto unimplemented;
>  #ifdef TARGET_NR_alarm /* not on alpha */
>      case TARGET_NR_alarm:
> -        ret = alarm(arg1);
> -        break;
> +        return alarm(arg1);
>  #endif
>  #ifdef TARGET_NR_oldfstat
>      case TARGET_NR_oldfstat:
> @@ -8458,8 +8450,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (!block_signals()) {
>              sigsuspend(&((TaskState *)cpu->opaque)->signal_mask);
>          }
> -        ret = -TARGET_EINTR;
> -        break;
> +        return -TARGET_EINTR;
>  #endif
>  #ifdef TARGET_NR_utime
>      case TARGET_NR_utime:
> @@ -8481,7 +8472,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              ret = get_errno(utime(p, host_tbuf));
>              unlock_user(p, arg1, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_utimes
>      case TARGET_NR_utimes:
> @@ -8501,7 +8492,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              ret = get_errno(utimes(p, tvp));
>              unlock_user(p, arg1, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_futimesat)
>      case TARGET_NR_futimesat:
> @@ -8521,7 +8512,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              ret = get_errno(futimesat(arg1, path(p), tvp));
>              unlock_user(p, arg2, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_stty
>      case TARGET_NR_stty:
> @@ -8537,7 +8528,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(access(path(p), arg2));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
>      case TARGET_NR_faccessat:
> @@ -8545,12 +8536,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(faccessat(arg1, p, arg3, 0));
>          unlock_user(p, arg2, 0);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_nice /* not on alpha */
>      case TARGET_NR_nice:
> -        ret = get_errno(nice(arg1));
> -        break;
> +        return get_errno(nice(arg1));
>  #endif
>  #ifdef TARGET_NR_ftime
>      case TARGET_NR_ftime:
> @@ -8558,16 +8548,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #endif
>      case TARGET_NR_sync:
>          sync();
> -        ret = 0;
> -        break;
> +        return 0;
>  #if defined(TARGET_NR_syncfs) && defined(CONFIG_SYNCFS)
>      case TARGET_NR_syncfs:
> -        ret = get_errno(syncfs(arg1));
> -        break;
> +        return get_errno(syncfs(arg1));
>  #endif
>      case TARGET_NR_kill:
> -        ret = get_errno(safe_kill(arg1, target_to_host_signal(arg2)));
> -        break;
> +        return get_errno(safe_kill(arg1, target_to_host_signal(arg2)));
>  #ifdef TARGET_NR_rename
>      case TARGET_NR_rename:
>          {
> @@ -8581,7 +8568,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(p2, arg2, 0);
>              unlock_user(p, arg1, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_renameat)
>      case TARGET_NR_renameat:
> @@ -8596,7 +8583,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(p2, arg4, 0);
>              unlock_user(p, arg2, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_renameat2)
>      case TARGET_NR_renameat2:
> @@ -8612,7 +8599,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(p2, arg4, 0);
>              unlock_user(p, arg2, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_mkdir
>      case TARGET_NR_mkdir:
> @@ -8620,7 +8607,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(mkdir(p, arg2));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_mkdirat)
>      case TARGET_NR_mkdirat:
> @@ -8628,7 +8615,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(mkdirat(arg1, p, arg3));
>          unlock_user(p, arg2, 0);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_rmdir
>      case TARGET_NR_rmdir:
> @@ -8636,24 +8623,22 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(rmdir(p));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_dup:
>          ret = get_errno(dup(arg1));
>          if (ret >= 0) {
>              fd_trans_dup(arg1, ret);
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_pipe
>      case TARGET_NR_pipe:
> -        ret = do_pipe(cpu_env, arg1, 0, 0);
> -        break;
> +        return do_pipe(cpu_env, arg1, 0, 0);
>  #endif
>  #ifdef TARGET_NR_pipe2
>      case TARGET_NR_pipe2:
> -        ret = do_pipe(cpu_env, arg1,
> -                      target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
> -        break;
> +        return do_pipe(cpu_env, arg1,
> +                       target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
>  #endif
>      case TARGET_NR_times:
>          {
> @@ -8672,7 +8657,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              if (!is_error(ret))
>                  ret = host_to_target_clock_t(ret);
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_prof
>      case TARGET_NR_prof:
>          goto unimplemented;
> @@ -8690,34 +8675,31 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              ret = get_errno(acct(path(p)));
>              unlock_user(p, arg1, 0);
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_umount2
>      case TARGET_NR_umount2:
>          if (!(p = lock_user_string(arg1)))
>              goto efault;
>          ret = get_errno(umount2(p, arg2));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_lock
>      case TARGET_NR_lock:
>          goto unimplemented;
>  #endif
>      case TARGET_NR_ioctl:
> -        ret = do_ioctl(arg1, arg2, arg3);
> -        break;
> +        return do_ioctl(arg1, arg2, arg3);
>  #ifdef TARGET_NR_fcntl
>      case TARGET_NR_fcntl:
> -        ret = do_fcntl(arg1, arg2, arg3);
> -        break;
> +        return do_fcntl(arg1, arg2, arg3);
>  #endif
>  #ifdef TARGET_NR_mpx
>      case TARGET_NR_mpx:
>          goto unimplemented;
>  #endif
>      case TARGET_NR_setpgid:
> -        ret = get_errno(setpgid(arg1, arg2));
> -        break;
> +        return get_errno(setpgid(arg1, arg2));
>  #ifdef TARGET_NR_ulimit
>      case TARGET_NR_ulimit:
>          goto unimplemented;
> @@ -8727,14 +8709,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          goto unimplemented;
>  #endif
>      case TARGET_NR_umask:
> -        ret = get_errno(umask(arg1));
> -        break;
> +        return get_errno(umask(arg1));
>      case TARGET_NR_chroot:
>          if (!(p = lock_user_string(arg1)))
>              goto efault;
>          ret = get_errno(chroot(p));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_ustat
>      case TARGET_NR_ustat:
>          goto unimplemented;
> @@ -8745,7 +8726,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (ret >= 0) {
>              fd_trans_dup(arg1, arg2);
>          }
> -        break;
> +        return ret;
>  #endif
>  #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
>      case TARGET_NR_dup3:
> @@ -8760,22 +8741,19 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (ret >= 0) {
>              fd_trans_dup(arg1, arg2);
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  #ifdef TARGET_NR_getppid /* not on alpha */
>      case TARGET_NR_getppid:
> -        ret = get_errno(getppid());
> -        break;
> +        return get_errno(getppid());
>  #endif
>  #ifdef TARGET_NR_getpgrp
>      case TARGET_NR_getpgrp:
> -        ret = get_errno(getpgrp());
> -        break;
> +        return get_errno(getpgrp());
>  #endif
>      case TARGET_NR_setsid:
> -        ret = get_errno(setsid());
> -        break;
> +        return get_errno(setsid());
>  #ifdef TARGET_NR_sigaction
>      case TARGET_NR_sigaction:
>          {
> @@ -8859,7 +8837,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              }
>  #endif
>          }
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_rt_sigaction:
>          {
> @@ -8876,8 +8854,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              struct target_sigaction act, oact, *pact = 0;
>  
>              if (arg4 != sizeof(target_sigset_t)) {
> -                ret = -TARGET_EINVAL;
> -                break;
> +                return -TARGET_EINVAL;
>              }
>              if (arg2) {
>                  if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
> @@ -8909,8 +8886,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              struct target_sigaction *oact;
>  
>              if (sigsetsize != sizeof(target_sigset_t)) {
> -                ret = -TARGET_EINVAL;
> -                break;
> +                return -TARGET_EINVAL;
>              }
>              if (arg2) {
>                  if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) {
> @@ -8937,7 +8913,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user_struct(oact, arg3, 1);
>  #endif
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_sgetmask /* not on alpha */
>      case TARGET_NR_sgetmask:
>          {
> @@ -8949,7 +8925,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = target_set;
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_ssetmask /* not on alpha */
>      case TARGET_NR_ssetmask:
> @@ -8963,7 +8939,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = target_set;
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_sigprocmask
>      case TARGET_NR_sigprocmask:
> @@ -9033,7 +9009,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              }
>  #endif
>          }
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_rt_sigprocmask:
>          {
> @@ -9041,8 +9017,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              sigset_t set, oldset, *set_ptr;
>  
>              if (arg4 != sizeof(target_sigset_t)) {
> -                ret = -TARGET_EINVAL;
> -                break;
> +                return -TARGET_EINVAL;
>              }
>  
>              if (arg2) {
> @@ -9077,7 +9052,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user(p, arg3, sizeof(target_sigset_t));
>              }
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_sigpending
>      case TARGET_NR_sigpending:
>          {
> @@ -9090,7 +9065,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user(p, arg1, sizeof(target_sigset_t));
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_rt_sigpending:
>          {
> @@ -9102,8 +9077,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>               * the old_sigset_t is smaller in size.
>               */
>              if (arg2 > sizeof(target_sigset_t)) {
> -                ret = -TARGET_EINVAL;
> -                break;
> +                return -TARGET_EINVAL;
>              }
>  
>              ret = get_errno(sigpending(&set));
> @@ -9114,7 +9088,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user(p, arg1, sizeof(target_sigset_t));
>              }
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_sigsuspend
>      case TARGET_NR_sigsuspend:
>          {
> @@ -9134,15 +9108,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ts->in_sigsuspend = 1;
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_rt_sigsuspend:
>          {
>              TaskState *ts = cpu->opaque;
>  
>              if (arg2 != sizeof(target_sigset_t)) {
> -                ret = -TARGET_EINVAL;
> -                break;
> +                return -TARGET_EINVAL;
>              }
>              if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
>                  goto efault;
> @@ -9154,7 +9127,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ts->in_sigsuspend = 1;
>              }
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_rt_sigtimedwait:
>          {
>              sigset_t set;
> @@ -9162,8 +9135,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              siginfo_t uinfo;
>  
>              if (arg4 != sizeof(target_sigset_t)) {
> -                ret = -TARGET_EINVAL;
> -                break;
> +                return -TARGET_EINVAL;
>              }
>  
>              if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
> @@ -9191,7 +9163,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = host_to_target_signal(ret);
>              }
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_rt_sigqueueinfo:
>          {
>              siginfo_t uinfo;
> @@ -9204,7 +9176,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(p, arg3, 0);
>              ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_rt_tgsigqueueinfo:
>          {
>              siginfo_t uinfo;
> @@ -9217,29 +9189,25 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(p, arg4, 0);
>              ret = get_errno(sys_rt_tgsigqueueinfo(arg1, arg2, arg3, &uinfo));
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_sigreturn
>      case TARGET_NR_sigreturn:
>          if (block_signals()) {
> -            ret = -TARGET_ERESTARTSYS;
> -        } else {
> -            ret = do_sigreturn(cpu_env);
> +            return -TARGET_ERESTARTSYS;
>          }
> -        break;
> +        return do_sigreturn(cpu_env);
>  #endif
>      case TARGET_NR_rt_sigreturn:
>          if (block_signals()) {
> -            ret = -TARGET_ERESTARTSYS;
> -        } else {
> -            ret = do_rt_sigreturn(cpu_env);
> +            return -TARGET_ERESTARTSYS;
>          }
> -        break;
> +        return do_rt_sigreturn(cpu_env);
>      case TARGET_NR_sethostname:
>          if (!(p = lock_user_string(arg1)))
>              goto efault;
>          ret = get_errno(sethostname(p, arg2));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_setrlimit
>      case TARGET_NR_setrlimit:
>          {
> @@ -9251,9 +9219,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
>              rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
>              unlock_user_struct(target_rlim, arg2, 0);
> -            ret = get_errno(setrlimit(resource, &rlim));
> +            return get_errno(setrlimit(resource, &rlim));
>          }
> -        break;
>  #endif
>  #ifdef TARGET_NR_getrlimit
>      case TARGET_NR_getrlimit:
> @@ -9271,7 +9238,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user_struct(target_rlim, arg2, 1);
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_getrusage:
>          {
> @@ -9281,7 +9248,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = host_to_target_rusage(arg2, &rusage);
>              }
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_gettimeofday:
>          {
>              struct timeval tv;
> @@ -9291,7 +9258,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                      goto efault;
>              }
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_settimeofday:
>          {
>              struct timeval tv, *ptv = NULL;
> @@ -9311,9 +9278,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ptz = &tz;
>              }
>  
> -            ret = get_errno(settimeofday(ptv, ptz));
> +            return get_errno(settimeofday(ptv, ptz));
>          }
> -        break;
>  #if defined(TARGET_NR_select)
>      case TARGET_NR_select:
>  #if defined(TARGET_WANT_NI_OLD_SELECT)
> @@ -9326,7 +9292,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #else
>          ret = do_select(arg1, arg2, arg3, arg4, arg5);
>  #endif
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_pselect6
>      case TARGET_NR_pselect6:
> @@ -9430,7 +9396,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                      goto efault;
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_symlink
>      case TARGET_NR_symlink:
> @@ -9445,7 +9411,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(p2, arg2, 0);
>              unlock_user(p, arg1, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_symlinkat)
>      case TARGET_NR_symlinkat:
> @@ -9460,7 +9426,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(p2, arg3, 0);
>              unlock_user(p, arg1, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_oldlstat
>      case TARGET_NR_oldlstat:
> @@ -9496,7 +9462,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(p2, arg2, ret);
>              unlock_user(p, arg1, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_readlinkat)
>      case TARGET_NR_readlinkat:
> @@ -9517,7 +9483,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(p2, arg3, ret);
>              unlock_user(p, arg2, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_uselib
>      case TARGET_NR_uselib:
> @@ -9529,7 +9495,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(swapon(p, arg2));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_reboot:
>          if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
> @@ -9543,7 +9509,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          } else {
>             ret = get_errno(reboot(arg1, arg2, arg3, NULL));
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_readdir
>      case TARGET_NR_readdir:
>          goto unimplemented;
> @@ -9576,22 +9542,20 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                                      arg5,
>                                      arg6));
>  #endif
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_mmap2
>      case TARGET_NR_mmap2:
>  #ifndef MMAP_SHIFT
>  #define MMAP_SHIFT 12
>  #endif
> -        ret = get_errno(target_mmap(arg1, arg2, arg3,
> -                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
> -                                    arg5,
> -                                    arg6 << MMAP_SHIFT));
> -        break;
> +        ret = target_mmap(arg1, arg2, arg3,
> +                          target_to_host_bitmask(arg4, mmap_flags_tbl),
> +                          arg5, arg6 << MMAP_SHIFT);
> +        return get_errno(ret);
>  #endif
>      case TARGET_NR_munmap:
> -        ret = get_errno(target_munmap(arg1, arg2));
> -        break;
> +        return get_errno(target_munmap(arg1, arg2));
>      case TARGET_NR_mprotect:
>          {
>              TaskState *ts = cpu->opaque;
> @@ -9604,38 +9568,31 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  arg1 = ts->info->stack_limit;
>              }
>          }
> -        ret = get_errno(target_mprotect(arg1, arg2, arg3));
> -        break;
> +        return get_errno(target_mprotect(arg1, arg2, arg3));
>  #ifdef TARGET_NR_mremap
>      case TARGET_NR_mremap:
> -        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
> -        break;
> +        return get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
>  #endif
>          /* ??? msync/mlock/munlock are broken for softmmu.  */
>  #ifdef TARGET_NR_msync
>      case TARGET_NR_msync:
> -        ret = get_errno(msync(g2h(arg1), arg2, arg3));
> -        break;
> +        return get_errno(msync(g2h(arg1), arg2, arg3));
>  #endif
>  #ifdef TARGET_NR_mlock
>      case TARGET_NR_mlock:
> -        ret = get_errno(mlock(g2h(arg1), arg2));
> -        break;
> +        return get_errno(mlock(g2h(arg1), arg2));
>  #endif
>  #ifdef TARGET_NR_munlock
>      case TARGET_NR_munlock:
> -        ret = get_errno(munlock(g2h(arg1), arg2));
> -        break;
> +        return get_errno(munlock(g2h(arg1), arg2));
>  #endif
>  #ifdef TARGET_NR_mlockall
>      case TARGET_NR_mlockall:
> -        ret = get_errno(mlockall(target_to_host_mlockall_arg(arg1)));
> -        break;
> +        return get_errno(mlockall(target_to_host_mlockall_arg(arg1)));
>  #endif
>  #ifdef TARGET_NR_munlockall
>      case TARGET_NR_munlockall:
> -        ret = get_errno(munlockall());
> -        break;
> +        return get_errno(munlockall());
>  #endif
>  #ifdef TARGET_NR_truncate
>      case TARGET_NR_truncate:
> @@ -9643,23 +9600,21 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(truncate(p, arg2));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_ftruncate
>      case TARGET_NR_ftruncate:
> -        ret = get_errno(ftruncate(arg1, arg2));
> -        break;
> +        return get_errno(ftruncate(arg1, arg2));
>  #endif
>      case TARGET_NR_fchmod:
> -        ret = get_errno(fchmod(arg1, arg2));
> -        break;
> +        return get_errno(fchmod(arg1, arg2));
>  #if defined(TARGET_NR_fchmodat)
>      case TARGET_NR_fchmodat:
>          if (!(p = lock_user_string(arg2)))
>              goto efault;
>          ret = get_errno(fchmodat(arg1, p, arg3, 0));
>          unlock_user(p, arg2, 0);
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_getpriority:
>          /* Note that negative values are valid for getpriority, so we must
> @@ -9667,8 +9622,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          errno = 0;
>          ret = getpriority(arg1, arg2);
>          if (ret == -1 && errno != 0) {
> -            ret = -host_to_target_errno(errno);
> -            break;
> +            return -host_to_target_errno(errno);
>          }
>  #ifdef TARGET_ALPHA
>          /* Return value is the unbiased priority.  Signal no error.  */
> @@ -9677,10 +9631,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          /* Return value is a biased priority to avoid negative numbers.  */
>          ret = 20 - ret;
>  #endif
> -        break;
> +        return ret;
>      case TARGET_NR_setpriority:
> -        ret = get_errno(setpriority(arg1, arg2, arg3));
> -        break;
> +        return get_errno(setpriority(arg1, arg2, arg3));
>  #ifdef TARGET_NR_profil
>      case TARGET_NR_profil:
>          goto unimplemented;
> @@ -9716,7 +9669,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
>              unlock_user_struct(target_stfs, arg2, 1);
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_fstatfs
>      case TARGET_NR_fstatfs:
> @@ -9749,7 +9702,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
>              unlock_user_struct(target_stfs, arg3, 1);
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_fstatfs64:
>          ret = get_errno(fstatfs(arg1, &stfs));
>          goto convert_statfs64;
> @@ -9760,91 +9713,73 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #endif
>  #ifdef TARGET_NR_socketcall
>      case TARGET_NR_socketcall:
> -        ret = do_socketcall(arg1, arg2);
> -        break;
> +        return do_socketcall(arg1, arg2);
>  #endif
>  #ifdef TARGET_NR_accept
>      case TARGET_NR_accept:
> -        ret = do_accept4(arg1, arg2, arg3, 0);
> -        break;
> +        return do_accept4(arg1, arg2, arg3, 0);
>  #endif
>  #ifdef TARGET_NR_accept4
>      case TARGET_NR_accept4:
> -        ret = do_accept4(arg1, arg2, arg3, arg4);
> -        break;
> +        return do_accept4(arg1, arg2, arg3, arg4);
>  #endif
>  #ifdef TARGET_NR_bind
>      case TARGET_NR_bind:
> -        ret = do_bind(arg1, arg2, arg3);
> -        break;
> +        return do_bind(arg1, arg2, arg3);
>  #endif
>  #ifdef TARGET_NR_connect
>      case TARGET_NR_connect:
> -        ret = do_connect(arg1, arg2, arg3);
> -        break;
> +        return do_connect(arg1, arg2, arg3);
>  #endif
>  #ifdef TARGET_NR_getpeername
>      case TARGET_NR_getpeername:
> -        ret = do_getpeername(arg1, arg2, arg3);
> -        break;
> +        return do_getpeername(arg1, arg2, arg3);
>  #endif
>  #ifdef TARGET_NR_getsockname
>      case TARGET_NR_getsockname:
> -        ret = do_getsockname(arg1, arg2, arg3);
> -        break;
> +        return do_getsockname(arg1, arg2, arg3);
>  #endif
>  #ifdef TARGET_NR_getsockopt
>      case TARGET_NR_getsockopt:
> -        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
> -        break;
> +        return do_getsockopt(arg1, arg2, arg3, arg4, arg5);
>  #endif
>  #ifdef TARGET_NR_listen
>      case TARGET_NR_listen:
> -        ret = get_errno(listen(arg1, arg2));
> -        break;
> +        return get_errno(listen(arg1, arg2));
>  #endif
>  #ifdef TARGET_NR_recv
>      case TARGET_NR_recv:
> -        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
> -        break;
> +        return do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
>  #endif
>  #ifdef TARGET_NR_recvfrom
>      case TARGET_NR_recvfrom:
> -        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
> -        break;
> +        return do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
>  #endif
>  #ifdef TARGET_NR_recvmsg
>      case TARGET_NR_recvmsg:
> -        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
> -        break;
> +        return do_sendrecvmsg(arg1, arg2, arg3, 0);
>  #endif
>  #ifdef TARGET_NR_send
>      case TARGET_NR_send:
> -        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
> -        break;
> +        return do_sendto(arg1, arg2, arg3, arg4, 0, 0);
>  #endif
>  #ifdef TARGET_NR_sendmsg
>      case TARGET_NR_sendmsg:
> -        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
> -        break;
> +        return do_sendrecvmsg(arg1, arg2, arg3, 1);
>  #endif
>  #ifdef TARGET_NR_sendmmsg
>      case TARGET_NR_sendmmsg:
> -        ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1);
> -        break;
> +        return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1);
>      case TARGET_NR_recvmmsg:
> -        ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0);
> -        break;
> +        return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0);
>  #endif
>  #ifdef TARGET_NR_sendto
>      case TARGET_NR_sendto:
> -        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
> -        break;
> +        return do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
>  #endif
>  #ifdef TARGET_NR_shutdown
>      case TARGET_NR_shutdown:
> -        ret = get_errno(shutdown(arg1, arg2));
> -        break;
> +        return get_errno(shutdown(arg1, arg2));
>  #endif
>  #if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
>      case TARGET_NR_getrandom:
> @@ -9854,22 +9789,19 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          }
>          ret = get_errno(getrandom(p, arg2, arg3));
>          unlock_user(p, arg1, ret);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_socket
>      case TARGET_NR_socket:
> -        ret = do_socket(arg1, arg2, arg3);
> -        break;
> +        return do_socket(arg1, arg2, arg3);
>  #endif
>  #ifdef TARGET_NR_socketpair
>      case TARGET_NR_socketpair:
> -        ret = do_socketpair(arg1, arg2, arg3, arg4);
> -        break;
> +        return do_socketpair(arg1, arg2, arg3, arg4);
>  #endif
>  #ifdef TARGET_NR_setsockopt
>      case TARGET_NR_setsockopt:
> -        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
> -        break;
> +        return do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
>  #endif
>  #if defined(TARGET_NR_syslog)
>      case TARGET_NR_syslog:
> @@ -9885,10 +9817,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              case TARGET_SYSLOG_ACTION_CONSOLE_LEVEL: /* Set messages level */
>              case TARGET_SYSLOG_ACTION_SIZE_UNREAD:   /* Number of chars */
>              case TARGET_SYSLOG_ACTION_SIZE_BUFFER:   /* Size of the buffer */
> -                {
> -                    ret = get_errno(sys_syslog((int)arg1, NULL, (int)arg3));
> -                }
> -                break;
> +                return get_errno(sys_syslog((int)arg1, NULL, (int)arg3));
>              case TARGET_SYSLOG_ACTION_READ:          /* Read from log */
>              case TARGET_SYSLOG_ACTION_READ_CLEAR:    /* Read/clear msgs */
>              case TARGET_SYSLOG_ACTION_READ_ALL:      /* Read last messages */
> @@ -9897,9 +9826,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                      if (len < 0) {
>                          goto fail;
>                      }
> -                    ret = 0;
>                      if (len == 0) {
> -                        break;
> +                        return 0;
>                      }
>                      p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
>                      if (!p) {
> @@ -9909,10 +9837,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                      ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
>                      unlock_user(p, arg2, arg3);
>                  }
> -                break;
> +                return ret;
>              default:
> -                ret = -EINVAL;
> -                break;
> +                return -TARGET_EINVAL;
>              }
>          }
>          break;
> @@ -9939,7 +9866,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                      goto efault;
>              }
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_getitimer:
>          {
>              struct itimerval value;
> @@ -9953,7 +9880,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                      goto efault;
>              }
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_stat
>      case TARGET_NR_stat:
>          if (!(p = lock_user_string(arg1)))
> @@ -9999,7 +9926,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user_struct(target_st, arg2, 1);
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_olduname
>      case TARGET_NR_olduname:
> @@ -10010,17 +9937,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          goto unimplemented;
>  #endif
>      case TARGET_NR_vhangup:
> -        ret = get_errno(vhangup());
> -        break;
> +        return get_errno(vhangup());
>  #ifdef TARGET_NR_idle
>      case TARGET_NR_idle:
>          goto unimplemented;
>  #endif
>  #ifdef TARGET_NR_syscall
>      case TARGET_NR_syscall:
> -        ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
> -                         arg6, arg7, arg8, 0);
> -        break;
> +        return do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
> +                          arg6, arg7, arg8, 0);
>  #endif
>      case TARGET_NR_wait4:
>          {
> @@ -10048,14 +9973,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  }
>              }
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_swapoff
>      case TARGET_NR_swapoff:
>          if (!(p = lock_user_string(arg1)))
>              goto efault;
>          ret = get_errno(swapoff(p));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_sysinfo:
>          {
> @@ -10083,70 +10008,57 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user_struct(target_value, arg1, 1);
>              }
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_ipc
>      case TARGET_NR_ipc:
> -        ret = do_ipc(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
> -        break;
> +        return do_ipc(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
>  #endif
>  #ifdef TARGET_NR_semget
>      case TARGET_NR_semget:
> -        ret = get_errno(semget(arg1, arg2, arg3));
> -        break;
> +        return get_errno(semget(arg1, arg2, arg3));
>  #endif
>  #ifdef TARGET_NR_semop
>      case TARGET_NR_semop:
> -        ret = do_semop(arg1, arg2, arg3);
> -        break;
> +        return do_semop(arg1, arg2, arg3);
>  #endif
>  #ifdef TARGET_NR_semctl
>      case TARGET_NR_semctl:
> -        ret = do_semctl(arg1, arg2, arg3, arg4);
> -        break;
> +        return do_semctl(arg1, arg2, arg3, arg4);
>  #endif
>  #ifdef TARGET_NR_msgctl
>      case TARGET_NR_msgctl:
> -        ret = do_msgctl(arg1, arg2, arg3);
> -        break;
> +        return do_msgctl(arg1, arg2, arg3);
>  #endif
>  #ifdef TARGET_NR_msgget
>      case TARGET_NR_msgget:
> -        ret = get_errno(msgget(arg1, arg2));
> -        break;
> +        return get_errno(msgget(arg1, arg2));
>  #endif
>  #ifdef TARGET_NR_msgrcv
>      case TARGET_NR_msgrcv:
> -        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
> -        break;
> +        return do_msgrcv(arg1, arg2, arg3, arg4, arg5);
>  #endif
>  #ifdef TARGET_NR_msgsnd
>      case TARGET_NR_msgsnd:
> -        ret = do_msgsnd(arg1, arg2, arg3, arg4);
> -        break;
> +        return do_msgsnd(arg1, arg2, arg3, arg4);
>  #endif
>  #ifdef TARGET_NR_shmget
>      case TARGET_NR_shmget:
> -        ret = get_errno(shmget(arg1, arg2, arg3));
> -        break;
> +        return get_errno(shmget(arg1, arg2, arg3));
>  #endif
>  #ifdef TARGET_NR_shmctl
>      case TARGET_NR_shmctl:
> -        ret = do_shmctl(arg1, arg2, arg3);
> -        break;
> +        return do_shmctl(arg1, arg2, arg3);
>  #endif
>  #ifdef TARGET_NR_shmat
>      case TARGET_NR_shmat:
> -        ret = do_shmat(cpu_env, arg1, arg2, arg3);
> -        break;
> +        return do_shmat(cpu_env, arg1, arg2, arg3);
>  #endif
>  #ifdef TARGET_NR_shmdt
>      case TARGET_NR_shmdt:
> -        ret = do_shmdt(arg1);
> -        break;
> +        return do_shmdt(arg1);
>  #endif
>      case TARGET_NR_fsync:
> -        ret = get_errno(fsync(arg1));
> -        break;
> +        return get_errno(fsync(arg1));
>      case TARGET_NR_clone:
>          /* Linux manages to have three different orderings for its
>           * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
> @@ -10163,20 +10075,19 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #else
>          ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
>  #endif
> -        break;
> +        return ret;
>  #ifdef __NR_exit_group
>          /* new thread calls */
>      case TARGET_NR_exit_group:
>          preexit_cleanup(cpu_env, arg1);
> -        ret = get_errno(exit_group(arg1));
> -        break;
> +        return get_errno(exit_group(arg1));
>  #endif
>      case TARGET_NR_setdomainname:
>          if (!(p = lock_user_string(arg1)))
>              goto efault;
>          ret = get_errno(setdomainname(p, arg2));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>      case TARGET_NR_uname:
>          /* no need to transcode because we use the linux syscall */
>          {
> @@ -10198,17 +10109,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              }
>              unlock_user_struct(buf, arg1, 1);
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_I386
>      case TARGET_NR_modify_ldt:
> -        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
> -        break;
> +        return do_modify_ldt(cpu_env, arg1, arg2, arg3);
>  #if !defined(TARGET_X86_64)
>      case TARGET_NR_vm86old:
>          goto unimplemented;
>      case TARGET_NR_vm86:
> -        ret = do_vm86(cpu_env, arg1, arg2);
> -        break;
> +        return do_vm86(cpu_env, arg1, arg2);
>  #endif
>  #endif
>      case TARGET_NR_adjtimex:
> @@ -10225,7 +10134,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  }
>              }
>          }
> -        break;
> +        return ret;
>  #if defined(TARGET_NR_clock_adjtime) && defined(CONFIG_CLOCK_ADJTIME)
>      case TARGET_NR_clock_adjtime:
>          {
> @@ -10241,7 +10150,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  }
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_create_module
>      case TARGET_NR_create_module:
> @@ -10255,11 +10164,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>      case TARGET_NR_quotactl:
>          goto unimplemented;
>      case TARGET_NR_getpgid:
> -        ret = get_errno(getpgid(arg1));
> -        break;
> +        return get_errno(getpgid(arg1));
>      case TARGET_NR_fchdir:
> -        ret = get_errno(fchdir(arg1));
> -        break;
> +        return get_errno(fchdir(arg1));
>  #ifdef TARGET_NR_bdflush /* not on x86_64 */
>      case TARGET_NR_bdflush:
>          goto unimplemented;
> @@ -10269,8 +10176,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          goto unimplemented;
>  #endif
>      case TARGET_NR_personality:
> -        ret = get_errno(personality(arg1));
> -        break;
> +        return get_errno(personality(arg1));
>  #ifdef TARGET_NR_afs_syscall
>      case TARGET_NR_afs_syscall:
>          goto unimplemented;
> @@ -10293,7 +10199,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  goto efault;
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_getdents
>      case TARGET_NR_getdents:
> @@ -10425,7 +10331,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(dirp, arg2, ret);
>          }
>  #endif
> -        break;
> +        return ret;
>  #endif /* TARGET_NR_getdents */
>  #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
>      case TARGET_NR_getdents64:
> @@ -10453,12 +10359,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              }
>              unlock_user(dirp, arg2, ret);
>          }
> -        break;
> +        return ret;
>  #endif /* TARGET_NR_getdents64 */
>  #if defined(TARGET_NR__newselect)
>      case TARGET_NR__newselect:
> -        ret = do_select(arg1, arg2, arg3, arg4, arg5);
> -        break;
> +        return do_select(arg1, arg2, arg3, arg4, arg5);
>  #endif
>  #if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
>  # ifdef TARGET_NR_poll
> @@ -10477,8 +10382,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              target_pfd = NULL;
>              if (nfds) {
>                  if (nfds > (INT_MAX / sizeof(struct target_pollfd))) {
> -                    ret = -TARGET_EINVAL;
> -                    break;
> +                    return -TARGET_EINVAL;
>                  }
>  
>                  target_pfd = lock_user(VERIFY_WRITE, arg1,
> @@ -10514,8 +10418,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  if (arg4) {
>                      if (arg5 != sizeof(target_sigset_t)) {
>                          unlock_user(target_pfd, arg1, 0);
> -                        ret = -TARGET_EINVAL;
> -                        break;
> +                        return -TARGET_EINVAL;
>                      }
>  
>                      target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
> @@ -10569,13 +10472,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              }
>              unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
>          }
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_flock:
>          /* NOTE: the flock constant seems to be the same for every
>             Linux platform */
> -        ret = get_errno(safe_flock(arg1, arg2));
> -        break;
> +        return get_errno(safe_flock(arg1, arg2));
>      case TARGET_NR_readv:
>          {
>              struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
> @@ -10586,7 +10488,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = -host_to_target_errno(errno);
>              }
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_writev:
>          {
>              struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
> @@ -10597,7 +10499,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = -host_to_target_errno(errno);
>              }
>          }
> -        break;
> +        return ret;
>  #if defined(TARGET_NR_preadv)
>      case TARGET_NR_preadv:
>          {
> @@ -10612,7 +10514,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = -host_to_target_errno(errno);
>             }
>          }
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_pwritev)
>      case TARGET_NR_pwritev:
> @@ -10628,22 +10530,19 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = -host_to_target_errno(errno);
>             }
>          }
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_getsid:
> -        ret = get_errno(getsid(arg1));
> -        break;
> +        return get_errno(getsid(arg1));
>  #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
>      case TARGET_NR_fdatasync:
> -        ret = get_errno(fdatasync(arg1));
> -        break;
> +        return get_errno(fdatasync(arg1));
>  #endif
>  #ifdef TARGET_NR__sysctl
>      case TARGET_NR__sysctl:
>          /* We don't implement this, but ENOTDIR is always a safe
>             return value. */
> -        ret = -TARGET_ENOTDIR;
> -        break;
> +        return -TARGET_ENOTDIR;
>  #endif
>      case TARGET_NR_sched_getaffinity:
>          {
> @@ -10655,8 +10554,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>               * care of mismatches between target ulong and host ulong sizes.
>               */
>              if (arg2 & (sizeof(abi_ulong) - 1)) {
> -                ret = -TARGET_EINVAL;
> -                break;
> +                return -TARGET_EINVAL;
>              }
>              mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
>  
> @@ -10675,8 +10573,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                       */
>                      int numcpus = sysconf(_SC_NPROCESSORS_CONF);
>                      if (numcpus > arg2 * 8) {
> -                        ret = -TARGET_EINVAL;
> -                        break;
> +                        return -TARGET_EINVAL;
>                      }
>                      ret = arg2;
>                  }
> @@ -10686,7 +10583,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  }
>              }
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_sched_setaffinity:
>          {
>              unsigned int mask_size;
> @@ -10697,20 +10594,18 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>               * care of mismatches between target ulong and host ulong sizes.
>               */
>              if (arg2 & (sizeof(abi_ulong) - 1)) {
> -                ret = -TARGET_EINVAL;
> -                break;
> +                return -TARGET_EINVAL;
>              }
>              mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
>              mask = alloca(mask_size);
>  
>              ret = target_to_host_cpu_mask(mask, mask_size, arg3, arg2);
>              if (ret) {
> -                break;
> +                return ret;
>              }
>  
> -            ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
> +            return get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
>          }
> -        break;
>      case TARGET_NR_getcpu:
>          {
>              unsigned cpu, node;
> @@ -10727,7 +10622,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  goto efault;
>              }
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_sched_setparam:
>          {
>              struct sched_param *target_schp;
> @@ -10740,9 +10635,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  goto efault;
>              schp.sched_priority = tswap32(target_schp->sched_priority);
>              unlock_user_struct(target_schp, arg2, 0);
> -            ret = get_errno(sched_setparam(arg1, &schp));
> +            return get_errno(sched_setparam(arg1, &schp));
>          }
> -        break;
>      case TARGET_NR_sched_getparam:
>          {
>              struct sched_param *target_schp;
> @@ -10759,7 +10653,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user_struct(target_schp, arg2, 1);
>              }
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_sched_setscheduler:
>          {
>              struct sched_param *target_schp;
> @@ -10771,21 +10665,16 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  goto efault;
>              schp.sched_priority = tswap32(target_schp->sched_priority);
>              unlock_user_struct(target_schp, arg3, 0);
> -            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
> +            return get_errno(sched_setscheduler(arg1, arg2, &schp));
>          }
> -        break;
>      case TARGET_NR_sched_getscheduler:
> -        ret = get_errno(sched_getscheduler(arg1));
> -        break;
> +        return get_errno(sched_getscheduler(arg1));
>      case TARGET_NR_sched_yield:
> -        ret = get_errno(sched_yield());
> -        break;
> +        return get_errno(sched_yield());
>      case TARGET_NR_sched_get_priority_max:
> -        ret = get_errno(sched_get_priority_max(arg1));
> -        break;
> +        return get_errno(sched_get_priority_max(arg1));
>      case TARGET_NR_sched_get_priority_min:
> -        ret = get_errno(sched_get_priority_min(arg1));
> -        break;
> +        return get_errno(sched_get_priority_min(arg1));
>      case TARGET_NR_sched_rr_get_interval:
>          {
>              struct timespec ts;
> @@ -10794,7 +10683,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = host_to_target_timespec(arg2, &ts);
>              }
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_nanosleep:
>          {
>              struct timespec req, rem;
> @@ -10804,7 +10693,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  host_to_target_timespec(arg2, &rem);
>              }
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_query_module
>      case TARGET_NR_query_module:
>          goto unimplemented;
> @@ -10823,7 +10712,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  && put_user_ual(deathsig, arg2)) {
>                  goto efault;
>              }
> -            break;
> +            return ret;
>          }
>  #ifdef PR_GET_NAME
>          case PR_GET_NAME:
> @@ -10835,7 +10724,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              ret = get_errno(prctl(arg1, (unsigned long)name,
>                                    arg3, arg4, arg5));
>              unlock_user(name, arg2, 16);
> -            break;
> +            return ret;
>          }
>          case PR_SET_NAME:
>          {
> @@ -10846,7 +10735,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              ret = get_errno(prctl(arg1, (unsigned long)name,
>                                    arg3, arg4, arg5));
>              unlock_user(name, arg2, 0);
> -            break;
> +            return ret;
>          }
>  #endif
>  #ifdef TARGET_AARCH64
> @@ -10874,32 +10763,29 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  env->vfp.zcr_el[1] = vq - 1;
>                  ret = vq * 16;
>              }
> -            break;
> +            return ret;
>          case TARGET_PR_SVE_GET_VL:
>              ret = -TARGET_EINVAL;
>              if (arm_feature(cpu_env, ARM_FEATURE_SVE)) {
>                  CPUARMState *env = cpu_env;
>                  ret = ((env->vfp.zcr_el[1] & 0xf) + 1) * 16;
>              }
> -            break;
> +            return ret;
>  #endif /* AARCH64 */
>          case PR_GET_SECCOMP:
>          case PR_SET_SECCOMP:
>              /* Disable seccomp to prevent the target disabling syscalls we
>               * need. */
> -            ret = -TARGET_EINVAL;
> -            break;
> +            return -TARGET_EINVAL;
>          default:
>              /* Most prctl options have no pointer arguments */
> -            ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
> -            break;
> +            return get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
>          }
>          break;
>  #ifdef TARGET_NR_arch_prctl
>      case TARGET_NR_arch_prctl:
>  #if defined(TARGET_I386) && !defined(TARGET_ABI32)
> -        ret = do_arch_prctl(cpu_env, arg1, arg2);
> -        break;
> +        return do_arch_prctl(cpu_env, arg1, arg2);
>  #else
>          goto unimplemented;
>  #endif
> @@ -10914,7 +10800,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
>          unlock_user(p, arg2, ret);
> -        break;
> +        return ret;
>      case TARGET_NR_pwrite64:
>          if (regpairs_aligned(cpu_env, num)) {
>              arg4 = arg5;
> @@ -10924,14 +10810,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
>          unlock_user(p, arg2, 0);
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_getcwd:
>          if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
>              goto efault;
>          ret = get_errno(sys_getcwd1(p, arg2));
>          unlock_user(p, arg1, ret);
> -        break;
> +        return ret;
>      case TARGET_NR_capget:
>      case TARGET_NR_capset:
>      {
> @@ -11000,11 +10886,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user(target_data, arg2, 0);
>              }
>          }
> -        break;
> +        return ret;
>      }
>      case TARGET_NR_sigaltstack:
> -        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
> -        break;
> +        return do_sigaltstack(arg1, arg2,
> +                              get_sp_from_cpustate((CPUArchState *)cpu_env));
>  
>  #ifdef CONFIG_SENDFILE
>  #ifdef TARGET_NR_sendfile
> @@ -11015,7 +10901,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (arg3) {
>              ret = get_user_sal(off, arg3);
>              if (is_error(ret)) {
> -                break;
> +                return ret;
>              }
>              offp = &off;
>          }
> @@ -11026,7 +10912,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = ret2;
>              }
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  #ifdef TARGET_NR_sendfile64
> @@ -11037,7 +10923,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (arg3) {
>              ret = get_user_s64(off, arg3);
>              if (is_error(ret)) {
> -                break;
> +                return ret;
>              }
>              offp = &off;
>          }
> @@ -11048,7 +10934,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = ret2;
>              }
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  #else
> @@ -11069,10 +10955,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #endif
>  #ifdef TARGET_NR_vfork
>      case TARGET_NR_vfork:
> -        ret = get_errno(do_fork(cpu_env,
> -                        CLONE_VFORK | CLONE_VM | TARGET_SIGCHLD,
> -                        0, 0, 0, 0));
> -        break;
> +        return get_errno(do_fork(cpu_env,
> +                         CLONE_VFORK | CLONE_VM | TARGET_SIGCHLD,
> +                         0, 0, 0, 0));
>  #endif
>  #ifdef TARGET_NR_ugetrlimit
>      case TARGET_NR_ugetrlimit:
> @@ -11088,7 +10973,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  	    target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
>              unlock_user_struct(target_rlim, arg2, 1);
>  	}
> -	break;
> +        return ret;
>      }
>  #endif
>  #ifdef TARGET_NR_truncate64
> @@ -11097,12 +10982,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>  	ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
>          unlock_user(p, arg1, 0);
> -	break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_ftruncate64
>      case TARGET_NR_ftruncate64:
> -	ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
> -	break;
> +        return target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
>  #endif
>  #ifdef TARGET_NR_stat64
>      case TARGET_NR_stat64:
> @@ -11112,7 +10996,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          unlock_user(p, arg1, 0);
>          if (!is_error(ret))
>              ret = host_to_target_stat64(cpu_env, arg2, &st);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_lstat64
>      case TARGET_NR_lstat64:
> @@ -11122,14 +11006,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          unlock_user(p, arg1, 0);
>          if (!is_error(ret))
>              ret = host_to_target_stat64(cpu_env, arg2, &st);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_fstat64
>      case TARGET_NR_fstat64:
>          ret = get_errno(fstat(arg1, &st));
>          if (!is_error(ret))
>              ret = host_to_target_stat64(cpu_env, arg2, &st);
> -        break;
> +        return ret;
>  #endif
>  #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
>  #ifdef TARGET_NR_fstatat64
> @@ -11143,7 +11027,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          ret = get_errno(fstatat(arg1, path(p), &st, arg4));
>          if (!is_error(ret))
>              ret = host_to_target_stat64(cpu_env, arg3, &st);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_lchown
>      case TARGET_NR_lchown:
> @@ -11151,34 +11035,28 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_getuid
>      case TARGET_NR_getuid:
> -        ret = get_errno(high2lowuid(getuid()));
> -        break;
> +        return get_errno(high2lowuid(getuid()));
>  #endif
>  #ifdef TARGET_NR_getgid
>      case TARGET_NR_getgid:
> -        ret = get_errno(high2lowgid(getgid()));
> -        break;
> +        return get_errno(high2lowgid(getgid()));
>  #endif
>  #ifdef TARGET_NR_geteuid
>      case TARGET_NR_geteuid:
> -        ret = get_errno(high2lowuid(geteuid()));
> -        break;
> +        return get_errno(high2lowuid(geteuid()));
>  #endif
>  #ifdef TARGET_NR_getegid
>      case TARGET_NR_getegid:
> -        ret = get_errno(high2lowgid(getegid()));
> -        break;
> +        return get_errno(high2lowgid(getegid()));
>  #endif
>      case TARGET_NR_setreuid:
> -        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
> -        break;
> +        return get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
>      case TARGET_NR_setregid:
> -        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
> -        break;
> +        return get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
>      case TARGET_NR_getgroups:
>          {
>              int gidsetsize = arg1;
> @@ -11189,7 +11067,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              grouplist = alloca(gidsetsize * sizeof(gid_t));
>              ret = get_errno(getgroups(gidsetsize, grouplist));
>              if (gidsetsize == 0)
> -                break;
> +                return ret;
>              if (!is_error(ret)) {
>                  target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
>                  if (!target_grouplist)
> @@ -11199,7 +11077,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
>              }
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_setgroups:
>          {
>              int gidsetsize = arg1;
> @@ -11218,12 +11096,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  }
>                  unlock_user(target_grouplist, arg2, 0);
>              }
> -            ret = get_errno(setgroups(gidsetsize, grouplist));
> +            return get_errno(setgroups(gidsetsize, grouplist));
>          }
> -        break;
>      case TARGET_NR_fchown:
> -        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
> -        break;
> +        return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
>  #if defined(TARGET_NR_fchownat)
>      case TARGET_NR_fchownat:
>          if (!(p = lock_user_string(arg2))) 
> @@ -11231,14 +11107,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
>                                   low2highgid(arg4), arg5));
>          unlock_user(p, arg2, 0);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_setresuid
>      case TARGET_NR_setresuid:
> -        ret = get_errno(sys_setresuid(low2highuid(arg1),
> -                                      low2highuid(arg2),
> -                                      low2highuid(arg3)));
> -        break;
> +        return get_errno(sys_setresuid(low2highuid(arg1),
> +                                       low2highuid(arg2),
> +                                       low2highuid(arg3)));
>  #endif
>  #ifdef TARGET_NR_getresuid
>      case TARGET_NR_getresuid:
> @@ -11252,14 +11127,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                      goto efault;
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_getresgid
>      case TARGET_NR_setresgid:
> -        ret = get_errno(sys_setresgid(low2highgid(arg1),
> -                                      low2highgid(arg2),
> -                                      low2highgid(arg3)));
> -        break;
> +        return get_errno(sys_setresgid(low2highgid(arg1),
> +                                       low2highgid(arg2),
> +                                       low2highgid(arg3)));
>  #endif
>  #ifdef TARGET_NR_getresgid
>      case TARGET_NR_getresgid:
> @@ -11273,7 +11147,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                      goto efault;
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_chown
>      case TARGET_NR_chown:
> @@ -11281,20 +11155,16 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_setuid:
> -        ret = get_errno(sys_setuid(low2highuid(arg1)));
> -        break;
> +        return get_errno(sys_setuid(low2highuid(arg1)));
>      case TARGET_NR_setgid:
> -        ret = get_errno(sys_setgid(low2highgid(arg1)));
> -        break;
> +        return get_errno(sys_setgid(low2highgid(arg1)));
>      case TARGET_NR_setfsuid:
> -        ret = get_errno(setfsuid(arg1));
> -        break;
> +        return get_errno(setfsuid(arg1));
>      case TARGET_NR_setfsgid:
> -        ret = get_errno(setfsgid(arg1));
> -        break;
> +        return get_errno(setfsgid(arg1));
>  
>  #ifdef TARGET_NR_lchown32
>      case TARGET_NR_lchown32:
> @@ -11302,12 +11172,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(lchown(p, arg2, arg3));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_getuid32
>      case TARGET_NR_getuid32:
> -        ret = get_errno(getuid());
> -        break;
> +        return get_errno(getuid());
>  #endif
>  
>  #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
> @@ -11318,8 +11187,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              euid=geteuid();
>              ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
>           }
> -        ret = get_errno(getuid());
> -        break;
> +        return get_errno(getuid());
>  #endif
>  #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
>     /* Alpha specific */
> @@ -11329,8 +11197,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              egid=getegid();
>              ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
>           }
> -        ret = get_errno(getgid());
> -        break;
> +        return get_errno(getgid());
>  #endif
>  #if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
>      /* Alpha specific */
> @@ -11368,7 +11235,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>               -- Grabs a copy of the HWRPB; surely not used.
>            */
>          }
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
>      /* Alpha specific */
> @@ -11459,7 +11326,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>               -- Not implemented in linux kernel
>            */
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_osf_sigprocmask
>      /* Alpha specific.  */
> @@ -11491,33 +11358,28 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = mask;
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  
>  #ifdef TARGET_NR_getgid32
>      case TARGET_NR_getgid32:
> -        ret = get_errno(getgid());
> -        break;
> +        return get_errno(getgid());
>  #endif
>  #ifdef TARGET_NR_geteuid32
>      case TARGET_NR_geteuid32:
> -        ret = get_errno(geteuid());
> -        break;
> +        return get_errno(geteuid());
>  #endif
>  #ifdef TARGET_NR_getegid32
>      case TARGET_NR_getegid32:
> -        ret = get_errno(getegid());
> -        break;
> +        return get_errno(getegid());
>  #endif
>  #ifdef TARGET_NR_setreuid32
>      case TARGET_NR_setreuid32:
> -        ret = get_errno(setreuid(arg1, arg2));
> -        break;
> +        return get_errno(setreuid(arg1, arg2));
>  #endif
>  #ifdef TARGET_NR_setregid32
>      case TARGET_NR_setregid32:
> -        ret = get_errno(setregid(arg1, arg2));
> -        break;
> +        return get_errno(setregid(arg1, arg2));
>  #endif
>  #ifdef TARGET_NR_getgroups32
>      case TARGET_NR_getgroups32:
> @@ -11530,7 +11392,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              grouplist = alloca(gidsetsize * sizeof(gid_t));
>              ret = get_errno(getgroups(gidsetsize, grouplist));
>              if (gidsetsize == 0)
> -                break;
> +                return ret;
>              if (!is_error(ret)) {
>                  target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
>                  if (!target_grouplist) {
> @@ -11542,7 +11404,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user(target_grouplist, arg2, gidsetsize * 4);
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_setgroups32
>      case TARGET_NR_setgroups32:
> @@ -11561,19 +11423,16 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              for(i = 0;i < gidsetsize; i++)
>                  grouplist[i] = tswap32(target_grouplist[i]);
>              unlock_user(target_grouplist, arg2, 0);
> -            ret = get_errno(setgroups(gidsetsize, grouplist));
> +            return get_errno(setgroups(gidsetsize, grouplist));
>          }
> -        break;
>  #endif
>  #ifdef TARGET_NR_fchown32
>      case TARGET_NR_fchown32:
> -        ret = get_errno(fchown(arg1, arg2, arg3));
> -        break;
> +        return get_errno(fchown(arg1, arg2, arg3));
>  #endif
>  #ifdef TARGET_NR_setresuid32
>      case TARGET_NR_setresuid32:
> -        ret = get_errno(sys_setresuid(arg1, arg2, arg3));
> -        break;
> +        return get_errno(sys_setresuid(arg1, arg2, arg3));
>  #endif
>  #ifdef TARGET_NR_getresuid32
>      case TARGET_NR_getresuid32:
> @@ -11587,12 +11446,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                      goto efault;
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_setresgid32
>      case TARGET_NR_setresgid32:
> -        ret = get_errno(sys_setresgid(arg1, arg2, arg3));
> -        break;
> +        return get_errno(sys_setresgid(arg1, arg2, arg3));
>  #endif
>  #ifdef TARGET_NR_getresgid32
>      case TARGET_NR_getresgid32:
> @@ -11606,7 +11464,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                      goto efault;
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_chown32
>      case TARGET_NR_chown32:
> @@ -11614,27 +11472,23 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              goto efault;
>          ret = get_errno(chown(p, arg2, arg3));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_setuid32
>      case TARGET_NR_setuid32:
> -        ret = get_errno(sys_setuid(arg1));
> -        break;
> +        return get_errno(sys_setuid(arg1));
>  #endif
>  #ifdef TARGET_NR_setgid32
>      case TARGET_NR_setgid32:
> -        ret = get_errno(sys_setgid(arg1));
> -        break;
> +        return get_errno(sys_setgid(arg1));
>  #endif
>  #ifdef TARGET_NR_setfsuid32
>      case TARGET_NR_setfsuid32:
> -        ret = get_errno(setfsuid(arg1));
> -        break;
> +        return get_errno(setfsuid(arg1));
>  #endif
>  #ifdef TARGET_NR_setfsgid32
>      case TARGET_NR_setfsgid32:
> -        ret = get_errno(setfsgid(arg1));
> -        break;
> +        return get_errno(setfsgid(arg1));
>  #endif
>  
>      case TARGET_NR_pivot_root:
> @@ -11658,7 +11512,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              mincore_fail:
>              unlock_user(a, arg1, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_arm_fadvise64_64
>      case TARGET_NR_arm_fadvise64_64:
> @@ -11670,8 +11524,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>           */
>          ret = posix_fadvise(arg1, target_offset64(arg3, arg4),
>                              target_offset64(arg5, arg6), arg2);
> -        ret = -host_to_target_errno(ret);
> -        break;
> +        return -host_to_target_errno(ret);
>  #endif
>  
>  #if TARGET_ABI_BITS == 32
> @@ -11697,11 +11550,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              arg6 = arg7;
>          }
>  #endif
> -        ret = -host_to_target_errno(posix_fadvise(arg1,
> -                                                  target_offset64(arg2, arg3),
> -                                                  target_offset64(arg4, arg5),
> -                                                  arg6));
> -        break;
> +        ret = posix_fadvise(arg1, target_offset64(arg2, arg3),
> +                            target_offset64(arg4, arg5), arg6);
> +        return -host_to_target_errno(ret);
>  #endif
>  
>  #ifdef TARGET_NR_fadvise64
> @@ -11714,10 +11565,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              arg4 = arg5;
>              arg5 = arg6;
>          }
> -        ret = -host_to_target_errno(posix_fadvise(arg1,
> -                                                  target_offset64(arg2, arg3),
> -                                                  arg4, arg5));
> -        break;
> +        ret = posix_fadvise(arg1, target_offset64(arg2, arg3), arg4, arg5);
> +        return -host_to_target_errno(ret);
>  #endif
>  
>  #else /* not a 32-bit ABI */
> @@ -11737,8 +11586,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          default: break;
>          }
>  #endif
> -        ret = -host_to_target_errno(posix_fadvise(arg1, arg2, arg3, arg4));
> -        break;
> +        return -host_to_target_errno(posix_fadvise(arg1, arg2, arg3, arg4));
>  #endif
>  #endif /* end of 64-bit ABI fadvise handling */
>  
> @@ -11748,8 +11596,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>             turns private file-backed mappings into anonymous mappings.
>             This will break MADV_DONTNEED.
>             This is a hint, so ignoring and returning success is ok.  */
> -        ret = get_errno(0);
> -        break;
> +        return 0;
>  #endif
>  #if TARGET_ABI_BITS == 32
>      case TARGET_NR_fcntl64:
> @@ -11768,8 +11615,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  
>  	cmd = target_to_host_fcntl_cmd(arg2);
>          if (cmd == -TARGET_EINVAL) {
> -            ret = cmd;
> -            break;
> +            return cmd;
>          }
>  
>          switch(arg2) {
> @@ -11796,14 +11642,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              ret = do_fcntl(arg1, arg2, arg3);
>              break;
>          }
> -	break;
> +        return ret;
>      }
>  #endif
>  #ifdef TARGET_NR_cacheflush
>      case TARGET_NR_cacheflush:
>          /* self-modifying code is handled automatically, so nothing needed */
> -        ret = 0;
> -        break;
> +        return 0;
>  #endif
>  #ifdef TARGET_NR_security
>      case TARGET_NR_security:
> @@ -11811,12 +11656,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #endif
>  #ifdef TARGET_NR_getpagesize
>      case TARGET_NR_getpagesize:
> -        ret = TARGET_PAGE_SIZE;
> -        break;
> +        return TARGET_PAGE_SIZE;
>  #endif
>      case TARGET_NR_gettid:
> -        ret = get_errno(gettid());
> -        break;
> +        return get_errno(gettid());
>  #ifdef TARGET_NR_readahead
>      case TARGET_NR_readahead:
>  #if TARGET_ABI_BITS == 32
> @@ -11829,7 +11672,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #else
>          ret = get_errno(readahead(arg1, arg2, arg3));
>  #endif
> -        break;
> +        return ret;
>  #endif
>  #ifdef CONFIG_ATTR
>  #ifdef TARGET_NR_setxattr
> @@ -11840,8 +11683,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (arg2) {
>              b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
>              if (!b) {
> -                ret = -TARGET_EFAULT;
> -                break;
> +                return -TARGET_EFAULT;
>              }
>          }
>          p = lock_user_string(arg1);
> @@ -11856,7 +11698,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          }
>          unlock_user(p, arg1, 0);
>          unlock_user(b, arg2, arg3);
> -        break;
> +        return ret;
>      }
>      case TARGET_NR_flistxattr:
>      {
> @@ -11864,13 +11706,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (arg2) {
>              b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
>              if (!b) {
> -                ret = -TARGET_EFAULT;
> -                break;
> +                return -TARGET_EFAULT;
>              }
>          }
>          ret = get_errno(flistxattr(arg1, b, arg3));
>          unlock_user(b, arg2, arg3);
> -        break;
> +        return ret;
>      }
>      case TARGET_NR_setxattr:
>      case TARGET_NR_lsetxattr:
> @@ -11879,8 +11720,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              if (arg3) {
>                  v = lock_user(VERIFY_READ, arg3, arg4, 1);
>                  if (!v) {
> -                    ret = -TARGET_EFAULT;
> -                    break;
> +                    return -TARGET_EFAULT;
>                  }
>              }
>              p = lock_user_string(arg1);
> @@ -11898,15 +11738,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(n, arg2, 0);
>              unlock_user(v, arg3, 0);
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_fsetxattr:
>          {
>              void *n, *v = 0;
>              if (arg3) {
>                  v = lock_user(VERIFY_READ, arg3, arg4, 1);
>                  if (!v) {
> -                    ret = -TARGET_EFAULT;
> -                    break;
> +                    return -TARGET_EFAULT;
>                  }
>              }
>              n = lock_user_string(arg2);
> @@ -11918,7 +11757,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(n, arg2, 0);
>              unlock_user(v, arg3, 0);
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_getxattr:
>      case TARGET_NR_lgetxattr:
>          {
> @@ -11926,8 +11765,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              if (arg3) {
>                  v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
>                  if (!v) {
> -                    ret = -TARGET_EFAULT;
> -                    break;
> +                    return -TARGET_EFAULT;
>                  }
>              }
>              p = lock_user_string(arg1);
> @@ -11945,15 +11783,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(n, arg2, 0);
>              unlock_user(v, arg3, arg4);
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_fgetxattr:
>          {
>              void *n, *v = 0;
>              if (arg3) {
>                  v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
>                  if (!v) {
> -                    ret = -TARGET_EFAULT;
> -                    break;
> +                    return -TARGET_EFAULT;
>                  }
>              }
>              n = lock_user_string(arg2);
> @@ -11965,7 +11802,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(n, arg2, 0);
>              unlock_user(v, arg3, arg4);
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_removexattr:
>      case TARGET_NR_lremovexattr:
>          {
> @@ -11984,7 +11821,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(p, arg1, 0);
>              unlock_user(n, arg2, 0);
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_fremovexattr:
>          {
>              void *n;
> @@ -11996,15 +11833,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              }
>              unlock_user(n, arg2, 0);
>          }
> -        break;
> +        return ret;
>  #endif
>  #endif /* CONFIG_ATTR */
>  #ifdef TARGET_NR_set_thread_area
>      case TARGET_NR_set_thread_area:
>  #if defined(TARGET_MIPS)
>        ((CPUMIPSState *) cpu_env)->active_tc.CP0_UserLocal = arg1;
> -      ret = 0;
> -      break;
> +      return 0;
>  #elif defined(TARGET_CRIS)
>        if (arg1 & 0xff)
>            ret = -TARGET_EINVAL;
> @@ -12012,16 +11848,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>            ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
>            ret = 0;
>        }
> -      break;
> +      return ret;
>  #elif defined(TARGET_I386) && defined(TARGET_ABI32)
> -      ret = do_set_thread_area(cpu_env, arg1);
> -      break;
> +      return do_set_thread_area(cpu_env, arg1);
>  #elif defined(TARGET_M68K)
>        {
>            TaskState *ts = cpu->opaque;
>            ts->tp_value = arg1;
> -          ret = 0;
> -          break;
> +          return 0;
>        }
>  #else
>        goto unimplemented_nowarn;
> @@ -12030,13 +11864,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #ifdef TARGET_NR_get_thread_area
>      case TARGET_NR_get_thread_area:
>  #if defined(TARGET_I386) && defined(TARGET_ABI32)
> -        ret = do_get_thread_area(cpu_env, arg1);
> -        break;
> +        return do_get_thread_area(cpu_env, arg1);
>  #elif defined(TARGET_M68K)
>          {
>              TaskState *ts = cpu->opaque;
> -            ret = ts->tp_value;
> -            break;
> +            return ts->tp_value;
>          }
>  #else
>          goto unimplemented_nowarn;
> @@ -12056,7 +11888,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (!is_error(ret)) {
>              ret = get_errno(clock_settime(arg1, &ts));
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  #ifdef TARGET_NR_clock_gettime
> @@ -12067,7 +11899,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (!is_error(ret)) {
>              ret = host_to_target_timespec(arg2, &ts);
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  #ifdef TARGET_NR_clock_getres
> @@ -12078,7 +11910,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (!is_error(ret)) {
>              host_to_target_timespec(arg2, &ts);
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  #ifdef TARGET_NR_clock_nanosleep
> @@ -12098,24 +11930,21 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              ((CPUPPCState *)cpu_env)->crf[0] |= 1;
>          }
>  #endif
> -        break;
> +        return ret;
>      }
>  #endif
>  
>  #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
>      case TARGET_NR_set_tid_address:
> -        ret = get_errno(set_tid_address((int *)g2h(arg1)));
> -        break;
> +        return get_errno(set_tid_address((int *)g2h(arg1)));
>  #endif
>  
>      case TARGET_NR_tkill:
> -        ret = get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2)));
> -        break;
> +        return get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2)));
>  
>      case TARGET_NR_tgkill:
> -        ret = get_errno(safe_tgkill((int)arg1, (int)arg2,
> -                        target_to_host_signal(arg3)));
> -        break;
> +        return get_errno(safe_tgkill((int)arg1, (int)arg2,
> +                         target_to_host_signal(arg3)));
>  
>  #ifdef TARGET_NR_set_robust_list
>      case TARGET_NR_set_robust_list:
> @@ -12157,18 +11986,17 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user(p, arg2, 0);
>              }
>          }
> -	break;
> +        return ret;
>  #endif
>      case TARGET_NR_futex:
> -        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
> -        break;
> +        return do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
>  #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
>      case TARGET_NR_inotify_init:
>          ret = get_errno(sys_inotify_init());
>          if (ret >= 0) {
>              fd_trans_register(ret, &target_inotify_trans);
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef CONFIG_INOTIFY1
>  #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
> @@ -12178,7 +12006,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (ret >= 0) {
>              fd_trans_register(ret, &target_inotify_trans);
>          }
> -        break;
> +        return ret;
>  #endif
>  #endif
>  #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
> @@ -12186,12 +12014,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          p = lock_user_string(arg2);
>          ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
>          unlock_user(p, arg2, 0);
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
>      case TARGET_NR_inotify_rm_watch:
> -        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
> -        break;
> +        return get_errno(sys_inotify_rm_watch(arg1, arg2));
>  #endif
>  
>  #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
> @@ -12216,17 +12043,16 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              ret = get_errno(mq_open(p, host_flags, arg3, pposix_mq_attr));
>              unlock_user (p, arg1, 0);
>          }
> -        break;
> +        return ret;
>  
>      case TARGET_NR_mq_unlink:
>          p = lock_user_string(arg1 - 1);
>          if (!p) {
> -            ret = -TARGET_EFAULT;
> -            break;
> +            return -TARGET_EFAULT;
>          }
>          ret = get_errno(mq_unlink(p));
>          unlock_user (p, arg1, 0);
> -        break;
> +        return ret;
>  
>      case TARGET_NR_mq_timedsend:
>          {
> @@ -12242,7 +12068,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              }
>              unlock_user (p, arg2, arg3);
>          }
> -        break;
> +        return ret;
>  
>      case TARGET_NR_mq_timedreceive:
>          {
> @@ -12263,7 +12089,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              if (arg4 != 0)
>                  put_user_u32(prio, arg4);
>          }
> -        break;
> +        return ret;
>  
>      /* Not implemented for now... */
>  /*     case TARGET_NR_mq_notify: */
> @@ -12284,7 +12110,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  
>  #ifdef CONFIG_SPLICE
> @@ -12293,7 +12119,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          {
>              ret = get_errno(tee(arg1,arg2,arg3,arg4));
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_splice
>      case TARGET_NR_splice:
> @@ -12324,7 +12150,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  }
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #ifdef TARGET_NR_vmsplice
>  	case TARGET_NR_vmsplice:
> @@ -12337,7 +12163,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = -host_to_target_errno(errno);
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  #endif /* CONFIG_SPLICE */
>  #ifdef CONFIG_EVENTFD
> @@ -12347,7 +12173,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (ret >= 0) {
>              fd_trans_register(ret, &target_eventfd_trans);
>          }
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_eventfd2)
>      case TARGET_NR_eventfd2:
> @@ -12363,7 +12189,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          if (ret >= 0) {
>              fd_trans_register(ret, &target_eventfd_trans);
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  #endif /* CONFIG_EVENTFD  */
> @@ -12375,7 +12201,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #else
>          ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
>  #endif
> -        break;
> +        return ret;
>  #endif
>  #if defined(CONFIG_SYNC_FILE_RANGE)
>  #if defined(TARGET_NR_sync_file_range)
> @@ -12391,7 +12217,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #else
>          ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
>  #endif
> -        break;
> +        return ret;
>  #endif
>  #if defined(TARGET_NR_sync_file_range2)
>      case TARGET_NR_sync_file_range2:
> @@ -12402,29 +12228,25 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #else
>          ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
>  #endif
> -        break;
> +        return ret;
>  #endif
>  #endif
>  #if defined(TARGET_NR_signalfd4)
>      case TARGET_NR_signalfd4:
> -        ret = do_signalfd4(arg1, arg2, arg4);
> -        break;
> +        return do_signalfd4(arg1, arg2, arg4);
>  #endif
>  #if defined(TARGET_NR_signalfd)
>      case TARGET_NR_signalfd:
> -        ret = do_signalfd4(arg1, arg2, 0);
> -        break;
> +        return do_signalfd4(arg1, arg2, 0);
>  #endif
>  #if defined(CONFIG_EPOLL)
>  #if defined(TARGET_NR_epoll_create)
>      case TARGET_NR_epoll_create:
> -        ret = get_errno(epoll_create(arg1));
> -        break;
> +        return get_errno(epoll_create(arg1));
>  #endif
>  #if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
>      case TARGET_NR_epoll_create1:
> -        ret = get_errno(epoll_create1(arg1));
> -        break;
> +        return get_errno(epoll_create1(arg1));
>  #endif
>  #if defined(TARGET_NR_epoll_ctl)
>      case TARGET_NR_epoll_ctl:
> @@ -12445,8 +12267,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user_struct(target_ep, arg4, 0);
>              epp = &ep;
>          }
> -        ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
> -        break;
> +        return get_errno(epoll_ctl(arg1, arg2, arg3, epp));
>      }
>  #endif
>  
> @@ -12465,8 +12286,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          int timeout = arg4;
>  
>          if (maxevents <= 0 || maxevents > TARGET_EP_MAX_EVENTS) {
> -            ret = -TARGET_EINVAL;
> -            break;
> +            return -TARGET_EINVAL;
>          }
>  
>          target_ep = lock_user(VERIFY_WRITE, arg2,
> @@ -12478,8 +12298,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          ep = g_try_new(struct epoll_event, maxevents);
>          if (!ep) {
>              unlock_user(target_ep, arg2, 0);
> -            ret = -TARGET_ENOMEM;
> -            break;
> +            return -TARGET_ENOMEM;
>          }
>  
>          switch (num) {
> @@ -12533,7 +12352,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              unlock_user(target_ep, arg2, 0);
>          }
>          g_free(ep);
> -        break;
> +        return ret;
>      }
>  #endif
>  #endif
> @@ -12563,7 +12382,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              target_rold->rlim_max = tswap64(rold.rlim_max);
>              unlock_user_struct(target_rold, arg4, 1);
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  #ifdef TARGET_NR_gethostname
> @@ -12576,7 +12395,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          } else {
>              ret = -TARGET_EFAULT;
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  #ifdef TARGET_NR_atomic_cmpxchg_32
> @@ -12597,17 +12416,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          }
>          if (mem_value == arg2)
>              put_user_u32(arg1, arg6);
> -        ret = mem_value;
> -        break;
> +        return mem_value;
>      }
>  #endif
>  #ifdef TARGET_NR_atomic_barrier
>      case TARGET_NR_atomic_barrier:
> -    {
> -        /* Like the kernel implementation and the qemu arm barrier, no-op this? */
> -        ret = 0;
> -        break;
> -    }
> +        /* Like the kernel implementation and the
> +           qemu arm barrier, no-op this? */
> +        return 0;
>  #endif
>  
>  #ifdef TARGET_NR_timer_create
> @@ -12629,7 +12445,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  phost_sevp = &host_sevp;
>                  ret = target_to_host_sigevent(phost_sevp, arg2);
>                  if (ret != 0) {
> -                    break;
> +                    return ret;
>                  }
>              }
>  
> @@ -12642,7 +12458,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  }
>              }
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  
> @@ -12670,7 +12486,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  goto efault;
>              }
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  
> @@ -12693,7 +12509,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = -TARGET_EFAULT;
>              }
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  
> @@ -12710,7 +12526,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              ret = get_errno(timer_getoverrun(htimer));
>          }
>          fd_trans_unregister(ret);
> -        break;
> +        return ret;
>      }
>  #endif
>  
> @@ -12727,15 +12543,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              ret = get_errno(timer_delete(htimer));
>              g_posix_timers[timerid] = 0;
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  
>  #if defined(TARGET_NR_timerfd_create) && defined(CONFIG_TIMERFD)
>      case TARGET_NR_timerfd_create:
> -        ret = get_errno(timerfd_create(arg1,
> -                target_to_host_bitmask(arg2, fcntl_flags_tbl)));
> -        break;
> +        return get_errno(timerfd_create(arg1,
> +                          target_to_host_bitmask(arg2, fcntl_flags_tbl)));
>  #endif
>  
>  #if defined(TARGET_NR_timerfd_gettime) && defined(CONFIG_TIMERFD)
> @@ -12749,7 +12564,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  goto efault;
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  
>  #if defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD)
> @@ -12772,41 +12587,35 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  goto efault;
>              }
>          }
> -        break;
> +        return ret;
>  #endif
>  
>  #if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
>      case TARGET_NR_ioprio_get:
> -        ret = get_errno(ioprio_get(arg1, arg2));
> -        break;
> +        return get_errno(ioprio_get(arg1, arg2));
>  #endif
>  
>  #if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
>      case TARGET_NR_ioprio_set:
> -        ret = get_errno(ioprio_set(arg1, arg2, arg3));
> -        break;
> +        return get_errno(ioprio_set(arg1, arg2, arg3));
>  #endif
>  
>  #if defined(TARGET_NR_setns) && defined(CONFIG_SETNS)
>      case TARGET_NR_setns:
> -        ret = get_errno(setns(arg1, arg2));
> -        break;
> +        return get_errno(setns(arg1, arg2));
>  #endif
>  #if defined(TARGET_NR_unshare) && defined(CONFIG_SETNS)
>      case TARGET_NR_unshare:
> -        ret = get_errno(unshare(arg1));
> -        break;
> +        return get_errno(unshare(arg1));
>  #endif
>  #if defined(TARGET_NR_kcmp) && defined(__NR_kcmp)
>      case TARGET_NR_kcmp:
> -        ret = get_errno(kcmp(arg1, arg2, arg3, arg4, arg5));
> -        break;
> +        return get_errno(kcmp(arg1, arg2, arg3, arg4, arg5));
>  #endif
>  #ifdef TARGET_NR_swapcontext
>      case TARGET_NR_swapcontext:
>          /* PowerPC specific.  */
> -        ret = do_swapcontext(cpu_env, arg1, arg2, arg3);
> -        break;
> +        return do_swapcontext(cpu_env, arg1, arg2, arg3);
>  #endif
>  
>      default:
> @@ -12815,8 +12624,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
>      unimplemented_nowarn:
>  #endif
> -        ret = -TARGET_ENOSYS;
> -        break;
> +        return -TARGET_ENOSYS;
>      }
>  fail:
>      return ret;
> 

Lot of fun!

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v4 06/16] linux-user: Propagate goto unimplemented to default
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 06/16] linux-user: Propagate goto unimplemented to default Richard Henderson
  2018-08-21 16:35   ` Laurent Vivier
@ 2018-08-21 18:45   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 29+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-08-21 18:45 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: laurent

On 08/18/2018 04:01 PM, Richard Henderson wrote:
> There is no point in listing a syscall if you want the same effect as
> not listing it.  In one less trivial case, the goto was demonstrably
> not reachable.
> 
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  linux-user/syscall.c | 144 +------------------------------------------
>  1 file changed, 1 insertion(+), 143 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 812fb27fa1..ef3b9b623c 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8341,14 +8341,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          unlock_user(p, arg1, 0);
>          return ret;
>  #endif
> -#ifdef TARGET_NR_break
> -    case TARGET_NR_break:
> -        goto unimplemented;
> -#endif
> -#ifdef TARGET_NR_oldstat
> -    case TARGET_NR_oldstat:
> -        goto unimplemented;
> -#endif
>  #ifdef TARGET_NR_lseek
>      case TARGET_NR_lseek:
>          return get_errno(lseek(arg1, arg2, arg3));
> @@ -8435,16 +8427,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              return get_errno(stime(&host_time));
>          }
>  #endif
> -    case TARGET_NR_ptrace:
> -        goto unimplemented;
>  #ifdef TARGET_NR_alarm /* not on alpha */
>      case TARGET_NR_alarm:
>          return alarm(arg1);
>  #endif
> -#ifdef TARGET_NR_oldfstat
> -    case TARGET_NR_oldfstat:
> -        goto unimplemented;
> -#endif
>  #ifdef TARGET_NR_pause /* not on alpha */
>      case TARGET_NR_pause:
>          if (!block_signals()) {
> @@ -8515,14 +8501,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          }
>          return ret;
>  #endif
> -#ifdef TARGET_NR_stty
> -    case TARGET_NR_stty:
> -        goto unimplemented;
> -#endif
> -#ifdef TARGET_NR_gtty
> -    case TARGET_NR_gtty:
> -        goto unimplemented;
> -#endif
>  #ifdef TARGET_NR_access
>      case TARGET_NR_access:
>          if (!(p = lock_user_string(arg1))) {
> @@ -8544,10 +8522,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #ifdef TARGET_NR_nice /* not on alpha */
>      case TARGET_NR_nice:
>          return get_errno(nice(arg1));
> -#endif
> -#ifdef TARGET_NR_ftime
> -    case TARGET_NR_ftime:
> -        goto unimplemented;
>  #endif
>      case TARGET_NR_sync:
>          sync();
> @@ -8661,14 +8635,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = host_to_target_clock_t(ret);
>          }
>          return ret;
> -#ifdef TARGET_NR_prof
> -    case TARGET_NR_prof:
> -        goto unimplemented;
> -#endif
> -#ifdef TARGET_NR_signal
> -    case TARGET_NR_signal:
> -        goto unimplemented;
> -#endif
>      case TARGET_NR_acct:
>          if (arg1 == 0) {
>              ret = get_errno(acct(NULL));
> @@ -8687,31 +8653,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          ret = get_errno(umount2(p, arg2));
>          unlock_user(p, arg1, 0);
>          return ret;
> -#endif
> -#ifdef TARGET_NR_lock
> -    case TARGET_NR_lock:
> -        goto unimplemented;
>  #endif
>      case TARGET_NR_ioctl:
>          return do_ioctl(arg1, arg2, arg3);
>  #ifdef TARGET_NR_fcntl
>      case TARGET_NR_fcntl:
>          return do_fcntl(arg1, arg2, arg3);
> -#endif
> -#ifdef TARGET_NR_mpx
> -    case TARGET_NR_mpx:
> -        goto unimplemented;
>  #endif
>      case TARGET_NR_setpgid:
>          return get_errno(setpgid(arg1, arg2));
> -#ifdef TARGET_NR_ulimit
> -    case TARGET_NR_ulimit:
> -        goto unimplemented;
> -#endif
> -#ifdef TARGET_NR_oldolduname
> -    case TARGET_NR_oldolduname:
> -        goto unimplemented;
> -#endif
>      case TARGET_NR_umask:
>          return get_errno(umask(arg1));
>      case TARGET_NR_chroot:
> @@ -8720,10 +8670,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          ret = get_errno(chroot(p));
>          unlock_user(p, arg1, 0);
>          return ret;
> -#ifdef TARGET_NR_ustat
> -    case TARGET_NR_ustat:
> -        goto unimplemented;
> -#endif
>  #ifdef TARGET_NR_dup2
>      case TARGET_NR_dup2:
>          ret = get_errno(dup2(arg1, arg2));
> @@ -9432,10 +9378,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          }
>          return ret;
>  #endif
> -#ifdef TARGET_NR_oldlstat
> -    case TARGET_NR_oldlstat:
> -        goto unimplemented;
> -#endif
>  #ifdef TARGET_NR_readlink
>      case TARGET_NR_readlink:
>          {
> @@ -9489,10 +9431,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          }
>          return ret;
>  #endif
> -#ifdef TARGET_NR_uselib
> -    case TARGET_NR_uselib:
> -        goto unimplemented;
> -#endif
>  #ifdef TARGET_NR_swapon
>      case TARGET_NR_swapon:
>          if (!(p = lock_user_string(arg1)))
> @@ -9514,10 +9452,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>             ret = get_errno(reboot(arg1, arg2, arg3, NULL));
>          }
>          return ret;
> -#ifdef TARGET_NR_readdir
> -    case TARGET_NR_readdir:
> -        goto unimplemented;
> -#endif
>  #ifdef TARGET_NR_mmap
>      case TARGET_NR_mmap:
>  #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
> @@ -9638,10 +9572,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          return ret;
>      case TARGET_NR_setpriority:
>          return get_errno(setpriority(arg1, arg2, arg3));
> -#ifdef TARGET_NR_profil
> -    case TARGET_NR_profil:
> -        goto unimplemented;
> -#endif
>  #ifdef TARGET_NR_statfs
>      case TARGET_NR_statfs:
>          if (!(p = lock_user_string(arg1))) {
> @@ -9713,10 +9643,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          ret = get_errno(fstatfs(arg1, &stfs));
>          goto convert_statfs64;
>  #endif
> -#ifdef TARGET_NR_ioperm
> -    case TARGET_NR_ioperm:
> -        goto unimplemented;
> -#endif
>  #ifdef TARGET_NR_socketcall
>      case TARGET_NR_socketcall:
>          return do_socketcall(arg1, arg2);
> @@ -9935,21 +9861,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              }
>          }
>          return ret;
> -#endif
> -#ifdef TARGET_NR_olduname
> -    case TARGET_NR_olduname:
> -        goto unimplemented;
> -#endif
> -#ifdef TARGET_NR_iopl
> -    case TARGET_NR_iopl:
> -        goto unimplemented;
>  #endif
>      case TARGET_NR_vhangup:
>          return get_errno(vhangup());
> -#ifdef TARGET_NR_idle
> -    case TARGET_NR_idle:
> -        goto unimplemented;
> -#endif
>  #ifdef TARGET_NR_syscall
>      case TARGET_NR_syscall:
>          return do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
> @@ -10122,8 +10036,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>      case TARGET_NR_modify_ldt:
>          return do_modify_ldt(cpu_env, arg1, arg2, arg3);
>  #if !defined(TARGET_X86_64)
> -    case TARGET_NR_vm86old:
> -        goto unimplemented;
>      case TARGET_NR_vm86:
>          return do_vm86(cpu_env, arg1, arg2);
>  #endif
> @@ -10160,35 +10072,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          }
>          return ret;
>  #endif
> -#ifdef TARGET_NR_create_module
> -    case TARGET_NR_create_module:
> -#endif
> -    case TARGET_NR_init_module:
> -    case TARGET_NR_delete_module:
> -#ifdef TARGET_NR_get_kernel_syms
> -    case TARGET_NR_get_kernel_syms:
> -#endif
> -        goto unimplemented;
> -    case TARGET_NR_quotactl:
> -        goto unimplemented;
>      case TARGET_NR_getpgid:
>          return get_errno(getpgid(arg1));
>      case TARGET_NR_fchdir:
>          return get_errno(fchdir(arg1));
> -#ifdef TARGET_NR_bdflush /* not on x86_64 */
> -    case TARGET_NR_bdflush:
> -        goto unimplemented;
> -#endif
> -#ifdef TARGET_NR_sysfs
> -    case TARGET_NR_sysfs:
> -        goto unimplemented;
> -#endif
>      case TARGET_NR_personality:
>          return get_errno(personality(arg1));
> -#ifdef TARGET_NR_afs_syscall
> -    case TARGET_NR_afs_syscall:
> -        goto unimplemented;
> -#endif
>  #ifdef TARGET_NR__llseek /* Not on alpha */
>      case TARGET_NR__llseek:
>          {
> @@ -10702,14 +10591,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              }
>          }
>          return ret;
> -#ifdef TARGET_NR_query_module
> -    case TARGET_NR_query_module:
> -        goto unimplemented;
> -#endif
> -#ifdef TARGET_NR_nfsservctl
> -    case TARGET_NR_nfsservctl:
> -        goto unimplemented;
> -#endif
>      case TARGET_NR_prctl:
>          switch (arg1) {
>          case PR_GET_PDEATHSIG:
> @@ -10795,7 +10676,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #if defined(TARGET_I386) && !defined(TARGET_ABI32)
>          return do_arch_prctl(cpu_env, arg1, arg2);
>  #else
> -        goto unimplemented;
> +#error unreachable
>  #endif
>  #endif
>  #ifdef TARGET_NR_pread64
> @@ -10945,21 +10826,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          return ret;
>      }
>  #endif
> -#else
> -    case TARGET_NR_sendfile:
> -#ifdef TARGET_NR_sendfile64
> -    case TARGET_NR_sendfile64:
> -#endif
> -        goto unimplemented;
> -#endif
> -
> -#ifdef TARGET_NR_getpmsg
> -    case TARGET_NR_getpmsg:
> -        goto unimplemented;
> -#endif
> -#ifdef TARGET_NR_putpmsg
> -    case TARGET_NR_putpmsg:
> -        goto unimplemented;
>  #endif
>  #ifdef TARGET_NR_vfork
>      case TARGET_NR_vfork:
> @@ -11502,9 +11368,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>      case TARGET_NR_setfsgid32:
>          return get_errno(setfsgid(arg1));
>  #endif
> -
> -    case TARGET_NR_pivot_root:
> -        goto unimplemented;
>  #ifdef TARGET_NR_mincore
>      case TARGET_NR_mincore:
>          {
> @@ -11662,10 +11525,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          /* self-modifying code is handled automatically, so nothing needed */
>          return 0;
>  #endif
> -#ifdef TARGET_NR_security
> -    case TARGET_NR_security:
> -        goto unimplemented;
> -#endif
>  #ifdef TARGET_NR_getpagesize
>      case TARGET_NR_getpagesize:
>          return TARGET_PAGE_SIZE;
> @@ -12631,7 +12490,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #endif
>  
>      default:
> -    unimplemented:
>          qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
>          return -TARGET_ENOSYS;
>      }
> 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v4 10/16] linux-user: Split out some simple file syscalls
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 10/16] linux-user: Split out some simple file syscalls Richard Henderson
@ 2018-08-22  0:50   ` Laurent Vivier
  2018-08-22 22:58     ` Richard Henderson
  0 siblings, 1 reply; 29+ messages in thread
From: Laurent Vivier @ 2018-08-22  0:50 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 18/08/2018 à 21:01, Richard Henderson a écrit :
> This includes close, open, openat, read, readlink, readlinkat, write.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/strace.c           |  64 -----
>  linux-user/syscall-file.inc.c | 440 ++++++++++++++++++++++++++++++++++
>  linux-user/syscall.c          | 393 ++----------------------------
>  linux-user/strace.list        |  21 --
>  4 files changed, 463 insertions(+), 455 deletions(-)
>  create mode 100644 linux-user/syscall-file.inc.c
> 
...
> +#include "syscall-file.inc.c"
> +
>  static const SyscallDef *syscall_table(int num)
>  {
> -#define S(NAME)  case TARGET_NR_##NAME: return &def_##NAME;
> +#define S(NAME)  case TARGET_NR_##NAME: return &def_##NAME
>  
>      switch (num) {
> +    /*
> +     * Unconditional syscalls.
> +     */
> +    S(close);
> +    S(openat);
> +    S(read);
> +    S(write);
> +
> +    /*
> +     * Conditional syscalls.
> +     */
> +#ifdef TARGET_NR_open
> +    S(open);
> +#endif
> +#ifdef TARGET_NR_readlink
> +    S(readlink);
> +#endif
> +#ifdef TARGET_NR_readlinkat
> +    S(readlinkat);
> +#endif
>      }
>      return NULL;

I don't understand why you need/want to duplicate the list of syscalls here.

If I modify your patch as following, it works without duplicating the list:

diff --git a/linux-user/syscall-file.def.c b/linux-user/syscall-file.def.c
new file mode 100644
index 0000000000..78b1bd0467
--- /dev/null
+++ b/linux-user/syscall-file.def.c
@@ -0,0 +1,13 @@
+SYSCALL_DEF(close, ARG_DEC);
+#ifdef TARGET_NR_open
+SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
+#endif
+SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
+SYSCALL_DEF(read, ARG_DEC, ARG_PTR, ARG_DEC);
+#ifdef TARGET_NR_readlink
+SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC);
+#endif
+#ifdef TARGET_NR_readlinkat
+SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC);
+#endif
+SYSCALL_DEF(write, ARG_DEC, ARG_PTR, ARG_DEC);
diff --git a/linux-user/syscall-file.inc.c b/linux-user/syscall-file.inc.c
index aecc63682f..dda04200ed 100644
--- a/linux-user/syscall-file.inc.c
+++ b/linux-user/syscall-file.inc.c
@@ -307,21 +307,18 @@ SYSCALL_IMPL(close)
     fd_trans_unregister(arg1);
     return get_errno(close(arg1));
 }
-SYSCALL_DEF(close, ARG_DEC);

 #ifdef TARGET_NR_open
 SYSCALL_IMPL(open)
 {
     return do_openat(cpu_env, AT_FDCWD, arg1, arg2, arg3);
 }
-SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
 #endif

 SYSCALL_IMPL(openat)
 {
     return do_openat(cpu_env, arg1, arg2, arg3, arg4);
 }
-SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);

 SYSCALL_IMPL(read)
 {
@@ -346,7 +343,6 @@ SYSCALL_IMPL(read)
     unlock_user(p, arg2, ret);
     return ret;
 }
-SYSCALL_DEF(read, ARG_DEC, ARG_PTR, ARG_DEC);

 static abi_long do_readlink_proc_exe(char *buf, abi_ulong bufsiz)
 {
@@ -386,7 +382,6 @@ SYSCALL_IMPL(readlink)
     unlock_user(p, arg1, 0);
     return ret;
 }
-SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC);
 #endif

 #ifdef TARGET_NR_readlinkat
@@ -411,7 +406,6 @@ SYSCALL_IMPL(readlinkat)
     unlock_user(p, arg2, 0);
     return ret;
 }
-SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC);
 #endif

 SYSCALL_IMPL(write)
@@ -437,4 +431,4 @@ SYSCALL_IMPL(write)
     unlock_user(p, arg2, 0);
     return ret;
 }
-SYSCALL_DEF(write, ARG_DEC, ARG_PTR, ARG_DEC);
+#include "syscall-file.def.c"
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f757ae87b0..21e7700255 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -12117,33 +12117,15 @@ static abi_long do_syscall1(void *cpu_env, int
num, abi_long arg1,

 static const SyscallDef *syscall_table(int num)
 {
-#define S(NAME)  case TARGET_NR_##NAME: return &def_##NAME
+#undef SYSCALL_DEF
+#define SYSCALL_DEF(NAME, ...)  case TARGET_NR_##NAME: return &def_##NAME

     switch (num) {
-    /*
-     * Unconditional syscalls.
-     */
-    S(close);
-    S(openat);
-    S(read);
-    S(write);
-
-    /*
-     * Conditional syscalls.
-     */
-#ifdef TARGET_NR_open
-    S(open);
-#endif
-#ifdef TARGET_NR_readlink
-    S(readlink);
-#endif
-#ifdef TARGET_NR_readlinkat
-    S(readlinkat);
-#endif
+#include "syscall-file.def.c"
     }
     return NULL;

-#undef S
+#undef SYSCALL_DEF
 }

 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v4 08/16] configure: Use -Wunused-const-variable
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 08/16] configure: Use -Wunused-const-variable Richard Henderson
  2018-08-21 17:29   ` Laurent Vivier
  2018-08-21 17:34   ` Laurent Vivier
@ 2018-08-22  1:06   ` Laurent Vivier
  2 siblings, 0 replies; 29+ messages in thread
From: Laurent Vivier @ 2018-08-22  1:06 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 18/08/2018 à 21:01, Richard Henderson a écrit :
> For the linux-user syscall split, we have static const structs
> that must be matched up with a switch statement that uses them.
> By default, gcc will not warn for such a variable, but silently
> remove them.
> 
> For C++, such objects are sometimes declared for their constructor
> side effects.  Do not propagate this flag into QEM_CXXFLAGS.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  configure | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/configure b/configure
> index db97930314..86e6e18428 100755
> --- a/configure
> +++ b/configure
> @@ -105,7 +105,8 @@ update_cxxflags() {
>      for arg in $QEMU_CFLAGS; do
>          case $arg in
>              -Wstrict-prototypes|-Wmissing-prototypes|-Wnested-externs|\
> -            -Wold-style-declaration|-Wold-style-definition|-Wredundant-decls)
> +            -Wold-style-declaration|-Wold-style-definition|-Wredundant-decls|\
> +            -Wunused-const-variable)
>                  ;;
>              *)
>                  QEMU_CXXFLAGS=${QEMU_CXXFLAGS:+$QEMU_CXXFLAGS }$arg
> @@ -1780,6 +1781,7 @@ gcc_flags="-Wendif-labels -Wno-shift-negative-value $gcc_flags"
>  gcc_flags="-Wno-initializer-overrides -Wexpansion-to-defined $gcc_flags"
>  gcc_flags="-Wno-string-plus-int $gcc_flags"
>  gcc_flags="-Wno-error=address-of-packed-member $gcc_flags"
> +gcc_flags="-Wunused-const-variable $gcc_flags"
>  # Note that we do not add -Werror to gcc_flags here, because that would
>  # enable it for all configure tests. If a configure test failed due
>  # to -Werror this would just silently disable some features,
> 

This breaks build of hw/misc/macio/gpio.o:

In file included from include/hw/misc/macio/macio.h:33,
                 from hw/misc/macio/gpio.c:29:
hw/misc/macio/pmu.h:129:21: error: 'pmu_data_len' defined but not used
[-Werror=unused-const-variable=]
 static const int8_t pmu_data_len[256][2] = {
                     ^~~~~~~~~~~~
In file included from include/hw/misc/macio/macio.h:33,
                 from hw/misc/macio/macio.c:33:
include/hw/misc/macio/pmu.h:129:21: error: 'pmu_data_len' defined but
not used [-Werror=unused-const-variable=]
 static const int8_t pmu_data_len[256][2] = {
                     ^~~~~~~~~~~~

This can be fixed by moving pmu_data_len array from pmu.h to pmu.c as it
is the only user.

Thanks,
Laurent

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v4 11/16] linux-user: Split out preadv, pwritev, readv, writev
  2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 11/16] linux-user: Split out preadv, pwritev, readv, writev Richard Henderson
@ 2018-08-22 16:03   ` Laurent Vivier
  0 siblings, 0 replies; 29+ messages in thread
From: Laurent Vivier @ 2018-08-22 16:03 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 18/08/2018 à 21:01, Richard Henderson a écrit :
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/syscall-file.inc.c | 98 +++++++++++++++++++++++++++++++++++
>  linux-user/syscall.c          | 75 ++-------------------------
>  linux-user/strace.list        | 12 -----
>  3 files changed, 102 insertions(+), 83 deletions(-)
> 
...
> +SYSCALL_IMPL(pwritev)
> +{
> +    struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
> +    unsigned long lo, hi;
> +    abi_long ret;
> +
> +    if (vec == NULL) {
> +        ret = -host_to_target_errno(errno);

           return -host_to_target_errno(errno);

Found while testing with LTP

Thanks,
Laurent

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v4 10/16] linux-user: Split out some simple file syscalls
  2018-08-22  0:50   ` Laurent Vivier
@ 2018-08-22 22:58     ` Richard Henderson
  2018-08-23 15:48       ` Laurent Vivier
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Henderson @ 2018-08-22 22:58 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel

On 08/21/2018 05:50 PM, Laurent Vivier wrote:
> I don't understand why you need/want to duplicate the list of syscalls here.
> 
> If I modify your patch as following, it works without duplicating the list:
> 
> diff --git a/linux-user/syscall-file.def.c b/linux-user/syscall-file.def.c
> new file mode 100644
> index 0000000000..78b1bd0467
> --- /dev/null
> +++ b/linux-user/syscall-file.def.c
> @@ -0,0 +1,13 @@
> +SYSCALL_DEF(close, ARG_DEC);
> +#ifdef TARGET_NR_open
> +SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
> +#endif
> +SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
> +SYSCALL_DEF(read, ARG_DEC, ARG_PTR, ARG_DEC);
> +#ifdef TARGET_NR_readlink
> +SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC);
> +#endif
> +#ifdef TARGET_NR_readlinkat
> +SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC);
> +#endif
> +SYSCALL_DEF(write, ARG_DEC, ARG_PTR, ARG_DEC);

Sort-of interesting, but I do have other definitions of
syscall structures that do not use this macro.

Please look through e.g. patch 15 and suggest how I might
define mmap2 with your scheme.


r~

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH v4 10/16] linux-user: Split out some simple file syscalls
  2018-08-22 22:58     ` Richard Henderson
@ 2018-08-23 15:48       ` Laurent Vivier
  0 siblings, 0 replies; 29+ messages in thread
From: Laurent Vivier @ 2018-08-23 15:48 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 23/08/2018 à 00:58, Richard Henderson a écrit :
> On 08/21/2018 05:50 PM, Laurent Vivier wrote:
>> I don't understand why you need/want to duplicate the list of syscalls here.
>>
>> If I modify your patch as following, it works without duplicating the list:
>>
>> diff --git a/linux-user/syscall-file.def.c b/linux-user/syscall-file.def.c
>> new file mode 100644
>> index 0000000000..78b1bd0467
>> --- /dev/null
>> +++ b/linux-user/syscall-file.def.c
>> @@ -0,0 +1,13 @@
>> +SYSCALL_DEF(close, ARG_DEC);
>> +#ifdef TARGET_NR_open
>> +SYSCALL_DEF(open, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
>> +#endif
>> +SYSCALL_DEF(openat, ARG_ATDIRFD, ARG_STR, ARG_OPENFLAG, ARG_MODEFLAG);
>> +SYSCALL_DEF(read, ARG_DEC, ARG_PTR, ARG_DEC);
>> +#ifdef TARGET_NR_readlink
>> +SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC);
>> +#endif
>> +#ifdef TARGET_NR_readlinkat
>> +SYSCALL_DEF(readlinkat, ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_DEC);
>> +#endif
>> +SYSCALL_DEF(write, ARG_DEC, ARG_PTR, ARG_DEC);
> 
> Sort-of interesting, but I do have other definitions of
> syscall structures that do not use this macro.
> 
> Please look through e.g. patch 15 and suggest how I might
> define mmap2 with your scheme.

We can add a base macro in syscall.h:

#define SYSCALL_DECL(NAME, ARGS, IMPL, PRINT, PRINT_RET, ...) \
    static const SyscallDef def_##NAME = { \
        .name = #NAME, .args = ARGS, .impl = IMPL, .print = PRINT, \
        .print_ret = PRINT_RET, .arg_type = { __VA_ARGS__ } \
    }

and use it with the others:

#define SYSCALL_DEF(NAME, ...) \
    SYSCALL_DECL(NAME, NULL, impl_##NAME, NULL, NULL, __VA_ARGS__)

#define SYSCALL_DEF_ARGS(NAME, ...) \
    SYSCALL_DECL(NAME, args_##NAME, impl_##NAME, NULL, NULL, __VA_ARGS__)

Then in syscall.c:

static const SyscallDef *syscall_table(int num)
{
#undef SYSCALL_DECL
#define SYSCALL_DECL(NAME, ...)  \
    case TARGET_NR_##NAME: return &def_##NAME

    switch (num) {
#include "syscall-file.def.c"
#include "syscall-ipc.def.c"
#include "syscall-mem.def.c"
#include "syscall-proc.def.c"
    }
    return NULL;

#undef SYSCALL_DECL
}

and for mmap2 in syscall-mem.def.c:

SYSCALL_DEF(mlock, ARG_PTR, ARG_DEC);
SYSCALL_DEF(mlockall, ARG_HEX);
#ifdef TARGET_NR_mmap
SYSCALL_DECL(mmap, args_mmap, impl_mmap, NULL, print_syscall_ptr_ret,
             ARG_PTR, ARG_DEC, ARG_MMAPPROT, ARG_MMAPFLAG, ARG_DEC,
ARG_DEC);
#endif
#ifdef TARGET_NR_mmap2
SYSCALL_DECL(mmap2, args_mmap2, impl_mmap, NULL, print_syscall_ptr_ret,
             ARG_PTR, ARG_DEC, ARG_MMAPPROT, ARG_MMAPFLAG, ARG_DEC,
ARG_DEC64);
#endif
...

I pushed the modifications into:
git://github.com/vivier/qemu.git lu-split-4

Note that ipc_shmat can't use the macro (because the name of structure
is def_ipc_shmat, and not def_shmat), but we don't need it because it is
not exported to the syscall_table and only used locally by
SYSCALL_ARGS(ipc).

And doing like this, I think we don't need to add -Wunused-const-variable.

Thanks,
Laurent

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2018-08-23 15:49 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-18 19:01 [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Richard Henderson
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 01/16] linux-user: Remove DEBUG Richard Henderson
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 02/16] linux-user: Split out do_syscall1 Richard Henderson
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 03/16] linux-user: Relax single exit from "break" Richard Henderson
2018-08-21 18:45   ` Philippe Mathieu-Daudé
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 04/16] linux-user: Propagate goto efault to return Richard Henderson
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 05/16] linux-user: Propagate goto unimplemented_nowarn " Richard Henderson
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 06/16] linux-user: Propagate goto unimplemented to default Richard Henderson
2018-08-21 16:35   ` Laurent Vivier
2018-08-21 18:45   ` Philippe Mathieu-Daudé
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 07/16] linux-user: Propagate goto fail to return Richard Henderson
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 08/16] configure: Use -Wunused-const-variable Richard Henderson
2018-08-21 17:29   ` Laurent Vivier
2018-08-21 17:34   ` Laurent Vivier
2018-08-22  1:06   ` Laurent Vivier
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 09/16] linux-user: Setup split syscall infrastructure Richard Henderson
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 10/16] linux-user: Split out some simple file syscalls Richard Henderson
2018-08-22  0:50   ` Laurent Vivier
2018-08-22 22:58     ` Richard Henderson
2018-08-23 15:48       ` Laurent Vivier
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 11/16] linux-user: Split out preadv, pwritev, readv, writev Richard Henderson
2018-08-22 16:03   ` Laurent Vivier
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 12/16] linux-user: Split out pread64, pwrite64 Richard Henderson
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 13/16] linux-user: Split out name_to_handle_at, open_by_handle_at Richard Henderson
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 14/16] linux-user: Split out ipc syscalls Richard Henderson
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 15/16] linux-user: Split out memory syscalls Richard Henderson
2018-08-18 19:01 ` [Qemu-devel] [PATCH v4 16/16] linux-user: Split out some process syscalls Richard Henderson
2018-08-21 17:33 ` [Qemu-devel] [PATCH v4 00/16] linux-user: Split do_syscall Laurent Vivier
2018-08-21 17:36   ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.