Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ f0cbb613

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