Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ b2178704

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