alpha-linux-user: Fix pipe return mechanism.
At the same time, tidy the code wrt MIPS and SH4 which have the
same two register return mechanism. Fix confusion between pipe
and pipe2 with an explicit flags=0, when the guest will not be
using the two register return mechanism.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 746967a..1a5e381 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -995,7 +995,8 @@
#endif
}
-static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, int flags)
+static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
+ int flags, int is_pipe2)
{
int host_pipe[2];
abi_long ret;
@@ -1003,20 +1004,25 @@
if (is_error(ret))
return get_errno(ret);
-#if defined(TARGET_MIPS)
- ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
- ret = host_pipe[0];
-#else
-#if defined(TARGET_SH4)
- if (!flags) {
+
+ /* Several targets have special calling conventions for the original
+ pipe syscall, but didn't replicate this into the pipe2 syscall. */
+ if (!is_pipe2) {
+#if defined(TARGET_ALPHA)
+ ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
+ return host_pipe[0];
+#elif defined(TARGET_MIPS)
+ ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
+ return host_pipe[0];
+#elif defined(TARGET_SH4)
((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
- ret = host_pipe[0];
- } else
+ return host_pipe[0];
#endif
+ }
+
if (put_user_s32(host_pipe[0], pipedes)
|| put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
return -TARGET_EFAULT;
-#endif
return get_errno(ret);
}
@@ -4706,11 +4712,11 @@
ret = get_errno(dup(arg1));
break;
case TARGET_NR_pipe:
- ret = do_pipe(cpu_env, arg1, 0);
+ ret = do_pipe(cpu_env, arg1, 0, 0);
break;
#ifdef TARGET_NR_pipe2
case TARGET_NR_pipe2:
- ret = do_pipe(cpu_env, arg1, arg2);
+ ret = do_pipe(cpu_env, arg1, arg2, 1);
break;
#endif
case TARGET_NR_times: