Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ c05c7a73

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