Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 42673936

History | View | Annotate | Download (221.8 kB)

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