diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-03-07 18:40:43 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-03-07 18:40:43 +0000 |
commit | c4e0780ed1ffd056f205348d387a61b4136a45df (patch) | |
tree | 1b2f96807ab10e5b0d6210d2ad903223a70a20db /linux-user/syscall.c | |
parent | 6cb4f6db4f4367faa33da85b15f75bbbd2bed2a6 (diff) | |
parent | 61b463fbf6cbf21fcd9abb5af765a19b88dbc1ba (diff) |
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-4.0-pull-request' into staging
- Update netlink types to linux v5.0
- fix accept4/getpeername/getsockname/recvfrom/recvmsg/read
- add/fix ELF_PLATFORM ofr aarch64 and arm
- fix "may be used uninitialized" warnings
- Fix breakpoint support in Nios
- Nicer strace output of chroot() syscall
# gpg: Signature made Thu 07 Mar 2019 10:06:16 GMT
# gpg: using RSA key F30C38BD3F2FBE3C
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg: aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C
* remotes/vivier2/tags/linux-user-for-4.0-pull-request:
linux-user: add new netlink types
linux-user: Nicer strace output of chroot() syscall
linux-user: fix "may be used uninitialized" warnings
linux-user: don't short-circuit read with zero length
Fix breakpoint support in Nios II user-mode emulation.
linux-user: fix emulation of accept4/getpeername/getsockname/recvfrom syscalls
linux-user: Fix ELF_PLATFORM for aarch64_be-linux-user
linux-user: Add ELF_PLATFORM for arm
linux-user: fix recvmsg emulation
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r-- | linux-user/syscall.c | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5bbb72f3d5..208fd1813d 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2759,6 +2759,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, } if (!is_error(ret)) { msgp->msg_namelen = tswap32(msg.msg_namelen); + msgp->msg_flags = tswap32(msg.msg_flags); if (msg.msg_name != NULL && msg.msg_name != (void *)-1) { ret = host_to_target_sockaddr(tswapal(msgp->msg_name), msg.msg_name, msg.msg_namelen); @@ -2846,7 +2847,7 @@ static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec, static abi_long do_accept4(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr, int flags) { - socklen_t addrlen; + socklen_t addrlen, ret_addrlen; void *addr; abi_long ret; int host_flags; @@ -2870,11 +2871,13 @@ static abi_long do_accept4(int fd, abi_ulong target_addr, addr = alloca(addrlen); - ret = get_errno(safe_accept4(fd, addr, &addrlen, host_flags)); + ret_addrlen = addrlen; + ret = get_errno(safe_accept4(fd, addr, &ret_addrlen, host_flags)); if (!is_error(ret)) { - host_to_target_sockaddr(target_addr, addr, addrlen); - if (put_user_u32(addrlen, target_addrlen_addr)) + host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen)); + if (put_user_u32(ret_addrlen, target_addrlen_addr)) { ret = -TARGET_EFAULT; + } } return ret; } @@ -2883,7 +2886,7 @@ static abi_long do_accept4(int fd, abi_ulong target_addr, static abi_long do_getpeername(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr) { - socklen_t addrlen; + socklen_t addrlen, ret_addrlen; void *addr; abi_long ret; @@ -2899,11 +2902,13 @@ static abi_long do_getpeername(int fd, abi_ulong target_addr, addr = alloca(addrlen); - ret = get_errno(getpeername(fd, addr, &addrlen)); + ret_addrlen = addrlen; + ret = get_errno(getpeername(fd, addr, &ret_addrlen)); if (!is_error(ret)) { - host_to_target_sockaddr(target_addr, addr, addrlen); - if (put_user_u32(addrlen, target_addrlen_addr)) + host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen)); + if (put_user_u32(ret_addrlen, target_addrlen_addr)) { ret = -TARGET_EFAULT; + } } return ret; } @@ -2912,7 +2917,7 @@ static abi_long do_getpeername(int fd, abi_ulong target_addr, static abi_long do_getsockname(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr) { - socklen_t addrlen; + socklen_t addrlen, ret_addrlen; void *addr; abi_long ret; @@ -2928,11 +2933,13 @@ static abi_long do_getsockname(int fd, abi_ulong target_addr, addr = alloca(addrlen); - ret = get_errno(getsockname(fd, addr, &addrlen)); + ret_addrlen = addrlen; + ret = get_errno(getsockname(fd, addr, &ret_addrlen)); if (!is_error(ret)) { - host_to_target_sockaddr(target_addr, addr, addrlen); - if (put_user_u32(addrlen, target_addrlen_addr)) + host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen)); + if (put_user_u32(ret_addrlen, target_addrlen_addr)) { ret = -TARGET_EFAULT; + } } return ret; } @@ -3004,7 +3011,7 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr, abi_ulong target_addrlen) { - socklen_t addrlen; + socklen_t addrlen, ret_addrlen; void *addr; void *host_msg; abi_long ret; @@ -3022,10 +3029,12 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, goto fail; } addr = alloca(addrlen); + ret_addrlen = addrlen; ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, - addr, &addrlen)); + addr, &ret_addrlen)); } else { addr = NULL; /* To keep compiler quiet. */ + addrlen = 0; /* To keep compiler quiet. */ ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, NULL, 0)); } if (!is_error(ret)) { @@ -3038,8 +3047,9 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, } } if (target_addr) { - host_to_target_sockaddr(target_addr, addr, addrlen); - if (put_user_u32(addrlen, target_addrlen)) { + host_to_target_sockaddr(target_addr, addr, + MIN(addrlen, ret_addrlen)); + if (put_user_u32(ret_addrlen, target_addrlen)) { ret = -TARGET_EFAULT; goto fail; } @@ -4723,8 +4733,8 @@ static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp, const int *dst_offsets, *src_offsets; int target_size; void *argptr; - abi_ulong *target_rt_dev_ptr; - unsigned long *host_rt_dev_ptr; + abi_ulong *target_rt_dev_ptr = NULL; + unsigned long *host_rt_dev_ptr = NULL; abi_long ret; int i; @@ -4770,6 +4780,9 @@ static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp, unlock_user(argptr, arg, 0); ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); + + assert(host_rt_dev_ptr != NULL); + assert(target_rt_dev_ptr != NULL); if (*host_rt_dev_ptr != 0) { unlock_user((void *)*host_rt_dev_ptr, *target_rt_dev_ptr, 0); @@ -6999,8 +7012,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, _exit(arg1); return 0; /* avoid warning */ case TARGET_NR_read: - if (arg3 == 0) { - return 0; + if (arg2 == 0 && arg3 == 0) { + return get_errno(safe_read(arg1, 0, 0)); } else { if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) return -TARGET_EFAULT; |