Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ b55266b5

History | View | Annotate | Download (182 kB)

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