Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ fad6cb1a

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