All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall
@ 2018-06-12  0:51 Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 01/19] linux-user/alpha: Fix epoll syscalls Richard Henderson
                   ` (21 more replies)
  0 siblings, 22 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

Version 3 does not attempt the whole thing in one go,
and does attempt to incorporate strace into the reorg.

Thoughts?


r~


Richard Henderson (19):
  linux-user/alpha: Fix epoll syscalls
  linux-user/hppa: Fix typo in mknodat syscall
  linux-user/microblaze: Fix typo in accept4 syscall
  linux-user/sparc64: Add inotify_rm_watch and tee syscalls
  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
  linux-user: Setup split syscall infrastructure
  linux-user: Split out close, open, openat, read, write
  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/alpha/syscall_nr.h      |    6 +-
 linux-user/hppa/syscall_nr.h       |    2 +-
 linux-user/microblaze/syscall_nr.h |    2 +-
 linux-user/sparc64/syscall_nr.h    |    4 +-
 linux-user/syscall.h               |  389 +++
 linux-user/strace.c                |  600 ++---
 linux-user/syscall.c               | 4015 ++++------------------------
 linux-user/syscall_file.c          |  669 +++++
 linux-user/syscall_ipc.c           | 1095 ++++++++
 linux-user/syscall_mem.c           |  190 ++
 linux-user/syscall_proc.c          |  914 +++++++
 linux-user/Makefile.objs           |   17 +-
 linux-user/gen_syscall_list.py     |  160 ++
 linux-user/strace.list             |  264 --
 14 files changed, 4300 insertions(+), 4027 deletions(-)
 create mode 100644 linux-user/syscall.h
 create mode 100644 linux-user/syscall_file.c
 create mode 100644 linux-user/syscall_ipc.c
 create mode 100644 linux-user/syscall_mem.c
 create mode 100644 linux-user/syscall_proc.c
 create mode 100644 linux-user/gen_syscall_list.py

-- 
2.17.1

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

* [Qemu-devel] [PATCH v3 01/19] linux-user/alpha: Fix epoll syscalls
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 02/19] linux-user/hppa: Fix typo in mknodat syscall Richard Henderson
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

These were named incorrectly, going so far as to invade strace.list.

Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/alpha/syscall_nr.h | 6 +++---
 linux-user/strace.list        | 9 ---------
 2 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h
index 00e14bb6b3..6532376e3e 100644
--- a/linux-user/alpha/syscall_nr.h
+++ b/linux-user/alpha/syscall_nr.h
@@ -343,9 +343,9 @@
 #define TARGET_NR_io_cancel			402
 #define TARGET_NR_exit_group			405
 #define TARGET_NR_lookup_dcookie		406
-#define TARGET_NR_sys_epoll_create		407
-#define TARGET_NR_sys_epoll_ctl		408
-#define TARGET_NR_sys_epoll_wait		409
+#define TARGET_NR_epoll_create		407
+#define TARGET_NR_epoll_ctl		408
+#define TARGET_NR_epoll_wait		409
 #define TARGET_NR_remap_file_pages		410
 #define TARGET_NR_set_tid_address		411
 #define TARGET_NR_restart_syscall		412
diff --git a/linux-user/strace.list b/linux-user/strace.list
index a91e33f7e5..2bc5ba04d4 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1467,15 +1467,6 @@
 #ifdef TARGET_NR__sysctl
 { TARGET_NR__sysctl, "_sysctl" , NULL, NULL, NULL },
 #endif
-#ifdef TARGET_NR_sys_epoll_create
-{ TARGET_NR_sys_epoll_create, "sys_epoll_create" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_sys_epoll_ctl
-{ TARGET_NR_sys_epoll_ctl, "sys_epoll_ctl" , NULL, NULL, NULL },
-#endif
-#ifdef TARGET_NR_sys_epoll_wait
-{ TARGET_NR_sys_epoll_wait, "sys_epoll_wait" , NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_sysfs
 { TARGET_NR_sysfs, "sysfs" , NULL, NULL, NULL },
 #endif
-- 
2.17.1

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

* [Qemu-devel] [PATCH v3 02/19] linux-user/hppa: Fix typo in mknodat syscall
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 01/19] linux-user/alpha: Fix epoll syscalls Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 03/19] linux-user/microblaze: Fix typo in accept4 syscall Richard Henderson
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

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/hppa/syscall_nr.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/hppa/syscall_nr.h b/linux-user/hppa/syscall_nr.h
index 55bdf71d50..9c1d0a195d 100644
--- a/linux-user/hppa/syscall_nr.h
+++ b/linux-user/hppa/syscall_nr.h
@@ -279,7 +279,7 @@
 #define TARGET_NR_ppoll             274
 #define TARGET_NR_openat            275
 #define TARGET_NR_mkdirat           276
-#define TARGET_NR_mknotat           277
+#define TARGET_NR_mknodat           277
 #define TARGET_NR_fchownat          278
 #define TARGET_NR_futimesat         279
 #define TARGET_NR_fstatat64         280
-- 
2.17.1

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

* [Qemu-devel] [PATCH v3 03/19] linux-user/microblaze: Fix typo in accept4 syscall
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 01/19] linux-user/alpha: Fix epoll syscalls Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 02/19] linux-user/hppa: Fix typo in mknodat syscall Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 04/19] linux-user/sparc64: Add inotify_rm_watch and tee syscalls Richard Henderson
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

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/microblaze/syscall_nr.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/microblaze/syscall_nr.h b/linux-user/microblaze/syscall_nr.h
index 0704449bae..761208e9e6 100644
--- a/linux-user/microblaze/syscall_nr.h
+++ b/linux-user/microblaze/syscall_nr.h
@@ -363,7 +363,7 @@
 #define TARGET_NR_shutdown		359 /* new */
 #define TARGET_NR_sendmsg		360 /* new */
 #define TARGET_NR_recvmsg		361 /* new */
-#define TARGET_NR_accept04		362 /* new */
+#define TARGET_NR_accept4		362 /* new */
 #define TARGET_NR_preadv                363 /* new */
 #define TARGET_NR_pwritev               364 /* new */
 #define TARGET_NR_rt_tgsigqueueinfo     365 /* new */
-- 
2.17.1

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

* [Qemu-devel] [PATCH v3 04/19] linux-user/sparc64: Add inotify_rm_watch and tee syscalls
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (2 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 03/19] linux-user/microblaze: Fix typo in accept4 syscall Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 05/19] linux-user: Remove DEBUG Richard Henderson
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/sparc64/syscall_nr.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/linux-user/sparc64/syscall_nr.h b/linux-user/sparc64/syscall_nr.h
index 9391645598..0b91b896da 100644
--- a/linux-user/sparc64/syscall_nr.h
+++ b/linux-user/sparc64/syscall_nr.h
@@ -154,7 +154,7 @@
 #define TARGET_NR_poll               153 /* Common                                      */
 #define TARGET_NR_getdents64		154 /* Linux specific				   */
 #define TARGET_NR_fcntl64            155 /* Linux sparc32 Specific                      */
-/* #define TARGET_NR_getdirentries   156    SunOS Specific                              */
+#define TARGET_NR_inotify_rm_watch   156 /* Linux specific                              */
 #define TARGET_NR_statfs             157 /* Common                                      */
 #define TARGET_NR_fstatfs            158 /* Common                                      */
 #define TARGET_NR_umount             159 /* Common                                      */
@@ -278,7 +278,7 @@
 #define TARGET_NR_mq_notify		277
 #define TARGET_NR_mq_getsetattr	278
 #define TARGET_NR_waitid		279
-/*#define TARGET_NR_sys_setaltroot	280 available (was setaltroot) */
+#define TARGET_NR_tee                   280
 #define TARGET_NR_add_key		281
 #define TARGET_NR_request_key	282
 #define TARGET_NR_keyctl		283
-- 
2.17.1

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

* [Qemu-devel] [PATCH v3 05/19] linux-user: Remove DEBUG
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (3 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 04/19] linux-user/sparc64: Add inotify_rm_watch and tee syscalls Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 06/19] linux-user: Split out do_syscall1 Richard Henderson
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

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 7b9ac3b408..c212149245 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.
  */
@@ -5777,9 +5776,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) {
@@ -7980,9 +7976,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);
@@ -12772,9 +12765,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] 39+ messages in thread

* [Qemu-devel] [PATCH v3 06/19] linux-user: Split out do_syscall1
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (4 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 05/19] linux-user: Remove DEBUG Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12 16:11   ` Philippe Mathieu-Daudé
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 07/19] linux-user: Relax single exit from "break" Richard Henderson
                   ` (15 subsequent siblings)
  21 siblings, 1 reply; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

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: 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 c212149245..ec3bc1cbe5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7947,13 +7947,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;
@@ -7961,25 +7963,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     struct statfs stfs;
     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).
@@ -12765,11 +12748,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] 39+ messages in thread

* [Qemu-devel] [PATCH v3 07/19] linux-user: Relax single exit from "break"
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (5 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 06/19] linux-user: Split out do_syscall1 Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12 16:23   ` Philippe Mathieu-Daudé
  2018-08-11 21:50   ` Laurent Vivier
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 08/19] linux-user: Propagate goto efault to return Richard Henderson
                   ` (14 subsequent siblings)
  21 siblings, 2 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

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 | 970 +++++++++++++++++--------------------------
 1 file changed, 390 insertions(+), 580 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ec3bc1cbe5..efe882612b 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7971,8 +7971,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();
@@ -8004,12 +8003,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
         gdb_exit(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));
@@ -8019,7 +8017,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;
@@ -8035,7 +8033,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)))
@@ -8045,7 +8044,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)))
@@ -8055,29 +8054,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:
@@ -8088,7 +8085,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:
@@ -8103,7 +8100,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:
@@ -8112,7 +8109,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:
@@ -8127,7 +8124,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:
@@ -8144,7 +8141,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:
@@ -8152,7 +8149,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:
@@ -8160,7 +8157,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:
         {
@@ -8258,13 +8255,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:
         {
@@ -8275,7 +8272,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:
@@ -8283,7 +8280,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:
@@ -8291,7 +8288,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:
@@ -8299,7 +8296,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:
@@ -8310,19 +8307,16 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         goto unimplemented;
 #endif
     case TARGET_NR_lseek:
-        ret = get_errno(lseek(arg1, arg2, arg3));
-        break;
+        return get_errno(lseek(arg1, arg2, arg3));
 #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:
         {
@@ -8378,14 +8372,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:
@@ -8393,16 +8387,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:
@@ -8413,8 +8405,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:
@@ -8436,7 +8427,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:
@@ -8456,7 +8447,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:
@@ -8476,7 +8467,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:
@@ -8492,7 +8483,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:
@@ -8500,12 +8491,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:
@@ -8513,16 +8503,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:
         {
@@ -8536,7 +8523,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:
@@ -8551,7 +8538,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:
@@ -8567,7 +8554,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:
@@ -8575,7 +8562,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:
@@ -8583,7 +8570,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:
@@ -8591,24 +8578,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:
         {
@@ -8627,7 +8612,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;
@@ -8645,34 +8630,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;
@@ -8682,14 +8664,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;
@@ -8700,7 +8681,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:
@@ -8715,22 +8696,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:
         {
@@ -8814,7 +8792,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
 #endif
         }
-        break;
+        return ret;
 #endif
     case TARGET_NR_rt_sigaction:
         {
@@ -8831,8 +8809,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))
@@ -8864,8 +8841,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)) {
@@ -8892,7 +8868,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:
         {
@@ -8904,7 +8880,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:
@@ -8918,7 +8894,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:
@@ -8988,7 +8964,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
 #endif
         }
-        break;
+        return ret;
 #endif
     case TARGET_NR_rt_sigprocmask:
         {
@@ -8996,8 +8972,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) {
@@ -9032,7 +9007,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:
         {
@@ -9045,7 +9020,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:
         {
@@ -9057,8 +9032,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));
@@ -9069,7 +9043,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:
         {
@@ -9089,15 +9063,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;
@@ -9109,7 +9082,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;
@@ -9117,8 +9090,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)))
@@ -9146,7 +9118,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;
@@ -9159,7 +9131,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;
@@ -9172,7 +9144,7 @@ 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()) {
@@ -9180,21 +9152,20 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         } else {
             ret = do_sigreturn(cpu_env);
         }
-        break;
+        return ret;
 #endif
     case TARGET_NR_rt_sigreturn:
         if (block_signals()) {
-            ret = -TARGET_ERESTARTSYS;
+            return -TARGET_ERESTARTSYS;
         } else {
-            ret = do_rt_sigreturn(cpu_env);
+            return do_rt_sigreturn(cpu_env);
         }
-        break;
     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;
     case TARGET_NR_setrlimit:
         {
             int resource = target_to_host_resource(arg1);
@@ -9205,9 +9176,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;
     case TARGET_NR_getrlimit:
         {
             int resource = target_to_host_resource(arg1);
@@ -9223,7 +9193,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user_struct(target_rlim, arg2, 1);
             }
         }
-        break;
+        return ret;
     case TARGET_NR_getrusage:
         {
             struct rusage rusage;
@@ -9232,7 +9202,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;
@@ -9242,7 +9212,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;
@@ -9262,9 +9232,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)
@@ -9277,7 +9246,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:
@@ -9381,7 +9350,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:
@@ -9396,7 +9365,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:
@@ -9411,7 +9380,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:
@@ -9447,7 +9416,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:
@@ -9468,7 +9437,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:
@@ -9480,7 +9449,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) {
@@ -9494,7 +9463,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;
@@ -9527,22 +9496,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;
@@ -9555,58 +9522,49 @@ 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
     case TARGET_NR_truncate:
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(truncate(p, arg2));
         unlock_user(p, arg1, 0);
-        break;
+        return ret;
     case TARGET_NR_ftruncate:
-        ret = get_errno(ftruncate(arg1, arg2));
-        break;
+        return get_errno(ftruncate(arg1, arg2));
     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
@@ -9614,8 +9572,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.  */
@@ -9624,10 +9581,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;
@@ -9662,7 +9618,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;
     case TARGET_NR_fstatfs:
         ret = get_errno(fstatfs(arg1, &stfs));
         goto convert_statfs;
@@ -9692,7 +9648,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;
@@ -9703,91 +9659,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:
@@ -9797,22 +9735,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:
@@ -9828,10 +9763,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 */
@@ -9840,9 +9772,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) {
@@ -9852,10 +9783,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;
@@ -9882,7 +9812,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;
@@ -9896,7 +9826,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)))
@@ -9941,7 +9871,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 unlock_user_struct(target_st, arg2, 1);
             }
         }
-        break;
+        return ret;
 #ifdef TARGET_NR_olduname
     case TARGET_NR_olduname:
         goto unimplemented;
@@ -9951,17 +9881,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:
         {
@@ -9989,14 +9917,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:
         {
@@ -10024,70 +9952,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
@@ -10104,7 +10019,7 @@ 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:
@@ -10112,15 +10027,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         _mcleanup();
 #endif
         gdb_exit(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 */
         {
@@ -10142,17 +10056,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:
@@ -10169,7 +10081,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:
         {
@@ -10185,7 +10097,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:
@@ -10199,11 +10111,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;
@@ -10213,8 +10123,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;
@@ -10237,7 +10146,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:
@@ -10369,7 +10278,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:
@@ -10397,12 +10306,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
@@ -10421,8 +10329,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,
@@ -10458,8 +10365,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);
@@ -10481,7 +10387,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 if (arg4) {
                     unlock_user(target_set, arg4, 0);
                 }
-                break;
+                return ret;
             }
 # endif
 # ifdef TARGET_NR_poll
@@ -10498,8 +10404,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                     /* -ve poll() timeout means "infinite" */
                     pts = NULL;
                 }
-                ret = get_errno(safe_ppoll(pfd, nfds, pts, NULL, 0));
-                break;
+                return get_errno(safe_ppoll(pfd, nfds, pts, NULL, 0));
             }
 # endif
             default:
@@ -10513,13 +10418,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);
@@ -10530,7 +10434,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);
@@ -10541,7 +10445,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:
         {
@@ -10556,7 +10460,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:
@@ -10572,22 +10476,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:
         {
@@ -10599,8 +10500,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);
 
@@ -10619,8 +10519,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;
                 }
@@ -10630,7 +10529,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;
@@ -10641,20 +10540,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;
@@ -10671,7 +10568,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;
@@ -10684,9 +10581,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;
@@ -10703,7 +10599,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;
@@ -10715,21 +10611,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;
@@ -10738,7 +10629,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;
@@ -10748,7 +10639,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;
@@ -10767,7 +10658,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:
@@ -10779,7 +10670,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:
         {
@@ -10790,7 +10681,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
@@ -10811,32 +10702,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
@@ -10851,7 +10739,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;
@@ -10861,14 +10749,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:
     {
@@ -10937,11 +10825,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
     case TARGET_NR_sendfile:
@@ -10951,7 +10839,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;
         }
@@ -10962,7 +10850,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = ret2;
             }
         }
-        break;
+        return ret;
     }
 #ifdef TARGET_NR_sendfile64
     case TARGET_NR_sendfile64:
@@ -10972,7 +10860,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;
         }
@@ -10983,7 +10871,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = ret2;
             }
         }
-        break;
+        return ret;
     }
 #endif
 #else
@@ -11004,10 +10892,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:
@@ -11023,7 +10910,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
@@ -11032,12 +10919,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:
@@ -11047,7 +10933,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:
@@ -11057,14 +10943,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
@@ -11078,7 +10964,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:
@@ -11086,34 +10972,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;
@@ -11124,7 +11004,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)
@@ -11134,7 +11014,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;
@@ -11153,12 +11033,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))) 
@@ -11166,14 +11044,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:
@@ -11187,14 +11064,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:
@@ -11208,7 +11084,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:
@@ -11216,20 +11092,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:
@@ -11237,12 +11109,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)
@@ -11253,8 +11124,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 */
@@ -11264,8 +11134,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 */
@@ -11303,7 +11172,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 */
@@ -11394,7 +11263,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.  */
@@ -11426,33 +11295,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:
@@ -11465,7 +11329,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) {
@@ -11477,7 +11341,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:
@@ -11496,19 +11360,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:
@@ -11522,12 +11383,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:
@@ -11541,7 +11401,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:
@@ -11549,27 +11409,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:
@@ -11593,7 +11449,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:
@@ -11605,8 +11461,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
@@ -11632,11 +11487,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
@@ -11649,10 +11502,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 */
@@ -11672,8 +11523,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 */
 
@@ -11683,8 +11533,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:
@@ -11703,8 +11552,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) {
@@ -11731,14 +11579,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:
@@ -11746,12 +11593,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
@@ -11764,7 +11609,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
@@ -11775,8 +11620,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);
@@ -11791,7 +11635,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:
     {
@@ -11799,13 +11643,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:
@@ -11814,8 +11657,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);
@@ -11833,15 +11675,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);
@@ -11853,7 +11694,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:
         {
@@ -11861,8 +11702,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);
@@ -11880,15 +11720,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);
@@ -11900,7 +11739,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:
         {
@@ -11919,7 +11758,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;
@@ -11931,15 +11770,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;
@@ -11947,16 +11785,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;
@@ -11965,13 +11801,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;
@@ -11991,7 +11825,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
@@ -12002,7 +11836,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
@@ -12013,7 +11847,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
@@ -12033,24 +11867,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:
@@ -12092,18 +11923,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)
@@ -12113,7 +11943,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)
@@ -12121,12 +11951,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)
@@ -12151,17 +11980,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:
         {
@@ -12177,7 +12005,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:
         {
@@ -12198,7 +12026,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: */
@@ -12219,7 +12047,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
@@ -12228,7 +12056,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:
@@ -12259,7 +12087,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:
@@ -12272,7 +12100,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
@@ -12282,7 +12110,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:
@@ -12298,7 +12126,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  */
@@ -12310,7 +12138,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)
@@ -12326,7 +12154,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:
@@ -12337,29 +12165,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:
@@ -12380,8 +12204,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
 
@@ -12400,8 +12223,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,
@@ -12413,8 +12235,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) {
@@ -12444,7 +12265,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 
             ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
                                              set, SIGSET_T_SIZE));
-            break;
         }
 #endif
 #if defined(TARGET_NR_epoll_wait)
@@ -12468,7 +12288,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
@@ -12498,7 +12318,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
@@ -12511,7 +12331,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
@@ -12532,17 +12352,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
@@ -12564,7 +12381,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;
                 }
             }
 
@@ -12577,7 +12394,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 }
             }
         }
-        break;
+        return ret;
     }
 #endif
 
@@ -12605,7 +12422,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 goto efault;
             }
         }
-        break;
+        return ret;
     }
 #endif
 
@@ -12628,7 +12445,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
                 ret = -TARGET_EFAULT;
             }
         }
-        break;
+        return ret;
     }
 #endif
 
@@ -12645,7 +12462,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
 
@@ -12662,15 +12479,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)
@@ -12684,7 +12500,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)
@@ -12707,35 +12523,30 @@ 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
 
     default:
@@ -12744,8 +12555,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] 39+ messages in thread

* [Qemu-devel] [PATCH v3 08/19] linux-user: Propagate goto efault to return
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (6 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 07/19] linux-user: Relax single exit from "break" Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12 16:27   ` Philippe Mathieu-Daudé
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 09/19] linux-user: Propagate goto unimplemented_nowarn " Richard Henderson
                   ` (13 subsequent siblings)
  21 siblings, 1 reply; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

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 efe882612b..a6b8268332 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8009,7 +8009,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)) {
@@ -8020,7 +8020,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);
@@ -8038,7 +8038,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));
@@ -8048,7 +8048,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));
@@ -8083,7 +8083,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
@@ -8095,7 +8095,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));
             }
@@ -8105,7 +8105,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);
@@ -8131,7 +8131,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)
@@ -8146,7 +8146,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;
@@ -8154,7 +8154,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;
@@ -8174,7 +8174,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++;
@@ -8183,7 +8183,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++;
@@ -8258,7 +8258,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;
@@ -8270,14 +8270,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;
@@ -8285,7 +8285,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;
@@ -8293,7 +8293,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;
@@ -8326,7 +8326,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;
@@ -8337,7 +8337,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) {
@@ -8347,7 +8347,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;
@@ -8376,7 +8376,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;
@@ -8386,7 +8386,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
@@ -8414,7 +8414,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);
@@ -8423,7 +8423,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);
         }
@@ -8437,13 +8437,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);
         }
@@ -8457,13 +8457,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);
         }
@@ -8479,16 +8480,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;
@@ -8559,7 +8562,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;
@@ -8567,7 +8570,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;
@@ -8575,7 +8578,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;
@@ -8603,7 +8606,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));
@@ -8625,8 +8628,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);
         }
@@ -8634,7 +8638,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;
@@ -8667,7 +8671,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;
@@ -8717,7 +8721,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;
@@ -8728,7 +8732,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;
@@ -8739,7 +8743,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;
@@ -8753,7 +8757,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];
@@ -8767,7 +8771,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;
@@ -8783,7 +8787,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;
@@ -8813,7 +8817,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;
@@ -8824,7 +8828,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;
@@ -8845,7 +8849,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;
@@ -8947,7 +8951,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;
@@ -8958,7 +8962,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));
             }
@@ -8991,7 +8995,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;
@@ -9002,7 +9006,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));
             }
@@ -9015,7 +9019,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));
             }
@@ -9038,7 +9042,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));
             }
@@ -9053,7 +9057,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
@@ -9073,7 +9077,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,
@@ -9094,7 +9098,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) {
@@ -9110,7 +9114,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));
@@ -9125,7 +9129,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);
@@ -9138,7 +9142,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);
@@ -9162,7 +9166,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         }
     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;
@@ -9172,7 +9176,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);
@@ -9187,7 +9191,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);
@@ -9209,7 +9213,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;
@@ -9220,14 +9224,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;
             }
@@ -9294,7 +9298,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 {
@@ -9308,7 +9312,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]);
@@ -9324,7 +9328,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);
@@ -9340,14 +9344,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;
@@ -9446,7 +9450,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;
@@ -9456,7 +9460,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);
@@ -9478,7 +9482,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]);
@@ -9550,7 +9554,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
     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;
@@ -9561,7 +9565,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;
@@ -9589,8 +9593,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         goto unimplemented;
 #endif
     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:
@@ -9598,7 +9603,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);
@@ -9624,8 +9629,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         goto convert_statfs;
 #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:
@@ -9633,7 +9639,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);
@@ -9731,7 +9737,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);
@@ -9799,7 +9805,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;
             }
@@ -9809,7 +9815,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;
@@ -9823,22 +9829,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;
@@ -9853,7 +9861,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);
@@ -9907,7 +9915,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);
@@ -9921,7 +9929,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;
@@ -9934,7 +9942,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]);
@@ -10031,7 +10039,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;
@@ -10041,7 +10049,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
@@ -10072,12 +10080,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;
                 }
             }
         }
@@ -10088,12 +10096,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;
                 }
             }
         }
@@ -10143,7 +10151,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;
@@ -10174,7 +10182,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;
@@ -10202,7 +10210,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;
@@ -10231,7 +10239,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)) {
@@ -10286,7 +10294,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;
@@ -10335,7 +10343,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);
@@ -10356,7 +10364,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;
@@ -10371,7 +10379,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 {
@@ -10525,7 +10533,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;
                 }
             }
         }
@@ -10562,10 +10570,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;
@@ -10578,7 +10586,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));
@@ -10594,7 +10602,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);
             }
@@ -10608,7 +10616,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));
@@ -10656,7 +10664,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;
         }
@@ -10665,7 +10673,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));
@@ -10676,7 +10684,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));
@@ -10736,7 +10744,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;
@@ -10746,14 +10754,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;
@@ -10769,7 +10777,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);
@@ -10789,7 +10797,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) {
@@ -10905,7 +10913,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);
@@ -10916,7 +10924,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;
@@ -10927,8 +10935,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))
@@ -10937,8 +10946,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))
@@ -10959,9 +10969,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;
@@ -10969,7 +10981,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;
@@ -11008,7 +11020,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));
@@ -11040,7 +11052,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);
@@ -11061,7 +11073,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;
@@ -11081,7 +11093,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;
@@ -11089,7 +11101,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;
@@ -11106,7 +11118,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;
@@ -11157,7 +11169,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;
@@ -11184,7 +11196,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;
@@ -11211,7 +11223,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);
@@ -11380,7 +11392,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;
@@ -11398,7 +11410,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;
@@ -11406,7 +11418,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;
@@ -11969,13 +11981,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);
@@ -12065,25 +12077,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;
                 }
             }
         }
@@ -12193,7 +12205,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,
@@ -12229,7 +12241,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);
@@ -12301,7 +12313,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);
@@ -12312,7 +12324,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);
@@ -12390,7 +12402,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;
                 }
             }
         }
@@ -12414,12 +12426,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;
@@ -12497,7 +12509,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;
@@ -12510,7 +12522,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 {
@@ -12520,7 +12532,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;
@@ -12559,9 +12571,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] 39+ messages in thread

* [Qemu-devel] [PATCH v3 09/19] linux-user: Propagate goto unimplemented_nowarn to return
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (7 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 08/19] linux-user: Propagate goto efault to return Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12 16:28   ` Philippe Mathieu-Daudé
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 10/19] linux-user: Propagate goto unimplemented to default Richard Henderson
                   ` (12 subsequent siblings)
  21 siblings, 1 reply; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

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 a6b8268332..06205d3d65 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -11807,7 +11807,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
@@ -11820,12 +11820,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
@@ -11910,7 +11910,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)
@@ -12564,9 +12564,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     default:
     unimplemented:
         gemu_log("qemu: 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] 39+ messages in thread

* [Qemu-devel] [PATCH v3 10/19] linux-user: Propagate goto unimplemented to default
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (8 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 09/19] linux-user: Propagate goto unimplemented_nowarn " Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-22 10:16   ` Peter Maydell
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 11/19] linux-user: Propagate goto fail to return Richard Henderson
                   ` (11 subsequent siblings)
  21 siblings, 1 reply; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

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.

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 06205d3d65..5a17803732 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8297,14 +8297,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(chmod(p, arg2));
         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
     case TARGET_NR_lseek:
         return get_errno(lseek(arg1, arg2, arg3));
@@ -8390,16 +8382,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()) {
@@ -8470,14 +8456,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))) {
@@ -8499,10 +8477,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();
@@ -8616,14 +8590,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));
@@ -8642,31 +8608,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:
@@ -8675,10 +8625,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));
@@ -9386,10 +9332,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:
         {
@@ -9443,10 +9385,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)))
@@ -9468,10 +9406,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)) || \
@@ -9588,10 +9522,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
     case TARGET_NR_statfs:
         if (!(p = lock_user_string(arg1))) {
             return -TARGET_EFAULT;
@@ -9659,10 +9589,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);
@@ -9880,20 +9806,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
             }
         }
         return ret;
-#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,
@@ -10069,8 +9983,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
@@ -10107,35 +10019,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:
         {
@@ -10648,14 +10537,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:
@@ -10734,7 +10615,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
@@ -10882,21 +10763,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:
@@ -11439,9 +11305,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:
         {
@@ -11599,10 +11462,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;
@@ -12562,7 +12421,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
 
     default:
-    unimplemented:
         gemu_log("qemu: Unsupported syscall: %d\n", num);
         return -TARGET_ENOSYS;
     }
-- 
2.17.1

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

* [Qemu-devel] [PATCH v3 11/19] linux-user: Propagate goto fail to return
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (9 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 10/19] linux-user: Propagate goto unimplemented to default Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 12/19] linux-user: Setup split syscall infrastructure Richard Henderson
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

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 5a17803732..fd8d48b0da 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8865,8 +8865,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);
@@ -8893,8 +8892,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;
@@ -8937,8 +8935,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;
@@ -9227,15 +9224,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;
             }
 
             /*
@@ -9268,8 +9265,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);
@@ -9700,17 +9696,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);
@@ -10056,8 +10050,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));
@@ -10456,7 +10449,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;
@@ -10903,8 +10896,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]));
@@ -11162,8 +11154,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);
@@ -11211,8 +11202,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]);
@@ -11232,8 +11222,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]);
@@ -11308,20 +11297,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;
@@ -11787,8 +11773,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);
@@ -12424,7 +12409,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         gemu_log("qemu: Unsupported syscall: %d\n", num);
         return -TARGET_ENOSYS;
     }
-fail:
     return ret;
 }
 
-- 
2.17.1

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

* [Qemu-devel] [PATCH v3 12/19] linux-user: Setup split syscall infrastructure
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (10 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 11/19] linux-user: Propagate goto fail to return Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-22 10:30   ` Peter Maydell
  2018-08-12 20:45   ` Laurent Vivier
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 13/19] linux-user: Split out close, open, openat, read, write Richard Henderson
                   ` (9 subsequent siblings)
  21 siblings, 2 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

Defines a unified structure for implementation and strace.
Supplies a generator script to build the declarations and
the lookup function.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.h           | 178 +++++++++++++++
 linux-user/strace.c            | 386 ++++++++++++++++++++++++---------
 linux-user/syscall.c           | 113 ++++------
 linux-user/Makefile.objs       |  10 +
 linux-user/gen_syscall_list.py |  82 +++++++
 5 files changed, 595 insertions(+), 174 deletions(-)
 create mode 100644 linux-user/syscall.h
 create mode 100644 linux-user/gen_syscall_list.py

diff --git a/linux-user/syscall.h b/linux-user/syscall.h
new file mode 100644
index 0000000000..7eb078c3e5
--- /dev/null
+++ b/linux-user/syscall.h
@@ -0,0 +1,178 @@
+/*
+ *  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, ...) \
+    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, ...) \
+    const SyscallDef def_##NAME = { \
+        .name = #NAME, .args = args_##NAME, .impl = impl_##NAME, \
+        .arg_type = { __VA_ARGS__ } \
+    }
+
+/* Declarations from the main syscall.c for use in syscall_foo.c,
+ * or for the moment, vice versa.
+ */
+
+int host_to_target_errno(int err);
+
+static inline abi_long get_errno(abi_long ret)
+{
+    return unlikely(ret == -1) ? -host_to_target_errno(errno) : ret;
+}
+
+static inline int is_error(abi_ulong ret)
+{
+    return ret >= -4096;
+}
+
+/* Declarators for interruptable system calls.  */
+
+#define safe_syscall0(type, name) \
+static type safe_##name(void) \
+{ \
+    return safe_syscall(__NR_##name); \
+}
+
+#define safe_syscall1(type, name, type1, arg1) \
+static type safe_##name(type1 arg1) \
+{ \
+    return safe_syscall(__NR_##name, arg1); \
+}
+
+#define safe_syscall2(type, name, type1, arg1, type2, arg2) \
+static type safe_##name(type1 arg1, type2 arg2) \
+{ \
+    return safe_syscall(__NR_##name, arg1, arg2); \
+}
+
+#define safe_syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
+static type safe_##name(type1 arg1, type2 arg2, type3 arg3) \
+{ \
+    return safe_syscall(__NR_##name, arg1, arg2, arg3); \
+}
+
+#define safe_syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
+    type4, arg4) \
+static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+    return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4); \
+}
+
+#define safe_syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
+    type4, arg4, type5, arg5) \
+static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+    type5 arg5) \
+{ \
+    return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
+}
+
+#define safe_syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
+    type4, arg4, type5, arg5, type6, arg6) \
+static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+    type5 arg5, type6 arg6) \
+{ \
+    return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
+}
+
+/* Include declarations of syscall definitions.  */
+#include "syscall_list.h"
diff --git a/linux-user/strace.c b/linux-user/strace.c
index bd897a3f20..6375feb747 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));
 }
 
 /*
@@ -2623,32 +2663,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 fd8d48b0da..a96bbf9093 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 */
@@ -879,7 +880,7 @@ static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
 #endif
 };
 
-static inline int host_to_target_errno(int err)
+int host_to_target_errno(int err)
 {
     if (err >= 0 && err < ERRNO_TABLE_SIZE &&
         host_to_target_errno_table[err]) {
@@ -897,19 +898,6 @@ static inline int target_to_host_errno(int err)
     return err;
 }
 
-static inline abi_long get_errno(abi_long ret)
-{
-    if (ret == -1)
-        return -host_to_target_errno(errno);
-    else
-        return ret;
-}
-
-static inline int is_error(abi_long ret)
-{
-    return (abi_ulong)ret >= (abi_ulong)(-4096);
-}
-
 const char *target_strerror(int err)
 {
     if (err == TARGET_ERESTARTSYS) {
@@ -925,53 +913,6 @@ const char *target_strerror(int err)
     return strerror(target_to_host_errno(err));
 }
 
-#define safe_syscall0(type, name) \
-static type safe_##name(void) \
-{ \
-    return safe_syscall(__NR_##name); \
-}
-
-#define safe_syscall1(type, name, type1, arg1) \
-static type safe_##name(type1 arg1) \
-{ \
-    return safe_syscall(__NR_##name, arg1); \
-}
-
-#define safe_syscall2(type, name, type1, arg1, type2, arg2) \
-static type safe_##name(type1 arg1, type2 arg2) \
-{ \
-    return safe_syscall(__NR_##name, arg1, arg2); \
-}
-
-#define safe_syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
-static type safe_##name(type1 arg1, type2 arg2, type3 arg3) \
-{ \
-    return safe_syscall(__NR_##name, arg1, arg2, arg3); \
-}
-
-#define safe_syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
-    type4, arg4) \
-static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
-    return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4); \
-}
-
-#define safe_syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
-    type4, arg4, type5, arg5) \
-static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
-    type5 arg5) \
-{ \
-    return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
-}
-
-#define safe_syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
-    type4, arg4, type5, arg5, type6, arg6) \
-static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
-    type5 arg5, type6 arg6) \
-{ \
-    return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
-}
-
 safe_syscall3(ssize_t, read, int, fd, void *, buff, size_t, count)
 safe_syscall3(ssize_t, write, int, fd, const void *, buff, size_t, count)
 safe_syscall4(int, openat, int, dirfd, const char *, pathname, \
@@ -12412,12 +12353,18 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     return ret;
 }
 
+/* Include the generated syscall lookup function.  */
+#include "syscall_list.inc.c"
+
 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
@@ -12437,16 +12384,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;
 }
diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
index 59a5c17354..afa69ed6d2 100644
--- a/linux-user/Makefile.objs
+++ b/linux-user/Makefile.objs
@@ -7,3 +7,13 @@ obj-$(TARGET_HAS_BFLT) += flatload.o
 obj-$(TARGET_I386) += vm86.o
 obj-$(TARGET_ARM) += arm/nwfpe/
 obj-$(TARGET_M68K) += m68k-sim.o
+
+GEN_SYSCALL_LIST = $(SRC_PATH)/linux-user/gen_syscall_list.py
+SYSCALL_LIST = linux-user/syscall_list.h linux-user/syscall_list.inc.c
+
+$(SYSCALL_LIST): $(GEN_SYSCALL_LIST)
+	$(call quiet-command,\
+	  $(PYTHON) $(GEN_SYSCALL_LIST) $@, "GEN", $(TARGET_DIR)$@)
+
+linux-user/syscall.o \
+linux-user/strace.o: $(SYSCALL_LIST)
diff --git a/linux-user/gen_syscall_list.py b/linux-user/gen_syscall_list.py
new file mode 100644
index 0000000000..2e0fc39100
--- /dev/null
+++ b/linux-user/gen_syscall_list.py
@@ -0,0 +1,82 @@
+#
+# Linux syscall table generator
+# 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/>.
+#
+
+from __future__ import print_function
+import sys
+
+# These are sets of all syscalls that have been converted.
+# The lists are in collation order with '_' ignored.
+
+# These syscalls are supported by all targets.
+# Avoiding ifdefs for these can diagnose typos in $cpu/syscall_nr.h
+unconditional_syscalls = [
+]
+
+# These syscalls are only supported by some target or abis.
+conditional_syscalls = [
+]
+
+
+def header(f):
+    # Do not ifdef the declarations -- their use may be complicated.
+    all = unconditional_syscalls + conditional_syscalls
+    all.sort()
+    for s in all:
+        print("extern const SyscallDef def_", s, ";", sep = '', file = f)
+
+
+def def_syscall(s, f):
+    print("    case TARGET_NR_", s, ": return &def_", s, ";",
+          sep = '', file = f);
+
+
+def source(f):
+    print("static const SyscallDef *syscall_table(int num)",
+          "{",
+          "    switch (num) {",
+          sep = '\n', file = f)
+
+    for s in unconditional_syscalls:
+        def_syscall(s, f)
+    for s in conditional_syscalls:
+        print("#ifdef TARGET_NR_", s, sep = '', file = f)
+        def_syscall(s, f)
+        print("#endif", file = f)
+
+    print("    }",
+          "    return NULL;",
+          "}",
+          sep = '\n', file = f);
+
+
+def main():
+    p = sys.argv[1]
+    f = open(p, "w")
+
+    print("/* This file is autogenerated by gensyscall.py.  */\n\n",
+          file = f)
+
+    if p[len(p) - 1] == 'h':
+        header(f)
+    else:
+        source(f)
+
+    f.close();
+
+
+main()
-- 
2.17.1

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

* [Qemu-devel] [PATCH v3 13/19] linux-user: Split out close, open, openat, read, write
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (11 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 12/19] linux-user: Setup split syscall infrastructure Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-22 10:38   ` Peter Maydell
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 14/19] linux-user: Split out preadv, pwritev, readv, writev Richard Henderson
                   ` (8 subsequent siblings)
  21 siblings, 1 reply; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.h           |  51 ++++
 linux-user/strace.c            |  35 ---
 linux-user/syscall.c           | 402 +------------------------------
 linux-user/syscall_file.c      | 423 +++++++++++++++++++++++++++++++++
 linux-user/Makefile.objs       |   3 +-
 linux-user/gen_syscall_list.py |   5 +
 linux-user/strace.list         |  15 --
 7 files changed, 484 insertions(+), 450 deletions(-)
 create mode 100644 linux-user/syscall_file.c

diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index 7eb078c3e5..e35b0a60f5 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -125,6 +125,57 @@ static inline int is_error(abi_ulong ret)
     return ret >= -4096;
 }
 
+typedef abi_long (*TargetFdDataFunc)(void *, size_t);
+typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t);
+typedef struct TargetFdTrans {
+    TargetFdDataFunc host_to_target_data;
+    TargetFdDataFunc target_to_host_data;
+    TargetFdAddrFunc target_to_host_addr;
+} TargetFdTrans;
+
+extern TargetFdTrans **target_fd_trans;
+extern unsigned int target_fd_max;
+
+static inline TargetFdDataFunc fd_trans_target_to_host_data(int fd)
+{
+    if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
+        return target_fd_trans[fd]->target_to_host_data;
+    }
+    return NULL;
+}
+
+static inline TargetFdDataFunc fd_trans_host_to_target_data(int fd)
+{
+    if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
+        return target_fd_trans[fd]->host_to_target_data;
+    }
+    return NULL;
+}
+
+static inline TargetFdAddrFunc fd_trans_target_to_host_addr(int fd)
+{
+    if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
+        return target_fd_trans[fd]->target_to_host_addr;
+    }
+    return NULL;
+}
+
+void fd_trans_register(int fd, TargetFdTrans *trans);
+
+static inline void fd_trans_unregister(int fd)
+{
+    if (fd >= 0 && fd < target_fd_max) {
+        target_fd_trans[fd] = NULL;
+    }
+}
+
+/* Temporary declarations from syscall_foo.c back to main syscall.c.
+ * These indicate incomplete conversion.
+ */
+
+int is_proc_myself(const char *filename, const char *entry);
+extern bitmask_transtbl const fcntl_flags_tbl[];
+
 /* Declarators for interruptable system calls.  */
 
 #define safe_syscall0(type, name) \
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 6375feb747..1ae0057365 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,
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index a96bbf9093..c47e73de5f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -325,42 +325,6 @@ _syscall5(int, kcmp, pid_t, pid1, pid_t, pid2, int, type,
           unsigned long, idx1, unsigned long, idx2)
 #endif
 
-static bitmask_transtbl fcntl_flags_tbl[] = {
-  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
-  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
-  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
-  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
-  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
-  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
-  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
-  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
-  { TARGET_O_SYNC,      TARGET_O_DSYNC,     O_SYNC,      O_DSYNC,     },
-  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
-  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
-  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
-  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
-#if defined(O_DIRECT)
-  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
-#endif
-#if defined(O_NOATIME)
-  { TARGET_O_NOATIME,   TARGET_O_NOATIME,   O_NOATIME,   O_NOATIME    },
-#endif
-#if defined(O_CLOEXEC)
-  { TARGET_O_CLOEXEC,   TARGET_O_CLOEXEC,   O_CLOEXEC,   O_CLOEXEC    },
-#endif
-#if defined(O_PATH)
-  { TARGET_O_PATH,      TARGET_O_PATH,      O_PATH,      O_PATH       },
-#endif
-#if defined(O_TMPFILE)
-  { TARGET_O_TMPFILE,   TARGET_O_TMPFILE,   O_TMPFILE,   O_TMPFILE    },
-#endif
-  /* Don't terminate the list prematurely on 64-bit host+guest.  */
-#if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
-  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
-#endif
-  { 0, 0, 0, 0 }
-};
-
 enum {
     QEMU_IFLA_BR_UNSPEC,
     QEMU_IFLA_BR_FORWARD_DELAY,
@@ -539,43 +503,10 @@ enum {
     QEMU___IFLA_XDP_MAX,
 };
 
-typedef abi_long (*TargetFdDataFunc)(void *, size_t);
-typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t);
-typedef struct TargetFdTrans {
-    TargetFdDataFunc host_to_target_data;
-    TargetFdDataFunc target_to_host_data;
-    TargetFdAddrFunc target_to_host_addr;
-} TargetFdTrans;
+TargetFdTrans **target_fd_trans;
+unsigned int target_fd_max;
 
-static TargetFdTrans **target_fd_trans;
-
-static unsigned int target_fd_max;
-
-static TargetFdDataFunc fd_trans_target_to_host_data(int fd)
-{
-    if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
-        return target_fd_trans[fd]->target_to_host_data;
-    }
-    return NULL;
-}
-
-static TargetFdDataFunc fd_trans_host_to_target_data(int fd)
-{
-    if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
-        return target_fd_trans[fd]->host_to_target_data;
-    }
-    return NULL;
-}
-
-static TargetFdAddrFunc fd_trans_target_to_host_addr(int fd)
-{
-    if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
-        return target_fd_trans[fd]->target_to_host_addr;
-    }
-    return NULL;
-}
-
-static void fd_trans_register(int fd, TargetFdTrans *trans)
+void fd_trans_register(int fd, TargetFdTrans *trans)
 {
     unsigned int oldmax;
 
@@ -590,13 +521,6 @@ static void fd_trans_register(int fd, TargetFdTrans *trans)
     target_fd_trans[fd] = trans;
 }
 
-static void fd_trans_unregister(int fd)
-{
-    if (fd >= 0 && fd < target_fd_max) {
-        target_fd_trans[fd] = NULL;
-    }
-}
-
 static void fd_trans_dup(int oldfd, int newfd)
 {
     fd_trans_unregister(newfd);
@@ -913,10 +837,6 @@ const char *target_strerror(int err)
     return strerror(target_to_host_errno(err));
 }
 
-safe_syscall3(ssize_t, read, int, fd, void *, buff, size_t, count)
-safe_syscall3(ssize_t, write, int, fd, const void *, buff, size_t, count)
-safe_syscall4(int, openat, int, dirfd, const char *, pathname, \
-              int, flags, mode_t, mode)
 safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, \
               struct rusage *, rusage)
 safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \
@@ -7490,267 +7410,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
 
@@ -7945,57 +7604,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         gdb_exit(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);
@@ -8007,10 +7615,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
diff --git a/linux-user/syscall_file.c b/linux-user/syscall_file.c
new file mode 100644
index 0000000000..d11128787f
--- /dev/null
+++ b/linux-user/syscall_file.c
@@ -0,0 +1,423 @@
+/*
+ *  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/>.
+ */
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "qemu/path.h"
+#include "qemu.h"
+#include "syscall.h"
+#include <elf.h>
+#include <linux/unistd.h>
+
+
+safe_syscall4(int, openat, int, dirfd, const char *, pathname, \
+              int, flags, mode_t, mode)
+safe_syscall3(ssize_t, read, int, fd, void *, buff, size_t, count)
+safe_syscall3(ssize_t, write, int, fd, const void *, buff, size_t, count)
+
+bitmask_transtbl const fcntl_flags_tbl[] = {
+  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
+  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
+  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
+  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
+  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
+  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
+  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
+  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
+  { TARGET_O_SYNC,      TARGET_O_DSYNC,     O_SYNC,      O_DSYNC,     },
+  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
+  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
+  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
+  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
+#if defined(O_DIRECT)
+  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
+#endif
+#if defined(O_NOATIME)
+  { TARGET_O_NOATIME,   TARGET_O_NOATIME,   O_NOATIME,   O_NOATIME    },
+#endif
+#if defined(O_CLOEXEC)
+  { TARGET_O_CLOEXEC,   TARGET_O_CLOEXEC,   O_CLOEXEC,   O_CLOEXEC    },
+#endif
+#if defined(O_PATH)
+  { TARGET_O_PATH,      TARGET_O_PATH,      O_PATH,      O_PATH       },
+#endif
+#if defined(O_TMPFILE)
+  { TARGET_O_TMPFILE,   TARGET_O_TMPFILE,   O_TMPFILE,   O_TMPFILE    },
+#endif
+  /* Don't terminate the list prematurely on 64-bit host+guest.  */
+#if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
+  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
+#endif
+  { 0, 0, 0, 0 }
+};
+
+
+/*
+ * 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;
+}
+
+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);
+
+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/Makefile.objs b/linux-user/Makefile.objs
index afa69ed6d2..63b81f50e8 100644
--- a/linux-user/Makefile.objs
+++ b/linux-user/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y = main.o syscall.o strace.o mmap.o signal.o \
+obj-y = main.o syscall.o syscall_file.o strace.o mmap.o signal.o \
 	elfload.o linuxload.o uaccess.o uname.o \
 	safe-syscall.o $(TARGET_ABI_DIR)/signal.o \
         $(TARGET_ABI_DIR)/cpu_loop.o
@@ -16,4 +16,5 @@ $(SYSCALL_LIST): $(GEN_SYSCALL_LIST)
 	  $(PYTHON) $(GEN_SYSCALL_LIST) $@, "GEN", $(TARGET_DIR)$@)
 
 linux-user/syscall.o \
+linux-user/syscall_file.o \
 linux-user/strace.o: $(SYSCALL_LIST)
diff --git a/linux-user/gen_syscall_list.py b/linux-user/gen_syscall_list.py
index 2e0fc39100..3d223e3468 100644
--- a/linux-user/gen_syscall_list.py
+++ b/linux-user/gen_syscall_list.py
@@ -25,10 +25,15 @@ import sys
 # These syscalls are supported by all targets.
 # Avoiding ifdefs for these can diagnose typos in $cpu/syscall_nr.h
 unconditional_syscalls = [
+    "close",
+    "openat",
+    "read",
+    "write",
 ]
 
 # These syscalls are only supported by some target or abis.
 conditional_syscalls = [
+    "open",
 ]
 
 
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 2bc5ba04d4..baafa28370 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,9 +1067,6 @@
 #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
@@ -1626,9 +1614,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] 39+ messages in thread

* [Qemu-devel] [PATCH v3 14/19] linux-user: Split out preadv, pwritev, readv, writev
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (12 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 13/19] linux-user: Split out close, open, openat, read, write Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 15/19] linux-user: Split out pread64, pwrite64 Richard Henderson
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.h           |   5 ++
 linux-user/syscall.c           |  85 ++-------------------------
 linux-user/syscall_file.c      | 103 +++++++++++++++++++++++++++++++++
 linux-user/gen_syscall_list.py |   4 ++
 linux-user/strace.list         |  12 ----
 5 files changed, 116 insertions(+), 93 deletions(-)

diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index e35b0a60f5..3fc49d5b65 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -169,6 +169,11 @@ static inline void fd_trans_unregister(int fd)
     }
 }
 
+struct iovec *lock_iovec(int type, abi_ulong target_addr,
+                         abi_ulong count, int copy);
+void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
+                  abi_ulong count, int copy);
+
 /* Temporary declarations from syscall_foo.c back to main syscall.c.
  * These indicate incomplete conversion.
  */
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c47e73de5f..381ee9c3a2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -856,12 +856,6 @@ safe_syscall2(int, rt_sigsuspend, sigset_t *, newset, size_t, sigsetsize)
 safe_syscall2(int, kill, pid_t, pid, int, sig)
 safe_syscall2(int, tkill, int, tid, int, sig)
 safe_syscall3(int, tgkill, int, tgid, int, pid, int, sig)
-safe_syscall3(ssize_t, readv, int, fd, const struct iovec *, iov, int, iovcnt)
-safe_syscall3(ssize_t, writev, int, fd, const struct iovec *, iov, int, iovcnt)
-safe_syscall5(ssize_t, preadv, int, fd, const struct iovec *, iov, int, iovcnt,
-              unsigned long, pos_l, unsigned long, pos_h)
-safe_syscall5(ssize_t, pwritev, int, fd, const struct iovec *, iov, int, iovcnt,
-              unsigned long, pos_l, unsigned long, pos_h)
 safe_syscall3(int, connect, int, fd, const struct sockaddr *, addr,
               socklen_t, addrlen)
 safe_syscall6(ssize_t, sendto, int, fd, const void *, buf, size_t, len,
@@ -3317,25 +3311,8 @@ 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)
+struct iovec *lock_iovec(int type, abi_ulong target_addr,
+                         abi_ulong count, int copy)
 {
     struct target_iovec *target_vec;
     struct iovec *vec;
@@ -3422,8 +3399,8 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
     return NULL;
 }
 
-static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
-                         abi_ulong count, int copy)
+void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
+                  abi_ulong count, int copy)
 {
     struct target_iovec *target_vec;
     int i;
@@ -9859,60 +9836,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 ?) */
diff --git a/linux-user/syscall_file.c b/linux-user/syscall_file.c
index d11128787f..4cc7051847 100644
--- a/linux-user/syscall_file.c
+++ b/linux-user/syscall_file.c
@@ -26,8 +26,14 @@
 
 safe_syscall4(int, openat, int, dirfd, const char *, pathname, \
               int, flags, mode_t, mode)
+safe_syscall5(ssize_t, preadv, int, fd, const struct iovec *, iov,
+              int, iovcnt, unsigned long, pos_l, unsigned long, pos_h)
+safe_syscall5(ssize_t, pwritev, int, fd, const struct iovec *, iov,
+              int, iovcnt, unsigned long, pos_l, unsigned long, pos_h)
 safe_syscall3(ssize_t, read, int, fd, void *, buff, size_t, count)
+safe_syscall3(ssize_t, readv, int, fd, const struct iovec *, iov, int, iovcnt)
 safe_syscall3(ssize_t, write, int, fd, const void *, buff, size_t, count)
+safe_syscall3(ssize_t, writev, int, fd, const struct iovec *, iov, int, iovcnt)
 
 bitmask_transtbl const fcntl_flags_tbl[] = {
   { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
@@ -372,6 +378,75 @@ 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;
+}
+
+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;
+}
+
+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;
@@ -397,6 +472,20 @@ SYSCALL_IMPL(read)
 }
 SYSCALL_DEF(read, ARG_DEC, ARG_PTR, ARG_DEC);
 
+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);
@@ -421,3 +510,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/gen_syscall_list.py b/linux-user/gen_syscall_list.py
index 3d223e3468..ce6dca742c 100644
--- a/linux-user/gen_syscall_list.py
+++ b/linux-user/gen_syscall_list.py
@@ -27,8 +27,12 @@ import sys
 unconditional_syscalls = [
     "close",
     "openat",
+    "preadv",
+    "pwritev",
     "read",
+    "readv",
     "write",
+    "writev",
 ]
 
 # These syscalls are only supported by some target or abis.
diff --git a/linux-user/strace.list b/linux-user/strace.list
index baafa28370..d5ee55ac82 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
@@ -1079,9 +1073,6 @@
 #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
 #ifdef TARGET_NR_reboot
 { TARGET_NR_reboot, "reboot" , NULL, NULL, NULL },
 #endif
@@ -1614,9 +1605,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] 39+ messages in thread

* [Qemu-devel] [PATCH v3 15/19] linux-user: Split out pread64, pwrite64
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (13 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 14/19] linux-user: Split out preadv, pwritev, readv, writev Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12 16:37   ` Philippe Mathieu-Daudé
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 16/19] linux-user: Split out name_to_handle_at, open_by_handle_at Richard Henderson
                   ` (6 subsequent siblings)
  21 siblings, 1 reply; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.h           | 44 +++++++++++++++++++++
 linux-user/syscall.c           | 70 ----------------------------------
 linux-user/syscall_file.c      | 61 +++++++++++++++++++++++++++--
 linux-user/gen_syscall_list.py |  2 +
 linux-user/strace.list         |  6 ---
 5 files changed, 104 insertions(+), 79 deletions(-)

diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index 3fc49d5b65..a157e25bba 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -174,6 +174,50 @@ struct iovec *lock_iovec(int type, abi_ulong target_addr,
 void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
                   abi_ulong count, int copy);
 
+/* 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
+}
+
 /* Temporary declarations from syscall_foo.c back to main syscall.c.
  * These indicate incomplete conversion.
  */
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 381ee9c3a2..cdc9787240 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -642,38 +642,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
@@ -6864,22 +6832,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,
@@ -10078,28 +10030,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)))
diff --git a/linux-user/syscall_file.c b/linux-user/syscall_file.c
index 4cc7051847..aae9c49599 100644
--- a/linux-user/syscall_file.c
+++ b/linux-user/syscall_file.c
@@ -378,15 +378,70 @@ 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;
+}
+
+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;
+}
+
+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.
  */
 #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/gen_syscall_list.py b/linux-user/gen_syscall_list.py
index ce6dca742c..7481d030ee 100644
--- a/linux-user/gen_syscall_list.py
+++ b/linux-user/gen_syscall_list.py
@@ -27,7 +27,9 @@ import sys
 unconditional_syscalls = [
     "close",
     "openat",
+    "pread64",
     "preadv",
+    "pwrite64",
     "pwritev",
     "read",
     "readv",
diff --git a/linux-user/strace.list b/linux-user/strace.list
index d5ee55ac82..d978cefa31 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] 39+ messages in thread

* [Qemu-devel] [PATCH v3 16/19] linux-user: Split out name_to_handle_at, open_by_handle_at
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (14 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 15/19] linux-user: Split out pread64, pwrite64 Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 17/19] linux-user: Split out ipc syscalls Richard Henderson
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall.h           |  1 +
 linux-user/strace.c            |  5 +-
 linux-user/syscall.c           | 98 ----------------------------------
 linux-user/syscall_file.c      | 88 ++++++++++++++++++++++++++++++
 linux-user/gen_syscall_list.py |  2 +
 linux-user/strace.list         |  3 --
 6 files changed, 95 insertions(+), 102 deletions(-)

diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index a157e25bba..217267409b 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -52,6 +52,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 1ae0057365..4240ea649a 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
@@ -2693,6 +2693,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.c b/linux-user/syscall.c
index cdc9787240..8c7dd3049e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7151,93 +7151,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)
 
@@ -7533,17 +7446,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
         gdb_exit(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
diff --git a/linux-user/syscall_file.c b/linux-user/syscall_file.c
index aae9c49599..9ee10b415e 100644
--- a/linux-user/syscall_file.c
+++ b/linux-user/syscall_file.c
@@ -24,8 +24,12 @@
 #include <linux/unistd.h>
 
 
+safe_syscall5(int, name_to_handle_at, int, dirfd, const char *, pathname,
+              struct file_handle *, handle, int *, mount_id, int, flags)
 safe_syscall4(int, openat, int, dirfd, const char *, pathname, \
               int, flags, mode_t, mode)
+safe_syscall3(int, open_by_handle_at, int, mount_fd,
+              struct file_handle *, handle, int, flags)
 safe_syscall5(ssize_t, preadv, int, fd, const struct iovec *, iov,
               int, iovcnt, unsigned long, pos_l, unsigned long, pos_h)
 safe_syscall5(ssize_t, pwritev, int, fd, const struct iovec *, iov,
@@ -76,6 +80,90 @@ bitmask_transtbl const fcntl_flags_tbl[] = {
  * Helpers for do_openat, manipulating /proc/self/foo.
  */
 
+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);
+
 static int open_self_cmdline(void *cpu_env, int fd)
 {
     CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
diff --git a/linux-user/gen_syscall_list.py b/linux-user/gen_syscall_list.py
index 7481d030ee..cebf111660 100644
--- a/linux-user/gen_syscall_list.py
+++ b/linux-user/gen_syscall_list.py
@@ -26,7 +26,9 @@ import sys
 # Avoiding ifdefs for these can diagnose typos in $cpu/syscall_nr.h
 unconditional_syscalls = [
     "close",
+    "name_to_handle_at",
     "openat",
+    "open_by_handle_at",
     "pread64",
     "preadv",
     "pwrite64",
diff --git a/linux-user/strace.list b/linux-user/strace.list
index d978cefa31..d7880665a4 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] 39+ messages in thread

* [Qemu-devel] [PATCH v3 17/19] linux-user: Split out ipc syscalls
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (15 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 16/19] linux-user: Split out name_to_handle_at, open_by_handle_at Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 18/19] linux-user: Split out memory syscalls Richard Henderson
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

Given that these are all intertwined via TARGET_NR_ipc,
we must move them all to the new file all at once.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/strace.c            |   83 ---
 linux-user/syscall.c           |  973 ----------------------------
 linux-user/syscall_ipc.c       | 1095 ++++++++++++++++++++++++++++++++
 linux-user/Makefile.objs       |    4 +-
 linux-user/gen_syscall_list.py |   12 +
 linux-user/strace.list         |   42 --
 6 files changed, 1110 insertions(+), 1099 deletions(-)
 create mode 100644 linux-user/syscall_ipc.c

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 4240ea649a..79d2d91636 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.c b/linux-user/syscall.c
index 8c7dd3049e..51d27f2a88 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -23,8 +23,6 @@
 #include <elf.h>
 #include <endian.h>
 #include <grp.h>
-#include <sys/ipc.h>
-#include <sys/msg.h>
 #include <sys/wait.h>
 #include <sys/mount.h>
 #include <sys/file.h>
@@ -41,8 +39,6 @@
 #include <sys/uio.h>
 #include <poll.h>
 #include <sys/times.h>
-#include <sys/shm.h>
-#include <sys/sem.h>
 #include <sys/statfs.h>
 #include <utime.h>
 #include <sys/sysinfo.h>
@@ -843,43 +839,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)
@@ -4083,890 +4042,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,
@@ -9245,54 +8320,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:
diff --git a/linux-user/syscall_ipc.c b/linux-user/syscall_ipc.c
new file mode 100644
index 0000000000..e2617c7a63
--- /dev/null
+++ b/linux-user/syscall_ipc.c
@@ -0,0 +1,1095 @@
+/*
+ *  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/>.
+ */
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "qemu/path.h"
+#include "qemu.h"
+#include "syscall.h"
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <sys/shm.h>
+#include <sys/sem.h>
+#include <linux/unistd.h>
+
+
+#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/Makefile.objs b/linux-user/Makefile.objs
index 63b81f50e8..18dfda66c9 100644
--- a/linux-user/Makefile.objs
+++ b/linux-user/Makefile.objs
@@ -1,4 +1,5 @@
-obj-y = main.o syscall.o syscall_file.o strace.o mmap.o signal.o \
+obj-y = main.o syscall.o syscall_file.o syscall_ipc.o \
+	strace.o mmap.o signal.o \
 	elfload.o linuxload.o uaccess.o uname.o \
 	safe-syscall.o $(TARGET_ABI_DIR)/signal.o \
         $(TARGET_ABI_DIR)/cpu_loop.o
@@ -17,4 +18,5 @@ $(SYSCALL_LIST): $(GEN_SYSCALL_LIST)
 
 linux-user/syscall.o \
 linux-user/syscall_file.o \
+linux-user/syscall_ipc.o \
 linux-user/strace.o: $(SYSCALL_LIST)
diff --git a/linux-user/gen_syscall_list.py b/linux-user/gen_syscall_list.py
index cebf111660..68ab279d00 100644
--- a/linux-user/gen_syscall_list.py
+++ b/linux-user/gen_syscall_list.py
@@ -41,7 +41,19 @@ unconditional_syscalls = [
 
 # These syscalls are only supported by some target or abis.
 conditional_syscalls = [
+    "ipc",
+    "msgctl",
+    "msgget",
+    "msgrcv",
+    "msgsnd",
     "open",
+    "semctl",
+    "semget",
+    "semop",
+    "shmat",
+    "shmctl",
+    "shmdt",
+    "shmget",
 ]
 
 
diff --git a/linux-user/strace.list b/linux-user/strace.list
index d7880665a4..b0a9b4ad1a 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
@@ -1190,18 +1172,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
@@ -1329,18 +1299,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] 39+ messages in thread

* [Qemu-devel] [PATCH v3 18/19] linux-user: Split out memory syscalls
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (16 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 17/19] linux-user: Split out ipc syscalls Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 19/19] linux-user: Split out some process syscalls Richard Henderson
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

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.c           | 118 --------------------
 linux-user/syscall_mem.c       | 190 +++++++++++++++++++++++++++++++++
 linux-user/Makefile.objs       |   3 +-
 linux-user/gen_syscall_list.py |  10 ++
 linux-user/strace.list         |  33 ------
 7 files changed, 212 insertions(+), 199 deletions(-)
 create mode 100644 linux-user/syscall_mem.c

diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index 217267409b..0bbbf6f7b0 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -53,6 +53,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 79d2d91636..6ebd261a84 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),
@@ -2364,51 +2364,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)
 {
@@ -2613,6 +2568,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.c b/linux-user/syscall.c
index 51d27f2a88..67fbf7f674 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4899,29 +4899,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 */
@@ -6097,21 +6074,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
-
 static inline abi_long host_to_target_stat64(void *cpu_env,
                                              abi_ulong target_addr,
                                              struct stat *host_st)
@@ -7853,86 +7815,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
     case TARGET_NR_truncate:
         if (!(p = lock_user_string(arg1)))
             return -TARGET_EFAULT;
diff --git a/linux-user/syscall_mem.c b/linux-user/syscall_mem.c
new file mode 100644
index 0000000000..71a2fb6747
--- /dev/null
+++ b/linux-user/syscall_mem.c
@@ -0,0 +1,190 @@
+/*
+ *  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/>.
+ */
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "qemu/path.h"
+#include "qemu.h"
+#include "syscall.h"
+#include <elf.h>
+#include <linux/unistd.h>
+
+
+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));
+}
+
+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 }
+};
+
+#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;
+}
+
+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));
+}
+
+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/Makefile.objs b/linux-user/Makefile.objs
index 18dfda66c9..92ffe66fef 100644
--- a/linux-user/Makefile.objs
+++ b/linux-user/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y = main.o syscall.o syscall_file.o syscall_ipc.o \
+obj-y = main.o syscall.o syscall_file.o syscall_ipc.o syscall_mem.o \
 	strace.o mmap.o signal.o \
 	elfload.o linuxload.o uaccess.o uname.o \
 	safe-syscall.o $(TARGET_ABI_DIR)/signal.o \
@@ -18,5 +18,6 @@ $(SYSCALL_LIST): $(GEN_SYSCALL_LIST)
 
 linux-user/syscall.o \
 linux-user/syscall_file.o \
+linux-user/syscall_mem.o \
 linux-user/syscall_ipc.o \
 linux-user/strace.o: $(SYSCALL_LIST)
diff --git a/linux-user/gen_syscall_list.py b/linux-user/gen_syscall_list.py
index 68ab279d00..4eb83ae9ce 100644
--- a/linux-user/gen_syscall_list.py
+++ b/linux-user/gen_syscall_list.py
@@ -26,6 +26,14 @@ import sys
 # Avoiding ifdefs for these can diagnose typos in $cpu/syscall_nr.h
 unconditional_syscalls = [
     "close",
+    "mlock",
+    "mlockall",
+    "mprotect",
+    "mremap",
+    "msync",
+    "munlock",
+    "munlockall",
+    "munmap",
     "name_to_handle_at",
     "openat",
     "open_by_handle_at",
@@ -42,6 +50,8 @@ unconditional_syscalls = [
 # These syscalls are only supported by some target or abis.
 conditional_syscalls = [
     "ipc",
+    "mmap",
+    "mmap2",
     "msgctl",
     "msgget",
     "msgrcv",
diff --git a/linux-user/strace.list b/linux-user/strace.list
index b0a9b4ad1a..28d1c616ac 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] 39+ messages in thread

* [Qemu-devel] [PATCH v3 19/19] linux-user: Split out some process syscalls
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (17 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 18/19] linux-user: Split out memory syscalls Richard Henderson
@ 2018-06-12  0:51 ` Richard Henderson
  2018-08-11 22:48   ` Laurent Vivier
  2018-06-12  1:19 ` [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall no-reply
                   ` (2 subsequent siblings)
  21 siblings, 1 reply; 39+ messages in thread
From: Richard Henderson @ 2018-06-12  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent, peter.maydell

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           | 108 ++++
 linux-user/strace.c            |  36 +-
 linux-user/syscall.c           | 799 ----------------------------
 linux-user/syscall_proc.c      | 914 +++++++++++++++++++++++++++++++++
 linux-user/Makefile.objs       |   5 +-
 linux-user/gen_syscall_list.py |  43 ++
 linux-user/strace.list         | 144 ------
 7 files changed, 1072 insertions(+), 977 deletions(-)
 create mode 100644 linux-user/syscall_proc.c

diff --git a/linux-user/syscall.h b/linux-user/syscall.h
index 0bbbf6f7b0..de99ae5a3b 100644
--- a/linux-user/syscall.h
+++ b/linux-user/syscall.h
@@ -53,6 +53,7 @@ typedef enum {
     /* These print as sets of flags.  */
     ARG_ATDIRFD,
     ARG_ATFLAG,
+    ARG_CLONEFLAG,
     ARG_MMAPFLAG,
     ARG_MMAPPROT,
     ARG_MODEFLAG,
@@ -221,6 +222,61 @@ static inline uint64_t target_offset64(abi_ulong word0, abi_ulong word1)
 #endif
 }
 
+#ifdef USE_UID16
+static inline int high2lowuid(int uid)
+{
+    return uid > 65535 ? 65534 : uid;
+}
+
+static inline int high2lowgid(int gid)
+{
+    return gid > 65535 ? 65534 : gid;
+}
+
+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 /* !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 */
+
 /* Temporary declarations from syscall_foo.c back to main syscall.c.
  * These indicate incomplete conversion.
  */
@@ -277,5 +333,57 @@ static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
     return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
 }
 
+/* Declarators for non-interruptable system calls.  */
+
+#undef _syscall0
+#undef _syscall1
+#undef _syscall2
+#undef _syscall3
+#undef _syscall4
+#undef _syscall5
+#undef _syscall6
+
+#define _syscall0(type, name)                   \
+    static type name(void)                      \
+    {                                           \
+        return syscall(__NR_##name);            \
+    }
+
+#define _syscall1(T0, name, T1, A1)             \
+    static T0 name(T1 A1)                       \
+    {                                           \
+        return syscall(__NR_##name, A1);        \
+    }
+
+#define _syscall2(T0, name, T1, A1, T2, A2)     \
+    static T0 name(T1 A1, T2 A2)                \
+    {                                           \
+        return syscall(__NR_##name, A1, A2);    \
+    }
+
+#define _syscall3(T0, name, T1, A1, T2, A2, T3, A3)     \
+    static T0 name(T1 A1, T2 A2, T3 A3)                 \
+    {                                                   \
+        return syscall(__NR_##name, A1, A2, A3);        \
+    }
+
+#define _syscall4(T0, name, T1, A1, T2, A2, T3, A3, T4, A4)     \
+    static T0 name(T1 A1, T2 A2, T3 A3, T4 A4)                  \
+    {                                                           \
+        return syscall(__NR_##name, A1, A2, A3, A4);            \
+    }
+
+#define _syscall5(T0, name, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5)     \
+    static T0 name(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5)                   \
+    {                                                                   \
+        return syscall(__NR_##name, A1, A2, A3, A4, A5);                \
+    }
+
+#define _syscall6(T0, name, T1, A1, T2, A2, T3, A3, T4, A4, T5, A5, T6, A6) \
+    static T0 name(T1 A1, T2 A2, T3 A3, T4 A4, T5 A5, T6 A6)            \
+    {                                                                   \
+        return syscall(__NR_##name, A1, A2, A3, A4, A5, A6);            \
+    }
+
 /* Include declarations of syscall definitions.  */
 #include "syscall_list.h"
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 6ebd261a84..8b0104afce 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,
@@ -2568,6 +2537,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.c b/linux-user/syscall.c
index 67fbf7f674..58754c9674 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -22,11 +22,9 @@
 #include "qemu/path.h"
 #include <elf.h>
 #include <endian.h>
-#include <grp.h>
 #include <sys/wait.h>
 #include <sys/mount.h>
 #include <sys/file.h>
-#include <sys/fsuid.h>
 #include <sys/personality.h>
 #include <sys/prctl.h>
 #include <sys/resource.h>
@@ -109,57 +107,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.
  */
@@ -169,61 +116,6 @@
 #define	VFAT_IOCTL_READDIR_BOTH		_IOR('r', 1, struct linux_dirent [2])
 #define	VFAT_IOCTL_READDIR_SHORT	_IOR('r', 2, struct linux_dirent [2])
 
-#undef _syscall0
-#undef _syscall1
-#undef _syscall2
-#undef _syscall3
-#undef _syscall4
-#undef _syscall5
-#undef _syscall6
-
-#define _syscall0(type,name)		\
-static type name (void)			\
-{					\
-	return syscall(__NR_##name);	\
-}
-
-#define _syscall1(type,name,type1,arg1)		\
-static type name (type1 arg1)			\
-{						\
-	return syscall(__NR_##name, arg1);	\
-}
-
-#define _syscall2(type,name,type1,arg1,type2,arg2)	\
-static type name (type1 arg1,type2 arg2)		\
-{							\
-	return syscall(__NR_##name, arg1, arg2);	\
-}
-
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)	\
-static type name (type1 arg1,type2 arg2,type3 arg3)		\
-{								\
-	return syscall(__NR_##name, arg1, arg2, arg3);		\
-}
-
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)	\
-static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)			\
-{										\
-	return syscall(__NR_##name, arg1, arg2, arg3, arg4);			\
-}
-
-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,	\
-		  type5,arg5)							\
-static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)	\
-{										\
-	return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);		\
-}
-
-
-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,	\
-		  type5,arg5,type6,arg6)					\
-static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,	\
-                  type6 arg6)							\
-{										\
-	return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);	\
-}
-
-
 #define __NR_sys_uname __NR_uname
 #define __NR_sys_getcwd1 __NR_getcwd
 #define __NR_sys_getdents __NR_getdents
@@ -246,16 +138,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
@@ -285,9 +167,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)
@@ -5123,53 +5002,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
@@ -5209,194 +5041,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)
 {
@@ -5732,106 +5376,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;
@@ -6485,10 +6029,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:
         {
@@ -6713,16 +6253,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #endif
     case TARGET_NR_lseek:
         return get_errno(lseek(arg1, arg2, arg3));
-#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:
         {
             /* need to look at the data field */
@@ -7062,16 +6592,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:
         {
@@ -8204,23 +7724,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:
@@ -8966,12 +8469,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:
     {
@@ -9054,66 +8551,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)
@@ -9125,46 +8562,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)))
@@ -9173,15 +8570,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)))
@@ -9190,31 +8578,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:
@@ -9375,110 +8738,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)))
@@ -9487,22 +8750,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:
         {
@@ -9661,8 +8908,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
@@ -9839,44 +9084,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;
@@ -9936,12 +9143,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)));
 
diff --git a/linux-user/syscall_proc.c b/linux-user/syscall_proc.c
new file mode 100644
index 0000000000..80c0027625
--- /dev/null
+++ b/linux-user/syscall_proc.c
@@ -0,0 +1,914 @@
+/*
+ *  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/>.
+ */
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "qemu/path.h"
+#include "qemu.h"
+#include "syscall.h"
+#include <grp.h>
+#include <sys/fsuid.h>
+#include <linux/unistd.h>
+
+
+/* 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
+}
+
+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/Makefile.objs b/linux-user/Makefile.objs
index 92ffe66fef..0e18fc88e6 100644
--- a/linux-user/Makefile.objs
+++ b/linux-user/Makefile.objs
@@ -1,5 +1,5 @@
 obj-y = main.o syscall.o syscall_file.o syscall_ipc.o syscall_mem.o \
-	strace.o mmap.o signal.o \
+	syscall_proc.o strace.o mmap.o signal.o \
 	elfload.o linuxload.o uaccess.o uname.o \
 	safe-syscall.o $(TARGET_ABI_DIR)/signal.o \
         $(TARGET_ABI_DIR)/cpu_loop.o
@@ -18,6 +18,7 @@ $(SYSCALL_LIST): $(GEN_SYSCALL_LIST)
 
 linux-user/syscall.o \
 linux-user/syscall_file.o \
-linux-user/syscall_mem.o \
 linux-user/syscall_ipc.o \
+linux-user/syscall_mem.o \
+linux-user/syscall_proc.o \
 linux-user/strace.o: $(SYSCALL_LIST)
diff --git a/linux-user/gen_syscall_list.py b/linux-user/gen_syscall_list.py
index 4eb83ae9ce..9c28221bdd 100644
--- a/linux-user/gen_syscall_list.py
+++ b/linux-user/gen_syscall_list.py
@@ -25,7 +25,10 @@ import sys
 # These syscalls are supported by all targets.
 # Avoiding ifdefs for these can diagnose typos in $cpu/syscall_nr.h
 unconditional_syscalls = [
+    "clone",
     "close",
+    "getgroups",
+    "gettid",
     "mlock",
     "mlockall",
     "mprotect",
@@ -43,12 +46,38 @@ unconditional_syscalls = [
     "pwritev",
     "read",
     "readv",
+    "setfsgid",
+    "setfsuid",
+    "setgid",
+    "setgroups",
+    "setsid",
+    "setuid",
     "write",
     "writev",
 ]
 
 # These syscalls are only supported by some target or abis.
 conditional_syscalls = [
+    "fork",
+    "getegid",
+    "getegid32",
+    "geteuid",
+    "geteuid32",
+    "getgid",
+    "getgid32",
+    "getgroups32",
+    "getpgrp",
+    "getpid",
+    "getppid",
+    "getresgid",
+    "getresgid32",
+    "getresuid",
+    "getresuid32",
+    "getuid",
+    "getuid32",
+    "getxgid",
+    "getxpid",
+    "getxuid",
     "ipc",
     "mmap",
     "mmap2",
@@ -60,10 +89,24 @@ conditional_syscalls = [
     "semctl",
     "semget",
     "semop",
+    "setfsgid32",
+    "setfsuid32",
+    "setgid32",
+    "setgroups32",
+    "setregid",
+    "setregid32",
+    "setresgid",
+    "setresgid32",
+    "setresuid",
+    "setresuid32",
+    "setreuid",
+    "setreuid32",
+    "setuid32",
     "shmat",
     "shmctl",
     "shmdt",
     "shmget",
+    "vfork",
 ]
 
 
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 28d1c616ac..d03b5d5096 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
@@ -1160,30 +1082,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
@@ -1199,48 +1097,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
@@ -1254,12 +1119,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
@@ -1494,9 +1353,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] 39+ messages in thread

* Re: [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (18 preceding siblings ...)
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 19/19] linux-user: Split out some process syscalls Richard Henderson
@ 2018-06-12  1:19 ` no-reply
  2018-06-12 11:00 ` Laurent Vivier
  2018-06-22 10:40 ` Peter Maydell
  21 siblings, 0 replies; 39+ messages in thread
From: no-reply @ 2018-06-12  1:19 UTC (permalink / raw)
  To: richard.henderson; +Cc: famz, qemu-devel, peter.maydell, laurent

Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20180612005145.3375-1-richard.henderson@linaro.org
Subject: [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]               patchew/20180612005145.3375-1-richard.henderson@linaro.org -> patchew/20180612005145.3375-1-richard.henderson@linaro.org
Switched to a new branch 'test'
41150e125a linux-user: Split out some process syscalls
fb226d75f3 linux-user: Split out memory syscalls
a1be98d2de linux-user: Split out ipc syscalls
4ed2df106e linux-user: Split out name_to_handle_at, open_by_handle_at
aa14b5dcfe linux-user: Split out pread64, pwrite64
856ddcb6c5 linux-user: Split out preadv, pwritev, readv, writev
4b6c6ec7c9 linux-user: Split out close, open, openat, read, write
796e07dce5 linux-user: Setup split syscall infrastructure
67e916d5d7 linux-user: Propagate goto fail to return
209fad0642 linux-user: Propagate goto unimplemented to default
df63822df8 linux-user: Propagate goto unimplemented_nowarn to return
6211190a92 linux-user: Propagate goto efault to return
daed129053 linux-user: Relax single exit from "break"
850a3c73a6 linux-user: Split out do_syscall1
1344862476 linux-user: Remove DEBUG
d4c997503b linux-user/sparc64: Add inotify_rm_watch and tee syscalls
57b7c2976f linux-user/microblaze: Fix typo in accept4 syscall
ca160b0d28 linux-user/hppa: Fix typo in mknodat syscall
2fd6a8234f linux-user/alpha: Fix epoll syscalls

=== OUTPUT BEGIN ===
Checking PATCH 1/19: linux-user/alpha: Fix epoll syscalls...
ERROR: code indent should never use tabs
#23: FILE: linux-user/alpha/syscall_nr.h:346:
+#define TARGET_NR_epoll_create^I^I407$

ERROR: code indent should never use tabs
#24: FILE: linux-user/alpha/syscall_nr.h:347:
+#define TARGET_NR_epoll_ctl^I^I408$

ERROR: code indent should never use tabs
#25: FILE: linux-user/alpha/syscall_nr.h:348:
+#define TARGET_NR_epoll_wait^I^I409$

total: 3 errors, 0 warnings, 27 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 2/19: linux-user/hppa: Fix typo in mknodat syscall...
Checking PATCH 3/19: linux-user/microblaze: Fix typo in accept4 syscall...
ERROR: code indent should never use tabs
#23: FILE: linux-user/microblaze/syscall_nr.h:366:
+#define TARGET_NR_accept4^I^I362 /* new */$

total: 1 errors, 0 warnings, 8 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 4/19: linux-user/sparc64: Add inotify_rm_watch and tee syscalls...
WARNING: line over 80 characters
#19: FILE: linux-user/sparc64/syscall_nr.h:157:
+#define TARGET_NR_inotify_rm_watch   156 /* Linux specific                              */

total: 0 errors, 1 warnings, 16 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 5/19: linux-user: Remove DEBUG...
Checking PATCH 6/19: linux-user: Split out do_syscall1...
Checking PATCH 7/19: linux-user: Relax single exit from "break"...
Checking PATCH 8/19: linux-user: Propagate goto efault to return...
ERROR: do not use assignment in if condition
#257: FILE: linux-user/syscall.c:8465:
+            if (!(p = lock_user_string(arg2))) {

ERROR: do not use assignment in if condition
#269: FILE: linux-user/syscall.c:8483:
+        if (!(p = lock_user_string(arg1))) {

ERROR: do not use assignment in if condition
#280: FILE: linux-user/syscall.c:8492:
+        if (!(p = lock_user_string(arg2))) {

ERROR: do not use assignment in if condition
#328: FILE: linux-user/syscall.c:8631:
+            if (!(p = lock_user_string(arg1))) {

ERROR: suspect code indent for conditional statements (11, 15)
#652: FILE: linux-user/syscall.c:9462:
            if (!p) {
+               return -TARGET_EFAULT;

ERROR: do not use assignment in if condition
#691: FILE: linux-user/syscall.c:9596:
+        if (!(p = lock_user_string(arg1))) {

ERROR: do not use assignment in if condition
#712: FILE: linux-user/syscall.c:9632:
+        if (!(p = lock_user_string(arg1))) {

ERROR: do not use assignment in if condition
#767: FILE: linux-user/syscall.c:9838:
+        if (!(p = lock_user_string(arg1))) {

ERROR: do not use assignment in if condition
#778: FILE: linux-user/syscall.c:9847:
+        if (!(p = lock_user_string(arg1))) {

ERROR: do not use assignment in if condition
#1084: FILE: linux-user/syscall.c:10938:
+        if (!(p = lock_user_string(arg1))) {

ERROR: do not use assignment in if condition
#1096: FILE: linux-user/syscall.c:10949:
+        if (!(p = lock_user_string(arg1))) {

ERROR: do not use assignment in if condition
#1108: FILE: linux-user/syscall.c:10972:
+        if (!(p = lock_user_string(arg2))) {

total: 12 errors, 0 warnings, 1228 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 9/19: linux-user: Propagate goto unimplemented_nowarn to return...
Checking PATCH 10/19: linux-user: Propagate goto unimplemented to default...
Checking PATCH 11/19: linux-user: Propagate goto fail to return...
Checking PATCH 12/19: linux-user: Setup split syscall infrastructure...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#32: 
new file mode 100644

total: 0 errors, 1 warnings, 912 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 13/19: linux-user: Split out close, open, openat, read, write...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#657: 
new file mode 100644

total: 0 errors, 1 warnings, 1030 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 14/19: linux-user: Split out preadv, pwritev, readv, writev...
Checking PATCH 15/19: linux-user: Split out pread64, pwrite64...
Checking PATCH 16/19: linux-user: Split out name_to_handle_at, open_by_handle_at...
Checking PATCH 17/19: linux-user: Split out ipc syscalls...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#1260: 
new file mode 100644

WARNING: architecture specific defines should be avoided
#1294: FILE: linux-user/syscall_ipc.c:30:
+#ifdef __NR_msgsnd

total: 0 errors, 2 warnings, 2305 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 18/19: linux-user: Split out memory syscalls...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#362: 
new file mode 100644

total: 0 errors, 1 warnings, 500 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 19/19: linux-user: Split out some process syscalls...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#1524: 
new file mode 100644

WARNING: architecture specific defines should be avoided
#1564: FILE: linux-user/syscall_proc.c:36:
+#ifdef __NR_setuid32

WARNING: architecture specific defines should be avoided
#1569: FILE: linux-user/syscall_proc.c:41:
+#ifdef __NR_setgid32

WARNING: architecture specific defines should be avoided
#1574: FILE: linux-user/syscall_proc.c:46:
+#ifdef __NR_setresuid32

WARNING: architecture specific defines should be avoided
#1579: FILE: linux-user/syscall_proc.c:51:
+#ifdef __NR_setresgid32

WARNING: architecture specific defines should be avoided
#1590: FILE: linux-user/syscall_proc.c:62:
+#ifndef __NR_gettid

WARNING: architecture specific defines should be avoided
#1595: FILE: linux-user/syscall_proc.c:67:
+#ifndef __NR_set_tid_address

total: 0 errors, 7 warnings, 2351 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* Re: [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (19 preceding siblings ...)
  2018-06-12  1:19 ` [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall no-reply
@ 2018-06-12 11:00 ` Laurent Vivier
  2018-06-22 10:40 ` Peter Maydell
  21 siblings, 0 replies; 39+ messages in thread
From: Laurent Vivier @ 2018-06-12 11:00 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell

Le 12/06/2018 à 02:51, Richard Henderson a écrit :
> Version 3 does not attempt the whole thing in one go,
> and does attempt to incorporate strace into the reorg.

I've included your first four patches in my last linux-user pull-request.

Thanks,
Laurent

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

* Re: [Qemu-devel] [PATCH v3 06/19] linux-user: Split out do_syscall1
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 06/19] linux-user: Split out do_syscall1 Richard Henderson
@ 2018-06-12 16:11   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 39+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-06-12 16:11 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, laurent

On 06/11/2018 09:51 PM, Richard Henderson wrote:
> 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: Laurent Vivier <laurent@vivier.eu>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.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 c212149245..ec3bc1cbe5 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -7947,13 +7947,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;
> @@ -7961,25 +7963,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>      struct statfs stfs;
>      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).
> @@ -12765,11 +12748,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;
> +}
> 

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

* Re: [Qemu-devel] [PATCH v3 07/19] linux-user: Relax single exit from "break"
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 07/19] linux-user: Relax single exit from "break" Richard Henderson
@ 2018-06-12 16:23   ` Philippe Mathieu-Daudé
  2018-08-11 21:50   ` Laurent Vivier
  1 sibling, 0 replies; 39+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-06-12 16:23 UTC (permalink / raw)
  To: Richard Henderson, peter.maydell, laurent; +Cc: qemu-devel

On 06/11/2018 09:51 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 | 970 +++++++++++++++++--------------------------
>  1 file changed, 390 insertions(+), 580 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index ec3bc1cbe5..efe882612b 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -7971,8 +7971,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();
> @@ -8004,12 +8003,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #endif
>          gdb_exit(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));
> @@ -8019,7 +8017,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;
> @@ -8035,7 +8033,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)))
> @@ -8045,7 +8044,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)))
> @@ -8055,29 +8054,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:
> @@ -8088,7 +8085,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:
> @@ -8103,7 +8100,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:
> @@ -8112,7 +8109,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:
> @@ -8127,7 +8124,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:
> @@ -8144,7 +8141,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:
> @@ -8152,7 +8149,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:
> @@ -8160,7 +8157,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:
>          {
> @@ -8258,13 +8255,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:
>          {
> @@ -8275,7 +8272,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:
> @@ -8283,7 +8280,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:
> @@ -8291,7 +8288,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:
> @@ -8299,7 +8296,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:
> @@ -8310,19 +8307,16 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          goto unimplemented;
>  #endif
>      case TARGET_NR_lseek:
> -        ret = get_errno(lseek(arg1, arg2, arg3));
> -        break;
> +        return get_errno(lseek(arg1, arg2, arg3));
>  #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:
>          {
> @@ -8378,14 +8372,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:
> @@ -8393,16 +8387,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:
> @@ -8413,8 +8405,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:
> @@ -8436,7 +8427,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:
> @@ -8456,7 +8447,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:
> @@ -8476,7 +8467,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:
> @@ -8492,7 +8483,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:
> @@ -8500,12 +8491,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:
> @@ -8513,16 +8503,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:
>          {
> @@ -8536,7 +8523,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:
> @@ -8551,7 +8538,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:
> @@ -8567,7 +8554,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:
> @@ -8575,7 +8562,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:
> @@ -8583,7 +8570,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:
> @@ -8591,24 +8578,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:
>          {
> @@ -8627,7 +8612,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;
> @@ -8645,34 +8630,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;
> @@ -8682,14 +8664,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;
> @@ -8700,7 +8681,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:
> @@ -8715,22 +8696,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:
>          {
> @@ -8814,7 +8792,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              }
>  #endif
>          }
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_rt_sigaction:
>          {
> @@ -8831,8 +8809,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))
> @@ -8864,8 +8841,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)) {
> @@ -8892,7 +8868,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:
>          {
> @@ -8904,7 +8880,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:
> @@ -8918,7 +8894,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:
> @@ -8988,7 +8964,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>              }
>  #endif
>          }
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_rt_sigprocmask:
>          {
> @@ -8996,8 +8972,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) {
> @@ -9032,7 +9007,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:
>          {
> @@ -9045,7 +9020,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:
>          {
> @@ -9057,8 +9032,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));
> @@ -9069,7 +9043,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:
>          {
> @@ -9089,15 +9063,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;
> @@ -9109,7 +9082,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;
> @@ -9117,8 +9090,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)))
> @@ -9146,7 +9118,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;
> @@ -9159,7 +9131,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;
> @@ -9172,7 +9144,7 @@ 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()) {
> @@ -9180,21 +9152,20 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          } else {
>              ret = do_sigreturn(cpu_env);
>          }
> -        break;
> +        return ret;
>  #endif
>      case TARGET_NR_rt_sigreturn:
>          if (block_signals()) {
> -            ret = -TARGET_ERESTARTSYS;
> +            return -TARGET_ERESTARTSYS;
>          } else {

Easier to read removing the else clause.

> -            ret = do_rt_sigreturn(cpu_env);
> +            return do_rt_sigreturn(cpu_env);
>          }
> -        break;
>      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;
>      case TARGET_NR_setrlimit:
>          {
>              int resource = target_to_host_resource(arg1);
> @@ -9205,9 +9176,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;

Also easier to read "return ret;" here but this 'll get cleaned later.

>      case TARGET_NR_getrlimit:
>          {
>              int resource = target_to_host_resource(arg1);
> @@ -9223,7 +9193,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user_struct(target_rlim, arg2, 1);
>              }
>          }
> -        break;
> +        return ret;
>      case TARGET_NR_getrusage:
>          {
>              struct rusage rusage;
> @@ -9232,7 +9202,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;
> @@ -9242,7 +9212,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;
> @@ -9262,9 +9232,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;

Ditto.

>  #if defined(TARGET_NR_select)
>      case TARGET_NR_select:
>  #if defined(TARGET_WANT_NI_OLD_SELECT)
> @@ -9277,7 +9246,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:
> @@ -9381,7 +9350,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:
> @@ -9396,7 +9365,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:
> @@ -9411,7 +9380,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:
> @@ -9447,7 +9416,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:
> @@ -9468,7 +9437,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:
> @@ -9480,7 +9449,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) {
> @@ -9494,7 +9463,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;
> @@ -9527,22 +9496,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;
> @@ -9555,58 +9522,49 @@ 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
>      case TARGET_NR_truncate:
>          if (!(p = lock_user_string(arg1)))
>              goto efault;
>          ret = get_errno(truncate(p, arg2));
>          unlock_user(p, arg1, 0);
> -        break;
> +        return ret;
>      case TARGET_NR_ftruncate:
> -        ret = get_errno(ftruncate(arg1, arg2));
> -        break;
> +        return get_errno(ftruncate(arg1, arg2));
>      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
> @@ -9614,8 +9572,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.  */
> @@ -9624,10 +9581,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;
> @@ -9662,7 +9618,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;
>      case TARGET_NR_fstatfs:
>          ret = get_errno(fstatfs(arg1, &stfs));
>          goto convert_statfs;
> @@ -9692,7 +9648,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;
> @@ -9703,91 +9659,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:
> @@ -9797,22 +9735,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:
> @@ -9828,10 +9763,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 */
> @@ -9840,9 +9772,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) {
> @@ -9852,10 +9783,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;

Oh, bug fixed?

>              }
>          }
>          break;
> @@ -9882,7 +9812,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;
> @@ -9896,7 +9826,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)))
> @@ -9941,7 +9871,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  unlock_user_struct(target_st, arg2, 1);
>              }
>          }
> -        break;
> +        return ret;
>  #ifdef TARGET_NR_olduname
>      case TARGET_NR_olduname:
>          goto unimplemented;
> @@ -9951,17 +9881,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:
>          {
> @@ -9989,14 +9917,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:
>          {
> @@ -10024,70 +9952,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
> @@ -10104,7 +10019,7 @@ 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:
> @@ -10112,15 +10027,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          _mcleanup();
>  #endif
>          gdb_exit(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 */
>          {
> @@ -10142,17 +10056,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:
> @@ -10169,7 +10081,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:
>          {
> @@ -10185,7 +10097,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:
> @@ -10199,11 +10111,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;
> @@ -10213,8 +10123,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;
> @@ -10237,7 +10146,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:
> @@ -10369,7 +10278,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:
> @@ -10397,12 +10306,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
> @@ -10421,8 +10329,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,
> @@ -10458,8 +10365,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);
> @@ -10481,7 +10387,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  if (arg4) {
>                      unlock_user(target_set, arg4, 0);
>                  }
> -                break;
> +                return ret;
>              }
>  # endif
>  # ifdef TARGET_NR_poll
> @@ -10498,8 +10404,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                      /* -ve poll() timeout means "infinite" */
>                      pts = NULL;
>                  }
> -                ret = get_errno(safe_ppoll(pfd, nfds, pts, NULL, 0));
> -                break;
> +                return get_errno(safe_ppoll(pfd, nfds, pts, NULL, 0));
>              }
>  # endif
>              default:
> @@ -10513,13 +10418,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);
> @@ -10530,7 +10434,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);
> @@ -10541,7 +10445,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:
>          {
> @@ -10556,7 +10460,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:
> @@ -10572,22 +10476,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:
>          {
> @@ -10599,8 +10500,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);
>  
> @@ -10619,8 +10519,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;
>                  }
> @@ -10630,7 +10529,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;
> @@ -10641,20 +10540,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;

Ditto (and so on) "return ret;" improved later in this series.

>      case TARGET_NR_getcpu:
>          {
>              unsigned cpu, node;
> @@ -10671,7 +10568,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;
> @@ -10684,9 +10581,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;
> @@ -10703,7 +10599,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;
> @@ -10715,21 +10611,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;
> @@ -10738,7 +10629,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;
> @@ -10748,7 +10639,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;
> @@ -10767,7 +10658,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:
> @@ -10779,7 +10670,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:
>          {
> @@ -10790,7 +10681,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
> @@ -10811,32 +10702,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
> @@ -10851,7 +10739,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;
> @@ -10861,14 +10749,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:
>      {
> @@ -10937,11 +10825,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
>      case TARGET_NR_sendfile:
> @@ -10951,7 +10839,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;
>          }
> @@ -10962,7 +10850,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = ret2;
>              }
>          }
> -        break;
> +        return ret;
>      }
>  #ifdef TARGET_NR_sendfile64
>      case TARGET_NR_sendfile64:
> @@ -10972,7 +10860,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;
>          }
> @@ -10983,7 +10871,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = ret2;
>              }
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  #else
> @@ -11004,10 +10892,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:
> @@ -11023,7 +10910,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;

Here we go!

>      }
>  #endif
>  #ifdef TARGET_NR_truncate64
> @@ -11032,12 +10919,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:
> @@ -11047,7 +10933,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:
> @@ -11057,14 +10943,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
> @@ -11078,7 +10964,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:
> @@ -11086,34 +10972,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;
> @@ -11124,7 +11004,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)
> @@ -11134,7 +11014,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;
> @@ -11153,12 +11033,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))) 
> @@ -11166,14 +11044,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:
> @@ -11187,14 +11064,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:
> @@ -11208,7 +11084,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:
> @@ -11216,20 +11092,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:
> @@ -11237,12 +11109,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)
> @@ -11253,8 +11124,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 */
> @@ -11264,8 +11134,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 */
> @@ -11303,7 +11172,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 */
> @@ -11394,7 +11263,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.  */
> @@ -11426,33 +11295,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:
> @@ -11465,7 +11329,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) {
> @@ -11477,7 +11341,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:
> @@ -11496,19 +11360,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:
> @@ -11522,12 +11383,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:
> @@ -11541,7 +11401,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:
> @@ -11549,27 +11409,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:
> @@ -11593,7 +11449,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:
> @@ -11605,8 +11461,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
> @@ -11632,11 +11487,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
> @@ -11649,10 +11502,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 */
> @@ -11672,8 +11523,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 */
>  
> @@ -11683,8 +11533,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:
> @@ -11703,8 +11552,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) {
> @@ -11731,14 +11579,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:
> @@ -11746,12 +11593,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
> @@ -11764,7 +11609,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
> @@ -11775,8 +11620,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);
> @@ -11791,7 +11635,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:
>      {
> @@ -11799,13 +11643,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:
> @@ -11814,8 +11657,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);
> @@ -11833,15 +11675,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);
> @@ -11853,7 +11694,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:
>          {
> @@ -11861,8 +11702,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);
> @@ -11880,15 +11720,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);
> @@ -11900,7 +11739,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:
>          {
> @@ -11919,7 +11758,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;
> @@ -11931,15 +11770,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;
> @@ -11947,16 +11785,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;
> @@ -11965,13 +11801,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;
> @@ -11991,7 +11825,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
> @@ -12002,7 +11836,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
> @@ -12013,7 +11847,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
> @@ -12033,24 +11867,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:
> @@ -12092,18 +11923,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)
> @@ -12113,7 +11943,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)
> @@ -12121,12 +11951,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)
> @@ -12151,17 +11980,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:
>          {
> @@ -12177,7 +12005,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:
>          {
> @@ -12198,7 +12026,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: */
> @@ -12219,7 +12047,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
> @@ -12228,7 +12056,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:
> @@ -12259,7 +12087,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:
> @@ -12272,7 +12100,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
> @@ -12282,7 +12110,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:
> @@ -12298,7 +12126,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  */
> @@ -12310,7 +12138,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)
> @@ -12326,7 +12154,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:
> @@ -12337,29 +12165,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:
> @@ -12380,8 +12204,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
>  
> @@ -12400,8 +12223,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,
> @@ -12413,8 +12235,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) {
> @@ -12444,7 +12265,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  
>              ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
>                                               set, SIGSET_T_SIZE));
> -            break;
>          }
>  #endif
>  #if defined(TARGET_NR_epoll_wait)
> @@ -12468,7 +12288,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
> @@ -12498,7 +12318,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
> @@ -12511,7 +12331,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
> @@ -12532,17 +12352,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
> @@ -12564,7 +12381,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;
>                  }
>              }
>  
> @@ -12577,7 +12394,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  }
>              }
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  
> @@ -12605,7 +12422,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  goto efault;
>              }
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  
> @@ -12628,7 +12445,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  ret = -TARGET_EFAULT;
>              }
>          }
> -        break;
> +        return ret;
>      }
>  #endif
>  
> @@ -12645,7 +12462,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
>  
> @@ -12662,15 +12479,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)
> @@ -12684,7 +12500,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)
> @@ -12707,35 +12523,30 @@ 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
>  
>      default:
> @@ -12744,8 +12555,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;
> 

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

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

* Re: [Qemu-devel] [PATCH v3 08/19] linux-user: Propagate goto efault to return
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 08/19] linux-user: Propagate goto efault to return Richard Henderson
@ 2018-06-12 16:27   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 39+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-06-12 16:27 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, laurent

On 06/11/2018 09:51 PM, Richard Henderson wrote:
> 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 efe882612b..a6b8268332 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8009,7 +8009,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)) {
> @@ -8020,7 +8020,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);
> @@ -8038,7 +8038,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));
> @@ -8048,7 +8048,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));
> @@ -8083,7 +8083,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
> @@ -8095,7 +8095,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));
>              }
> @@ -8105,7 +8105,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);
> @@ -8131,7 +8131,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)
> @@ -8146,7 +8146,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;
> @@ -8154,7 +8154,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;
> @@ -8174,7 +8174,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++;
> @@ -8183,7 +8183,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++;
> @@ -8258,7 +8258,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;
> @@ -8270,14 +8270,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;
> @@ -8285,7 +8285,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;
> @@ -8293,7 +8293,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;
> @@ -8326,7 +8326,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;
> @@ -8337,7 +8337,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) {
> @@ -8347,7 +8347,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;
> @@ -8376,7 +8376,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;
> @@ -8386,7 +8386,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
> @@ -8414,7 +8414,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);
> @@ -8423,7 +8423,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);
>          }
> @@ -8437,13 +8437,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);
>          }
> @@ -8457,13 +8457,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);
>          }
> @@ -8479,16 +8480,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;
> @@ -8559,7 +8562,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;
> @@ -8567,7 +8570,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;
> @@ -8575,7 +8578,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;
> @@ -8603,7 +8606,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));
> @@ -8625,8 +8628,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);
>          }
> @@ -8634,7 +8638,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;
> @@ -8667,7 +8671,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;
> @@ -8717,7 +8721,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;
> @@ -8728,7 +8732,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;
> @@ -8739,7 +8743,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;
> @@ -8753,7 +8757,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];
> @@ -8767,7 +8771,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;
> @@ -8783,7 +8787,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;
> @@ -8813,7 +8817,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;
> @@ -8824,7 +8828,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;
> @@ -8845,7 +8849,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;
> @@ -8947,7 +8951,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;
> @@ -8958,7 +8962,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));
>              }
> @@ -8991,7 +8995,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;
> @@ -9002,7 +9006,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));
>              }
> @@ -9015,7 +9019,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));
>              }
> @@ -9038,7 +9042,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));
>              }
> @@ -9053,7 +9057,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
> @@ -9073,7 +9077,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,
> @@ -9094,7 +9098,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) {
> @@ -9110,7 +9114,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));
> @@ -9125,7 +9129,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);
> @@ -9138,7 +9142,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);
> @@ -9162,7 +9166,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          }
>      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;
> @@ -9172,7 +9176,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);
> @@ -9187,7 +9191,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);
> @@ -9209,7 +9213,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;
> @@ -9220,14 +9224,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;
>              }
> @@ -9294,7 +9298,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 {
> @@ -9308,7 +9312,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]);
> @@ -9324,7 +9328,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);
> @@ -9340,14 +9344,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;
> @@ -9446,7 +9450,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;
> @@ -9456,7 +9460,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);
> @@ -9478,7 +9482,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]);
> @@ -9550,7 +9554,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  #endif
>      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;
> @@ -9561,7 +9565,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;
> @@ -9589,8 +9593,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          goto unimplemented;
>  #endif
>      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:
> @@ -9598,7 +9603,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);
> @@ -9624,8 +9629,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>          goto convert_statfs;
>  #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:
> @@ -9633,7 +9639,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);
> @@ -9731,7 +9737,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);
> @@ -9799,7 +9805,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;
>              }
> @@ -9809,7 +9815,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;
> @@ -9823,22 +9829,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;
> @@ -9853,7 +9861,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);
> @@ -9907,7 +9915,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);
> @@ -9921,7 +9929,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;
> @@ -9934,7 +9942,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]);
> @@ -10031,7 +10039,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;
> @@ -10041,7 +10049,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
> @@ -10072,12 +10080,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;
>                  }
>              }
>          }
> @@ -10088,12 +10096,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;
>                  }
>              }
>          }
> @@ -10143,7 +10151,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;
> @@ -10174,7 +10182,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;
> @@ -10202,7 +10210,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;
> @@ -10231,7 +10239,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)) {
> @@ -10286,7 +10294,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;
> @@ -10335,7 +10343,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);
> @@ -10356,7 +10364,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;
> @@ -10371,7 +10379,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 {
> @@ -10525,7 +10533,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;
>                  }
>              }
>          }
> @@ -10562,10 +10570,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;
> @@ -10578,7 +10586,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));
> @@ -10594,7 +10602,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);
>              }
> @@ -10608,7 +10616,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));
> @@ -10656,7 +10664,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;
>          }
> @@ -10665,7 +10673,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));
> @@ -10676,7 +10684,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));
> @@ -10736,7 +10744,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;
> @@ -10746,14 +10754,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;
> @@ -10769,7 +10777,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);
> @@ -10789,7 +10797,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) {
> @@ -10905,7 +10913,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);
> @@ -10916,7 +10924,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;
> @@ -10927,8 +10935,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))
> @@ -10937,8 +10946,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))
> @@ -10959,9 +10969,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);

Oh, another bug fixed? Is it worth a separate patch?

>          if (!is_error(ret))
>              ret = host_to_target_stat64(cpu_env, arg3, &st);
>          return ret;
> @@ -10969,7 +10981,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;
> @@ -11008,7 +11020,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));
> @@ -11040,7 +11052,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);
> @@ -11061,7 +11073,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;
> @@ -11081,7 +11093,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;
> @@ -11089,7 +11101,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;
> @@ -11106,7 +11118,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;
> @@ -11157,7 +11169,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;
> @@ -11184,7 +11196,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;
> @@ -11211,7 +11223,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);
> @@ -11380,7 +11392,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;
> @@ -11398,7 +11410,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;
> @@ -11406,7 +11418,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;
> @@ -11969,13 +11981,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);
> @@ -12065,25 +12077,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;
>                  }
>              }
>          }
> @@ -12193,7 +12205,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,
> @@ -12229,7 +12241,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);
> @@ -12301,7 +12313,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);
> @@ -12312,7 +12324,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);
> @@ -12390,7 +12402,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;
>                  }
>              }
>          }
> @@ -12414,12 +12426,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;
> @@ -12497,7 +12509,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;
> @@ -12510,7 +12522,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 {
> @@ -12520,7 +12532,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;
> @@ -12559,9 +12571,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,
> 

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

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

* Re: [Qemu-devel] [PATCH v3 09/19] linux-user: Propagate goto unimplemented_nowarn to return
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 09/19] linux-user: Propagate goto unimplemented_nowarn " Richard Henderson
@ 2018-06-12 16:28   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 39+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-06-12 16:28 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, laurent

On 06/11/2018 09:51 PM, Richard Henderson wrote:
> Reviewed-by: Laurent Vivier <laurent@vivier.eu>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.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 a6b8268332..06205d3d65 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -11807,7 +11807,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
> @@ -11820,12 +11820,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
> @@ -11910,7 +11910,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)
> @@ -12564,9 +12564,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>      default:
>      unimplemented:
>          gemu_log("qemu: 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:
> 

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

* Re: [Qemu-devel] [PATCH v3 15/19] linux-user: Split out pread64, pwrite64
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 15/19] linux-user: Split out pread64, pwrite64 Richard Henderson
@ 2018-06-12 16:37   ` Philippe Mathieu-Daudé
  2018-06-12 17:44     ` Richard Henderson
  0 siblings, 1 reply; 39+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-06-12 16:37 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, laurent

Hi Richard,

On 06/11/2018 09:51 PM, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/syscall.h           | 44 +++++++++++++++++++++
>  linux-user/syscall.c           | 70 ----------------------------------
>  linux-user/syscall_file.c      | 61 +++++++++++++++++++++++++++--
>  linux-user/gen_syscall_list.py |  2 +
>  linux-user/strace.list         |  6 ---
>  5 files changed, 104 insertions(+), 79 deletions(-)
> 
> diff --git a/linux-user/syscall.h b/linux-user/syscall.h
> index 3fc49d5b65..a157e25bba 100644
> --- a/linux-user/syscall.h
> +++ b/linux-user/syscall.h
> @@ -174,6 +174,50 @@ struct iovec *lock_iovec(int type, abi_ulong target_addr,
>  void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
>                    abi_ulong count, int copy);
>  
> +/* 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
> +}
> +
>  /* Temporary declarations from syscall_foo.c back to main syscall.c.
>   * These indicate incomplete conversion.
>   */
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 381ee9c3a2..cdc9787240 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -642,38 +642,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
> @@ -6864,22 +6832,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,
> @@ -10078,28 +10030,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)))
> diff --git a/linux-user/syscall_file.c b/linux-user/syscall_file.c
> index 4cc7051847..aae9c49599 100644
> --- a/linux-user/syscall_file.c
> +++ b/linux-user/syscall_file.c
> @@ -378,15 +378,70 @@ 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;
> +}
> +
> +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;
> +}
> +
> +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.
>   */
>  #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;

Why this change? If correct, can you update the comment?
Also this seems related to your previous patch #14: "Split out preadv,
pwritev, readv, writev", not this one.

>      return def;
>  }
>  #else
> diff --git a/linux-user/gen_syscall_list.py b/linux-user/gen_syscall_list.py
> index ce6dca742c..7481d030ee 100644
> --- a/linux-user/gen_syscall_list.py
> +++ b/linux-user/gen_syscall_list.py
> @@ -27,7 +27,9 @@ import sys
>  unconditional_syscalls = [
>      "close",
>      "openat",
> +    "pread64",
>      "preadv",
> +    "pwrite64",
>      "pwritev",
>      "read",
>      "readv",
> diff --git a/linux-user/strace.list b/linux-user/strace.list
> index d5ee55ac82..d978cefa31 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
> 

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

* Re: [Qemu-devel] [PATCH v3 15/19] linux-user: Split out pread64, pwrite64
  2018-06-12 16:37   ` Philippe Mathieu-Daudé
@ 2018-06-12 17:44     ` Richard Henderson
  2018-06-12 19:02       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 39+ messages in thread
From: Richard Henderson @ 2018-06-12 17:44 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: peter.maydell, laurent

On 06/12/2018 06:37 AM, Philippe Mathieu-Daudé wrote:
>>  /* 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;
>> +    /* We have already assigned out[0-2].  */
>> +    abi_ulong lo = in[3], hi = in[4];
>> +    out[3] = ((hi << (TARGET_ABI_BITS - 1)) << 1) | lo;
> Why this change? If correct, can you update the comment?
> Also this seems related to your previous patch #14: "Split out preadv,
> pwritev, readv, writev", not this one.
> 

You're right, this hunk should be folded back into the previous patch.


r~

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

* Re: [Qemu-devel] [PATCH v3 15/19] linux-user: Split out pread64, pwrite64
  2018-06-12 17:44     ` Richard Henderson
@ 2018-06-12 19:02       ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 39+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-06-12 19:02 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, laurent

On 06/12/2018 02:44 PM, Richard Henderson wrote:
> On 06/12/2018 06:37 AM, Philippe Mathieu-Daudé wrote:
>>>  /* 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;
>>> +    /* We have already assigned out[0-2].  */
>>> +    abi_ulong lo = in[3], hi = in[4];
>>> +    out[3] = ((hi << (TARGET_ABI_BITS - 1)) << 1) | lo;
>> Why this change? If correct, can you update the comment?
>> Also this seems related to your previous patch #14: "Split out preadv,
>> pwritev, readv, writev", not this one.
>>
> 
> You're right, this hunk should be folded back into the previous patch.

So for this patch without this hunk:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

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

* Re: [Qemu-devel] [PATCH v3 10/19] linux-user: Propagate goto unimplemented to default
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 10/19] linux-user: Propagate goto unimplemented to default Richard Henderson
@ 2018-06-22 10:16   ` Peter Maydell
  0 siblings, 0 replies; 39+ messages in thread
From: Peter Maydell @ 2018-06-22 10:16 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers, Laurent Vivier

On 12 June 2018 at 01:51, Richard Henderson
<richard.henderson@linaro.org> 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.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/syscall.c | 144 +------------------------------------------
>  1 file changed, 1 insertion(+), 143 deletions(-)
>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v3 12/19] linux-user: Setup split syscall infrastructure
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 12/19] linux-user: Setup split syscall infrastructure Richard Henderson
@ 2018-06-22 10:30   ` Peter Maydell
  2018-06-22 17:32     ` Richard Henderson
  2018-08-12 20:45   ` Laurent Vivier
  1 sibling, 1 reply; 39+ messages in thread
From: Peter Maydell @ 2018-06-22 10:30 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers, Laurent Vivier

On 12 June 2018 at 01:51, Richard Henderson
<richard.henderson@linaro.org> wrote:
> Defines a unified structure for implementation and strace.
> Supplies a generator script to build the declarations and
> the lookup function.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/syscall.h           | 178 +++++++++++++++
>  linux-user/strace.c            | 386 ++++++++++++++++++++++++---------
>  linux-user/syscall.c           | 113 ++++------
>  linux-user/Makefile.objs       |  10 +
>  linux-user/gen_syscall_list.py |  82 +++++++
>  5 files changed, 595 insertions(+), 174 deletions(-)
>  create mode 100644 linux-user/syscall.h
>  create mode 100644 linux-user/gen_syscall_list.py
>
> diff --git a/linux-user/syscall.h b/linux-user/syscall.h
> new file mode 100644
> index 0000000000..7eb078c3e5
> --- /dev/null
> +++ b/linux-user/syscall.h
> @@ -0,0 +1,178 @@
> +/*
> + *  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

"demultiplexed"

> + * 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;

Are all these hook functions mandatory, or can a syscall
implementation leave some of them NULL for a default behaviour?

> +    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, ...) \
> +    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, ...) \
> +    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 bd897a3f20..6375feb747 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));
> +}

All this refactoring of the strace functions feels like it
should have been in a separate patch...

>
> -    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));
> -        }


> @@ -12412,12 +12353,18 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>      return ret;
>  }
>
> +/* Include the generated syscall lookup function.  */
> +#include "syscall_list.inc.c"
> +
>  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
> @@ -12437,16 +12384,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;
>  }
> diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
> index 59a5c17354..afa69ed6d2 100644
> --- a/linux-user/Makefile.objs
> +++ b/linux-user/Makefile.objs
> @@ -7,3 +7,13 @@ obj-$(TARGET_HAS_BFLT) += flatload.o
>  obj-$(TARGET_I386) += vm86.o
>  obj-$(TARGET_ARM) += arm/nwfpe/
>  obj-$(TARGET_M68K) += m68k-sim.o
> +
> +GEN_SYSCALL_LIST = $(SRC_PATH)/linux-user/gen_syscall_list.py
> +SYSCALL_LIST = linux-user/syscall_list.h linux-user/syscall_list.inc.c
> +
> +$(SYSCALL_LIST): $(GEN_SYSCALL_LIST)
> +       $(call quiet-command,\
> +         $(PYTHON) $(GEN_SYSCALL_LIST) $@, "GEN", $(TARGET_DIR)$@)
> +
> +linux-user/syscall.o \
> +linux-user/strace.o: $(SYSCALL_LIST)
> diff --git a/linux-user/gen_syscall_list.py b/linux-user/gen_syscall_list.py
> new file mode 100644
> index 0000000000..2e0fc39100
> --- /dev/null
> +++ b/linux-user/gen_syscall_list.py
> @@ -0,0 +1,82 @@
> +#
> +# Linux syscall table generator
> +# 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/>.
> +#
> +
> +from __future__ import print_function
> +import sys
> +
> +# These are sets of all syscalls that have been converted.
> +# The lists are in collation order with '_' ignored.
> +
> +# These syscalls are supported by all targets.
> +# Avoiding ifdefs for these can diagnose typos in $cpu/syscall_nr.h
> +unconditional_syscalls = [
> +]
> +
> +# These syscalls are only supported by some target or abis.
> +conditional_syscalls = [
> +]
> +
> +
> +def header(f):
> +    # Do not ifdef the declarations -- their use may be complicated.
> +    all = unconditional_syscalls + conditional_syscalls
> +    all.sort()
> +    for s in all:
> +        print("extern const SyscallDef def_", s, ";", sep = '', file = f)
> +
> +
> +def def_syscall(s, f):
> +    print("    case TARGET_NR_", s, ": return &def_", s, ";",
> +          sep = '', file = f);
> +
> +
> +def source(f):
> +    print("static const SyscallDef *syscall_table(int num)",
> +          "{",
> +          "    switch (num) {",
> +          sep = '\n', file = f)
> +
> +    for s in unconditional_syscalls:
> +        def_syscall(s, f)
> +    for s in conditional_syscalls:
> +        print("#ifdef TARGET_NR_", s, sep = '', file = f)
> +        def_syscall(s, f)
> +        print("#endif", file = f)
> +
> +    print("    }",
> +          "    return NULL;",
> +          "}",
> +          sep = '\n', file = f);
> +
> +
> +def main():
> +    p = sys.argv[1]
> +    f = open(p, "w")
> +
> +    print("/* This file is autogenerated by gensyscall.py.  */\n\n",
> +          file = f)
> +
> +    if p[len(p) - 1] == 'h':
> +        header(f)
> +    else:
> +        source(f)
> +
> +    f.close();
> +
> +
> +main()

Codegen looks good to me.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v3 13/19] linux-user: Split out close, open, openat, read, write
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 13/19] linux-user: Split out close, open, openat, read, write Richard Henderson
@ 2018-06-22 10:38   ` Peter Maydell
  2018-06-22 17:39     ` Richard Henderson
  0 siblings, 1 reply; 39+ messages in thread
From: Peter Maydell @ 2018-06-22 10:38 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers, Laurent Vivier

On 12 June 2018 at 01:51, Richard Henderson
<richard.henderson@linaro.org> wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/syscall.h           |  51 ++++
>  linux-user/strace.c            |  35 ---
>  linux-user/syscall.c           | 402 +------------------------------
>  linux-user/syscall_file.c      | 423 +++++++++++++++++++++++++++++++++
>  linux-user/Makefile.objs       |   3 +-
>  linux-user/gen_syscall_list.py |   5 +
>  linux-user/strace.list         |  15 --
>  7 files changed, 484 insertions(+), 450 deletions(-)
>  create mode 100644 linux-user/syscall_file.c

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

> +SYSCALL_IMPL(close)
> +{
> +    fd_trans_unregister(arg1);
> +    return get_errno(close(arg1));
> +}
> +SYSCALL_DEF(close, ARG_DEC);

If in future we wanted to extend the set of information
we had for each syscall in the SyscallDef struct, I guess
we'd add parameters to the SYSCALL_DEF macro (or have
more variant macros)? I can't offhand think of something I'd
want to use that for, so it's a bit of an abstract question
for the moment.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall
  2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
                   ` (20 preceding siblings ...)
  2018-06-12 11:00 ` Laurent Vivier
@ 2018-06-22 10:40 ` Peter Maydell
  21 siblings, 0 replies; 39+ messages in thread
From: Peter Maydell @ 2018-06-22 10:40 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers, Laurent Vivier

On 12 June 2018 at 01:51, Richard Henderson
<richard.henderson@linaro.org> wrote:
> Version 3 does not attempt the whole thing in one go,
> and does attempt to incorporate strace into the reorg.
>
> Thoughts?

This approach works for me. I won't bother to review the
rest of the patchset for the moment, until Laurent weighs
in on whether he likes the structure or not...

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH v3 12/19] linux-user: Setup split syscall infrastructure
  2018-06-22 10:30   ` Peter Maydell
@ 2018-06-22 17:32     ` Richard Henderson
  0 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-22 17:32 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Laurent Vivier

On 06/22/2018 03:30 AM, Peter Maydell wrote:
>> +struct SyscallDef {
>> +    const char *name;
>> +    SyscallArgsFn *args;
>> +    SyscallImplFn *impl;
>> +    SyscallPrintFn *print;
>> +    SyscallPrintRetFn *print_ret;
> 
> Are all these hook functions mandatory, or can a syscall
> implementation leave some of them NULL for a default behaviour?

Only impl is mandatory.  You're right that there should be more doco here at
the structure definition.  Here, the docs got split down to the macros that
define the most common forms of the structures.  Will fix.


>>  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));
>> +}
> 
> All this refactoring of the strace functions feels like it
> should have been in a separate patch...

Fair.


r~

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

* Re: [Qemu-devel] [PATCH v3 13/19] linux-user: Split out close, open, openat, read, write
  2018-06-22 10:38   ` Peter Maydell
@ 2018-06-22 17:39     ` Richard Henderson
  0 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-06-22 17:39 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Laurent Vivier

On 06/22/2018 03:38 AM, Peter Maydell wrote:
>> +SYSCALL_IMPL(close)
>> +{
>> +    fd_trans_unregister(arg1);
>> +    return get_errno(close(arg1));
>> +}
>> +SYSCALL_DEF(close, ARG_DEC);
> 
> If in future we wanted to extend the set of information
> we had for each syscall in the SyscallDef struct, I guess
> we'd add parameters to the SYSCALL_DEF macro (or have
> more variant macros)? I can't offhand think of something I'd
> want to use that for, so it's a bit of an abstract question
> for the moment.

Yes, I imagine we'd extend the SYSCALL_DEF macro(s) in that case.

Another thought I've had is to define variant SYSCALL_IMPL<N> macros that would
allow us to put names to arguments, and help make the implementations clearer.
E.g.

SYSCALL_IMPL1(close, fd)
{
    fd_trans_unregister(fd);
    return get_errno(close(fd));
}


r~

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

* Re: [Qemu-devel] [PATCH v3 07/19] linux-user: Relax single exit from "break"
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 07/19] linux-user: Relax single exit from "break" Richard Henderson
  2018-06-12 16:23   ` Philippe Mathieu-Daudé
@ 2018-08-11 21:50   ` Laurent Vivier
  1 sibling, 0 replies; 39+ messages in thread
From: Laurent Vivier @ 2018-08-11 21:50 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell

Le 12/06/2018 à 02:51, Richard Henderson a écrit :
> 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 | 970 +++++++++++++++++--------------------------
>  1 file changed, 390 insertions(+), 580 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index ec3bc1cbe5..efe882612b 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
...
> @@ -10481,7 +10387,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                  if (arg4) {
>                      unlock_user(target_set, arg4, 0);
>                  }
> -                break;
> +                return ret;
>              }
>  # endif
>  # ifdef TARGET_NR_poll
> @@ -10498,8 +10404,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>                      /* -ve poll() timeout means "infinite" */
>                      pts = NULL;
>                  }
> -                ret = get_errno(safe_ppoll(pfd, nfds, pts, NULL, 0));
> -                break;
> +                return get_errno(safe_ppoll(pfd, nfds, pts, NULL, 0));
>              }
>  # endif
>              default:

You can't change these breaks by returns because they are in an inner
switch() (see the "default:"), that is followed by:

    if (!is_error(ret)) {
        for(i = 0; i < nfds; i++) {
            target_pfd[i].revents = tswap16(pfd[i].revents);
        }
        }
    unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);

which are needed to copy the result to the target array.
...
> @@ -12444,7 +12265,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
>  
>              ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
>                                               set, SIGSET_T_SIZE));
> -            break;

You can't remove this break because otherwise it falls through the
following case (and you can't put a return because it's in an inner
switch())
>          }
>  #endif
>  #if defined(TARGET_NR_epoll_wait)
> @@ -12468,7 +12288,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

Thanks,
Laurent

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

* Re: [Qemu-devel] [PATCH v3 19/19] linux-user: Split out some process syscalls
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 19/19] linux-user: Split out some process syscalls Richard Henderson
@ 2018-08-11 22:48   ` Laurent Vivier
  0 siblings, 0 replies; 39+ messages in thread
From: Laurent Vivier @ 2018-08-11 22:48 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell

Le 12/06/2018 à 02:51, Richard Henderson a écrit :
> 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           | 108 ++++
>  linux-user/strace.c            |  36 +-
>  linux-user/syscall.c           | 799 ----------------------------
>  linux-user/syscall_proc.c      | 914 +++++++++++++++++++++++++++++++++
>  linux-user/Makefile.objs       |   5 +-
>  linux-user/gen_syscall_list.py |  43 ++
>  linux-user/strace.list         | 144 ------
>  7 files changed, 1072 insertions(+), 977 deletions(-)
>  create mode 100644 linux-user/syscall_proc.c
> 
...
> diff --git a/linux-user/gen_syscall_list.py b/linux-user/gen_syscall_list.py
> index 4eb83ae9ce..9c28221bdd 100644
> --- a/linux-user/gen_syscall_list.py
> +++ b/linux-user/gen_syscall_list.py
...
> @@ -43,12 +46,38 @@ unconditional_syscalls = [
>      "pwritev",
>      "read",
>      "readv",
> +    "setfsgid",
> +    "setfsuid",
> +    "setgid",
> +    "setgroups",
> +    "setsid",
> +    "setuid",
>      "write",
>      "writev",
>  ]
>  
>  # These syscalls are only supported by some target or abis.
>  conditional_syscalls = [
> +    "fork",
> +    "getegid",
> +    "getegid32",
> +    "geteuid",
> +    "geteuid32",
> +    "getgid",
> +    "getgid32",
> +    "getgroups32",
> +    "getpgrp",
> +    "getpid",
> +    "getppid",
> +    "getresgid",
> +    "getresgid32",
> +    "getresuid",
> +    "getresuid32",
> +    "getuid",
> +    "getuid32",
> +    "getxgid",
> +    "getxpid",
> +    "getxuid",
>      "ipc",
>      "mmap",
>      "mmap2"> @@ -60,10 +89,24 @@ conditional_syscalls = [
>      "semctl",
>      "semget",
>      "semop",
> +    "setfsgid32",
> +    "setfsuid32",
> +    "setgid32",
> +    "setgroups32",
> +    "setregid",
> +    "setregid32",
> +    "setresgid",
> +    "setresgid32",
> +    "setresuid",
> +    "setresuid32",
> +    "setreuid",
> +    "setreuid32",
> +    "setuid32",
>      "shmat",
>      "shmctl",
>      "shmdt",
>      "shmget",
> +    "vfork",
>  ]

At least the following syscalls are missing in the list:

get_thread_area, set_thread_area, set_tid_address, ...

Thanks,
Laurent

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

* Re: [Qemu-devel] [PATCH v3 12/19] linux-user: Setup split syscall infrastructure
  2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 12/19] linux-user: Setup split syscall infrastructure Richard Henderson
  2018-06-22 10:30   ` Peter Maydell
@ 2018-08-12 20:45   ` Laurent Vivier
  2018-08-13  0:09     ` Richard Henderson
  1 sibling, 1 reply; 39+ messages in thread
From: Laurent Vivier @ 2018-08-12 20:45 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell

Le 12/06/2018 à 02:51, Richard Henderson a écrit :
> Defines a unified structure for implementation and strace.
> Supplies a generator script to build the declarations and
> the lookup function.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/syscall.h           | 178 +++++++++++++++
>  linux-user/strace.c            | 386 ++++++++++++++++++++++++---------
>  linux-user/syscall.c           | 113 ++++------
>  linux-user/Makefile.objs       |  10 +
>  linux-user/gen_syscall_list.py |  82 +++++++
>  5 files changed, 595 insertions(+), 174 deletions(-)
>  create mode 100644 linux-user/syscall.h
>  create mode 100644 linux-user/gen_syscall_list.py
...
> diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
> index 59a5c17354..afa69ed6d2 100644
> --- a/linux-user/Makefile.objs
> +++ b/linux-user/Makefile.objs
> @@ -7,3 +7,13 @@ obj-$(TARGET_HAS_BFLT) += flatload.o
>  obj-$(TARGET_I386) += vm86.o
>  obj-$(TARGET_ARM) += arm/nwfpe/
>  obj-$(TARGET_M68K) += m68k-sim.o
> +
> +GEN_SYSCALL_LIST = $(SRC_PATH)/linux-user/gen_syscall_list.py
> +SYSCALL_LIST = linux-user/syscall_list.h linux-user/syscall_list.inc.c
> +
> +$(SYSCALL_LIST): $(GEN_SYSCALL_LIST)
> +	$(call quiet-command,\
> +	  $(PYTHON) $(GEN_SYSCALL_LIST) $@, "GEN", $(TARGET_DIR)$@)
> +
> +linux-user/syscall.o \
> +linux-user/strace.o: $(SYSCALL_LIST)
> diff --git a/linux-user/gen_syscall_list.py b/linux-user/gen_syscall_list.py
> new file mode 100644
> index 0000000000..2e0fc39100
> --- /dev/null
> +++ b/linux-user/gen_syscall_list.py
> @@ -0,0 +1,82 @@
> +#
> +# Linux syscall table generator
> +# 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/>.
> +#
> +
> +from __future__ import print_function
> +import sys
> +
> +# These are sets of all syscalls that have been converted.
> +# The lists are in collation order with '_' ignored.
> +
> +# These syscalls are supported by all targets.
> +# Avoiding ifdefs for these can diagnose typos in $cpu/syscall_nr.h
> +unconditional_syscalls = [
> +]
> +
> +# These syscalls are only supported by some target or abis.
> +conditional_syscalls = [
> +]
> +
> +
> +def header(f):
> +    # Do not ifdef the declarations -- their use may be complicated.
> +    all = unconditional_syscalls + conditional_syscalls
> +    all.sort()
> +    for s in all:
> +        print("extern const SyscallDef def_", s, ";", sep = '', file = f)
> +
> +
> +def def_syscall(s, f):
> +    print("    case TARGET_NR_", s, ": return &def_", s, ";",
> +          sep = '', file = f);
> +
> +
> +def source(f):
> +    print("static const SyscallDef *syscall_table(int num)",
> +          "{",
> +          "    switch (num) {",
> +          sep = '\n', file = f)
> +
> +    for s in unconditional_syscalls:
> +        def_syscall(s, f)
> +    for s in conditional_syscalls:
> +        print("#ifdef TARGET_NR_", s, sep = '', file = f)
> +        def_syscall(s, f)
> +        print("#endif", file = f)
> +
> +    print("    }",
> +          "    return NULL;",
> +          "}",
> +          sep = '\n', file = f);
> +
> +
> +def main():
> +    p = sys.argv[1]
> +    f = open(p, "w")
> +
> +    print("/* This file is autogenerated by gensyscall.py.  */\n\n",
> +          file = f)
> +
> +    if p[len(p) - 1] == 'h':
> +        header(f)
> +    else:
> +        source(f)
> +
> +    f.close();
> +
> +
> +main()
> 

As we can see in patch 19/19 it's easy to forget to update the syscalls
lists.

Should it be possible to generate syscalls switch from the macro we
already have?

Something like (it should not be as simple as this but...):

#define SYSCALL_DEF(NAME, ...) \
    case TARGET_NR_##NAME: return @def_##NAME

static const SyscallDef *syscall_table(int num)
{
    switch (num) {
#include "syscall_file.def"
#include "syscall_ipc.def"
#include "syscall_mem.def"
#include "syscall_proc.def"
    }
    return NULL;
}

and in syscall_proc.def:

...
SYSCALL_DEF(clone)
#ifdef TARGET_NR_fork
SYSCALL_DEF(fork);
#endif
#ifdef TARGET_NR_vfork
SYSCALL_DEF(vfork);
#endif
...
SYSCALL_DEF(set_tid_address, ARG_PTR);

and in syscall_proc.c:
...
SYSCALL_IMPL(set_tid_address)
{
    return get_errno(set_tid_address((int *)g2h(arg1)));
}
#include "syscall_proc.def".

So compiler will detect any unused references (if SYSCALL_DEF doesn't
match SYSCALL_IMPL), the syscall_table has automatically all implemented
syscalls, it automatically manage conditional/unconditional syscalls and
we don't need generated files per target.

Thanks,
Laurent

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

* Re: [Qemu-devel] [PATCH v3 12/19] linux-user: Setup split syscall infrastructure
  2018-08-12 20:45   ` Laurent Vivier
@ 2018-08-13  0:09     ` Richard Henderson
  0 siblings, 0 replies; 39+ messages in thread
From: Richard Henderson @ 2018-08-13  0:09 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: peter.maydell

On 08/12/2018 01:45 PM, Laurent Vivier wrote:
> Le 12/06/2018 à 02:51, Richard Henderson a écrit :
>> Defines a unified structure for implementation and strace.
>> Supplies a generator script to build the declarations and
>> the lookup function.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>  linux-user/syscall.h           | 178 +++++++++++++++
>>  linux-user/strace.c            | 386 ++++++++++++++++++++++++---------
>>  linux-user/syscall.c           | 113 ++++------
>>  linux-user/Makefile.objs       |  10 +
>>  linux-user/gen_syscall_list.py |  82 +++++++
>>  5 files changed, 595 insertions(+), 174 deletions(-)
>>  create mode 100644 linux-user/syscall.h
>>  create mode 100644 linux-user/gen_syscall_list.py
> ...
>> diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
>> index 59a5c17354..afa69ed6d2 100644
>> --- a/linux-user/Makefile.objs
>> +++ b/linux-user/Makefile.objs
>> @@ -7,3 +7,13 @@ obj-$(TARGET_HAS_BFLT) += flatload.o
>>  obj-$(TARGET_I386) += vm86.o
>>  obj-$(TARGET_ARM) += arm/nwfpe/
>>  obj-$(TARGET_M68K) += m68k-sim.o
>> +
>> +GEN_SYSCALL_LIST = $(SRC_PATH)/linux-user/gen_syscall_list.py
>> +SYSCALL_LIST = linux-user/syscall_list.h linux-user/syscall_list.inc.c
>> +
>> +$(SYSCALL_LIST): $(GEN_SYSCALL_LIST)
>> +	$(call quiet-command,\
>> +	  $(PYTHON) $(GEN_SYSCALL_LIST) $@, "GEN", $(TARGET_DIR)$@)
>> +
>> +linux-user/syscall.o \
>> +linux-user/strace.o: $(SYSCALL_LIST)
>> diff --git a/linux-user/gen_syscall_list.py b/linux-user/gen_syscall_list.py
>> new file mode 100644
>> index 0000000000..2e0fc39100
>> --- /dev/null
>> +++ b/linux-user/gen_syscall_list.py
>> @@ -0,0 +1,82 @@
>> +#
>> +# Linux syscall table generator
>> +# 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/>.
>> +#
>> +
>> +from __future__ import print_function
>> +import sys
>> +
>> +# These are sets of all syscalls that have been converted.
>> +# The lists are in collation order with '_' ignored.
>> +
>> +# These syscalls are supported by all targets.
>> +# Avoiding ifdefs for these can diagnose typos in $cpu/syscall_nr.h
>> +unconditional_syscalls = [
>> +]
>> +
>> +# These syscalls are only supported by some target or abis.
>> +conditional_syscalls = [
>> +]
>> +
>> +
>> +def header(f):
>> +    # Do not ifdef the declarations -- their use may be complicated.
>> +    all = unconditional_syscalls + conditional_syscalls
>> +    all.sort()
>> +    for s in all:
>> +        print("extern const SyscallDef def_", s, ";", sep = '', file = f)
>> +
>> +
>> +def def_syscall(s, f):
>> +    print("    case TARGET_NR_", s, ": return &def_", s, ";",
>> +          sep = '', file = f);
>> +
>> +
>> +def source(f):
>> +    print("static const SyscallDef *syscall_table(int num)",
>> +          "{",
>> +          "    switch (num) {",
>> +          sep = '\n', file = f)
>> +
>> +    for s in unconditional_syscalls:
>> +        def_syscall(s, f)
>> +    for s in conditional_syscalls:
>> +        print("#ifdef TARGET_NR_", s, sep = '', file = f)
>> +        def_syscall(s, f)
>> +        print("#endif", file = f)
>> +
>> +    print("    }",
>> +          "    return NULL;",
>> +          "}",
>> +          sep = '\n', file = f);
>> +
>> +
>> +def main():
>> +    p = sys.argv[1]
>> +    f = open(p, "w")
>> +
>> +    print("/* This file is autogenerated by gensyscall.py.  */\n\n",
>> +          file = f)
>> +
>> +    if p[len(p) - 1] == 'h':
>> +        header(f)
>> +    else:
>> +        source(f)
>> +
>> +    f.close();
>> +
>> +
>> +main()
>>
> 
> As we can see in patch 19/19 it's easy to forget to update the syscalls
> lists.
> 
> Should it be possible to generate syscalls switch from the macro we
> already have?

I didn't see how, right off.

It was possible when all of the syscalls were still in the same file, as we
could get defined-but-unused warnings.  With them in different files, we don't
get that.

Perhaps there's a way that

> static const SyscallDef *syscall_table(int num)
> {
>     switch (num) {
> #include "syscall_file.def"
> #include "syscall_ipc.def"
> #include "syscall_mem.def"
> #include "syscall_proc.def"
>     }
>     return NULL;
> }
> 
> and in syscall_proc.def:

something like this achieves that, via missing-prototype warnings.

But if we have a structure like this, I wonder if we're better off with

#include "syscall_file.inc.c"
#include "syscall_ipc.inc.c"

etc and go back to the defined-but-unused warnings, which are simpler to
manage.  That lets me drop the python script entirely, much like v2.


r~

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

end of thread, other threads:[~2018-08-13  0:09 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-12  0:51 [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 01/19] linux-user/alpha: Fix epoll syscalls Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 02/19] linux-user/hppa: Fix typo in mknodat syscall Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 03/19] linux-user/microblaze: Fix typo in accept4 syscall Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 04/19] linux-user/sparc64: Add inotify_rm_watch and tee syscalls Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 05/19] linux-user: Remove DEBUG Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 06/19] linux-user: Split out do_syscall1 Richard Henderson
2018-06-12 16:11   ` Philippe Mathieu-Daudé
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 07/19] linux-user: Relax single exit from "break" Richard Henderson
2018-06-12 16:23   ` Philippe Mathieu-Daudé
2018-08-11 21:50   ` Laurent Vivier
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 08/19] linux-user: Propagate goto efault to return Richard Henderson
2018-06-12 16:27   ` Philippe Mathieu-Daudé
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 09/19] linux-user: Propagate goto unimplemented_nowarn " Richard Henderson
2018-06-12 16:28   ` Philippe Mathieu-Daudé
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 10/19] linux-user: Propagate goto unimplemented to default Richard Henderson
2018-06-22 10:16   ` Peter Maydell
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 11/19] linux-user: Propagate goto fail to return Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 12/19] linux-user: Setup split syscall infrastructure Richard Henderson
2018-06-22 10:30   ` Peter Maydell
2018-06-22 17:32     ` Richard Henderson
2018-08-12 20:45   ` Laurent Vivier
2018-08-13  0:09     ` Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 13/19] linux-user: Split out close, open, openat, read, write Richard Henderson
2018-06-22 10:38   ` Peter Maydell
2018-06-22 17:39     ` Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 14/19] linux-user: Split out preadv, pwritev, readv, writev Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 15/19] linux-user: Split out pread64, pwrite64 Richard Henderson
2018-06-12 16:37   ` Philippe Mathieu-Daudé
2018-06-12 17:44     ` Richard Henderson
2018-06-12 19:02       ` Philippe Mathieu-Daudé
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 16/19] linux-user: Split out name_to_handle_at, open_by_handle_at Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 17/19] linux-user: Split out ipc syscalls Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 18/19] linux-user: Split out memory syscalls Richard Henderson
2018-06-12  0:51 ` [Qemu-devel] [PATCH v3 19/19] linux-user: Split out some process syscalls Richard Henderson
2018-08-11 22:48   ` Laurent Vivier
2018-06-12  1:19 ` [Qemu-devel] [PATCH v3 00/19] linux-user: Split do_syscall no-reply
2018-06-12 11:00 ` Laurent Vivier
2018-06-22 10:40 ` Peter Maydell

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.