At the same time, merge do_ipc into the new function. Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- linux-user/syscall.c | 193 ++++++++++++++++++------------------------- 1 file changed, 82 insertions(+), 111 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index a0fbbbbb4a..6ac7532ea6 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4962,113 +4962,6 @@ static inline abi_long do_shmdt(abi_ulong shmaddr) return rv; } -#ifdef TARGET_NR_ipc -/* ??? This only works with linear mappings. */ -/* do_ipc() must return target values and target errnos. */ -static abi_long do_ipc(CPUArchState *cpu_env, - unsigned int call, abi_long first, - abi_long second, abi_long third, - abi_long ptr, abi_long fifth) -{ - int version; - abi_long ret = 0; - - version = call >> 16; - call &= 0xffff; - - switch (call) { - case IPCOP_semop: - ret = do_semop(first, ptr, second); - break; - - case IPCOP_semget: - ret = get_errno(semget(first, second, third)); - break; - - case IPCOP_semctl: { - /* The semun argument to semctl is passed by value, so dereference the - * ptr argument. */ - abi_ulong atptr; - get_user_ual(atptr, ptr); - ret = do_semctl(first, second, third, atptr); - break; - } - - case IPCOP_msgget: - ret = get_errno(msgget(first, second)); - break; - - case IPCOP_msgsnd: - ret = do_msgsnd(first, ptr, second, third); - break; - - case IPCOP_msgctl: - ret = do_msgctl(first, second, ptr); - break; - - case IPCOP_msgrcv: - switch (version) { - case 0: - { - struct target_ipc_kludge { - abi_long msgp; - abi_long msgtyp; - } *tmp; - - if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) { - ret = -TARGET_EFAULT; - break; - } - - ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third); - - unlock_user_struct(tmp, ptr, 0); - break; - } - default: - ret = do_msgrcv(first, ptr, second, fifth, third); - } - break; - - case IPCOP_shmat: - switch (version) { - default: - { - abi_ulong raddr; - raddr = do_shmat(cpu_env, first, ptr, second); - if (is_error(raddr)) - return get_errno(raddr); - if (put_user_ual(raddr, third)) - return -TARGET_EFAULT; - break; - } - case 1: - ret = -TARGET_EINVAL; - break; - } - break; - case IPCOP_shmdt: - ret = do_shmdt(ptr); - break; - - case IPCOP_shmget: - /* IPC_* flag values are the same on all linux platforms */ - ret = get_errno(shmget(first, second, third)); - break; - - /* IPC_* and SHM_* command values are the same on all linux platforms */ - case IPCOP_shmctl: - ret = do_shmctl(first, second, ptr); - break; - default: - gemu_log("Unsupported ipc call: %d (version %d)\n", call, version); - ret = -TARGET_ENOSYS; - break; - } - return ret; -} -#endif - /* kernel structure types definitions */ #define STRUCT(name, ...) STRUCT_ ## name, @@ -8425,6 +8318,85 @@ IMPL(ioctl) return ret; } +#ifdef TARGET_NR_ipc +IMPL(ipc) +{ + unsigned int call = arg1; + abi_long first = arg2; + abi_long second = arg3; + abi_long third = arg4; + abi_long ptr = arg5; + abi_long fifth = arg6; + int version; + abi_long ret; + abi_ulong atptr; + + version = call >> 16; + call &= 0xffff; + + /* IPC_* and SHM_* command values are the same on all linux platforms */ + switch (call) { + case IPCOP_semop: + return do_semop(first, ptr, second); + case IPCOP_semget: + return get_errno(semget(first, second, third)); + case IPCOP_semctl: + /* The semun argument to semctl is passed by value, + * so dereference the ptr argument. + */ + get_user_ual(atptr, ptr); + return do_semctl(first, second, third, atptr); + + case IPCOP_msgget: + return get_errno(msgget(first, second)); + case IPCOP_msgsnd: + return do_msgsnd(first, ptr, second, third); + case IPCOP_msgctl: + return do_msgctl(first, second, ptr); + case IPCOP_msgrcv: + if (version == 0) { + struct target_ipc_kludge { + abi_long msgp; + abi_long msgtyp; + } *tmp; + + if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) { + return -TARGET_EFAULT; + } + + ret = do_msgrcv(first, tswapal(tmp->msgp), second, + tswapal(tmp->msgtyp), third); + unlock_user_struct(tmp, ptr, 0); + return ret; + } + return do_msgrcv(first, ptr, second, fifth, third); + + case IPCOP_shmat: + if (version == 1) { + return -TARGET_EINVAL; + } + ret = do_shmat(cpu_env, first, ptr, second); + if (is_error(ret)) { + return get_errno(ret); + } + if (put_user_ual(ret, third)) { + return -TARGET_EFAULT; + } + return ret; + case IPCOP_shmdt: + return do_shmdt(ptr); + case IPCOP_shmget: + return get_errno(shmget(first, second, third)); + case IPCOP_shmctl: + return do_shmctl(first, second, ptr); + + default: + gemu_log("Unsupported ipc call: %d (version %d)\n", call, version); + return -TARGET_ENOSYS; + } +} +#endif + IMPL(kill) { return get_errno(safe_kill(arg1, target_to_host_signal(arg2))); @@ -10300,10 +10272,6 @@ static abi_long do_syscall1(void *cpu_env, unsigned num, abi_long arg1, void *p; switch(num) { -#ifdef TARGET_NR_ipc - case TARGET_NR_ipc: - return do_ipc(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6); -#endif #ifdef TARGET_NR_semget case TARGET_NR_semget: return get_errno(semget(arg1, arg2, arg3)); @@ -12941,6 +12909,9 @@ static impl_fn *syscall_table(unsigned num) SYSCALL(getxpid); #endif SYSCALL(ioctl); +#ifdef TARGET_NR_ipc + SYSCALL(ipc); +#endif SYSCALL(kill); #ifdef TARGET_NR_link SYSCALL(link); -- 2.17.1