Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ a4c075f1

History | View | Annotate | Download (241.4 kB)

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