Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 03ff3ca3

History | View | Annotate | Download (180.1 kB)

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