Laurent, Seems to work well for my specific case – select no longer returns EFAULT on x86_64 linux user mode, and the arguments are passed correctly.
Thank you! Cheers, Allan On 7/7/16, 7:17 PM, "Laurent Vivier" <laur...@vivier.eu> wrote: >TARGET_NR_select can have three different implementations: > > 1- to always return -ENOSYS > > microblaze, ppc, ppc64 > > -> TARGET_WANT_NI_OLD_SELECT > > 2- to take parameters from a structure pointed by arg1 > (kernel sys_old_select) > > i386, arm, m68k > > -> TARGET_WANT_OLD_SYS_SELECT > > 3- to take parameters from arg[1-5] > (kernel sys_select) > > x86_64, alpha, s390x, > cris, sparc, sparc64 > >Some (new) architectures don't define NR_select, > > 4- but only NR__newselect with sys_select: > > mips, mips64, sh > > 5- don't define NR__newselect, and use pselect6 syscall: > > aarch64, openrisc, tilegx, unicore32 > >Reported-by: Timothy Pearson <tpear...@raptorengineering.com> >Reported-by: Allan Wirth <awi...@akamai.com> >Suggested-by: Peter Maydell <peter.mayd...@linaro.org> >Signed-off-by: Laurent Vivier <laur...@vivier.eu> >--- > linux-user/arm/target_syscall.h | 2 ++ > linux-user/i386/target_syscall.h | 2 ++ > linux-user/m68k/target_syscall.h | 2 ++ > linux-user/microblaze/target_syscall.h | 2 ++ > linux-user/openrisc/syscall_nr.h | 2 -- > linux-user/ppc/target_syscall.h | 2 ++ > linux-user/sh4/syscall_nr.h | 2 +- > linux-user/syscall.c | 48 ++++++++++++++++++++++------------ > linux-user/tilegx/syscall_nr.h | 1 - > 9 files changed, 42 insertions(+), 21 deletions(-) > >diff --git a/linux-user/arm/target_syscall.h b/linux-user/arm/target_syscall.h >index 11077b7..b1073bf 100644 >--- a/linux-user/arm/target_syscall.h >+++ b/linux-user/arm/target_syscall.h >@@ -33,4 +33,6 @@ struct target_pt_regs { > #define TARGET_MLOCKALL_MCL_CURRENT 1 > #define TARGET_MLOCKALL_MCL_FUTURE 2 > >+#define TARGET_WANT_OLD_SYS_SELECT >+ > #endif /* TARGET_SYSCALL_H */ >diff --git a/linux-user/i386/target_syscall.h >b/linux-user/i386/target_syscall.h >index 0ac84dc..6678763 100644 >--- a/linux-user/i386/target_syscall.h >+++ b/linux-user/i386/target_syscall.h >@@ -154,4 +154,6 @@ struct target_vm86plus_struct { > #define TARGET_MLOCKALL_MCL_CURRENT 1 > #define TARGET_MLOCKALL_MCL_FUTURE 2 > >+#define TARGET_WANT_OLD_SYS_SELECT >+ > #endif /* TARGET_SYSCALL_H */ >diff --git a/linux-user/m68k/target_syscall.h >b/linux-user/m68k/target_syscall.h >index 97a4cc0..5e2ccf1 100644 >--- a/linux-user/m68k/target_syscall.h >+++ b/linux-user/m68k/target_syscall.h >@@ -24,6 +24,8 @@ struct target_pt_regs { > #define TARGET_MLOCKALL_MCL_CURRENT 1 > #define TARGET_MLOCKALL_MCL_FUTURE 2 > >+#define TARGET_WANT_OLD_SYS_SELECT >+ > void do_m68k_simcall(CPUM68KState *, int); > > #endif /* TARGET_SYSCALL_H */ >diff --git a/linux-user/microblaze/target_syscall.h >b/linux-user/microblaze/target_syscall.h >index 3c1ed27..65b07c2 100644 >--- a/linux-user/microblaze/target_syscall.h >+++ b/linux-user/microblaze/target_syscall.h >@@ -53,4 +53,6 @@ struct target_pt_regs { > #define TARGET_MLOCKALL_MCL_CURRENT 1 > #define TARGET_MLOCKALL_MCL_FUTURE 2 > >+#define TARGET_WANT_NI_OLD_SELECT >+ > #endif >diff --git a/linux-user/openrisc/syscall_nr.h >b/linux-user/openrisc/syscall_nr.h >index 6b1c7d2..04059d0 100644 >--- a/linux-user/openrisc/syscall_nr.h >+++ b/linux-user/openrisc/syscall_nr.h >@@ -459,8 +459,6 @@ > #define TARGET_NR_getdents 1065 > #define __ARCH_WANT_SYS_GETDENTS > #define TARGET_NR_futimesat 1066 >-#define TARGET_NR_select 1067 >-#define __ARCH_WANT_SYS_SELECT > #define TARGET_NR_poll 1068 > #define TARGET_NR_epoll_wait 1069 > #define TARGET_NR_ustat 1070 >diff --git a/linux-user/ppc/target_syscall.h b/linux-user/ppc/target_syscall.h >index 7ca83c2..6616678 100644 >--- a/linux-user/ppc/target_syscall.h >+++ b/linux-user/ppc/target_syscall.h >@@ -75,4 +75,6 @@ struct target_revectored_struct { > #define TARGET_MLOCKALL_MCL_CURRENT 0x2000 > #define TARGET_MLOCKALL_MCL_FUTURE 0x4000 > >+#define TARGET_WANT_NI_OLD_SELECT >+ > #endif /* TARGET_SYSCALL_H */ >diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h >index 5009984..e99f735 100644 >--- a/linux-user/sh4/syscall_nr.h >+++ b/linux-user/sh4/syscall_nr.h >@@ -84,7 +84,7 @@ > #define TARGET_NR_settimeofday 79 > #define TARGET_NR_getgroups 80 > #define TARGET_NR_setgroups 81 >-#define TARGET_NR_select 82 >+ /* 82 was sys_oldselect */ > #define TARGET_NR_symlink 83 > #define TARGET_NR_oldlstat 84 > #define TARGET_NR_readlink 85 >diff --git a/linux-user/syscall.c b/linux-user/syscall.c >index 37f0660..e7ec2d3 100644 >--- a/linux-user/syscall.c >+++ b/linux-user/syscall.c >@@ -1255,6 +1255,29 @@ static abi_long do_select(int n, > > return ret; > } >+ >+#if defined(TARGET_WANT_OLD_SYS_SELECT) >+static abi_long do_old_select(abi_ulong arg1) >+{ >+ struct target_sel_arg_struct *sel; >+ abi_ulong inp, outp, exp, tvp; >+ long nsel; >+ >+ if (!lock_user_struct(VERIFY_READ, sel, arg1, 1)) { >+ return -TARGET_EFAULT; >+ } >+ >+ nsel = tswapal(sel->n); >+ inp = tswapal(sel->inp); >+ outp = tswapal(sel->outp); >+ exp = tswapal(sel->exp); >+ tvp = tswapal(sel->tvp); >+ >+ unlock_user_struct(sel, arg1, 0); >+ >+ return do_select(nsel, inp, outp, exp, tvp); >+} >+#endif > #endif > > static abi_long do_pipe2(int host_pipe[], int flags) >@@ -8372,24 +8395,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long >arg1, > break; > #if defined(TARGET_NR_select) > case TARGET_NR_select: >-#if defined(TARGET_S390X) || defined(TARGET_ALPHA) >- ret = do_select(arg1, arg2, arg3, arg4, arg5); >+#if defined(TARGET_WANT_NI_OLD_SELECT) >+ /* some architectures used to have old_select here >+ * but now ENOSYS it. >+ */ >+ ret = -TARGET_ENOSYS; >+#elif defined(TARGET_WANT_OLD_SYS_SELECT) >+ ret = do_old_select(arg1); > #else >- { >- struct target_sel_arg_struct *sel; >- abi_ulong inp, outp, exp, tvp; >- long nsel; >- >- if (!lock_user_struct(VERIFY_READ, sel, arg1, 1)) >- goto efault; >- nsel = tswapal(sel->n); >- inp = tswapal(sel->inp); >- outp = tswapal(sel->outp); >- exp = tswapal(sel->exp); >- tvp = tswapal(sel->tvp); >- unlock_user_struct(sel, arg1, 0); >- ret = do_select(nsel, inp, outp, exp, tvp); >- } >+ ret = do_select(arg1, arg2, arg3, arg4, arg5); > #endif > break; > #endif >diff --git a/linux-user/tilegx/syscall_nr.h b/linux-user/tilegx/syscall_nr.h >index 87fb72c..b86f0fc 100644 >--- a/linux-user/tilegx/syscall_nr.h >+++ b/linux-user/tilegx/syscall_nr.h >@@ -311,7 +311,6 @@ > #define TARGET_NR_creat 1064 > #define TARGET_NR_getdents 1065 > #define TARGET_NR_futimesat 1066 >-#define TARGET_NR_select 1067 > #define TARGET_NR_poll 1068 > #define TARGET_NR_epoll_wait 1069 > #define TARGET_NR_ustat 1070 >-- >2.5.5 >