Commit 0da46a6e2e5fc10b757612e9ac1707dc1fb6dc5a
1 parent
1931e260
Syscall target errno fixes, by Thayne Harbaugh.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3418 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
100 additions
and
55 deletions
linux-user/signal.c
| @@ -438,6 +438,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info, | @@ -438,6 +438,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info, | ||
| 438 | } | 438 | } |
| 439 | } | 439 | } |
| 440 | 440 | ||
| 441 | +/* do_sigaltstack() returns target values and errnos. */ | ||
| 441 | int do_sigaltstack(const struct target_sigaltstack *uss, | 442 | int do_sigaltstack(const struct target_sigaltstack *uss, |
| 442 | struct target_sigaltstack *uoss, | 443 | struct target_sigaltstack *uoss, |
| 443 | abi_ulong sp) | 444 | abi_ulong sp) |
| @@ -457,18 +458,18 @@ int do_sigaltstack(const struct target_sigaltstack *uss, | @@ -457,18 +458,18 @@ int do_sigaltstack(const struct target_sigaltstack *uss, | ||
| 457 | { | 458 | { |
| 458 | struct target_sigaltstack ss; | 459 | struct target_sigaltstack ss; |
| 459 | 460 | ||
| 460 | - ret = -EFAULT; | 461 | + ret = -TARGET_EFAULT; |
| 461 | if (!access_ok(VERIFY_READ, uss, sizeof(*uss)) | 462 | if (!access_ok(VERIFY_READ, uss, sizeof(*uss)) |
| 462 | || __get_user(ss.ss_sp, &uss->ss_sp) | 463 | || __get_user(ss.ss_sp, &uss->ss_sp) |
| 463 | || __get_user(ss.ss_size, &uss->ss_size) | 464 | || __get_user(ss.ss_size, &uss->ss_size) |
| 464 | || __get_user(ss.ss_flags, &uss->ss_flags)) | 465 | || __get_user(ss.ss_flags, &uss->ss_flags)) |
| 465 | goto out; | 466 | goto out; |
| 466 | 467 | ||
| 467 | - ret = -EPERM; | 468 | + ret = -TARGET_EPERM; |
| 468 | if (on_sig_stack(sp)) | 469 | if (on_sig_stack(sp)) |
| 469 | goto out; | 470 | goto out; |
| 470 | 471 | ||
| 471 | - ret = -EINVAL; | 472 | + ret = -TARGET_EINVAL; |
| 472 | if (ss.ss_flags != TARGET_SS_DISABLE | 473 | if (ss.ss_flags != TARGET_SS_DISABLE |
| 473 | && ss.ss_flags != TARGET_SS_ONSTACK | 474 | && ss.ss_flags != TARGET_SS_ONSTACK |
| 474 | && ss.ss_flags != 0) | 475 | && ss.ss_flags != 0) |
| @@ -478,7 +479,7 @@ int do_sigaltstack(const struct target_sigaltstack *uss, | @@ -478,7 +479,7 @@ int do_sigaltstack(const struct target_sigaltstack *uss, | ||
| 478 | ss.ss_size = 0; | 479 | ss.ss_size = 0; |
| 479 | ss.ss_sp = 0; | 480 | ss.ss_sp = 0; |
| 480 | } else { | 481 | } else { |
| 481 | - ret = -ENOMEM; | 482 | + ret = -TARGET_ENOMEM; |
| 482 | if (ss.ss_size < MINSIGSTKSZ) | 483 | if (ss.ss_size < MINSIGSTKSZ) |
| 483 | goto out; | 484 | goto out; |
| 484 | } | 485 | } |
| @@ -488,7 +489,7 @@ int do_sigaltstack(const struct target_sigaltstack *uss, | @@ -488,7 +489,7 @@ int do_sigaltstack(const struct target_sigaltstack *uss, | ||
| 488 | } | 489 | } |
| 489 | 490 | ||
| 490 | if (uoss) { | 491 | if (uoss) { |
| 491 | - ret = -EFAULT; | 492 | + ret = -TARGET_EFAULT; |
| 492 | if (!access_ok(VERIFY_WRITE, uoss, sizeof(oss))) | 493 | if (!access_ok(VERIFY_WRITE, uoss, sizeof(oss))) |
| 493 | goto out; | 494 | goto out; |
| 494 | memcpy(uoss, &oss, sizeof(oss)); | 495 | memcpy(uoss, &oss, sizeof(oss)); |
| @@ -499,12 +500,14 @@ out: | @@ -499,12 +500,14 @@ out: | ||
| 499 | return ret; | 500 | return ret; |
| 500 | } | 501 | } |
| 501 | 502 | ||
| 503 | +/* do_sigaction() return host values and errnos */ | ||
| 502 | int do_sigaction(int sig, const struct target_sigaction *act, | 504 | int do_sigaction(int sig, const struct target_sigaction *act, |
| 503 | struct target_sigaction *oact) | 505 | struct target_sigaction *oact) |
| 504 | { | 506 | { |
| 505 | struct emulated_sigaction *k; | 507 | struct emulated_sigaction *k; |
| 506 | struct sigaction act1; | 508 | struct sigaction act1; |
| 507 | int host_sig; | 509 | int host_sig; |
| 510 | + int ret = 0; | ||
| 508 | 511 | ||
| 509 | if (sig < 1 || sig > TARGET_NSIG || sig == SIGKILL || sig == SIGSTOP) | 512 | if (sig < 1 || sig > TARGET_NSIG || sig == SIGKILL || sig == SIGSTOP) |
| 510 | return -EINVAL; | 513 | return -EINVAL; |
| @@ -546,10 +549,10 @@ int do_sigaction(int sig, const struct target_sigaction *act, | @@ -546,10 +549,10 @@ int do_sigaction(int sig, const struct target_sigaction *act, | ||
| 546 | } else { | 549 | } else { |
| 547 | act1.sa_sigaction = host_signal_handler; | 550 | act1.sa_sigaction = host_signal_handler; |
| 548 | } | 551 | } |
| 549 | - sigaction(host_sig, &act1, NULL); | 552 | + ret = sigaction(host_sig, &act1, NULL); |
| 550 | } | 553 | } |
| 551 | } | 554 | } |
| 552 | - return 0; | 555 | + return ret; |
| 553 | } | 556 | } |
| 554 | 557 | ||
| 555 | #ifndef offsetof | 558 | #ifndef offsetof |
linux-user/syscall.c
| @@ -167,6 +167,8 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ | @@ -167,6 +167,8 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ | ||
| 167 | #ifdef __NR_gettid | 167 | #ifdef __NR_gettid |
| 168 | _syscall0(int, gettid) | 168 | _syscall0(int, gettid) |
| 169 | #else | 169 | #else |
| 170 | +/* This is a replacement for the host gettid() and must return a host | ||
| 171 | + errno. */ | ||
| 170 | static int gettid(void) { | 172 | static int gettid(void) { |
| 171 | return -ENOSYS; | 173 | return -ENOSYS; |
| 172 | } | 174 | } |
| @@ -389,6 +391,7 @@ void target_set_brk(abi_ulong new_brk) | @@ -389,6 +391,7 @@ void target_set_brk(abi_ulong new_brk) | ||
| 389 | target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk); | 391 | target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk); |
| 390 | } | 392 | } |
| 391 | 393 | ||
| 394 | +/* do_brk() must return target values and target errnos. */ | ||
| 392 | abi_long do_brk(abi_ulong new_brk) | 395 | abi_long do_brk(abi_ulong new_brk) |
| 393 | { | 396 | { |
| 394 | abi_ulong brk_page; | 397 | abi_ulong brk_page; |
| @@ -398,7 +401,7 @@ abi_long do_brk(abi_ulong new_brk) | @@ -398,7 +401,7 @@ abi_long do_brk(abi_ulong new_brk) | ||
| 398 | if (!new_brk) | 401 | if (!new_brk) |
| 399 | return target_brk; | 402 | return target_brk; |
| 400 | if (new_brk < target_original_brk) | 403 | if (new_brk < target_original_brk) |
| 401 | - return -ENOMEM; | 404 | + return -TARGET_ENOMEM; |
| 402 | 405 | ||
| 403 | brk_page = HOST_PAGE_ALIGN(target_brk); | 406 | brk_page = HOST_PAGE_ALIGN(target_brk); |
| 404 | 407 | ||
| @@ -532,6 +535,7 @@ static inline void host_to_target_timeval(abi_ulong target_addr, | @@ -532,6 +535,7 @@ static inline void host_to_target_timeval(abi_ulong target_addr, | ||
| 532 | } | 535 | } |
| 533 | 536 | ||
| 534 | 537 | ||
| 538 | +/* do_select() must return target values and target errnos. */ | ||
| 535 | static abi_long do_select(int n, | 539 | static abi_long do_select(int n, |
| 536 | abi_ulong rfd_p, abi_ulong wfd_p, | 540 | abi_ulong rfd_p, abi_ulong wfd_p, |
| 537 | abi_ulong efd_p, abi_ulong target_tv) | 541 | abi_ulong efd_p, abi_ulong target_tv) |
| @@ -706,6 +710,7 @@ static inline void host_to_target_cmsg(struct target_msghdr *target_msgh, | @@ -706,6 +710,7 @@ static inline void host_to_target_cmsg(struct target_msghdr *target_msgh, | ||
| 706 | msgh->msg_controllen = tswapl(space); | 710 | msgh->msg_controllen = tswapl(space); |
| 707 | } | 711 | } |
| 708 | 712 | ||
| 713 | +/* do_setsockopt() Must return target values and target errnos. */ | ||
| 709 | static abi_long do_setsockopt(int sockfd, int level, int optname, | 714 | static abi_long do_setsockopt(int sockfd, int level, int optname, |
| 710 | abi_ulong optval, socklen_t optlen) | 715 | abi_ulong optval, socklen_t optlen) |
| 711 | { | 716 | { |
| @@ -716,7 +721,7 @@ static abi_long do_setsockopt(int sockfd, int level, int optname, | @@ -716,7 +721,7 @@ static abi_long do_setsockopt(int sockfd, int level, int optname, | ||
| 716 | case SOL_TCP: | 721 | case SOL_TCP: |
| 717 | /* TCP options all take an 'int' value. */ | 722 | /* TCP options all take an 'int' value. */ |
| 718 | if (optlen < sizeof(uint32_t)) | 723 | if (optlen < sizeof(uint32_t)) |
| 719 | - return -EINVAL; | 724 | + return -TARGET_EINVAL; |
| 720 | 725 | ||
| 721 | val = tget32(optval); | 726 | val = tget32(optval); |
| 722 | ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); | 727 | ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); |
| @@ -814,7 +819,7 @@ static abi_long do_setsockopt(int sockfd, int level, int optname, | @@ -814,7 +819,7 @@ static abi_long do_setsockopt(int sockfd, int level, int optname, | ||
| 814 | goto unimplemented; | 819 | goto unimplemented; |
| 815 | } | 820 | } |
| 816 | if (optlen < sizeof(uint32_t)) | 821 | if (optlen < sizeof(uint32_t)) |
| 817 | - return -EINVAL; | 822 | + return -TARGET_EINVAL; |
| 818 | 823 | ||
| 819 | val = tget32(optval); | 824 | val = tget32(optval); |
| 820 | ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val))); | 825 | ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val))); |
| @@ -822,11 +827,12 @@ static abi_long do_setsockopt(int sockfd, int level, int optname, | @@ -822,11 +827,12 @@ static abi_long do_setsockopt(int sockfd, int level, int optname, | ||
| 822 | default: | 827 | default: |
| 823 | unimplemented: | 828 | unimplemented: |
| 824 | gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname); | 829 | gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname); |
| 825 | - ret = -ENOSYS; | 830 | + ret = -TARGET_ENOSYS; |
| 826 | } | 831 | } |
| 827 | return ret; | 832 | return ret; |
| 828 | } | 833 | } |
| 829 | 834 | ||
| 835 | +/* do_getsockopt() Must return target values and target errnos. */ | ||
| 830 | static abi_long do_getsockopt(int sockfd, int level, int optname, | 836 | static abi_long do_getsockopt(int sockfd, int level, int optname, |
| 831 | abi_ulong optval, abi_ulong optlen) | 837 | abi_ulong optval, abi_ulong optlen) |
| 832 | { | 838 | { |
| @@ -853,7 +859,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, | @@ -853,7 +859,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, | ||
| 853 | int_case: | 859 | int_case: |
| 854 | len = tget32(optlen); | 860 | len = tget32(optlen); |
| 855 | if (len < 0) | 861 | if (len < 0) |
| 856 | - return -EINVAL; | 862 | + return -TARGET_EINVAL; |
| 857 | lv = sizeof(int); | 863 | lv = sizeof(int); |
| 858 | ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); | 864 | ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); |
| 859 | if (ret < 0) | 865 | if (ret < 0) |
| @@ -886,7 +892,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, | @@ -886,7 +892,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, | ||
| 886 | case IP_MULTICAST_LOOP: | 892 | case IP_MULTICAST_LOOP: |
| 887 | len = tget32(optlen); | 893 | len = tget32(optlen); |
| 888 | if (len < 0) | 894 | if (len < 0) |
| 889 | - return -EINVAL; | 895 | + return -TARGET_EINVAL; |
| 890 | lv = sizeof(int); | 896 | lv = sizeof(int); |
| 891 | ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); | 897 | ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); |
| 892 | if (ret < 0) | 898 | if (ret < 0) |
| @@ -910,7 +916,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, | @@ -910,7 +916,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, | ||
| 910 | unimplemented: | 916 | unimplemented: |
| 911 | gemu_log("getsockopt level=%d optname=%d not yet supported\n", | 917 | gemu_log("getsockopt level=%d optname=%d not yet supported\n", |
| 912 | level, optname); | 918 | level, optname); |
| 913 | - ret = -ENOSYS; | 919 | + ret = -TARGET_ENOSYS; |
| 914 | break; | 920 | break; |
| 915 | } | 921 | } |
| 916 | return ret; | 922 | return ret; |
| @@ -947,6 +953,7 @@ static void unlock_iovec(struct iovec *vec, abi_ulong target_addr, | @@ -947,6 +953,7 @@ static void unlock_iovec(struct iovec *vec, abi_ulong target_addr, | ||
| 947 | unlock_user (target_vec, target_addr, 0); | 953 | unlock_user (target_vec, target_addr, 0); |
| 948 | } | 954 | } |
| 949 | 955 | ||
| 956 | +/* do_socket() Must return target values and target errnos. */ | ||
| 950 | static abi_long do_socket(int domain, int type, int protocol) | 957 | static abi_long do_socket(int domain, int type, int protocol) |
| 951 | { | 958 | { |
| 952 | #if defined(TARGET_MIPS) | 959 | #if defined(TARGET_MIPS) |
| @@ -974,6 +981,7 @@ static abi_long do_socket(int domain, int type, int protocol) | @@ -974,6 +981,7 @@ static abi_long do_socket(int domain, int type, int protocol) | ||
| 974 | return get_errno(socket(domain, type, protocol)); | 981 | return get_errno(socket(domain, type, protocol)); |
| 975 | } | 982 | } |
| 976 | 983 | ||
| 984 | +/* do_bind() Must return target values and target errnos. */ | ||
| 977 | static abi_long do_bind(int sockfd, abi_ulong target_addr, | 985 | static abi_long do_bind(int sockfd, abi_ulong target_addr, |
| 978 | socklen_t addrlen) | 986 | socklen_t addrlen) |
| 979 | { | 987 | { |
| @@ -983,6 +991,7 @@ static abi_long do_bind(int sockfd, abi_ulong target_addr, | @@ -983,6 +991,7 @@ static abi_long do_bind(int sockfd, abi_ulong target_addr, | ||
| 983 | return get_errno(bind(sockfd, addr, addrlen)); | 991 | return get_errno(bind(sockfd, addr, addrlen)); |
| 984 | } | 992 | } |
| 985 | 993 | ||
| 994 | +/* do_connect() Must return target values and target errnos. */ | ||
| 986 | static abi_long do_connect(int sockfd, abi_ulong target_addr, | 995 | static abi_long do_connect(int sockfd, abi_ulong target_addr, |
| 987 | socklen_t addrlen) | 996 | socklen_t addrlen) |
| 988 | { | 997 | { |
| @@ -992,6 +1001,7 @@ static abi_long do_connect(int sockfd, abi_ulong target_addr, | @@ -992,6 +1001,7 @@ static abi_long do_connect(int sockfd, abi_ulong target_addr, | ||
| 992 | return get_errno(connect(sockfd, addr, addrlen)); | 1001 | return get_errno(connect(sockfd, addr, addrlen)); |
| 993 | } | 1002 | } |
| 994 | 1003 | ||
| 1004 | +/* do_sendrecvmsg() Must return target values and target errnos. */ | ||
| 995 | static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, | 1005 | static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, |
| 996 | int flags, int send) | 1006 | int flags, int send) |
| 997 | { | 1007 | { |
| @@ -1035,6 +1045,7 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, | @@ -1035,6 +1045,7 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, | ||
| 1035 | return ret; | 1045 | return ret; |
| 1036 | } | 1046 | } |
| 1037 | 1047 | ||
| 1048 | +/* do_accept() Must return target values and target errnos. */ | ||
| 1038 | static abi_long do_accept(int fd, abi_ulong target_addr, | 1049 | static abi_long do_accept(int fd, abi_ulong target_addr, |
| 1039 | abi_ulong target_addrlen) | 1050 | abi_ulong target_addrlen) |
| 1040 | { | 1051 | { |
| @@ -1050,6 +1061,7 @@ static abi_long do_accept(int fd, abi_ulong target_addr, | @@ -1050,6 +1061,7 @@ static abi_long do_accept(int fd, abi_ulong target_addr, | ||
| 1050 | return ret; | 1061 | return ret; |
| 1051 | } | 1062 | } |
| 1052 | 1063 | ||
| 1064 | +/* do_getpeername() Must return target values and target errnos. */ | ||
| 1053 | static abi_long do_getpeername(int fd, abi_ulong target_addr, | 1065 | static abi_long do_getpeername(int fd, abi_ulong target_addr, |
| 1054 | abi_ulong target_addrlen) | 1066 | abi_ulong target_addrlen) |
| 1055 | { | 1067 | { |
| @@ -1065,6 +1077,7 @@ static abi_long do_getpeername(int fd, abi_ulong target_addr, | @@ -1065,6 +1077,7 @@ static abi_long do_getpeername(int fd, abi_ulong target_addr, | ||
| 1065 | return ret; | 1077 | return ret; |
| 1066 | } | 1078 | } |
| 1067 | 1079 | ||
| 1080 | +/* do_getsockname() Must return target values and target errnos. */ | ||
| 1068 | static abi_long do_getsockname(int fd, abi_ulong target_addr, | 1081 | static abi_long do_getsockname(int fd, abi_ulong target_addr, |
| 1069 | abi_ulong target_addrlen) | 1082 | abi_ulong target_addrlen) |
| 1070 | { | 1083 | { |
| @@ -1080,6 +1093,7 @@ static abi_long do_getsockname(int fd, abi_ulong target_addr, | @@ -1080,6 +1093,7 @@ static abi_long do_getsockname(int fd, abi_ulong target_addr, | ||
| 1080 | return ret; | 1093 | return ret; |
| 1081 | } | 1094 | } |
| 1082 | 1095 | ||
| 1096 | +/* do_socketpair() Must return target values and target errnos. */ | ||
| 1083 | static abi_long do_socketpair(int domain, int type, int protocol, | 1097 | static abi_long do_socketpair(int domain, int type, int protocol, |
| 1084 | abi_ulong target_tab) | 1098 | abi_ulong target_tab) |
| 1085 | { | 1099 | { |
| @@ -1094,6 +1108,7 @@ static abi_long do_socketpair(int domain, int type, int protocol, | @@ -1094,6 +1108,7 @@ static abi_long do_socketpair(int domain, int type, int protocol, | ||
| 1094 | return ret; | 1108 | return ret; |
| 1095 | } | 1109 | } |
| 1096 | 1110 | ||
| 1111 | +/* do_sendto() Must return target values and target errnos. */ | ||
| 1097 | static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags, | 1112 | static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags, |
| 1098 | abi_ulong target_addr, socklen_t addrlen) | 1113 | abi_ulong target_addr, socklen_t addrlen) |
| 1099 | { | 1114 | { |
| @@ -1113,6 +1128,7 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags, | @@ -1113,6 +1128,7 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags, | ||
| 1113 | return ret; | 1128 | return ret; |
| 1114 | } | 1129 | } |
| 1115 | 1130 | ||
| 1131 | +/* do_recvfrom() Must return target values and target errnos. */ | ||
| 1116 | static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, | 1132 | static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, |
| 1117 | abi_ulong target_addr, | 1133 | abi_ulong target_addr, |
| 1118 | abi_ulong target_addrlen) | 1134 | abi_ulong target_addrlen) |
| @@ -1144,6 +1160,7 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, | @@ -1144,6 +1160,7 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, | ||
| 1144 | } | 1160 | } |
| 1145 | 1161 | ||
| 1146 | #ifdef TARGET_NR_socketcall | 1162 | #ifdef TARGET_NR_socketcall |
| 1163 | +/* do_socketcall() Must return target values and target errnos. */ | ||
| 1147 | static abi_long do_socketcall(int num, abi_ulong vptr) | 1164 | static abi_long do_socketcall(int num, abi_ulong vptr) |
| 1148 | { | 1165 | { |
| 1149 | abi_long ret; | 1166 | abi_long ret; |
| @@ -1301,7 +1318,7 @@ static abi_long do_socketcall(int num, abi_ulong vptr) | @@ -1301,7 +1318,7 @@ static abi_long do_socketcall(int num, abi_ulong vptr) | ||
| 1301 | break; | 1318 | break; |
| 1302 | default: | 1319 | default: |
| 1303 | gemu_log("Unsupported socketcall: %d\n", num); | 1320 | gemu_log("Unsupported socketcall: %d\n", num); |
| 1304 | - ret = -ENOSYS; | 1321 | + ret = -TARGET_ENOSYS; |
| 1305 | break; | 1322 | break; |
| 1306 | } | 1323 | } |
| 1307 | return ret; | 1324 | return ret; |
| @@ -1639,6 +1656,7 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp, | @@ -1639,6 +1656,7 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp, | ||
| 1639 | } | 1656 | } |
| 1640 | 1657 | ||
| 1641 | /* ??? This only works with linear mappings. */ | 1658 | /* ??? This only works with linear mappings. */ |
| 1659 | +/* do_ipc() must return target values and target errnos. */ | ||
| 1642 | static abi_long do_ipc(unsigned int call, int first, | 1660 | static abi_long do_ipc(unsigned int call, int first, |
| 1643 | int second, int third, | 1661 | int second, int third, |
| 1644 | abi_long ptr, abi_long fifth) | 1662 | abi_long ptr, abi_long fifth) |
| @@ -1667,7 +1685,7 @@ static abi_long do_ipc(unsigned int call, int first, | @@ -1667,7 +1685,7 @@ static abi_long do_ipc(unsigned int call, int first, | ||
| 1667 | 1685 | ||
| 1668 | case IPCOP_semtimedop: | 1686 | case IPCOP_semtimedop: |
| 1669 | gemu_log("Unsupported ipc call: %d (version %d)\n", call, version); | 1687 | gemu_log("Unsupported ipc call: %d (version %d)\n", call, version); |
| 1670 | - ret = -ENOSYS; | 1688 | + ret = -TARGET_ENOSYS; |
| 1671 | break; | 1689 | break; |
| 1672 | 1690 | ||
| 1673 | case IPCOP_msgget: | 1691 | case IPCOP_msgget: |
| @@ -1723,7 +1741,7 @@ static abi_long do_ipc(unsigned int call, int first, | @@ -1723,7 +1741,7 @@ static abi_long do_ipc(unsigned int call, int first, | ||
| 1723 | } | 1741 | } |
| 1724 | } | 1742 | } |
| 1725 | if (put_user(raddr, (abi_ulong *)third)) | 1743 | if (put_user(raddr, (abi_ulong *)third)) |
| 1726 | - return -EFAULT; | 1744 | + return -TARGET_EFAULT; |
| 1727 | ret = 0; | 1745 | ret = 0; |
| 1728 | break; | 1746 | break; |
| 1729 | case IPCOP_shmdt: | 1747 | case IPCOP_shmdt: |
| @@ -1757,7 +1775,7 @@ static abi_long do_ipc(unsigned int call, int first, | @@ -1757,7 +1775,7 @@ static abi_long do_ipc(unsigned int call, int first, | ||
| 1757 | default: | 1775 | default: |
| 1758 | unimplemented: | 1776 | unimplemented: |
| 1759 | gemu_log("Unsupported ipc call: %d (version %d)\n", call, version); | 1777 | gemu_log("Unsupported ipc call: %d (version %d)\n", call, version); |
| 1760 | - ret = -ENOSYS; | 1778 | + ret = -TARGET_ENOSYS; |
| 1761 | break; | 1779 | break; |
| 1762 | } | 1780 | } |
| 1763 | return ret; | 1781 | return ret; |
| @@ -1803,6 +1821,7 @@ IOCTLEntry ioctl_entries[] = { | @@ -1803,6 +1821,7 @@ IOCTLEntry ioctl_entries[] = { | ||
| 1803 | }; | 1821 | }; |
| 1804 | 1822 | ||
| 1805 | /* ??? Implement proper locking for ioctls. */ | 1823 | /* ??? Implement proper locking for ioctls. */ |
| 1824 | +/* do_ioctl() Must return target values and target errnos. */ | ||
| 1806 | static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) | 1825 | static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) |
| 1807 | { | 1826 | { |
| 1808 | const IOCTLEntry *ie; | 1827 | const IOCTLEntry *ie; |
| @@ -1816,7 +1835,7 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) | @@ -1816,7 +1835,7 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) | ||
| 1816 | for(;;) { | 1835 | for(;;) { |
| 1817 | if (ie->target_cmd == 0) { | 1836 | if (ie->target_cmd == 0) { |
| 1818 | gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd); | 1837 | gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd); |
| 1819 | - return -ENOSYS; | 1838 | + return -TARGET_ENOSYS; |
| 1820 | } | 1839 | } |
| 1821 | if (ie->target_cmd == cmd) | 1840 | if (ie->target_cmd == cmd) |
| 1822 | break; | 1841 | break; |
| @@ -1871,7 +1890,7 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) | @@ -1871,7 +1890,7 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg) | ||
| 1871 | default: | 1890 | default: |
| 1872 | gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", | 1891 | gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", |
| 1873 | (long)cmd, arg_type[0]); | 1892 | (long)cmd, arg_type[0]); |
| 1874 | - ret = -ENOSYS; | 1893 | + ret = -TARGET_ENOSYS; |
| 1875 | break; | 1894 | break; |
| 1876 | } | 1895 | } |
| 1877 | return ret; | 1896 | return ret; |
| @@ -2106,6 +2125,7 @@ static int read_ldt(abi_ulong ptr, unsigned long bytecount) | @@ -2106,6 +2125,7 @@ static int read_ldt(abi_ulong ptr, unsigned long bytecount) | ||
| 2106 | } | 2125 | } |
| 2107 | 2126 | ||
| 2108 | /* XXX: add locking support */ | 2127 | /* XXX: add locking support */ |
| 2128 | +/* write_ldt() returns host errnos */ | ||
| 2109 | static int write_ldt(CPUX86State *env, | 2129 | static int write_ldt(CPUX86State *env, |
| 2110 | abi_ulong ptr, unsigned long bytecount, int oldmode) | 2130 | abi_ulong ptr, unsigned long bytecount, int oldmode) |
| 2111 | { | 2131 | { |
| @@ -2188,6 +2208,8 @@ install: | @@ -2188,6 +2208,8 @@ install: | ||
| 2188 | } | 2208 | } |
| 2189 | 2209 | ||
| 2190 | /* specific and weird i386 syscalls */ | 2210 | /* specific and weird i386 syscalls */ |
| 2211 | +/* do_modify_ldt() returns host errnos (it is inconsistent with the | ||
| 2212 | + other do_*() functions which return target errnos). */ | ||
| 2191 | int do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr, unsigned long bytecount) | 2213 | int do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr, unsigned long bytecount) |
| 2192 | { | 2214 | { |
| 2193 | int ret = -ENOSYS; | 2215 | int ret = -ENOSYS; |
| @@ -2220,6 +2242,8 @@ static int clone_func(void *arg) | @@ -2220,6 +2242,8 @@ static int clone_func(void *arg) | ||
| 2220 | return 0; | 2242 | return 0; |
| 2221 | } | 2243 | } |
| 2222 | 2244 | ||
| 2245 | +/* do_fork() Must return host values and target errnos (unlike most | ||
| 2246 | + do_*() functions). */ | ||
| 2223 | int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp) | 2247 | int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp) |
| 2224 | { | 2248 | { |
| 2225 | int ret; | 2249 | int ret; |
| @@ -2547,6 +2571,9 @@ static inline void host_to_target_timespec(abi_ulong target_addr, | @@ -2547,6 +2571,9 @@ static inline void host_to_target_timespec(abi_ulong target_addr, | ||
| 2547 | unlock_user_struct(target_ts, target_addr, 1); | 2571 | unlock_user_struct(target_ts, target_addr, 1); |
| 2548 | } | 2572 | } |
| 2549 | 2573 | ||
| 2574 | +/* do_syscall() should always have a single exit point at the end so | ||
| 2575 | + that actions, such as logging of syscall results, can be performed. | ||
| 2576 | + All errnos that do_syscall() returns must be -TARGET_<errcode>. */ | ||
| 2550 | abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | 2577 | abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
| 2551 | abi_long arg2, abi_long arg3, abi_long arg4, | 2578 | abi_long arg2, abi_long arg3, abi_long arg4, |
| 2552 | abi_long arg5, abi_long arg6) | 2579 | abi_long arg5, abi_long arg6) |
| @@ -2590,12 +2617,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -2590,12 +2617,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 2590 | #if defined(TARGET_NR_openat) && defined(__NR_openat) | 2617 | #if defined(TARGET_NR_openat) && defined(__NR_openat) |
| 2591 | case TARGET_NR_openat: | 2618 | case TARGET_NR_openat: |
| 2592 | if (!arg2) { | 2619 | if (!arg2) { |
| 2593 | - ret = -EFAULT; | 2620 | + ret = -TARGET_EFAULT; |
| 2594 | goto fail; | 2621 | goto fail; |
| 2595 | } | 2622 | } |
| 2596 | p = lock_user_string(arg2); | 2623 | p = lock_user_string(arg2); |
| 2597 | if (!access_ok(VERIFY_READ, p, 1)) | 2624 | if (!access_ok(VERIFY_READ, p, 1)) |
| 2598 | - ret = -EFAULT; | 2625 | + /* Don't "goto fail" so that cleanup can happen. */ |
| 2626 | + ret = -TARGET_EFAULT; | ||
| 2599 | else | 2627 | else |
| 2600 | ret = get_errno(sys_openat(arg1, | 2628 | ret = get_errno(sys_openat(arg1, |
| 2601 | path(p), | 2629 | path(p), |
| @@ -2644,16 +2672,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -2644,16 +2672,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 2644 | #if defined(TARGET_NR_linkat) && defined(__NR_linkat) | 2672 | #if defined(TARGET_NR_linkat) && defined(__NR_linkat) |
| 2645 | case TARGET_NR_linkat: | 2673 | case TARGET_NR_linkat: |
| 2646 | if (!arg2 || !arg4) { | 2674 | if (!arg2 || !arg4) { |
| 2647 | - ret = -EFAULT; | 2675 | + ret = -TARGET_EFAULT; |
| 2648 | goto fail; | 2676 | goto fail; |
| 2649 | - } | 2677 | + } |
| 2650 | { | 2678 | { |
| 2651 | void * p2 = NULL; | 2679 | void * p2 = NULL; |
| 2652 | p = lock_user_string(arg2); | 2680 | p = lock_user_string(arg2); |
| 2653 | p2 = lock_user_string(arg4); | 2681 | p2 = lock_user_string(arg4); |
| 2654 | if (!access_ok(VERIFY_READ, p, 1) | 2682 | if (!access_ok(VERIFY_READ, p, 1) |
| 2655 | || !access_ok(VERIFY_READ, p2, 1)) | 2683 | || !access_ok(VERIFY_READ, p2, 1)) |
| 2656 | - ret = -EFAULT; | 2684 | + /* Don't "goto fail" so that cleanup can happen. */ |
| 2685 | + ret = -TARGET_EFAULT; | ||
| 2657 | else | 2686 | else |
| 2658 | ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5)); | 2687 | ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5)); |
| 2659 | if (p2) | 2688 | if (p2) |
| @@ -2671,12 +2700,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -2671,12 +2700,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 2671 | #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat) | 2700 | #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat) |
| 2672 | case TARGET_NR_unlinkat: | 2701 | case TARGET_NR_unlinkat: |
| 2673 | if (!arg2) { | 2702 | if (!arg2) { |
| 2674 | - ret = -EFAULT; | 2703 | + ret = -TARGET_EFAULT; |
| 2675 | goto fail; | 2704 | goto fail; |
| 2676 | } | 2705 | } |
| 2677 | p = lock_user_string(arg2); | 2706 | p = lock_user_string(arg2); |
| 2678 | if (!access_ok(VERIFY_READ, p, 1)) | 2707 | if (!access_ok(VERIFY_READ, p, 1)) |
| 2679 | - ret = -EFAULT; | 2708 | + /* Don't "goto fail" so that cleanup can happen. */ |
| 2709 | + ret = -TARGET_EFAULT; | ||
| 2680 | else | 2710 | else |
| 2681 | ret = get_errno(sys_unlinkat(arg1, p, arg3)); | 2711 | ret = get_errno(sys_unlinkat(arg1, p, arg3)); |
| 2682 | if (p) | 2712 | if (p) |
| @@ -2762,12 +2792,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -2762,12 +2792,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 2762 | #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat) | 2792 | #if defined(TARGET_NR_mknodat) && defined(__NR_mknodat) |
| 2763 | case TARGET_NR_mknodat: | 2793 | case TARGET_NR_mknodat: |
| 2764 | if (!arg2) { | 2794 | if (!arg2) { |
| 2765 | - ret = -EFAULT; | 2795 | + ret = -TARGET_EFAULT; |
| 2766 | goto fail; | 2796 | goto fail; |
| 2767 | } | 2797 | } |
| 2768 | p = lock_user_string(arg2); | 2798 | p = lock_user_string(arg2); |
| 2769 | if (!access_ok(VERIFY_READ, p, 1)) | 2799 | if (!access_ok(VERIFY_READ, p, 1)) |
| 2770 | - ret = -EFAULT; | 2800 | + /* Don't "goto fail" so that cleanup can happen. */ |
| 2801 | + ret = -TARGET_EFAULT; | ||
| 2771 | else | 2802 | else |
| 2772 | ret = get_errno(sys_mknodat(arg1, p, arg3, arg4)); | 2803 | ret = get_errno(sys_mknodat(arg1, p, arg3, arg4)); |
| 2773 | if (p) | 2804 | if (p) |
| @@ -2894,12 +2925,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -2894,12 +2925,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 2894 | #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat) | 2925 | #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat) |
| 2895 | case TARGET_NR_faccessat: | 2926 | case TARGET_NR_faccessat: |
| 2896 | if (!arg2) { | 2927 | if (!arg2) { |
| 2897 | - ret = -EFAULT; | 2928 | + ret = -TARGET_EFAULT; |
| 2898 | goto fail; | 2929 | goto fail; |
| 2899 | } | 2930 | } |
| 2900 | p = lock_user_string(arg2); | 2931 | p = lock_user_string(arg2); |
| 2901 | if (!access_ok(VERIFY_READ, p, 1)) | 2932 | if (!access_ok(VERIFY_READ, p, 1)) |
| 2902 | - ret = -EFAULT; | 2933 | + /* Don't "goto fail" so that cleanup can happen. */ |
| 2934 | + ret = -TARGET_EFAULT; | ||
| 2903 | else | 2935 | else |
| 2904 | ret = get_errno(sys_faccessat(arg1, p, arg3, arg4)); | 2936 | ret = get_errno(sys_faccessat(arg1, p, arg3, arg4)); |
| 2905 | if (p) | 2937 | if (p) |
| @@ -2935,8 +2967,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -2935,8 +2967,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 2935 | #if defined(TARGET_NR_renameat) && defined(__NR_renameat) | 2967 | #if defined(TARGET_NR_renameat) && defined(__NR_renameat) |
| 2936 | case TARGET_NR_renameat: | 2968 | case TARGET_NR_renameat: |
| 2937 | if (!arg2 || !arg4) { | 2969 | if (!arg2 || !arg4) { |
| 2938 | - ret = -EFAULT; | ||
| 2939 | - goto fail; | 2970 | + ret = -TARGET_EFAULT; |
| 2971 | + goto fail; | ||
| 2940 | } | 2972 | } |
| 2941 | { | 2973 | { |
| 2942 | void *p2 = NULL; | 2974 | void *p2 = NULL; |
| @@ -2944,7 +2976,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -2944,7 +2976,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 2944 | p2 = lock_user_string(arg4); | 2976 | p2 = lock_user_string(arg4); |
| 2945 | if (!access_ok(VERIFY_READ, p, 1) | 2977 | if (!access_ok(VERIFY_READ, p, 1) |
| 2946 | || !access_ok(VERIFY_READ, p2, 1)) | 2978 | || !access_ok(VERIFY_READ, p2, 1)) |
| 2947 | - ret = -EFAULT; | 2979 | + /* Don't "goto fail" so that cleanup can happen. */ |
| 2980 | + ret = -TARGET_EFAULT; | ||
| 2948 | else | 2981 | else |
| 2949 | ret = get_errno(sys_renameat(arg1, p, arg3, p2)); | 2982 | ret = get_errno(sys_renameat(arg1, p, arg3, p2)); |
| 2950 | if (p2) | 2983 | if (p2) |
| @@ -2962,12 +2995,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -2962,12 +2995,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 2962 | #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat) | 2995 | #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat) |
| 2963 | case TARGET_NR_mkdirat: | 2996 | case TARGET_NR_mkdirat: |
| 2964 | if (!arg2) { | 2997 | if (!arg2) { |
| 2965 | - ret = -EFAULT; | 2998 | + ret = -TARGET_EFAULT; |
| 2966 | goto fail; | 2999 | goto fail; |
| 2967 | } | 3000 | } |
| 2968 | p = lock_user_string(arg2); | 3001 | p = lock_user_string(arg2); |
| 2969 | if (!access_ok(VERIFY_READ, p, 1)) | 3002 | if (!access_ok(VERIFY_READ, p, 1)) |
| 2970 | - ret = -EFAULT; | 3003 | + /* Don't "goto fail" so that cleanup can happen. */ |
| 3004 | + ret = -TARGET_EFAULT; | ||
| 2971 | else | 3005 | else |
| 2972 | ret = get_errno(sys_mkdirat(arg1, p, arg3)); | 3006 | ret = get_errno(sys_mkdirat(arg1, p, arg3)); |
| 2973 | if (p) | 3007 | if (p) |
| @@ -3202,7 +3236,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -3202,7 +3236,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 3202 | how = SIG_SETMASK; | 3236 | how = SIG_SETMASK; |
| 3203 | break; | 3237 | break; |
| 3204 | default: | 3238 | default: |
| 3205 | - ret = -EINVAL; | 3239 | + ret = -TARGET_EINVAL; |
| 3206 | goto fail; | 3240 | goto fail; |
| 3207 | } | 3241 | } |
| 3208 | p = lock_user(arg2, sizeof(target_sigset_t), 1); | 3242 | p = lock_user(arg2, sizeof(target_sigset_t), 1); |
| @@ -3239,7 +3273,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -3239,7 +3273,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 3239 | how = SIG_SETMASK; | 3273 | how = SIG_SETMASK; |
| 3240 | break; | 3274 | break; |
| 3241 | default: | 3275 | default: |
| 3242 | - ret = -EINVAL; | 3276 | + ret = -TARGET_EINVAL; |
| 3243 | goto fail; | 3277 | goto fail; |
| 3244 | } | 3278 | } |
| 3245 | p = lock_user(arg2, sizeof(target_sigset_t), 1); | 3279 | p = lock_user(arg2, sizeof(target_sigset_t), 1); |
| @@ -3434,16 +3468,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -3434,16 +3468,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 3434 | #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat) | 3468 | #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat) |
| 3435 | case TARGET_NR_symlinkat: | 3469 | case TARGET_NR_symlinkat: |
| 3436 | if (!arg1 || !arg3) { | 3470 | if (!arg1 || !arg3) { |
| 3437 | - ret = -EFAULT; | ||
| 3438 | - goto fail; | ||
| 3439 | - } | 3471 | + ret = -TARGET_EFAULT; |
| 3472 | + goto fail; | ||
| 3473 | + } | ||
| 3440 | { | 3474 | { |
| 3441 | void *p2 = NULL; | 3475 | void *p2 = NULL; |
| 3442 | p = lock_user_string(arg1); | 3476 | p = lock_user_string(arg1); |
| 3443 | p2 = lock_user_string(arg3); | 3477 | p2 = lock_user_string(arg3); |
| 3444 | if (!access_ok(VERIFY_READ, p, 1) | 3478 | if (!access_ok(VERIFY_READ, p, 1) |
| 3445 | || !access_ok(VERIFY_READ, p2, 1)) | 3479 | || !access_ok(VERIFY_READ, p2, 1)) |
| 3446 | - ret = -EFAULT; | 3480 | + /* Don't "goto fail" so that cleanup can happen. */ |
| 3481 | + ret = -TARGET_EFAULT; | ||
| 3447 | else | 3482 | else |
| 3448 | ret = get_errno(sys_symlinkat(p, arg2, p2)); | 3483 | ret = get_errno(sys_symlinkat(p, arg2, p2)); |
| 3449 | if (p2) | 3484 | if (p2) |
| @@ -3470,16 +3505,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -3470,16 +3505,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 3470 | #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat) | 3505 | #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat) |
| 3471 | case TARGET_NR_readlinkat: | 3506 | case TARGET_NR_readlinkat: |
| 3472 | if (!arg2 || !arg3) { | 3507 | if (!arg2 || !arg3) { |
| 3473 | - ret = -EFAULT; | 3508 | + ret = -TARGET_EFAULT; |
| 3474 | goto fail; | 3509 | goto fail; |
| 3475 | - } | 3510 | + } |
| 3476 | { | 3511 | { |
| 3477 | void *p2 = NULL; | 3512 | void *p2 = NULL; |
| 3478 | p = lock_user_string(arg2); | 3513 | p = lock_user_string(arg2); |
| 3479 | p2 = lock_user(arg3, arg4, 0); | 3514 | p2 = lock_user(arg3, arg4, 0); |
| 3480 | if (!access_ok(VERIFY_READ, p, 1) | 3515 | if (!access_ok(VERIFY_READ, p, 1) |
| 3481 | || !access_ok(VERIFY_READ, p2, 1)) | 3516 | || !access_ok(VERIFY_READ, p2, 1)) |
| 3482 | - ret = -EFAULT; | 3517 | + /* Don't "goto fail" so that cleanup can happen. */ |
| 3518 | + ret = -TARGET_EFAULT; | ||
| 3483 | else | 3519 | else |
| 3484 | ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4)); | 3520 | ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4)); |
| 3485 | if (p2) | 3521 | if (p2) |
| @@ -3596,12 +3632,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -3596,12 +3632,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 3596 | #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat) | 3632 | #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat) |
| 3597 | case TARGET_NR_fchmodat: | 3633 | case TARGET_NR_fchmodat: |
| 3598 | if (!arg2) { | 3634 | if (!arg2) { |
| 3599 | - ret = -EFAULT; | 3635 | + ret = -TARGET_EFAULT; |
| 3600 | goto fail; | 3636 | goto fail; |
| 3601 | } | 3637 | } |
| 3602 | p = lock_user_string(arg2); | 3638 | p = lock_user_string(arg2); |
| 3603 | if (!access_ok(VERIFY_READ, p, 1)) | 3639 | if (!access_ok(VERIFY_READ, p, 1)) |
| 3604 | - ret = -EFAULT; | 3640 | + /* Don't "goto fail" so that cleanup can happen. */ |
| 3641 | + ret = -TARGET_EFAULT; | ||
| 3605 | else | 3642 | else |
| 3606 | ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4)); | 3643 | ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4)); |
| 3607 | if (p) | 3644 | if (p) |
| @@ -4055,8 +4092,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -4055,8 +4092,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 4055 | abi_long count = arg3; | 4092 | abi_long count = arg3; |
| 4056 | 4093 | ||
| 4057 | dirp = malloc(count); | 4094 | dirp = malloc(count); |
| 4058 | - if (!dirp) | ||
| 4059 | - return -ENOMEM; | 4095 | + if (!dirp) { |
| 4096 | + ret = -TARGET_EFAULT; | ||
| 4097 | + goto fail; | ||
| 4098 | + } | ||
| 4060 | 4099 | ||
| 4061 | ret = get_errno(sys_getdents(arg1, dirp, count)); | 4100 | ret = get_errno(sys_getdents(arg1, dirp, count)); |
| 4062 | if (!is_error(ret)) { | 4101 | if (!is_error(ret)) { |
| @@ -4213,9 +4252,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -4213,9 +4252,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 4213 | break; | 4252 | break; |
| 4214 | #endif | 4253 | #endif |
| 4215 | case TARGET_NR__sysctl: | 4254 | case TARGET_NR__sysctl: |
| 4216 | - /* We don't implement this, but ENODIR is always a safe | 4255 | + /* We don't implement this, but ENOTDIR is always a safe |
| 4217 | return value. */ | 4256 | return value. */ |
| 4218 | - return -ENOTDIR; | 4257 | + ret = -TARGET_ENOTDIR; |
| 4258 | + break; | ||
| 4219 | case TARGET_NR_sched_setparam: | 4259 | case TARGET_NR_sched_setparam: |
| 4220 | { | 4260 | { |
| 4221 | struct sched_param *target_schp; | 4261 | struct sched_param *target_schp; |
| @@ -4514,12 +4554,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -4514,12 +4554,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 4514 | #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) | 4554 | #if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) |
| 4515 | case TARGET_NR_fchownat: | 4555 | case TARGET_NR_fchownat: |
| 4516 | if (!arg2) { | 4556 | if (!arg2) { |
| 4517 | - ret = -EFAULT; | 4557 | + ret = -TARGET_EFAULT; |
| 4518 | goto fail; | 4558 | goto fail; |
| 4519 | } | 4559 | } |
| 4520 | p = lock_user_string(arg2); | 4560 | p = lock_user_string(arg2); |
| 4521 | if (!access_ok(VERIFY_READ, p, 1)) | 4561 | if (!access_ok(VERIFY_READ, p, 1)) |
| 4522 | - ret = -EFAULT; | 4562 | + /* Don't "goto fail" so that cleanup can happen. */ |
| 4563 | + ret = -TARGET_EFAULT; | ||
| 4523 | else | 4564 | else |
| 4524 | ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5)); | 4565 | ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5)); |
| 4525 | if (p) | 4566 | if (p) |
| @@ -4958,7 +4999,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -4958,7 +4999,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 4958 | else { | 4999 | else { |
| 4959 | p = lock_user_string(arg2); | 5000 | p = lock_user_string(arg2); |
| 4960 | if (!access_ok(VERIFY_READ, p, 1)) | 5001 | if (!access_ok(VERIFY_READ, p, 1)) |
| 4961 | - ret = -EFAULT; | 5002 | + /* Don't "goto fail" so that cleanup can happen. */ |
| 5003 | + ret = -TARGET_EFAULT; | ||
| 4962 | else | 5004 | else |
| 4963 | ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4)); | 5005 | ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4)); |
| 4964 | if (p) | 5006 | if (p) |
| @@ -4974,7 +5016,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -4974,7 +5016,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 4974 | #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list) | 5016 | #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list) |
| 4975 | unimplemented_nowarn: | 5017 | unimplemented_nowarn: |
| 4976 | #endif | 5018 | #endif |
| 4977 | - ret = -ENOSYS; | 5019 | + ret = -TARGET_ENOSYS; |
| 4978 | break; | 5020 | break; |
| 4979 | } | 5021 | } |
| 4980 | fail: | 5022 | fail: |