@@ -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);
At the same time, merge do_ipc into the new function. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- linux-user/syscall.c | 193 ++++++++++++++++++------------------------- 1 file changed, 82 insertions(+), 111 deletions(-) -- 2.17.1