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