@@ -143,6 +143,10 @@ SYSCALL_DEF(munlockall);
SYSCALL_DEF(munmap, ARG_PTR, ARG_DEC);
SYSCALL_DEF(name_to_handle_at,
ARG_ATDIRFD, ARG_STR, ARG_PTR, ARG_PTR, ARG_ATFLAG);
+#ifdef TARGET_NR__newselect
+SYSCALL_DEF_FULL(_newselect, .impl = impl_select,
+ .arg_type = { ARG_DEC, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR });
+#endif
#ifdef TARGET_NR_nice
SYSCALL_DEF(nice, ARG_DEC);
#endif
@@ -209,6 +213,13 @@ SYSCALL_DEF(rt_sigreturn);
SYSCALL_DEF(rt_sigsuspend, ARG_PTR, ARG_DEC);
SYSCALL_DEF(rt_sigtimedwait, ARG_PTR, ARG_PTR, ARG_PTR, ARG_DEC);
SYSCALL_DEF(rt_tgsigqueueinfo, ARG_DEC, ARG_DEC, ARG_SIGNAL, ARG_PTR);
+#ifdef TARGET_NR_select
+# if defined(TARGET_WANT_NI_OLD_SELECT)
+SYSCALL_DEF_NOSYS(select);
+# else
+SYSCALL_DEF_ARGS(select, ARG_DEC, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR);
+# endif
+#endif
#if !defined(SYSCALL_TABLE) || defined(TARGET_NR_semctl)
SYSCALL_DEF(semctl, ARG_DEC, ARG_DEC, ARG_DEC, ARG_HEX);
#endif
@@ -384,34 +384,6 @@ print_socket_protocol(int domain, int type, int protocol)
}
-#ifdef TARGET_NR__newselect
-static void
-print_fdset(int n, abi_ulong target_fds_addr)
-{
- int i;
-
- gemu_log("[");
- if( target_fds_addr ) {
- abi_long *target_fds;
-
- target_fds = lock_user(VERIFY_READ,
- target_fds_addr,
- sizeof(*target_fds)*(n / TARGET_ABI_BITS + 1),
- 1);
-
- if (!target_fds)
- return;
-
- for (i=n; i>=0; i--) {
- if ((tswapal(target_fds[i / TARGET_ABI_BITS]) >> (i & (TARGET_ABI_BITS - 1))) & 1)
- gemu_log("%d,", i );
- }
- unlock_user(target_fds, target_fds_addr, 0);
- }
- gemu_log("]");
-}
-#endif
-
#ifdef TARGET_NR_clock_adjtime
/* IDs of the various system clocks */
#define TARGET_CLOCK_REALTIME 0
@@ -479,58 +451,6 @@ print_clockid(int clockid, int last)
* Sysycall specific output functions
*/
-/* select */
-#ifdef TARGET_NR__newselect
-static long newselect_arg1 = 0;
-static long newselect_arg2 = 0;
-static long newselect_arg3 = 0;
-static long newselect_arg4 = 0;
-static long newselect_arg5 = 0;
-
-static void
-print_newselect(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 ",", name->name, arg1);
- print_fdset(arg1, arg2);
- gemu_log(",");
- print_fdset(arg1, arg3);
- gemu_log(",");
- print_fdset(arg1, arg4);
- gemu_log(",");
- print_timeval(arg5, 1);
- gemu_log(")");
-
- /* save for use in the return output function below */
- newselect_arg1=arg1;
- newselect_arg2=arg2;
- newselect_arg3=arg3;
- newselect_arg4=arg4;
- newselect_arg5=arg5;
-}
-#endif
-
-/*
- * Variants for the return value output function
- */
-
-#ifdef TARGET_NR__newselect
-static void
-print_syscall_ret_newselect(const struct syscallname *name, abi_long ret)
-{
- gemu_log(" = 0x" TARGET_ABI_FMT_lx " (", ret);
- print_fdset(newselect_arg1,newselect_arg2);
- gemu_log(",");
- print_fdset(newselect_arg1,newselect_arg3);
- gemu_log(",");
- print_fdset(newselect_arg1,newselect_arg4);
- gemu_log(",");
- print_timeval(newselect_arg5, 1);
- gemu_log(")\n");
-}
-#endif
-
/* special meanings of adjtimex()' non-negative return values */
#define TARGET_TIME_OK 0 /* clock synchronized, no leap second */
#define TARGET_TIME_INS 1 /* insert leap second */
@@ -1067,6 +1067,97 @@ SYSCALL_IMPL(renameat2)
return do_renameat2(arg1, arg2, arg3, arg4, arg5);
}
+#if defined(TARGET_NR_select) && defined(TARGET_WANT_OLD_SYS_SELECT)
+SYSCALL_ARGS(select)
+{
+ struct target_sel_arg_struct *sel;
+ abi_ulong inp, outp, exp, tvp;
+ abi_long nsel;
+
+ if (!lock_user_struct(VERIFY_READ, sel, in[0], 1)) {
+ errno = EFAULT;
+ return NULL;
+ }
+ nsel = tswapal(sel->n);
+ inp = tswapal(sel->inp);
+ outp = tswapal(sel->outp);
+ exp = tswapal(sel->exp);
+ tvp = tswapal(sel->tvp);
+ unlock_user_struct(sel, in[0], 0);
+
+ out[0] = nsel;
+ out[1] = inp;
+ out[2] = outp;
+ out[3] = exp;
+ out[4] = tvp;
+ return def;
+}
+#else
+# define args_select NULL
+#endif
+
+#if (defined(TARGET_NR_select) && !defined(TARGET_WANT_NI_OLD_SELECT)) \
+ || defined(TARGET_NR__newselect)
+SYSCALL_IMPL(select)
+{
+ int n = arg1;
+ abi_ulong rfd_addr = arg2;
+ abi_ulong wfd_addr = arg3;
+ abi_ulong efd_addr = arg4;
+ abi_ulong target_tv_addr = arg5;
+ fd_set rfds, wfds, efds;
+ fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
+ struct timeval tv;
+ struct timespec ts, *ts_ptr = NULL;
+ abi_long ret;
+
+ ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
+ if (ret) {
+ return ret;
+ }
+ ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
+ if (ret) {
+ return ret;
+ }
+ ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
+ if (ret) {
+ return ret;
+ }
+
+ if (target_tv_addr) {
+ if (copy_from_user_timeval(&tv, target_tv_addr))
+ return -TARGET_EFAULT;
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
+ ts_ptr = &ts;
+ }
+
+ ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
+ ts_ptr, NULL));
+
+ if (!is_error(ret)) {
+ if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n)) {
+ return -TARGET_EFAULT;
+ }
+ if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n)) {
+ return -TARGET_EFAULT;
+ }
+ if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) {
+ return -TARGET_EFAULT;
+ }
+ if (target_tv_addr) {
+ tv.tv_sec = ts.tv_sec;
+ tv.tv_usec = ts.tv_nsec / 1000;
+ if (copy_to_user_timeval(target_tv_addr, &tv)) {
+ return -TARGET_EFAULT;
+ }
+ }
+ }
+
+ return ret;
+}
+#endif
+
SYSCALL_IMPL(sync)
{
sync();
@@ -1055,88 +1055,6 @@ static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
}
#endif
-#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
-/* do_select() must return target values and target errnos. */
-static abi_long do_select(int n,
- abi_ulong rfd_addr, abi_ulong wfd_addr,
- abi_ulong efd_addr, abi_ulong target_tv_addr)
-{
- fd_set rfds, wfds, efds;
- fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
- struct timeval tv;
- struct timespec ts, *ts_ptr;
- abi_long ret;
-
- ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
- if (ret) {
- return ret;
- }
- ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
- if (ret) {
- return ret;
- }
- ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
- if (ret) {
- return ret;
- }
-
- if (target_tv_addr) {
- if (copy_from_user_timeval(&tv, target_tv_addr))
- return -TARGET_EFAULT;
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000;
- ts_ptr = &ts;
- } else {
- ts_ptr = NULL;
- }
-
- ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
- ts_ptr, NULL));
-
- if (!is_error(ret)) {
- if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
- return -TARGET_EFAULT;
- if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
- return -TARGET_EFAULT;
- if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
- return -TARGET_EFAULT;
-
- if (target_tv_addr) {
- tv.tv_sec = ts.tv_sec;
- tv.tv_usec = ts.tv_nsec / 1000;
- if (copy_to_user_timeval(target_tv_addr, &tv)) {
- return -TARGET_EFAULT;
- }
- }
- }
-
- 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 inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
abi_ulong target_addr,
socklen_t len)
@@ -4240,20 +4158,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
void *p;
switch(num) {
-#if defined(TARGET_NR_select)
- case TARGET_NR_select:
-#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
- ret = do_select(arg1, arg2, arg3, arg4, arg5);
-#endif
- return ret;
-#endif
#ifdef TARGET_NR_pselect6
case TARGET_NR_pselect6:
{
@@ -5007,10 +4911,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
}
return ret;
#endif /* TARGET_NR_getdents64 */
-#if defined(TARGET_NR__newselect)
- case TARGET_NR__newselect:
- return do_select(arg1, arg2, arg3, arg4, arg5);
-#endif
#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
# ifdef TARGET_NR_poll
case TARGET_NR_poll:
@@ -7233,6 +7133,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
#include "syscall-sig.inc.c"
#include "syscall-time.inc.c"
+static SyscallImplFn impl_enosys __attribute__((unused));
+SYSCALL_IMPL(enosys)
+{
+ return -TARGET_ENOSYS;
+}
+
#undef SYSCALL_IMPL
#undef SYSCALL_ARGS
@@ -7254,6 +7160,10 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
SYSCALL_DEF_FULL(NAME, .impl = impl_##NAME, .args = args_##NAME, \
.arg_type = { __VA_ARGS__ })
+/* Emit a definition that always produces ENOSYS without logging. */
+#define SYSCALL_DEF_NOSYS(NAME) \
+ SYSCALL_DEF_FULL(NAME, .impl = impl_enosys)
+
#include "syscall-defs.h"
#undef SYSCALL_DEF
@@ -470,9 +470,6 @@
#ifdef TARGET_NR_newfstatat
{ TARGET_NR_newfstatat, "newfstatat" , NULL, print_newfstatat, NULL },
#endif
-#ifdef TARGET_NR__newselect
-{ TARGET_NR__newselect, "_newselect" , NULL, print_newselect, print_syscall_ret_newselect },
-#endif
#ifdef TARGET_NR_nfsservctl
{ TARGET_NR_nfsservctl, "nfsservctl" , NULL, NULL, NULL },
#endif
@@ -962,9 +959,6 @@
#ifdef TARGET_NR_security
{ TARGET_NR_security, "security" , NULL, NULL, NULL },
#endif
-#ifdef TARGET_NR_select
-{ TARGET_NR_select, "select" , NULL, NULL, NULL },
-#endif
#ifdef TARGET_NR_send
{ TARGET_NR_send, "send" , NULL, NULL, NULL },
#endif
This removes the printing of the fdset outputs. It's hard to see how this could have been reliable in a multi-threaded program, saving syscall arguments to global variables. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- linux-user/syscall-defs.h | 11 ++++ linux-user/strace.c | 80 ------------------------- linux-user/syscall-file.inc.c | 91 ++++++++++++++++++++++++++++ linux-user/syscall.c | 110 ++++------------------------------ linux-user/strace.list | 6 -- 5 files changed, 112 insertions(+), 186 deletions(-) -- 2.17.1