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: | ... | ... |