Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ fefe54e3

History | View | Annotate | Download (187.9 kB)

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