Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ a1606b0b

History | View | Annotate | Download (222.4 kB)

1 31e31b8a bellard
/*
2 31e31b8a bellard
 *  Linux syscalls
3 5fafdf24 ths
 *
4 31e31b8a bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 31e31b8a bellard
 *
6 31e31b8a bellard
 *  This program is free software; you can redistribute it and/or modify
7 31e31b8a bellard
 *  it under the terms of the GNU General Public License as published by
8 31e31b8a bellard
 *  the Free Software Foundation; either version 2 of the License, or
9 31e31b8a bellard
 *  (at your option) any later version.
10 31e31b8a bellard
 *
11 31e31b8a bellard
 *  This program is distributed in the hope that it will be useful,
12 31e31b8a bellard
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 31e31b8a bellard
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 31e31b8a bellard
 *  GNU General Public License for more details.
15 31e31b8a bellard
 *
16 31e31b8a bellard
 *  You should have received a copy of the GNU General Public License
17 8167ee88 Blue Swirl
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18 31e31b8a bellard
 */
19 d5b3a9b6 Eduardo Habkost
#define _ATFILE_SOURCE
20 31e31b8a bellard
#include <stdlib.h>
21 31e31b8a bellard
#include <stdio.h>
22 31e31b8a bellard
#include <stdarg.h>
23 04369ff2 bellard
#include <string.h>
24 31e31b8a bellard
#include <elf.h>
25 31e31b8a bellard
#include <endian.h>
26 31e31b8a bellard
#include <errno.h>
27 31e31b8a bellard
#include <unistd.h>
28 31e31b8a bellard
#include <fcntl.h>
29 7854b056 bellard
#include <time.h>
30 82e671d9 pbrook
#include <limits.h>
31 31e31b8a bellard
#include <sys/types.h>
32 d08d3bb8 ths
#include <sys/ipc.h>
33 d08d3bb8 ths
#include <sys/msg.h>
34 31e31b8a bellard
#include <sys/wait.h>
35 31e31b8a bellard
#include <sys/time.h>
36 31e31b8a bellard
#include <sys/stat.h>
37 31e31b8a bellard
#include <sys/mount.h>
38 39b9aae1 ths
#include <sys/prctl.h>
39 31e31b8a bellard
#include <sys/resource.h>
40 31e31b8a bellard
#include <sys/mman.h>
41 31e31b8a bellard
#include <sys/swap.h>
42 31e31b8a bellard
#include <signal.h>
43 31e31b8a bellard
#include <sched.h>
44 60e99246 Aurelien Jarno
#ifdef __ia64__
45 60e99246 Aurelien Jarno
int __clone2(int (*fn)(void *), void *child_stack_base,
46 60e99246 Aurelien Jarno
             size_t stack_size, int flags, void *arg, ...);
47 60e99246 Aurelien Jarno
#endif
48 31e31b8a bellard
#include <sys/socket.h>
49 607175e0 aurel32
#include <sys/un.h>
50 31e31b8a bellard
#include <sys/uio.h>
51 9de5e440 bellard
#include <sys/poll.h>
52 32f36bce bellard
#include <sys/times.h>
53 8853f86e bellard
#include <sys/shm.h>
54 fa294816 ths
#include <sys/sem.h>
55 56c8f68f bellard
#include <sys/statfs.h>
56 ebc05488 bellard
#include <utime.h>
57 a5448a7d bellard
#include <sys/sysinfo.h>
58 3b3f24ad aurel32
#include <sys/utsname.h>
59 72f03900 bellard
//#include <sys/user.h>
60 8853f86e bellard
#include <netinet/ip.h>
61 7854b056 bellard
#include <netinet/tcp.h>
62 0b6d3ae0 aurel32
#include <qemu-common.h>
63 9788c9ca Juan Quintela
#ifdef TARGET_GPROF
64 6d946cda aurel32
#include <sys/gmon.h>
65 6d946cda aurel32
#endif
66 c2882b96 Riku Voipio
#ifdef CONFIG_EVENTFD
67 c2882b96 Riku Voipio
#include <sys/eventfd.h>
68 c2882b96 Riku Voipio
#endif
69 31e31b8a bellard
70 31e31b8a bellard
#define termios host_termios
71 31e31b8a bellard
#define winsize host_winsize
72 31e31b8a bellard
#define termio host_termio
73 04369ff2 bellard
#define sgttyb host_sgttyb /* same as target */
74 04369ff2 bellard
#define tchars host_tchars /* same as target */
75 04369ff2 bellard
#define ltchars host_ltchars /* same as target */
76 31e31b8a bellard
77 31e31b8a bellard
#include <linux/termios.h>
78 31e31b8a bellard
#include <linux/unistd.h>
79 31e31b8a bellard
#include <linux/utsname.h>
80 31e31b8a bellard
#include <linux/cdrom.h>
81 31e31b8a bellard
#include <linux/hdreg.h>
82 31e31b8a bellard
#include <linux/soundcard.h>
83 19b84f3c bellard
#include <linux/kd.h>
84 8fbd6b52 balrog
#include <linux/mtio.h>
85 350d1779 Martin Mohring
#include <linux/fs.h>
86 f7680a55 Ulrich Hecht
#include <linux/fb.h>
87 f7680a55 Ulrich Hecht
#include <linux/vt.h>
88 d7e4036e pbrook
#include "linux_loop.h"
89 da79030f Loïc Minier
#include "cpu-uname.h"
90 31e31b8a bellard
91 3ef693a0 bellard
#include "qemu.h"
92 526ccb7a balrog
#include "qemu-common.h"
93 31e31b8a bellard
94 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
95 d865bab5 pbrook
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
96 d865bab5 pbrook
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
97 d865bab5 pbrook
#else
98 d865bab5 pbrook
/* XXX: Hardcode the above values.  */
99 d865bab5 pbrook
#define CLONE_NPTL_FLAGS2 0
100 30813cea pbrook
#endif
101 30813cea pbrook
102 72f03900 bellard
//#define DEBUG
103 31e31b8a bellard
104 1a9353d2 bellard
//#include <linux/msdos_fs.h>
105 6556a833 aurel32
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
106 6556a833 aurel32
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
107 1a9353d2 bellard
108 70a194b9 bellard
109 70a194b9 bellard
#undef _syscall0
110 70a194b9 bellard
#undef _syscall1
111 70a194b9 bellard
#undef _syscall2
112 70a194b9 bellard
#undef _syscall3
113 70a194b9 bellard
#undef _syscall4
114 70a194b9 bellard
#undef _syscall5
115 83fcb515 bellard
#undef _syscall6
116 70a194b9 bellard
117 83fcb515 bellard
#define _syscall0(type,name)                \
118 8fcd3692 blueswir1
static type name (void)                        \
119 83fcb515 bellard
{                                        \
120 83fcb515 bellard
        return syscall(__NR_##name);        \
121 83fcb515 bellard
}
122 70a194b9 bellard
123 83fcb515 bellard
#define _syscall1(type,name,type1,arg1)                \
124 8fcd3692 blueswir1
static type name (type1 arg1)                        \
125 83fcb515 bellard
{                                                \
126 83fcb515 bellard
        return syscall(__NR_##name, arg1);        \
127 70a194b9 bellard
}
128 70a194b9 bellard
129 83fcb515 bellard
#define _syscall2(type,name,type1,arg1,type2,arg2)        \
130 8fcd3692 blueswir1
static type name (type1 arg1,type2 arg2)                \
131 83fcb515 bellard
{                                                        \
132 83fcb515 bellard
        return syscall(__NR_##name, arg1, arg2);        \
133 70a194b9 bellard
}
134 70a194b9 bellard
135 83fcb515 bellard
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)        \
136 8fcd3692 blueswir1
static type name (type1 arg1,type2 arg2,type3 arg3)                \
137 83fcb515 bellard
{                                                                \
138 83fcb515 bellard
        return syscall(__NR_##name, arg1, arg2, arg3);                \
139 70a194b9 bellard
}
140 70a194b9 bellard
141 83fcb515 bellard
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)        \
142 8fcd3692 blueswir1
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)                        \
143 83fcb515 bellard
{                                                                                \
144 83fcb515 bellard
        return syscall(__NR_##name, arg1, arg2, arg3, arg4);                        \
145 70a194b9 bellard
}
146 70a194b9 bellard
147 83fcb515 bellard
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
148 83fcb515 bellard
                  type5,arg5)                                                        \
149 8fcd3692 blueswir1
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)        \
150 83fcb515 bellard
{                                                                                \
151 83fcb515 bellard
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);                \
152 70a194b9 bellard
}
153 70a194b9 bellard
154 83fcb515 bellard
155 83fcb515 bellard
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
156 83fcb515 bellard
                  type5,arg5,type6,arg6)                                        \
157 8fcd3692 blueswir1
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,        \
158 8fcd3692 blueswir1
                  type6 arg6)                                                        \
159 83fcb515 bellard
{                                                                                \
160 83fcb515 bellard
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
161 70a194b9 bellard
}
162 83fcb515 bellard
163 70a194b9 bellard
164 31e31b8a bellard
#define __NR_sys_uname __NR_uname
165 92a34c10 ths
#define __NR_sys_faccessat __NR_faccessat
166 814d7977 ths
#define __NR_sys_fchmodat __NR_fchmodat
167 ccfa72b7 ths
#define __NR_sys_fchownat __NR_fchownat
168 6a24a778 balrog
#define __NR_sys_fstatat64 __NR_fstatat64
169 ac8a6556 balrog
#define __NR_sys_futimesat __NR_futimesat
170 72f03900 bellard
#define __NR_sys_getcwd1 __NR_getcwd
171 72f03900 bellard
#define __NR_sys_getdents __NR_getdents
172 dab2ed99 bellard
#define __NR_sys_getdents64 __NR_getdents64
173 c6cda17a ths
#define __NR_sys_getpriority __NR_getpriority
174 64f0ce4c ths
#define __NR_sys_linkat __NR_linkat
175 4472ad0d ths
#define __NR_sys_mkdirat __NR_mkdirat
176 75ac37a0 ths
#define __NR_sys_mknodat __NR_mknodat
177 9d33b76b aurel32
#define __NR_sys_newfstatat __NR_newfstatat
178 82424832 ths
#define __NR_sys_openat __NR_openat
179 5e0ccb18 ths
#define __NR_sys_readlinkat __NR_readlinkat
180 722183f6 ths
#define __NR_sys_renameat __NR_renameat
181 66fb9763 bellard
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
182 f0b6243d ths
#define __NR_sys_symlinkat __NR_symlinkat
183 7494b0f9 ths
#define __NR_sys_syslog __NR_syslog
184 71455574 ths
#define __NR_sys_tgkill __NR_tgkill
185 4cae1d16 ths
#define __NR_sys_tkill __NR_tkill
186 8170f56b ths
#define __NR_sys_unlinkat __NR_unlinkat
187 9007f0ef ths
#define __NR_sys_utimensat __NR_utimensat
188 bd0c5661 pbrook
#define __NR_sys_futex __NR_futex
189 39b59763 aurel32
#define __NR_sys_inotify_init __NR_inotify_init
190 39b59763 aurel32
#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
191 39b59763 aurel32
#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
192 31e31b8a bellard
193 bc51c5c9 bellard
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
194 9af9eaaa bellard
#define __NR__llseek __NR_lseek
195 9af9eaaa bellard
#endif
196 9af9eaaa bellard
197 72f03900 bellard
#ifdef __NR_gettid
198 31e31b8a bellard
_syscall0(int, gettid)
199 72f03900 bellard
#else
200 0da46a6e ths
/* This is a replacement for the host gettid() and must return a host
201 0da46a6e ths
   errno. */
202 72f03900 bellard
static int gettid(void) {
203 72f03900 bellard
    return -ENOSYS;
204 72f03900 bellard
}
205 72f03900 bellard
#endif
206 3b3f24ad aurel32
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
207 3b3f24ad aurel32
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
208 3b3f24ad aurel32
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
209 3b3f24ad aurel32
#endif
210 3b3f24ad aurel32
_syscall2(int, sys_getpriority, int, which, int, who);
211 909b69cf Paul Brook
#if defined(TARGET_NR__llseek) && !defined (__x86_64__)
212 3b3f24ad aurel32
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
213 3b3f24ad aurel32
          loff_t *, res, uint, wh);
214 3b3f24ad aurel32
#endif
215 3b3f24ad aurel32
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
216 3b3f24ad aurel32
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
217 3b3f24ad aurel32
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
218 3b3f24ad aurel32
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
219 3b3f24ad aurel32
#endif
220 3b3f24ad aurel32
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
221 3b3f24ad aurel32
_syscall2(int,sys_tkill,int,tid,int,sig)
222 3b3f24ad aurel32
#endif
223 3b3f24ad aurel32
#ifdef __NR_exit_group
224 3b3f24ad aurel32
_syscall1(int,exit_group,int,error_code)
225 3b3f24ad aurel32
#endif
226 3b3f24ad aurel32
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
227 3b3f24ad aurel32
_syscall1(int,set_tid_address,int *,tidptr)
228 3b3f24ad aurel32
#endif
229 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
230 3b3f24ad aurel32
#if defined(TARGET_NR_futex) && defined(__NR_futex)
231 3b3f24ad aurel32
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
232 3b3f24ad aurel32
          const struct timespec *,timeout,int *,uaddr2,int,val3)
233 3b3f24ad aurel32
#endif
234 3b3f24ad aurel32
#endif
235 3b3f24ad aurel32
236 3b3f24ad aurel32
static bitmask_transtbl fcntl_flags_tbl[] = {
237 3b3f24ad aurel32
  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
238 3b3f24ad aurel32
  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
239 3b3f24ad aurel32
  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
240 3b3f24ad aurel32
  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
241 3b3f24ad aurel32
  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
242 3b3f24ad aurel32
  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
243 3b3f24ad aurel32
  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
244 3b3f24ad aurel32
  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
245 3b3f24ad aurel32
  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
246 3b3f24ad aurel32
  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
247 3b3f24ad aurel32
  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
248 3b3f24ad aurel32
  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
249 3b3f24ad aurel32
  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
250 3b3f24ad aurel32
#if defined(O_DIRECT)
251 3b3f24ad aurel32
  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
252 3b3f24ad aurel32
#endif
253 3b3f24ad aurel32
  { 0, 0, 0, 0 }
254 3b3f24ad aurel32
};
255 3b3f24ad aurel32
256 3b3f24ad aurel32
#define COPY_UTSNAME_FIELD(dest, src) \
257 3b3f24ad aurel32
  do { \
258 3b3f24ad aurel32
      /* __NEW_UTS_LEN doesn't include terminating null */ \
259 3b3f24ad aurel32
      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
260 3b3f24ad aurel32
      (dest)[__NEW_UTS_LEN] = '\0'; \
261 3b3f24ad aurel32
  } while (0)
262 3b3f24ad aurel32
263 3b3f24ad aurel32
static int sys_uname(struct new_utsname *buf)
264 3b3f24ad aurel32
{
265 3b3f24ad aurel32
  struct utsname uts_buf;
266 3b3f24ad aurel32
267 3b3f24ad aurel32
  if (uname(&uts_buf) < 0)
268 3b3f24ad aurel32
      return (-1);
269 3b3f24ad aurel32
270 3b3f24ad aurel32
  /*
271 3b3f24ad aurel32
   * Just in case these have some differences, we
272 3b3f24ad aurel32
   * translate utsname to new_utsname (which is the
273 3b3f24ad aurel32
   * struct linux kernel uses).
274 3b3f24ad aurel32
   */
275 3b3f24ad aurel32
276 3b3f24ad aurel32
  bzero(buf, sizeof (*buf));
277 3b3f24ad aurel32
  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
278 3b3f24ad aurel32
  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
279 3b3f24ad aurel32
  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
280 3b3f24ad aurel32
  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
281 3b3f24ad aurel32
  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
282 3b3f24ad aurel32
#ifdef _GNU_SOURCE
283 3b3f24ad aurel32
  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
284 3b3f24ad aurel32
#endif
285 3b3f24ad aurel32
  return (0);
286 3b3f24ad aurel32
287 3b3f24ad aurel32
#undef COPY_UTSNAME_FIELD
288 3b3f24ad aurel32
}
289 3b3f24ad aurel32
290 3b3f24ad aurel32
static int sys_getcwd1(char *buf, size_t size)
291 3b3f24ad aurel32
{
292 3b3f24ad aurel32
  if (getcwd(buf, size) == NULL) {
293 3b3f24ad aurel32
      /* getcwd() sets errno */
294 3b3f24ad aurel32
      return (-1);
295 3b3f24ad aurel32
  }
296 aaf4ad39 aurel32
  return strlen(buf)+1;
297 3b3f24ad aurel32
}
298 3b3f24ad aurel32
299 3b3f24ad aurel32
#ifdef CONFIG_ATFILE
300 3b3f24ad aurel32
/*
301 3b3f24ad aurel32
 * Host system seems to have atfile syscall stubs available.  We
302 3b3f24ad aurel32
 * now enable them one by one as specified by target syscall_nr.h.
303 3b3f24ad aurel32
 */
304 3b3f24ad aurel32
305 3b3f24ad aurel32
#ifdef TARGET_NR_faccessat
306 465c9f06 aurel32
static int sys_faccessat(int dirfd, const char *pathname, int mode)
307 3b3f24ad aurel32
{
308 465c9f06 aurel32
  return (faccessat(dirfd, pathname, mode, 0));
309 3b3f24ad aurel32
}
310 3b3f24ad aurel32
#endif
311 3b3f24ad aurel32
#ifdef TARGET_NR_fchmodat
312 465c9f06 aurel32
static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
313 3b3f24ad aurel32
{
314 465c9f06 aurel32
  return (fchmodat(dirfd, pathname, mode, 0));
315 3b3f24ad aurel32
}
316 3b3f24ad aurel32
#endif
317 fda33744 aurel32
#if defined(TARGET_NR_fchownat) && defined(USE_UID16)
318 3b3f24ad aurel32
static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
319 3b3f24ad aurel32
    gid_t group, int flags)
320 3b3f24ad aurel32
{
321 3b3f24ad aurel32
  return (fchownat(dirfd, pathname, owner, group, flags));
322 3b3f24ad aurel32
}
323 3b3f24ad aurel32
#endif
324 3b3f24ad aurel32
#ifdef __NR_fstatat64
325 3b3f24ad aurel32
static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
326 3b3f24ad aurel32
    int flags)
327 3b3f24ad aurel32
{
328 3b3f24ad aurel32
  return (fstatat(dirfd, pathname, buf, flags));
329 3b3f24ad aurel32
}
330 3b3f24ad aurel32
#endif
331 3b3f24ad aurel32
#ifdef __NR_newfstatat
332 3b3f24ad aurel32
static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
333 3b3f24ad aurel32
    int flags)
334 3b3f24ad aurel32
{
335 3b3f24ad aurel32
  return (fstatat(dirfd, pathname, buf, flags));
336 3b3f24ad aurel32
}
337 3b3f24ad aurel32
#endif
338 3b3f24ad aurel32
#ifdef TARGET_NR_futimesat
339 3b3f24ad aurel32
static int sys_futimesat(int dirfd, const char *pathname,
340 3b3f24ad aurel32
    const struct timeval times[2])
341 3b3f24ad aurel32
{
342 3b3f24ad aurel32
  return (futimesat(dirfd, pathname, times));
343 3b3f24ad aurel32
}
344 3b3f24ad aurel32
#endif
345 3b3f24ad aurel32
#ifdef TARGET_NR_linkat
346 3b3f24ad aurel32
static int sys_linkat(int olddirfd, const char *oldpath,
347 3b3f24ad aurel32
    int newdirfd, const char *newpath, int flags)
348 3b3f24ad aurel32
{
349 3b3f24ad aurel32
  return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
350 3b3f24ad aurel32
}
351 3b3f24ad aurel32
#endif
352 3b3f24ad aurel32
#ifdef TARGET_NR_mkdirat
353 3b3f24ad aurel32
static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
354 3b3f24ad aurel32
{
355 3b3f24ad aurel32
  return (mkdirat(dirfd, pathname, mode));
356 3b3f24ad aurel32
}
357 3b3f24ad aurel32
#endif
358 3b3f24ad aurel32
#ifdef TARGET_NR_mknodat
359 3b3f24ad aurel32
static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
360 3b3f24ad aurel32
    dev_t dev)
361 3b3f24ad aurel32
{
362 3b3f24ad aurel32
  return (mknodat(dirfd, pathname, mode, dev));
363 3b3f24ad aurel32
}
364 3b3f24ad aurel32
#endif
365 3b3f24ad aurel32
#ifdef TARGET_NR_openat
366 3b3f24ad aurel32
static int sys_openat(int dirfd, const char *pathname, int flags, ...)
367 3b3f24ad aurel32
{
368 3b3f24ad aurel32
  /*
369 3b3f24ad aurel32
   * open(2) has extra parameter 'mode' when called with
370 3b3f24ad aurel32
   * flag O_CREAT.
371 3b3f24ad aurel32
   */
372 3b3f24ad aurel32
  if ((flags & O_CREAT) != 0) {
373 3b3f24ad aurel32
      va_list ap;
374 3b3f24ad aurel32
      mode_t mode;
375 3b3f24ad aurel32
376 3b3f24ad aurel32
      /*
377 3b3f24ad aurel32
       * Get the 'mode' parameter and translate it to
378 3b3f24ad aurel32
       * host bits.
379 3b3f24ad aurel32
       */
380 3b3f24ad aurel32
      va_start(ap, flags);
381 3b3f24ad aurel32
      mode = va_arg(ap, mode_t);
382 3b3f24ad aurel32
      mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
383 3b3f24ad aurel32
      va_end(ap);
384 3b3f24ad aurel32
385 3b3f24ad aurel32
      return (openat(dirfd, pathname, flags, mode));
386 3b3f24ad aurel32
  }
387 3b3f24ad aurel32
  return (openat(dirfd, pathname, flags));
388 3b3f24ad aurel32
}
389 3b3f24ad aurel32
#endif
390 3b3f24ad aurel32
#ifdef TARGET_NR_readlinkat
391 3b3f24ad aurel32
static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
392 3b3f24ad aurel32
{
393 3b3f24ad aurel32
  return (readlinkat(dirfd, pathname, buf, bufsiz));
394 3b3f24ad aurel32
}
395 3b3f24ad aurel32
#endif
396 3b3f24ad aurel32
#ifdef TARGET_NR_renameat
397 3b3f24ad aurel32
static int sys_renameat(int olddirfd, const char *oldpath,
398 3b3f24ad aurel32
    int newdirfd, const char *newpath)
399 3b3f24ad aurel32
{
400 3b3f24ad aurel32
  return (renameat(olddirfd, oldpath, newdirfd, newpath));
401 3b3f24ad aurel32
}
402 3b3f24ad aurel32
#endif
403 3b3f24ad aurel32
#ifdef TARGET_NR_symlinkat
404 3b3f24ad aurel32
static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
405 3b3f24ad aurel32
{
406 3b3f24ad aurel32
  return (symlinkat(oldpath, newdirfd, newpath));
407 3b3f24ad aurel32
}
408 3b3f24ad aurel32
#endif
409 3b3f24ad aurel32
#ifdef TARGET_NR_unlinkat
410 3b3f24ad aurel32
static int sys_unlinkat(int dirfd, const char *pathname, int flags)
411 3b3f24ad aurel32
{
412 3b3f24ad aurel32
  return (unlinkat(dirfd, pathname, flags));
413 3b3f24ad aurel32
}
414 3b3f24ad aurel32
#endif
415 3b3f24ad aurel32
#else /* !CONFIG_ATFILE */
416 3b3f24ad aurel32
417 3b3f24ad aurel32
/*
418 3b3f24ad aurel32
 * Try direct syscalls instead
419 3b3f24ad aurel32
 */
420 92a34c10 ths
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
421 465c9f06 aurel32
_syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
422 92a34c10 ths
#endif
423 814d7977 ths
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
424 465c9f06 aurel32
_syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
425 814d7977 ths
#endif
426 4583f589 blueswir1
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
427 ccfa72b7 ths
_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
428 ccfa72b7 ths
          uid_t,owner,gid_t,group,int,flags)
429 ccfa72b7 ths
#endif
430 9d33b76b aurel32
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
431 9d33b76b aurel32
        defined(__NR_fstatat64)
432 6a24a778 balrog
_syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
433 6a24a778 balrog
          struct stat *,buf,int,flags)
434 6a24a778 balrog
#endif
435 ac8a6556 balrog
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
436 ac8a6556 balrog
_syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
437 ac8a6556 balrog
         const struct timeval *,times)
438 ac8a6556 balrog
#endif
439 3b3f24ad aurel32
#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
440 3b3f24ad aurel32
        defined(__NR_newfstatat)
441 3b3f24ad aurel32
_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
442 3b3f24ad aurel32
          struct stat *,buf,int,flags)
443 8fcd3692 blueswir1
#endif
444 64f0ce4c ths
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
445 64f0ce4c ths
_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
446 3b3f24ad aurel32
      int,newdirfd,const char *,newpath,int,flags)
447 64f0ce4c ths
#endif
448 4472ad0d ths
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
449 4472ad0d ths
_syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
450 4472ad0d ths
#endif
451 75ac37a0 ths
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
452 75ac37a0 ths
_syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
453 75ac37a0 ths
          mode_t,mode,dev_t,dev)
454 75ac37a0 ths
#endif
455 82424832 ths
#if defined(TARGET_NR_openat) && defined(__NR_openat)
456 82424832 ths
_syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
457 82424832 ths
#endif
458 5e0ccb18 ths
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
459 5e0ccb18 ths
_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
460 5e0ccb18 ths
          char *,buf,size_t,bufsize)
461 5e0ccb18 ths
#endif
462 722183f6 ths
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
463 722183f6 ths
_syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
464 722183f6 ths
          int,newdirfd,const char *,newpath)
465 722183f6 ths
#endif
466 b51eaa82 ths
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
467 f0b6243d ths
_syscall3(int,sys_symlinkat,const char *,oldpath,
468 f0b6243d ths
          int,newdirfd,const char *,newpath)
469 f0b6243d ths
#endif
470 8170f56b ths
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
471 8170f56b ths
_syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
472 8170f56b ths
#endif
473 ebc996f3 Riku Voipio
474 ebc996f3 Riku Voipio
#endif /* CONFIG_ATFILE */
475 ebc996f3 Riku Voipio
476 ebc996f3 Riku Voipio
#ifdef CONFIG_UTIMENSAT
477 ebc996f3 Riku Voipio
static int sys_utimensat(int dirfd, const char *pathname,
478 ebc996f3 Riku Voipio
    const struct timespec times[2], int flags)
479 ebc996f3 Riku Voipio
{
480 ebc996f3 Riku Voipio
    if (pathname == NULL)
481 ebc996f3 Riku Voipio
        return futimens(dirfd, times);
482 ebc996f3 Riku Voipio
    else
483 ebc996f3 Riku Voipio
        return utimensat(dirfd, pathname, times, flags);
484 ebc996f3 Riku Voipio
}
485 ebc996f3 Riku Voipio
#else
486 9007f0ef ths
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
487 9007f0ef ths
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
488 9007f0ef ths
          const struct timespec *,tsp,int,flags)
489 9007f0ef ths
#endif
490 ebc996f3 Riku Voipio
#endif /* CONFIG_UTIMENSAT  */
491 3b3f24ad aurel32
492 3b3f24ad aurel32
#ifdef CONFIG_INOTIFY
493 8690e420 aurel32
#include <sys/inotify.h>
494 3b3f24ad aurel32
495 39b59763 aurel32
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
496 3b3f24ad aurel32
static int sys_inotify_init(void)
497 3b3f24ad aurel32
{
498 3b3f24ad aurel32
  return (inotify_init());
499 3b3f24ad aurel32
}
500 39b59763 aurel32
#endif
501 39b59763 aurel32
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
502 3b3f24ad aurel32
static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
503 3b3f24ad aurel32
{
504 3b3f24ad aurel32
  return (inotify_add_watch(fd, pathname, mask));
505 3b3f24ad aurel32
}
506 39b59763 aurel32
#endif
507 39b59763 aurel32
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
508 3b3f24ad aurel32
static int sys_inotify_rm_watch(int fd, int32_t wd)
509 3b3f24ad aurel32
{
510 8690e420 aurel32
  return (inotify_rm_watch(fd, wd));
511 3b3f24ad aurel32
}
512 bd0c5661 pbrook
#endif
513 c05c7a73 Riku Voipio
#ifdef CONFIG_INOTIFY1
514 c05c7a73 Riku Voipio
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
515 c05c7a73 Riku Voipio
static int sys_inotify_init1(int flags)
516 c05c7a73 Riku Voipio
{
517 c05c7a73 Riku Voipio
  return (inotify_init1(flags));
518 c05c7a73 Riku Voipio
}
519 c05c7a73 Riku Voipio
#endif
520 c05c7a73 Riku Voipio
#endif
521 3b3f24ad aurel32
#else
522 3b3f24ad aurel32
/* Userspace can usually survive runtime without inotify */
523 3b3f24ad aurel32
#undef TARGET_NR_inotify_init
524 c05c7a73 Riku Voipio
#undef TARGET_NR_inotify_init1
525 3b3f24ad aurel32
#undef TARGET_NR_inotify_add_watch
526 3b3f24ad aurel32
#undef TARGET_NR_inotify_rm_watch
527 3b3f24ad aurel32
#endif /* CONFIG_INOTIFY  */
528 3b3f24ad aurel32
529 66fb9763 bellard
530 66fb9763 bellard
extern int personality(int);
531 9de5e440 bellard
extern int flock(int, int);
532 9de5e440 bellard
extern int setfsuid(int);
533 9de5e440 bellard
extern int setfsgid(int);
534 19b84f3c bellard
extern int setgroups(int, gid_t *);
535 31e31b8a bellard
536 b92c47c1 ths
#define ERRNO_TABLE_SIZE 1200
537 b92c47c1 ths
538 b92c47c1 ths
/* target_to_host_errno_table[] is initialized from
539 b92c47c1 ths
 * host_to_target_errno_table[] in syscall_init(). */
540 b92c47c1 ths
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
541 b92c47c1 ths
};
542 b92c47c1 ths
543 637947f1 ths
/*
544 fe8f096b ths
 * This list is the union of errno values overridden in asm-<arch>/errno.h
545 637947f1 ths
 * minus the errnos that are not actually generic to all archs.
546 637947f1 ths
 */
547 b92c47c1 ths
static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
548 637947f1 ths
    [EIDRM]                = TARGET_EIDRM,
549 637947f1 ths
    [ECHRNG]                = TARGET_ECHRNG,
550 637947f1 ths
    [EL2NSYNC]                = TARGET_EL2NSYNC,
551 637947f1 ths
    [EL3HLT]                = TARGET_EL3HLT,
552 637947f1 ths
    [EL3RST]                = TARGET_EL3RST,
553 637947f1 ths
    [ELNRNG]                = TARGET_ELNRNG,
554 637947f1 ths
    [EUNATCH]                = TARGET_EUNATCH,
555 637947f1 ths
    [ENOCSI]                = TARGET_ENOCSI,
556 637947f1 ths
    [EL2HLT]                = TARGET_EL2HLT,
557 637947f1 ths
    [EDEADLK]                = TARGET_EDEADLK,
558 637947f1 ths
    [ENOLCK]                = TARGET_ENOLCK,
559 637947f1 ths
    [EBADE]                = TARGET_EBADE,
560 637947f1 ths
    [EBADR]                = TARGET_EBADR,
561 637947f1 ths
    [EXFULL]                = TARGET_EXFULL,
562 637947f1 ths
    [ENOANO]                = TARGET_ENOANO,
563 637947f1 ths
    [EBADRQC]                = TARGET_EBADRQC,
564 637947f1 ths
    [EBADSLT]                = TARGET_EBADSLT,
565 637947f1 ths
    [EBFONT]                = TARGET_EBFONT,
566 637947f1 ths
    [ENOSTR]                = TARGET_ENOSTR,
567 637947f1 ths
    [ENODATA]                = TARGET_ENODATA,
568 637947f1 ths
    [ETIME]                = TARGET_ETIME,
569 637947f1 ths
    [ENOSR]                = TARGET_ENOSR,
570 637947f1 ths
    [ENONET]                = TARGET_ENONET,
571 637947f1 ths
    [ENOPKG]                = TARGET_ENOPKG,
572 637947f1 ths
    [EREMOTE]                = TARGET_EREMOTE,
573 637947f1 ths
    [ENOLINK]                = TARGET_ENOLINK,
574 637947f1 ths
    [EADV]                = TARGET_EADV,
575 637947f1 ths
    [ESRMNT]                = TARGET_ESRMNT,
576 637947f1 ths
    [ECOMM]                = TARGET_ECOMM,
577 637947f1 ths
    [EPROTO]                = TARGET_EPROTO,
578 637947f1 ths
    [EDOTDOT]                = TARGET_EDOTDOT,
579 637947f1 ths
    [EMULTIHOP]                = TARGET_EMULTIHOP,
580 637947f1 ths
    [EBADMSG]                = TARGET_EBADMSG,
581 637947f1 ths
    [ENAMETOOLONG]        = TARGET_ENAMETOOLONG,
582 637947f1 ths
    [EOVERFLOW]                = TARGET_EOVERFLOW,
583 637947f1 ths
    [ENOTUNIQ]                = TARGET_ENOTUNIQ,
584 637947f1 ths
    [EBADFD]                = TARGET_EBADFD,
585 637947f1 ths
    [EREMCHG]                = TARGET_EREMCHG,
586 637947f1 ths
    [ELIBACC]                = TARGET_ELIBACC,
587 637947f1 ths
    [ELIBBAD]                = TARGET_ELIBBAD,
588 637947f1 ths
    [ELIBSCN]                = TARGET_ELIBSCN,
589 637947f1 ths
    [ELIBMAX]                = TARGET_ELIBMAX,
590 637947f1 ths
    [ELIBEXEC]                = TARGET_ELIBEXEC,
591 637947f1 ths
    [EILSEQ]                = TARGET_EILSEQ,
592 637947f1 ths
    [ENOSYS]                = TARGET_ENOSYS,
593 637947f1 ths
    [ELOOP]                = TARGET_ELOOP,
594 637947f1 ths
    [ERESTART]                = TARGET_ERESTART,
595 637947f1 ths
    [ESTRPIPE]                = TARGET_ESTRPIPE,
596 637947f1 ths
    [ENOTEMPTY]                = TARGET_ENOTEMPTY,
597 637947f1 ths
    [EUSERS]                = TARGET_EUSERS,
598 637947f1 ths
    [ENOTSOCK]                = TARGET_ENOTSOCK,
599 637947f1 ths
    [EDESTADDRREQ]        = TARGET_EDESTADDRREQ,
600 637947f1 ths
    [EMSGSIZE]                = TARGET_EMSGSIZE,
601 637947f1 ths
    [EPROTOTYPE]        = TARGET_EPROTOTYPE,
602 637947f1 ths
    [ENOPROTOOPT]        = TARGET_ENOPROTOOPT,
603 637947f1 ths
    [EPROTONOSUPPORT]        = TARGET_EPROTONOSUPPORT,
604 637947f1 ths
    [ESOCKTNOSUPPORT]        = TARGET_ESOCKTNOSUPPORT,
605 637947f1 ths
    [EOPNOTSUPP]        = TARGET_EOPNOTSUPP,
606 637947f1 ths
    [EPFNOSUPPORT]        = TARGET_EPFNOSUPPORT,
607 637947f1 ths
    [EAFNOSUPPORT]        = TARGET_EAFNOSUPPORT,
608 637947f1 ths
    [EADDRINUSE]        = TARGET_EADDRINUSE,
609 637947f1 ths
    [EADDRNOTAVAIL]        = TARGET_EADDRNOTAVAIL,
610 637947f1 ths
    [ENETDOWN]                = TARGET_ENETDOWN,
611 637947f1 ths
    [ENETUNREACH]        = TARGET_ENETUNREACH,
612 637947f1 ths
    [ENETRESET]                = TARGET_ENETRESET,
613 637947f1 ths
    [ECONNABORTED]        = TARGET_ECONNABORTED,
614 637947f1 ths
    [ECONNRESET]        = TARGET_ECONNRESET,
615 637947f1 ths
    [ENOBUFS]                = TARGET_ENOBUFS,
616 637947f1 ths
    [EISCONN]                = TARGET_EISCONN,
617 637947f1 ths
    [ENOTCONN]                = TARGET_ENOTCONN,
618 637947f1 ths
    [EUCLEAN]                = TARGET_EUCLEAN,
619 637947f1 ths
    [ENOTNAM]                = TARGET_ENOTNAM,
620 637947f1 ths
    [ENAVAIL]                = TARGET_ENAVAIL,
621 637947f1 ths
    [EISNAM]                = TARGET_EISNAM,
622 637947f1 ths
    [EREMOTEIO]                = TARGET_EREMOTEIO,
623 637947f1 ths
    [ESHUTDOWN]                = TARGET_ESHUTDOWN,
624 637947f1 ths
    [ETOOMANYREFS]        = TARGET_ETOOMANYREFS,
625 637947f1 ths
    [ETIMEDOUT]                = TARGET_ETIMEDOUT,
626 637947f1 ths
    [ECONNREFUSED]        = TARGET_ECONNREFUSED,
627 637947f1 ths
    [EHOSTDOWN]                = TARGET_EHOSTDOWN,
628 637947f1 ths
    [EHOSTUNREACH]        = TARGET_EHOSTUNREACH,
629 637947f1 ths
    [EALREADY]                = TARGET_EALREADY,
630 637947f1 ths
    [EINPROGRESS]        = TARGET_EINPROGRESS,
631 637947f1 ths
    [ESTALE]                = TARGET_ESTALE,
632 637947f1 ths
    [ECANCELED]                = TARGET_ECANCELED,
633 637947f1 ths
    [ENOMEDIUM]                = TARGET_ENOMEDIUM,
634 637947f1 ths
    [EMEDIUMTYPE]        = TARGET_EMEDIUMTYPE,
635 b7fe5db7 ths
#ifdef ENOKEY
636 637947f1 ths
    [ENOKEY]                = TARGET_ENOKEY,
637 b7fe5db7 ths
#endif
638 b7fe5db7 ths
#ifdef EKEYEXPIRED
639 637947f1 ths
    [EKEYEXPIRED]        = TARGET_EKEYEXPIRED,
640 b7fe5db7 ths
#endif
641 b7fe5db7 ths
#ifdef EKEYREVOKED
642 637947f1 ths
    [EKEYREVOKED]        = TARGET_EKEYREVOKED,
643 b7fe5db7 ths
#endif
644 b7fe5db7 ths
#ifdef EKEYREJECTED
645 637947f1 ths
    [EKEYREJECTED]        = TARGET_EKEYREJECTED,
646 b7fe5db7 ths
#endif
647 b7fe5db7 ths
#ifdef EOWNERDEAD
648 637947f1 ths
    [EOWNERDEAD]        = TARGET_EOWNERDEAD,
649 b7fe5db7 ths
#endif
650 b7fe5db7 ths
#ifdef ENOTRECOVERABLE
651 637947f1 ths
    [ENOTRECOVERABLE]        = TARGET_ENOTRECOVERABLE,
652 b7fe5db7 ths
#endif
653 b92c47c1 ths
};
654 637947f1 ths
655 637947f1 ths
static inline int host_to_target_errno(int err)
656 637947f1 ths
{
657 637947f1 ths
    if(host_to_target_errno_table[err])
658 637947f1 ths
        return host_to_target_errno_table[err];
659 637947f1 ths
    return err;
660 637947f1 ths
}
661 637947f1 ths
662 b92c47c1 ths
static inline int target_to_host_errno(int err)
663 b92c47c1 ths
{
664 b92c47c1 ths
    if (target_to_host_errno_table[err])
665 b92c47c1 ths
        return target_to_host_errno_table[err];
666 b92c47c1 ths
    return err;
667 b92c47c1 ths
}
668 b92c47c1 ths
669 992f48a0 blueswir1
static inline abi_long get_errno(abi_long ret)
670 31e31b8a bellard
{
671 31e31b8a bellard
    if (ret == -1)
672 637947f1 ths
        return -host_to_target_errno(errno);
673 31e31b8a bellard
    else
674 31e31b8a bellard
        return ret;
675 31e31b8a bellard
}
676 31e31b8a bellard
677 992f48a0 blueswir1
static inline int is_error(abi_long ret)
678 31e31b8a bellard
{
679 992f48a0 blueswir1
    return (abi_ulong)ret >= (abi_ulong)(-4096);
680 31e31b8a bellard
}
681 31e31b8a bellard
682 b92c47c1 ths
char *target_strerror(int err)
683 b92c47c1 ths
{
684 b92c47c1 ths
    return strerror(target_to_host_errno(err));
685 b92c47c1 ths
}
686 b92c47c1 ths
687 992f48a0 blueswir1
static abi_ulong target_brk;
688 992f48a0 blueswir1
static abi_ulong target_original_brk;
689 31e31b8a bellard
690 992f48a0 blueswir1
void target_set_brk(abi_ulong new_brk)
691 31e31b8a bellard
{
692 4c1de73d blueswir1
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
693 31e31b8a bellard
}
694 31e31b8a bellard
695 0da46a6e ths
/* do_brk() must return target values and target errnos. */
696 992f48a0 blueswir1
abi_long do_brk(abi_ulong new_brk)
697 31e31b8a bellard
{
698 992f48a0 blueswir1
    abi_ulong brk_page;
699 992f48a0 blueswir1
    abi_long mapped_addr;
700 31e31b8a bellard
    int        new_alloc_size;
701 31e31b8a bellard
702 31e31b8a bellard
    if (!new_brk)
703 53a5960a pbrook
        return target_brk;
704 31e31b8a bellard
    if (new_brk < target_original_brk)
705 7ab240ad balrog
        return target_brk;
706 3b46e624 ths
707 53a5960a pbrook
    brk_page = HOST_PAGE_ALIGN(target_brk);
708 31e31b8a bellard
709 31e31b8a bellard
    /* If the new brk is less than this, set it and we're done... */
710 31e31b8a bellard
    if (new_brk < brk_page) {
711 31e31b8a bellard
        target_brk = new_brk;
712 53a5960a pbrook
            return target_brk;
713 31e31b8a bellard
    }
714 31e31b8a bellard
715 31e31b8a bellard
    /* We need to allocate more memory after the brk... */
716 54936004 bellard
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
717 5fafdf24 ths
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
718 54936004 bellard
                                        PROT_READ|PROT_WRITE,
719 54936004 bellard
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
720 7ab240ad balrog
721 7ab240ad balrog
    if (!is_error(mapped_addr))
722 31e31b8a bellard
        target_brk = new_brk;
723 7ab240ad balrog
    
724 7ab240ad balrog
    return target_brk;
725 31e31b8a bellard
}
726 31e31b8a bellard
727 26edcf41 ths
static inline abi_long copy_from_user_fdset(fd_set *fds,
728 26edcf41 ths
                                            abi_ulong target_fds_addr,
729 26edcf41 ths
                                            int n)
730 31e31b8a bellard
{
731 26edcf41 ths
    int i, nw, j, k;
732 26edcf41 ths
    abi_ulong b, *target_fds;
733 26edcf41 ths
734 26edcf41 ths
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
735 26edcf41 ths
    if (!(target_fds = lock_user(VERIFY_READ,
736 26edcf41 ths
                                 target_fds_addr,
737 26edcf41 ths
                                 sizeof(abi_ulong) * nw,
738 26edcf41 ths
                                 1)))
739 26edcf41 ths
        return -TARGET_EFAULT;
740 26edcf41 ths
741 26edcf41 ths
    FD_ZERO(fds);
742 26edcf41 ths
    k = 0;
743 26edcf41 ths
    for (i = 0; i < nw; i++) {
744 26edcf41 ths
        /* grab the abi_ulong */
745 26edcf41 ths
        __get_user(b, &target_fds[i]);
746 26edcf41 ths
        for (j = 0; j < TARGET_ABI_BITS; j++) {
747 26edcf41 ths
            /* check the bit inside the abi_ulong */
748 26edcf41 ths
            if ((b >> j) & 1)
749 26edcf41 ths
                FD_SET(k, fds);
750 26edcf41 ths
            k++;
751 31e31b8a bellard
        }
752 31e31b8a bellard
    }
753 26edcf41 ths
754 26edcf41 ths
    unlock_user(target_fds, target_fds_addr, 0);
755 26edcf41 ths
756 26edcf41 ths
    return 0;
757 31e31b8a bellard
}
758 31e31b8a bellard
759 26edcf41 ths
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
760 26edcf41 ths
                                          const fd_set *fds,
761 26edcf41 ths
                                          int n)
762 31e31b8a bellard
{
763 31e31b8a bellard
    int i, nw, j, k;
764 992f48a0 blueswir1
    abi_long v;
765 26edcf41 ths
    abi_ulong *target_fds;
766 31e31b8a bellard
767 26edcf41 ths
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
768 26edcf41 ths
    if (!(target_fds = lock_user(VERIFY_WRITE,
769 26edcf41 ths
                                 target_fds_addr,
770 26edcf41 ths
                                 sizeof(abi_ulong) * nw,
771 26edcf41 ths
                                 0)))
772 26edcf41 ths
        return -TARGET_EFAULT;
773 26edcf41 ths
774 26edcf41 ths
    k = 0;
775 26edcf41 ths
    for (i = 0; i < nw; i++) {
776 26edcf41 ths
        v = 0;
777 26edcf41 ths
        for (j = 0; j < TARGET_ABI_BITS; j++) {
778 26edcf41 ths
            v |= ((FD_ISSET(k, fds) != 0) << j);
779 26edcf41 ths
            k++;
780 31e31b8a bellard
        }
781 26edcf41 ths
        __put_user(v, &target_fds[i]);
782 31e31b8a bellard
    }
783 26edcf41 ths
784 26edcf41 ths
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
785 26edcf41 ths
786 26edcf41 ths
    return 0;
787 31e31b8a bellard
}
788 31e31b8a bellard
789 c596ed17 bellard
#if defined(__alpha__)
790 c596ed17 bellard
#define HOST_HZ 1024
791 c596ed17 bellard
#else
792 c596ed17 bellard
#define HOST_HZ 100
793 c596ed17 bellard
#endif
794 c596ed17 bellard
795 992f48a0 blueswir1
static inline abi_long host_to_target_clock_t(long ticks)
796 c596ed17 bellard
{
797 c596ed17 bellard
#if HOST_HZ == TARGET_HZ
798 c596ed17 bellard
    return ticks;
799 c596ed17 bellard
#else
800 c596ed17 bellard
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
801 c596ed17 bellard
#endif
802 c596ed17 bellard
}
803 c596ed17 bellard
804 579a97f7 bellard
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
805 579a97f7 bellard
                                             const struct rusage *rusage)
806 b409186b bellard
{
807 53a5960a pbrook
    struct target_rusage *target_rusage;
808 53a5960a pbrook
809 579a97f7 bellard
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
810 579a97f7 bellard
        return -TARGET_EFAULT;
811 b409186b bellard
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
812 b409186b bellard
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
813 b409186b bellard
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
814 b409186b bellard
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
815 b409186b bellard
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
816 b409186b bellard
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
817 b409186b bellard
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
818 b409186b bellard
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
819 b409186b bellard
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
820 b409186b bellard
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
821 b409186b bellard
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
822 b409186b bellard
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
823 b409186b bellard
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
824 b409186b bellard
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
825 b409186b bellard
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
826 b409186b bellard
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
827 b409186b bellard
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
828 b409186b bellard
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
829 53a5960a pbrook
    unlock_user_struct(target_rusage, target_addr, 1);
830 579a97f7 bellard
831 579a97f7 bellard
    return 0;
832 b409186b bellard
}
833 b409186b bellard
834 788f5ec4 ths
static inline abi_long copy_from_user_timeval(struct timeval *tv,
835 788f5ec4 ths
                                              abi_ulong target_tv_addr)
836 31e31b8a bellard
{
837 53a5960a pbrook
    struct target_timeval *target_tv;
838 53a5960a pbrook
839 788f5ec4 ths
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
840 579a97f7 bellard
        return -TARGET_EFAULT;
841 788f5ec4 ths
842 788f5ec4 ths
    __get_user(tv->tv_sec, &target_tv->tv_sec);
843 788f5ec4 ths
    __get_user(tv->tv_usec, &target_tv->tv_usec);
844 788f5ec4 ths
845 788f5ec4 ths
    unlock_user_struct(target_tv, target_tv_addr, 0);
846 579a97f7 bellard
847 579a97f7 bellard
    return 0;
848 31e31b8a bellard
}
849 31e31b8a bellard
850 788f5ec4 ths
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
851 788f5ec4 ths
                                            const struct timeval *tv)
852 31e31b8a bellard
{
853 53a5960a pbrook
    struct target_timeval *target_tv;
854 53a5960a pbrook
855 788f5ec4 ths
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
856 579a97f7 bellard
        return -TARGET_EFAULT;
857 788f5ec4 ths
858 788f5ec4 ths
    __put_user(tv->tv_sec, &target_tv->tv_sec);
859 788f5ec4 ths
    __put_user(tv->tv_usec, &target_tv->tv_usec);
860 788f5ec4 ths
861 788f5ec4 ths
    unlock_user_struct(target_tv, target_tv_addr, 1);
862 579a97f7 bellard
863 579a97f7 bellard
    return 0;
864 31e31b8a bellard
}
865 31e31b8a bellard
866 8ec9cf89 Nathan Froyd
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
867 8ec9cf89 Nathan Froyd
#include <mqueue.h>
868 8ec9cf89 Nathan Froyd
869 24e1003a aurel32
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
870 24e1003a aurel32
                                              abi_ulong target_mq_attr_addr)
871 24e1003a aurel32
{
872 24e1003a aurel32
    struct target_mq_attr *target_mq_attr;
873 24e1003a aurel32
874 24e1003a aurel32
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
875 24e1003a aurel32
                          target_mq_attr_addr, 1))
876 24e1003a aurel32
        return -TARGET_EFAULT;
877 24e1003a aurel32
878 24e1003a aurel32
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
879 24e1003a aurel32
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
880 24e1003a aurel32
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
881 24e1003a aurel32
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
882 24e1003a aurel32
883 24e1003a aurel32
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
884 24e1003a aurel32
885 24e1003a aurel32
    return 0;
886 24e1003a aurel32
}
887 24e1003a aurel32
888 24e1003a aurel32
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
889 24e1003a aurel32
                                            const struct mq_attr *attr)
890 24e1003a aurel32
{
891 24e1003a aurel32
    struct target_mq_attr *target_mq_attr;
892 24e1003a aurel32
893 24e1003a aurel32
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
894 24e1003a aurel32
                          target_mq_attr_addr, 0))
895 24e1003a aurel32
        return -TARGET_EFAULT;
896 24e1003a aurel32
897 24e1003a aurel32
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
898 24e1003a aurel32
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
899 24e1003a aurel32
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
900 24e1003a aurel32
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
901 24e1003a aurel32
902 24e1003a aurel32
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
903 24e1003a aurel32
904 24e1003a aurel32
    return 0;
905 24e1003a aurel32
}
906 8ec9cf89 Nathan Froyd
#endif
907 31e31b8a bellard
908 0da46a6e ths
/* do_select() must return target values and target errnos. */
909 992f48a0 blueswir1
static abi_long do_select(int n,
910 26edcf41 ths
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
911 26edcf41 ths
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
912 31e31b8a bellard
{
913 31e31b8a bellard
    fd_set rfds, wfds, efds;
914 31e31b8a bellard
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
915 31e31b8a bellard
    struct timeval tv, *tv_ptr;
916 992f48a0 blueswir1
    abi_long ret;
917 31e31b8a bellard
918 26edcf41 ths
    if (rfd_addr) {
919 26edcf41 ths
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
920 26edcf41 ths
            return -TARGET_EFAULT;
921 26edcf41 ths
        rfds_ptr = &rfds;
922 53a5960a pbrook
    } else {
923 53a5960a pbrook
        rfds_ptr = NULL;
924 53a5960a pbrook
    }
925 26edcf41 ths
    if (wfd_addr) {
926 26edcf41 ths
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
927 26edcf41 ths
            return -TARGET_EFAULT;
928 26edcf41 ths
        wfds_ptr = &wfds;
929 53a5960a pbrook
    } else {
930 53a5960a pbrook
        wfds_ptr = NULL;
931 53a5960a pbrook
    }
932 26edcf41 ths
    if (efd_addr) {
933 26edcf41 ths
        if (copy_from_user_fdset(&efds, efd_addr, n))
934 26edcf41 ths
            return -TARGET_EFAULT;
935 26edcf41 ths
        efds_ptr = &efds;
936 53a5960a pbrook
    } else {
937 53a5960a pbrook
        efds_ptr = NULL;
938 53a5960a pbrook
    }
939 3b46e624 ths
940 26edcf41 ths
    if (target_tv_addr) {
941 788f5ec4 ths
        if (copy_from_user_timeval(&tv, target_tv_addr))
942 788f5ec4 ths
            return -TARGET_EFAULT;
943 31e31b8a bellard
        tv_ptr = &tv;
944 31e31b8a bellard
    } else {
945 31e31b8a bellard
        tv_ptr = NULL;
946 31e31b8a bellard
    }
947 26edcf41 ths
948 31e31b8a bellard
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
949 53a5960a pbrook
950 26edcf41 ths
    if (!is_error(ret)) {
951 26edcf41 ths
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
952 26edcf41 ths
            return -TARGET_EFAULT;
953 26edcf41 ths
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
954 26edcf41 ths
            return -TARGET_EFAULT;
955 26edcf41 ths
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
956 26edcf41 ths
            return -TARGET_EFAULT;
957 31e31b8a bellard
958 788f5ec4 ths
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
959 788f5ec4 ths
            return -TARGET_EFAULT;
960 31e31b8a bellard
    }
961 579a97f7 bellard
962 31e31b8a bellard
    return ret;
963 31e31b8a bellard
}
964 31e31b8a bellard
965 099d6b0f Riku Voipio
static abi_long do_pipe2(int host_pipe[], int flags)
966 099d6b0f Riku Voipio
{
967 099d6b0f Riku Voipio
#ifdef CONFIG_PIPE2
968 099d6b0f Riku Voipio
    return pipe2(host_pipe, flags);
969 099d6b0f Riku Voipio
#else
970 099d6b0f Riku Voipio
    return -ENOSYS;
971 099d6b0f Riku Voipio
#endif
972 099d6b0f Riku Voipio
}
973 099d6b0f Riku Voipio
974 784ccfdb Ulrich Hecht
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, int flags)
975 099d6b0f Riku Voipio
{
976 099d6b0f Riku Voipio
    int host_pipe[2];
977 099d6b0f Riku Voipio
    abi_long ret;
978 099d6b0f Riku Voipio
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
979 099d6b0f Riku Voipio
980 099d6b0f Riku Voipio
    if (is_error(ret))
981 099d6b0f Riku Voipio
        return get_errno(ret);
982 099d6b0f Riku Voipio
#if defined(TARGET_MIPS)
983 099d6b0f Riku Voipio
    ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
984 099d6b0f Riku Voipio
    ret = host_pipe[0];
985 099d6b0f Riku Voipio
#else
986 597c0212 takasi-y@ops.dti.ne.jp
#if defined(TARGET_SH4)
987 597c0212 takasi-y@ops.dti.ne.jp
    if (!flags) {
988 597c0212 takasi-y@ops.dti.ne.jp
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
989 597c0212 takasi-y@ops.dti.ne.jp
        ret = host_pipe[0];
990 597c0212 takasi-y@ops.dti.ne.jp
    } else
991 597c0212 takasi-y@ops.dti.ne.jp
#endif
992 099d6b0f Riku Voipio
    if (put_user_s32(host_pipe[0], pipedes)
993 099d6b0f Riku Voipio
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
994 099d6b0f Riku Voipio
        return -TARGET_EFAULT;
995 099d6b0f Riku Voipio
#endif
996 099d6b0f Riku Voipio
    return get_errno(ret);
997 099d6b0f Riku Voipio
}
998 099d6b0f Riku Voipio
999 b975b83b Lionel Landwerlin
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1000 b975b83b Lionel Landwerlin
                                              abi_ulong target_addr,
1001 b975b83b Lionel Landwerlin
                                              socklen_t len)
1002 b975b83b Lionel Landwerlin
{
1003 b975b83b Lionel Landwerlin
    struct target_ip_mreqn *target_smreqn;
1004 b975b83b Lionel Landwerlin
1005 b975b83b Lionel Landwerlin
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1006 b975b83b Lionel Landwerlin
    if (!target_smreqn)
1007 b975b83b Lionel Landwerlin
        return -TARGET_EFAULT;
1008 b975b83b Lionel Landwerlin
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1009 b975b83b Lionel Landwerlin
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1010 b975b83b Lionel Landwerlin
    if (len == sizeof(struct target_ip_mreqn))
1011 b975b83b Lionel Landwerlin
        mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
1012 b975b83b Lionel Landwerlin
    unlock_user(target_smreqn, target_addr, 0);
1013 b975b83b Lionel Landwerlin
1014 b975b83b Lionel Landwerlin
    return 0;
1015 b975b83b Lionel Landwerlin
}
1016 b975b83b Lionel Landwerlin
1017 579a97f7 bellard
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1018 579a97f7 bellard
                                               abi_ulong target_addr,
1019 579a97f7 bellard
                                               socklen_t len)
1020 7854b056 bellard
{
1021 607175e0 aurel32
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1022 607175e0 aurel32
    sa_family_t sa_family;
1023 53a5960a pbrook
    struct target_sockaddr *target_saddr;
1024 53a5960a pbrook
1025 579a97f7 bellard
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1026 579a97f7 bellard
    if (!target_saddr)
1027 579a97f7 bellard
        return -TARGET_EFAULT;
1028 607175e0 aurel32
1029 607175e0 aurel32
    sa_family = tswap16(target_saddr->sa_family);
1030 607175e0 aurel32
1031 607175e0 aurel32
    /* Oops. The caller might send a incomplete sun_path; sun_path
1032 607175e0 aurel32
     * must be terminated by \0 (see the manual page), but
1033 607175e0 aurel32
     * unfortunately it is quite common to specify sockaddr_un
1034 607175e0 aurel32
     * length as "strlen(x->sun_path)" while it should be
1035 607175e0 aurel32
     * "strlen(...) + 1". We'll fix that here if needed.
1036 607175e0 aurel32
     * Linux kernel has a similar feature.
1037 607175e0 aurel32
     */
1038 607175e0 aurel32
1039 607175e0 aurel32
    if (sa_family == AF_UNIX) {
1040 607175e0 aurel32
        if (len < unix_maxlen && len > 0) {
1041 607175e0 aurel32
            char *cp = (char*)target_saddr;
1042 607175e0 aurel32
1043 607175e0 aurel32
            if ( cp[len-1] && !cp[len] )
1044 607175e0 aurel32
                len++;
1045 607175e0 aurel32
        }
1046 607175e0 aurel32
        if (len > unix_maxlen)
1047 607175e0 aurel32
            len = unix_maxlen;
1048 607175e0 aurel32
    }
1049 607175e0 aurel32
1050 53a5960a pbrook
    memcpy(addr, target_saddr, len);
1051 607175e0 aurel32
    addr->sa_family = sa_family;
1052 53a5960a pbrook
    unlock_user(target_saddr, target_addr, 0);
1053 579a97f7 bellard
1054 579a97f7 bellard
    return 0;
1055 7854b056 bellard
}
1056 7854b056 bellard
1057 579a97f7 bellard
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1058 579a97f7 bellard
                                               struct sockaddr *addr,
1059 579a97f7 bellard
                                               socklen_t len)
1060 7854b056 bellard
{
1061 53a5960a pbrook
    struct target_sockaddr *target_saddr;
1062 53a5960a pbrook
1063 579a97f7 bellard
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1064 579a97f7 bellard
    if (!target_saddr)
1065 579a97f7 bellard
        return -TARGET_EFAULT;
1066 53a5960a pbrook
    memcpy(target_saddr, addr, len);
1067 53a5960a pbrook
    target_saddr->sa_family = tswap16(addr->sa_family);
1068 53a5960a pbrook
    unlock_user(target_saddr, target_addr, len);
1069 579a97f7 bellard
1070 579a97f7 bellard
    return 0;
1071 7854b056 bellard
}
1072 7854b056 bellard
1073 53a5960a pbrook
/* ??? Should this also swap msgh->name?  */
1074 5a4a898d bellard
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1075 5a4a898d bellard
                                           struct target_msghdr *target_msgh)
1076 7854b056 bellard
{
1077 7854b056 bellard
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1078 5a4a898d bellard
    abi_long msg_controllen;
1079 5a4a898d bellard
    abi_ulong target_cmsg_addr;
1080 5a4a898d bellard
    struct target_cmsghdr *target_cmsg;
1081 7854b056 bellard
    socklen_t space = 0;
1082 5a4a898d bellard
    
1083 5a4a898d bellard
    msg_controllen = tswapl(target_msgh->msg_controllen);
1084 5a4a898d bellard
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1085 5a4a898d bellard
        goto the_end;
1086 5a4a898d bellard
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1087 5a4a898d bellard
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1088 5a4a898d bellard
    if (!target_cmsg)
1089 5a4a898d bellard
        return -TARGET_EFAULT;
1090 7854b056 bellard
1091 7854b056 bellard
    while (cmsg && target_cmsg) {
1092 7854b056 bellard
        void *data = CMSG_DATA(cmsg);
1093 7854b056 bellard
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1094 7854b056 bellard
1095 5fafdf24 ths
        int len = tswapl(target_cmsg->cmsg_len)
1096 7854b056 bellard
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1097 7854b056 bellard
1098 7854b056 bellard
        space += CMSG_SPACE(len);
1099 7854b056 bellard
        if (space > msgh->msg_controllen) {
1100 7854b056 bellard
            space -= CMSG_SPACE(len);
1101 31febb71 bellard
            gemu_log("Host cmsg overflow\n");
1102 7854b056 bellard
            break;
1103 7854b056 bellard
        }
1104 7854b056 bellard
1105 7854b056 bellard
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1106 7854b056 bellard
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1107 7854b056 bellard
        cmsg->cmsg_len = CMSG_LEN(len);
1108 7854b056 bellard
1109 3532fa74 bellard
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1110 7854b056 bellard
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1111 7854b056 bellard
            memcpy(data, target_data, len);
1112 7854b056 bellard
        } else {
1113 7854b056 bellard
            int *fd = (int *)data;
1114 7854b056 bellard
            int *target_fd = (int *)target_data;
1115 7854b056 bellard
            int i, numfds = len / sizeof(int);
1116 7854b056 bellard
1117 7854b056 bellard
            for (i = 0; i < numfds; i++)
1118 7854b056 bellard
                fd[i] = tswap32(target_fd[i]);
1119 7854b056 bellard
        }
1120 7854b056 bellard
1121 7854b056 bellard
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1122 7854b056 bellard
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1123 7854b056 bellard
    }
1124 5a4a898d bellard
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1125 5a4a898d bellard
 the_end:
1126 7854b056 bellard
    msgh->msg_controllen = space;
1127 5a4a898d bellard
    return 0;
1128 7854b056 bellard
}
1129 7854b056 bellard
1130 53a5960a pbrook
/* ??? Should this also swap msgh->name?  */
1131 5a4a898d bellard
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1132 5a4a898d bellard
                                           struct msghdr *msgh)
1133 7854b056 bellard
{
1134 7854b056 bellard
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1135 5a4a898d bellard
    abi_long msg_controllen;
1136 5a4a898d bellard
    abi_ulong target_cmsg_addr;
1137 5a4a898d bellard
    struct target_cmsghdr *target_cmsg;
1138 7854b056 bellard
    socklen_t space = 0;
1139 7854b056 bellard
1140 5a4a898d bellard
    msg_controllen = tswapl(target_msgh->msg_controllen);
1141 5a4a898d bellard
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1142 5a4a898d bellard
        goto the_end;
1143 5a4a898d bellard
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1144 5a4a898d bellard
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1145 5a4a898d bellard
    if (!target_cmsg)
1146 5a4a898d bellard
        return -TARGET_EFAULT;
1147 5a4a898d bellard
1148 7854b056 bellard
    while (cmsg && target_cmsg) {
1149 7854b056 bellard
        void *data = CMSG_DATA(cmsg);
1150 7854b056 bellard
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1151 7854b056 bellard
1152 7854b056 bellard
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1153 7854b056 bellard
1154 7854b056 bellard
        space += TARGET_CMSG_SPACE(len);
1155 5a4a898d bellard
        if (space > msg_controllen) {
1156 7854b056 bellard
            space -= TARGET_CMSG_SPACE(len);
1157 31febb71 bellard
            gemu_log("Target cmsg overflow\n");
1158 7854b056 bellard
            break;
1159 7854b056 bellard
        }
1160 7854b056 bellard
1161 7854b056 bellard
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1162 7854b056 bellard
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1163 7854b056 bellard
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1164 7854b056 bellard
1165 3532fa74 bellard
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1166 7854b056 bellard
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1167 7854b056 bellard
            memcpy(target_data, data, len);
1168 7854b056 bellard
        } else {
1169 7854b056 bellard
            int *fd = (int *)data;
1170 7854b056 bellard
            int *target_fd = (int *)target_data;
1171 7854b056 bellard
            int i, numfds = len / sizeof(int);
1172 7854b056 bellard
1173 7854b056 bellard
            for (i = 0; i < numfds; i++)
1174 7854b056 bellard
                target_fd[i] = tswap32(fd[i]);
1175 7854b056 bellard
        }
1176 7854b056 bellard
1177 7854b056 bellard
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1178 7854b056 bellard
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1179 7854b056 bellard
    }
1180 5a4a898d bellard
    unlock_user(target_cmsg, target_cmsg_addr, space);
1181 5a4a898d bellard
 the_end:
1182 5a4a898d bellard
    target_msgh->msg_controllen = tswapl(space);
1183 5a4a898d bellard
    return 0;
1184 7854b056 bellard
}
1185 7854b056 bellard
1186 0da46a6e ths
/* do_setsockopt() Must return target values and target errnos. */
1187 992f48a0 blueswir1
static abi_long do_setsockopt(int sockfd, int level, int optname,
1188 2f619698 bellard
                              abi_ulong optval_addr, socklen_t optlen)
1189 7854b056 bellard
{
1190 992f48a0 blueswir1
    abi_long ret;
1191 32407103 j_mayer
    int val;
1192 b975b83b Lionel Landwerlin
    struct ip_mreqn *ip_mreq;
1193 6e3cb58f Lionel Landwerlin
    struct ip_mreq_source *ip_mreq_source;
1194 3b46e624 ths
1195 8853f86e bellard
    switch(level) {
1196 8853f86e bellard
    case SOL_TCP:
1197 7854b056 bellard
        /* TCP options all take an 'int' value.  */
1198 7854b056 bellard
        if (optlen < sizeof(uint32_t))
1199 0da46a6e ths
            return -TARGET_EINVAL;
1200 3b46e624 ths
1201 2f619698 bellard
        if (get_user_u32(val, optval_addr))
1202 2f619698 bellard
            return -TARGET_EFAULT;
1203 8853f86e bellard
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1204 8853f86e bellard
        break;
1205 8853f86e bellard
    case SOL_IP:
1206 8853f86e bellard
        switch(optname) {
1207 2efbe911 bellard
        case IP_TOS:
1208 2efbe911 bellard
        case IP_TTL:
1209 8853f86e bellard
        case IP_HDRINCL:
1210 2efbe911 bellard
        case IP_ROUTER_ALERT:
1211 2efbe911 bellard
        case IP_RECVOPTS:
1212 2efbe911 bellard
        case IP_RETOPTS:
1213 2efbe911 bellard
        case IP_PKTINFO:
1214 2efbe911 bellard
        case IP_MTU_DISCOVER:
1215 2efbe911 bellard
        case IP_RECVERR:
1216 2efbe911 bellard
        case IP_RECVTOS:
1217 2efbe911 bellard
#ifdef IP_FREEBIND
1218 2efbe911 bellard
        case IP_FREEBIND:
1219 2efbe911 bellard
#endif
1220 2efbe911 bellard
        case IP_MULTICAST_TTL:
1221 2efbe911 bellard
        case IP_MULTICAST_LOOP:
1222 8853f86e bellard
            val = 0;
1223 8853f86e bellard
            if (optlen >= sizeof(uint32_t)) {
1224 2f619698 bellard
                if (get_user_u32(val, optval_addr))
1225 2f619698 bellard
                    return -TARGET_EFAULT;
1226 8853f86e bellard
            } else if (optlen >= 1) {
1227 2f619698 bellard
                if (get_user_u8(val, optval_addr))
1228 2f619698 bellard
                    return -TARGET_EFAULT;
1229 8853f86e bellard
            }
1230 8853f86e bellard
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1231 8853f86e bellard
            break;
1232 b975b83b Lionel Landwerlin
        case IP_ADD_MEMBERSHIP:
1233 b975b83b Lionel Landwerlin
        case IP_DROP_MEMBERSHIP:
1234 b975b83b Lionel Landwerlin
            if (optlen < sizeof (struct target_ip_mreq) ||
1235 b975b83b Lionel Landwerlin
                optlen > sizeof (struct target_ip_mreqn))
1236 b975b83b Lionel Landwerlin
                return -TARGET_EINVAL;
1237 b975b83b Lionel Landwerlin
1238 b975b83b Lionel Landwerlin
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1239 b975b83b Lionel Landwerlin
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1240 b975b83b Lionel Landwerlin
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1241 b975b83b Lionel Landwerlin
            break;
1242 b975b83b Lionel Landwerlin
1243 6e3cb58f Lionel Landwerlin
        case IP_BLOCK_SOURCE:
1244 6e3cb58f Lionel Landwerlin
        case IP_UNBLOCK_SOURCE:
1245 6e3cb58f Lionel Landwerlin
        case IP_ADD_SOURCE_MEMBERSHIP:
1246 6e3cb58f Lionel Landwerlin
        case IP_DROP_SOURCE_MEMBERSHIP:
1247 6e3cb58f Lionel Landwerlin
            if (optlen != sizeof (struct target_ip_mreq_source))
1248 6e3cb58f Lionel Landwerlin
                return -TARGET_EINVAL;
1249 6e3cb58f Lionel Landwerlin
1250 6e3cb58f Lionel Landwerlin
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1251 6e3cb58f Lionel Landwerlin
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1252 6e3cb58f Lionel Landwerlin
            unlock_user (ip_mreq_source, optval_addr, 0);
1253 6e3cb58f Lionel Landwerlin
            break;
1254 6e3cb58f Lionel Landwerlin
1255 8853f86e bellard
        default:
1256 8853f86e bellard
            goto unimplemented;
1257 8853f86e bellard
        }
1258 8853f86e bellard
        break;
1259 3532fa74 bellard
    case TARGET_SOL_SOCKET:
1260 8853f86e bellard
        switch (optname) {
1261 8853f86e bellard
            /* Options with 'int' argument.  */
1262 3532fa74 bellard
        case TARGET_SO_DEBUG:
1263 3532fa74 bellard
                optname = SO_DEBUG;
1264 3532fa74 bellard
                break;
1265 3532fa74 bellard
        case TARGET_SO_REUSEADDR:
1266 3532fa74 bellard
                optname = SO_REUSEADDR;
1267 3532fa74 bellard
                break;
1268 3532fa74 bellard
        case TARGET_SO_TYPE:
1269 3532fa74 bellard
                optname = SO_TYPE;
1270 3532fa74 bellard
                break;
1271 3532fa74 bellard
        case TARGET_SO_ERROR:
1272 3532fa74 bellard
                optname = SO_ERROR;
1273 3532fa74 bellard
                break;
1274 3532fa74 bellard
        case TARGET_SO_DONTROUTE:
1275 3532fa74 bellard
                optname = SO_DONTROUTE;
1276 3532fa74 bellard
                break;
1277 3532fa74 bellard
        case TARGET_SO_BROADCAST:
1278 3532fa74 bellard
                optname = SO_BROADCAST;
1279 3532fa74 bellard
                break;
1280 3532fa74 bellard
        case TARGET_SO_SNDBUF:
1281 3532fa74 bellard
                optname = SO_SNDBUF;
1282 3532fa74 bellard
                break;
1283 3532fa74 bellard
        case TARGET_SO_RCVBUF:
1284 3532fa74 bellard
                optname = SO_RCVBUF;
1285 3532fa74 bellard
                break;
1286 3532fa74 bellard
        case TARGET_SO_KEEPALIVE:
1287 3532fa74 bellard
                optname = SO_KEEPALIVE;
1288 3532fa74 bellard
                break;
1289 3532fa74 bellard
        case TARGET_SO_OOBINLINE:
1290 3532fa74 bellard
                optname = SO_OOBINLINE;
1291 3532fa74 bellard
                break;
1292 3532fa74 bellard
        case TARGET_SO_NO_CHECK:
1293 3532fa74 bellard
                optname = SO_NO_CHECK;
1294 3532fa74 bellard
                break;
1295 3532fa74 bellard
        case TARGET_SO_PRIORITY:
1296 3532fa74 bellard
                optname = SO_PRIORITY;
1297 3532fa74 bellard
                break;
1298 5e83e8e3 bellard
#ifdef SO_BSDCOMPAT
1299 3532fa74 bellard
        case TARGET_SO_BSDCOMPAT:
1300 3532fa74 bellard
                optname = SO_BSDCOMPAT;
1301 3532fa74 bellard
                break;
1302 5e83e8e3 bellard
#endif
1303 3532fa74 bellard
        case TARGET_SO_PASSCRED:
1304 3532fa74 bellard
                optname = SO_PASSCRED;
1305 3532fa74 bellard
                break;
1306 3532fa74 bellard
        case TARGET_SO_TIMESTAMP:
1307 3532fa74 bellard
                optname = SO_TIMESTAMP;
1308 3532fa74 bellard
                break;
1309 3532fa74 bellard
        case TARGET_SO_RCVLOWAT:
1310 3532fa74 bellard
                optname = SO_RCVLOWAT;
1311 3532fa74 bellard
                break;
1312 3532fa74 bellard
        case TARGET_SO_RCVTIMEO:
1313 3532fa74 bellard
                optname = SO_RCVTIMEO;
1314 3532fa74 bellard
                break;
1315 3532fa74 bellard
        case TARGET_SO_SNDTIMEO:
1316 3532fa74 bellard
                optname = SO_SNDTIMEO;
1317 3532fa74 bellard
                break;
1318 8853f86e bellard
            break;
1319 8853f86e bellard
        default:
1320 8853f86e bellard
            goto unimplemented;
1321 8853f86e bellard
        }
1322 3532fa74 bellard
        if (optlen < sizeof(uint32_t))
1323 2f619698 bellard
            return -TARGET_EINVAL;
1324 3532fa74 bellard
1325 2f619698 bellard
        if (get_user_u32(val, optval_addr))
1326 2f619698 bellard
            return -TARGET_EFAULT;
1327 3532fa74 bellard
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1328 8853f86e bellard
        break;
1329 7854b056 bellard
    default:
1330 8853f86e bellard
    unimplemented:
1331 8853f86e bellard
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1332 6fa13c17 ths
        ret = -TARGET_ENOPROTOOPT;
1333 7854b056 bellard
    }
1334 8853f86e bellard
    return ret;
1335 7854b056 bellard
}
1336 7854b056 bellard
1337 0da46a6e ths
/* do_getsockopt() Must return target values and target errnos. */
1338 992f48a0 blueswir1
static abi_long do_getsockopt(int sockfd, int level, int optname,
1339 2f619698 bellard
                              abi_ulong optval_addr, abi_ulong optlen)
1340 7854b056 bellard
{
1341 992f48a0 blueswir1
    abi_long ret;
1342 b55266b5 blueswir1
    int len, val;
1343 b55266b5 blueswir1
    socklen_t lv;
1344 8853f86e bellard
1345 8853f86e bellard
    switch(level) {
1346 3532fa74 bellard
    case TARGET_SOL_SOCKET:
1347 3532fa74 bellard
            level = SOL_SOCKET;
1348 8853f86e bellard
        switch (optname) {
1349 3532fa74 bellard
        case TARGET_SO_LINGER:
1350 3532fa74 bellard
        case TARGET_SO_RCVTIMEO:
1351 3532fa74 bellard
        case TARGET_SO_SNDTIMEO:
1352 3532fa74 bellard
        case TARGET_SO_PEERCRED:
1353 3532fa74 bellard
        case TARGET_SO_PEERNAME:
1354 8853f86e bellard
            /* These don't just return a single integer */
1355 8853f86e bellard
            goto unimplemented;
1356 8853f86e bellard
        default:
1357 2efbe911 bellard
            goto int_case;
1358 2efbe911 bellard
        }
1359 2efbe911 bellard
        break;
1360 2efbe911 bellard
    case SOL_TCP:
1361 2efbe911 bellard
        /* TCP options all take an 'int' value.  */
1362 2efbe911 bellard
    int_case:
1363 2f619698 bellard
        if (get_user_u32(len, optlen))
1364 2f619698 bellard
            return -TARGET_EFAULT;
1365 2efbe911 bellard
        if (len < 0)
1366 0da46a6e ths
            return -TARGET_EINVAL;
1367 2efbe911 bellard
        lv = sizeof(int);
1368 2efbe911 bellard
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1369 2efbe911 bellard
        if (ret < 0)
1370 2efbe911 bellard
            return ret;
1371 2efbe911 bellard
        if (len > lv)
1372 2efbe911 bellard
            len = lv;
1373 2f619698 bellard
        if (len == 4) {
1374 2f619698 bellard
            if (put_user_u32(val, optval_addr))
1375 2f619698 bellard
                return -TARGET_EFAULT;
1376 2f619698 bellard
        } else {
1377 2f619698 bellard
            if (put_user_u8(val, optval_addr))
1378 2f619698 bellard
                return -TARGET_EFAULT;
1379 2f619698 bellard
        }
1380 2f619698 bellard
        if (put_user_u32(len, optlen))
1381 2f619698 bellard
            return -TARGET_EFAULT;
1382 2efbe911 bellard
        break;
1383 2efbe911 bellard
    case SOL_IP:
1384 2efbe911 bellard
        switch(optname) {
1385 2efbe911 bellard
        case IP_TOS:
1386 2efbe911 bellard
        case IP_TTL:
1387 2efbe911 bellard
        case IP_HDRINCL:
1388 2efbe911 bellard
        case IP_ROUTER_ALERT:
1389 2efbe911 bellard
        case IP_RECVOPTS:
1390 2efbe911 bellard
        case IP_RETOPTS:
1391 2efbe911 bellard
        case IP_PKTINFO:
1392 2efbe911 bellard
        case IP_MTU_DISCOVER:
1393 2efbe911 bellard
        case IP_RECVERR:
1394 2efbe911 bellard
        case IP_RECVTOS:
1395 2efbe911 bellard
#ifdef IP_FREEBIND
1396 2efbe911 bellard
        case IP_FREEBIND:
1397 2efbe911 bellard
#endif
1398 2efbe911 bellard
        case IP_MULTICAST_TTL:
1399 2efbe911 bellard
        case IP_MULTICAST_LOOP:
1400 2f619698 bellard
            if (get_user_u32(len, optlen))
1401 2f619698 bellard
                return -TARGET_EFAULT;
1402 8853f86e bellard
            if (len < 0)
1403 0da46a6e ths
                return -TARGET_EINVAL;
1404 8853f86e bellard
            lv = sizeof(int);
1405 8853f86e bellard
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1406 8853f86e bellard
            if (ret < 0)
1407 8853f86e bellard
                return ret;
1408 2efbe911 bellard
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1409 2efbe911 bellard
                len = 1;
1410 2f619698 bellard
                if (put_user_u32(len, optlen)
1411 2f619698 bellard
                    || put_user_u8(val, optval_addr))
1412 2f619698 bellard
                    return -TARGET_EFAULT;
1413 2efbe911 bellard
            } else {
1414 2efbe911 bellard
                if (len > sizeof(int))
1415 2efbe911 bellard
                    len = sizeof(int);
1416 2f619698 bellard
                if (put_user_u32(len, optlen)
1417 2f619698 bellard
                    || put_user_u32(val, optval_addr))
1418 2f619698 bellard
                    return -TARGET_EFAULT;
1419 2efbe911 bellard
            }
1420 8853f86e bellard
            break;
1421 2efbe911 bellard
        default:
1422 c02f499e ths
            ret = -TARGET_ENOPROTOOPT;
1423 c02f499e ths
            break;
1424 8853f86e bellard
        }
1425 8853f86e bellard
        break;
1426 8853f86e bellard
    default:
1427 8853f86e bellard
    unimplemented:
1428 8853f86e bellard
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1429 8853f86e bellard
                 level, optname);
1430 c02f499e ths
        ret = -TARGET_EOPNOTSUPP;
1431 8853f86e bellard
        break;
1432 8853f86e bellard
    }
1433 8853f86e bellard
    return ret;
1434 7854b056 bellard
}
1435 7854b056 bellard
1436 579a97f7 bellard
/* FIXME
1437 579a97f7 bellard
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1438 579a97f7 bellard
 * other lock functions have a return code of 0 for failure.
1439 579a97f7 bellard
 */
1440 579a97f7 bellard
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1441 579a97f7 bellard
                           int count, int copy)
1442 53a5960a pbrook
{
1443 53a5960a pbrook
    struct target_iovec *target_vec;
1444 992f48a0 blueswir1
    abi_ulong base;
1445 d732dcb4 balrog
    int i;
1446 53a5960a pbrook
1447 579a97f7 bellard
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1448 579a97f7 bellard
    if (!target_vec)
1449 579a97f7 bellard
        return -TARGET_EFAULT;
1450 53a5960a pbrook
    for(i = 0;i < count; i++) {
1451 53a5960a pbrook
        base = tswapl(target_vec[i].iov_base);
1452 53a5960a pbrook
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1453 41df8411 bellard
        if (vec[i].iov_len != 0) {
1454 41df8411 bellard
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1455 d732dcb4 balrog
            /* Don't check lock_user return value. We must call writev even
1456 d732dcb4 balrog
               if a element has invalid base address. */
1457 41df8411 bellard
        } else {
1458 41df8411 bellard
            /* zero length pointer is ignored */
1459 41df8411 bellard
            vec[i].iov_base = NULL;
1460 41df8411 bellard
        }
1461 579a97f7 bellard
    }
1462 579a97f7 bellard
    unlock_user (target_vec, target_addr, 0);
1463 579a97f7 bellard
    return 0;
1464 53a5960a pbrook
}
1465 53a5960a pbrook
1466 579a97f7 bellard
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1467 579a97f7 bellard
                             int count, int copy)
1468 53a5960a pbrook
{
1469 53a5960a pbrook
    struct target_iovec *target_vec;
1470 992f48a0 blueswir1
    abi_ulong base;
1471 53a5960a pbrook
    int i;
1472 53a5960a pbrook
1473 579a97f7 bellard
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1474 579a97f7 bellard
    if (!target_vec)
1475 579a97f7 bellard
        return -TARGET_EFAULT;
1476 53a5960a pbrook
    for(i = 0;i < count; i++) {
1477 d732dcb4 balrog
        if (target_vec[i].iov_base) {
1478 d732dcb4 balrog
            base = tswapl(target_vec[i].iov_base);
1479 d732dcb4 balrog
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1480 d732dcb4 balrog
        }
1481 53a5960a pbrook
    }
1482 53a5960a pbrook
    unlock_user (target_vec, target_addr, 0);
1483 579a97f7 bellard
1484 579a97f7 bellard
    return 0;
1485 53a5960a pbrook
}
1486 53a5960a pbrook
1487 0da46a6e ths
/* do_socket() Must return target values and target errnos. */
1488 992f48a0 blueswir1
static abi_long do_socket(int domain, int type, int protocol)
1489 3532fa74 bellard
{
1490 3532fa74 bellard
#if defined(TARGET_MIPS)
1491 3532fa74 bellard
    switch(type) {
1492 3532fa74 bellard
    case TARGET_SOCK_DGRAM:
1493 3532fa74 bellard
        type = SOCK_DGRAM;
1494 3532fa74 bellard
        break;
1495 3532fa74 bellard
    case TARGET_SOCK_STREAM:
1496 3532fa74 bellard
        type = SOCK_STREAM;
1497 3532fa74 bellard
        break;
1498 3532fa74 bellard
    case TARGET_SOCK_RAW:
1499 3532fa74 bellard
        type = SOCK_RAW;
1500 3532fa74 bellard
        break;
1501 3532fa74 bellard
    case TARGET_SOCK_RDM:
1502 3532fa74 bellard
        type = SOCK_RDM;
1503 3532fa74 bellard
        break;
1504 3532fa74 bellard
    case TARGET_SOCK_SEQPACKET:
1505 3532fa74 bellard
        type = SOCK_SEQPACKET;
1506 3532fa74 bellard
        break;
1507 3532fa74 bellard
    case TARGET_SOCK_PACKET:
1508 3532fa74 bellard
        type = SOCK_PACKET;
1509 3532fa74 bellard
        break;
1510 3532fa74 bellard
    }
1511 3532fa74 bellard
#endif
1512 12bc92ab balrog
    if (domain == PF_NETLINK)
1513 12bc92ab balrog
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1514 3532fa74 bellard
    return get_errno(socket(domain, type, protocol));
1515 3532fa74 bellard
}
1516 3532fa74 bellard
1517 0da46a6e ths
/* do_bind() Must return target values and target errnos. */
1518 992f48a0 blueswir1
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1519 992f48a0 blueswir1
                        socklen_t addrlen)
1520 3532fa74 bellard
{
1521 8f7aeaf6 aurel32
    void *addr;
1522 917507b0 Arnaud Patard
    abi_long ret;
1523 8f7aeaf6 aurel32
1524 be09ac41 aurel32
    if (addrlen < 0)
1525 8f7aeaf6 aurel32
        return -TARGET_EINVAL;
1526 8f7aeaf6 aurel32
1527 607175e0 aurel32
    addr = alloca(addrlen+1);
1528 3b46e624 ths
1529 917507b0 Arnaud Patard
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1530 917507b0 Arnaud Patard
    if (ret)
1531 917507b0 Arnaud Patard
        return ret;
1532 917507b0 Arnaud Patard
1533 3532fa74 bellard
    return get_errno(bind(sockfd, addr, addrlen));
1534 3532fa74 bellard
}
1535 3532fa74 bellard
1536 0da46a6e ths
/* do_connect() Must return target values and target errnos. */
1537 992f48a0 blueswir1
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1538 992f48a0 blueswir1
                           socklen_t addrlen)
1539 3532fa74 bellard
{
1540 8f7aeaf6 aurel32
    void *addr;
1541 917507b0 Arnaud Patard
    abi_long ret;
1542 8f7aeaf6 aurel32
1543 be09ac41 aurel32
    if (addrlen < 0)
1544 8f7aeaf6 aurel32
        return -TARGET_EINVAL;
1545 8f7aeaf6 aurel32
1546 8f7aeaf6 aurel32
    addr = alloca(addrlen);
1547 3b46e624 ths
1548 917507b0 Arnaud Patard
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1549 917507b0 Arnaud Patard
    if (ret)
1550 917507b0 Arnaud Patard
        return ret;
1551 917507b0 Arnaud Patard
1552 3532fa74 bellard
    return get_errno(connect(sockfd, addr, addrlen));
1553 3532fa74 bellard
}
1554 3532fa74 bellard
1555 0da46a6e ths
/* do_sendrecvmsg() Must return target values and target errnos. */
1556 992f48a0 blueswir1
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1557 992f48a0 blueswir1
                               int flags, int send)
1558 3532fa74 bellard
{
1559 6de645c7 balrog
    abi_long ret, len;
1560 3532fa74 bellard
    struct target_msghdr *msgp;
1561 3532fa74 bellard
    struct msghdr msg;
1562 3532fa74 bellard
    int count;
1563 3532fa74 bellard
    struct iovec *vec;
1564 992f48a0 blueswir1
    abi_ulong target_vec;
1565 3532fa74 bellard
1566 579a97f7 bellard
    /* FIXME */
1567 579a97f7 bellard
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1568 579a97f7 bellard
                          msgp,
1569 579a97f7 bellard
                          target_msg,
1570 579a97f7 bellard
                          send ? 1 : 0))
1571 579a97f7 bellard
        return -TARGET_EFAULT;
1572 3532fa74 bellard
    if (msgp->msg_name) {
1573 3532fa74 bellard
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1574 3532fa74 bellard
        msg.msg_name = alloca(msg.msg_namelen);
1575 917507b0 Arnaud Patard
        ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1576 3532fa74 bellard
                                msg.msg_namelen);
1577 917507b0 Arnaud Patard
        if (ret) {
1578 917507b0 Arnaud Patard
            unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1579 917507b0 Arnaud Patard
            return ret;
1580 917507b0 Arnaud Patard
        }
1581 3532fa74 bellard
    } else {
1582 3532fa74 bellard
        msg.msg_name = NULL;
1583 3532fa74 bellard
        msg.msg_namelen = 0;
1584 3532fa74 bellard
    }
1585 3532fa74 bellard
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1586 3532fa74 bellard
    msg.msg_control = alloca(msg.msg_controllen);
1587 3532fa74 bellard
    msg.msg_flags = tswap32(msgp->msg_flags);
1588 3b46e624 ths
1589 3532fa74 bellard
    count = tswapl(msgp->msg_iovlen);
1590 3532fa74 bellard
    vec = alloca(count * sizeof(struct iovec));
1591 3532fa74 bellard
    target_vec = tswapl(msgp->msg_iov);
1592 579a97f7 bellard
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1593 3532fa74 bellard
    msg.msg_iovlen = count;
1594 3532fa74 bellard
    msg.msg_iov = vec;
1595 3b46e624 ths
1596 3532fa74 bellard
    if (send) {
1597 5a4a898d bellard
        ret = target_to_host_cmsg(&msg, msgp);
1598 5a4a898d bellard
        if (ret == 0)
1599 5a4a898d bellard
            ret = get_errno(sendmsg(fd, &msg, flags));
1600 3532fa74 bellard
    } else {
1601 3532fa74 bellard
        ret = get_errno(recvmsg(fd, &msg, flags));
1602 6de645c7 balrog
        if (!is_error(ret)) {
1603 6de645c7 balrog
            len = ret;
1604 5a4a898d bellard
            ret = host_to_target_cmsg(msgp, &msg);
1605 6de645c7 balrog
            if (!is_error(ret))
1606 6de645c7 balrog
                ret = len;
1607 6de645c7 balrog
        }
1608 3532fa74 bellard
    }
1609 3532fa74 bellard
    unlock_iovec(vec, target_vec, count, !send);
1610 579a97f7 bellard
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1611 3532fa74 bellard
    return ret;
1612 3532fa74 bellard
}
1613 3532fa74 bellard
1614 0da46a6e ths
/* do_accept() Must return target values and target errnos. */
1615 992f48a0 blueswir1
static abi_long do_accept(int fd, abi_ulong target_addr,
1616 2f619698 bellard
                          abi_ulong target_addrlen_addr)
1617 1be9e1dc pbrook
{
1618 2f619698 bellard
    socklen_t addrlen;
1619 2f619698 bellard
    void *addr;
1620 992f48a0 blueswir1
    abi_long ret;
1621 1be9e1dc pbrook
1622 917507b0 Arnaud Patard
    if (target_addr == 0)
1623 917507b0 Arnaud Patard
       return get_errno(accept(fd, NULL, NULL));
1624 917507b0 Arnaud Patard
1625 917507b0 Arnaud Patard
    /* linux returns EINVAL if addrlen pointer is invalid */
1626 2f619698 bellard
    if (get_user_u32(addrlen, target_addrlen_addr))
1627 917507b0 Arnaud Patard
        return -TARGET_EINVAL;
1628 2f619698 bellard
1629 be09ac41 aurel32
    if (addrlen < 0)
1630 8f7aeaf6 aurel32
        return -TARGET_EINVAL;
1631 8f7aeaf6 aurel32
1632 917507b0 Arnaud Patard
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1633 917507b0 Arnaud Patard
        return -TARGET_EINVAL;
1634 917507b0 Arnaud Patard
1635 2f619698 bellard
    addr = alloca(addrlen);
1636 2f619698 bellard
1637 1be9e1dc pbrook
    ret = get_errno(accept(fd, addr, &addrlen));
1638 1be9e1dc pbrook
    if (!is_error(ret)) {
1639 1be9e1dc pbrook
        host_to_target_sockaddr(target_addr, addr, addrlen);
1640 2f619698 bellard
        if (put_user_u32(addrlen, target_addrlen_addr))
1641 2f619698 bellard
            ret = -TARGET_EFAULT;
1642 1be9e1dc pbrook
    }
1643 1be9e1dc pbrook
    return ret;
1644 1be9e1dc pbrook
}
1645 1be9e1dc pbrook
1646 0da46a6e ths
/* do_getpeername() Must return target values and target errnos. */
1647 992f48a0 blueswir1
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1648 2f619698 bellard
                               abi_ulong target_addrlen_addr)
1649 1be9e1dc pbrook
{
1650 2f619698 bellard
    socklen_t addrlen;
1651 2f619698 bellard
    void *addr;
1652 992f48a0 blueswir1
    abi_long ret;
1653 1be9e1dc pbrook
1654 2f619698 bellard
    if (get_user_u32(addrlen, target_addrlen_addr))
1655 2f619698 bellard
        return -TARGET_EFAULT;
1656 2f619698 bellard
1657 be09ac41 aurel32
    if (addrlen < 0)
1658 8f7aeaf6 aurel32
        return -TARGET_EINVAL;
1659 8f7aeaf6 aurel32
1660 917507b0 Arnaud Patard
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1661 917507b0 Arnaud Patard
        return -TARGET_EFAULT;
1662 917507b0 Arnaud Patard
1663 2f619698 bellard
    addr = alloca(addrlen);
1664 2f619698 bellard
1665 1be9e1dc pbrook
    ret = get_errno(getpeername(fd, addr, &addrlen));
1666 1be9e1dc pbrook
    if (!is_error(ret)) {
1667 1be9e1dc pbrook
        host_to_target_sockaddr(target_addr, addr, addrlen);
1668 2f619698 bellard
        if (put_user_u32(addrlen, target_addrlen_addr))
1669 2f619698 bellard
            ret = -TARGET_EFAULT;
1670 1be9e1dc pbrook
    }
1671 1be9e1dc pbrook
    return ret;
1672 1be9e1dc pbrook
}
1673 1be9e1dc pbrook
1674 0da46a6e ths
/* do_getsockname() Must return target values and target errnos. */
1675 992f48a0 blueswir1
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1676 2f619698 bellard
                               abi_ulong target_addrlen_addr)
1677 1be9e1dc pbrook
{
1678 2f619698 bellard
    socklen_t addrlen;
1679 2f619698 bellard
    void *addr;
1680 992f48a0 blueswir1
    abi_long ret;
1681 1be9e1dc pbrook
1682 2f619698 bellard
    if (get_user_u32(addrlen, target_addrlen_addr))
1683 2f619698 bellard
        return -TARGET_EFAULT;
1684 2f619698 bellard
1685 be09ac41 aurel32
    if (addrlen < 0)
1686 8f7aeaf6 aurel32
        return -TARGET_EINVAL;
1687 8f7aeaf6 aurel32
1688 917507b0 Arnaud Patard
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1689 917507b0 Arnaud Patard
        return -TARGET_EFAULT;
1690 917507b0 Arnaud Patard
1691 2f619698 bellard
    addr = alloca(addrlen);
1692 2f619698 bellard
1693 1be9e1dc pbrook
    ret = get_errno(getsockname(fd, addr, &addrlen));
1694 1be9e1dc pbrook
    if (!is_error(ret)) {
1695 1be9e1dc pbrook
        host_to_target_sockaddr(target_addr, addr, addrlen);
1696 2f619698 bellard
        if (put_user_u32(addrlen, target_addrlen_addr))
1697 2f619698 bellard
            ret = -TARGET_EFAULT;
1698 1be9e1dc pbrook
    }
1699 1be9e1dc pbrook
    return ret;
1700 1be9e1dc pbrook
}
1701 1be9e1dc pbrook
1702 0da46a6e ths
/* do_socketpair() Must return target values and target errnos. */
1703 992f48a0 blueswir1
static abi_long do_socketpair(int domain, int type, int protocol,
1704 2f619698 bellard
                              abi_ulong target_tab_addr)
1705 1be9e1dc pbrook
{
1706 1be9e1dc pbrook
    int tab[2];
1707 992f48a0 blueswir1
    abi_long ret;
1708 1be9e1dc pbrook
1709 1be9e1dc pbrook
    ret = get_errno(socketpair(domain, type, protocol, tab));
1710 1be9e1dc pbrook
    if (!is_error(ret)) {
1711 2f619698 bellard
        if (put_user_s32(tab[0], target_tab_addr)
1712 2f619698 bellard
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1713 2f619698 bellard
            ret = -TARGET_EFAULT;
1714 1be9e1dc pbrook
    }
1715 1be9e1dc pbrook
    return ret;
1716 1be9e1dc pbrook
}
1717 1be9e1dc pbrook
1718 0da46a6e ths
/* do_sendto() Must return target values and target errnos. */
1719 992f48a0 blueswir1
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1720 992f48a0 blueswir1
                          abi_ulong target_addr, socklen_t addrlen)
1721 1be9e1dc pbrook
{
1722 1be9e1dc pbrook
    void *addr;
1723 1be9e1dc pbrook
    void *host_msg;
1724 992f48a0 blueswir1
    abi_long ret;
1725 1be9e1dc pbrook
1726 be09ac41 aurel32
    if (addrlen < 0)
1727 8f7aeaf6 aurel32
        return -TARGET_EINVAL;
1728 8f7aeaf6 aurel32
1729 579a97f7 bellard
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1730 579a97f7 bellard
    if (!host_msg)
1731 579a97f7 bellard
        return -TARGET_EFAULT;
1732 1be9e1dc pbrook
    if (target_addr) {
1733 1be9e1dc pbrook
        addr = alloca(addrlen);
1734 917507b0 Arnaud Patard
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1735 917507b0 Arnaud Patard
        if (ret) {
1736 917507b0 Arnaud Patard
            unlock_user(host_msg, msg, 0);
1737 917507b0 Arnaud Patard
            return ret;
1738 917507b0 Arnaud Patard
        }
1739 1be9e1dc pbrook
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1740 1be9e1dc pbrook
    } else {
1741 1be9e1dc pbrook
        ret = get_errno(send(fd, host_msg, len, flags));
1742 1be9e1dc pbrook
    }
1743 1be9e1dc pbrook
    unlock_user(host_msg, msg, 0);
1744 1be9e1dc pbrook
    return ret;
1745 1be9e1dc pbrook
}
1746 1be9e1dc pbrook
1747 0da46a6e ths
/* do_recvfrom() Must return target values and target errnos. */
1748 992f48a0 blueswir1
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1749 992f48a0 blueswir1
                            abi_ulong target_addr,
1750 992f48a0 blueswir1
                            abi_ulong target_addrlen)
1751 1be9e1dc pbrook
{
1752 1be9e1dc pbrook
    socklen_t addrlen;
1753 1be9e1dc pbrook
    void *addr;
1754 1be9e1dc pbrook
    void *host_msg;
1755 992f48a0 blueswir1
    abi_long ret;
1756 1be9e1dc pbrook
1757 579a97f7 bellard
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1758 579a97f7 bellard
    if (!host_msg)
1759 579a97f7 bellard
        return -TARGET_EFAULT;
1760 1be9e1dc pbrook
    if (target_addr) {
1761 2f619698 bellard
        if (get_user_u32(addrlen, target_addrlen)) {
1762 2f619698 bellard
            ret = -TARGET_EFAULT;
1763 2f619698 bellard
            goto fail;
1764 2f619698 bellard
        }
1765 be09ac41 aurel32
        if (addrlen < 0) {
1766 8f7aeaf6 aurel32
            ret = -TARGET_EINVAL;
1767 8f7aeaf6 aurel32
            goto fail;
1768 8f7aeaf6 aurel32
        }
1769 1be9e1dc pbrook
        addr = alloca(addrlen);
1770 1be9e1dc pbrook
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1771 1be9e1dc pbrook
    } else {
1772 1be9e1dc pbrook
        addr = NULL; /* To keep compiler quiet.  */
1773 1be9e1dc pbrook
        ret = get_errno(recv(fd, host_msg, len, flags));
1774 1be9e1dc pbrook
    }
1775 1be9e1dc pbrook
    if (!is_error(ret)) {
1776 1be9e1dc pbrook
        if (target_addr) {
1777 1be9e1dc pbrook
            host_to_target_sockaddr(target_addr, addr, addrlen);
1778 2f619698 bellard
            if (put_user_u32(addrlen, target_addrlen)) {
1779 2f619698 bellard
                ret = -TARGET_EFAULT;
1780 2f619698 bellard
                goto fail;
1781 2f619698 bellard
            }
1782 1be9e1dc pbrook
        }
1783 1be9e1dc pbrook
        unlock_user(host_msg, msg, len);
1784 1be9e1dc pbrook
    } else {
1785 2f619698 bellard
fail:
1786 1be9e1dc pbrook
        unlock_user(host_msg, msg, 0);
1787 1be9e1dc pbrook
    }
1788 1be9e1dc pbrook
    return ret;
1789 1be9e1dc pbrook
}
1790 1be9e1dc pbrook
1791 32407103 j_mayer
#ifdef TARGET_NR_socketcall
1792 0da46a6e ths
/* do_socketcall() Must return target values and target errnos. */
1793 992f48a0 blueswir1
static abi_long do_socketcall(int num, abi_ulong vptr)
1794 31e31b8a bellard
{
1795 992f48a0 blueswir1
    abi_long ret;
1796 992f48a0 blueswir1
    const int n = sizeof(abi_ulong);
1797 31e31b8a bellard
1798 31e31b8a bellard
    switch(num) {
1799 31e31b8a bellard
    case SOCKOP_socket:
1800 7854b056 bellard
        {
1801 98818189 Ulrich Hecht
            abi_ulong domain, type, protocol;
1802 2f619698 bellard
1803 98818189 Ulrich Hecht
            if (get_user_ual(domain, vptr)
1804 98818189 Ulrich Hecht
                || get_user_ual(type, vptr + n)
1805 98818189 Ulrich Hecht
                || get_user_ual(protocol, vptr + 2 * n))
1806 2f619698 bellard
                return -TARGET_EFAULT;
1807 2f619698 bellard
1808 3532fa74 bellard
            ret = do_socket(domain, type, protocol);
1809 7854b056 bellard
        }
1810 31e31b8a bellard
        break;
1811 31e31b8a bellard
    case SOCKOP_bind:
1812 7854b056 bellard
        {
1813 98818189 Ulrich Hecht
            abi_ulong sockfd;
1814 2f619698 bellard
            abi_ulong target_addr;
1815 2f619698 bellard
            socklen_t addrlen;
1816 2f619698 bellard
1817 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
1818 2f619698 bellard
                || get_user_ual(target_addr, vptr + n)
1819 98818189 Ulrich Hecht
                || get_user_ual(addrlen, vptr + 2 * n))
1820 2f619698 bellard
                return -TARGET_EFAULT;
1821 2f619698 bellard
1822 3532fa74 bellard
            ret = do_bind(sockfd, target_addr, addrlen);
1823 7854b056 bellard
        }
1824 31e31b8a bellard
        break;
1825 31e31b8a bellard
    case SOCKOP_connect:
1826 7854b056 bellard
        {
1827 98818189 Ulrich Hecht
            abi_ulong sockfd;
1828 2f619698 bellard
            abi_ulong target_addr;
1829 2f619698 bellard
            socklen_t addrlen;
1830 2f619698 bellard
1831 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
1832 2f619698 bellard
                || get_user_ual(target_addr, vptr + n)
1833 98818189 Ulrich Hecht
                || get_user_ual(addrlen, vptr + 2 * n))
1834 2f619698 bellard
                return -TARGET_EFAULT;
1835 2f619698 bellard
1836 3532fa74 bellard
            ret = do_connect(sockfd, target_addr, addrlen);
1837 7854b056 bellard
        }
1838 31e31b8a bellard
        break;
1839 31e31b8a bellard
    case SOCKOP_listen:
1840 7854b056 bellard
        {
1841 98818189 Ulrich Hecht
            abi_ulong sockfd, backlog;
1842 2f619698 bellard
1843 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
1844 98818189 Ulrich Hecht
                || get_user_ual(backlog, vptr + n))
1845 2f619698 bellard
                return -TARGET_EFAULT;
1846 2f619698 bellard
1847 7854b056 bellard
            ret = get_errno(listen(sockfd, backlog));
1848 7854b056 bellard
        }
1849 31e31b8a bellard
        break;
1850 31e31b8a bellard
    case SOCKOP_accept:
1851 31e31b8a bellard
        {
1852 98818189 Ulrich Hecht
            abi_ulong sockfd;
1853 2f619698 bellard
            abi_ulong target_addr, target_addrlen;
1854 2f619698 bellard
1855 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
1856 2f619698 bellard
                || get_user_ual(target_addr, vptr + n)
1857 98818189 Ulrich Hecht
                || get_user_ual(target_addrlen, vptr + 2 * n))
1858 2f619698 bellard
                return -TARGET_EFAULT;
1859 2f619698 bellard
1860 1be9e1dc pbrook
            ret = do_accept(sockfd, target_addr, target_addrlen);
1861 31e31b8a bellard
        }
1862 31e31b8a bellard
        break;
1863 31e31b8a bellard
    case SOCKOP_getsockname:
1864 31e31b8a bellard
        {
1865 98818189 Ulrich Hecht
            abi_ulong sockfd;
1866 2f619698 bellard
            abi_ulong target_addr, target_addrlen;
1867 2f619698 bellard
1868 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
1869 2f619698 bellard
                || get_user_ual(target_addr, vptr + n)
1870 98818189 Ulrich Hecht
                || get_user_ual(target_addrlen, vptr + 2 * n))
1871 2f619698 bellard
                return -TARGET_EFAULT;
1872 2f619698 bellard
1873 1be9e1dc pbrook
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1874 31e31b8a bellard
        }
1875 31e31b8a bellard
        break;
1876 31e31b8a bellard
    case SOCKOP_getpeername:
1877 31e31b8a bellard
        {
1878 98818189 Ulrich Hecht
            abi_ulong sockfd;
1879 2f619698 bellard
            abi_ulong target_addr, target_addrlen;
1880 2f619698 bellard
1881 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
1882 2f619698 bellard
                || get_user_ual(target_addr, vptr + n)
1883 98818189 Ulrich Hecht
                || get_user_ual(target_addrlen, vptr + 2 * n))
1884 2f619698 bellard
                return -TARGET_EFAULT;
1885 2f619698 bellard
1886 1be9e1dc pbrook
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1887 31e31b8a bellard
        }
1888 31e31b8a bellard
        break;
1889 31e31b8a bellard
    case SOCKOP_socketpair:
1890 31e31b8a bellard
        {
1891 98818189 Ulrich Hecht
            abi_ulong domain, type, protocol;
1892 2f619698 bellard
            abi_ulong tab;
1893 2f619698 bellard
1894 98818189 Ulrich Hecht
            if (get_user_ual(domain, vptr)
1895 98818189 Ulrich Hecht
                || get_user_ual(type, vptr + n)
1896 98818189 Ulrich Hecht
                || get_user_ual(protocol, vptr + 2 * n)
1897 2f619698 bellard
                || get_user_ual(tab, vptr + 3 * n))
1898 2f619698 bellard
                return -TARGET_EFAULT;
1899 2f619698 bellard
1900 1be9e1dc pbrook
            ret = do_socketpair(domain, type, protocol, tab);
1901 31e31b8a bellard
        }
1902 31e31b8a bellard
        break;
1903 31e31b8a bellard
    case SOCKOP_send:
1904 7854b056 bellard
        {
1905 98818189 Ulrich Hecht
            abi_ulong sockfd;
1906 2f619698 bellard
            abi_ulong msg;
1907 2f619698 bellard
            size_t len;
1908 98818189 Ulrich Hecht
            abi_ulong flags;
1909 2f619698 bellard
1910 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
1911 2f619698 bellard
                || get_user_ual(msg, vptr + n)
1912 2f619698 bellard
                || get_user_ual(len, vptr + 2 * n)
1913 98818189 Ulrich Hecht
                || get_user_ual(flags, vptr + 3 * n))
1914 2f619698 bellard
                return -TARGET_EFAULT;
1915 2f619698 bellard
1916 1be9e1dc pbrook
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1917 7854b056 bellard
        }
1918 31e31b8a bellard
        break;
1919 31e31b8a bellard
    case SOCKOP_recv:
1920 7854b056 bellard
        {
1921 98818189 Ulrich Hecht
            abi_ulong sockfd;
1922 2f619698 bellard
            abi_ulong msg;
1923 2f619698 bellard
            size_t len;
1924 98818189 Ulrich Hecht
            abi_ulong flags;
1925 2f619698 bellard
1926 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
1927 2f619698 bellard
                || get_user_ual(msg, vptr + n)
1928 2f619698 bellard
                || get_user_ual(len, vptr + 2 * n)
1929 98818189 Ulrich Hecht
                || get_user_ual(flags, vptr + 3 * n))
1930 2f619698 bellard
                return -TARGET_EFAULT;
1931 2f619698 bellard
1932 1be9e1dc pbrook
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1933 7854b056 bellard
        }
1934 31e31b8a bellard
        break;
1935 31e31b8a bellard
    case SOCKOP_sendto:
1936 7854b056 bellard
        {
1937 98818189 Ulrich Hecht
            abi_ulong sockfd;
1938 2f619698 bellard
            abi_ulong msg;
1939 2f619698 bellard
            size_t len;
1940 98818189 Ulrich Hecht
            abi_ulong flags;
1941 2f619698 bellard
            abi_ulong addr;
1942 2f619698 bellard
            socklen_t addrlen;
1943 2f619698 bellard
1944 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
1945 2f619698 bellard
                || get_user_ual(msg, vptr + n)
1946 2f619698 bellard
                || get_user_ual(len, vptr + 2 * n)
1947 98818189 Ulrich Hecht
                || get_user_ual(flags, vptr + 3 * n)
1948 2f619698 bellard
                || get_user_ual(addr, vptr + 4 * n)
1949 98818189 Ulrich Hecht
                || get_user_ual(addrlen, vptr + 5 * n))
1950 2f619698 bellard
                return -TARGET_EFAULT;
1951 2f619698 bellard
1952 1be9e1dc pbrook
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1953 7854b056 bellard
        }
1954 31e31b8a bellard
        break;
1955 31e31b8a bellard
    case SOCKOP_recvfrom:
1956 31e31b8a bellard
        {
1957 98818189 Ulrich Hecht
            abi_ulong sockfd;
1958 2f619698 bellard
            abi_ulong msg;
1959 2f619698 bellard
            size_t len;
1960 98818189 Ulrich Hecht
            abi_ulong flags;
1961 2f619698 bellard
            abi_ulong addr;
1962 2f619698 bellard
            socklen_t addrlen;
1963 2f619698 bellard
1964 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
1965 2f619698 bellard
                || get_user_ual(msg, vptr + n)
1966 2f619698 bellard
                || get_user_ual(len, vptr + 2 * n)
1967 98818189 Ulrich Hecht
                || get_user_ual(flags, vptr + 3 * n)
1968 2f619698 bellard
                || get_user_ual(addr, vptr + 4 * n)
1969 98818189 Ulrich Hecht
                || get_user_ual(addrlen, vptr + 5 * n))
1970 2f619698 bellard
                return -TARGET_EFAULT;
1971 2f619698 bellard
1972 1be9e1dc pbrook
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1973 31e31b8a bellard
        }
1974 31e31b8a bellard
        break;
1975 31e31b8a bellard
    case SOCKOP_shutdown:
1976 7854b056 bellard
        {
1977 98818189 Ulrich Hecht
            abi_ulong sockfd, how;
1978 2f619698 bellard
1979 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
1980 98818189 Ulrich Hecht
                || get_user_ual(how, vptr + n))
1981 2f619698 bellard
                return -TARGET_EFAULT;
1982 7854b056 bellard
1983 7854b056 bellard
            ret = get_errno(shutdown(sockfd, how));
1984 7854b056 bellard
        }
1985 31e31b8a bellard
        break;
1986 31e31b8a bellard
    case SOCKOP_sendmsg:
1987 31e31b8a bellard
    case SOCKOP_recvmsg:
1988 1a9353d2 bellard
        {
1989 98818189 Ulrich Hecht
            abi_ulong fd;
1990 992f48a0 blueswir1
            abi_ulong target_msg;
1991 98818189 Ulrich Hecht
            abi_ulong flags;
1992 1a9353d2 bellard
1993 98818189 Ulrich Hecht
            if (get_user_ual(fd, vptr)
1994 2f619698 bellard
                || get_user_ual(target_msg, vptr + n)
1995 98818189 Ulrich Hecht
                || get_user_ual(flags, vptr + 2 * n))
1996 2f619698 bellard
                return -TARGET_EFAULT;
1997 3532fa74 bellard
1998 5fafdf24 ths
            ret = do_sendrecvmsg(fd, target_msg, flags,
1999 3532fa74 bellard
                                 (num == SOCKOP_sendmsg));
2000 1a9353d2 bellard
        }
2001 1a9353d2 bellard
        break;
2002 31e31b8a bellard
    case SOCKOP_setsockopt:
2003 7854b056 bellard
        {
2004 98818189 Ulrich Hecht
            abi_ulong sockfd;
2005 98818189 Ulrich Hecht
            abi_ulong level;
2006 98818189 Ulrich Hecht
            abi_ulong optname;
2007 2f619698 bellard
            abi_ulong optval;
2008 2f619698 bellard
            socklen_t optlen;
2009 2f619698 bellard
2010 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2011 98818189 Ulrich Hecht
                || get_user_ual(level, vptr + n)
2012 98818189 Ulrich Hecht
                || get_user_ual(optname, vptr + 2 * n)
2013 2f619698 bellard
                || get_user_ual(optval, vptr + 3 * n)
2014 98818189 Ulrich Hecht
                || get_user_ual(optlen, vptr + 4 * n))
2015 2f619698 bellard
                return -TARGET_EFAULT;
2016 7854b056 bellard
2017 7854b056 bellard
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2018 7854b056 bellard
        }
2019 7854b056 bellard
        break;
2020 31e31b8a bellard
    case SOCKOP_getsockopt:
2021 7854b056 bellard
        {
2022 98818189 Ulrich Hecht
            abi_ulong sockfd;
2023 98818189 Ulrich Hecht
            abi_ulong level;
2024 98818189 Ulrich Hecht
            abi_ulong optname;
2025 2f619698 bellard
            abi_ulong optval;
2026 2f619698 bellard
            socklen_t optlen;
2027 2f619698 bellard
2028 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2029 98818189 Ulrich Hecht
                || get_user_ual(level, vptr + n)
2030 98818189 Ulrich Hecht
                || get_user_ual(optname, vptr + 2 * n)
2031 2f619698 bellard
                || get_user_ual(optval, vptr + 3 * n)
2032 98818189 Ulrich Hecht
                || get_user_ual(optlen, vptr + 4 * n))
2033 2f619698 bellard
                return -TARGET_EFAULT;
2034 7854b056 bellard
2035 2f619698 bellard
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2036 7854b056 bellard
        }
2037 7854b056 bellard
        break;
2038 31e31b8a bellard
    default:
2039 31e31b8a bellard
        gemu_log("Unsupported socketcall: %d\n", num);
2040 0da46a6e ths
        ret = -TARGET_ENOSYS;
2041 31e31b8a bellard
        break;
2042 31e31b8a bellard
    }
2043 31e31b8a bellard
    return ret;
2044 31e31b8a bellard
}
2045 32407103 j_mayer
#endif
2046 31e31b8a bellard
2047 8853f86e bellard
#define N_SHM_REGIONS        32
2048 8853f86e bellard
2049 8853f86e bellard
static struct shm_region {
2050 5a4a898d bellard
    abi_ulong        start;
2051 5a4a898d bellard
    abi_ulong        size;
2052 8853f86e bellard
} shm_regions[N_SHM_REGIONS];
2053 8853f86e bellard
2054 3eb6b044 ths
struct target_ipc_perm
2055 3eb6b044 ths
{
2056 992f48a0 blueswir1
    abi_long __key;
2057 992f48a0 blueswir1
    abi_ulong uid;
2058 992f48a0 blueswir1
    abi_ulong gid;
2059 992f48a0 blueswir1
    abi_ulong cuid;
2060 992f48a0 blueswir1
    abi_ulong cgid;
2061 3eb6b044 ths
    unsigned short int mode;
2062 3eb6b044 ths
    unsigned short int __pad1;
2063 3eb6b044 ths
    unsigned short int __seq;
2064 3eb6b044 ths
    unsigned short int __pad2;
2065 992f48a0 blueswir1
    abi_ulong __unused1;
2066 992f48a0 blueswir1
    abi_ulong __unused2;
2067 3eb6b044 ths
};
2068 3eb6b044 ths
2069 3eb6b044 ths
struct target_semid_ds
2070 3eb6b044 ths
{
2071 3eb6b044 ths
  struct target_ipc_perm sem_perm;
2072 992f48a0 blueswir1
  abi_ulong sem_otime;
2073 992f48a0 blueswir1
  abi_ulong __unused1;
2074 992f48a0 blueswir1
  abi_ulong sem_ctime;
2075 992f48a0 blueswir1
  abi_ulong __unused2;
2076 992f48a0 blueswir1
  abi_ulong sem_nsems;
2077 992f48a0 blueswir1
  abi_ulong __unused3;
2078 992f48a0 blueswir1
  abi_ulong __unused4;
2079 3eb6b044 ths
};
2080 3eb6b044 ths
2081 579a97f7 bellard
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2082 579a97f7 bellard
                                               abi_ulong target_addr)
2083 3eb6b044 ths
{
2084 3eb6b044 ths
    struct target_ipc_perm *target_ip;
2085 3eb6b044 ths
    struct target_semid_ds *target_sd;
2086 3eb6b044 ths
2087 579a97f7 bellard
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2088 579a97f7 bellard
        return -TARGET_EFAULT;
2089 e8bbe36c Michael S. Tsirkin
    target_ip = &(target_sd->sem_perm);
2090 3eb6b044 ths
    host_ip->__key = tswapl(target_ip->__key);
2091 3eb6b044 ths
    host_ip->uid = tswapl(target_ip->uid);
2092 3eb6b044 ths
    host_ip->gid = tswapl(target_ip->gid);
2093 3eb6b044 ths
    host_ip->cuid = tswapl(target_ip->cuid);
2094 3eb6b044 ths
    host_ip->cgid = tswapl(target_ip->cgid);
2095 3eb6b044 ths
    host_ip->mode = tswapl(target_ip->mode);
2096 3eb6b044 ths
    unlock_user_struct(target_sd, target_addr, 0);
2097 579a97f7 bellard
    return 0;
2098 3eb6b044 ths
}
2099 3eb6b044 ths
2100 579a97f7 bellard
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2101 579a97f7 bellard
                                               struct ipc_perm *host_ip)
2102 3eb6b044 ths
{
2103 3eb6b044 ths
    struct target_ipc_perm *target_ip;
2104 3eb6b044 ths
    struct target_semid_ds *target_sd;
2105 3eb6b044 ths
2106 579a97f7 bellard
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2107 579a97f7 bellard
        return -TARGET_EFAULT;
2108 3eb6b044 ths
    target_ip = &(target_sd->sem_perm);
2109 3eb6b044 ths
    target_ip->__key = tswapl(host_ip->__key);
2110 3eb6b044 ths
    target_ip->uid = tswapl(host_ip->uid);
2111 3eb6b044 ths
    target_ip->gid = tswapl(host_ip->gid);
2112 3eb6b044 ths
    target_ip->cuid = tswapl(host_ip->cuid);
2113 3eb6b044 ths
    target_ip->cgid = tswapl(host_ip->cgid);
2114 3eb6b044 ths
    target_ip->mode = tswapl(host_ip->mode);
2115 3eb6b044 ths
    unlock_user_struct(target_sd, target_addr, 1);
2116 579a97f7 bellard
    return 0;
2117 3eb6b044 ths
}
2118 3eb6b044 ths
2119 579a97f7 bellard
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2120 579a97f7 bellard
                                               abi_ulong target_addr)
2121 3eb6b044 ths
{
2122 3eb6b044 ths
    struct target_semid_ds *target_sd;
2123 3eb6b044 ths
2124 579a97f7 bellard
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2125 579a97f7 bellard
        return -TARGET_EFAULT;
2126 e5289087 aurel32
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2127 e5289087 aurel32
        return -TARGET_EFAULT;
2128 3eb6b044 ths
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2129 3eb6b044 ths
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
2130 3eb6b044 ths
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2131 3eb6b044 ths
    unlock_user_struct(target_sd, target_addr, 0);
2132 579a97f7 bellard
    return 0;
2133 3eb6b044 ths
}
2134 3eb6b044 ths
2135 579a97f7 bellard
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2136 579a97f7 bellard
                                               struct semid_ds *host_sd)
2137 3eb6b044 ths
{
2138 3eb6b044 ths
    struct target_semid_ds *target_sd;
2139 3eb6b044 ths
2140 579a97f7 bellard
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2141 579a97f7 bellard
        return -TARGET_EFAULT;
2142 e5289087 aurel32
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2143 e5289087 aurel32
        return -TARGET_EFAULT;;
2144 3eb6b044 ths
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2145 3eb6b044 ths
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2146 3eb6b044 ths
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2147 3eb6b044 ths
    unlock_user_struct(target_sd, target_addr, 1);
2148 579a97f7 bellard
    return 0;
2149 3eb6b044 ths
}
2150 3eb6b044 ths
2151 e5289087 aurel32
struct target_seminfo {
2152 e5289087 aurel32
    int semmap;
2153 e5289087 aurel32
    int semmni;
2154 e5289087 aurel32
    int semmns;
2155 e5289087 aurel32
    int semmnu;
2156 e5289087 aurel32
    int semmsl;
2157 e5289087 aurel32
    int semopm;
2158 e5289087 aurel32
    int semume;
2159 e5289087 aurel32
    int semusz;
2160 e5289087 aurel32
    int semvmx;
2161 e5289087 aurel32
    int semaem;
2162 e5289087 aurel32
};
2163 e5289087 aurel32
2164 e5289087 aurel32
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2165 e5289087 aurel32
                                              struct seminfo *host_seminfo)
2166 e5289087 aurel32
{
2167 e5289087 aurel32
    struct target_seminfo *target_seminfo;
2168 e5289087 aurel32
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2169 e5289087 aurel32
        return -TARGET_EFAULT;
2170 e5289087 aurel32
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2171 e5289087 aurel32
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2172 e5289087 aurel32
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2173 e5289087 aurel32
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2174 e5289087 aurel32
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2175 e5289087 aurel32
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2176 e5289087 aurel32
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2177 e5289087 aurel32
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2178 e5289087 aurel32
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2179 e5289087 aurel32
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2180 e5289087 aurel32
    unlock_user_struct(target_seminfo, target_addr, 1);
2181 e5289087 aurel32
    return 0;
2182 e5289087 aurel32
}
2183 e5289087 aurel32
2184 fa294816 ths
union semun {
2185 fa294816 ths
        int val;
2186 3eb6b044 ths
        struct semid_ds *buf;
2187 fa294816 ths
        unsigned short *array;
2188 e5289087 aurel32
        struct seminfo *__buf;
2189 fa294816 ths
};
2190 fa294816 ths
2191 3eb6b044 ths
union target_semun {
2192 3eb6b044 ths
        int val;
2193 e5289087 aurel32
        abi_ulong buf;
2194 e5289087 aurel32
        abi_ulong array;
2195 e5289087 aurel32
        abi_ulong __buf;
2196 3eb6b044 ths
};
2197 3eb6b044 ths
2198 e5289087 aurel32
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2199 e5289087 aurel32
                                               abi_ulong target_addr)
2200 3eb6b044 ths
{
2201 e5289087 aurel32
    int nsems;
2202 e5289087 aurel32
    unsigned short *array;
2203 e5289087 aurel32
    union semun semun;
2204 e5289087 aurel32
    struct semid_ds semid_ds;
2205 e5289087 aurel32
    int i, ret;
2206 3eb6b044 ths
2207 e5289087 aurel32
    semun.buf = &semid_ds;
2208 e5289087 aurel32
2209 e5289087 aurel32
    ret = semctl(semid, 0, IPC_STAT, semun);
2210 e5289087 aurel32
    if (ret == -1)
2211 e5289087 aurel32
        return get_errno(ret);
2212 e5289087 aurel32
2213 e5289087 aurel32
    nsems = semid_ds.sem_nsems;
2214 e5289087 aurel32
2215 e5289087 aurel32
    *host_array = malloc(nsems*sizeof(unsigned short));
2216 e5289087 aurel32
    array = lock_user(VERIFY_READ, target_addr,
2217 e5289087 aurel32
                      nsems*sizeof(unsigned short), 1);
2218 e5289087 aurel32
    if (!array)
2219 e5289087 aurel32
        return -TARGET_EFAULT;
2220 e5289087 aurel32
2221 e5289087 aurel32
    for(i=0; i<nsems; i++) {
2222 e5289087 aurel32
        __get_user((*host_array)[i], &array[i]);
2223 3eb6b044 ths
    }
2224 e5289087 aurel32
    unlock_user(array, target_addr, 0);
2225 e5289087 aurel32
2226 579a97f7 bellard
    return 0;
2227 3eb6b044 ths
}
2228 3eb6b044 ths
2229 e5289087 aurel32
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2230 e5289087 aurel32
                                               unsigned short **host_array)
2231 3eb6b044 ths
{
2232 e5289087 aurel32
    int nsems;
2233 e5289087 aurel32
    unsigned short *array;
2234 e5289087 aurel32
    union semun semun;
2235 e5289087 aurel32
    struct semid_ds semid_ds;
2236 e5289087 aurel32
    int i, ret;
2237 3eb6b044 ths
2238 e5289087 aurel32
    semun.buf = &semid_ds;
2239 e5289087 aurel32
2240 e5289087 aurel32
    ret = semctl(semid, 0, IPC_STAT, semun);
2241 e5289087 aurel32
    if (ret == -1)
2242 e5289087 aurel32
        return get_errno(ret);
2243 e5289087 aurel32
2244 e5289087 aurel32
    nsems = semid_ds.sem_nsems;
2245 e5289087 aurel32
2246 e5289087 aurel32
    array = lock_user(VERIFY_WRITE, target_addr,
2247 e5289087 aurel32
                      nsems*sizeof(unsigned short), 0);
2248 e5289087 aurel32
    if (!array)
2249 e5289087 aurel32
        return -TARGET_EFAULT;
2250 e5289087 aurel32
2251 e5289087 aurel32
    for(i=0; i<nsems; i++) {
2252 e5289087 aurel32
        __put_user((*host_array)[i], &array[i]);
2253 3eb6b044 ths
    }
2254 e5289087 aurel32
    free(*host_array);
2255 e5289087 aurel32
    unlock_user(array, target_addr, 1);
2256 e5289087 aurel32
2257 579a97f7 bellard
    return 0;
2258 3eb6b044 ths
}
2259 3eb6b044 ths
2260 e5289087 aurel32
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2261 e5289087 aurel32
                                 union target_semun target_su)
2262 3eb6b044 ths
{
2263 3eb6b044 ths
    union semun arg;
2264 3eb6b044 ths
    struct semid_ds dsarg;
2265 7b8118e8 vibi sreenivasan
    unsigned short *array = NULL;
2266 e5289087 aurel32
    struct seminfo seminfo;
2267 e5289087 aurel32
    abi_long ret = -TARGET_EINVAL;
2268 e5289087 aurel32
    abi_long err;
2269 e5289087 aurel32
    cmd &= 0xff;
2270 3eb6b044 ths
2271 3eb6b044 ths
    switch( cmd ) {
2272 3eb6b044 ths
        case GETVAL:
2273 3eb6b044 ths
        case SETVAL:
2274 e5289087 aurel32
            arg.val = tswapl(target_su.val);
2275 e5289087 aurel32
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2276 e5289087 aurel32
            target_su.val = tswapl(arg.val);
2277 3eb6b044 ths
            break;
2278 3eb6b044 ths
        case GETALL:
2279 3eb6b044 ths
        case SETALL:
2280 e5289087 aurel32
            err = target_to_host_semarray(semid, &array, target_su.array);
2281 e5289087 aurel32
            if (err)
2282 e5289087 aurel32
                return err;
2283 e5289087 aurel32
            arg.array = array;
2284 e5289087 aurel32
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2285 e5289087 aurel32
            err = host_to_target_semarray(semid, target_su.array, &array);
2286 e5289087 aurel32
            if (err)
2287 e5289087 aurel32
                return err;
2288 3eb6b044 ths
            break;
2289 3eb6b044 ths
        case IPC_STAT:
2290 3eb6b044 ths
        case IPC_SET:
2291 e5289087 aurel32
        case SEM_STAT:
2292 e5289087 aurel32
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2293 e5289087 aurel32
            if (err)
2294 e5289087 aurel32
                return err;
2295 e5289087 aurel32
            arg.buf = &dsarg;
2296 e5289087 aurel32
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2297 e5289087 aurel32
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2298 e5289087 aurel32
            if (err)
2299 e5289087 aurel32
                return err;
2300 e5289087 aurel32
            break;
2301 e5289087 aurel32
        case IPC_INFO:
2302 e5289087 aurel32
        case SEM_INFO:
2303 e5289087 aurel32
            arg.__buf = &seminfo;
2304 e5289087 aurel32
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2305 e5289087 aurel32
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2306 e5289087 aurel32
            if (err)
2307 e5289087 aurel32
                return err;
2308 e5289087 aurel32
            break;
2309 e5289087 aurel32
        case IPC_RMID:
2310 e5289087 aurel32
        case GETPID:
2311 e5289087 aurel32
        case GETNCNT:
2312 e5289087 aurel32
        case GETZCNT:
2313 e5289087 aurel32
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2314 3eb6b044 ths
            break;
2315 3eb6b044 ths
    }
2316 3eb6b044 ths
2317 3eb6b044 ths
    return ret;
2318 3eb6b044 ths
}
2319 3eb6b044 ths
2320 e5289087 aurel32
struct target_sembuf {
2321 e5289087 aurel32
    unsigned short sem_num;
2322 e5289087 aurel32
    short sem_op;
2323 e5289087 aurel32
    short sem_flg;
2324 e5289087 aurel32
};
2325 e5289087 aurel32
2326 e5289087 aurel32
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2327 e5289087 aurel32
                                             abi_ulong target_addr,
2328 e5289087 aurel32
                                             unsigned nsops)
2329 e5289087 aurel32
{
2330 e5289087 aurel32
    struct target_sembuf *target_sembuf;
2331 e5289087 aurel32
    int i;
2332 e5289087 aurel32
2333 e5289087 aurel32
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2334 e5289087 aurel32
                              nsops*sizeof(struct target_sembuf), 1);
2335 e5289087 aurel32
    if (!target_sembuf)
2336 e5289087 aurel32
        return -TARGET_EFAULT;
2337 e5289087 aurel32
2338 e5289087 aurel32
    for(i=0; i<nsops; i++) {
2339 e5289087 aurel32
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2340 e5289087 aurel32
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2341 e5289087 aurel32
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2342 e5289087 aurel32
    }
2343 e5289087 aurel32
2344 e5289087 aurel32
    unlock_user(target_sembuf, target_addr, 0);
2345 e5289087 aurel32
2346 e5289087 aurel32
    return 0;
2347 e5289087 aurel32
}
2348 e5289087 aurel32
2349 e5289087 aurel32
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2350 e5289087 aurel32
{
2351 e5289087 aurel32
    struct sembuf sops[nsops];
2352 e5289087 aurel32
2353 e5289087 aurel32
    if (target_to_host_sembuf(sops, ptr, nsops))
2354 e5289087 aurel32
        return -TARGET_EFAULT;
2355 e5289087 aurel32
2356 e5289087 aurel32
    return semop(semid, sops, nsops);
2357 e5289087 aurel32
}
2358 e5289087 aurel32
2359 1bc012f6 ths
struct target_msqid_ds
2360 1bc012f6 ths
{
2361 1c54ff97 aurel32
    struct target_ipc_perm msg_perm;
2362 1c54ff97 aurel32
    abi_ulong msg_stime;
2363 1c54ff97 aurel32
#if TARGET_ABI_BITS == 32
2364 1c54ff97 aurel32
    abi_ulong __unused1;
2365 1c54ff97 aurel32
#endif
2366 1c54ff97 aurel32
    abi_ulong msg_rtime;
2367 1c54ff97 aurel32
#if TARGET_ABI_BITS == 32
2368 1c54ff97 aurel32
    abi_ulong __unused2;
2369 1c54ff97 aurel32
#endif
2370 1c54ff97 aurel32
    abi_ulong msg_ctime;
2371 1c54ff97 aurel32
#if TARGET_ABI_BITS == 32
2372 1c54ff97 aurel32
    abi_ulong __unused3;
2373 1c54ff97 aurel32
#endif
2374 1c54ff97 aurel32
    abi_ulong __msg_cbytes;
2375 1c54ff97 aurel32
    abi_ulong msg_qnum;
2376 1c54ff97 aurel32
    abi_ulong msg_qbytes;
2377 1c54ff97 aurel32
    abi_ulong msg_lspid;
2378 1c54ff97 aurel32
    abi_ulong msg_lrpid;
2379 1c54ff97 aurel32
    abi_ulong __unused4;
2380 1c54ff97 aurel32
    abi_ulong __unused5;
2381 1bc012f6 ths
};
2382 1bc012f6 ths
2383 579a97f7 bellard
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2384 579a97f7 bellard
                                               abi_ulong target_addr)
2385 1bc012f6 ths
{
2386 1bc012f6 ths
    struct target_msqid_ds *target_md;
2387 1bc012f6 ths
2388 579a97f7 bellard
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2389 579a97f7 bellard
        return -TARGET_EFAULT;
2390 1c54ff97 aurel32
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2391 1c54ff97 aurel32
        return -TARGET_EFAULT;
2392 1bc012f6 ths
    host_md->msg_stime = tswapl(target_md->msg_stime);
2393 1bc012f6 ths
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2394 1bc012f6 ths
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2395 1bc012f6 ths
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2396 1bc012f6 ths
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2397 1bc012f6 ths
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2398 1bc012f6 ths
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2399 1bc012f6 ths
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2400 1bc012f6 ths
    unlock_user_struct(target_md, target_addr, 0);
2401 579a97f7 bellard
    return 0;
2402 1bc012f6 ths
}
2403 1bc012f6 ths
2404 579a97f7 bellard
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2405 579a97f7 bellard
                                               struct msqid_ds *host_md)
2406 1bc012f6 ths
{
2407 1bc012f6 ths
    struct target_msqid_ds *target_md;
2408 1bc012f6 ths
2409 579a97f7 bellard
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2410 579a97f7 bellard
        return -TARGET_EFAULT;
2411 1c54ff97 aurel32
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2412 1c54ff97 aurel32
        return -TARGET_EFAULT;
2413 1bc012f6 ths
    target_md->msg_stime = tswapl(host_md->msg_stime);
2414 1bc012f6 ths
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2415 1bc012f6 ths
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2416 1bc012f6 ths
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2417 1bc012f6 ths
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2418 1bc012f6 ths
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2419 1bc012f6 ths
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2420 1bc012f6 ths
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2421 1bc012f6 ths
    unlock_user_struct(target_md, target_addr, 1);
2422 579a97f7 bellard
    return 0;
2423 1bc012f6 ths
}
2424 1bc012f6 ths
2425 1c54ff97 aurel32
struct target_msginfo {
2426 1c54ff97 aurel32
    int msgpool;
2427 1c54ff97 aurel32
    int msgmap;
2428 1c54ff97 aurel32
    int msgmax;
2429 1c54ff97 aurel32
    int msgmnb;
2430 1c54ff97 aurel32
    int msgmni;
2431 1c54ff97 aurel32
    int msgssz;
2432 1c54ff97 aurel32
    int msgtql;
2433 1c54ff97 aurel32
    unsigned short int msgseg;
2434 1c54ff97 aurel32
};
2435 1c54ff97 aurel32
2436 1c54ff97 aurel32
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2437 1c54ff97 aurel32
                                              struct msginfo *host_msginfo)
2438 1c54ff97 aurel32
{
2439 1c54ff97 aurel32
    struct target_msginfo *target_msginfo;
2440 1c54ff97 aurel32
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2441 1c54ff97 aurel32
        return -TARGET_EFAULT;
2442 1c54ff97 aurel32
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2443 1c54ff97 aurel32
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2444 1c54ff97 aurel32
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2445 1c54ff97 aurel32
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2446 1c54ff97 aurel32
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2447 1c54ff97 aurel32
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2448 1c54ff97 aurel32
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2449 1c54ff97 aurel32
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2450 1c54ff97 aurel32
    unlock_user_struct(target_msginfo, target_addr, 1);
2451 00b229ac aurel32
    return 0;
2452 1c54ff97 aurel32
}
2453 1c54ff97 aurel32
2454 1c54ff97 aurel32
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2455 1bc012f6 ths
{
2456 1bc012f6 ths
    struct msqid_ds dsarg;
2457 1c54ff97 aurel32
    struct msginfo msginfo;
2458 1c54ff97 aurel32
    abi_long ret = -TARGET_EINVAL;
2459 1c54ff97 aurel32
2460 1c54ff97 aurel32
    cmd &= 0xff;
2461 1c54ff97 aurel32
2462 1c54ff97 aurel32
    switch (cmd) {
2463 1bc012f6 ths
    case IPC_STAT:
2464 1bc012f6 ths
    case IPC_SET:
2465 1c54ff97 aurel32
    case MSG_STAT:
2466 1c54ff97 aurel32
        if (target_to_host_msqid_ds(&dsarg,ptr))
2467 1c54ff97 aurel32
            return -TARGET_EFAULT;
2468 1c54ff97 aurel32
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2469 1c54ff97 aurel32
        if (host_to_target_msqid_ds(ptr,&dsarg))
2470 1c54ff97 aurel32
            return -TARGET_EFAULT;
2471 1c54ff97 aurel32
        break;
2472 1c54ff97 aurel32
    case IPC_RMID:
2473 1c54ff97 aurel32
        ret = get_errno(msgctl(msgid, cmd, NULL));
2474 1c54ff97 aurel32
        break;
2475 1c54ff97 aurel32
    case IPC_INFO:
2476 1c54ff97 aurel32
    case MSG_INFO:
2477 1c54ff97 aurel32
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2478 1c54ff97 aurel32
        if (host_to_target_msginfo(ptr, &msginfo))
2479 1c54ff97 aurel32
            return -TARGET_EFAULT;
2480 1c54ff97 aurel32
        break;
2481 1bc012f6 ths
    }
2482 1c54ff97 aurel32
2483 1bc012f6 ths
    return ret;
2484 1bc012f6 ths
}
2485 1bc012f6 ths
2486 1bc012f6 ths
struct target_msgbuf {
2487 1c54ff97 aurel32
    abi_long mtype;
2488 1c54ff97 aurel32
    char        mtext[1];
2489 1bc012f6 ths
};
2490 1bc012f6 ths
2491 992f48a0 blueswir1
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2492 992f48a0 blueswir1
                                 unsigned int msgsz, int msgflg)
2493 1bc012f6 ths
{
2494 1bc012f6 ths
    struct target_msgbuf *target_mb;
2495 1bc012f6 ths
    struct msgbuf *host_mb;
2496 992f48a0 blueswir1
    abi_long ret = 0;
2497 1bc012f6 ths
2498 579a97f7 bellard
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2499 579a97f7 bellard
        return -TARGET_EFAULT;
2500 1bc012f6 ths
    host_mb = malloc(msgsz+sizeof(long));
2501 1c54ff97 aurel32
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2502 1c54ff97 aurel32
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2503 1bc012f6 ths
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2504 1bc012f6 ths
    free(host_mb);
2505 1bc012f6 ths
    unlock_user_struct(target_mb, msgp, 0);
2506 1bc012f6 ths
2507 1bc012f6 ths
    return ret;
2508 1bc012f6 ths
}
2509 1bc012f6 ths
2510 992f48a0 blueswir1
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2511 1c54ff97 aurel32
                                 unsigned int msgsz, abi_long msgtyp,
2512 992f48a0 blueswir1
                                 int msgflg)
2513 1bc012f6 ths
{
2514 1bc012f6 ths
    struct target_msgbuf *target_mb;
2515 579a97f7 bellard
    char *target_mtext;
2516 1bc012f6 ths
    struct msgbuf *host_mb;
2517 992f48a0 blueswir1
    abi_long ret = 0;
2518 1bc012f6 ths
2519 579a97f7 bellard
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2520 579a97f7 bellard
        return -TARGET_EFAULT;
2521 1c54ff97 aurel32
2522 1bc012f6 ths
    host_mb = malloc(msgsz+sizeof(long));
2523 1c54ff97 aurel32
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2524 1c54ff97 aurel32
2525 579a97f7 bellard
    if (ret > 0) {
2526 579a97f7 bellard
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2527 579a97f7 bellard
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2528 579a97f7 bellard
        if (!target_mtext) {
2529 579a97f7 bellard
            ret = -TARGET_EFAULT;
2530 579a97f7 bellard
            goto end;
2531 579a97f7 bellard
        }
2532 1c54ff97 aurel32
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2533 579a97f7 bellard
        unlock_user(target_mtext, target_mtext_addr, ret);
2534 579a97f7 bellard
    }
2535 1c54ff97 aurel32
2536 1bc012f6 ths
    target_mb->mtype = tswapl(host_mb->mtype);
2537 1bc012f6 ths
    free(host_mb);
2538 1bc012f6 ths
2539 579a97f7 bellard
end:
2540 579a97f7 bellard
    if (target_mb)
2541 579a97f7 bellard
        unlock_user_struct(target_mb, msgp, 1);
2542 1bc012f6 ths
    return ret;
2543 1bc012f6 ths
}
2544 1bc012f6 ths
2545 88a8c984 Riku Voipio
struct target_shmid_ds
2546 88a8c984 Riku Voipio
{
2547 88a8c984 Riku Voipio
    struct target_ipc_perm shm_perm;
2548 88a8c984 Riku Voipio
    abi_ulong shm_segsz;
2549 88a8c984 Riku Voipio
    abi_ulong shm_atime;
2550 88a8c984 Riku Voipio
#if TARGET_ABI_BITS == 32
2551 88a8c984 Riku Voipio
    abi_ulong __unused1;
2552 88a8c984 Riku Voipio
#endif
2553 88a8c984 Riku Voipio
    abi_ulong shm_dtime;
2554 88a8c984 Riku Voipio
#if TARGET_ABI_BITS == 32
2555 88a8c984 Riku Voipio
    abi_ulong __unused2;
2556 88a8c984 Riku Voipio
#endif
2557 88a8c984 Riku Voipio
    abi_ulong shm_ctime;
2558 88a8c984 Riku Voipio
#if TARGET_ABI_BITS == 32
2559 88a8c984 Riku Voipio
    abi_ulong __unused3;
2560 88a8c984 Riku Voipio
#endif
2561 88a8c984 Riku Voipio
    int shm_cpid;
2562 88a8c984 Riku Voipio
    int shm_lpid;
2563 88a8c984 Riku Voipio
    abi_ulong shm_nattch;
2564 88a8c984 Riku Voipio
    unsigned long int __unused4;
2565 88a8c984 Riku Voipio
    unsigned long int __unused5;
2566 88a8c984 Riku Voipio
};
2567 88a8c984 Riku Voipio
2568 88a8c984 Riku Voipio
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2569 88a8c984 Riku Voipio
                                               abi_ulong target_addr)
2570 88a8c984 Riku Voipio
{
2571 88a8c984 Riku Voipio
    struct target_shmid_ds *target_sd;
2572 88a8c984 Riku Voipio
2573 88a8c984 Riku Voipio
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2574 88a8c984 Riku Voipio
        return -TARGET_EFAULT;
2575 88a8c984 Riku Voipio
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2576 88a8c984 Riku Voipio
        return -TARGET_EFAULT;
2577 88a8c984 Riku Voipio
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2578 88a8c984 Riku Voipio
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2579 88a8c984 Riku Voipio
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2580 88a8c984 Riku Voipio
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2581 88a8c984 Riku Voipio
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2582 88a8c984 Riku Voipio
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2583 88a8c984 Riku Voipio
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2584 88a8c984 Riku Voipio
    unlock_user_struct(target_sd, target_addr, 0);
2585 88a8c984 Riku Voipio
    return 0;
2586 88a8c984 Riku Voipio
}
2587 88a8c984 Riku Voipio
2588 88a8c984 Riku Voipio
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2589 88a8c984 Riku Voipio
                                               struct shmid_ds *host_sd)
2590 88a8c984 Riku Voipio
{
2591 88a8c984 Riku Voipio
    struct target_shmid_ds *target_sd;
2592 88a8c984 Riku Voipio
2593 88a8c984 Riku Voipio
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2594 88a8c984 Riku Voipio
        return -TARGET_EFAULT;
2595 88a8c984 Riku Voipio
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2596 88a8c984 Riku Voipio
        return -TARGET_EFAULT;
2597 88a8c984 Riku Voipio
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2598 88a8c984 Riku Voipio
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2599 88a8c984 Riku Voipio
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2600 88a8c984 Riku Voipio
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2601 88a8c984 Riku Voipio
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2602 88a8c984 Riku Voipio
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2603 88a8c984 Riku Voipio
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2604 88a8c984 Riku Voipio
    unlock_user_struct(target_sd, target_addr, 1);
2605 88a8c984 Riku Voipio
    return 0;
2606 88a8c984 Riku Voipio
}
2607 88a8c984 Riku Voipio
2608 88a8c984 Riku Voipio
struct  target_shminfo {
2609 88a8c984 Riku Voipio
    abi_ulong shmmax;
2610 88a8c984 Riku Voipio
    abi_ulong shmmin;
2611 88a8c984 Riku Voipio
    abi_ulong shmmni;
2612 88a8c984 Riku Voipio
    abi_ulong shmseg;
2613 88a8c984 Riku Voipio
    abi_ulong shmall;
2614 88a8c984 Riku Voipio
};
2615 88a8c984 Riku Voipio
2616 88a8c984 Riku Voipio
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2617 88a8c984 Riku Voipio
                                              struct shminfo *host_shminfo)
2618 88a8c984 Riku Voipio
{
2619 88a8c984 Riku Voipio
    struct target_shminfo *target_shminfo;
2620 88a8c984 Riku Voipio
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2621 88a8c984 Riku Voipio
        return -TARGET_EFAULT;
2622 88a8c984 Riku Voipio
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2623 88a8c984 Riku Voipio
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2624 88a8c984 Riku Voipio
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2625 88a8c984 Riku Voipio
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2626 88a8c984 Riku Voipio
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2627 88a8c984 Riku Voipio
    unlock_user_struct(target_shminfo, target_addr, 1);
2628 88a8c984 Riku Voipio
    return 0;
2629 88a8c984 Riku Voipio
}
2630 88a8c984 Riku Voipio
2631 88a8c984 Riku Voipio
struct target_shm_info {
2632 88a8c984 Riku Voipio
    int used_ids;
2633 88a8c984 Riku Voipio
    abi_ulong shm_tot;
2634 88a8c984 Riku Voipio
    abi_ulong shm_rss;
2635 88a8c984 Riku Voipio
    abi_ulong shm_swp;
2636 88a8c984 Riku Voipio
    abi_ulong swap_attempts;
2637 88a8c984 Riku Voipio
    abi_ulong swap_successes;
2638 88a8c984 Riku Voipio
};
2639 88a8c984 Riku Voipio
2640 88a8c984 Riku Voipio
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2641 88a8c984 Riku Voipio
                                               struct shm_info *host_shm_info)
2642 88a8c984 Riku Voipio
{
2643 88a8c984 Riku Voipio
    struct target_shm_info *target_shm_info;
2644 88a8c984 Riku Voipio
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2645 88a8c984 Riku Voipio
        return -TARGET_EFAULT;
2646 88a8c984 Riku Voipio
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2647 88a8c984 Riku Voipio
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2648 88a8c984 Riku Voipio
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2649 88a8c984 Riku Voipio
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2650 88a8c984 Riku Voipio
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2651 88a8c984 Riku Voipio
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2652 88a8c984 Riku Voipio
    unlock_user_struct(target_shm_info, target_addr, 1);
2653 88a8c984 Riku Voipio
    return 0;
2654 88a8c984 Riku Voipio
}
2655 88a8c984 Riku Voipio
2656 88a8c984 Riku Voipio
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2657 88a8c984 Riku Voipio
{
2658 88a8c984 Riku Voipio
    struct shmid_ds dsarg;
2659 88a8c984 Riku Voipio
    struct shminfo shminfo;
2660 88a8c984 Riku Voipio
    struct shm_info shm_info;
2661 88a8c984 Riku Voipio
    abi_long ret = -TARGET_EINVAL;
2662 88a8c984 Riku Voipio
2663 88a8c984 Riku Voipio
    cmd &= 0xff;
2664 88a8c984 Riku Voipio
2665 88a8c984 Riku Voipio
    switch(cmd) {
2666 88a8c984 Riku Voipio
    case IPC_STAT:
2667 88a8c984 Riku Voipio
    case IPC_SET:
2668 88a8c984 Riku Voipio
    case SHM_STAT:
2669 88a8c984 Riku Voipio
        if (target_to_host_shmid_ds(&dsarg, buf))
2670 88a8c984 Riku Voipio
            return -TARGET_EFAULT;
2671 88a8c984 Riku Voipio
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2672 88a8c984 Riku Voipio
        if (host_to_target_shmid_ds(buf, &dsarg))
2673 88a8c984 Riku Voipio
            return -TARGET_EFAULT;
2674 88a8c984 Riku Voipio
        break;
2675 88a8c984 Riku Voipio
    case IPC_INFO:
2676 88a8c984 Riku Voipio
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2677 88a8c984 Riku Voipio
        if (host_to_target_shminfo(buf, &shminfo))
2678 88a8c984 Riku Voipio
            return -TARGET_EFAULT;
2679 88a8c984 Riku Voipio
        break;
2680 88a8c984 Riku Voipio
    case SHM_INFO:
2681 88a8c984 Riku Voipio
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2682 88a8c984 Riku Voipio
        if (host_to_target_shm_info(buf, &shm_info))
2683 88a8c984 Riku Voipio
            return -TARGET_EFAULT;
2684 88a8c984 Riku Voipio
        break;
2685 88a8c984 Riku Voipio
    case IPC_RMID:
2686 88a8c984 Riku Voipio
    case SHM_LOCK:
2687 88a8c984 Riku Voipio
    case SHM_UNLOCK:
2688 88a8c984 Riku Voipio
        ret = get_errno(shmctl(shmid, cmd, NULL));
2689 88a8c984 Riku Voipio
        break;
2690 88a8c984 Riku Voipio
    }
2691 88a8c984 Riku Voipio
2692 88a8c984 Riku Voipio
    return ret;
2693 88a8c984 Riku Voipio
}
2694 88a8c984 Riku Voipio
2695 88a8c984 Riku Voipio
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2696 88a8c984 Riku Voipio
{
2697 88a8c984 Riku Voipio
    abi_long raddr;
2698 88a8c984 Riku Voipio
    void *host_raddr;
2699 88a8c984 Riku Voipio
    struct shmid_ds shm_info;
2700 88a8c984 Riku Voipio
    int i,ret;
2701 88a8c984 Riku Voipio
2702 88a8c984 Riku Voipio
    /* find out the length of the shared memory segment */
2703 88a8c984 Riku Voipio
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2704 88a8c984 Riku Voipio
    if (is_error(ret)) {
2705 88a8c984 Riku Voipio
        /* can't get length, bail out */
2706 88a8c984 Riku Voipio
        return ret;
2707 88a8c984 Riku Voipio
    }
2708 88a8c984 Riku Voipio
2709 88a8c984 Riku Voipio
    mmap_lock();
2710 88a8c984 Riku Voipio
2711 88a8c984 Riku Voipio
    if (shmaddr)
2712 88a8c984 Riku Voipio
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2713 88a8c984 Riku Voipio
    else {
2714 88a8c984 Riku Voipio
        abi_ulong mmap_start;
2715 88a8c984 Riku Voipio
2716 88a8c984 Riku Voipio
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2717 88a8c984 Riku Voipio
2718 88a8c984 Riku Voipio
        if (mmap_start == -1) {
2719 88a8c984 Riku Voipio
            errno = ENOMEM;
2720 88a8c984 Riku Voipio
            host_raddr = (void *)-1;
2721 88a8c984 Riku Voipio
        } else
2722 88a8c984 Riku Voipio
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2723 88a8c984 Riku Voipio
    }
2724 88a8c984 Riku Voipio
2725 88a8c984 Riku Voipio
    if (host_raddr == (void *)-1) {
2726 88a8c984 Riku Voipio
        mmap_unlock();
2727 88a8c984 Riku Voipio
        return get_errno((long)host_raddr);
2728 88a8c984 Riku Voipio
    }
2729 88a8c984 Riku Voipio
    raddr=h2g((unsigned long)host_raddr);
2730 88a8c984 Riku Voipio
2731 88a8c984 Riku Voipio
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2732 88a8c984 Riku Voipio
                   PAGE_VALID | PAGE_READ |
2733 88a8c984 Riku Voipio
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2734 88a8c984 Riku Voipio
2735 88a8c984 Riku Voipio
    for (i = 0; i < N_SHM_REGIONS; i++) {
2736 88a8c984 Riku Voipio
        if (shm_regions[i].start == 0) {
2737 88a8c984 Riku Voipio
            shm_regions[i].start = raddr;
2738 88a8c984 Riku Voipio
            shm_regions[i].size = shm_info.shm_segsz;
2739 88a8c984 Riku Voipio
            break;
2740 88a8c984 Riku Voipio
        }
2741 88a8c984 Riku Voipio
    }
2742 88a8c984 Riku Voipio
2743 88a8c984 Riku Voipio
    mmap_unlock();
2744 88a8c984 Riku Voipio
    return raddr;
2745 88a8c984 Riku Voipio
2746 88a8c984 Riku Voipio
}
2747 88a8c984 Riku Voipio
2748 88a8c984 Riku Voipio
static inline abi_long do_shmdt(abi_ulong shmaddr)
2749 88a8c984 Riku Voipio
{
2750 88a8c984 Riku Voipio
    int i;
2751 88a8c984 Riku Voipio
2752 88a8c984 Riku Voipio
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2753 88a8c984 Riku Voipio
        if (shm_regions[i].start == shmaddr) {
2754 88a8c984 Riku Voipio
            shm_regions[i].start = 0;
2755 88a8c984 Riku Voipio
            page_set_flags(shmaddr, shm_regions[i].size, 0);
2756 88a8c984 Riku Voipio
            break;
2757 88a8c984 Riku Voipio
        }
2758 88a8c984 Riku Voipio
    }
2759 88a8c984 Riku Voipio
2760 88a8c984 Riku Voipio
    return get_errno(shmdt(g2h(shmaddr)));
2761 88a8c984 Riku Voipio
}
2762 88a8c984 Riku Voipio
2763 1c54ff97 aurel32
#ifdef TARGET_NR_ipc
2764 53a5960a pbrook
/* ??? This only works with linear mappings.  */
2765 0da46a6e ths
/* do_ipc() must return target values and target errnos. */
2766 992f48a0 blueswir1
static abi_long do_ipc(unsigned int call, int first,
2767 992f48a0 blueswir1
                       int second, int third,
2768 992f48a0 blueswir1
                       abi_long ptr, abi_long fifth)
2769 8853f86e bellard
{
2770 8853f86e bellard
    int version;
2771 992f48a0 blueswir1
    abi_long ret = 0;
2772 8853f86e bellard
2773 8853f86e bellard
    version = call >> 16;
2774 8853f86e bellard
    call &= 0xffff;
2775 8853f86e bellard
2776 8853f86e bellard
    switch (call) {
2777 fa294816 ths
    case IPCOP_semop:
2778 e5289087 aurel32
        ret = do_semop(first, ptr, second);
2779 fa294816 ths
        break;
2780 fa294816 ths
2781 fa294816 ths
    case IPCOP_semget:
2782 fa294816 ths
        ret = get_errno(semget(first, second, third));
2783 fa294816 ths
        break;
2784 fa294816 ths
2785 fa294816 ths
    case IPCOP_semctl:
2786 e5289087 aurel32
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2787 fa294816 ths
        break;
2788 d96372ef ths
2789 1c54ff97 aurel32
    case IPCOP_msgget:
2790 1c54ff97 aurel32
        ret = get_errno(msgget(first, second));
2791 1c54ff97 aurel32
        break;
2792 d96372ef ths
2793 1c54ff97 aurel32
    case IPCOP_msgsnd:
2794 1c54ff97 aurel32
        ret = do_msgsnd(first, ptr, second, third);
2795 1c54ff97 aurel32
        break;
2796 d96372ef ths
2797 1c54ff97 aurel32
    case IPCOP_msgctl:
2798 1c54ff97 aurel32
        ret = do_msgctl(first, second, ptr);
2799 1c54ff97 aurel32
        break;
2800 d96372ef ths
2801 1c54ff97 aurel32
    case IPCOP_msgrcv:
2802 1c54ff97 aurel32
        switch (version) {
2803 1c54ff97 aurel32
        case 0:
2804 1c54ff97 aurel32
            {
2805 1c54ff97 aurel32
                struct target_ipc_kludge {
2806 1c54ff97 aurel32
                    abi_long msgp;
2807 1c54ff97 aurel32
                    abi_long msgtyp;
2808 1c54ff97 aurel32
                } *tmp;
2809 1c54ff97 aurel32
2810 1c54ff97 aurel32
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2811 1c54ff97 aurel32
                    ret = -TARGET_EFAULT;
2812 1c54ff97 aurel32
                    break;
2813 1c54ff97 aurel32
                }
2814 d96372ef ths
2815 1c54ff97 aurel32
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2816 d96372ef ths
2817 1c54ff97 aurel32
                unlock_user_struct(tmp, ptr, 0);
2818 1c54ff97 aurel32
                break;
2819 1c54ff97 aurel32
            }
2820 1c54ff97 aurel32
        default:
2821 1c54ff97 aurel32
            ret = do_msgrcv(first, ptr, second, fifth, third);
2822 1c54ff97 aurel32
        }
2823 1c54ff97 aurel32
        break;
2824 d96372ef ths
2825 8853f86e bellard
    case IPCOP_shmat:
2826 88a8c984 Riku Voipio
        switch (version) {
2827 88a8c984 Riku Voipio
        default:
2828 5a4a898d bellard
        {
2829 5a4a898d bellard
            abi_ulong raddr;
2830 88a8c984 Riku Voipio
            raddr = do_shmat(first, ptr, second);
2831 88a8c984 Riku Voipio
            if (is_error(raddr))
2832 88a8c984 Riku Voipio
                return get_errno(raddr);
2833 2f619698 bellard
            if (put_user_ual(raddr, third))
2834 5a4a898d bellard
                return -TARGET_EFAULT;
2835 88a8c984 Riku Voipio
            break;
2836 88a8c984 Riku Voipio
        }
2837 88a8c984 Riku Voipio
        case 1:
2838 88a8c984 Riku Voipio
            ret = -TARGET_EINVAL;
2839 88a8c984 Riku Voipio
            break;
2840 5a4a898d bellard
        }
2841 8853f86e bellard
        break;
2842 8853f86e bellard
    case IPCOP_shmdt:
2843 88a8c984 Riku Voipio
        ret = do_shmdt(ptr);
2844 8853f86e bellard
        break;
2845 8853f86e bellard
2846 8853f86e bellard
    case IPCOP_shmget:
2847 8853f86e bellard
        /* IPC_* flag values are the same on all linux platforms */
2848 8853f86e bellard
        ret = get_errno(shmget(first, second, third));
2849 8853f86e bellard
        break;
2850 8853f86e bellard
2851 8853f86e bellard
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2852 8853f86e bellard
    case IPCOP_shmctl:
2853 88a8c984 Riku Voipio
        ret = do_shmctl(first, second, third);
2854 8853f86e bellard
        break;
2855 8853f86e bellard
    default:
2856 32407103 j_mayer
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2857 0da46a6e ths
        ret = -TARGET_ENOSYS;
2858 8853f86e bellard
        break;
2859 8853f86e bellard
    }
2860 8853f86e bellard
    return ret;
2861 8853f86e bellard
}
2862 32407103 j_mayer
#endif
2863 8853f86e bellard
2864 31e31b8a bellard
/* kernel structure types definitions */
2865 31e31b8a bellard
#define IFNAMSIZ        16
2866 31e31b8a bellard
2867 001faf32 Blue Swirl
#define STRUCT(name, ...) STRUCT_ ## name,
2868 31e31b8a bellard
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2869 31e31b8a bellard
enum {
2870 31e31b8a bellard
#include "syscall_types.h"
2871 31e31b8a bellard
};
2872 31e31b8a bellard
#undef STRUCT
2873 31e31b8a bellard
#undef STRUCT_SPECIAL
2874 31e31b8a bellard
2875 001faf32 Blue Swirl
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2876 31e31b8a bellard
#define STRUCT_SPECIAL(name)
2877 31e31b8a bellard
#include "syscall_types.h"
2878 31e31b8a bellard
#undef STRUCT
2879 31e31b8a bellard
#undef STRUCT_SPECIAL
2880 31e31b8a bellard
2881 31e31b8a bellard
typedef struct IOCTLEntry {
2882 2ab83ea7 bellard
    unsigned int target_cmd;
2883 2ab83ea7 bellard
    unsigned int host_cmd;
2884 31e31b8a bellard
    const char *name;
2885 31e31b8a bellard
    int access;
2886 1a9353d2 bellard
    const argtype arg_type[5];
2887 31e31b8a bellard
} IOCTLEntry;
2888 31e31b8a bellard
2889 31e31b8a bellard
#define IOC_R 0x0001
2890 31e31b8a bellard
#define IOC_W 0x0002
2891 31e31b8a bellard
#define IOC_RW (IOC_R | IOC_W)
2892 31e31b8a bellard
2893 31e31b8a bellard
#define MAX_STRUCT_SIZE 4096
2894 31e31b8a bellard
2895 9f106a75 blueswir1
static IOCTLEntry ioctl_entries[] = {
2896 001faf32 Blue Swirl
#define IOCTL(cmd, access, ...) \
2897 001faf32 Blue Swirl
    { TARGET_ ## cmd, cmd, #cmd, access, {  __VA_ARGS__ } },
2898 31e31b8a bellard
#include "ioctls.h"
2899 31e31b8a bellard
    { 0, 0, },
2900 31e31b8a bellard
};
2901 31e31b8a bellard
2902 53a5960a pbrook
/* ??? Implement proper locking for ioctls.  */
2903 0da46a6e ths
/* do_ioctl() Must return target values and target errnos. */
2904 992f48a0 blueswir1
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2905 31e31b8a bellard
{
2906 31e31b8a bellard
    const IOCTLEntry *ie;
2907 31e31b8a bellard
    const argtype *arg_type;
2908 992f48a0 blueswir1
    abi_long ret;
2909 31e31b8a bellard
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2910 53a5960a pbrook
    int target_size;
2911 53a5960a pbrook
    void *argptr;
2912 31e31b8a bellard
2913 31e31b8a bellard
    ie = ioctl_entries;
2914 31e31b8a bellard
    for(;;) {
2915 31e31b8a bellard
        if (ie->target_cmd == 0) {
2916 32407103 j_mayer
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2917 0da46a6e ths
            return -TARGET_ENOSYS;
2918 31e31b8a bellard
        }
2919 31e31b8a bellard
        if (ie->target_cmd == cmd)
2920 31e31b8a bellard
            break;
2921 31e31b8a bellard
        ie++;
2922 31e31b8a bellard
    }
2923 31e31b8a bellard
    arg_type = ie->arg_type;
2924 9de5e440 bellard
#if defined(DEBUG)
2925 32407103 j_mayer
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2926 72f03900 bellard
#endif
2927 31e31b8a bellard
    switch(arg_type[0]) {
2928 31e31b8a bellard
    case TYPE_NULL:
2929 31e31b8a bellard
        /* no argument */
2930 31e31b8a bellard
        ret = get_errno(ioctl(fd, ie->host_cmd));
2931 31e31b8a bellard
        break;
2932 31e31b8a bellard
    case TYPE_PTRVOID:
2933 31e31b8a bellard
    case TYPE_INT:
2934 31e31b8a bellard
        /* int argment */
2935 31e31b8a bellard
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2936 31e31b8a bellard
        break;
2937 31e31b8a bellard
    case TYPE_PTR:
2938 31e31b8a bellard
        arg_type++;
2939 53a5960a pbrook
        target_size = thunk_type_size(arg_type, 0);
2940 31e31b8a bellard
        switch(ie->access) {
2941 31e31b8a bellard
        case IOC_R:
2942 31e31b8a bellard
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2943 31e31b8a bellard
            if (!is_error(ret)) {
2944 579a97f7 bellard
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2945 579a97f7 bellard
                if (!argptr)
2946 579a97f7 bellard
                    return -TARGET_EFAULT;
2947 53a5960a pbrook
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2948 53a5960a pbrook
                unlock_user(argptr, arg, target_size);
2949 31e31b8a bellard
            }
2950 31e31b8a bellard
            break;
2951 31e31b8a bellard
        case IOC_W:
2952 579a97f7 bellard
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2953 579a97f7 bellard
            if (!argptr)
2954 579a97f7 bellard
                return -TARGET_EFAULT;
2955 53a5960a pbrook
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2956 53a5960a pbrook
            unlock_user(argptr, arg, 0);
2957 31e31b8a bellard
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2958 31e31b8a bellard
            break;
2959 31e31b8a bellard
        default:
2960 31e31b8a bellard
        case IOC_RW:
2961 579a97f7 bellard
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2962 579a97f7 bellard
            if (!argptr)
2963 579a97f7 bellard
                return -TARGET_EFAULT;
2964 53a5960a pbrook
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2965 53a5960a pbrook
            unlock_user(argptr, arg, 0);
2966 31e31b8a bellard
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2967 31e31b8a bellard
            if (!is_error(ret)) {
2968 579a97f7 bellard
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2969 579a97f7 bellard
                if (!argptr)
2970 579a97f7 bellard
                    return -TARGET_EFAULT;
2971 53a5960a pbrook
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2972 53a5960a pbrook
                unlock_user(argptr, arg, target_size);
2973 31e31b8a bellard
            }
2974 31e31b8a bellard
            break;
2975 31e31b8a bellard
        }
2976 31e31b8a bellard
        break;
2977 31e31b8a bellard
    default:
2978 32407103 j_mayer
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2979 32407103 j_mayer
                 (long)cmd, arg_type[0]);
2980 0da46a6e ths
        ret = -TARGET_ENOSYS;
2981 31e31b8a bellard
        break;
2982 31e31b8a bellard
    }
2983 31e31b8a bellard
    return ret;
2984 31e31b8a bellard
}
2985 31e31b8a bellard
2986 b39bc503 blueswir1
static const bitmask_transtbl iflag_tbl[] = {
2987 31e31b8a bellard
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2988 31e31b8a bellard
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2989 31e31b8a bellard
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2990 31e31b8a bellard
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2991 31e31b8a bellard
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2992 31e31b8a bellard
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2993 31e31b8a bellard
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2994 31e31b8a bellard
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2995 31e31b8a bellard
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2996 31e31b8a bellard
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2997 31e31b8a bellard
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2998 31e31b8a bellard
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2999 31e31b8a bellard
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3000 31e31b8a bellard
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3001 31e31b8a bellard
        { 0, 0, 0, 0 }
3002 31e31b8a bellard
};
3003 31e31b8a bellard
3004 b39bc503 blueswir1
static const bitmask_transtbl oflag_tbl[] = {
3005 31e31b8a bellard
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3006 31e31b8a bellard
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3007 31e31b8a bellard
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3008 31e31b8a bellard
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3009 31e31b8a bellard
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3010 31e31b8a bellard
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3011 31e31b8a bellard
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3012 31e31b8a bellard
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3013 31e31b8a bellard
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3014 31e31b8a bellard
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3015 31e31b8a bellard
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3016 31e31b8a bellard
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3017 31e31b8a bellard
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3018 31e31b8a bellard
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3019 31e31b8a bellard
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3020 31e31b8a bellard
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3021 31e31b8a bellard
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3022 31e31b8a bellard
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3023 31e31b8a bellard
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3024 31e31b8a bellard
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3025 31e31b8a bellard
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3026 31e31b8a bellard
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3027 31e31b8a bellard
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3028 31e31b8a bellard
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3029 31e31b8a bellard
        { 0, 0, 0, 0 }
3030 31e31b8a bellard
};
3031 31e31b8a bellard
3032 b39bc503 blueswir1
static const bitmask_transtbl cflag_tbl[] = {
3033 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3034 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3035 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3036 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3037 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3038 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3039 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3040 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3041 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3042 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3043 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3044 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3045 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3046 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3047 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3048 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3049 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3050 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3051 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3052 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3053 31e31b8a bellard
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3054 31e31b8a bellard
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3055 31e31b8a bellard
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3056 31e31b8a bellard
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3057 31e31b8a bellard
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3058 31e31b8a bellard
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3059 31e31b8a bellard
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3060 31e31b8a bellard
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3061 31e31b8a bellard
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3062 31e31b8a bellard
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3063 31e31b8a bellard
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3064 31e31b8a bellard
        { 0, 0, 0, 0 }
3065 31e31b8a bellard
};
3066 31e31b8a bellard
3067 b39bc503 blueswir1
static const bitmask_transtbl lflag_tbl[] = {
3068 31e31b8a bellard
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3069 31e31b8a bellard
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3070 31e31b8a bellard
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3071 31e31b8a bellard
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3072 31e31b8a bellard
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3073 31e31b8a bellard
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3074 31e31b8a bellard
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3075 31e31b8a bellard
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3076 31e31b8a bellard
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3077 31e31b8a bellard
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3078 31e31b8a bellard
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3079 31e31b8a bellard
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3080 31e31b8a bellard
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3081 31e31b8a bellard
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3082 31e31b8a bellard
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3083 31e31b8a bellard
        { 0, 0, 0, 0 }
3084 31e31b8a bellard
};
3085 31e31b8a bellard
3086 31e31b8a bellard
static void target_to_host_termios (void *dst, const void *src)
3087 31e31b8a bellard
{
3088 31e31b8a bellard
    struct host_termios *host = dst;
3089 31e31b8a bellard
    const struct target_termios *target = src;
3090 3b46e624 ths
3091 5fafdf24 ths
    host->c_iflag =
3092 31e31b8a bellard
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3093 5fafdf24 ths
    host->c_oflag =
3094 31e31b8a bellard
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3095 5fafdf24 ths
    host->c_cflag =
3096 31e31b8a bellard
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3097 5fafdf24 ths
    host->c_lflag =
3098 31e31b8a bellard
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3099 31e31b8a bellard
    host->c_line = target->c_line;
3100 3b46e624 ths
3101 44607123 Arnaud Patard
    memset(host->c_cc, 0, sizeof(host->c_cc));
3102 5fafdf24 ths
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3103 5fafdf24 ths
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3104 3b46e624 ths
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3105 5fafdf24 ths
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3106 3b46e624 ths
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3107 5fafdf24 ths
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3108 3b46e624 ths
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3109 5fafdf24 ths
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3110 3b46e624 ths
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3111 5fafdf24 ths
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3112 5fafdf24 ths
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3113 3b46e624 ths
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3114 3b46e624 ths
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3115 3b46e624 ths
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3116 3b46e624 ths
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3117 3b46e624 ths
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3118 5fafdf24 ths
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3119 31e31b8a bellard
}
3120 3b46e624 ths
3121 31e31b8a bellard
static void host_to_target_termios (void *dst, const void *src)
3122 31e31b8a bellard
{
3123 31e31b8a bellard
    struct target_termios *target = dst;
3124 31e31b8a bellard
    const struct host_termios *host = src;
3125 31e31b8a bellard
3126 5fafdf24 ths
    target->c_iflag =
3127 31e31b8a bellard
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3128 5fafdf24 ths
    target->c_oflag =
3129 31e31b8a bellard
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3130 5fafdf24 ths
    target->c_cflag =
3131 31e31b8a bellard
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3132 5fafdf24 ths
    target->c_lflag =
3133 31e31b8a bellard
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3134 31e31b8a bellard
    target->c_line = host->c_line;
3135 3b46e624 ths
3136 44607123 Arnaud Patard
    memset(target->c_cc, 0, sizeof(target->c_cc));
3137 31e31b8a bellard
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3138 31e31b8a bellard
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3139 31e31b8a bellard
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3140 31e31b8a bellard
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3141 31e31b8a bellard
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3142 31e31b8a bellard
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3143 31e31b8a bellard
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3144 31e31b8a bellard
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3145 31e31b8a bellard
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3146 31e31b8a bellard
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3147 31e31b8a bellard
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3148 31e31b8a bellard
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3149 31e31b8a bellard
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3150 31e31b8a bellard
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3151 31e31b8a bellard
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3152 31e31b8a bellard
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3153 31e31b8a bellard
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3154 31e31b8a bellard
}
3155 31e31b8a bellard
3156 8e853dc7 blueswir1
static const StructEntry struct_termios_def = {
3157 31e31b8a bellard
    .convert = { host_to_target_termios, target_to_host_termios },
3158 31e31b8a bellard
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3159 31e31b8a bellard
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3160 31e31b8a bellard
};
3161 31e31b8a bellard
3162 5286db75 bellard
static bitmask_transtbl mmap_flags_tbl[] = {
3163 5286db75 bellard
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3164 5286db75 bellard
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3165 5286db75 bellard
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3166 5286db75 bellard
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3167 5286db75 bellard
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3168 5286db75 bellard
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3169 5286db75 bellard
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3170 5286db75 bellard
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3171 5286db75 bellard
        { 0, 0, 0, 0 }
3172 5286db75 bellard
};
3173 5286db75 bellard
3174 2ab83ea7 bellard
#if defined(TARGET_I386)
3175 6dbad63e bellard
3176 6dbad63e bellard
/* NOTE: there is really one LDT for all the threads */
3177 b1d8e52e blueswir1
static uint8_t *ldt_table;
3178 6dbad63e bellard
3179 03acab66 bellard
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3180 6dbad63e bellard
{
3181 6dbad63e bellard
    int size;
3182 53a5960a pbrook
    void *p;
3183 6dbad63e bellard
3184 6dbad63e bellard
    if (!ldt_table)
3185 6dbad63e bellard
        return 0;
3186 6dbad63e bellard
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3187 6dbad63e bellard
    if (size > bytecount)
3188 6dbad63e bellard
        size = bytecount;
3189 579a97f7 bellard
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3190 579a97f7 bellard
    if (!p)
3191 03acab66 bellard
        return -TARGET_EFAULT;
3192 579a97f7 bellard
    /* ??? Should this by byteswapped?  */
3193 53a5960a pbrook
    memcpy(p, ldt_table, size);
3194 53a5960a pbrook
    unlock_user(p, ptr, size);
3195 6dbad63e bellard
    return size;
3196 6dbad63e bellard
}
3197 6dbad63e bellard
3198 6dbad63e bellard
/* XXX: add locking support */
3199 03acab66 bellard
static abi_long write_ldt(CPUX86State *env,
3200 03acab66 bellard
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3201 6dbad63e bellard
{
3202 6dbad63e bellard
    struct target_modify_ldt_ldt_s ldt_info;
3203 53a5960a pbrook
    struct target_modify_ldt_ldt_s *target_ldt_info;
3204 6dbad63e bellard
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3205 8d18e893 bellard
    int seg_not_present, useable, lm;
3206 6dbad63e bellard
    uint32_t *lp, entry_1, entry_2;
3207 6dbad63e bellard
3208 6dbad63e bellard
    if (bytecount != sizeof(ldt_info))
3209 03acab66 bellard
        return -TARGET_EINVAL;
3210 579a97f7 bellard
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3211 03acab66 bellard
        return -TARGET_EFAULT;
3212 53a5960a pbrook
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3213 53a5960a pbrook
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3214 53a5960a pbrook
    ldt_info.limit = tswap32(target_ldt_info->limit);
3215 53a5960a pbrook
    ldt_info.flags = tswap32(target_ldt_info->flags);
3216 53a5960a pbrook
    unlock_user_struct(target_ldt_info, ptr, 0);
3217 3b46e624 ths
3218 6dbad63e bellard
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3219 03acab66 bellard
        return -TARGET_EINVAL;
3220 6dbad63e bellard
    seg_32bit = ldt_info.flags & 1;
3221 6dbad63e bellard
    contents = (ldt_info.flags >> 1) & 3;
3222 6dbad63e bellard
    read_exec_only = (ldt_info.flags >> 3) & 1;
3223 6dbad63e bellard
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3224 6dbad63e bellard
    seg_not_present = (ldt_info.flags >> 5) & 1;
3225 6dbad63e bellard
    useable = (ldt_info.flags >> 6) & 1;
3226 8d18e893 bellard
#ifdef TARGET_ABI32
3227 8d18e893 bellard
    lm = 0;
3228 8d18e893 bellard
#else
3229 8d18e893 bellard
    lm = (ldt_info.flags >> 7) & 1;
3230 8d18e893 bellard
#endif
3231 6dbad63e bellard
    if (contents == 3) {
3232 6dbad63e bellard
        if (oldmode)
3233 03acab66 bellard
            return -TARGET_EINVAL;
3234 6dbad63e bellard
        if (seg_not_present == 0)
3235 03acab66 bellard
            return -TARGET_EINVAL;
3236 6dbad63e bellard
    }
3237 6dbad63e bellard
    /* allocate the LDT */
3238 6dbad63e bellard
    if (!ldt_table) {
3239 e441570f balrog
        env->ldt.base = target_mmap(0,
3240 e441570f balrog
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3241 e441570f balrog
                                    PROT_READ|PROT_WRITE,
3242 e441570f balrog
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3243 e441570f balrog
        if (env->ldt.base == -1)
3244 03acab66 bellard
            return -TARGET_ENOMEM;
3245 e441570f balrog
        memset(g2h(env->ldt.base), 0,
3246 e441570f balrog
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3247 6dbad63e bellard
        env->ldt.limit = 0xffff;
3248 e441570f balrog
        ldt_table = g2h(env->ldt.base);
3249 6dbad63e bellard
    }
3250 6dbad63e bellard
3251 6dbad63e bellard
    /* NOTE: same code as Linux kernel */
3252 6dbad63e bellard
    /* Allow LDTs to be cleared by the user. */
3253 6dbad63e bellard
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3254 6dbad63e bellard
        if (oldmode ||
3255 6dbad63e bellard
            (contents == 0                &&
3256 6dbad63e bellard
             read_exec_only == 1        &&
3257 6dbad63e bellard
             seg_32bit == 0                &&
3258 6dbad63e bellard
             limit_in_pages == 0        &&
3259 6dbad63e bellard
             seg_not_present == 1        &&
3260 6dbad63e bellard
             useable == 0 )) {
3261 6dbad63e bellard
            entry_1 = 0;
3262 6dbad63e bellard
            entry_2 = 0;
3263 6dbad63e bellard
            goto install;
3264 6dbad63e bellard
        }
3265 6dbad63e bellard
    }
3266 3b46e624 ths
3267 6dbad63e bellard
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3268 6dbad63e bellard
        (ldt_info.limit & 0x0ffff);
3269 6dbad63e bellard
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3270 6dbad63e bellard
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3271 6dbad63e bellard
        (ldt_info.limit & 0xf0000) |
3272 6dbad63e bellard
        ((read_exec_only ^ 1) << 9) |
3273 6dbad63e bellard
        (contents << 10) |
3274 6dbad63e bellard
        ((seg_not_present ^ 1) << 15) |
3275 6dbad63e bellard
        (seg_32bit << 22) |
3276 6dbad63e bellard
        (limit_in_pages << 23) |
3277 8d18e893 bellard
        (lm << 21) |
3278 6dbad63e bellard
        0x7000;
3279 6dbad63e bellard
    if (!oldmode)
3280 6dbad63e bellard
        entry_2 |= (useable << 20);
3281 14ae3ba7 bellard
3282 6dbad63e bellard
    /* Install the new entry ...  */
3283 6dbad63e bellard
install:
3284 6dbad63e bellard
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3285 6dbad63e bellard
    lp[0] = tswap32(entry_1);
3286 6dbad63e bellard
    lp[1] = tswap32(entry_2);
3287 6dbad63e bellard
    return 0;
3288 6dbad63e bellard
}
3289 6dbad63e bellard
3290 6dbad63e bellard
/* specific and weird i386 syscalls */
3291 8fcd3692 blueswir1
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3292 8fcd3692 blueswir1
                              unsigned long bytecount)
3293 6dbad63e bellard
{
3294 03acab66 bellard
    abi_long ret;
3295 3b46e624 ths
3296 6dbad63e bellard
    switch (func) {
3297 6dbad63e bellard
    case 0:
3298 6dbad63e bellard
        ret = read_ldt(ptr, bytecount);
3299 6dbad63e bellard
        break;
3300 6dbad63e bellard
    case 1:
3301 6dbad63e bellard
        ret = write_ldt(env, ptr, bytecount, 1);
3302 6dbad63e bellard
        break;
3303 6dbad63e bellard
    case 0x11:
3304 6dbad63e bellard
        ret = write_ldt(env, ptr, bytecount, 0);
3305 6dbad63e bellard
        break;
3306 03acab66 bellard
    default:
3307 03acab66 bellard
        ret = -TARGET_ENOSYS;
3308 03acab66 bellard
        break;
3309 6dbad63e bellard
    }
3310 6dbad63e bellard
    return ret;
3311 6dbad63e bellard
}
3312 1b6b029e bellard
3313 4583f589 blueswir1
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3314 8fcd3692 blueswir1
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3315 8d18e893 bellard
{
3316 8d18e893 bellard
    uint64_t *gdt_table = g2h(env->gdt.base);
3317 8d18e893 bellard
    struct target_modify_ldt_ldt_s ldt_info;
3318 8d18e893 bellard
    struct target_modify_ldt_ldt_s *target_ldt_info;
3319 8d18e893 bellard
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3320 8d18e893 bellard
    int seg_not_present, useable, lm;
3321 8d18e893 bellard
    uint32_t *lp, entry_1, entry_2;
3322 8d18e893 bellard
    int i;
3323 8d18e893 bellard
3324 8d18e893 bellard
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3325 8d18e893 bellard
    if (!target_ldt_info)
3326 8d18e893 bellard
        return -TARGET_EFAULT;
3327 8d18e893 bellard
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3328 8d18e893 bellard
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3329 8d18e893 bellard
    ldt_info.limit = tswap32(target_ldt_info->limit);
3330 8d18e893 bellard
    ldt_info.flags = tswap32(target_ldt_info->flags);
3331 8d18e893 bellard
    if (ldt_info.entry_number == -1) {
3332 8d18e893 bellard
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3333 8d18e893 bellard
            if (gdt_table[i] == 0) {
3334 8d18e893 bellard
                ldt_info.entry_number = i;
3335 8d18e893 bellard
                target_ldt_info->entry_number = tswap32(i);
3336 8d18e893 bellard
                break;
3337 8d18e893 bellard
            }
3338 8d18e893 bellard
        }
3339 8d18e893 bellard
    }
3340 8d18e893 bellard
    unlock_user_struct(target_ldt_info, ptr, 1);
3341 8d18e893 bellard
3342 8d18e893 bellard
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3343 8d18e893 bellard
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3344 8d18e893 bellard
           return -TARGET_EINVAL;
3345 8d18e893 bellard
    seg_32bit = ldt_info.flags & 1;
3346 8d18e893 bellard
    contents = (ldt_info.flags >> 1) & 3;
3347 8d18e893 bellard
    read_exec_only = (ldt_info.flags >> 3) & 1;
3348 8d18e893 bellard
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3349 8d18e893 bellard
    seg_not_present = (ldt_info.flags >> 5) & 1;
3350 8d18e893 bellard
    useable = (ldt_info.flags >> 6) & 1;
3351 8d18e893 bellard
#ifdef TARGET_ABI32
3352 8d18e893 bellard
    lm = 0;
3353 8d18e893 bellard
#else
3354 8d18e893 bellard
    lm = (ldt_info.flags >> 7) & 1;
3355 8d18e893 bellard
#endif
3356 8d18e893 bellard
3357 8d18e893 bellard
    if (contents == 3) {
3358 8d18e893 bellard
        if (seg_not_present == 0)
3359 8d18e893 bellard
            return -TARGET_EINVAL;
3360 8d18e893 bellard
    }
3361 8d18e893 bellard
3362 8d18e893 bellard
    /* NOTE: same code as Linux kernel */
3363 8d18e893 bellard
    /* Allow LDTs to be cleared by the user. */
3364 8d18e893 bellard
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3365 8d18e893 bellard
        if ((contents == 0             &&
3366 8d18e893 bellard
             read_exec_only == 1       &&
3367 8d18e893 bellard
             seg_32bit == 0            &&
3368 8d18e893 bellard
             limit_in_pages == 0       &&
3369 8d18e893 bellard
             seg_not_present == 1      &&
3370 8d18e893 bellard
             useable == 0 )) {
3371 8d18e893 bellard
            entry_1 = 0;
3372 8d18e893 bellard
            entry_2 = 0;
3373 8d18e893 bellard
            goto install;
3374 8d18e893 bellard
        }
3375 8d18e893 bellard
    }
3376 8d18e893 bellard
3377 8d18e893 bellard
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3378 8d18e893 bellard
        (ldt_info.limit & 0x0ffff);
3379 8d18e893 bellard
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3380 8d18e893 bellard
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3381 8d18e893 bellard
        (ldt_info.limit & 0xf0000) |
3382 8d18e893 bellard
        ((read_exec_only ^ 1) << 9) |
3383 8d18e893 bellard
        (contents << 10) |
3384 8d18e893 bellard
        ((seg_not_present ^ 1) << 15) |
3385 8d18e893 bellard
        (seg_32bit << 22) |
3386 8d18e893 bellard
        (limit_in_pages << 23) |
3387 8d18e893 bellard
        (useable << 20) |
3388 8d18e893 bellard
        (lm << 21) |
3389 8d18e893 bellard
        0x7000;
3390 8d18e893 bellard
3391 8d18e893 bellard
    /* Install the new entry ...  */
3392 8d18e893 bellard
install:
3393 8d18e893 bellard
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3394 8d18e893 bellard
    lp[0] = tswap32(entry_1);
3395 8d18e893 bellard
    lp[1] = tswap32(entry_2);
3396 8d18e893 bellard
    return 0;
3397 8d18e893 bellard
}
3398 8d18e893 bellard
3399 8fcd3692 blueswir1
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3400 8d18e893 bellard
{
3401 8d18e893 bellard
    struct target_modify_ldt_ldt_s *target_ldt_info;
3402 8d18e893 bellard
    uint64_t *gdt_table = g2h(env->gdt.base);
3403 8d18e893 bellard
    uint32_t base_addr, limit, flags;
3404 8d18e893 bellard
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3405 8d18e893 bellard
    int seg_not_present, useable, lm;
3406 8d18e893 bellard
    uint32_t *lp, entry_1, entry_2;
3407 8d18e893 bellard
3408 8d18e893 bellard
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3409 8d18e893 bellard
    if (!target_ldt_info)
3410 8d18e893 bellard
        return -TARGET_EFAULT;
3411 8d18e893 bellard
    idx = tswap32(target_ldt_info->entry_number);
3412 8d18e893 bellard
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3413 8d18e893 bellard
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3414 8d18e893 bellard
        unlock_user_struct(target_ldt_info, ptr, 1);
3415 8d18e893 bellard
        return -TARGET_EINVAL;
3416 8d18e893 bellard
    }
3417 8d18e893 bellard
    lp = (uint32_t *)(gdt_table + idx);
3418 8d18e893 bellard
    entry_1 = tswap32(lp[0]);
3419 8d18e893 bellard
    entry_2 = tswap32(lp[1]);
3420 8d18e893 bellard
    
3421 8d18e893 bellard
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3422 8d18e893 bellard
    contents = (entry_2 >> 10) & 3;
3423 8d18e893 bellard
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3424 8d18e893 bellard
    seg_32bit = (entry_2 >> 22) & 1;
3425 8d18e893 bellard
    limit_in_pages = (entry_2 >> 23) & 1;
3426 8d18e893 bellard
    useable = (entry_2 >> 20) & 1;
3427 8d18e893 bellard
#ifdef TARGET_ABI32
3428 8d18e893 bellard
    lm = 0;
3429 8d18e893 bellard
#else
3430 8d18e893 bellard
    lm = (entry_2 >> 21) & 1;
3431 8d18e893 bellard
#endif
3432 8d18e893 bellard
    flags = (seg_32bit << 0) | (contents << 1) |
3433 8d18e893 bellard
        (read_exec_only << 3) | (limit_in_pages << 4) |
3434 8d18e893 bellard
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3435 8d18e893 bellard
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3436 8d18e893 bellard
    base_addr = (entry_1 >> 16) | 
3437 8d18e893 bellard
        (entry_2 & 0xff000000) | 
3438 8d18e893 bellard
        ((entry_2 & 0xff) << 16);
3439 8d18e893 bellard
    target_ldt_info->base_addr = tswapl(base_addr);
3440 8d18e893 bellard
    target_ldt_info->limit = tswap32(limit);
3441 8d18e893 bellard
    target_ldt_info->flags = tswap32(flags);
3442 8d18e893 bellard
    unlock_user_struct(target_ldt_info, ptr, 1);
3443 8d18e893 bellard
    return 0;
3444 8d18e893 bellard
}
3445 4583f589 blueswir1
#endif /* TARGET_I386 && TARGET_ABI32 */
3446 8d18e893 bellard
3447 d2fd1af7 bellard
#ifndef TARGET_ABI32
3448 8fcd3692 blueswir1
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3449 d2fd1af7 bellard
{
3450 d2fd1af7 bellard
    abi_long ret;
3451 d2fd1af7 bellard
    abi_ulong val;
3452 d2fd1af7 bellard
    int idx;
3453 d2fd1af7 bellard
    
3454 d2fd1af7 bellard
    switch(code) {
3455 d2fd1af7 bellard
    case TARGET_ARCH_SET_GS:
3456 d2fd1af7 bellard
    case TARGET_ARCH_SET_FS:
3457 d2fd1af7 bellard
        if (code == TARGET_ARCH_SET_GS)
3458 d2fd1af7 bellard
            idx = R_GS;
3459 d2fd1af7 bellard
        else
3460 d2fd1af7 bellard
            idx = R_FS;
3461 d2fd1af7 bellard
        cpu_x86_load_seg(env, idx, 0);
3462 d2fd1af7 bellard
        env->segs[idx].base = addr;
3463 d2fd1af7 bellard
        break;
3464 d2fd1af7 bellard
    case TARGET_ARCH_GET_GS:
3465 d2fd1af7 bellard
    case TARGET_ARCH_GET_FS:
3466 d2fd1af7 bellard
        if (code == TARGET_ARCH_GET_GS)
3467 d2fd1af7 bellard
            idx = R_GS;
3468 d2fd1af7 bellard
        else
3469 d2fd1af7 bellard
            idx = R_FS;
3470 d2fd1af7 bellard
        val = env->segs[idx].base;
3471 d2fd1af7 bellard
        if (put_user(val, addr, abi_ulong))
3472 d2fd1af7 bellard
            return -TARGET_EFAULT;
3473 d2fd1af7 bellard
        break;
3474 d2fd1af7 bellard
    default:
3475 d2fd1af7 bellard
        ret = -TARGET_EINVAL;
3476 d2fd1af7 bellard
        break;
3477 d2fd1af7 bellard
    }
3478 d2fd1af7 bellard
    return 0;
3479 d2fd1af7 bellard
}
3480 d2fd1af7 bellard
#endif
3481 d2fd1af7 bellard
3482 2ab83ea7 bellard
#endif /* defined(TARGET_I386) */
3483 2ab83ea7 bellard
3484 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
3485 d865bab5 pbrook
3486 d865bab5 pbrook
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3487 d865bab5 pbrook
3488 d865bab5 pbrook
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3489 d865bab5 pbrook
typedef struct {
3490 d865bab5 pbrook
    CPUState *env;
3491 d865bab5 pbrook
    pthread_mutex_t mutex;
3492 d865bab5 pbrook
    pthread_cond_t cond;
3493 d865bab5 pbrook
    pthread_t thread;
3494 d865bab5 pbrook
    uint32_t tid;
3495 d865bab5 pbrook
    abi_ulong child_tidptr;
3496 d865bab5 pbrook
    abi_ulong parent_tidptr;
3497 d865bab5 pbrook
    sigset_t sigmask;
3498 d865bab5 pbrook
} new_thread_info;
3499 d865bab5 pbrook
3500 d865bab5 pbrook
static void *clone_func(void *arg)
3501 d865bab5 pbrook
{
3502 d865bab5 pbrook
    new_thread_info *info = arg;
3503 d865bab5 pbrook
    CPUState *env;
3504 edf8e2af Mika Westerberg
    TaskState *ts;
3505 d865bab5 pbrook
3506 d865bab5 pbrook
    env = info->env;
3507 d865bab5 pbrook
    thread_env = env;
3508 edf8e2af Mika Westerberg
    ts = (TaskState *)thread_env->opaque;
3509 d865bab5 pbrook
    info->tid = gettid();
3510 1e9fa730 Nathan Froyd
    env->host_tid = info->tid;
3511 edf8e2af Mika Westerberg
    task_settid(ts);
3512 d865bab5 pbrook
    if (info->child_tidptr)
3513 d865bab5 pbrook
        put_user_u32(info->tid, info->child_tidptr);
3514 d865bab5 pbrook
    if (info->parent_tidptr)
3515 d865bab5 pbrook
        put_user_u32(info->tid, info->parent_tidptr);
3516 d865bab5 pbrook
    /* Enable signals.  */
3517 d865bab5 pbrook
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3518 d865bab5 pbrook
    /* Signal to the parent that we're ready.  */
3519 d865bab5 pbrook
    pthread_mutex_lock(&info->mutex);
3520 d865bab5 pbrook
    pthread_cond_broadcast(&info->cond);
3521 d865bab5 pbrook
    pthread_mutex_unlock(&info->mutex);
3522 d865bab5 pbrook
    /* Wait until the parent has finshed initializing the tls state.  */
3523 d865bab5 pbrook
    pthread_mutex_lock(&clone_lock);
3524 d865bab5 pbrook
    pthread_mutex_unlock(&clone_lock);
3525 d865bab5 pbrook
    cpu_loop(env);
3526 d865bab5 pbrook
    /* never exits */
3527 d865bab5 pbrook
    return NULL;
3528 d865bab5 pbrook
}
3529 d865bab5 pbrook
#else
3530 1b6b029e bellard
/* this stack is the equivalent of the kernel stack associated with a
3531 1b6b029e bellard
   thread/process */
3532 1b6b029e bellard
#define NEW_STACK_SIZE 8192
3533 1b6b029e bellard
3534 1b6b029e bellard
static int clone_func(void *arg)
3535 1b6b029e bellard
{
3536 2ab83ea7 bellard
    CPUState *env = arg;
3537 1b6b029e bellard
    cpu_loop(env);
3538 1b6b029e bellard
    /* never exits */
3539 1b6b029e bellard
    return 0;
3540 1b6b029e bellard
}
3541 d865bab5 pbrook
#endif
3542 1b6b029e bellard
3543 0da46a6e ths
/* do_fork() Must return host values and target errnos (unlike most
3544 0da46a6e ths
   do_*() functions). */
3545 d865bab5 pbrook
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3546 d865bab5 pbrook
                   abi_ulong parent_tidptr, target_ulong newtls,
3547 d865bab5 pbrook
                   abi_ulong child_tidptr)
3548 1b6b029e bellard
{
3549 1b6b029e bellard
    int ret;
3550 5cd4393b bellard
    TaskState *ts;
3551 1b6b029e bellard
    uint8_t *new_stack;
3552 2ab83ea7 bellard
    CPUState *new_env;
3553 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
3554 d865bab5 pbrook
    unsigned int nptl_flags;
3555 d865bab5 pbrook
    sigset_t sigmask;
3556 d865bab5 pbrook
#endif
3557 3b46e624 ths
3558 436d124b balrog
    /* Emulate vfork() with fork() */
3559 436d124b balrog
    if (flags & CLONE_VFORK)
3560 436d124b balrog
        flags &= ~(CLONE_VFORK | CLONE_VM);
3561 436d124b balrog
3562 1b6b029e bellard
    if (flags & CLONE_VM) {
3563 edf8e2af Mika Westerberg
        TaskState *parent_ts = (TaskState *)env->opaque;
3564 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
3565 d865bab5 pbrook
        new_thread_info info;
3566 d865bab5 pbrook
        pthread_attr_t attr;
3567 bd0c5661 pbrook
#endif
3568 c3a92833 pbrook
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3569 624f7979 pbrook
        init_task_state(ts);
3570 5cd4393b bellard
        new_stack = ts->stack;
3571 1b6b029e bellard
        /* we create a new CPU instance. */
3572 c5be9f08 ths
        new_env = cpu_copy(env);
3573 b4558d74 Blue Swirl
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
3574 b4558d74 Blue Swirl
        cpu_reset(new_env);
3575 b4558d74 Blue Swirl
#endif
3576 6e68e076 pbrook
        /* Init regs that differ from the parent.  */
3577 6e68e076 pbrook
        cpu_clone_regs(new_env, newsp);
3578 5cd4393b bellard
        new_env->opaque = ts;
3579 edf8e2af Mika Westerberg
        ts->bprm = parent_ts->bprm;
3580 edf8e2af Mika Westerberg
        ts->info = parent_ts->info;
3581 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
3582 d865bab5 pbrook
        nptl_flags = flags;
3583 d865bab5 pbrook
        flags &= ~CLONE_NPTL_FLAGS2;
3584 d865bab5 pbrook
3585 c2764719 pbrook
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3586 c2764719 pbrook
            ts->child_tidptr = child_tidptr;
3587 c2764719 pbrook
        }
3588 c2764719 pbrook
3589 d865bab5 pbrook
        if (nptl_flags & CLONE_SETTLS)
3590 d865bab5 pbrook
            cpu_set_tls (new_env, newtls);
3591 d865bab5 pbrook
3592 d865bab5 pbrook
        /* Grab a mutex so that thread setup appears atomic.  */
3593 d865bab5 pbrook
        pthread_mutex_lock(&clone_lock);
3594 d865bab5 pbrook
3595 d865bab5 pbrook
        memset(&info, 0, sizeof(info));
3596 d865bab5 pbrook
        pthread_mutex_init(&info.mutex, NULL);
3597 d865bab5 pbrook
        pthread_mutex_lock(&info.mutex);
3598 d865bab5 pbrook
        pthread_cond_init(&info.cond, NULL);
3599 d865bab5 pbrook
        info.env = new_env;
3600 d865bab5 pbrook
        if (nptl_flags & CLONE_CHILD_SETTID)
3601 d865bab5 pbrook
            info.child_tidptr = child_tidptr;
3602 d865bab5 pbrook
        if (nptl_flags & CLONE_PARENT_SETTID)
3603 d865bab5 pbrook
            info.parent_tidptr = parent_tidptr;
3604 d865bab5 pbrook
3605 d865bab5 pbrook
        ret = pthread_attr_init(&attr);
3606 d865bab5 pbrook
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3607 d865bab5 pbrook
        /* It is not safe to deliver signals until the child has finished
3608 d865bab5 pbrook
           initializing, so temporarily block all signals.  */
3609 d865bab5 pbrook
        sigfillset(&sigmask);
3610 d865bab5 pbrook
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3611 d865bab5 pbrook
3612 d865bab5 pbrook
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
3613 c2764719 pbrook
        /* TODO: Free new CPU state if thread creation failed.  */
3614 d865bab5 pbrook
3615 d865bab5 pbrook
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3616 d865bab5 pbrook
        pthread_attr_destroy(&attr);
3617 d865bab5 pbrook
        if (ret == 0) {
3618 d865bab5 pbrook
            /* Wait for the child to initialize.  */
3619 d865bab5 pbrook
            pthread_cond_wait(&info.cond, &info.mutex);
3620 d865bab5 pbrook
            ret = info.tid;
3621 d865bab5 pbrook
            if (flags & CLONE_PARENT_SETTID)
3622 d865bab5 pbrook
                put_user_u32(ret, parent_tidptr);
3623 d865bab5 pbrook
        } else {
3624 d865bab5 pbrook
            ret = -1;
3625 d865bab5 pbrook
        }
3626 d865bab5 pbrook
        pthread_mutex_unlock(&info.mutex);
3627 d865bab5 pbrook
        pthread_cond_destroy(&info.cond);
3628 d865bab5 pbrook
        pthread_mutex_destroy(&info.mutex);
3629 d865bab5 pbrook
        pthread_mutex_unlock(&clone_lock);
3630 d865bab5 pbrook
#else
3631 d865bab5 pbrook
        if (flags & CLONE_NPTL_FLAGS2)
3632 d865bab5 pbrook
            return -EINVAL;
3633 d865bab5 pbrook
        /* This is probably going to die very quickly, but do it anyway.  */
3634 27725c1d bellard
#ifdef __ia64__
3635 60e99246 Aurelien Jarno
        ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
3636 27725c1d bellard
#else
3637 27725c1d bellard
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3638 27725c1d bellard
#endif
3639 d865bab5 pbrook
#endif
3640 1b6b029e bellard
    } else {
3641 1b6b029e bellard
        /* if no CLONE_VM, we consider it is a fork */
3642 d865bab5 pbrook
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3643 1b6b029e bellard
            return -EINVAL;
3644 d865bab5 pbrook
        fork_start();
3645 1b6b029e bellard
        ret = fork();
3646 d865bab5 pbrook
        if (ret == 0) {
3647 2b1319c8 aurel32
            /* Child Process.  */
3648 d865bab5 pbrook
            cpu_clone_regs(env, newsp);
3649 d865bab5 pbrook
            fork_end(1);
3650 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
3651 2b1319c8 aurel32
            /* There is a race condition here.  The parent process could
3652 2b1319c8 aurel32
               theoretically read the TID in the child process before the child
3653 2b1319c8 aurel32
               tid is set.  This would require using either ptrace
3654 2b1319c8 aurel32
               (not implemented) or having *_tidptr to point at a shared memory
3655 2b1319c8 aurel32
               mapping.  We can't repeat the spinlock hack used above because
3656 2b1319c8 aurel32
               the child process gets its own copy of the lock.  */
3657 d865bab5 pbrook
            if (flags & CLONE_CHILD_SETTID)
3658 d865bab5 pbrook
                put_user_u32(gettid(), child_tidptr);
3659 d865bab5 pbrook
            if (flags & CLONE_PARENT_SETTID)
3660 d865bab5 pbrook
                put_user_u32(gettid(), parent_tidptr);
3661 d865bab5 pbrook
            ts = (TaskState *)env->opaque;
3662 d865bab5 pbrook
            if (flags & CLONE_SETTLS)
3663 d865bab5 pbrook
                cpu_set_tls (env, newtls);
3664 c2764719 pbrook
            if (flags & CLONE_CHILD_CLEARTID)
3665 c2764719 pbrook
                ts->child_tidptr = child_tidptr;
3666 2b1319c8 aurel32
#endif
3667 d865bab5 pbrook
        } else {
3668 d865bab5 pbrook
            fork_end(0);
3669 d865bab5 pbrook
        }
3670 1b6b029e bellard
    }
3671 1b6b029e bellard
    return ret;
3672 1b6b029e bellard
}
3673 1b6b029e bellard
3674 5f106811 Arnaud Patard (Rtp)
/* warning : doesn't handle linux specific flags... */
3675 5f106811 Arnaud Patard (Rtp)
static int target_to_host_fcntl_cmd(int cmd)
3676 5f106811 Arnaud Patard (Rtp)
{
3677 5f106811 Arnaud Patard (Rtp)
    switch(cmd) {
3678 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_DUPFD:
3679 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_GETFD:
3680 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETFD:
3681 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_GETFL:
3682 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETFL:
3683 5f106811 Arnaud Patard (Rtp)
            return cmd;
3684 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_GETLK:
3685 5f106811 Arnaud Patard (Rtp)
            return F_GETLK;
3686 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETLK:
3687 5f106811 Arnaud Patard (Rtp)
            return F_SETLK;
3688 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETLKW:
3689 5f106811 Arnaud Patard (Rtp)
            return F_SETLKW;
3690 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_GETOWN:
3691 5f106811 Arnaud Patard (Rtp)
            return F_GETOWN;
3692 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETOWN:
3693 5f106811 Arnaud Patard (Rtp)
            return F_SETOWN;
3694 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_GETSIG:
3695 5f106811 Arnaud Patard (Rtp)
            return F_GETSIG;
3696 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETSIG:
3697 5f106811 Arnaud Patard (Rtp)
            return F_SETSIG;
3698 5f106811 Arnaud Patard (Rtp)
#if TARGET_ABI_BITS == 32
3699 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_GETLK64:
3700 5f106811 Arnaud Patard (Rtp)
            return F_GETLK64;
3701 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETLK64:
3702 5f106811 Arnaud Patard (Rtp)
            return F_SETLK64;
3703 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETLKW64:
3704 5f106811 Arnaud Patard (Rtp)
            return F_SETLKW64;
3705 5f106811 Arnaud Patard (Rtp)
#endif
3706 7e22e546 Ulrich Hecht
        case TARGET_F_SETLEASE:
3707 7e22e546 Ulrich Hecht
            return F_SETLEASE;
3708 7e22e546 Ulrich Hecht
        case TARGET_F_GETLEASE:
3709 7e22e546 Ulrich Hecht
            return F_GETLEASE;
3710 fbd5de9b malc
#ifdef F_DUPFD_CLOEXEC
3711 7e22e546 Ulrich Hecht
        case TARGET_F_DUPFD_CLOEXEC:
3712 7e22e546 Ulrich Hecht
            return F_DUPFD_CLOEXEC;
3713 fbd5de9b malc
#endif
3714 7e22e546 Ulrich Hecht
        case TARGET_F_NOTIFY:
3715 7e22e546 Ulrich Hecht
            return F_NOTIFY;
3716 5f106811 Arnaud Patard (Rtp)
        default:
3717 5f106811 Arnaud Patard (Rtp)
            return -TARGET_EINVAL;
3718 5f106811 Arnaud Patard (Rtp)
    }
3719 5f106811 Arnaud Patard (Rtp)
    return -TARGET_EINVAL;
3720 5f106811 Arnaud Patard (Rtp)
}
3721 5f106811 Arnaud Patard (Rtp)
3722 992f48a0 blueswir1
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3723 7775e9ec bellard
{
3724 7775e9ec bellard
    struct flock fl;
3725 53a5960a pbrook
    struct target_flock *target_fl;
3726 43f238d7 ths
    struct flock64 fl64;
3727 43f238d7 ths
    struct target_flock64 *target_fl64;
3728 992f48a0 blueswir1
    abi_long ret;
3729 5f106811 Arnaud Patard (Rtp)
    int host_cmd = target_to_host_fcntl_cmd(cmd);
3730 5f106811 Arnaud Patard (Rtp)
3731 5f106811 Arnaud Patard (Rtp)
    if (host_cmd == -TARGET_EINVAL)
3732 5f106811 Arnaud Patard (Rtp)
            return host_cmd;
3733 53a5960a pbrook
3734 7775e9ec bellard
    switch(cmd) {
3735 7775e9ec bellard
    case TARGET_F_GETLK:
3736 579a97f7 bellard
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3737 579a97f7 bellard
            return -TARGET_EFAULT;
3738 5813427b ths
        fl.l_type = tswap16(target_fl->l_type);
3739 5813427b ths
        fl.l_whence = tswap16(target_fl->l_whence);
3740 5813427b ths
        fl.l_start = tswapl(target_fl->l_start);
3741 5813427b ths
        fl.l_len = tswapl(target_fl->l_len);
3742 7e22e546 Ulrich Hecht
        fl.l_pid = tswap32(target_fl->l_pid);
3743 5813427b ths
        unlock_user_struct(target_fl, arg, 0);
3744 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3745 7775e9ec bellard
        if (ret == 0) {
3746 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3747 579a97f7 bellard
                return -TARGET_EFAULT;
3748 7775e9ec bellard
            target_fl->l_type = tswap16(fl.l_type);
3749 7775e9ec bellard
            target_fl->l_whence = tswap16(fl.l_whence);
3750 7775e9ec bellard
            target_fl->l_start = tswapl(fl.l_start);
3751 7775e9ec bellard
            target_fl->l_len = tswapl(fl.l_len);
3752 7e22e546 Ulrich Hecht
            target_fl->l_pid = tswap32(fl.l_pid);
3753 53a5960a pbrook
            unlock_user_struct(target_fl, arg, 1);
3754 7775e9ec bellard
        }
3755 7775e9ec bellard
        break;
3756 3b46e624 ths
3757 7775e9ec bellard
    case TARGET_F_SETLK:
3758 7775e9ec bellard
    case TARGET_F_SETLKW:
3759 579a97f7 bellard
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3760 579a97f7 bellard
            return -TARGET_EFAULT;
3761 7775e9ec bellard
        fl.l_type = tswap16(target_fl->l_type);
3762 7775e9ec bellard
        fl.l_whence = tswap16(target_fl->l_whence);
3763 7775e9ec bellard
        fl.l_start = tswapl(target_fl->l_start);
3764 7775e9ec bellard
        fl.l_len = tswapl(target_fl->l_len);
3765 7e22e546 Ulrich Hecht
        fl.l_pid = tswap32(target_fl->l_pid);
3766 53a5960a pbrook
        unlock_user_struct(target_fl, arg, 0);
3767 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3768 7775e9ec bellard
        break;
3769 3b46e624 ths
3770 7775e9ec bellard
    case TARGET_F_GETLK64:
3771 579a97f7 bellard
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3772 579a97f7 bellard
            return -TARGET_EFAULT;
3773 5813427b ths
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3774 5813427b ths
        fl64.l_whence = tswap16(target_fl64->l_whence);
3775 5813427b ths
        fl64.l_start = tswapl(target_fl64->l_start);
3776 5813427b ths
        fl64.l_len = tswapl(target_fl64->l_len);
3777 7e22e546 Ulrich Hecht
        fl64.l_pid = tswap32(target_fl64->l_pid);
3778 5813427b ths
        unlock_user_struct(target_fl64, arg, 0);
3779 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3780 43f238d7 ths
        if (ret == 0) {
3781 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3782 579a97f7 bellard
                return -TARGET_EFAULT;
3783 43f238d7 ths
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3784 43f238d7 ths
            target_fl64->l_whence = tswap16(fl64.l_whence);
3785 43f238d7 ths
            target_fl64->l_start = tswapl(fl64.l_start);
3786 43f238d7 ths
            target_fl64->l_len = tswapl(fl64.l_len);
3787 7e22e546 Ulrich Hecht
            target_fl64->l_pid = tswap32(fl64.l_pid);
3788 43f238d7 ths
            unlock_user_struct(target_fl64, arg, 1);
3789 43f238d7 ths
        }
3790 9ee1fa2c bellard
        break;
3791 7775e9ec bellard
    case TARGET_F_SETLK64:
3792 7775e9ec bellard
    case TARGET_F_SETLKW64:
3793 579a97f7 bellard
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3794 579a97f7 bellard
            return -TARGET_EFAULT;
3795 43f238d7 ths
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3796 43f238d7 ths
        fl64.l_whence = tswap16(target_fl64->l_whence);
3797 43f238d7 ths
        fl64.l_start = tswapl(target_fl64->l_start);
3798 43f238d7 ths
        fl64.l_len = tswapl(target_fl64->l_len);
3799 7e22e546 Ulrich Hecht
        fl64.l_pid = tswap32(target_fl64->l_pid);
3800 43f238d7 ths
        unlock_user_struct(target_fl64, arg, 0);
3801 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3802 7775e9ec bellard
        break;
3803 7775e9ec bellard
3804 5f106811 Arnaud Patard (Rtp)
    case TARGET_F_GETFL:
3805 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, arg));
3806 9ee1fa2c bellard
        if (ret >= 0) {
3807 9ee1fa2c bellard
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3808 9ee1fa2c bellard
        }
3809 ffa65c3b bellard
        break;
3810 ffa65c3b bellard
3811 5f106811 Arnaud Patard (Rtp)
    case TARGET_F_SETFL:
3812 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3813 5f106811 Arnaud Patard (Rtp)
        break;
3814 5f106811 Arnaud Patard (Rtp)
3815 5f106811 Arnaud Patard (Rtp)
    case TARGET_F_SETOWN:
3816 5f106811 Arnaud Patard (Rtp)
    case TARGET_F_GETOWN:
3817 5f106811 Arnaud Patard (Rtp)
    case TARGET_F_SETSIG:
3818 5f106811 Arnaud Patard (Rtp)
    case TARGET_F_GETSIG:
3819 7e22e546 Ulrich Hecht
    case TARGET_F_SETLEASE:
3820 7e22e546 Ulrich Hecht
    case TARGET_F_GETLEASE:
3821 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, arg));
3822 ffa65c3b bellard
        break;
3823 ffa65c3b bellard
3824 7775e9ec bellard
    default:
3825 9ee1fa2c bellard
        ret = get_errno(fcntl(fd, cmd, arg));
3826 7775e9ec bellard
        break;
3827 7775e9ec bellard
    }
3828 7775e9ec bellard
    return ret;
3829 7775e9ec bellard
}
3830 7775e9ec bellard
3831 67867308 bellard
#ifdef USE_UID16
3832 7775e9ec bellard
3833 67867308 bellard
static inline int high2lowuid(int uid)
3834 67867308 bellard
{
3835 67867308 bellard
    if (uid > 65535)
3836 67867308 bellard
        return 65534;
3837 67867308 bellard
    else
3838 67867308 bellard
        return uid;
3839 67867308 bellard
}
3840 67867308 bellard
3841 67867308 bellard
static inline int high2lowgid(int gid)
3842 67867308 bellard
{
3843 67867308 bellard
    if (gid > 65535)
3844 67867308 bellard
        return 65534;
3845 67867308 bellard
    else
3846 67867308 bellard
        return gid;
3847 67867308 bellard
}
3848 67867308 bellard
3849 67867308 bellard
static inline int low2highuid(int uid)
3850 67867308 bellard
{
3851 67867308 bellard
    if ((int16_t)uid == -1)
3852 67867308 bellard
        return -1;
3853 67867308 bellard
    else
3854 67867308 bellard
        return uid;
3855 67867308 bellard
}
3856 67867308 bellard
3857 67867308 bellard
static inline int low2highgid(int gid)
3858 67867308 bellard
{
3859 67867308 bellard
    if ((int16_t)gid == -1)
3860 67867308 bellard
        return -1;
3861 67867308 bellard
    else
3862 67867308 bellard
        return gid;
3863 67867308 bellard
}
3864 67867308 bellard
3865 67867308 bellard
#endif /* USE_UID16 */
3866 1b6b029e bellard
3867 31e31b8a bellard
void syscall_init(void)
3868 31e31b8a bellard
{
3869 2ab83ea7 bellard
    IOCTLEntry *ie;
3870 2ab83ea7 bellard
    const argtype *arg_type;
3871 2ab83ea7 bellard
    int size;
3872 b92c47c1 ths
    int i;
3873 2ab83ea7 bellard
3874 001faf32 Blue Swirl
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3875 5fafdf24 ths
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3876 31e31b8a bellard
#include "syscall_types.h"
3877 31e31b8a bellard
#undef STRUCT
3878 31e31b8a bellard
#undef STRUCT_SPECIAL
3879 2ab83ea7 bellard
3880 2ab83ea7 bellard
    /* we patch the ioctl size if necessary. We rely on the fact that
3881 2ab83ea7 bellard
       no ioctl has all the bits at '1' in the size field */
3882 2ab83ea7 bellard
    ie = ioctl_entries;
3883 2ab83ea7 bellard
    while (ie->target_cmd != 0) {
3884 2ab83ea7 bellard
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3885 2ab83ea7 bellard
            TARGET_IOC_SIZEMASK) {
3886 2ab83ea7 bellard
            arg_type = ie->arg_type;
3887 2ab83ea7 bellard
            if (arg_type[0] != TYPE_PTR) {
3888 5fafdf24 ths
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3889 2ab83ea7 bellard
                        ie->target_cmd);
3890 2ab83ea7 bellard
                exit(1);
3891 2ab83ea7 bellard
            }
3892 2ab83ea7 bellard
            arg_type++;
3893 2ab83ea7 bellard
            size = thunk_type_size(arg_type, 0);
3894 5fafdf24 ths
            ie->target_cmd = (ie->target_cmd &
3895 2ab83ea7 bellard
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3896 2ab83ea7 bellard
                (size << TARGET_IOC_SIZESHIFT);
3897 2ab83ea7 bellard
        }
3898 b92c47c1 ths
3899 b92c47c1 ths
        /* Build target_to_host_errno_table[] table from
3900 b92c47c1 ths
         * host_to_target_errno_table[]. */
3901 b92c47c1 ths
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3902 b92c47c1 ths
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3903 b92c47c1 ths
3904 2ab83ea7 bellard
        /* automatic consistency check if same arch */
3905 872ea0c0 balrog
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3906 872ea0c0 balrog
    (defined(__x86_64__) && defined(TARGET_X86_64))
3907 872ea0c0 balrog
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3908 872ea0c0 balrog
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3909 872ea0c0 balrog
                    ie->name, ie->target_cmd, ie->host_cmd);
3910 2ab83ea7 bellard
        }
3911 2ab83ea7 bellard
#endif
3912 2ab83ea7 bellard
        ie++;
3913 2ab83ea7 bellard
    }
3914 31e31b8a bellard
}
3915 c573ff67 bellard
3916 992f48a0 blueswir1
#if TARGET_ABI_BITS == 32
3917 ce4defa0 pbrook
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3918 ce4defa0 pbrook
{
3919 af325d36 ths
#ifdef TARGET_WORDS_BIGENDIAN
3920 ce4defa0 pbrook
    return ((uint64_t)word0 << 32) | word1;
3921 ce4defa0 pbrook
#else
3922 ce4defa0 pbrook
    return ((uint64_t)word1 << 32) | word0;
3923 ce4defa0 pbrook
#endif
3924 ce4defa0 pbrook
}
3925 992f48a0 blueswir1
#else /* TARGET_ABI_BITS == 32 */
3926 32407103 j_mayer
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3927 32407103 j_mayer
{
3928 32407103 j_mayer
    return word0;
3929 32407103 j_mayer
}
3930 992f48a0 blueswir1
#endif /* TARGET_ABI_BITS != 32 */
3931 ce4defa0 pbrook
3932 ce4defa0 pbrook
#ifdef TARGET_NR_truncate64
3933 992f48a0 blueswir1
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3934 992f48a0 blueswir1
                                         abi_long arg2,
3935 992f48a0 blueswir1
                                         abi_long arg3,
3936 992f48a0 blueswir1
                                         abi_long arg4)
3937 ce4defa0 pbrook
{
3938 ce4defa0 pbrook
#ifdef TARGET_ARM
3939 ce4defa0 pbrook
    if (((CPUARMState *)cpu_env)->eabi)
3940 ce4defa0 pbrook
      {
3941 ce4defa0 pbrook
        arg2 = arg3;
3942 ce4defa0 pbrook
        arg3 = arg4;
3943 ce4defa0 pbrook
      }
3944 ce4defa0 pbrook
#endif
3945 ce4defa0 pbrook
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3946 ce4defa0 pbrook
}
3947 ce4defa0 pbrook
#endif
3948 ce4defa0 pbrook
3949 ce4defa0 pbrook
#ifdef TARGET_NR_ftruncate64
3950 992f48a0 blueswir1
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3951 992f48a0 blueswir1
                                          abi_long arg2,
3952 992f48a0 blueswir1
                                          abi_long arg3,
3953 992f48a0 blueswir1
                                          abi_long arg4)
3954 ce4defa0 pbrook
{
3955 ce4defa0 pbrook
#ifdef TARGET_ARM
3956 ce4defa0 pbrook
    if (((CPUARMState *)cpu_env)->eabi)
3957 ce4defa0 pbrook
      {
3958 ce4defa0 pbrook
        arg2 = arg3;
3959 ce4defa0 pbrook
        arg3 = arg4;
3960 ce4defa0 pbrook
      }
3961 ce4defa0 pbrook
#endif
3962 ce4defa0 pbrook
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3963 ce4defa0 pbrook
}
3964 ce4defa0 pbrook
#endif
3965 ce4defa0 pbrook
3966 579a97f7 bellard
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3967 579a97f7 bellard
                                               abi_ulong target_addr)
3968 53a5960a pbrook
{
3969 53a5960a pbrook
    struct target_timespec *target_ts;
3970 53a5960a pbrook
3971 579a97f7 bellard
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3972 579a97f7 bellard
        return -TARGET_EFAULT;
3973 53a5960a pbrook
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3974 53a5960a pbrook
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3975 53a5960a pbrook
    unlock_user_struct(target_ts, target_addr, 0);
3976 b255bfa8 bellard
    return 0;
3977 53a5960a pbrook
}
3978 53a5960a pbrook
3979 579a97f7 bellard
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3980 579a97f7 bellard
                                               struct timespec *host_ts)
3981 53a5960a pbrook
{
3982 53a5960a pbrook
    struct target_timespec *target_ts;
3983 53a5960a pbrook
3984 579a97f7 bellard
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3985 579a97f7 bellard
        return -TARGET_EFAULT;
3986 53a5960a pbrook
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3987 53a5960a pbrook
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3988 53a5960a pbrook
    unlock_user_struct(target_ts, target_addr, 1);
3989 b255bfa8 bellard
    return 0;
3990 53a5960a pbrook
}
3991 53a5960a pbrook
3992 9d33b76b aurel32
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3993 6a24a778 balrog
static inline abi_long host_to_target_stat64(void *cpu_env,
3994 6a24a778 balrog
                                             abi_ulong target_addr,
3995 6a24a778 balrog
                                             struct stat *host_st)
3996 6a24a778 balrog
{
3997 6a24a778 balrog
#ifdef TARGET_ARM
3998 6a24a778 balrog
    if (((CPUARMState *)cpu_env)->eabi) {
3999 6a24a778 balrog
        struct target_eabi_stat64 *target_st;
4000 6a24a778 balrog
4001 6a24a778 balrog
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4002 6a24a778 balrog
            return -TARGET_EFAULT;
4003 6a24a778 balrog
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4004 6a24a778 balrog
        __put_user(host_st->st_dev, &target_st->st_dev);
4005 6a24a778 balrog
        __put_user(host_st->st_ino, &target_st->st_ino);
4006 6a24a778 balrog
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4007 6a24a778 balrog
        __put_user(host_st->st_ino, &target_st->__st_ino);
4008 6a24a778 balrog
#endif
4009 6a24a778 balrog
        __put_user(host_st->st_mode, &target_st->st_mode);
4010 6a24a778 balrog
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4011 6a24a778 balrog
        __put_user(host_st->st_uid, &target_st->st_uid);
4012 6a24a778 balrog
        __put_user(host_st->st_gid, &target_st->st_gid);
4013 6a24a778 balrog
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4014 6a24a778 balrog
        __put_user(host_st->st_size, &target_st->st_size);
4015 6a24a778 balrog
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4016 6a24a778 balrog
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4017 6a24a778 balrog
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4018 6a24a778 balrog
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4019 6a24a778 balrog
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4020 6a24a778 balrog
        unlock_user_struct(target_st, target_addr, 1);
4021 6a24a778 balrog
    } else
4022 6a24a778 balrog
#endif
4023 6a24a778 balrog
    {
4024 8b0ee8c5 Vince Weaver
#if (TARGET_LONG_BITS == 64) && (!defined(TARGET_ALPHA))
4025 9d33b76b aurel32
        struct target_stat *target_st;
4026 9d33b76b aurel32
#else
4027 6a24a778 balrog
        struct target_stat64 *target_st;
4028 9d33b76b aurel32
#endif
4029 6a24a778 balrog
4030 6a24a778 balrog
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4031 6a24a778 balrog
            return -TARGET_EFAULT;
4032 9d33b76b aurel32
        memset(target_st, 0, sizeof(*target_st));
4033 6a24a778 balrog
        __put_user(host_st->st_dev, &target_st->st_dev);
4034 6a24a778 balrog
        __put_user(host_st->st_ino, &target_st->st_ino);
4035 6a24a778 balrog
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4036 6a24a778 balrog
        __put_user(host_st->st_ino, &target_st->__st_ino);
4037 6a24a778 balrog
#endif
4038 6a24a778 balrog
        __put_user(host_st->st_mode, &target_st->st_mode);
4039 6a24a778 balrog
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4040 6a24a778 balrog
        __put_user(host_st->st_uid, &target_st->st_uid);
4041 6a24a778 balrog
        __put_user(host_st->st_gid, &target_st->st_gid);
4042 6a24a778 balrog
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4043 6a24a778 balrog
        /* XXX: better use of kernel struct */
4044 6a24a778 balrog
        __put_user(host_st->st_size, &target_st->st_size);
4045 6a24a778 balrog
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4046 6a24a778 balrog
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4047 6a24a778 balrog
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4048 6a24a778 balrog
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4049 6a24a778 balrog
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4050 6a24a778 balrog
        unlock_user_struct(target_st, target_addr, 1);
4051 6a24a778 balrog
    }
4052 6a24a778 balrog
4053 6a24a778 balrog
    return 0;
4054 6a24a778 balrog
}
4055 6a24a778 balrog
#endif
4056 6a24a778 balrog
4057 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
4058 bd0c5661 pbrook
/* ??? Using host futex calls even when target atomic operations
4059 bd0c5661 pbrook
   are not really atomic probably breaks things.  However implementing
4060 bd0c5661 pbrook
   futexes locally would make futexes shared between multiple processes
4061 bd0c5661 pbrook
   tricky.  However they're probably useless because guest atomic
4062 bd0c5661 pbrook
   operations won't work either.  */
4063 8fcd3692 blueswir1
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4064 8fcd3692 blueswir1
                    target_ulong uaddr2, int val3)
4065 bd0c5661 pbrook
{
4066 bd0c5661 pbrook
    struct timespec ts, *pts;
4067 a16aae0c Nathan Froyd
    int base_op;
4068 bd0c5661 pbrook
4069 bd0c5661 pbrook
    /* ??? We assume FUTEX_* constants are the same on both host
4070 bd0c5661 pbrook
       and target.  */
4071 a29ccd63 Martin Mohring
#ifdef FUTEX_CMD_MASK
4072 a16aae0c Nathan Froyd
    base_op = op & FUTEX_CMD_MASK;
4073 a29ccd63 Martin Mohring
#else
4074 a16aae0c Nathan Froyd
    base_op = op;
4075 a29ccd63 Martin Mohring
#endif
4076 a16aae0c Nathan Froyd
    switch (base_op) {
4077 bd0c5661 pbrook
    case FUTEX_WAIT:
4078 bd0c5661 pbrook
        if (timeout) {
4079 bd0c5661 pbrook
            pts = &ts;
4080 bd0c5661 pbrook
            target_to_host_timespec(pts, timeout);
4081 bd0c5661 pbrook
        } else {
4082 bd0c5661 pbrook
            pts = NULL;
4083 bd0c5661 pbrook
        }
4084 a29ccd63 Martin Mohring
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4085 bd0c5661 pbrook
                         pts, NULL, 0));
4086 bd0c5661 pbrook
    case FUTEX_WAKE:
4087 a29ccd63 Martin Mohring
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4088 bd0c5661 pbrook
    case FUTEX_FD:
4089 a29ccd63 Martin Mohring
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4090 bd0c5661 pbrook
    case FUTEX_REQUEUE:
4091 bd0c5661 pbrook
    case FUTEX_CMP_REQUEUE:
4092 a16aae0c Nathan Froyd
    case FUTEX_WAKE_OP:
4093 a16aae0c Nathan Froyd
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4094 a16aae0c Nathan Froyd
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4095 a16aae0c Nathan Froyd
           But the prototype takes a `struct timespec *'; insert casts
4096 a16aae0c Nathan Froyd
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4097 a16aae0c Nathan Froyd
           since it's not compared to guest memory.  */
4098 a16aae0c Nathan Froyd
        pts = (struct timespec *)(uintptr_t) timeout;
4099 a16aae0c Nathan Froyd
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4100 a16aae0c Nathan Froyd
                                   g2h(uaddr2),
4101 a16aae0c Nathan Froyd
                                   (base_op == FUTEX_CMP_REQUEUE
4102 a16aae0c Nathan Froyd
                                    ? tswap32(val3)
4103 a16aae0c Nathan Froyd
                                    : val3)));
4104 bd0c5661 pbrook
    default:
4105 bd0c5661 pbrook
        return -TARGET_ENOSYS;
4106 bd0c5661 pbrook
    }
4107 bd0c5661 pbrook
}
4108 bd0c5661 pbrook
#endif
4109 bd0c5661 pbrook
4110 1d9d8b55 pbrook
/* Map host to target signal numbers for the wait family of syscalls.
4111 1d9d8b55 pbrook
   Assume all other status bits are the same.  */
4112 1d9d8b55 pbrook
static int host_to_target_waitstatus(int status)
4113 1d9d8b55 pbrook
{
4114 1d9d8b55 pbrook
    if (WIFSIGNALED(status)) {
4115 1d9d8b55 pbrook
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4116 1d9d8b55 pbrook
    }
4117 1d9d8b55 pbrook
    if (WIFSTOPPED(status)) {
4118 1d9d8b55 pbrook
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4119 1d9d8b55 pbrook
               | (status & 0xff);
4120 1d9d8b55 pbrook
    }
4121 1d9d8b55 pbrook
    return status;
4122 1d9d8b55 pbrook
}
4123 1d9d8b55 pbrook
4124 a745ec6d pbrook
int get_osversion(void)
4125 a745ec6d pbrook
{
4126 a745ec6d pbrook
    static int osversion;
4127 a745ec6d pbrook
    struct new_utsname buf;
4128 a745ec6d pbrook
    const char *s;
4129 a745ec6d pbrook
    int i, n, tmp;
4130 a745ec6d pbrook
    if (osversion)
4131 a745ec6d pbrook
        return osversion;
4132 a745ec6d pbrook
    if (qemu_uname_release && *qemu_uname_release) {
4133 a745ec6d pbrook
        s = qemu_uname_release;
4134 a745ec6d pbrook
    } else {
4135 a745ec6d pbrook
        if (sys_uname(&buf))
4136 a745ec6d pbrook
            return 0;
4137 a745ec6d pbrook
        s = buf.release;
4138 a745ec6d pbrook
    }
4139 a745ec6d pbrook
    tmp = 0;
4140 a745ec6d pbrook
    for (i = 0; i < 3; i++) {
4141 a745ec6d pbrook
        n = 0;
4142 a745ec6d pbrook
        while (*s >= '0' && *s <= '9') {
4143 a745ec6d pbrook
            n *= 10;
4144 a745ec6d pbrook
            n += *s - '0';
4145 a745ec6d pbrook
            s++;
4146 a745ec6d pbrook
        }
4147 a745ec6d pbrook
        tmp = (tmp << 8) + n;
4148 a745ec6d pbrook
        if (*s == '.')
4149 a745ec6d pbrook
            s++;
4150 a745ec6d pbrook
    }
4151 a745ec6d pbrook
    osversion = tmp;
4152 a745ec6d pbrook
    return osversion;
4153 a745ec6d pbrook
}
4154 a745ec6d pbrook
4155 0da46a6e ths
/* do_syscall() should always have a single exit point at the end so
4156 0da46a6e ths
   that actions, such as logging of syscall results, can be performed.
4157 0da46a6e ths
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4158 992f48a0 blueswir1
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4159 992f48a0 blueswir1
                    abi_long arg2, abi_long arg3, abi_long arg4,
4160 992f48a0 blueswir1
                    abi_long arg5, abi_long arg6)
4161 31e31b8a bellard
{
4162 992f48a0 blueswir1
    abi_long ret;
4163 31e31b8a bellard
    struct stat st;
4164 56c8f68f bellard
    struct statfs stfs;
4165 53a5960a pbrook
    void *p;
4166 3b46e624 ths
4167 72f03900 bellard
#ifdef DEBUG
4168 c573ff67 bellard
    gemu_log("syscall %d", num);
4169 72f03900 bellard
#endif
4170 b92c47c1 ths
    if(do_strace)
4171 b92c47c1 ths
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4172 b92c47c1 ths
4173 31e31b8a bellard
    switch(num) {
4174 31e31b8a bellard
    case TARGET_NR_exit:
4175 2f7bb878 Juan Quintela
#ifdef CONFIG_USE_NPTL
4176 c2764719 pbrook
      /* In old applications this may be used to implement _exit(2).
4177 c2764719 pbrook
         However in threaded applictions it is used for thread termination,
4178 c2764719 pbrook
         and _exit_group is used for application termination.
4179 c2764719 pbrook
         Do thread termination if we have more then one thread.  */
4180 c2764719 pbrook
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4181 c2764719 pbrook
         be disabling signals.  */
4182 c2764719 pbrook
      if (first_cpu->next_cpu) {
4183 1e9fa730 Nathan Froyd
          TaskState *ts;
4184 c2764719 pbrook
          CPUState **lastp;
4185 c2764719 pbrook
          CPUState *p;
4186 c2764719 pbrook
4187 c2764719 pbrook
          cpu_list_lock();
4188 c2764719 pbrook
          lastp = &first_cpu;
4189 c2764719 pbrook
          p = first_cpu;
4190 c2764719 pbrook
          while (p && p != (CPUState *)cpu_env) {
4191 c2764719 pbrook
              lastp = &p->next_cpu;
4192 c2764719 pbrook
              p = p->next_cpu;
4193 c2764719 pbrook
          }
4194 c2764719 pbrook
          /* If we didn't find the CPU for this thread then something is
4195 c2764719 pbrook
             horribly wrong.  */
4196 c2764719 pbrook
          if (!p)
4197 c2764719 pbrook
              abort();
4198 c2764719 pbrook
          /* Remove the CPU from the list.  */
4199 c2764719 pbrook
          *lastp = p->next_cpu;
4200 c2764719 pbrook
          cpu_list_unlock();
4201 1e9fa730 Nathan Froyd
          ts = ((CPUState *)cpu_env)->opaque;
4202 c2764719 pbrook
          if (ts->child_tidptr) {
4203 c2764719 pbrook
              put_user_u32(0, ts->child_tidptr);
4204 c2764719 pbrook
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4205 c2764719 pbrook
                        NULL, NULL, 0);
4206 c2764719 pbrook
          }
4207 c2764719 pbrook
          /* TODO: Free CPU state.  */
4208 c2764719 pbrook
          pthread_exit(NULL);
4209 c2764719 pbrook
      }
4210 c2764719 pbrook
#endif
4211 9788c9ca Juan Quintela
#ifdef TARGET_GPROF
4212 7d13299d bellard
        _mcleanup();
4213 7d13299d bellard
#endif
4214 e9009676 bellard
        gdb_exit(cpu_env, arg1);
4215 c2764719 pbrook
        _exit(arg1);
4216 31e31b8a bellard
        ret = 0; /* avoid warning */
4217 31e31b8a bellard
        break;
4218 31e31b8a bellard
    case TARGET_NR_read:
4219 38d840e6 aurel32
        if (arg3 == 0)
4220 38d840e6 aurel32
            ret = 0;
4221 38d840e6 aurel32
        else {
4222 38d840e6 aurel32
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4223 38d840e6 aurel32
                goto efault;
4224 38d840e6 aurel32
            ret = get_errno(read(arg1, p, arg3));
4225 38d840e6 aurel32
            unlock_user(p, arg2, ret);
4226 38d840e6 aurel32
        }
4227 31e31b8a bellard
        break;
4228 31e31b8a bellard
    case TARGET_NR_write:
4229 579a97f7 bellard
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4230 579a97f7 bellard
            goto efault;
4231 53a5960a pbrook
        ret = get_errno(write(arg1, p, arg3));
4232 53a5960a pbrook
        unlock_user(p, arg2, 0);
4233 31e31b8a bellard
        break;
4234 31e31b8a bellard
    case TARGET_NR_open:
4235 2f619698 bellard
        if (!(p = lock_user_string(arg1)))
4236 2f619698 bellard
            goto efault;
4237 53a5960a pbrook
        ret = get_errno(open(path(p),
4238 ffa65c3b bellard
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
4239 ffa65c3b bellard
                             arg3));
4240 53a5960a pbrook
        unlock_user(p, arg1, 0);
4241 31e31b8a bellard
        break;
4242 82424832 ths
#if defined(TARGET_NR_openat) && defined(__NR_openat)
4243 82424832 ths
    case TARGET_NR_openat:
4244 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
4245 579a97f7 bellard
            goto efault;
4246 579a97f7 bellard
        ret = get_errno(sys_openat(arg1,
4247 579a97f7 bellard
                                   path(p),
4248 579a97f7 bellard
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
4249 579a97f7 bellard
                                   arg4));
4250 579a97f7 bellard
        unlock_user(p, arg2, 0);
4251 82424832 ths
        break;
4252 82424832 ths
#endif
4253 31e31b8a bellard
    case TARGET_NR_close:
4254 31e31b8a bellard
        ret = get_errno(close(arg1));
4255 31e31b8a bellard
        break;
4256 31e31b8a bellard
    case TARGET_NR_brk:
4257 53a5960a pbrook
        ret = do_brk(arg1);
4258 31e31b8a bellard
        break;
4259 31e31b8a bellard
    case TARGET_NR_fork:
4260 d865bab5 pbrook
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4261 31e31b8a bellard
        break;
4262 e5febef5 ths
#ifdef TARGET_NR_waitpid
4263 31e31b8a bellard
    case TARGET_NR_waitpid:
4264 31e31b8a bellard
        {
4265 53a5960a pbrook
            int status;
4266 53a5960a pbrook
            ret = get_errno(waitpid(arg1, &status, arg3));
4267 2f619698 bellard
            if (!is_error(ret) && arg2
4268 1d9d8b55 pbrook
                && put_user_s32(host_to_target_waitstatus(status), arg2))
4269 2f619698 bellard
                goto efault;
4270 31e31b8a bellard
        }
4271 31e31b8a bellard
        break;
4272 e5febef5 ths
#endif
4273 f0cbb613 pbrook
#ifdef TARGET_NR_waitid
4274 f0cbb613 pbrook
    case TARGET_NR_waitid:
4275 f0cbb613 pbrook
        {
4276 f0cbb613 pbrook
            siginfo_t info;
4277 f0cbb613 pbrook
            info.si_pid = 0;
4278 f0cbb613 pbrook
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
4279 f0cbb613 pbrook
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
4280 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4281 f0cbb613 pbrook
                    goto efault;
4282 f0cbb613 pbrook
                host_to_target_siginfo(p, &info);
4283 c227f099 Anthony Liguori
                unlock_user(p, arg3, sizeof(target_siginfo_t));
4284 f0cbb613 pbrook
            }
4285 f0cbb613 pbrook
        }
4286 f0cbb613 pbrook
        break;
4287 f0cbb613 pbrook
#endif
4288 7a3148a9 j_mayer
#ifdef TARGET_NR_creat /* not on alpha */
4289 31e31b8a bellard
    case TARGET_NR_creat:
4290 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4291 579a97f7 bellard
            goto efault;
4292 53a5960a pbrook
        ret = get_errno(creat(p, arg2));
4293 53a5960a pbrook
        unlock_user(p, arg1, 0);
4294 31e31b8a bellard
        break;
4295 7a3148a9 j_mayer
#endif
4296 31e31b8a bellard
    case TARGET_NR_link:
4297 53a5960a pbrook
        {
4298 53a5960a pbrook
            void * p2;
4299 53a5960a pbrook
            p = lock_user_string(arg1);
4300 53a5960a pbrook
            p2 = lock_user_string(arg2);
4301 579a97f7 bellard
            if (!p || !p2)
4302 579a97f7 bellard
                ret = -TARGET_EFAULT;
4303 579a97f7 bellard
            else
4304 579a97f7 bellard
                ret = get_errno(link(p, p2));
4305 53a5960a pbrook
            unlock_user(p2, arg2, 0);
4306 53a5960a pbrook
            unlock_user(p, arg1, 0);
4307 53a5960a pbrook
        }
4308 31e31b8a bellard
        break;
4309 64f0ce4c ths
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4310 64f0ce4c ths
    case TARGET_NR_linkat:
4311 64f0ce4c ths
        {
4312 64f0ce4c ths
            void * p2 = NULL;
4313 579a97f7 bellard
            if (!arg2 || !arg4)
4314 579a97f7 bellard
                goto efault;
4315 64f0ce4c ths
            p  = lock_user_string(arg2);
4316 64f0ce4c ths
            p2 = lock_user_string(arg4);
4317 579a97f7 bellard
            if (!p || !p2)
4318 0da46a6e ths
                ret = -TARGET_EFAULT;
4319 64f0ce4c ths
            else
4320 64f0ce4c ths
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4321 579a97f7 bellard
            unlock_user(p, arg2, 0);
4322 579a97f7 bellard
            unlock_user(p2, arg4, 0);
4323 64f0ce4c ths
        }
4324 64f0ce4c ths
        break;
4325 64f0ce4c ths
#endif
4326 31e31b8a bellard
    case TARGET_NR_unlink:
4327 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4328 579a97f7 bellard
            goto efault;
4329 53a5960a pbrook
        ret = get_errno(unlink(p));
4330 53a5960a pbrook
        unlock_user(p, arg1, 0);
4331 31e31b8a bellard
        break;
4332 8170f56b ths
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4333 8170f56b ths
    case TARGET_NR_unlinkat:
4334 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
4335 579a97f7 bellard
            goto efault;
4336 579a97f7 bellard
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
4337 579a97f7 bellard
        unlock_user(p, arg2, 0);
4338 ed494d87 balrog
        break;
4339 b7d35e65 balrog
#endif
4340 31e31b8a bellard
    case TARGET_NR_execve:
4341 7854b056 bellard
        {
4342 7854b056 bellard
            char **argp, **envp;
4343 f7341ff4 bellard
            int argc, envc;
4344 992f48a0 blueswir1
            abi_ulong gp;
4345 992f48a0 blueswir1
            abi_ulong guest_argp;
4346 992f48a0 blueswir1
            abi_ulong guest_envp;
4347 992f48a0 blueswir1
            abi_ulong addr;
4348 7854b056 bellard
            char **q;
4349 7854b056 bellard
4350 f7341ff4 bellard
            argc = 0;
4351 53a5960a pbrook
            guest_argp = arg2;
4352 da94d263 pbrook
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4353 03aa1976 ths
                if (get_user_ual(addr, gp))
4354 2f619698 bellard
                    goto efault;
4355 03aa1976 ths
                if (!addr)
4356 2f619698 bellard
                    break;
4357 7854b056 bellard
                argc++;
4358 2f619698 bellard
            }
4359 f7341ff4 bellard
            envc = 0;
4360 53a5960a pbrook
            guest_envp = arg3;
4361 da94d263 pbrook
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4362 03aa1976 ths
                if (get_user_ual(addr, gp))
4363 2f619698 bellard
                    goto efault;
4364 03aa1976 ths
                if (!addr)
4365 2f619698 bellard
                    break;
4366 7854b056 bellard
                envc++;
4367 2f619698 bellard
            }
4368 7854b056 bellard
4369 f7341ff4 bellard
            argp = alloca((argc + 1) * sizeof(void *));
4370 f7341ff4 bellard
            envp = alloca((envc + 1) * sizeof(void *));
4371 7854b056 bellard
4372 da94d263 pbrook
            for (gp = guest_argp, q = argp; gp;
4373 992f48a0 blueswir1
                  gp += sizeof(abi_ulong), q++) {
4374 2f619698 bellard
                if (get_user_ual(addr, gp))
4375 2f619698 bellard
                    goto execve_efault;
4376 53a5960a pbrook
                if (!addr)
4377 53a5960a pbrook
                    break;
4378 2f619698 bellard
                if (!(*q = lock_user_string(addr)))
4379 2f619698 bellard
                    goto execve_efault;
4380 53a5960a pbrook
            }
4381 f7341ff4 bellard
            *q = NULL;
4382 f7341ff4 bellard
4383 da94d263 pbrook
            for (gp = guest_envp, q = envp; gp;
4384 992f48a0 blueswir1
                  gp += sizeof(abi_ulong), q++) {
4385 2f619698 bellard
                if (get_user_ual(addr, gp))
4386 2f619698 bellard
                    goto execve_efault;
4387 53a5960a pbrook
                if (!addr)
4388 53a5960a pbrook
                    break;
4389 2f619698 bellard
                if (!(*q = lock_user_string(addr)))
4390 2f619698 bellard
                    goto execve_efault;
4391 53a5960a pbrook
            }
4392 f7341ff4 bellard
            *q = NULL;
4393 7854b056 bellard
4394 2f619698 bellard
            if (!(p = lock_user_string(arg1)))
4395 2f619698 bellard
                goto execve_efault;
4396 53a5960a pbrook
            ret = get_errno(execve(p, argp, envp));
4397 53a5960a pbrook
            unlock_user(p, arg1, 0);
4398 53a5960a pbrook
4399 2f619698 bellard
            goto execve_end;
4400 2f619698 bellard
4401 2f619698 bellard
        execve_efault:
4402 2f619698 bellard
            ret = -TARGET_EFAULT;
4403 2f619698 bellard
4404 2f619698 bellard
        execve_end:
4405 53a5960a pbrook
            for (gp = guest_argp, q = argp; *q;
4406 992f48a0 blueswir1
                  gp += sizeof(abi_ulong), q++) {
4407 2f619698 bellard
                if (get_user_ual(addr, gp)
4408 2f619698 bellard
                    || !addr)
4409 2f619698 bellard
                    break;
4410 53a5960a pbrook
                unlock_user(*q, addr, 0);
4411 53a5960a pbrook
            }
4412 53a5960a pbrook
            for (gp = guest_envp, q = envp; *q;
4413 992f48a0 blueswir1
                  gp += sizeof(abi_ulong), q++) {
4414 2f619698 bellard
                if (get_user_ual(addr, gp)
4415 2f619698 bellard
                    || !addr)
4416 2f619698 bellard
                    break;
4417 53a5960a pbrook
                unlock_user(*q, addr, 0);
4418 53a5960a pbrook
            }
4419 7854b056 bellard
        }
4420 31e31b8a bellard
        break;
4421 31e31b8a bellard
    case TARGET_NR_chdir:
4422 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4423 579a97f7 bellard
            goto efault;
4424 53a5960a pbrook
        ret = get_errno(chdir(p));
4425 53a5960a pbrook
        unlock_user(p, arg1, 0);
4426 31e31b8a bellard
        break;
4427 a315a145 bellard
#ifdef TARGET_NR_time
4428 31e31b8a bellard
    case TARGET_NR_time:
4429 31e31b8a bellard
        {
4430 53a5960a pbrook
            time_t host_time;
4431 53a5960a pbrook
            ret = get_errno(time(&host_time));
4432 2f619698 bellard
            if (!is_error(ret)
4433 2f619698 bellard
                && arg1
4434 2f619698 bellard
                && put_user_sal(host_time, arg1))
4435 2f619698 bellard
                goto efault;
4436 31e31b8a bellard
        }
4437 31e31b8a bellard
        break;
4438 a315a145 bellard
#endif
4439 31e31b8a bellard
    case TARGET_NR_mknod:
4440 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4441 579a97f7 bellard
            goto efault;
4442 53a5960a pbrook
        ret = get_errno(mknod(p, arg2, arg3));
4443 53a5960a pbrook
        unlock_user(p, arg1, 0);
4444 31e31b8a bellard
        break;
4445 75ac37a0 ths
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4446 75ac37a0 ths
    case TARGET_NR_mknodat:
4447 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
4448 579a97f7 bellard
            goto efault;
4449 579a97f7 bellard
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4450 579a97f7 bellard
        unlock_user(p, arg2, 0);
4451 75ac37a0 ths
        break;
4452 75ac37a0 ths
#endif
4453 31e31b8a bellard
    case TARGET_NR_chmod:
4454 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4455 579a97f7 bellard
            goto efault;
4456 53a5960a pbrook
        ret = get_errno(chmod(p, arg2));
4457 53a5960a pbrook
        unlock_user(p, arg1, 0);
4458 31e31b8a bellard
        break;
4459 ebc05488 bellard
#ifdef TARGET_NR_break
4460 31e31b8a bellard
    case TARGET_NR_break:
4461 31e31b8a bellard
        goto unimplemented;
4462 ebc05488 bellard
#endif
4463 ebc05488 bellard
#ifdef TARGET_NR_oldstat
4464 31e31b8a bellard
    case TARGET_NR_oldstat:
4465 31e31b8a bellard
        goto unimplemented;
4466 ebc05488 bellard
#endif
4467 31e31b8a bellard
    case TARGET_NR_lseek:
4468 31e31b8a bellard
        ret = get_errno(lseek(arg1, arg2, arg3));
4469 31e31b8a bellard
        break;
4470 7a3148a9 j_mayer
#ifdef TARGET_NR_getxpid
4471 7a3148a9 j_mayer
    case TARGET_NR_getxpid:
4472 7a3148a9 j_mayer
#else
4473 31e31b8a bellard
    case TARGET_NR_getpid:
4474 7a3148a9 j_mayer
#endif
4475 31e31b8a bellard
        ret = get_errno(getpid());
4476 31e31b8a bellard
        break;
4477 31e31b8a bellard
    case TARGET_NR_mount:
4478 80265918 ths
                {
4479 80265918 ths
                        /* need to look at the data field */
4480 80265918 ths
                        void *p2, *p3;
4481 80265918 ths
                        p = lock_user_string(arg1);
4482 80265918 ths
                        p2 = lock_user_string(arg2);
4483 80265918 ths
                        p3 = lock_user_string(arg3);
4484 579a97f7 bellard
                        if (!p || !p2 || !p3)
4485 579a97f7 bellard
                            ret = -TARGET_EFAULT;
4486 dab46405 Jan-Simon Möller
                        else {
4487 579a97f7 bellard
                            /* FIXME - arg5 should be locked, but it isn't clear how to
4488 579a97f7 bellard
                             * do that since it's not guaranteed to be a NULL-terminated
4489 579a97f7 bellard
                             * string.
4490 579a97f7 bellard
                             */
4491 dab46405 Jan-Simon Möller
                            if ( ! arg5 )
4492 dab46405 Jan-Simon Möller
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
4493 dab46405 Jan-Simon Möller
                            else
4494 dab46405 Jan-Simon Möller
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4495 dab46405 Jan-Simon Möller
                        }
4496 579a97f7 bellard
                        unlock_user(p, arg1, 0);
4497 579a97f7 bellard
                        unlock_user(p2, arg2, 0);
4498 579a97f7 bellard
                        unlock_user(p3, arg3, 0);
4499 80265918 ths
                        break;
4500 80265918 ths
                }
4501 e5febef5 ths
#ifdef TARGET_NR_umount
4502 31e31b8a bellard
    case TARGET_NR_umount:
4503 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4504 579a97f7 bellard
            goto efault;
4505 53a5960a pbrook
        ret = get_errno(umount(p));
4506 53a5960a pbrook
        unlock_user(p, arg1, 0);
4507 31e31b8a bellard
        break;
4508 e5febef5 ths
#endif
4509 7a3148a9 j_mayer
#ifdef TARGET_NR_stime /* not on alpha */
4510 31e31b8a bellard
    case TARGET_NR_stime:
4511 31e31b8a bellard
        {
4512 53a5960a pbrook
            time_t host_time;
4513 2f619698 bellard
            if (get_user_sal(host_time, arg1))
4514 2f619698 bellard
                goto efault;
4515 53a5960a pbrook
            ret = get_errno(stime(&host_time));
4516 31e31b8a bellard
        }
4517 31e31b8a bellard
        break;
4518 7a3148a9 j_mayer
#endif
4519 31e31b8a bellard
    case TARGET_NR_ptrace:
4520 31e31b8a bellard
        goto unimplemented;
4521 7a3148a9 j_mayer
#ifdef TARGET_NR_alarm /* not on alpha */
4522 31e31b8a bellard
    case TARGET_NR_alarm:
4523 31e31b8a bellard
        ret = alarm(arg1);
4524 31e31b8a bellard
        break;
4525 7a3148a9 j_mayer
#endif
4526 ebc05488 bellard
#ifdef TARGET_NR_oldfstat
4527 31e31b8a bellard
    case TARGET_NR_oldfstat:
4528 31e31b8a bellard
        goto unimplemented;
4529 ebc05488 bellard
#endif
4530 7a3148a9 j_mayer
#ifdef TARGET_NR_pause /* not on alpha */
4531 31e31b8a bellard
    case TARGET_NR_pause:
4532 31e31b8a bellard
        ret = get_errno(pause());
4533 31e31b8a bellard
        break;
4534 7a3148a9 j_mayer
#endif
4535 e5febef5 ths
#ifdef TARGET_NR_utime
4536 31e31b8a bellard
    case TARGET_NR_utime:
4537 ebc05488 bellard
        {
4538 53a5960a pbrook
            struct utimbuf tbuf, *host_tbuf;
4539 53a5960a pbrook
            struct target_utimbuf *target_tbuf;
4540 53a5960a pbrook
            if (arg2) {
4541 579a97f7 bellard
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4542 579a97f7 bellard
                    goto efault;
4543 53a5960a pbrook
                tbuf.actime = tswapl(target_tbuf->actime);
4544 53a5960a pbrook
                tbuf.modtime = tswapl(target_tbuf->modtime);
4545 53a5960a pbrook
                unlock_user_struct(target_tbuf, arg2, 0);
4546 53a5960a pbrook
                host_tbuf = &tbuf;
4547 f72e8ff4 bellard
            } else {
4548 53a5960a pbrook
                host_tbuf = NULL;
4549 f72e8ff4 bellard
            }
4550 579a97f7 bellard
            if (!(p = lock_user_string(arg1)))
4551 579a97f7 bellard
                goto efault;
4552 53a5960a pbrook
            ret = get_errno(utime(p, host_tbuf));
4553 53a5960a pbrook
            unlock_user(p, arg1, 0);
4554 ebc05488 bellard
        }
4555 ebc05488 bellard
        break;
4556 e5febef5 ths
#endif
4557 978a66ff bellard
    case TARGET_NR_utimes:
4558 978a66ff bellard
        {
4559 978a66ff bellard
            struct timeval *tvp, tv[2];
4560 53a5960a pbrook
            if (arg2) {
4561 788f5ec4 ths
                if (copy_from_user_timeval(&tv[0], arg2)
4562 788f5ec4 ths
                    || copy_from_user_timeval(&tv[1],
4563 788f5ec4 ths
                                              arg2 + sizeof(struct target_timeval)))
4564 788f5ec4 ths
                    goto efault;
4565 978a66ff bellard
                tvp = tv;
4566 978a66ff bellard
            } else {
4567 978a66ff bellard
                tvp = NULL;
4568 978a66ff bellard
            }
4569 579a97f7 bellard
            if (!(p = lock_user_string(arg1)))
4570 579a97f7 bellard
                goto efault;
4571 53a5960a pbrook
            ret = get_errno(utimes(p, tvp));
4572 53a5960a pbrook
            unlock_user(p, arg1, 0);
4573 978a66ff bellard
        }
4574 978a66ff bellard
        break;
4575 ac8a6556 balrog
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4576 ac8a6556 balrog
    case TARGET_NR_futimesat:
4577 ac8a6556 balrog
        {
4578 ac8a6556 balrog
            struct timeval *tvp, tv[2];
4579 ac8a6556 balrog
            if (arg3) {
4580 ac8a6556 balrog
                if (copy_from_user_timeval(&tv[0], arg3)
4581 ac8a6556 balrog
                    || copy_from_user_timeval(&tv[1],
4582 ac8a6556 balrog
                                              arg3 + sizeof(struct target_timeval)))
4583 ac8a6556 balrog
                    goto efault;
4584 ac8a6556 balrog
                tvp = tv;
4585 ac8a6556 balrog
            } else {
4586 ac8a6556 balrog
                tvp = NULL;
4587 ac8a6556 balrog
            }
4588 ac8a6556 balrog
            if (!(p = lock_user_string(arg2)))
4589 ac8a6556 balrog
                goto efault;
4590 ac8a6556 balrog
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4591 ac8a6556 balrog
            unlock_user(p, arg2, 0);
4592 ac8a6556 balrog
        }
4593 ac8a6556 balrog
        break;
4594 ac8a6556 balrog
#endif
4595 ebc05488 bellard
#ifdef TARGET_NR_stty
4596 31e31b8a bellard
    case TARGET_NR_stty:
4597 31e31b8a bellard
        goto unimplemented;
4598 ebc05488 bellard
#endif
4599 ebc05488 bellard
#ifdef TARGET_NR_gtty
4600 31e31b8a bellard
    case TARGET_NR_gtty:
4601 31e31b8a bellard
        goto unimplemented;
4602 ebc05488 bellard
#endif
4603 31e31b8a bellard
    case TARGET_NR_access:
4604 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4605 579a97f7 bellard
            goto efault;
4606 719f908e Ulrich Hecht
        ret = get_errno(access(path(p), arg2));
4607 53a5960a pbrook
        unlock_user(p, arg1, 0);
4608 31e31b8a bellard
        break;
4609 92a34c10 ths
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4610 92a34c10 ths
    case TARGET_NR_faccessat:
4611 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
4612 579a97f7 bellard
            goto efault;
4613 465c9f06 aurel32
        ret = get_errno(sys_faccessat(arg1, p, arg3));
4614 579a97f7 bellard
        unlock_user(p, arg2, 0);
4615 92a34c10 ths
        break;
4616 92a34c10 ths
#endif
4617 7a3148a9 j_mayer
#ifdef TARGET_NR_nice /* not on alpha */
4618 31e31b8a bellard
    case TARGET_NR_nice:
4619 31e31b8a bellard
        ret = get_errno(nice(arg1));
4620 31e31b8a bellard
        break;
4621 7a3148a9 j_mayer
#endif
4622 ebc05488 bellard
#ifdef TARGET_NR_ftime
4623 31e31b8a bellard
    case TARGET_NR_ftime:
4624 31e31b8a bellard
        goto unimplemented;
4625 ebc05488 bellard
#endif
4626 31e31b8a bellard
    case TARGET_NR_sync:
4627 04369ff2 bellard
        sync();
4628 04369ff2 bellard
        ret = 0;
4629 31e31b8a bellard
        break;
4630 31e31b8a bellard
    case TARGET_NR_kill:
4631 4cb05961 pbrook
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4632 31e31b8a bellard
        break;
4633 31e31b8a bellard
    case TARGET_NR_rename:
4634 53a5960a pbrook
        {
4635 53a5960a pbrook
            void *p2;
4636 53a5960a pbrook
            p = lock_user_string(arg1);
4637 53a5960a pbrook
            p2 = lock_user_string(arg2);
4638 579a97f7 bellard
            if (!p || !p2)
4639 579a97f7 bellard
                ret = -TARGET_EFAULT;
4640 579a97f7 bellard
            else
4641 579a97f7 bellard
                ret = get_errno(rename(p, p2));
4642 53a5960a pbrook
            unlock_user(p2, arg2, 0);
4643 53a5960a pbrook
            unlock_user(p, arg1, 0);
4644 53a5960a pbrook
        }
4645 31e31b8a bellard
        break;
4646 722183f6 ths
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4647 722183f6 ths
    case TARGET_NR_renameat:
4648 722183f6 ths
        {
4649 579a97f7 bellard
            void *p2;
4650 722183f6 ths
            p  = lock_user_string(arg2);
4651 722183f6 ths
            p2 = lock_user_string(arg4);
4652 579a97f7 bellard
            if (!p || !p2)
4653 0da46a6e ths
                ret = -TARGET_EFAULT;
4654 722183f6 ths
            else
4655 722183f6 ths
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4656 579a97f7 bellard
            unlock_user(p2, arg4, 0);
4657 579a97f7 bellard
            unlock_user(p, arg2, 0);
4658 722183f6 ths
        }
4659 722183f6 ths
        break;
4660 722183f6 ths
#endif
4661 31e31b8a bellard
    case TARGET_NR_mkdir:
4662 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4663 579a97f7 bellard
            goto efault;
4664 53a5960a pbrook
        ret = get_errno(mkdir(p, arg2));
4665 53a5960a pbrook
        unlock_user(p, arg1, 0);
4666 31e31b8a bellard
        break;
4667 4472ad0d ths
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4668 4472ad0d ths
    case TARGET_NR_mkdirat:
4669 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
4670 579a97f7 bellard
            goto efault;
4671 579a97f7 bellard
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
4672 579a97f7 bellard
        unlock_user(p, arg2, 0);
4673 4472ad0d ths
        break;
4674 4472ad0d ths
#endif
4675 31e31b8a bellard
    case TARGET_NR_rmdir:
4676 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4677 579a97f7 bellard
            goto efault;
4678 53a5960a pbrook
        ret = get_errno(rmdir(p));
4679 53a5960a pbrook
        unlock_user(p, arg1, 0);
4680 31e31b8a bellard
        break;
4681 31e31b8a bellard
    case TARGET_NR_dup:
4682 31e31b8a bellard
        ret = get_errno(dup(arg1));
4683 31e31b8a bellard
        break;
4684 31e31b8a bellard
    case TARGET_NR_pipe:
4685 099d6b0f Riku Voipio
        ret = do_pipe(cpu_env, arg1, 0);
4686 099d6b0f Riku Voipio
        break;
4687 099d6b0f Riku Voipio
#ifdef TARGET_NR_pipe2
4688 099d6b0f Riku Voipio
    case TARGET_NR_pipe2:
4689 099d6b0f Riku Voipio
        ret = do_pipe(cpu_env, arg1, arg2);
4690 31e31b8a bellard
        break;
4691 099d6b0f Riku Voipio
#endif
4692 31e31b8a bellard
    case TARGET_NR_times:
4693 32f36bce bellard
        {
4694 53a5960a pbrook
            struct target_tms *tmsp;
4695 32f36bce bellard
            struct tms tms;
4696 32f36bce bellard
            ret = get_errno(times(&tms));
4697 53a5960a pbrook
            if (arg1) {
4698 579a97f7 bellard
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4699 579a97f7 bellard
                if (!tmsp)
4700 579a97f7 bellard
                    goto efault;
4701 c596ed17 bellard
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4702 c596ed17 bellard
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4703 c596ed17 bellard
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4704 c596ed17 bellard
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4705 32f36bce bellard
            }
4706 c596ed17 bellard
            if (!is_error(ret))
4707 c596ed17 bellard
                ret = host_to_target_clock_t(ret);
4708 32f36bce bellard
        }
4709 32f36bce bellard
        break;
4710 ebc05488 bellard
#ifdef TARGET_NR_prof
4711 31e31b8a bellard
    case TARGET_NR_prof:
4712 31e31b8a bellard
        goto unimplemented;
4713 ebc05488 bellard
#endif
4714 e5febef5 ths
#ifdef TARGET_NR_signal
4715 31e31b8a bellard
    case TARGET_NR_signal:
4716 31e31b8a bellard
        goto unimplemented;
4717 e5febef5 ths
#endif
4718 31e31b8a bellard
    case TARGET_NR_acct:
4719 38d840e6 aurel32
        if (arg1 == 0) {
4720 38d840e6 aurel32
            ret = get_errno(acct(NULL));
4721 38d840e6 aurel32
        } else {
4722 38d840e6 aurel32
            if (!(p = lock_user_string(arg1)))
4723 38d840e6 aurel32
                goto efault;
4724 38d840e6 aurel32
            ret = get_errno(acct(path(p)));
4725 38d840e6 aurel32
            unlock_user(p, arg1, 0);
4726 38d840e6 aurel32
        }
4727 24836689 pbrook
        break;
4728 7a3148a9 j_mayer
#ifdef TARGET_NR_umount2 /* not on alpha */
4729 31e31b8a bellard
    case TARGET_NR_umount2:
4730 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4731 579a97f7 bellard
            goto efault;
4732 53a5960a pbrook
        ret = get_errno(umount2(p, arg2));
4733 53a5960a pbrook
        unlock_user(p, arg1, 0);
4734 31e31b8a bellard
        break;
4735 7a3148a9 j_mayer
#endif
4736 ebc05488 bellard
#ifdef TARGET_NR_lock
4737 31e31b8a bellard
    case TARGET_NR_lock:
4738 31e31b8a bellard
        goto unimplemented;
4739 ebc05488 bellard
#endif
4740 31e31b8a bellard
    case TARGET_NR_ioctl:
4741 31e31b8a bellard
        ret = do_ioctl(arg1, arg2, arg3);
4742 31e31b8a bellard
        break;
4743 31e31b8a bellard
    case TARGET_NR_fcntl:
4744 9ee1fa2c bellard
        ret = do_fcntl(arg1, arg2, arg3);
4745 31e31b8a bellard
        break;
4746 ebc05488 bellard
#ifdef TARGET_NR_mpx
4747 31e31b8a bellard
    case TARGET_NR_mpx:
4748 31e31b8a bellard
        goto unimplemented;
4749 ebc05488 bellard
#endif
4750 31e31b8a bellard
    case TARGET_NR_setpgid:
4751 31e31b8a bellard
        ret = get_errno(setpgid(arg1, arg2));
4752 31e31b8a bellard
        break;
4753 ebc05488 bellard
#ifdef TARGET_NR_ulimit
4754 31e31b8a bellard
    case TARGET_NR_ulimit:
4755 31e31b8a bellard
        goto unimplemented;
4756 ebc05488 bellard
#endif
4757 ebc05488 bellard
#ifdef TARGET_NR_oldolduname
4758 31e31b8a bellard
    case TARGET_NR_oldolduname:
4759 31e31b8a bellard
        goto unimplemented;
4760 ebc05488 bellard
#endif
4761 31e31b8a bellard
    case TARGET_NR_umask:
4762 31e31b8a bellard
        ret = get_errno(umask(arg1));
4763 31e31b8a bellard
        break;
4764 31e31b8a bellard
    case TARGET_NR_chroot:
4765 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4766 579a97f7 bellard
            goto efault;
4767 53a5960a pbrook
        ret = get_errno(chroot(p));
4768 53a5960a pbrook
        unlock_user(p, arg1, 0);
4769 31e31b8a bellard
        break;
4770 31e31b8a bellard
    case TARGET_NR_ustat:
4771 31e31b8a bellard
        goto unimplemented;
4772 31e31b8a bellard
    case TARGET_NR_dup2:
4773 31e31b8a bellard
        ret = get_errno(dup2(arg1, arg2));
4774 31e31b8a bellard
        break;
4775 d0927938 Ulrich Hecht
#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
4776 d0927938 Ulrich Hecht
    case TARGET_NR_dup3:
4777 d0927938 Ulrich Hecht
        ret = get_errno(dup3(arg1, arg2, arg3));
4778 d0927938 Ulrich Hecht
        break;
4779 d0927938 Ulrich Hecht
#endif
4780 7a3148a9 j_mayer
#ifdef TARGET_NR_getppid /* not on alpha */
4781 31e31b8a bellard
    case TARGET_NR_getppid:
4782 31e31b8a bellard
        ret = get_errno(getppid());
4783 31e31b8a bellard
        break;
4784 7a3148a9 j_mayer
#endif
4785 31e31b8a bellard
    case TARGET_NR_getpgrp:
4786 31e31b8a bellard
        ret = get_errno(getpgrp());
4787 31e31b8a bellard
        break;
4788 31e31b8a bellard
    case TARGET_NR_setsid:
4789 31e31b8a bellard
        ret = get_errno(setsid());
4790 31e31b8a bellard
        break;
4791 e5febef5 ths
#ifdef TARGET_NR_sigaction
4792 31e31b8a bellard
    case TARGET_NR_sigaction:
4793 31e31b8a bellard
        {
4794 6049f4f8 Richard Henderson
#if defined(TARGET_ALPHA)
4795 6049f4f8 Richard Henderson
            struct target_sigaction act, oact, *pact = 0;
4796 53a5960a pbrook
            struct target_old_sigaction *old_act;
4797 53a5960a pbrook
            if (arg2) {
4798 579a97f7 bellard
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4799 579a97f7 bellard
                    goto efault;
4800 66fb9763 bellard
                act._sa_handler = old_act->_sa_handler;
4801 66fb9763 bellard
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4802 66fb9763 bellard
                act.sa_flags = old_act->sa_flags;
4803 6049f4f8 Richard Henderson
                act.sa_restorer = 0;
4804 53a5960a pbrook
                unlock_user_struct(old_act, arg2, 0);
4805 66fb9763 bellard
                pact = &act;
4806 66fb9763 bellard
            }
4807 66fb9763 bellard
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4808 53a5960a pbrook
            if (!is_error(ret) && arg3) {
4809 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4810 579a97f7 bellard
                    goto efault;
4811 53a5960a pbrook
                old_act->_sa_handler = oact._sa_handler;
4812 53a5960a pbrook
                old_act->sa_mask = oact.sa_mask.sig[0];
4813 53a5960a pbrook
                old_act->sa_flags = oact.sa_flags;
4814 53a5960a pbrook
                unlock_user_struct(old_act, arg3, 1);
4815 66fb9763 bellard
            }
4816 6049f4f8 Richard Henderson
#elif defined(TARGET_MIPS)
4817 106ec879 bellard
            struct target_sigaction act, oact, *pact, *old_act;
4818 106ec879 bellard
4819 106ec879 bellard
            if (arg2) {
4820 579a97f7 bellard
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4821 579a97f7 bellard
                    goto efault;
4822 106ec879 bellard
                act._sa_handler = old_act->_sa_handler;
4823 106ec879 bellard
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4824 106ec879 bellard
                act.sa_flags = old_act->sa_flags;
4825 106ec879 bellard
                unlock_user_struct(old_act, arg2, 0);
4826 106ec879 bellard
                pact = &act;
4827 106ec879 bellard
            } else {
4828 106ec879 bellard
                pact = NULL;
4829 106ec879 bellard
            }
4830 106ec879 bellard
4831 106ec879 bellard
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4832 106ec879 bellard
4833 106ec879 bellard
            if (!is_error(ret) && arg3) {
4834 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4835 579a97f7 bellard
                    goto efault;
4836 106ec879 bellard
                old_act->_sa_handler = oact._sa_handler;
4837 106ec879 bellard
                old_act->sa_flags = oact.sa_flags;
4838 106ec879 bellard
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4839 106ec879 bellard
                old_act->sa_mask.sig[1] = 0;
4840 106ec879 bellard
                old_act->sa_mask.sig[2] = 0;
4841 106ec879 bellard
                old_act->sa_mask.sig[3] = 0;
4842 106ec879 bellard
                unlock_user_struct(old_act, arg3, 1);
4843 106ec879 bellard
            }
4844 6049f4f8 Richard Henderson
#else
4845 6049f4f8 Richard Henderson
            struct target_old_sigaction *old_act;
4846 6049f4f8 Richard Henderson
            struct target_sigaction act, oact, *pact;
4847 6049f4f8 Richard Henderson
            if (arg2) {
4848 6049f4f8 Richard Henderson
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4849 6049f4f8 Richard Henderson
                    goto efault;
4850 6049f4f8 Richard Henderson
                act._sa_handler = old_act->_sa_handler;
4851 6049f4f8 Richard Henderson
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4852 6049f4f8 Richard Henderson
                act.sa_flags = old_act->sa_flags;
4853 6049f4f8 Richard Henderson
                act.sa_restorer = old_act->sa_restorer;
4854 6049f4f8 Richard Henderson
                unlock_user_struct(old_act, arg2, 0);
4855 6049f4f8 Richard Henderson
                pact = &act;
4856 6049f4f8 Richard Henderson
            } else {
4857 6049f4f8 Richard Henderson
                pact = NULL;
4858 6049f4f8 Richard Henderson
            }
4859 6049f4f8 Richard Henderson
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4860 6049f4f8 Richard Henderson
            if (!is_error(ret) && arg3) {
4861 6049f4f8 Richard Henderson
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4862 6049f4f8 Richard Henderson
                    goto efault;
4863 6049f4f8 Richard Henderson
                old_act->_sa_handler = oact._sa_handler;
4864 6049f4f8 Richard Henderson
                old_act->sa_mask = oact.sa_mask.sig[0];
4865 6049f4f8 Richard Henderson
                old_act->sa_flags = oact.sa_flags;
4866 6049f4f8 Richard Henderson
                old_act->sa_restorer = oact.sa_restorer;
4867 6049f4f8 Richard Henderson
                unlock_user_struct(old_act, arg3, 1);
4868 6049f4f8 Richard Henderson
            }
4869 388bb21a ths
#endif
4870 31e31b8a bellard
        }
4871 31e31b8a bellard
        break;
4872 e5febef5 ths
#endif
4873 66fb9763 bellard
    case TARGET_NR_rt_sigaction:
4874 53a5960a pbrook
        {
4875 6049f4f8 Richard Henderson
#if defined(TARGET_ALPHA)
4876 6049f4f8 Richard Henderson
            struct target_sigaction act, oact, *pact = 0;
4877 6049f4f8 Richard Henderson
            struct target_rt_sigaction *rt_act;
4878 6049f4f8 Richard Henderson
            /* ??? arg4 == sizeof(sigset_t).  */
4879 6049f4f8 Richard Henderson
            if (arg2) {
4880 6049f4f8 Richard Henderson
                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
4881 6049f4f8 Richard Henderson
                    goto efault;
4882 6049f4f8 Richard Henderson
                act._sa_handler = rt_act->_sa_handler;
4883 6049f4f8 Richard Henderson
                act.sa_mask = rt_act->sa_mask;
4884 6049f4f8 Richard Henderson
                act.sa_flags = rt_act->sa_flags;
4885 6049f4f8 Richard Henderson
                act.sa_restorer = arg5;
4886 6049f4f8 Richard Henderson
                unlock_user_struct(rt_act, arg2, 0);
4887 6049f4f8 Richard Henderson
                pact = &act;
4888 6049f4f8 Richard Henderson
            }
4889 6049f4f8 Richard Henderson
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4890 6049f4f8 Richard Henderson
            if (!is_error(ret) && arg3) {
4891 6049f4f8 Richard Henderson
                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
4892 6049f4f8 Richard Henderson
                    goto efault;
4893 6049f4f8 Richard Henderson
                rt_act->_sa_handler = oact._sa_handler;
4894 6049f4f8 Richard Henderson
                rt_act->sa_mask = oact.sa_mask;
4895 6049f4f8 Richard Henderson
                rt_act->sa_flags = oact.sa_flags;
4896 6049f4f8 Richard Henderson
                unlock_user_struct(rt_act, arg3, 1);
4897 6049f4f8 Richard Henderson
            }
4898 6049f4f8 Richard Henderson
#else
4899 53a5960a pbrook
            struct target_sigaction *act;
4900 53a5960a pbrook
            struct target_sigaction *oact;
4901 53a5960a pbrook
4902 579a97f7 bellard
            if (arg2) {
4903 579a97f7 bellard
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4904 579a97f7 bellard
                    goto efault;
4905 579a97f7 bellard
            } else
4906 53a5960a pbrook
                act = NULL;
4907 579a97f7 bellard
            if (arg3) {
4908 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4909 579a97f7 bellard
                    ret = -TARGET_EFAULT;
4910 579a97f7 bellard
                    goto rt_sigaction_fail;
4911 579a97f7 bellard
                }
4912 579a97f7 bellard
            } else
4913 53a5960a pbrook
                oact = NULL;
4914 53a5960a pbrook
            ret = get_errno(do_sigaction(arg1, act, oact));
4915 579a97f7 bellard
        rt_sigaction_fail:
4916 579a97f7 bellard
            if (act)
4917 53a5960a pbrook
                unlock_user_struct(act, arg2, 0);
4918 579a97f7 bellard
            if (oact)
4919 53a5960a pbrook
                unlock_user_struct(oact, arg3, 1);
4920 6049f4f8 Richard Henderson
#endif
4921 53a5960a pbrook
        }
4922 66fb9763 bellard
        break;
4923 7a3148a9 j_mayer
#ifdef TARGET_NR_sgetmask /* not on alpha */
4924 31e31b8a bellard
    case TARGET_NR_sgetmask:
4925 66fb9763 bellard
        {
4926 66fb9763 bellard
            sigset_t cur_set;
4927 992f48a0 blueswir1
            abi_ulong target_set;
4928 66fb9763 bellard
            sigprocmask(0, NULL, &cur_set);
4929 66fb9763 bellard
            host_to_target_old_sigset(&target_set, &cur_set);
4930 66fb9763 bellard
            ret = target_set;
4931 66fb9763 bellard
        }
4932 66fb9763 bellard
        break;
4933 7a3148a9 j_mayer
#endif
4934 7a3148a9 j_mayer
#ifdef TARGET_NR_ssetmask /* not on alpha */
4935 31e31b8a bellard
    case TARGET_NR_ssetmask:
4936 66fb9763 bellard
        {
4937 66fb9763 bellard
            sigset_t set, oset, cur_set;
4938 992f48a0 blueswir1
            abi_ulong target_set = arg1;
4939 66fb9763 bellard
            sigprocmask(0, NULL, &cur_set);
4940 66fb9763 bellard
            target_to_host_old_sigset(&set, &target_set);
4941 66fb9763 bellard
            sigorset(&set, &set, &cur_set);
4942 66fb9763 bellard
            sigprocmask(SIG_SETMASK, &set, &oset);
4943 66fb9763 bellard
            host_to_target_old_sigset(&target_set, &oset);
4944 66fb9763 bellard
            ret = target_set;
4945 66fb9763 bellard
        }
4946 66fb9763 bellard
        break;
4947 7a3148a9 j_mayer
#endif
4948 e5febef5 ths
#ifdef TARGET_NR_sigprocmask
4949 66fb9763 bellard
    case TARGET_NR_sigprocmask:
4950 66fb9763 bellard
        {
4951 66fb9763 bellard
            int how = arg1;
4952 66fb9763 bellard
            sigset_t set, oldset, *set_ptr;
4953 3b46e624 ths
4954 53a5960a pbrook
            if (arg2) {
4955 66fb9763 bellard
                switch(how) {
4956 66fb9763 bellard
                case TARGET_SIG_BLOCK:
4957 66fb9763 bellard
                    how = SIG_BLOCK;
4958 66fb9763 bellard
                    break;
4959 66fb9763 bellard
                case TARGET_SIG_UNBLOCK:
4960 66fb9763 bellard
                    how = SIG_UNBLOCK;
4961 66fb9763 bellard
                    break;
4962 66fb9763 bellard
                case TARGET_SIG_SETMASK:
4963 66fb9763 bellard
                    how = SIG_SETMASK;
4964 66fb9763 bellard
                    break;
4965 66fb9763 bellard
                default:
4966 0da46a6e ths
                    ret = -TARGET_EINVAL;
4967 66fb9763 bellard
                    goto fail;
4968 66fb9763 bellard
                }
4969 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4970 579a97f7 bellard
                    goto efault;
4971 53a5960a pbrook
                target_to_host_old_sigset(&set, p);
4972 53a5960a pbrook
                unlock_user(p, arg2, 0);
4973 66fb9763 bellard
                set_ptr = &set;
4974 66fb9763 bellard
            } else {
4975 66fb9763 bellard
                how = 0;
4976 66fb9763 bellard
                set_ptr = NULL;
4977 66fb9763 bellard
            }
4978 66fb9763 bellard
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4979 53a5960a pbrook
            if (!is_error(ret) && arg3) {
4980 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4981 579a97f7 bellard
                    goto efault;
4982 53a5960a pbrook
                host_to_target_old_sigset(p, &oldset);
4983 c227f099 Anthony Liguori
                unlock_user(p, arg3, sizeof(target_sigset_t));
4984 66fb9763 bellard
            }
4985 66fb9763 bellard
        }
4986 66fb9763 bellard
        break;
4987 e5febef5 ths
#endif
4988 66fb9763 bellard
    case TARGET_NR_rt_sigprocmask:
4989 66fb9763 bellard
        {
4990 66fb9763 bellard
            int how = arg1;
4991 66fb9763 bellard
            sigset_t set, oldset, *set_ptr;
4992 3b46e624 ths
4993 53a5960a pbrook
            if (arg2) {
4994 66fb9763 bellard
                switch(how) {
4995 66fb9763 bellard
                case TARGET_SIG_BLOCK:
4996 66fb9763 bellard
                    how = SIG_BLOCK;
4997 66fb9763 bellard
                    break;
4998 66fb9763 bellard
                case TARGET_SIG_UNBLOCK:
4999 66fb9763 bellard
                    how = SIG_UNBLOCK;
5000 66fb9763 bellard
                    break;
5001 66fb9763 bellard
                case TARGET_SIG_SETMASK:
5002 66fb9763 bellard
                    how = SIG_SETMASK;
5003 66fb9763 bellard
                    break;
5004 66fb9763 bellard
                default:
5005 0da46a6e ths
                    ret = -TARGET_EINVAL;
5006 66fb9763 bellard
                    goto fail;
5007 66fb9763 bellard
                }
5008 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5009 579a97f7 bellard
                    goto efault;
5010 53a5960a pbrook
                target_to_host_sigset(&set, p);
5011 53a5960a pbrook
                unlock_user(p, arg2, 0);
5012 66fb9763 bellard
                set_ptr = &set;
5013 66fb9763 bellard
            } else {
5014 66fb9763 bellard
                how = 0;
5015 66fb9763 bellard
                set_ptr = NULL;
5016 66fb9763 bellard
            }
5017 66fb9763 bellard
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5018 53a5960a pbrook
            if (!is_error(ret) && arg3) {
5019 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5020 579a97f7 bellard
                    goto efault;
5021 53a5960a pbrook
                host_to_target_sigset(p, &oldset);
5022 c227f099 Anthony Liguori
                unlock_user(p, arg3, sizeof(target_sigset_t));
5023 66fb9763 bellard
            }
5024 66fb9763 bellard
        }
5025 66fb9763 bellard
        break;
5026 e5febef5 ths
#ifdef TARGET_NR_sigpending
5027 66fb9763 bellard
    case TARGET_NR_sigpending:
5028 66fb9763 bellard
        {
5029 66fb9763 bellard
            sigset_t set;
5030 66fb9763 bellard
            ret = get_errno(sigpending(&set));
5031 66fb9763 bellard
            if (!is_error(ret)) {
5032 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5033 579a97f7 bellard
                    goto efault;
5034 53a5960a pbrook
                host_to_target_old_sigset(p, &set);
5035 c227f099 Anthony Liguori
                unlock_user(p, arg1, sizeof(target_sigset_t));
5036 66fb9763 bellard
            }
5037 66fb9763 bellard
        }
5038 66fb9763 bellard
        break;
5039 e5febef5 ths
#endif
5040 66fb9763 bellard
    case TARGET_NR_rt_sigpending:
5041 66fb9763 bellard
        {
5042 66fb9763 bellard
            sigset_t set;
5043 66fb9763 bellard
            ret = get_errno(sigpending(&set));
5044 66fb9763 bellard
            if (!is_error(ret)) {
5045 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5046 579a97f7 bellard
                    goto efault;
5047 53a5960a pbrook
                host_to_target_sigset(p, &set);
5048 c227f099 Anthony Liguori
                unlock_user(p, arg1, sizeof(target_sigset_t));
5049 66fb9763 bellard
            }
5050 66fb9763 bellard
        }
5051 66fb9763 bellard
        break;
5052 e5febef5 ths
#ifdef TARGET_NR_sigsuspend
5053 66fb9763 bellard
    case TARGET_NR_sigsuspend:
5054 66fb9763 bellard
        {
5055 66fb9763 bellard
            sigset_t set;
5056 c227f099 Anthony Liguori
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5057 579a97f7 bellard
                goto efault;
5058 53a5960a pbrook
            target_to_host_old_sigset(&set, p);
5059 53a5960a pbrook
            unlock_user(p, arg1, 0);
5060 66fb9763 bellard
            ret = get_errno(sigsuspend(&set));
5061 66fb9763 bellard
        }
5062 66fb9763 bellard
        break;
5063 e5febef5 ths
#endif
5064 66fb9763 bellard
    case TARGET_NR_rt_sigsuspend:
5065 66fb9763 bellard
        {
5066 66fb9763 bellard
            sigset_t set;
5067 c227f099 Anthony Liguori
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5068 579a97f7 bellard
                goto efault;
5069 53a5960a pbrook
            target_to_host_sigset(&set, p);
5070 53a5960a pbrook
            unlock_user(p, arg1, 0);
5071 66fb9763 bellard
            ret = get_errno(sigsuspend(&set));
5072 66fb9763 bellard
        }
5073 66fb9763 bellard
        break;
5074 66fb9763 bellard
    case TARGET_NR_rt_sigtimedwait:
5075 66fb9763 bellard
        {
5076 66fb9763 bellard
            sigset_t set;
5077 66fb9763 bellard
            struct timespec uts, *puts;
5078 66fb9763 bellard
            siginfo_t uinfo;
5079 3b46e624 ths
5080 c227f099 Anthony Liguori
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5081 579a97f7 bellard
                goto efault;
5082 53a5960a pbrook
            target_to_host_sigset(&set, p);
5083 53a5960a pbrook
            unlock_user(p, arg1, 0);
5084 53a5960a pbrook
            if (arg3) {
5085 66fb9763 bellard
                puts = &uts;
5086 53a5960a pbrook
                target_to_host_timespec(puts, arg3);
5087 66fb9763 bellard
            } else {
5088 66fb9763 bellard
                puts = NULL;
5089 66fb9763 bellard
            }
5090 66fb9763 bellard
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
5091 53a5960a pbrook
            if (!is_error(ret) && arg2) {
5092 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
5093 579a97f7 bellard
                    goto efault;
5094 53a5960a pbrook
                host_to_target_siginfo(p, &uinfo);
5095 c227f099 Anthony Liguori
                unlock_user(p, arg2, sizeof(target_siginfo_t));
5096 66fb9763 bellard
            }
5097 66fb9763 bellard
        }
5098 66fb9763 bellard
        break;
5099 66fb9763 bellard
    case TARGET_NR_rt_sigqueueinfo:
5100 66fb9763 bellard
        {
5101 66fb9763 bellard
            siginfo_t uinfo;
5102 c227f099 Anthony Liguori
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
5103 579a97f7 bellard
                goto efault;
5104 53a5960a pbrook
            target_to_host_siginfo(&uinfo, p);
5105 53a5960a pbrook
            unlock_user(p, arg1, 0);
5106 66fb9763 bellard
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
5107 66fb9763 bellard
        }
5108 66fb9763 bellard
        break;
5109 e5febef5 ths
#ifdef TARGET_NR_sigreturn
5110 66fb9763 bellard
    case TARGET_NR_sigreturn:
5111 66fb9763 bellard
        /* NOTE: ret is eax, so not transcoding must be done */
5112 66fb9763 bellard
        ret = do_sigreturn(cpu_env);
5113 66fb9763 bellard
        break;
5114 e5febef5 ths
#endif
5115 66fb9763 bellard
    case TARGET_NR_rt_sigreturn:
5116 66fb9763 bellard
        /* NOTE: ret is eax, so not transcoding must be done */
5117 66fb9763 bellard
        ret = do_rt_sigreturn(cpu_env);
5118 66fb9763 bellard
        break;
5119 31e31b8a bellard
    case TARGET_NR_sethostname:
5120 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5121 579a97f7 bellard
            goto efault;
5122 53a5960a pbrook
        ret = get_errno(sethostname(p, arg2));
5123 53a5960a pbrook
        unlock_user(p, arg1, 0);
5124 31e31b8a bellard
        break;
5125 31e31b8a bellard
    case TARGET_NR_setrlimit:
5126 9de5e440 bellard
        {
5127 9de5e440 bellard
            /* XXX: convert resource ? */
5128 9de5e440 bellard
            int resource = arg1;
5129 53a5960a pbrook
            struct target_rlimit *target_rlim;
5130 9de5e440 bellard
            struct rlimit rlim;
5131 579a97f7 bellard
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
5132 579a97f7 bellard
                goto efault;
5133 9de5e440 bellard
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
5134 9de5e440 bellard
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
5135 53a5960a pbrook
            unlock_user_struct(target_rlim, arg2, 0);
5136 9de5e440 bellard
            ret = get_errno(setrlimit(resource, &rlim));
5137 9de5e440 bellard
        }
5138 9de5e440 bellard
        break;
5139 31e31b8a bellard
    case TARGET_NR_getrlimit:
5140 9de5e440 bellard
        {
5141 9de5e440 bellard
            /* XXX: convert resource ? */
5142 9de5e440 bellard
            int resource = arg1;
5143 53a5960a pbrook
            struct target_rlimit *target_rlim;
5144 9de5e440 bellard
            struct rlimit rlim;
5145 3b46e624 ths
5146 9de5e440 bellard
            ret = get_errno(getrlimit(resource, &rlim));
5147 9de5e440 bellard
            if (!is_error(ret)) {
5148 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5149 579a97f7 bellard
                    goto efault;
5150 666bcd91 Ulrich Hecht
                target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5151 666bcd91 Ulrich Hecht
                target_rlim->rlim_max = tswapl(rlim.rlim_max);
5152 53a5960a pbrook
                unlock_user_struct(target_rlim, arg2, 1);
5153 9de5e440 bellard
            }
5154 9de5e440 bellard
        }
5155 9de5e440 bellard
        break;
5156 31e31b8a bellard
    case TARGET_NR_getrusage:
5157 b409186b bellard
        {
5158 b409186b bellard
            struct rusage rusage;
5159 b409186b bellard
            ret = get_errno(getrusage(arg1, &rusage));
5160 b409186b bellard
            if (!is_error(ret)) {
5161 53a5960a pbrook
                host_to_target_rusage(arg2, &rusage);
5162 b409186b bellard
            }
5163 b409186b bellard
        }
5164 b409186b bellard
        break;
5165 31e31b8a bellard
    case TARGET_NR_gettimeofday:
5166 31e31b8a bellard
        {
5167 31e31b8a bellard
            struct timeval tv;
5168 31e31b8a bellard
            ret = get_errno(gettimeofday(&tv, NULL));
5169 31e31b8a bellard
            if (!is_error(ret)) {
5170 788f5ec4 ths
                if (copy_to_user_timeval(arg1, &tv))
5171 788f5ec4 ths
                    goto efault;
5172 31e31b8a bellard
            }
5173 31e31b8a bellard
        }
5174 31e31b8a bellard
        break;
5175 31e31b8a bellard
    case TARGET_NR_settimeofday:
5176 31e31b8a bellard
        {
5177 31e31b8a bellard
            struct timeval tv;
5178 788f5ec4 ths
            if (copy_from_user_timeval(&tv, arg1))
5179 788f5ec4 ths
                goto efault;
5180 31e31b8a bellard
            ret = get_errno(settimeofday(&tv, NULL));
5181 31e31b8a bellard
        }
5182 31e31b8a bellard
        break;
5183 048f6b4d bellard
#ifdef TARGET_NR_select
5184 31e31b8a bellard
    case TARGET_NR_select:
5185 f2674e31 bellard
        {
5186 53a5960a pbrook
            struct target_sel_arg_struct *sel;
5187 992f48a0 blueswir1
            abi_ulong inp, outp, exp, tvp;
5188 53a5960a pbrook
            long nsel;
5189 53a5960a pbrook
5190 579a97f7 bellard
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
5191 579a97f7 bellard
                goto efault;
5192 53a5960a pbrook
            nsel = tswapl(sel->n);
5193 53a5960a pbrook
            inp = tswapl(sel->inp);
5194 53a5960a pbrook
            outp = tswapl(sel->outp);
5195 53a5960a pbrook
            exp = tswapl(sel->exp);
5196 53a5960a pbrook
            tvp = tswapl(sel->tvp);
5197 53a5960a pbrook
            unlock_user_struct(sel, arg1, 0);
5198 53a5960a pbrook
            ret = do_select(nsel, inp, outp, exp, tvp);
5199 f2674e31 bellard
        }
5200 f2674e31 bellard
        break;
5201 048f6b4d bellard
#endif
5202 31e31b8a bellard
    case TARGET_NR_symlink:
5203 53a5960a pbrook
        {
5204 53a5960a pbrook
            void *p2;
5205 53a5960a pbrook
            p = lock_user_string(arg1);
5206 53a5960a pbrook
            p2 = lock_user_string(arg2);
5207 579a97f7 bellard
            if (!p || !p2)
5208 579a97f7 bellard
                ret = -TARGET_EFAULT;
5209 579a97f7 bellard
            else
5210 579a97f7 bellard
                ret = get_errno(symlink(p, p2));
5211 53a5960a pbrook
            unlock_user(p2, arg2, 0);
5212 53a5960a pbrook
            unlock_user(p, arg1, 0);
5213 53a5960a pbrook
        }
5214 31e31b8a bellard
        break;
5215 f0b6243d ths
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5216 f0b6243d ths
    case TARGET_NR_symlinkat:
5217 f0b6243d ths
        {
5218 579a97f7 bellard
            void *p2;
5219 f0b6243d ths
            p  = lock_user_string(arg1);
5220 f0b6243d ths
            p2 = lock_user_string(arg3);
5221 579a97f7 bellard
            if (!p || !p2)
5222 0da46a6e ths
                ret = -TARGET_EFAULT;
5223 f0b6243d ths
            else
5224 f0b6243d ths
                ret = get_errno(sys_symlinkat(p, arg2, p2));
5225 579a97f7 bellard
            unlock_user(p2, arg3, 0);
5226 579a97f7 bellard
            unlock_user(p, arg1, 0);
5227 f0b6243d ths
        }
5228 f0b6243d ths
        break;
5229 f0b6243d ths
#endif
5230 ebc05488 bellard
#ifdef TARGET_NR_oldlstat
5231 31e31b8a bellard
    case TARGET_NR_oldlstat:
5232 31e31b8a bellard
        goto unimplemented;
5233 ebc05488 bellard
#endif
5234 31e31b8a bellard
    case TARGET_NR_readlink:
5235 53a5960a pbrook
        {
5236 d088d664 aurel32
            void *p2, *temp;
5237 53a5960a pbrook
            p = lock_user_string(arg1);
5238 579a97f7 bellard
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
5239 579a97f7 bellard
            if (!p || !p2)
5240 579a97f7 bellard
                ret = -TARGET_EFAULT;
5241 d088d664 aurel32
            else {
5242 d088d664 aurel32
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5243 d088d664 aurel32
                    char real[PATH_MAX];
5244 d088d664 aurel32
                    temp = realpath(exec_path,real);
5245 d088d664 aurel32
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5246 d088d664 aurel32
                    snprintf((char *)p2, arg3, "%s", real);
5247 d088d664 aurel32
                    }
5248 d088d664 aurel32
                else
5249 d088d664 aurel32
                    ret = get_errno(readlink(path(p), p2, arg3));
5250 d088d664 aurel32
            }
5251 53a5960a pbrook
            unlock_user(p2, arg2, ret);
5252 53a5960a pbrook
            unlock_user(p, arg1, 0);
5253 53a5960a pbrook
        }
5254 31e31b8a bellard
        break;
5255 5e0ccb18 ths
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5256 5e0ccb18 ths
    case TARGET_NR_readlinkat:
5257 5e0ccb18 ths
        {
5258 579a97f7 bellard
            void *p2;
5259 5e0ccb18 ths
            p  = lock_user_string(arg2);
5260 579a97f7 bellard
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5261 579a97f7 bellard
            if (!p || !p2)
5262 0da46a6e ths
                ret = -TARGET_EFAULT;
5263 5e0ccb18 ths
            else
5264 5e0ccb18 ths
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5265 579a97f7 bellard
            unlock_user(p2, arg3, ret);
5266 579a97f7 bellard
            unlock_user(p, arg2, 0);
5267 5e0ccb18 ths
        }
5268 5e0ccb18 ths
        break;
5269 5e0ccb18 ths
#endif
5270 e5febef5 ths
#ifdef TARGET_NR_uselib
5271 31e31b8a bellard
    case TARGET_NR_uselib:
5272 31e31b8a bellard
        goto unimplemented;
5273 e5febef5 ths
#endif
5274 e5febef5 ths
#ifdef TARGET_NR_swapon
5275 31e31b8a bellard
    case TARGET_NR_swapon:
5276 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5277 579a97f7 bellard
            goto efault;
5278 53a5960a pbrook
        ret = get_errno(swapon(p, arg2));
5279 53a5960a pbrook
        unlock_user(p, arg1, 0);
5280 31e31b8a bellard
        break;
5281 e5febef5 ths
#endif
5282 31e31b8a bellard
    case TARGET_NR_reboot:
5283 31e31b8a bellard
        goto unimplemented;
5284 e5febef5 ths
#ifdef TARGET_NR_readdir
5285 31e31b8a bellard
    case TARGET_NR_readdir:
5286 31e31b8a bellard
        goto unimplemented;
5287 e5febef5 ths
#endif
5288 e5febef5 ths
#ifdef TARGET_NR_mmap
5289 31e31b8a bellard
    case TARGET_NR_mmap:
5290 b779e29e Edgar E. Iglesias
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5291 31e31b8a bellard
        {
5292 992f48a0 blueswir1
            abi_ulong *v;
5293 992f48a0 blueswir1
            abi_ulong v1, v2, v3, v4, v5, v6;
5294 579a97f7 bellard
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5295 579a97f7 bellard
                goto efault;
5296 53a5960a pbrook
            v1 = tswapl(v[0]);
5297 53a5960a pbrook
            v2 = tswapl(v[1]);
5298 53a5960a pbrook
            v3 = tswapl(v[2]);
5299 53a5960a pbrook
            v4 = tswapl(v[3]);
5300 53a5960a pbrook
            v5 = tswapl(v[4]);
5301 53a5960a pbrook
            v6 = tswapl(v[5]);
5302 53a5960a pbrook
            unlock_user(v, arg1, 0);
5303 5fafdf24 ths
            ret = get_errno(target_mmap(v1, v2, v3,
5304 5286db75 bellard
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
5305 5286db75 bellard
                                        v5, v6));
5306 31e31b8a bellard
        }
5307 31e31b8a bellard
#else
5308 5fafdf24 ths
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5309 5fafdf24 ths
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5310 6fb883e8 bellard
                                    arg5,
5311 6fb883e8 bellard
                                    arg6));
5312 31e31b8a bellard
#endif
5313 6fb883e8 bellard
        break;
5314 e5febef5 ths
#endif
5315 a315a145 bellard
#ifdef TARGET_NR_mmap2
5316 6fb883e8 bellard
    case TARGET_NR_mmap2:
5317 bb7ec043 pbrook
#ifndef MMAP_SHIFT
5318 c573ff67 bellard
#define MMAP_SHIFT 12
5319 c573ff67 bellard
#endif
5320 5fafdf24 ths
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5321 5fafdf24 ths
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5322 5286db75 bellard
                                    arg5,
5323 c573ff67 bellard
                                    arg6 << MMAP_SHIFT));
5324 31e31b8a bellard
        break;
5325 a315a145 bellard
#endif
5326 31e31b8a bellard
    case TARGET_NR_munmap:
5327 54936004 bellard
        ret = get_errno(target_munmap(arg1, arg2));
5328 31e31b8a bellard
        break;
5329 9de5e440 bellard
    case TARGET_NR_mprotect:
5330 54936004 bellard
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
5331 9de5e440 bellard
        break;
5332 e5febef5 ths
#ifdef TARGET_NR_mremap
5333 9de5e440 bellard
    case TARGET_NR_mremap:
5334 54936004 bellard
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5335 9de5e440 bellard
        break;
5336 e5febef5 ths
#endif
5337 53a5960a pbrook
        /* ??? msync/mlock/munlock are broken for softmmu.  */
5338 e5febef5 ths
#ifdef TARGET_NR_msync
5339 9de5e440 bellard
    case TARGET_NR_msync:
5340 53a5960a pbrook
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
5341 9de5e440 bellard
        break;
5342 e5febef5 ths
#endif
5343 e5febef5 ths
#ifdef TARGET_NR_mlock
5344 9de5e440 bellard
    case TARGET_NR_mlock:
5345 53a5960a pbrook
        ret = get_errno(mlock(g2h(arg1), arg2));
5346 9de5e440 bellard
        break;
5347 e5febef5 ths
#endif
5348 e5febef5 ths
#ifdef TARGET_NR_munlock
5349 9de5e440 bellard
    case TARGET_NR_munlock:
5350 53a5960a pbrook
        ret = get_errno(munlock(g2h(arg1), arg2));
5351 9de5e440 bellard
        break;
5352 e5febef5 ths
#endif
5353 e5febef5 ths
#ifdef TARGET_NR_mlockall
5354 9de5e440 bellard
    case TARGET_NR_mlockall:
5355 9de5e440 bellard
        ret = get_errno(mlockall(arg1));
5356 9de5e440 bellard
        break;
5357 e5febef5 ths
#endif
5358 e5febef5 ths
#ifdef TARGET_NR_munlockall
5359 9de5e440 bellard
    case TARGET_NR_munlockall:
5360 9de5e440 bellard
        ret = get_errno(munlockall());
5361 9de5e440 bellard
        break;
5362 e5febef5 ths
#endif
5363 31e31b8a bellard
    case TARGET_NR_truncate:
5364 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5365 579a97f7 bellard
            goto efault;
5366 53a5960a pbrook
        ret = get_errno(truncate(p, arg2));
5367 53a5960a pbrook
        unlock_user(p, arg1, 0);
5368 31e31b8a bellard
        break;
5369 31e31b8a bellard
    case TARGET_NR_ftruncate:
5370 31e31b8a bellard
        ret = get_errno(ftruncate(arg1, arg2));
5371 31e31b8a bellard
        break;
5372 31e31b8a bellard
    case TARGET_NR_fchmod:
5373 31e31b8a bellard
        ret = get_errno(fchmod(arg1, arg2));
5374 31e31b8a bellard
        break;
5375 814d7977 ths
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5376 814d7977 ths
    case TARGET_NR_fchmodat:
5377 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
5378 579a97f7 bellard
            goto efault;
5379 465c9f06 aurel32
        ret = get_errno(sys_fchmodat(arg1, p, arg3));
5380 579a97f7 bellard
        unlock_user(p, arg2, 0);
5381 814d7977 ths
        break;
5382 814d7977 ths
#endif
5383 31e31b8a bellard
    case TARGET_NR_getpriority:
5384 c6cda17a ths
        /* libc does special remapping of the return value of
5385 c6cda17a ths
         * sys_getpriority() so it's just easiest to call
5386 c6cda17a ths
         * sys_getpriority() directly rather than through libc. */
5387 69137206 Ulrich Hecht
        ret = get_errno(sys_getpriority(arg1, arg2));
5388 31e31b8a bellard
        break;
5389 31e31b8a bellard
    case TARGET_NR_setpriority:
5390 31e31b8a bellard
        ret = get_errno(setpriority(arg1, arg2, arg3));
5391 31e31b8a bellard
        break;
5392 ebc05488 bellard
#ifdef TARGET_NR_profil
5393 31e31b8a bellard
    case TARGET_NR_profil:
5394 31e31b8a bellard
        goto unimplemented;
5395 ebc05488 bellard
#endif
5396 31e31b8a bellard
    case TARGET_NR_statfs:
5397 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5398 579a97f7 bellard
            goto efault;
5399 53a5960a pbrook
        ret = get_errno(statfs(path(p), &stfs));
5400 53a5960a pbrook
        unlock_user(p, arg1, 0);
5401 31e31b8a bellard
    convert_statfs:
5402 31e31b8a bellard
        if (!is_error(ret)) {
5403 53a5960a pbrook
            struct target_statfs *target_stfs;
5404 3b46e624 ths
5405 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5406 579a97f7 bellard
                goto efault;
5407 579a97f7 bellard
            __put_user(stfs.f_type, &target_stfs->f_type);
5408 579a97f7 bellard
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5409 579a97f7 bellard
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5410 579a97f7 bellard
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5411 579a97f7 bellard
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5412 579a97f7 bellard
            __put_user(stfs.f_files, &target_stfs->f_files);
5413 579a97f7 bellard
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5414 579a97f7 bellard
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5415 579a97f7 bellard
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5416 579a97f7 bellard
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5417 53a5960a pbrook
            unlock_user_struct(target_stfs, arg2, 1);
5418 31e31b8a bellard
        }
5419 31e31b8a bellard
        break;
5420 31e31b8a bellard
    case TARGET_NR_fstatfs:
5421 56c8f68f bellard
        ret = get_errno(fstatfs(arg1, &stfs));
5422 31e31b8a bellard
        goto convert_statfs;
5423 56c8f68f bellard
#ifdef TARGET_NR_statfs64
5424 56c8f68f bellard
    case TARGET_NR_statfs64:
5425 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5426 579a97f7 bellard
            goto efault;
5427 53a5960a pbrook
        ret = get_errno(statfs(path(p), &stfs));
5428 53a5960a pbrook
        unlock_user(p, arg1, 0);
5429 56c8f68f bellard
    convert_statfs64:
5430 56c8f68f bellard
        if (!is_error(ret)) {
5431 53a5960a pbrook
            struct target_statfs64 *target_stfs;
5432 3b46e624 ths
5433 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5434 579a97f7 bellard
                goto efault;
5435 579a97f7 bellard
            __put_user(stfs.f_type, &target_stfs->f_type);
5436 579a97f7 bellard
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5437 579a97f7 bellard
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5438 579a97f7 bellard
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5439 579a97f7 bellard
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5440 579a97f7 bellard
            __put_user(stfs.f_files, &target_stfs->f_files);
5441 579a97f7 bellard
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5442 579a97f7 bellard
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5443 579a97f7 bellard
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5444 579a97f7 bellard
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5445 579a97f7 bellard
            unlock_user_struct(target_stfs, arg3, 1);
5446 56c8f68f bellard
        }
5447 56c8f68f bellard
        break;
5448 56c8f68f bellard
    case TARGET_NR_fstatfs64:
5449 56c8f68f bellard
        ret = get_errno(fstatfs(arg1, &stfs));
5450 56c8f68f bellard
        goto convert_statfs64;
5451 56c8f68f bellard
#endif
5452 ebc05488 bellard
#ifdef TARGET_NR_ioperm
5453 31e31b8a bellard
    case TARGET_NR_ioperm:
5454 31e31b8a bellard
        goto unimplemented;
5455 ebc05488 bellard
#endif
5456 e5febef5 ths
#ifdef TARGET_NR_socketcall
5457 31e31b8a bellard
    case TARGET_NR_socketcall:
5458 53a5960a pbrook
        ret = do_socketcall(arg1, arg2);
5459 31e31b8a bellard
        break;
5460 e5febef5 ths
#endif
5461 3532fa74 bellard
#ifdef TARGET_NR_accept
5462 3532fa74 bellard
    case TARGET_NR_accept:
5463 1be9e1dc pbrook
        ret = do_accept(arg1, arg2, arg3);
5464 3532fa74 bellard
        break;
5465 3532fa74 bellard
#endif
5466 3532fa74 bellard
#ifdef TARGET_NR_bind
5467 3532fa74 bellard
    case TARGET_NR_bind:
5468 3532fa74 bellard
        ret = do_bind(arg1, arg2, arg3);
5469 3532fa74 bellard
        break;
5470 3532fa74 bellard
#endif
5471 3532fa74 bellard
#ifdef TARGET_NR_connect
5472 3532fa74 bellard
    case TARGET_NR_connect:
5473 3532fa74 bellard
        ret = do_connect(arg1, arg2, arg3);
5474 3532fa74 bellard
        break;
5475 3532fa74 bellard
#endif
5476 3532fa74 bellard
#ifdef TARGET_NR_getpeername
5477 3532fa74 bellard
    case TARGET_NR_getpeername:
5478 1be9e1dc pbrook
        ret = do_getpeername(arg1, arg2, arg3);
5479 3532fa74 bellard
        break;
5480 3532fa74 bellard
#endif
5481 3532fa74 bellard
#ifdef TARGET_NR_getsockname
5482 3532fa74 bellard
    case TARGET_NR_getsockname:
5483 1be9e1dc pbrook
        ret = do_getsockname(arg1, arg2, arg3);
5484 3532fa74 bellard
        break;
5485 3532fa74 bellard
#endif
5486 3532fa74 bellard
#ifdef TARGET_NR_getsockopt
5487 3532fa74 bellard
    case TARGET_NR_getsockopt:
5488 3532fa74 bellard
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5489 3532fa74 bellard
        break;
5490 3532fa74 bellard
#endif
5491 3532fa74 bellard
#ifdef TARGET_NR_listen
5492 3532fa74 bellard
    case TARGET_NR_listen:
5493 1be9e1dc pbrook
        ret = get_errno(listen(arg1, arg2));
5494 3532fa74 bellard
        break;
5495 3532fa74 bellard
#endif
5496 3532fa74 bellard
#ifdef TARGET_NR_recv
5497 3532fa74 bellard
    case TARGET_NR_recv:
5498 214201bd pbrook
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5499 3532fa74 bellard
        break;
5500 3532fa74 bellard
#endif
5501 3532fa74 bellard
#ifdef TARGET_NR_recvfrom
5502 3532fa74 bellard
    case TARGET_NR_recvfrom:
5503 214201bd pbrook
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5504 3532fa74 bellard
        break;
5505 3532fa74 bellard
#endif
5506 3532fa74 bellard
#ifdef TARGET_NR_recvmsg
5507 3532fa74 bellard
    case TARGET_NR_recvmsg:
5508 3532fa74 bellard
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5509 3532fa74 bellard
        break;
5510 3532fa74 bellard
#endif
5511 3532fa74 bellard
#ifdef TARGET_NR_send
5512 3532fa74 bellard
    case TARGET_NR_send:
5513 1be9e1dc pbrook
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5514 3532fa74 bellard
        break;
5515 3532fa74 bellard
#endif
5516 3532fa74 bellard
#ifdef TARGET_NR_sendmsg
5517 3532fa74 bellard
    case TARGET_NR_sendmsg:
5518 3532fa74 bellard
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5519 3532fa74 bellard
        break;
5520 3532fa74 bellard
#endif
5521 3532fa74 bellard
#ifdef TARGET_NR_sendto
5522 3532fa74 bellard
    case TARGET_NR_sendto:
5523 1be9e1dc pbrook
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5524 3532fa74 bellard
        break;
5525 3532fa74 bellard
#endif
5526 3532fa74 bellard
#ifdef TARGET_NR_shutdown
5527 3532fa74 bellard
    case TARGET_NR_shutdown:
5528 1be9e1dc pbrook
        ret = get_errno(shutdown(arg1, arg2));
5529 3532fa74 bellard
        break;
5530 3532fa74 bellard
#endif
5531 3532fa74 bellard
#ifdef TARGET_NR_socket
5532 3532fa74 bellard
    case TARGET_NR_socket:
5533 3532fa74 bellard
        ret = do_socket(arg1, arg2, arg3);
5534 3532fa74 bellard
        break;
5535 3532fa74 bellard
#endif
5536 3532fa74 bellard
#ifdef TARGET_NR_socketpair
5537 3532fa74 bellard
    case TARGET_NR_socketpair:
5538 1be9e1dc pbrook
        ret = do_socketpair(arg1, arg2, arg3, arg4);
5539 3532fa74 bellard
        break;
5540 3532fa74 bellard
#endif
5541 3532fa74 bellard
#ifdef TARGET_NR_setsockopt
5542 3532fa74 bellard
    case TARGET_NR_setsockopt:
5543 3532fa74 bellard
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5544 3532fa74 bellard
        break;
5545 3532fa74 bellard
#endif
5546 7494b0f9 ths
5547 31e31b8a bellard
    case TARGET_NR_syslog:
5548 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
5549 579a97f7 bellard
            goto efault;
5550 e5574487 ths
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5551 e5574487 ths
        unlock_user(p, arg2, 0);
5552 7494b0f9 ths
        break;
5553 7494b0f9 ths
5554 31e31b8a bellard
    case TARGET_NR_setitimer:
5555 66fb9763 bellard
        {
5556 66fb9763 bellard
            struct itimerval value, ovalue, *pvalue;
5557 66fb9763 bellard
5558 53a5960a pbrook
            if (arg2) {
5559 66fb9763 bellard
                pvalue = &value;
5560 788f5ec4 ths
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5561 788f5ec4 ths
                    || copy_from_user_timeval(&pvalue->it_value,
5562 788f5ec4 ths
                                              arg2 + sizeof(struct target_timeval)))
5563 788f5ec4 ths
                    goto efault;
5564 66fb9763 bellard
            } else {
5565 66fb9763 bellard
                pvalue = NULL;
5566 66fb9763 bellard
            }
5567 66fb9763 bellard
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5568 53a5960a pbrook
            if (!is_error(ret) && arg3) {
5569 788f5ec4 ths
                if (copy_to_user_timeval(arg3,
5570 788f5ec4 ths
                                         &ovalue.it_interval)
5571 788f5ec4 ths
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5572 788f5ec4 ths
                                            &ovalue.it_value))
5573 788f5ec4 ths
                    goto efault;
5574 66fb9763 bellard
            }
5575 66fb9763 bellard
        }
5576 66fb9763 bellard
        break;
5577 31e31b8a bellard
    case TARGET_NR_getitimer:
5578 66fb9763 bellard
        {
5579 66fb9763 bellard
            struct itimerval value;
5580 3b46e624 ths
5581 66fb9763 bellard
            ret = get_errno(getitimer(arg1, &value));
5582 53a5960a pbrook
            if (!is_error(ret) && arg2) {
5583 788f5ec4 ths
                if (copy_to_user_timeval(arg2,
5584 788f5ec4 ths
                                         &value.it_interval)
5585 788f5ec4 ths
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5586 788f5ec4 ths
                                            &value.it_value))
5587 788f5ec4 ths
                    goto efault;
5588 66fb9763 bellard
            }
5589 66fb9763 bellard
        }
5590 66fb9763 bellard
        break;
5591 31e31b8a bellard
    case TARGET_NR_stat:
5592 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5593 579a97f7 bellard
            goto efault;
5594 53a5960a pbrook
        ret = get_errno(stat(path(p), &st));
5595 53a5960a pbrook
        unlock_user(p, arg1, 0);
5596 31e31b8a bellard
        goto do_stat;
5597 31e31b8a bellard
    case TARGET_NR_lstat:
5598 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5599 579a97f7 bellard
            goto efault;
5600 53a5960a pbrook
        ret = get_errno(lstat(path(p), &st));
5601 53a5960a pbrook
        unlock_user(p, arg1, 0);
5602 31e31b8a bellard
        goto do_stat;
5603 31e31b8a bellard
    case TARGET_NR_fstat:
5604 31e31b8a bellard
        {
5605 31e31b8a bellard
            ret = get_errno(fstat(arg1, &st));
5606 31e31b8a bellard
        do_stat:
5607 31e31b8a bellard
            if (!is_error(ret)) {
5608 53a5960a pbrook
                struct target_stat *target_st;
5609 e3584658 ths
5610 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5611 579a97f7 bellard
                    goto efault;
5612 12727917 Ulrich Hecht
                memset(target_st, 0, sizeof(*target_st));
5613 d2fd1af7 bellard
                __put_user(st.st_dev, &target_st->st_dev);
5614 d2fd1af7 bellard
                __put_user(st.st_ino, &target_st->st_ino);
5615 d2fd1af7 bellard
                __put_user(st.st_mode, &target_st->st_mode);
5616 d2fd1af7 bellard
                __put_user(st.st_uid, &target_st->st_uid);
5617 d2fd1af7 bellard
                __put_user(st.st_gid, &target_st->st_gid);
5618 d2fd1af7 bellard
                __put_user(st.st_nlink, &target_st->st_nlink);
5619 d2fd1af7 bellard
                __put_user(st.st_rdev, &target_st->st_rdev);
5620 d2fd1af7 bellard
                __put_user(st.st_size, &target_st->st_size);
5621 d2fd1af7 bellard
                __put_user(st.st_blksize, &target_st->st_blksize);
5622 d2fd1af7 bellard
                __put_user(st.st_blocks, &target_st->st_blocks);
5623 d2fd1af7 bellard
                __put_user(st.st_atime, &target_st->target_st_atime);
5624 d2fd1af7 bellard
                __put_user(st.st_mtime, &target_st->target_st_mtime);
5625 d2fd1af7 bellard
                __put_user(st.st_ctime, &target_st->target_st_ctime);
5626 53a5960a pbrook
                unlock_user_struct(target_st, arg2, 1);
5627 31e31b8a bellard
            }
5628 31e31b8a bellard
        }
5629 31e31b8a bellard
        break;
5630 ebc05488 bellard
#ifdef TARGET_NR_olduname
5631 31e31b8a bellard
    case TARGET_NR_olduname:
5632 31e31b8a bellard
        goto unimplemented;
5633 ebc05488 bellard
#endif
5634 ebc05488 bellard
#ifdef TARGET_NR_iopl
5635 31e31b8a bellard
    case TARGET_NR_iopl:
5636 31e31b8a bellard
        goto unimplemented;
5637 ebc05488 bellard
#endif
5638 31e31b8a bellard
    case TARGET_NR_vhangup:
5639 31e31b8a bellard
        ret = get_errno(vhangup());
5640 31e31b8a bellard
        break;
5641 ebc05488 bellard
#ifdef TARGET_NR_idle
5642 31e31b8a bellard
    case TARGET_NR_idle:
5643 31e31b8a bellard
        goto unimplemented;
5644 ebc05488 bellard
#endif
5645 42ad6ae9 bellard
#ifdef TARGET_NR_syscall
5646 42ad6ae9 bellard
    case TARGET_NR_syscall:
5647 42ad6ae9 bellard
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5648 42ad6ae9 bellard
            break;
5649 42ad6ae9 bellard
#endif
5650 31e31b8a bellard
    case TARGET_NR_wait4:
5651 31e31b8a bellard
        {
5652 31e31b8a bellard
            int status;
5653 992f48a0 blueswir1
            abi_long status_ptr = arg2;
5654 31e31b8a bellard
            struct rusage rusage, *rusage_ptr;
5655 992f48a0 blueswir1
            abi_ulong target_rusage = arg4;
5656 31e31b8a bellard
            if (target_rusage)
5657 31e31b8a bellard
                rusage_ptr = &rusage;
5658 31e31b8a bellard
            else
5659 31e31b8a bellard
                rusage_ptr = NULL;
5660 31e31b8a bellard
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5661 31e31b8a bellard
            if (!is_error(ret)) {
5662 2f619698 bellard
                if (status_ptr) {
5663 1d9d8b55 pbrook
                    status = host_to_target_waitstatus(status);
5664 2f619698 bellard
                    if (put_user_s32(status, status_ptr))
5665 2f619698 bellard
                        goto efault;
5666 31e31b8a bellard
                }
5667 2f619698 bellard
                if (target_rusage)
5668 2f619698 bellard
                    host_to_target_rusage(target_rusage, &rusage);
5669 31e31b8a bellard
            }
5670 31e31b8a bellard
        }
5671 31e31b8a bellard
        break;
5672 e5febef5 ths
#ifdef TARGET_NR_swapoff
5673 31e31b8a bellard
    case TARGET_NR_swapoff:
5674 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5675 579a97f7 bellard
            goto efault;
5676 53a5960a pbrook
        ret = get_errno(swapoff(p));
5677 53a5960a pbrook
        unlock_user(p, arg1, 0);
5678 31e31b8a bellard
        break;
5679 e5febef5 ths
#endif
5680 31e31b8a bellard
    case TARGET_NR_sysinfo:
5681 a5448a7d bellard
        {
5682 53a5960a pbrook
            struct target_sysinfo *target_value;
5683 a5448a7d bellard
            struct sysinfo value;
5684 a5448a7d bellard
            ret = get_errno(sysinfo(&value));
5685 53a5960a pbrook
            if (!is_error(ret) && arg1)
5686 a5448a7d bellard
            {
5687 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5688 579a97f7 bellard
                    goto efault;
5689 a5448a7d bellard
                __put_user(value.uptime, &target_value->uptime);
5690 a5448a7d bellard
                __put_user(value.loads[0], &target_value->loads[0]);
5691 a5448a7d bellard
                __put_user(value.loads[1], &target_value->loads[1]);
5692 a5448a7d bellard
                __put_user(value.loads[2], &target_value->loads[2]);
5693 a5448a7d bellard
                __put_user(value.totalram, &target_value->totalram);
5694 a5448a7d bellard
                __put_user(value.freeram, &target_value->freeram);
5695 a5448a7d bellard
                __put_user(value.sharedram, &target_value->sharedram);
5696 a5448a7d bellard
                __put_user(value.bufferram, &target_value->bufferram);
5697 a5448a7d bellard
                __put_user(value.totalswap, &target_value->totalswap);
5698 a5448a7d bellard
                __put_user(value.freeswap, &target_value->freeswap);
5699 a5448a7d bellard
                __put_user(value.procs, &target_value->procs);
5700 a5448a7d bellard
                __put_user(value.totalhigh, &target_value->totalhigh);
5701 a5448a7d bellard
                __put_user(value.freehigh, &target_value->freehigh);
5702 a5448a7d bellard
                __put_user(value.mem_unit, &target_value->mem_unit);
5703 53a5960a pbrook
                unlock_user_struct(target_value, arg1, 1);
5704 a5448a7d bellard
            }
5705 a5448a7d bellard
        }
5706 a5448a7d bellard
        break;
5707 e5febef5 ths
#ifdef TARGET_NR_ipc
5708 31e31b8a bellard
    case TARGET_NR_ipc:
5709 8853f86e bellard
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5710 8853f86e bellard
        break;
5711 e5febef5 ths
#endif
5712 e5289087 aurel32
#ifdef TARGET_NR_semget
5713 e5289087 aurel32
    case TARGET_NR_semget:
5714 e5289087 aurel32
        ret = get_errno(semget(arg1, arg2, arg3));
5715 e5289087 aurel32
        break;
5716 e5289087 aurel32
#endif
5717 e5289087 aurel32
#ifdef TARGET_NR_semop
5718 e5289087 aurel32
    case TARGET_NR_semop:
5719 e5289087 aurel32
        ret = get_errno(do_semop(arg1, arg2, arg3));
5720 e5289087 aurel32
        break;
5721 e5289087 aurel32
#endif
5722 e5289087 aurel32
#ifdef TARGET_NR_semctl
5723 e5289087 aurel32
    case TARGET_NR_semctl:
5724 e5289087 aurel32
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5725 e5289087 aurel32
        break;
5726 e5289087 aurel32
#endif
5727 eeb438c1 aurel32
#ifdef TARGET_NR_msgctl
5728 eeb438c1 aurel32
    case TARGET_NR_msgctl:
5729 eeb438c1 aurel32
        ret = do_msgctl(arg1, arg2, arg3);
5730 eeb438c1 aurel32
        break;
5731 eeb438c1 aurel32
#endif
5732 eeb438c1 aurel32
#ifdef TARGET_NR_msgget
5733 eeb438c1 aurel32
    case TARGET_NR_msgget:
5734 eeb438c1 aurel32
        ret = get_errno(msgget(arg1, arg2));
5735 eeb438c1 aurel32
        break;
5736 eeb438c1 aurel32
#endif
5737 eeb438c1 aurel32
#ifdef TARGET_NR_msgrcv
5738 eeb438c1 aurel32
    case TARGET_NR_msgrcv:
5739 eeb438c1 aurel32
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5740 eeb438c1 aurel32
        break;
5741 eeb438c1 aurel32
#endif
5742 eeb438c1 aurel32
#ifdef TARGET_NR_msgsnd
5743 eeb438c1 aurel32
    case TARGET_NR_msgsnd:
5744 eeb438c1 aurel32
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
5745 eeb438c1 aurel32
        break;
5746 eeb438c1 aurel32
#endif
5747 88a8c984 Riku Voipio
#ifdef TARGET_NR_shmget
5748 88a8c984 Riku Voipio
    case TARGET_NR_shmget:
5749 88a8c984 Riku Voipio
        ret = get_errno(shmget(arg1, arg2, arg3));
5750 88a8c984 Riku Voipio
        break;
5751 88a8c984 Riku Voipio
#endif
5752 88a8c984 Riku Voipio
#ifdef TARGET_NR_shmctl
5753 88a8c984 Riku Voipio
    case TARGET_NR_shmctl:
5754 88a8c984 Riku Voipio
        ret = do_shmctl(arg1, arg2, arg3);
5755 88a8c984 Riku Voipio
        break;
5756 88a8c984 Riku Voipio
#endif
5757 88a8c984 Riku Voipio
#ifdef TARGET_NR_shmat
5758 88a8c984 Riku Voipio
    case TARGET_NR_shmat:
5759 88a8c984 Riku Voipio
        ret = do_shmat(arg1, arg2, arg3);
5760 88a8c984 Riku Voipio
        break;
5761 88a8c984 Riku Voipio
#endif
5762 88a8c984 Riku Voipio
#ifdef TARGET_NR_shmdt
5763 88a8c984 Riku Voipio
    case TARGET_NR_shmdt:
5764 88a8c984 Riku Voipio
        ret = do_shmdt(arg1);
5765 88a8c984 Riku Voipio
        break;
5766 88a8c984 Riku Voipio
#endif
5767 31e31b8a bellard
    case TARGET_NR_fsync:
5768 31e31b8a bellard
        ret = get_errno(fsync(arg1));
5769 31e31b8a bellard
        break;
5770 31e31b8a bellard
    case TARGET_NR_clone:
5771 0b6d3ae0 aurel32
#if defined(TARGET_SH4)
5772 0b6d3ae0 aurel32
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5773 b15ad61c edgar_igl
#elif defined(TARGET_CRIS)
5774 b15ad61c edgar_igl
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5775 0b6d3ae0 aurel32
#else
5776 d865bab5 pbrook
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5777 0b6d3ae0 aurel32
#endif
5778 1b6b029e bellard
        break;
5779 ec86b0fb bellard
#ifdef __NR_exit_group
5780 ec86b0fb bellard
        /* new thread calls */
5781 ec86b0fb bellard
    case TARGET_NR_exit_group:
5782 9788c9ca Juan Quintela
#ifdef TARGET_GPROF
5783 6d946cda aurel32
        _mcleanup();
5784 6d946cda aurel32
#endif
5785 e9009676 bellard
        gdb_exit(cpu_env, arg1);
5786 ec86b0fb bellard
        ret = get_errno(exit_group(arg1));
5787 ec86b0fb bellard
        break;
5788 ec86b0fb bellard
#endif
5789 31e31b8a bellard
    case TARGET_NR_setdomainname:
5790 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5791 579a97f7 bellard
            goto efault;
5792 53a5960a pbrook
        ret = get_errno(setdomainname(p, arg2));
5793 53a5960a pbrook
        unlock_user(p, arg1, 0);
5794 31e31b8a bellard
        break;
5795 31e31b8a bellard
    case TARGET_NR_uname:
5796 31e31b8a bellard
        /* no need to transcode because we use the linux syscall */
5797 29e619b1 bellard
        {
5798 29e619b1 bellard
            struct new_utsname * buf;
5799 3b46e624 ths
5800 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5801 579a97f7 bellard
                goto efault;
5802 29e619b1 bellard
            ret = get_errno(sys_uname(buf));
5803 29e619b1 bellard
            if (!is_error(ret)) {
5804 29e619b1 bellard
                /* Overrite the native machine name with whatever is being
5805 29e619b1 bellard
                   emulated. */
5806 da79030f Loïc Minier
                strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
5807 c5937220 pbrook
                /* Allow the user to override the reported release.  */
5808 c5937220 pbrook
                if (qemu_uname_release && *qemu_uname_release)
5809 c5937220 pbrook
                  strcpy (buf->release, qemu_uname_release);
5810 29e619b1 bellard
            }
5811 53a5960a pbrook
            unlock_user_struct(buf, arg1, 1);
5812 29e619b1 bellard
        }
5813 31e31b8a bellard
        break;
5814 6dbad63e bellard
#ifdef TARGET_I386
5815 31e31b8a bellard
    case TARGET_NR_modify_ldt:
5816 03acab66 bellard
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5817 5cd4393b bellard
        break;
5818 84409ddb j_mayer
#if !defined(TARGET_X86_64)
5819 5cd4393b bellard
    case TARGET_NR_vm86old:
5820 5cd4393b bellard
        goto unimplemented;
5821 5cd4393b bellard
    case TARGET_NR_vm86:
5822 53a5960a pbrook
        ret = do_vm86(cpu_env, arg1, arg2);
5823 6dbad63e bellard
        break;
5824 6dbad63e bellard
#endif
5825 84409ddb j_mayer
#endif
5826 31e31b8a bellard
    case TARGET_NR_adjtimex:
5827 31e31b8a bellard
        goto unimplemented;
5828 e5febef5 ths
#ifdef TARGET_NR_create_module
5829 31e31b8a bellard
    case TARGET_NR_create_module:
5830 e5febef5 ths
#endif
5831 31e31b8a bellard
    case TARGET_NR_init_module:
5832 31e31b8a bellard
    case TARGET_NR_delete_module:
5833 e5febef5 ths
#ifdef TARGET_NR_get_kernel_syms
5834 31e31b8a bellard
    case TARGET_NR_get_kernel_syms:
5835 e5febef5 ths
#endif
5836 31e31b8a bellard
        goto unimplemented;
5837 31e31b8a bellard
    case TARGET_NR_quotactl:
5838 31e31b8a bellard
        goto unimplemented;
5839 31e31b8a bellard
    case TARGET_NR_getpgid:
5840 31e31b8a bellard
        ret = get_errno(getpgid(arg1));
5841 31e31b8a bellard
        break;
5842 31e31b8a bellard
    case TARGET_NR_fchdir:
5843 31e31b8a bellard
        ret = get_errno(fchdir(arg1));
5844 31e31b8a bellard
        break;
5845 84409ddb j_mayer
#ifdef TARGET_NR_bdflush /* not on x86_64 */
5846 31e31b8a bellard
    case TARGET_NR_bdflush:
5847 31e31b8a bellard
        goto unimplemented;
5848 84409ddb j_mayer
#endif
5849 e5febef5 ths
#ifdef TARGET_NR_sysfs
5850 31e31b8a bellard
    case TARGET_NR_sysfs:
5851 31e31b8a bellard
        goto unimplemented;
5852 e5febef5 ths
#endif
5853 31e31b8a bellard
    case TARGET_NR_personality:
5854 1b6b029e bellard
        ret = get_errno(personality(arg1));
5855 31e31b8a bellard
        break;
5856 e5febef5 ths
#ifdef TARGET_NR_afs_syscall
5857 31e31b8a bellard
    case TARGET_NR_afs_syscall:
5858 31e31b8a bellard
        goto unimplemented;
5859 e5febef5 ths
#endif
5860 7a3148a9 j_mayer
#ifdef TARGET_NR__llseek /* Not on alpha */
5861 31e31b8a bellard
    case TARGET_NR__llseek:
5862 31e31b8a bellard
        {
5863 4f2ac237 bellard
#if defined (__x86_64__)
5864 4f2ac237 bellard
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5865 2f619698 bellard
            if (put_user_s64(ret, arg4))
5866 2f619698 bellard
                goto efault;
5867 4f2ac237 bellard
#else
5868 31e31b8a bellard
            int64_t res;
5869 31e31b8a bellard
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5870 2f619698 bellard
            if (put_user_s64(res, arg4))
5871 2f619698 bellard
                goto efault;
5872 4f2ac237 bellard
#endif
5873 31e31b8a bellard
        }
5874 31e31b8a bellard
        break;
5875 7a3148a9 j_mayer
#endif
5876 31e31b8a bellard
    case TARGET_NR_getdents:
5877 d83c8733 Ulrich Hecht
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5878 4add45b4 bellard
        {
5879 53a5960a pbrook
            struct target_dirent *target_dirp;
5880 6556a833 aurel32
            struct linux_dirent *dirp;
5881 992f48a0 blueswir1
            abi_long count = arg3;
5882 4add45b4 bellard
5883 4add45b4 bellard
            dirp = malloc(count);
5884 0da46a6e ths
            if (!dirp) {
5885 579a97f7 bellard
                ret = -TARGET_ENOMEM;
5886 0da46a6e ths
                goto fail;
5887 0da46a6e ths
            }
5888 3b46e624 ths
5889 4add45b4 bellard
            ret = get_errno(sys_getdents(arg1, dirp, count));
5890 4add45b4 bellard
            if (!is_error(ret)) {
5891 6556a833 aurel32
                struct linux_dirent *de;
5892 4add45b4 bellard
                struct target_dirent *tde;
5893 4add45b4 bellard
                int len = ret;
5894 4add45b4 bellard
                int reclen, treclen;
5895 4add45b4 bellard
                int count1, tnamelen;
5896 4add45b4 bellard
5897 4add45b4 bellard
                count1 = 0;
5898 4add45b4 bellard
                de = dirp;
5899 579a97f7 bellard
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5900 579a97f7 bellard
                    goto efault;
5901 4add45b4 bellard
                tde = target_dirp;
5902 4add45b4 bellard
                while (len > 0) {
5903 4add45b4 bellard
                    reclen = de->d_reclen;
5904 992f48a0 blueswir1
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5905 4add45b4 bellard
                    tde->d_reclen = tswap16(treclen);
5906 4add45b4 bellard
                    tde->d_ino = tswapl(de->d_ino);
5907 4add45b4 bellard
                    tde->d_off = tswapl(de->d_off);
5908 992f48a0 blueswir1
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5909 4add45b4 bellard
                    if (tnamelen > 256)
5910 4add45b4 bellard
                        tnamelen = 256;
5911 80a9d035 bellard
                    /* XXX: may not be correct */
5912 be15b141 blueswir1
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5913 6556a833 aurel32
                    de = (struct linux_dirent *)((char *)de + reclen);
5914 4add45b4 bellard
                    len -= reclen;
5915 1c5bf3bf j_mayer
                    tde = (struct target_dirent *)((char *)tde + treclen);
5916 4add45b4 bellard
                    count1 += treclen;
5917 4add45b4 bellard
                }
5918 4add45b4 bellard
                ret = count1;
5919 579a97f7 bellard
                unlock_user(target_dirp, arg2, ret);
5920 4add45b4 bellard
            }
5921 4add45b4 bellard
            free(dirp);
5922 4add45b4 bellard
        }
5923 4add45b4 bellard
#else
5924 31e31b8a bellard
        {
5925 6556a833 aurel32
            struct linux_dirent *dirp;
5926 992f48a0 blueswir1
            abi_long count = arg3;
5927 dab2ed99 bellard
5928 579a97f7 bellard
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5929 579a97f7 bellard
                goto efault;
5930 72f03900 bellard
            ret = get_errno(sys_getdents(arg1, dirp, count));
5931 31e31b8a bellard
            if (!is_error(ret)) {
5932 6556a833 aurel32
                struct linux_dirent *de;
5933 31e31b8a bellard
                int len = ret;
5934 31e31b8a bellard
                int reclen;
5935 31e31b8a bellard
                de = dirp;
5936 31e31b8a bellard
                while (len > 0) {
5937 8083a3e5 bellard
                    reclen = de->d_reclen;
5938 31e31b8a bellard
                    if (reclen > len)
5939 31e31b8a bellard
                        break;
5940 8083a3e5 bellard
                    de->d_reclen = tswap16(reclen);
5941 31e31b8a bellard
                    tswapls(&de->d_ino);
5942 31e31b8a bellard
                    tswapls(&de->d_off);
5943 6556a833 aurel32
                    de = (struct linux_dirent *)((char *)de + reclen);
5944 31e31b8a bellard
                    len -= reclen;
5945 31e31b8a bellard
                }
5946 31e31b8a bellard
            }
5947 53a5960a pbrook
            unlock_user(dirp, arg2, ret);
5948 31e31b8a bellard
        }
5949 4add45b4 bellard
#endif
5950 31e31b8a bellard
        break;
5951 3ae43202 ths
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5952 dab2ed99 bellard
    case TARGET_NR_getdents64:
5953 dab2ed99 bellard
        {
5954 6556a833 aurel32
            struct linux_dirent64 *dirp;
5955 992f48a0 blueswir1
            abi_long count = arg3;
5956 579a97f7 bellard
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5957 579a97f7 bellard
                goto efault;
5958 dab2ed99 bellard
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5959 dab2ed99 bellard
            if (!is_error(ret)) {
5960 6556a833 aurel32
                struct linux_dirent64 *de;
5961 dab2ed99 bellard
                int len = ret;
5962 dab2ed99 bellard
                int reclen;
5963 dab2ed99 bellard
                de = dirp;
5964 dab2ed99 bellard
                while (len > 0) {
5965 8083a3e5 bellard
                    reclen = de->d_reclen;
5966 dab2ed99 bellard
                    if (reclen > len)
5967 dab2ed99 bellard
                        break;
5968 8083a3e5 bellard
                    de->d_reclen = tswap16(reclen);
5969 8582a53a bellard
                    tswap64s((uint64_t *)&de->d_ino);
5970 8582a53a bellard
                    tswap64s((uint64_t *)&de->d_off);
5971 6556a833 aurel32
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5972 dab2ed99 bellard
                    len -= reclen;
5973 dab2ed99 bellard
                }
5974 dab2ed99 bellard
            }
5975 53a5960a pbrook
            unlock_user(dirp, arg2, ret);
5976 dab2ed99 bellard
        }
5977 dab2ed99 bellard
        break;
5978 a541f297 bellard
#endif /* TARGET_NR_getdents64 */
5979 e5febef5 ths
#ifdef TARGET_NR__newselect
5980 31e31b8a bellard
    case TARGET_NR__newselect:
5981 53a5960a pbrook
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5982 31e31b8a bellard
        break;
5983 e5febef5 ths
#endif
5984 e5febef5 ths
#ifdef TARGET_NR_poll
5985 9de5e440 bellard
    case TARGET_NR_poll:
5986 9de5e440 bellard
        {
5987 53a5960a pbrook
            struct target_pollfd *target_pfd;
5988 9de5e440 bellard
            unsigned int nfds = arg2;
5989 9de5e440 bellard
            int timeout = arg3;
5990 9de5e440 bellard
            struct pollfd *pfd;
5991 7854b056 bellard
            unsigned int i;
5992 9de5e440 bellard
5993 579a97f7 bellard
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5994 579a97f7 bellard
            if (!target_pfd)
5995 579a97f7 bellard
                goto efault;
5996 9de5e440 bellard
            pfd = alloca(sizeof(struct pollfd) * nfds);
5997 9de5e440 bellard
            for(i = 0; i < nfds; i++) {
5998 5cd4393b bellard
                pfd[i].fd = tswap32(target_pfd[i].fd);
5999 5cd4393b bellard
                pfd[i].events = tswap16(target_pfd[i].events);
6000 9de5e440 bellard
            }
6001 9de5e440 bellard
            ret = get_errno(poll(pfd, nfds, timeout));
6002 9de5e440 bellard
            if (!is_error(ret)) {
6003 9de5e440 bellard
                for(i = 0; i < nfds; i++) {
6004 5cd4393b bellard
                    target_pfd[i].revents = tswap16(pfd[i].revents);
6005 9de5e440 bellard
                }
6006 53a5960a pbrook
                ret += nfds * (sizeof(struct target_pollfd)
6007 53a5960a pbrook
                               - sizeof(struct pollfd));
6008 9de5e440 bellard
            }
6009 53a5960a pbrook
            unlock_user(target_pfd, arg1, ret);
6010 9de5e440 bellard
        }
6011 9de5e440 bellard
        break;
6012 e5febef5 ths
#endif
6013 31e31b8a bellard
    case TARGET_NR_flock:
6014 9de5e440 bellard
        /* NOTE: the flock constant seems to be the same for every
6015 9de5e440 bellard
           Linux platform */
6016 9de5e440 bellard
        ret = get_errno(flock(arg1, arg2));
6017 31e31b8a bellard
        break;
6018 31e31b8a bellard
    case TARGET_NR_readv:
6019 31e31b8a bellard
        {
6020 31e31b8a bellard
            int count = arg3;
6021 31e31b8a bellard
            struct iovec *vec;
6022 31e31b8a bellard
6023 31e31b8a bellard
            vec = alloca(count * sizeof(struct iovec));
6024 41df8411 bellard
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
6025 41df8411 bellard
                goto efault;
6026 31e31b8a bellard
            ret = get_errno(readv(arg1, vec, count));
6027 53a5960a pbrook
            unlock_iovec(vec, arg2, count, 1);
6028 31e31b8a bellard
        }
6029 31e31b8a bellard
        break;
6030 31e31b8a bellard
    case TARGET_NR_writev:
6031 31e31b8a bellard
        {
6032 31e31b8a bellard
            int count = arg3;
6033 31e31b8a bellard
            struct iovec *vec;
6034 31e31b8a bellard
6035 31e31b8a bellard
            vec = alloca(count * sizeof(struct iovec));
6036 41df8411 bellard
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
6037 41df8411 bellard
                goto efault;
6038 31e31b8a bellard
            ret = get_errno(writev(arg1, vec, count));
6039 53a5960a pbrook
            unlock_iovec(vec, arg2, count, 0);
6040 31e31b8a bellard
        }
6041 31e31b8a bellard
        break;
6042 31e31b8a bellard
    case TARGET_NR_getsid:
6043 31e31b8a bellard
        ret = get_errno(getsid(arg1));
6044 31e31b8a bellard
        break;
6045 7a3148a9 j_mayer
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
6046 31e31b8a bellard
    case TARGET_NR_fdatasync:
6047 5cd4393b bellard
        ret = get_errno(fdatasync(arg1));
6048 5cd4393b bellard
        break;
6049 7a3148a9 j_mayer
#endif
6050 31e31b8a bellard
    case TARGET_NR__sysctl:
6051 0da46a6e ths
        /* We don't implement this, but ENOTDIR is always a safe
6052 29e619b1 bellard
           return value. */
6053 0da46a6e ths
        ret = -TARGET_ENOTDIR;
6054 0da46a6e ths
        break;
6055 31e31b8a bellard
    case TARGET_NR_sched_setparam:
6056 5cd4393b bellard
        {
6057 53a5960a pbrook
            struct sched_param *target_schp;
6058 5cd4393b bellard
            struct sched_param schp;
6059 53a5960a pbrook
6060 579a97f7 bellard
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
6061 579a97f7 bellard
                goto efault;
6062 5cd4393b bellard
            schp.sched_priority = tswap32(target_schp->sched_priority);
6063 53a5960a pbrook
            unlock_user_struct(target_schp, arg2, 0);
6064 5cd4393b bellard
            ret = get_errno(sched_setparam(arg1, &schp));
6065 5cd4393b bellard
        }
6066 5cd4393b bellard
        break;
6067 31e31b8a bellard
    case TARGET_NR_sched_getparam:
6068 5cd4393b bellard
        {
6069 53a5960a pbrook
            struct sched_param *target_schp;
6070 5cd4393b bellard
            struct sched_param schp;
6071 5cd4393b bellard
            ret = get_errno(sched_getparam(arg1, &schp));
6072 5cd4393b bellard
            if (!is_error(ret)) {
6073 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
6074 579a97f7 bellard
                    goto efault;
6075 5cd4393b bellard
                target_schp->sched_priority = tswap32(schp.sched_priority);
6076 53a5960a pbrook
                unlock_user_struct(target_schp, arg2, 1);
6077 5cd4393b bellard
            }
6078 5cd4393b bellard
        }
6079 5cd4393b bellard
        break;
6080 31e31b8a bellard
    case TARGET_NR_sched_setscheduler:
6081 5cd4393b bellard
        {
6082 53a5960a pbrook
            struct sched_param *target_schp;
6083 5cd4393b bellard
            struct sched_param schp;
6084 579a97f7 bellard
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
6085 579a97f7 bellard
                goto efault;
6086 5cd4393b bellard
            schp.sched_priority = tswap32(target_schp->sched_priority);
6087 53a5960a pbrook
            unlock_user_struct(target_schp, arg3, 0);
6088 5cd4393b bellard
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
6089 5cd4393b bellard
        }
6090 5cd4393b bellard
        break;
6091 31e31b8a bellard
    case TARGET_NR_sched_getscheduler:
6092 5cd4393b bellard
        ret = get_errno(sched_getscheduler(arg1));
6093 5cd4393b bellard
        break;
6094 31e31b8a bellard
    case TARGET_NR_sched_yield:
6095 31e31b8a bellard
        ret = get_errno(sched_yield());
6096 31e31b8a bellard
        break;
6097 31e31b8a bellard
    case TARGET_NR_sched_get_priority_max:
6098 5cd4393b bellard
        ret = get_errno(sched_get_priority_max(arg1));
6099 5cd4393b bellard
        break;
6100 31e31b8a bellard
    case TARGET_NR_sched_get_priority_min:
6101 5cd4393b bellard
        ret = get_errno(sched_get_priority_min(arg1));
6102 5cd4393b bellard
        break;
6103 31e31b8a bellard
    case TARGET_NR_sched_rr_get_interval:
6104 5cd4393b bellard
        {
6105 5cd4393b bellard
            struct timespec ts;
6106 5cd4393b bellard
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
6107 5cd4393b bellard
            if (!is_error(ret)) {
6108 53a5960a pbrook
                host_to_target_timespec(arg2, &ts);
6109 5cd4393b bellard
            }
6110 5cd4393b bellard
        }
6111 5cd4393b bellard
        break;
6112 31e31b8a bellard
    case TARGET_NR_nanosleep:
6113 1b6b029e bellard
        {
6114 1b6b029e bellard
            struct timespec req, rem;
6115 53a5960a pbrook
            target_to_host_timespec(&req, arg1);
6116 1b6b029e bellard
            ret = get_errno(nanosleep(&req, &rem));
6117 53a5960a pbrook
            if (is_error(ret) && arg2) {
6118 53a5960a pbrook
                host_to_target_timespec(arg2, &rem);
6119 1b6b029e bellard
            }
6120 1b6b029e bellard
        }
6121 1b6b029e bellard
        break;
6122 e5febef5 ths
#ifdef TARGET_NR_query_module
6123 31e31b8a bellard
    case TARGET_NR_query_module:
6124 5cd4393b bellard
        goto unimplemented;
6125 e5febef5 ths
#endif
6126 e5febef5 ths
#ifdef TARGET_NR_nfsservctl
6127 31e31b8a bellard
    case TARGET_NR_nfsservctl:
6128 5cd4393b bellard
        goto unimplemented;
6129 e5febef5 ths
#endif
6130 31e31b8a bellard
    case TARGET_NR_prctl:
6131 e5574487 ths
        switch (arg1)
6132 e5574487 ths
            {
6133 e5574487 ths
            case PR_GET_PDEATHSIG:
6134 e5574487 ths
                {
6135 e5574487 ths
                    int deathsig;
6136 e5574487 ths
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
6137 2f619698 bellard
                    if (!is_error(ret) && arg2
6138 2f619698 bellard
                        && put_user_ual(deathsig, arg2))
6139 2f619698 bellard
                        goto efault;
6140 e5574487 ths
                }
6141 e5574487 ths
                break;
6142 e5574487 ths
            default:
6143 e5574487 ths
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
6144 e5574487 ths
                break;
6145 e5574487 ths
            }
6146 39b9aae1 ths
        break;
6147 d2fd1af7 bellard
#ifdef TARGET_NR_arch_prctl
6148 d2fd1af7 bellard
    case TARGET_NR_arch_prctl:
6149 d2fd1af7 bellard
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
6150 d2fd1af7 bellard
        ret = do_arch_prctl(cpu_env, arg1, arg2);
6151 d2fd1af7 bellard
        break;
6152 d2fd1af7 bellard
#else
6153 d2fd1af7 bellard
        goto unimplemented;
6154 d2fd1af7 bellard
#endif
6155 d2fd1af7 bellard
#endif
6156 67867308 bellard
#ifdef TARGET_NR_pread
6157 31e31b8a bellard
    case TARGET_NR_pread:
6158 a4ae00bc balrog
#ifdef TARGET_ARM
6159 a4ae00bc balrog
        if (((CPUARMState *)cpu_env)->eabi)
6160 a4ae00bc balrog
            arg4 = arg5;
6161 a4ae00bc balrog
#endif
6162 579a97f7 bellard
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6163 579a97f7 bellard
            goto efault;
6164 53a5960a pbrook
        ret = get_errno(pread(arg1, p, arg3, arg4));
6165 53a5960a pbrook
        unlock_user(p, arg2, ret);
6166 206f0fa7 bellard
        break;
6167 31e31b8a bellard
    case TARGET_NR_pwrite:
6168 a4ae00bc balrog
#ifdef TARGET_ARM
6169 a4ae00bc balrog
        if (((CPUARMState *)cpu_env)->eabi)
6170 a4ae00bc balrog
            arg4 = arg5;
6171 a4ae00bc balrog
#endif
6172 579a97f7 bellard
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6173 579a97f7 bellard
            goto efault;
6174 53a5960a pbrook
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
6175 53a5960a pbrook
        unlock_user(p, arg2, 0);
6176 206f0fa7 bellard
        break;
6177 67867308 bellard
#endif
6178 f2c7ba15 aurel32
#ifdef TARGET_NR_pread64
6179 f2c7ba15 aurel32
    case TARGET_NR_pread64:
6180 f2c7ba15 aurel32
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6181 f2c7ba15 aurel32
            goto efault;
6182 f2c7ba15 aurel32
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
6183 f2c7ba15 aurel32
        unlock_user(p, arg2, ret);
6184 f2c7ba15 aurel32
        break;
6185 f2c7ba15 aurel32
    case TARGET_NR_pwrite64:
6186 f2c7ba15 aurel32
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6187 f2c7ba15 aurel32
            goto efault;
6188 f2c7ba15 aurel32
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
6189 f2c7ba15 aurel32
        unlock_user(p, arg2, 0);
6190 f2c7ba15 aurel32
        break;
6191 f2c7ba15 aurel32
#endif
6192 31e31b8a bellard
    case TARGET_NR_getcwd:
6193 579a97f7 bellard
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
6194 579a97f7 bellard
            goto efault;
6195 53a5960a pbrook
        ret = get_errno(sys_getcwd1(p, arg2));
6196 53a5960a pbrook
        unlock_user(p, arg1, ret);
6197 31e31b8a bellard
        break;
6198 31e31b8a bellard
    case TARGET_NR_capget:
6199 5cd4393b bellard
        goto unimplemented;
6200 31e31b8a bellard
    case TARGET_NR_capset:
6201 5cd4393b bellard
        goto unimplemented;
6202 31e31b8a bellard
    case TARGET_NR_sigaltstack:
6203 198a74de ths
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
6204 c761c154 Laurent Vivier
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
6205 c761c154 Laurent Vivier
    defined(TARGET_M68K)
6206 579a97f7 bellard
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
6207 a04e134a ths
        break;
6208 a04e134a ths
#else
6209 5cd4393b bellard
        goto unimplemented;
6210 a04e134a ths
#endif
6211 31e31b8a bellard
    case TARGET_NR_sendfile:
6212 5cd4393b bellard
        goto unimplemented;
6213 ebc05488 bellard
#ifdef TARGET_NR_getpmsg
6214 31e31b8a bellard
    case TARGET_NR_getpmsg:
6215 5cd4393b bellard
        goto unimplemented;
6216 ebc05488 bellard
#endif
6217 ebc05488 bellard
#ifdef TARGET_NR_putpmsg
6218 31e31b8a bellard
    case TARGET_NR_putpmsg:
6219 5cd4393b bellard
        goto unimplemented;
6220 ebc05488 bellard
#endif
6221 048f6b4d bellard
#ifdef TARGET_NR_vfork
6222 31e31b8a bellard
    case TARGET_NR_vfork:
6223 d865bab5 pbrook
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
6224 d865bab5 pbrook
                        0, 0, 0, 0));
6225 31e31b8a bellard
        break;
6226 048f6b4d bellard
#endif
6227 ebc05488 bellard
#ifdef TARGET_NR_ugetrlimit
6228 31e31b8a bellard
    case TARGET_NR_ugetrlimit:
6229 728584be bellard
    {
6230 728584be bellard
        struct rlimit rlim;
6231 728584be bellard
        ret = get_errno(getrlimit(arg1, &rlim));
6232 728584be bellard
        if (!is_error(ret)) {
6233 53a5960a pbrook
            struct target_rlimit *target_rlim;
6234 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6235 579a97f7 bellard
                goto efault;
6236 728584be bellard
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
6237 728584be bellard
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
6238 53a5960a pbrook
            unlock_user_struct(target_rlim, arg2, 1);
6239 728584be bellard
        }
6240 728584be bellard
        break;
6241 728584be bellard
    }
6242 ebc05488 bellard
#endif
6243 a315a145 bellard
#ifdef TARGET_NR_truncate64
6244 31e31b8a bellard
    case TARGET_NR_truncate64:
6245 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6246 579a97f7 bellard
            goto efault;
6247 53a5960a pbrook
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
6248 53a5960a pbrook
        unlock_user(p, arg1, 0);
6249 667f38b1 bellard
        break;
6250 a315a145 bellard
#endif
6251 a315a145 bellard
#ifdef TARGET_NR_ftruncate64
6252 31e31b8a bellard
    case TARGET_NR_ftruncate64:
6253 ce4defa0 pbrook
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
6254 667f38b1 bellard
        break;
6255 a315a145 bellard
#endif
6256 a315a145 bellard
#ifdef TARGET_NR_stat64
6257 31e31b8a bellard
    case TARGET_NR_stat64:
6258 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6259 579a97f7 bellard
            goto efault;
6260 53a5960a pbrook
        ret = get_errno(stat(path(p), &st));
6261 53a5960a pbrook
        unlock_user(p, arg1, 0);
6262 6a24a778 balrog
        if (!is_error(ret))
6263 6a24a778 balrog
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6264 6a24a778 balrog
        break;
6265 a315a145 bellard
#endif
6266 a315a145 bellard
#ifdef TARGET_NR_lstat64
6267 31e31b8a bellard
    case TARGET_NR_lstat64:
6268 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6269 579a97f7 bellard
            goto efault;
6270 53a5960a pbrook
        ret = get_errno(lstat(path(p), &st));
6271 53a5960a pbrook
        unlock_user(p, arg1, 0);
6272 6a24a778 balrog
        if (!is_error(ret))
6273 6a24a778 balrog
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6274 6a24a778 balrog
        break;
6275 a315a145 bellard
#endif
6276 a315a145 bellard
#ifdef TARGET_NR_fstat64
6277 31e31b8a bellard
    case TARGET_NR_fstat64:
6278 6a24a778 balrog
        ret = get_errno(fstat(arg1, &st));
6279 6a24a778 balrog
        if (!is_error(ret))
6280 6a24a778 balrog
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6281 6a24a778 balrog
        break;
6282 ce4defa0 pbrook
#endif
6283 9d33b76b aurel32
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6284 9d33b76b aurel32
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6285 9d33b76b aurel32
#ifdef TARGET_NR_fstatat64
6286 6a24a778 balrog
    case TARGET_NR_fstatat64:
6287 9d33b76b aurel32
#endif
6288 9d33b76b aurel32
#ifdef TARGET_NR_newfstatat
6289 9d33b76b aurel32
    case TARGET_NR_newfstatat:
6290 9d33b76b aurel32
#endif
6291 6a24a778 balrog
        if (!(p = lock_user_string(arg2)))
6292 6a24a778 balrog
            goto efault;
6293 9d33b76b aurel32
#ifdef __NR_fstatat64
6294 6a24a778 balrog
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
6295 9d33b76b aurel32
#else
6296 9d33b76b aurel32
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
6297 9d33b76b aurel32
#endif
6298 6a24a778 balrog
        if (!is_error(ret))
6299 6a24a778 balrog
            ret = host_to_target_stat64(cpu_env, arg3, &st);
6300 60cd49d5 bellard
        break;
6301 a315a145 bellard
#endif
6302 67867308 bellard
#ifdef USE_UID16
6303 67867308 bellard
    case TARGET_NR_lchown:
6304 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6305 579a97f7 bellard
            goto efault;
6306 53a5960a pbrook
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
6307 53a5960a pbrook
        unlock_user(p, arg1, 0);
6308 67867308 bellard
        break;
6309 67867308 bellard
    case TARGET_NR_getuid:
6310 67867308 bellard
        ret = get_errno(high2lowuid(getuid()));
6311 67867308 bellard
        break;
6312 67867308 bellard
    case TARGET_NR_getgid:
6313 67867308 bellard
        ret = get_errno(high2lowgid(getgid()));
6314 67867308 bellard
        break;
6315 67867308 bellard
    case TARGET_NR_geteuid:
6316 67867308 bellard
        ret = get_errno(high2lowuid(geteuid()));
6317 67867308 bellard
        break;
6318 67867308 bellard
    case TARGET_NR_getegid:
6319 67867308 bellard
        ret = get_errno(high2lowgid(getegid()));
6320 67867308 bellard
        break;
6321 67867308 bellard
    case TARGET_NR_setreuid:
6322 67867308 bellard
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
6323 67867308 bellard
        break;
6324 67867308 bellard
    case TARGET_NR_setregid:
6325 67867308 bellard
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
6326 67867308 bellard
        break;
6327 67867308 bellard
    case TARGET_NR_getgroups:
6328 67867308 bellard
        {
6329 67867308 bellard
            int gidsetsize = arg1;
6330 53a5960a pbrook
            uint16_t *target_grouplist;
6331 67867308 bellard
            gid_t *grouplist;
6332 67867308 bellard
            int i;
6333 67867308 bellard
6334 67867308 bellard
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6335 67867308 bellard
            ret = get_errno(getgroups(gidsetsize, grouplist));
6336 cb3bc233 balrog
            if (gidsetsize == 0)
6337 cb3bc233 balrog
                break;
6338 67867308 bellard
            if (!is_error(ret)) {
6339 579a97f7 bellard
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6340 579a97f7 bellard
                if (!target_grouplist)
6341 579a97f7 bellard
                    goto efault;
6342 a2155fcc balrog
                for(i = 0;i < ret; i++)
6343 67867308 bellard
                    target_grouplist[i] = tswap16(grouplist[i]);
6344 53a5960a pbrook
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
6345 67867308 bellard
            }
6346 67867308 bellard
        }
6347 67867308 bellard
        break;
6348 67867308 bellard
    case TARGET_NR_setgroups:
6349 67867308 bellard
        {
6350 67867308 bellard
            int gidsetsize = arg1;
6351 53a5960a pbrook
            uint16_t *target_grouplist;
6352 67867308 bellard
            gid_t *grouplist;
6353 67867308 bellard
            int i;
6354 67867308 bellard
6355 67867308 bellard
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6356 579a97f7 bellard
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
6357 579a97f7 bellard
            if (!target_grouplist) {
6358 579a97f7 bellard
                ret = -TARGET_EFAULT;
6359 579a97f7 bellard
                goto fail;
6360 579a97f7 bellard
            }
6361 67867308 bellard
            for(i = 0;i < gidsetsize; i++)
6362 67867308 bellard
                grouplist[i] = tswap16(target_grouplist[i]);
6363 53a5960a pbrook
            unlock_user(target_grouplist, arg2, 0);
6364 67867308 bellard
            ret = get_errno(setgroups(gidsetsize, grouplist));
6365 67867308 bellard
        }
6366 67867308 bellard
        break;
6367 67867308 bellard
    case TARGET_NR_fchown:
6368 67867308 bellard
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
6369 67867308 bellard
        break;
6370 ccfa72b7 ths
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6371 ccfa72b7 ths
    case TARGET_NR_fchownat:
6372 579a97f7 bellard
        if (!(p = lock_user_string(arg2))) 
6373 579a97f7 bellard
            goto efault;
6374 579a97f7 bellard
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
6375 579a97f7 bellard
        unlock_user(p, arg2, 0);
6376 ccfa72b7 ths
        break;
6377 ccfa72b7 ths
#endif
6378 67867308 bellard
#ifdef TARGET_NR_setresuid
6379 67867308 bellard
    case TARGET_NR_setresuid:
6380 5fafdf24 ths
        ret = get_errno(setresuid(low2highuid(arg1),
6381 5fafdf24 ths
                                  low2highuid(arg2),
6382 67867308 bellard
                                  low2highuid(arg3)));
6383 67867308 bellard
        break;
6384 67867308 bellard
#endif
6385 67867308 bellard
#ifdef TARGET_NR_getresuid
6386 67867308 bellard
    case TARGET_NR_getresuid:
6387 67867308 bellard
        {
6388 53a5960a pbrook
            uid_t ruid, euid, suid;
6389 67867308 bellard
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6390 67867308 bellard
            if (!is_error(ret)) {
6391 2f619698 bellard
                if (put_user_u16(high2lowuid(ruid), arg1)
6392 2f619698 bellard
                    || put_user_u16(high2lowuid(euid), arg2)
6393 2f619698 bellard
                    || put_user_u16(high2lowuid(suid), arg3))
6394 2f619698 bellard
                    goto efault;
6395 67867308 bellard
            }
6396 67867308 bellard
        }
6397 67867308 bellard
        break;
6398 67867308 bellard
#endif
6399 67867308 bellard
#ifdef TARGET_NR_getresgid
6400 67867308 bellard
    case TARGET_NR_setresgid:
6401 5fafdf24 ths
        ret = get_errno(setresgid(low2highgid(arg1),
6402 5fafdf24 ths
                                  low2highgid(arg2),
6403 67867308 bellard
                                  low2highgid(arg3)));
6404 67867308 bellard
        break;
6405 67867308 bellard
#endif
6406 67867308 bellard
#ifdef TARGET_NR_getresgid
6407 67867308 bellard
    case TARGET_NR_getresgid:
6408 67867308 bellard
        {
6409 53a5960a pbrook
            gid_t rgid, egid, sgid;
6410 67867308 bellard
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6411 67867308 bellard
            if (!is_error(ret)) {
6412 2f619698 bellard
                if (put_user_u16(high2lowgid(rgid), arg1)
6413 2f619698 bellard
                    || put_user_u16(high2lowgid(egid), arg2)
6414 2f619698 bellard
                    || put_user_u16(high2lowgid(sgid), arg3))
6415 2f619698 bellard
                    goto efault;
6416 67867308 bellard
            }
6417 67867308 bellard
        }
6418 67867308 bellard
        break;
6419 67867308 bellard
#endif
6420 67867308 bellard
    case TARGET_NR_chown:
6421 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6422 579a97f7 bellard
            goto efault;
6423 53a5960a pbrook
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
6424 53a5960a pbrook
        unlock_user(p, arg1, 0);
6425 67867308 bellard
        break;
6426 67867308 bellard
    case TARGET_NR_setuid:
6427 67867308 bellard
        ret = get_errno(setuid(low2highuid(arg1)));
6428 67867308 bellard
        break;
6429 67867308 bellard
    case TARGET_NR_setgid:
6430 67867308 bellard
        ret = get_errno(setgid(low2highgid(arg1)));
6431 67867308 bellard
        break;
6432 67867308 bellard
    case TARGET_NR_setfsuid:
6433 67867308 bellard
        ret = get_errno(setfsuid(arg1));
6434 67867308 bellard
        break;
6435 67867308 bellard
    case TARGET_NR_setfsgid:
6436 67867308 bellard
        ret = get_errno(setfsgid(arg1));
6437 67867308 bellard
        break;
6438 67867308 bellard
#endif /* USE_UID16 */
6439 67867308 bellard
6440 a315a145 bellard
#ifdef TARGET_NR_lchown32
6441 31e31b8a bellard
    case TARGET_NR_lchown32:
6442 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6443 579a97f7 bellard
            goto efault;
6444 53a5960a pbrook
        ret = get_errno(lchown(p, arg2, arg3));
6445 53a5960a pbrook
        unlock_user(p, arg1, 0);
6446 b03c60f3 bellard
        break;
6447 a315a145 bellard
#endif
6448 a315a145 bellard
#ifdef TARGET_NR_getuid32
6449 31e31b8a bellard
    case TARGET_NR_getuid32:
6450 b03c60f3 bellard
        ret = get_errno(getuid());
6451 b03c60f3 bellard
        break;
6452 a315a145 bellard
#endif
6453 64b4d28c aurel32
6454 64b4d28c aurel32
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6455 64b4d28c aurel32
   /* Alpha specific */
6456 64b4d28c aurel32
    case TARGET_NR_getxuid:
6457 ba0e276d Richard Henderson
         {
6458 ba0e276d Richard Henderson
            uid_t euid;
6459 ba0e276d Richard Henderson
            euid=geteuid();
6460 ba0e276d Richard Henderson
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6461 ba0e276d Richard Henderson
         }
6462 64b4d28c aurel32
        ret = get_errno(getuid());
6463 64b4d28c aurel32
        break;
6464 64b4d28c aurel32
#endif
6465 64b4d28c aurel32
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6466 64b4d28c aurel32
   /* Alpha specific */
6467 64b4d28c aurel32
    case TARGET_NR_getxgid:
6468 ba0e276d Richard Henderson
         {
6469 ba0e276d Richard Henderson
            uid_t egid;
6470 ba0e276d Richard Henderson
            egid=getegid();
6471 ba0e276d Richard Henderson
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6472 ba0e276d Richard Henderson
         }
6473 64b4d28c aurel32
        ret = get_errno(getgid());
6474 64b4d28c aurel32
        break;
6475 64b4d28c aurel32
#endif
6476 ba0e276d Richard Henderson
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
6477 ba0e276d Richard Henderson
    /* Alpha specific */
6478 ba0e276d Richard Henderson
    case TARGET_NR_osf_getsysinfo:
6479 ba0e276d Richard Henderson
        ret = -TARGET_EOPNOTSUPP;
6480 ba0e276d Richard Henderson
        switch (arg1) {
6481 ba0e276d Richard Henderson
          case TARGET_GSI_IEEE_FP_CONTROL:
6482 ba0e276d Richard Henderson
            {
6483 ba0e276d Richard Henderson
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
6484 ba0e276d Richard Henderson
6485 ba0e276d Richard Henderson
                /* Copied from linux ieee_fpcr_to_swcr.  */
6486 ba0e276d Richard Henderson
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
6487 ba0e276d Richard Henderson
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
6488 ba0e276d Richard Henderson
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
6489 ba0e276d Richard Henderson
                                        | SWCR_TRAP_ENABLE_DZE
6490 ba0e276d Richard Henderson
                                        | SWCR_TRAP_ENABLE_OVF);
6491 ba0e276d Richard Henderson
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
6492 ba0e276d Richard Henderson
                                        | SWCR_TRAP_ENABLE_INE);
6493 ba0e276d Richard Henderson
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
6494 ba0e276d Richard Henderson
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
6495 ba0e276d Richard Henderson
6496 ba0e276d Richard Henderson
                if (put_user_u64 (swcr, arg2))
6497 ba0e276d Richard Henderson
                        goto efault;
6498 ba0e276d Richard Henderson
                ret = 0;
6499 ba0e276d Richard Henderson
            }
6500 ba0e276d Richard Henderson
            break;
6501 ba0e276d Richard Henderson
6502 ba0e276d Richard Henderson
          /* case GSI_IEEE_STATE_AT_SIGNAL:
6503 ba0e276d Richard Henderson
             -- Not implemented in linux kernel.
6504 ba0e276d Richard Henderson
             case GSI_UACPROC:
6505 ba0e276d Richard Henderson
             -- Retrieves current unaligned access state; not much used.
6506 ba0e276d Richard Henderson
             case GSI_PROC_TYPE:
6507 ba0e276d Richard Henderson
             -- Retrieves implver information; surely not used.
6508 ba0e276d Richard Henderson
             case GSI_GET_HWRPB:
6509 ba0e276d Richard Henderson
             -- Grabs a copy of the HWRPB; surely not used.
6510 ba0e276d Richard Henderson
          */
6511 ba0e276d Richard Henderson
        }
6512 ba0e276d Richard Henderson
        break;
6513 ba0e276d Richard Henderson
#endif
6514 ba0e276d Richard Henderson
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
6515 ba0e276d Richard Henderson
    /* Alpha specific */
6516 ba0e276d Richard Henderson
    case TARGET_NR_osf_setsysinfo:
6517 ba0e276d Richard Henderson
        ret = -TARGET_EOPNOTSUPP;
6518 ba0e276d Richard Henderson
        switch (arg1) {
6519 ba0e276d Richard Henderson
          case TARGET_SSI_IEEE_FP_CONTROL:
6520 ba0e276d Richard Henderson
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
6521 ba0e276d Richard Henderson
            {
6522 ba0e276d Richard Henderson
                uint64_t swcr, fpcr, orig_fpcr;
6523 ba0e276d Richard Henderson
6524 ba0e276d Richard Henderson
                if (get_user_u64 (swcr, arg2))
6525 ba0e276d Richard Henderson
                    goto efault;
6526 ba0e276d Richard Henderson
                orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
6527 ba0e276d Richard Henderson
                fpcr = orig_fpcr & FPCR_DYN_MASK;
6528 ba0e276d Richard Henderson
6529 ba0e276d Richard Henderson
                /* Copied from linux ieee_swcr_to_fpcr.  */
6530 ba0e276d Richard Henderson
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
6531 ba0e276d Richard Henderson
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
6532 ba0e276d Richard Henderson
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
6533 ba0e276d Richard Henderson
                                  | SWCR_TRAP_ENABLE_DZE
6534 ba0e276d Richard Henderson
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
6535 ba0e276d Richard Henderson
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
6536 ba0e276d Richard Henderson
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
6537 ba0e276d Richard Henderson
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
6538 ba0e276d Richard Henderson
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
6539 ba0e276d Richard Henderson
6540 ba0e276d Richard Henderson
                cpu_alpha_store_fpcr (cpu_env, fpcr);
6541 ba0e276d Richard Henderson
                ret = 0;
6542 ba0e276d Richard Henderson
6543 ba0e276d Richard Henderson
                if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
6544 ba0e276d Richard Henderson
                    /* Old exceptions are not signaled.  */
6545 ba0e276d Richard Henderson
                    fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
6546 ba0e276d Richard Henderson
6547 ba0e276d Richard Henderson
                    /* If any exceptions set by this call, and are unmasked,
6548 ba0e276d Richard Henderson
                       send a signal.  */
6549 ba0e276d Richard Henderson
                    /* ??? FIXME */
6550 ba0e276d Richard Henderson
                }
6551 ba0e276d Richard Henderson
            }
6552 ba0e276d Richard Henderson
            break;
6553 ba0e276d Richard Henderson
6554 ba0e276d Richard Henderson
          /* case SSI_NVPAIRS:
6555 ba0e276d Richard Henderson
             -- Used with SSIN_UACPROC to enable unaligned accesses.
6556 ba0e276d Richard Henderson
             case SSI_IEEE_STATE_AT_SIGNAL:
6557 ba0e276d Richard Henderson
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
6558 ba0e276d Richard Henderson
             -- Not implemented in linux kernel
6559 ba0e276d Richard Henderson
          */
6560 ba0e276d Richard Henderson
        }
6561 ba0e276d Richard Henderson
        break;
6562 ba0e276d Richard Henderson
#endif
6563 ba0e276d Richard Henderson
#ifdef TARGET_NR_osf_sigprocmask
6564 ba0e276d Richard Henderson
    /* Alpha specific.  */
6565 ba0e276d Richard Henderson
    case TARGET_NR_osf_sigprocmask:
6566 ba0e276d Richard Henderson
        {
6567 ba0e276d Richard Henderson
            abi_ulong mask;
6568 ba0e276d Richard Henderson
            int how = arg1;
6569 ba0e276d Richard Henderson
            sigset_t set, oldset;
6570 ba0e276d Richard Henderson
6571 ba0e276d Richard Henderson
            switch(arg1) {
6572 ba0e276d Richard Henderson
            case TARGET_SIG_BLOCK:
6573 ba0e276d Richard Henderson
                how = SIG_BLOCK;
6574 ba0e276d Richard Henderson
                break;
6575 ba0e276d Richard Henderson
            case TARGET_SIG_UNBLOCK:
6576 ba0e276d Richard Henderson
                how = SIG_UNBLOCK;
6577 ba0e276d Richard Henderson
                break;
6578 ba0e276d Richard Henderson
            case TARGET_SIG_SETMASK:
6579 ba0e276d Richard Henderson
                how = SIG_SETMASK;
6580 ba0e276d Richard Henderson
                break;
6581 ba0e276d Richard Henderson
            default:
6582 ba0e276d Richard Henderson
                ret = -TARGET_EINVAL;
6583 ba0e276d Richard Henderson
                goto fail;
6584 ba0e276d Richard Henderson
            }
6585 ba0e276d Richard Henderson
            mask = arg2;
6586 ba0e276d Richard Henderson
            target_to_host_old_sigset(&set, &mask);
6587 ba0e276d Richard Henderson
            sigprocmask(arg1, &set, &oldset);
6588 ba0e276d Richard Henderson
            host_to_target_old_sigset(&mask, &oldset);
6589 ba0e276d Richard Henderson
            ret = mask;
6590 ba0e276d Richard Henderson
        }
6591 ba0e276d Richard Henderson
        break;
6592 ba0e276d Richard Henderson
#endif
6593 64b4d28c aurel32
6594 a315a145 bellard
#ifdef TARGET_NR_getgid32
6595 31e31b8a bellard
    case TARGET_NR_getgid32:
6596 b03c60f3 bellard
        ret = get_errno(getgid());
6597 b03c60f3 bellard
        break;
6598 a315a145 bellard
#endif
6599 a315a145 bellard
#ifdef TARGET_NR_geteuid32
6600 31e31b8a bellard
    case TARGET_NR_geteuid32:
6601 b03c60f3 bellard
        ret = get_errno(geteuid());
6602 b03c60f3 bellard
        break;
6603 a315a145 bellard
#endif
6604 a315a145 bellard
#ifdef TARGET_NR_getegid32
6605 31e31b8a bellard
    case TARGET_NR_getegid32:
6606 b03c60f3 bellard
        ret = get_errno(getegid());
6607 b03c60f3 bellard
        break;
6608 a315a145 bellard
#endif
6609 a315a145 bellard
#ifdef TARGET_NR_setreuid32
6610 31e31b8a bellard
    case TARGET_NR_setreuid32:
6611 b03c60f3 bellard
        ret = get_errno(setreuid(arg1, arg2));
6612 b03c60f3 bellard
        break;
6613 a315a145 bellard
#endif
6614 a315a145 bellard
#ifdef TARGET_NR_setregid32
6615 31e31b8a bellard
    case TARGET_NR_setregid32:
6616 b03c60f3 bellard
        ret = get_errno(setregid(arg1, arg2));
6617 b03c60f3 bellard
        break;
6618 a315a145 bellard
#endif
6619 a315a145 bellard
#ifdef TARGET_NR_getgroups32
6620 31e31b8a bellard
    case TARGET_NR_getgroups32:
6621 99c475ab bellard
        {
6622 99c475ab bellard
            int gidsetsize = arg1;
6623 53a5960a pbrook
            uint32_t *target_grouplist;
6624 99c475ab bellard
            gid_t *grouplist;
6625 99c475ab bellard
            int i;
6626 99c475ab bellard
6627 99c475ab bellard
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6628 99c475ab bellard
            ret = get_errno(getgroups(gidsetsize, grouplist));
6629 cb3bc233 balrog
            if (gidsetsize == 0)
6630 cb3bc233 balrog
                break;
6631 99c475ab bellard
            if (!is_error(ret)) {
6632 579a97f7 bellard
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6633 579a97f7 bellard
                if (!target_grouplist) {
6634 579a97f7 bellard
                    ret = -TARGET_EFAULT;
6635 579a97f7 bellard
                    goto fail;
6636 579a97f7 bellard
                }
6637 a2155fcc balrog
                for(i = 0;i < ret; i++)
6638 53a5960a pbrook
                    target_grouplist[i] = tswap32(grouplist[i]);
6639 53a5960a pbrook
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
6640 99c475ab bellard
            }
6641 99c475ab bellard
        }
6642 99c475ab bellard
        break;
6643 a315a145 bellard
#endif
6644 a315a145 bellard
#ifdef TARGET_NR_setgroups32
6645 31e31b8a bellard
    case TARGET_NR_setgroups32:
6646 99c475ab bellard
        {
6647 99c475ab bellard
            int gidsetsize = arg1;
6648 53a5960a pbrook
            uint32_t *target_grouplist;
6649 99c475ab bellard
            gid_t *grouplist;
6650 99c475ab bellard
            int i;
6651 3b46e624 ths
6652 99c475ab bellard
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6653 579a97f7 bellard
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6654 579a97f7 bellard
            if (!target_grouplist) {
6655 579a97f7 bellard
                ret = -TARGET_EFAULT;
6656 579a97f7 bellard
                goto fail;
6657 579a97f7 bellard
            }
6658 99c475ab bellard
            for(i = 0;i < gidsetsize; i++)
6659 53a5960a pbrook
                grouplist[i] = tswap32(target_grouplist[i]);
6660 53a5960a pbrook
            unlock_user(target_grouplist, arg2, 0);
6661 99c475ab bellard
            ret = get_errno(setgroups(gidsetsize, grouplist));
6662 99c475ab bellard
        }
6663 99c475ab bellard
        break;
6664 a315a145 bellard
#endif
6665 a315a145 bellard
#ifdef TARGET_NR_fchown32
6666 31e31b8a bellard
    case TARGET_NR_fchown32:
6667 b03c60f3 bellard
        ret = get_errno(fchown(arg1, arg2, arg3));
6668 b03c60f3 bellard
        break;
6669 a315a145 bellard
#endif
6670 a315a145 bellard
#ifdef TARGET_NR_setresuid32
6671 31e31b8a bellard
    case TARGET_NR_setresuid32:
6672 b03c60f3 bellard
        ret = get_errno(setresuid(arg1, arg2, arg3));
6673 b03c60f3 bellard
        break;
6674 a315a145 bellard
#endif
6675 a315a145 bellard
#ifdef TARGET_NR_getresuid32
6676 31e31b8a bellard
    case TARGET_NR_getresuid32:
6677 b03c60f3 bellard
        {
6678 53a5960a pbrook
            uid_t ruid, euid, suid;
6679 b03c60f3 bellard
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6680 b03c60f3 bellard
            if (!is_error(ret)) {
6681 2f619698 bellard
                if (put_user_u32(ruid, arg1)
6682 2f619698 bellard
                    || put_user_u32(euid, arg2)
6683 2f619698 bellard
                    || put_user_u32(suid, arg3))
6684 2f619698 bellard
                    goto efault;
6685 b03c60f3 bellard
            }
6686 b03c60f3 bellard
        }
6687 b03c60f3 bellard
        break;
6688 a315a145 bellard
#endif
6689 a315a145 bellard
#ifdef TARGET_NR_setresgid32
6690 31e31b8a bellard
    case TARGET_NR_setresgid32:
6691 b03c60f3 bellard
        ret = get_errno(setresgid(arg1, arg2, arg3));
6692 b03c60f3 bellard
        break;
6693 a315a145 bellard
#endif
6694 a315a145 bellard
#ifdef TARGET_NR_getresgid32
6695 31e31b8a bellard
    case TARGET_NR_getresgid32:
6696 b03c60f3 bellard
        {
6697 53a5960a pbrook
            gid_t rgid, egid, sgid;
6698 b03c60f3 bellard
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6699 b03c60f3 bellard
            if (!is_error(ret)) {
6700 2f619698 bellard
                if (put_user_u32(rgid, arg1)
6701 2f619698 bellard
                    || put_user_u32(egid, arg2)
6702 2f619698 bellard
                    || put_user_u32(sgid, arg3))
6703 2f619698 bellard
                    goto efault;
6704 b03c60f3 bellard
            }
6705 b03c60f3 bellard
        }
6706 b03c60f3 bellard
        break;
6707 a315a145 bellard
#endif
6708 a315a145 bellard
#ifdef TARGET_NR_chown32
6709 31e31b8a bellard
    case TARGET_NR_chown32:
6710 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6711 579a97f7 bellard
            goto efault;
6712 53a5960a pbrook
        ret = get_errno(chown(p, arg2, arg3));
6713 53a5960a pbrook
        unlock_user(p, arg1, 0);
6714 b03c60f3 bellard
        break;
6715 a315a145 bellard
#endif
6716 a315a145 bellard
#ifdef TARGET_NR_setuid32
6717 31e31b8a bellard
    case TARGET_NR_setuid32:
6718 b03c60f3 bellard
        ret = get_errno(setuid(arg1));
6719 b03c60f3 bellard
        break;
6720 a315a145 bellard
#endif
6721 a315a145 bellard
#ifdef TARGET_NR_setgid32
6722 31e31b8a bellard
    case TARGET_NR_setgid32:
6723 b03c60f3 bellard
        ret = get_errno(setgid(arg1));
6724 b03c60f3 bellard
        break;
6725 a315a145 bellard
#endif
6726 a315a145 bellard
#ifdef TARGET_NR_setfsuid32
6727 31e31b8a bellard
    case TARGET_NR_setfsuid32:
6728 b03c60f3 bellard
        ret = get_errno(setfsuid(arg1));
6729 b03c60f3 bellard
        break;
6730 a315a145 bellard
#endif
6731 a315a145 bellard
#ifdef TARGET_NR_setfsgid32
6732 31e31b8a bellard
    case TARGET_NR_setfsgid32:
6733 b03c60f3 bellard
        ret = get_errno(setfsgid(arg1));
6734 b03c60f3 bellard
        break;
6735 a315a145 bellard
#endif
6736 67867308 bellard
6737 31e31b8a bellard
    case TARGET_NR_pivot_root:
6738 b03c60f3 bellard
        goto unimplemented;
6739 ffa65c3b bellard
#ifdef TARGET_NR_mincore
6740 31e31b8a bellard
    case TARGET_NR_mincore:
6741 04bb9ace aurel32
        {
6742 04bb9ace aurel32
            void *a;
6743 04bb9ace aurel32
            ret = -TARGET_EFAULT;
6744 04bb9ace aurel32
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6745 04bb9ace aurel32
                goto efault;
6746 04bb9ace aurel32
            if (!(p = lock_user_string(arg3)))
6747 04bb9ace aurel32
                goto mincore_fail;
6748 04bb9ace aurel32
            ret = get_errno(mincore(a, arg2, p));
6749 04bb9ace aurel32
            unlock_user(p, arg3, ret);
6750 04bb9ace aurel32
            mincore_fail:
6751 04bb9ace aurel32
            unlock_user(a, arg1, 0);
6752 04bb9ace aurel32
        }
6753 04bb9ace aurel32
        break;
6754 ffa65c3b bellard
#endif
6755 408321b6 aurel32
#ifdef TARGET_NR_arm_fadvise64_64
6756 408321b6 aurel32
    case TARGET_NR_arm_fadvise64_64:
6757 408321b6 aurel32
        {
6758 408321b6 aurel32
                /*
6759 408321b6 aurel32
                 * arm_fadvise64_64 looks like fadvise64_64 but
6760 408321b6 aurel32
                 * with different argument order
6761 408321b6 aurel32
                 */
6762 408321b6 aurel32
                abi_long temp;
6763 408321b6 aurel32
                temp = arg3;
6764 408321b6 aurel32
                arg3 = arg4;
6765 408321b6 aurel32
                arg4 = temp;
6766 408321b6 aurel32
        }
6767 408321b6 aurel32
#endif
6768 e72d2cc7 Ulrich Hecht
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
6769 408321b6 aurel32
#ifdef TARGET_NR_fadvise64_64
6770 408321b6 aurel32
    case TARGET_NR_fadvise64_64:
6771 408321b6 aurel32
#endif
6772 e72d2cc7 Ulrich Hecht
#ifdef TARGET_NR_fadvise64
6773 e72d2cc7 Ulrich Hecht
    case TARGET_NR_fadvise64:
6774 e72d2cc7 Ulrich Hecht
#endif
6775 e72d2cc7 Ulrich Hecht
#ifdef TARGET_S390X
6776 e72d2cc7 Ulrich Hecht
        switch (arg4) {
6777 e72d2cc7 Ulrich Hecht
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
6778 e72d2cc7 Ulrich Hecht
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
6779 e72d2cc7 Ulrich Hecht
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
6780 e72d2cc7 Ulrich Hecht
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
6781 e72d2cc7 Ulrich Hecht
        default: break;
6782 e72d2cc7 Ulrich Hecht
        }
6783 e72d2cc7 Ulrich Hecht
#endif
6784 e72d2cc7 Ulrich Hecht
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
6785 408321b6 aurel32
        break;
6786 408321b6 aurel32
#endif
6787 ffa65c3b bellard
#ifdef TARGET_NR_madvise
6788 31e31b8a bellard
    case TARGET_NR_madvise:
6789 24836689 pbrook
        /* A straight passthrough may not be safe because qemu sometimes
6790 24836689 pbrook
           turns private flie-backed mappings into anonymous mappings.
6791 24836689 pbrook
           This will break MADV_DONTNEED.
6792 24836689 pbrook
           This is a hint, so ignoring and returning success is ok.  */
6793 24836689 pbrook
        ret = get_errno(0);
6794 24836689 pbrook
        break;
6795 ffa65c3b bellard
#endif
6796 992f48a0 blueswir1
#if TARGET_ABI_BITS == 32
6797 31e31b8a bellard
    case TARGET_NR_fcntl64:
6798 77e4672d bellard
    {
6799 b1e341eb ths
        int cmd;
6800 77e4672d bellard
        struct flock64 fl;
6801 53a5960a pbrook
        struct target_flock64 *target_fl;
6802 ce4defa0 pbrook
#ifdef TARGET_ARM
6803 53a5960a pbrook
        struct target_eabi_flock64 *target_efl;
6804 ce4defa0 pbrook
#endif
6805 77e4672d bellard
6806 5f106811 Arnaud Patard (Rtp)
        cmd = target_to_host_fcntl_cmd(arg2);
6807 5f106811 Arnaud Patard (Rtp)
        if (cmd == -TARGET_EINVAL)
6808 5f106811 Arnaud Patard (Rtp)
                return cmd;
6809 b1e341eb ths
6810 60cd49d5 bellard
        switch(arg2) {
6811 b1e341eb ths
        case TARGET_F_GETLK64:
6812 5813427b ths
#ifdef TARGET_ARM
6813 5813427b ths
            if (((CPUARMState *)cpu_env)->eabi) {
6814 9ee1fa2c bellard
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6815 9ee1fa2c bellard
                    goto efault;
6816 5813427b ths
                fl.l_type = tswap16(target_efl->l_type);
6817 5813427b ths
                fl.l_whence = tswap16(target_efl->l_whence);
6818 5813427b ths
                fl.l_start = tswap64(target_efl->l_start);
6819 5813427b ths
                fl.l_len = tswap64(target_efl->l_len);
6820 7e22e546 Ulrich Hecht
                fl.l_pid = tswap32(target_efl->l_pid);
6821 5813427b ths
                unlock_user_struct(target_efl, arg3, 0);
6822 5813427b ths
            } else
6823 5813427b ths
#endif
6824 5813427b ths
            {
6825 9ee1fa2c bellard
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6826 9ee1fa2c bellard
                    goto efault;
6827 5813427b ths
                fl.l_type = tswap16(target_fl->l_type);
6828 5813427b ths
                fl.l_whence = tswap16(target_fl->l_whence);
6829 5813427b ths
                fl.l_start = tswap64(target_fl->l_start);
6830 5813427b ths
                fl.l_len = tswap64(target_fl->l_len);
6831 7e22e546 Ulrich Hecht
                fl.l_pid = tswap32(target_fl->l_pid);
6832 5813427b ths
                unlock_user_struct(target_fl, arg3, 0);
6833 5813427b ths
            }
6834 b1e341eb ths
            ret = get_errno(fcntl(arg1, cmd, &fl));
6835 77e4672d bellard
            if (ret == 0) {
6836 ce4defa0 pbrook
#ifdef TARGET_ARM
6837 ce4defa0 pbrook
                if (((CPUARMState *)cpu_env)->eabi) {
6838 9ee1fa2c bellard
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
6839 9ee1fa2c bellard
                        goto efault;
6840 ce4defa0 pbrook
                    target_efl->l_type = tswap16(fl.l_type);
6841 ce4defa0 pbrook
                    target_efl->l_whence = tswap16(fl.l_whence);
6842 ce4defa0 pbrook
                    target_efl->l_start = tswap64(fl.l_start);
6843 ce4defa0 pbrook
                    target_efl->l_len = tswap64(fl.l_len);
6844 7e22e546 Ulrich Hecht
                    target_efl->l_pid = tswap32(fl.l_pid);
6845 53a5960a pbrook
                    unlock_user_struct(target_efl, arg3, 1);
6846 ce4defa0 pbrook
                } else
6847 ce4defa0 pbrook
#endif
6848 ce4defa0 pbrook
                {
6849 9ee1fa2c bellard
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
6850 9ee1fa2c bellard
                        goto efault;
6851 ce4defa0 pbrook
                    target_fl->l_type = tswap16(fl.l_type);
6852 ce4defa0 pbrook
                    target_fl->l_whence = tswap16(fl.l_whence);
6853 ce4defa0 pbrook
                    target_fl->l_start = tswap64(fl.l_start);
6854 ce4defa0 pbrook
                    target_fl->l_len = tswap64(fl.l_len);
6855 7e22e546 Ulrich Hecht
                    target_fl->l_pid = tswap32(fl.l_pid);
6856 53a5960a pbrook
                    unlock_user_struct(target_fl, arg3, 1);
6857 ce4defa0 pbrook
                }
6858 77e4672d bellard
            }
6859 77e4672d bellard
            break;
6860 77e4672d bellard
6861 b1e341eb ths
        case TARGET_F_SETLK64:
6862 b1e341eb ths
        case TARGET_F_SETLKW64:
6863 ce4defa0 pbrook
#ifdef TARGET_ARM
6864 ce4defa0 pbrook
            if (((CPUARMState *)cpu_env)->eabi) {
6865 9ee1fa2c bellard
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6866 9ee1fa2c bellard
                    goto efault;
6867 ce4defa0 pbrook
                fl.l_type = tswap16(target_efl->l_type);
6868 ce4defa0 pbrook
                fl.l_whence = tswap16(target_efl->l_whence);
6869 ce4defa0 pbrook
                fl.l_start = tswap64(target_efl->l_start);
6870 ce4defa0 pbrook
                fl.l_len = tswap64(target_efl->l_len);
6871 7e22e546 Ulrich Hecht
                fl.l_pid = tswap32(target_efl->l_pid);
6872 53a5960a pbrook
                unlock_user_struct(target_efl, arg3, 0);
6873 ce4defa0 pbrook
            } else
6874 ce4defa0 pbrook
#endif
6875 ce4defa0 pbrook
            {
6876 9ee1fa2c bellard
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6877 9ee1fa2c bellard
                    goto efault;
6878 ce4defa0 pbrook
                fl.l_type = tswap16(target_fl->l_type);
6879 ce4defa0 pbrook
                fl.l_whence = tswap16(target_fl->l_whence);
6880 ce4defa0 pbrook
                fl.l_start = tswap64(target_fl->l_start);
6881 ce4defa0 pbrook
                fl.l_len = tswap64(target_fl->l_len);
6882 7e22e546 Ulrich Hecht
                fl.l_pid = tswap32(target_fl->l_pid);
6883 53a5960a pbrook
                unlock_user_struct(target_fl, arg3, 0);
6884 ce4defa0 pbrook
            }
6885 b1e341eb ths
            ret = get_errno(fcntl(arg1, cmd, &fl));
6886 77e4672d bellard
            break;
6887 60cd49d5 bellard
        default:
6888 5f106811 Arnaud Patard (Rtp)
            ret = do_fcntl(arg1, arg2, arg3);
6889 60cd49d5 bellard
            break;
6890 60cd49d5 bellard
        }
6891 77e4672d bellard
        break;
6892 77e4672d bellard
    }
6893 60cd49d5 bellard
#endif
6894 7d600c80 ths
#ifdef TARGET_NR_cacheflush
6895 7d600c80 ths
    case TARGET_NR_cacheflush:
6896 7d600c80 ths
        /* self-modifying code is handled automatically, so nothing needed */
6897 7d600c80 ths
        ret = 0;
6898 7d600c80 ths
        break;
6899 7d600c80 ths
#endif
6900 ebc05488 bellard
#ifdef TARGET_NR_security
6901 31e31b8a bellard
    case TARGET_NR_security:
6902 31e31b8a bellard
        goto unimplemented;
6903 ebc05488 bellard
#endif
6904 c573ff67 bellard
#ifdef TARGET_NR_getpagesize
6905 c573ff67 bellard
    case TARGET_NR_getpagesize:
6906 c573ff67 bellard
        ret = TARGET_PAGE_SIZE;
6907 c573ff67 bellard
        break;
6908 c573ff67 bellard
#endif
6909 31e31b8a bellard
    case TARGET_NR_gettid:
6910 31e31b8a bellard
        ret = get_errno(gettid());
6911 31e31b8a bellard
        break;
6912 e5febef5 ths
#ifdef TARGET_NR_readahead
6913 31e31b8a bellard
    case TARGET_NR_readahead:
6914 2054ac9b aurel32
#if TARGET_ABI_BITS == 32
6915 2054ac9b aurel32
#ifdef TARGET_ARM
6916 2054ac9b aurel32
        if (((CPUARMState *)cpu_env)->eabi)
6917 2054ac9b aurel32
        {
6918 2054ac9b aurel32
            arg2 = arg3;
6919 2054ac9b aurel32
            arg3 = arg4;
6920 2054ac9b aurel32
            arg4 = arg5;
6921 2054ac9b aurel32
        }
6922 2054ac9b aurel32
#endif
6923 2054ac9b aurel32
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6924 2054ac9b aurel32
#else
6925 2054ac9b aurel32
        ret = get_errno(readahead(arg1, arg2, arg3));
6926 2054ac9b aurel32
#endif
6927 2054ac9b aurel32
        break;
6928 e5febef5 ths
#endif
6929 ebc05488 bellard
#ifdef TARGET_NR_setxattr
6930 31e31b8a bellard
    case TARGET_NR_setxattr:
6931 31e31b8a bellard
    case TARGET_NR_lsetxattr:
6932 31e31b8a bellard
    case TARGET_NR_fsetxattr:
6933 31e31b8a bellard
    case TARGET_NR_getxattr:
6934 31e31b8a bellard
    case TARGET_NR_lgetxattr:
6935 31e31b8a bellard
    case TARGET_NR_fgetxattr:
6936 31e31b8a bellard
    case TARGET_NR_listxattr:
6937 31e31b8a bellard
    case TARGET_NR_llistxattr:
6938 31e31b8a bellard
    case TARGET_NR_flistxattr:
6939 31e31b8a bellard
    case TARGET_NR_removexattr:
6940 31e31b8a bellard
    case TARGET_NR_lremovexattr:
6941 31e31b8a bellard
    case TARGET_NR_fremovexattr:
6942 6f932f91 Arnaud Patard
        ret = -TARGET_EOPNOTSUPP;
6943 6f932f91 Arnaud Patard
        break;
6944 ebc05488 bellard
#endif
6945 ebc05488 bellard
#ifdef TARGET_NR_set_thread_area
6946 5cd4393b bellard
    case TARGET_NR_set_thread_area:
6947 8d18e893 bellard
#if defined(TARGET_MIPS)
6948 6f5b89a0 ths
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6949 6f5b89a0 ths
      ret = 0;
6950 6f5b89a0 ths
      break;
6951 ef96779b edgar_igl
#elif defined(TARGET_CRIS)
6952 ef96779b edgar_igl
      if (arg1 & 0xff)
6953 ef96779b edgar_igl
          ret = -TARGET_EINVAL;
6954 ef96779b edgar_igl
      else {
6955 ef96779b edgar_igl
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6956 ef96779b edgar_igl
          ret = 0;
6957 ef96779b edgar_igl
      }
6958 ef96779b edgar_igl
      break;
6959 8d18e893 bellard
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
6960 8d18e893 bellard
      ret = do_set_thread_area(cpu_env, arg1);
6961 8d18e893 bellard
      break;
6962 6f5b89a0 ths
#else
6963 6f5b89a0 ths
      goto unimplemented_nowarn;
6964 6f5b89a0 ths
#endif
6965 6f5b89a0 ths
#endif
6966 6f5b89a0 ths
#ifdef TARGET_NR_get_thread_area
6967 5cd4393b bellard
    case TARGET_NR_get_thread_area:
6968 8d18e893 bellard
#if defined(TARGET_I386) && defined(TARGET_ABI32)
6969 8d18e893 bellard
        ret = do_get_thread_area(cpu_env, arg1);
6970 8d18e893 bellard
#else
6971 5cd4393b bellard
        goto unimplemented_nowarn;
6972 ebc05488 bellard
#endif
6973 8d18e893 bellard
#endif
6974 48dc41eb bellard
#ifdef TARGET_NR_getdomainname
6975 48dc41eb bellard
    case TARGET_NR_getdomainname:
6976 48dc41eb bellard
        goto unimplemented_nowarn;
6977 48dc41eb bellard
#endif
6978 6f5b89a0 ths
6979 b5906f95 ths
#ifdef TARGET_NR_clock_gettime
6980 b5906f95 ths
    case TARGET_NR_clock_gettime:
6981 b5906f95 ths
    {
6982 b5906f95 ths
        struct timespec ts;
6983 b5906f95 ths
        ret = get_errno(clock_gettime(arg1, &ts));
6984 b5906f95 ths
        if (!is_error(ret)) {
6985 b5906f95 ths
            host_to_target_timespec(arg2, &ts);
6986 b5906f95 ths
        }
6987 b5906f95 ths
        break;
6988 b5906f95 ths
    }
6989 b5906f95 ths
#endif
6990 b5906f95 ths
#ifdef TARGET_NR_clock_getres
6991 b5906f95 ths
    case TARGET_NR_clock_getres:
6992 b5906f95 ths
    {
6993 b5906f95 ths
        struct timespec ts;
6994 b5906f95 ths
        ret = get_errno(clock_getres(arg1, &ts));
6995 b5906f95 ths
        if (!is_error(ret)) {
6996 b5906f95 ths
            host_to_target_timespec(arg2, &ts);
6997 b5906f95 ths
        }
6998 b5906f95 ths
        break;
6999 b5906f95 ths
    }
7000 b5906f95 ths
#endif
7001 63d7651b pbrook
#ifdef TARGET_NR_clock_nanosleep
7002 63d7651b pbrook
    case TARGET_NR_clock_nanosleep:
7003 63d7651b pbrook
    {
7004 63d7651b pbrook
        struct timespec ts;
7005 63d7651b pbrook
        target_to_host_timespec(&ts, arg3);
7006 63d7651b pbrook
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
7007 63d7651b pbrook
        if (arg4)
7008 63d7651b pbrook
            host_to_target_timespec(arg4, &ts);
7009 63d7651b pbrook
        break;
7010 63d7651b pbrook
    }
7011 63d7651b pbrook
#endif
7012 b5906f95 ths
7013 6f5b89a0 ths
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
7014 6f5b89a0 ths
    case TARGET_NR_set_tid_address:
7015 579a97f7 bellard
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
7016 579a97f7 bellard
        break;
7017 6f5b89a0 ths
#endif
7018 6f5b89a0 ths
7019 3ae43202 ths
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
7020 4cae1d16 ths
    case TARGET_NR_tkill:
7021 4cb05961 pbrook
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
7022 4cae1d16 ths
        break;
7023 4cae1d16 ths
#endif
7024 4cae1d16 ths
7025 3ae43202 ths
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
7026 71455574 ths
    case TARGET_NR_tgkill:
7027 4cb05961 pbrook
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
7028 4cb05961 pbrook
                        target_to_host_signal(arg3)));
7029 71455574 ths
        break;
7030 71455574 ths
#endif
7031 71455574 ths
7032 4f2b1fe8 ths
#ifdef TARGET_NR_set_robust_list
7033 4f2b1fe8 ths
    case TARGET_NR_set_robust_list:
7034 4f2b1fe8 ths
        goto unimplemented_nowarn;
7035 4f2b1fe8 ths
#endif
7036 4f2b1fe8 ths
7037 9007f0ef ths
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
7038 9007f0ef ths
    case TARGET_NR_utimensat:
7039 9007f0ef ths
        {
7040 ebc996f3 Riku Voipio
            struct timespec *tsp, ts[2];
7041 ebc996f3 Riku Voipio
            if (!arg3) {
7042 ebc996f3 Riku Voipio
                tsp = NULL;
7043 ebc996f3 Riku Voipio
            } else {
7044 ebc996f3 Riku Voipio
                target_to_host_timespec(ts, arg3);
7045 ebc996f3 Riku Voipio
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
7046 ebc996f3 Riku Voipio
                tsp = ts;
7047 ebc996f3 Riku Voipio
            }
7048 9007f0ef ths
            if (!arg2)
7049 ebc996f3 Riku Voipio
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
7050 9007f0ef ths
            else {
7051 579a97f7 bellard
                if (!(p = lock_user_string(arg2))) {
7052 0da46a6e ths
                    ret = -TARGET_EFAULT;
7053 579a97f7 bellard
                    goto fail;
7054 579a97f7 bellard
                }
7055 ebc996f3 Riku Voipio
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
7056 579a97f7 bellard
                unlock_user(p, arg2, 0);
7057 9007f0ef ths
            }
7058 9007f0ef ths
        }
7059 9007f0ef ths
        break;
7060 9007f0ef ths
#endif
7061 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
7062 bd0c5661 pbrook
    case TARGET_NR_futex:
7063 bd0c5661 pbrook
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
7064 bd0c5661 pbrook
        break;
7065 bd0c5661 pbrook
#endif
7066 dbfe4c36 aurel32
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
7067 39b59763 aurel32
    case TARGET_NR_inotify_init:
7068 39b59763 aurel32
        ret = get_errno(sys_inotify_init());
7069 39b59763 aurel32
        break;
7070 39b59763 aurel32
#endif
7071 a1606b0b Stefan Weil
#ifdef CONFIG_INOTIFY1
7072 c05c7a73 Riku Voipio
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
7073 c05c7a73 Riku Voipio
    case TARGET_NR_inotify_init1:
7074 c05c7a73 Riku Voipio
        ret = get_errno(sys_inotify_init1(arg1));
7075 c05c7a73 Riku Voipio
        break;
7076 c05c7a73 Riku Voipio
#endif
7077 a1606b0b Stefan Weil
#endif
7078 dbfe4c36 aurel32
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
7079 39b59763 aurel32
    case TARGET_NR_inotify_add_watch:
7080 39b59763 aurel32
        p = lock_user_string(arg2);
7081 39b59763 aurel32
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
7082 39b59763 aurel32
        unlock_user(p, arg2, 0);
7083 39b59763 aurel32
        break;
7084 39b59763 aurel32
#endif
7085 dbfe4c36 aurel32
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
7086 39b59763 aurel32
    case TARGET_NR_inotify_rm_watch:
7087 39b59763 aurel32
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
7088 39b59763 aurel32
        break;
7089 39b59763 aurel32
#endif
7090 9007f0ef ths
7091 8ec9cf89 Nathan Froyd
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
7092 24e1003a aurel32
    case TARGET_NR_mq_open:
7093 24e1003a aurel32
        {
7094 24e1003a aurel32
            struct mq_attr posix_mq_attr;
7095 24e1003a aurel32
7096 24e1003a aurel32
            p = lock_user_string(arg1 - 1);
7097 24e1003a aurel32
            if (arg4 != 0)
7098 24e1003a aurel32
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
7099 24e1003a aurel32
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
7100 24e1003a aurel32
            unlock_user (p, arg1, 0);
7101 24e1003a aurel32
        }
7102 24e1003a aurel32
        break;
7103 24e1003a aurel32
7104 24e1003a aurel32
    case TARGET_NR_mq_unlink:
7105 24e1003a aurel32
        p = lock_user_string(arg1 - 1);
7106 24e1003a aurel32
        ret = get_errno(mq_unlink(p));
7107 24e1003a aurel32
        unlock_user (p, arg1, 0);
7108 24e1003a aurel32
        break;
7109 24e1003a aurel32
7110 24e1003a aurel32
    case TARGET_NR_mq_timedsend:
7111 24e1003a aurel32
        {
7112 24e1003a aurel32
            struct timespec ts;
7113 24e1003a aurel32
7114 24e1003a aurel32
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7115 24e1003a aurel32
            if (arg5 != 0) {
7116 24e1003a aurel32
                target_to_host_timespec(&ts, arg5);
7117 24e1003a aurel32
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
7118 24e1003a aurel32
                host_to_target_timespec(arg5, &ts);
7119 24e1003a aurel32
            }
7120 24e1003a aurel32
            else
7121 24e1003a aurel32
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
7122 24e1003a aurel32
            unlock_user (p, arg2, arg3);
7123 24e1003a aurel32
        }
7124 24e1003a aurel32
        break;
7125 24e1003a aurel32
7126 24e1003a aurel32
    case TARGET_NR_mq_timedreceive:
7127 24e1003a aurel32
        {
7128 24e1003a aurel32
            struct timespec ts;
7129 24e1003a aurel32
            unsigned int prio;
7130 24e1003a aurel32
7131 24e1003a aurel32
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7132 24e1003a aurel32
            if (arg5 != 0) {
7133 24e1003a aurel32
                target_to_host_timespec(&ts, arg5);
7134 24e1003a aurel32
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
7135 24e1003a aurel32
                host_to_target_timespec(arg5, &ts);
7136 24e1003a aurel32
            }
7137 24e1003a aurel32
            else
7138 24e1003a aurel32
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
7139 24e1003a aurel32
            unlock_user (p, arg2, arg3);
7140 24e1003a aurel32
            if (arg4 != 0)
7141 24e1003a aurel32
                put_user_u32(prio, arg4);
7142 24e1003a aurel32
        }
7143 24e1003a aurel32
        break;
7144 24e1003a aurel32
7145 24e1003a aurel32
    /* Not implemented for now... */
7146 24e1003a aurel32
/*     case TARGET_NR_mq_notify: */
7147 24e1003a aurel32
/*         break; */
7148 24e1003a aurel32
7149 24e1003a aurel32
    case TARGET_NR_mq_getsetattr:
7150 24e1003a aurel32
        {
7151 24e1003a aurel32
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
7152 24e1003a aurel32
            ret = 0;
7153 24e1003a aurel32
            if (arg3 != 0) {
7154 24e1003a aurel32
                ret = mq_getattr(arg1, &posix_mq_attr_out);
7155 24e1003a aurel32
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
7156 24e1003a aurel32
            }
7157 24e1003a aurel32
            if (arg2 != 0) {
7158 24e1003a aurel32
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
7159 24e1003a aurel32
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
7160 24e1003a aurel32
            }
7161 24e1003a aurel32
7162 24e1003a aurel32
        }
7163 24e1003a aurel32
        break;
7164 24e1003a aurel32
#endif
7165 24e1003a aurel32
7166 3ce34dfb vibisreenivasan
#ifdef CONFIG_SPLICE
7167 3ce34dfb vibisreenivasan
#ifdef TARGET_NR_tee
7168 3ce34dfb vibisreenivasan
    case TARGET_NR_tee:
7169 3ce34dfb vibisreenivasan
        {
7170 3ce34dfb vibisreenivasan
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
7171 3ce34dfb vibisreenivasan
        }
7172 3ce34dfb vibisreenivasan
        break;
7173 3ce34dfb vibisreenivasan
#endif
7174 3ce34dfb vibisreenivasan
#ifdef TARGET_NR_splice
7175 3ce34dfb vibisreenivasan
    case TARGET_NR_splice:
7176 3ce34dfb vibisreenivasan
        {
7177 3ce34dfb vibisreenivasan
            loff_t loff_in, loff_out;
7178 3ce34dfb vibisreenivasan
            loff_t *ploff_in = NULL, *ploff_out = NULL;
7179 3ce34dfb vibisreenivasan
            if(arg2) {
7180 3ce34dfb vibisreenivasan
                get_user_u64(loff_in, arg2);
7181 3ce34dfb vibisreenivasan
                ploff_in = &loff_in;
7182 3ce34dfb vibisreenivasan
            }
7183 3ce34dfb vibisreenivasan
            if(arg4) {
7184 3ce34dfb vibisreenivasan
                get_user_u64(loff_out, arg2);
7185 3ce34dfb vibisreenivasan
                ploff_out = &loff_out;
7186 3ce34dfb vibisreenivasan
            }
7187 3ce34dfb vibisreenivasan
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
7188 3ce34dfb vibisreenivasan
        }
7189 3ce34dfb vibisreenivasan
        break;
7190 3ce34dfb vibisreenivasan
#endif
7191 3ce34dfb vibisreenivasan
#ifdef TARGET_NR_vmsplice
7192 3ce34dfb vibisreenivasan
        case TARGET_NR_vmsplice:
7193 3ce34dfb vibisreenivasan
        {
7194 3ce34dfb vibisreenivasan
            int count = arg3;
7195 3ce34dfb vibisreenivasan
            struct iovec *vec;
7196 3ce34dfb vibisreenivasan
7197 3ce34dfb vibisreenivasan
            vec = alloca(count * sizeof(struct iovec));
7198 3ce34dfb vibisreenivasan
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
7199 3ce34dfb vibisreenivasan
                goto efault;
7200 3ce34dfb vibisreenivasan
            ret = get_errno(vmsplice(arg1, vec, count, arg4));
7201 3ce34dfb vibisreenivasan
            unlock_iovec(vec, arg2, count, 0);
7202 3ce34dfb vibisreenivasan
        }
7203 3ce34dfb vibisreenivasan
        break;
7204 3ce34dfb vibisreenivasan
#endif
7205 3ce34dfb vibisreenivasan
#endif /* CONFIG_SPLICE */
7206 c2882b96 Riku Voipio
#ifdef CONFIG_EVENTFD
7207 c2882b96 Riku Voipio
#if defined(TARGET_NR_eventfd)
7208 c2882b96 Riku Voipio
    case TARGET_NR_eventfd:
7209 c2882b96 Riku Voipio
        ret = get_errno(eventfd(arg1, 0));
7210 c2882b96 Riku Voipio
        break;
7211 c2882b96 Riku Voipio
#endif
7212 c2882b96 Riku Voipio
#if defined(TARGET_NR_eventfd2)
7213 c2882b96 Riku Voipio
    case TARGET_NR_eventfd2:
7214 c2882b96 Riku Voipio
        ret = get_errno(eventfd(arg1, arg2));
7215 c2882b96 Riku Voipio
        break;
7216 c2882b96 Riku Voipio
#endif
7217 c2882b96 Riku Voipio
#endif /* CONFIG_EVENTFD  */
7218 d0927938 Ulrich Hecht
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
7219 d0927938 Ulrich Hecht
    case TARGET_NR_fallocate:
7220 d0927938 Ulrich Hecht
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
7221 d0927938 Ulrich Hecht
        break;
7222 d0927938 Ulrich Hecht
#endif
7223 31e31b8a bellard
    default:
7224 31e31b8a bellard
    unimplemented:
7225 5cd4393b bellard
        gemu_log("qemu: Unsupported syscall: %d\n", num);
7226 4f2b1fe8 ths
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
7227 5cd4393b bellard
    unimplemented_nowarn:
7228 80a9d035 bellard
#endif
7229 0da46a6e ths
        ret = -TARGET_ENOSYS;
7230 31e31b8a bellard
        break;
7231 31e31b8a bellard
    }
7232 579a97f7 bellard
fail:
7233 c573ff67 bellard
#ifdef DEBUG
7234 0bf9e31a Blue Swirl
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
7235 c573ff67 bellard
#endif
7236 b92c47c1 ths
    if(do_strace)
7237 b92c47c1 ths
        print_syscall_ret(num, ret);
7238 31e31b8a bellard
    return ret;
7239 579a97f7 bellard
efault:
7240 579a97f7 bellard
    ret = -TARGET_EFAULT;
7241 579a97f7 bellard
    goto fail;
7242 31e31b8a bellard
}