Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ f97572e5

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