Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ ca20cf32

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