Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 4cb05961

History | View | Annotate | Download (175.3 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 7a3148a9 j_mayer
#ifdef TARGET_NR_creat /* not on alpha */
3173 31e31b8a bellard
    case TARGET_NR_creat:
3174 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3175 579a97f7 bellard
            goto efault;
3176 53a5960a pbrook
        ret = get_errno(creat(p, arg2));
3177 53a5960a pbrook
        unlock_user(p, arg1, 0);
3178 31e31b8a bellard
        break;
3179 7a3148a9 j_mayer
#endif
3180 31e31b8a bellard
    case TARGET_NR_link:
3181 53a5960a pbrook
        {
3182 53a5960a pbrook
            void * p2;
3183 53a5960a pbrook
            p = lock_user_string(arg1);
3184 53a5960a pbrook
            p2 = lock_user_string(arg2);
3185 579a97f7 bellard
            if (!p || !p2)
3186 579a97f7 bellard
                ret = -TARGET_EFAULT;
3187 579a97f7 bellard
            else
3188 579a97f7 bellard
                ret = get_errno(link(p, p2));
3189 53a5960a pbrook
            unlock_user(p2, arg2, 0);
3190 53a5960a pbrook
            unlock_user(p, arg1, 0);
3191 53a5960a pbrook
        }
3192 31e31b8a bellard
        break;
3193 64f0ce4c ths
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3194 64f0ce4c ths
    case TARGET_NR_linkat:
3195 64f0ce4c ths
        {
3196 64f0ce4c ths
            void * p2 = NULL;
3197 579a97f7 bellard
            if (!arg2 || !arg4)
3198 579a97f7 bellard
                goto efault;
3199 64f0ce4c ths
            p  = lock_user_string(arg2);
3200 64f0ce4c ths
            p2 = lock_user_string(arg4);
3201 579a97f7 bellard
            if (!p || !p2)
3202 0da46a6e ths
                ret = -TARGET_EFAULT;
3203 64f0ce4c ths
            else
3204 64f0ce4c ths
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3205 579a97f7 bellard
            unlock_user(p, arg2, 0);
3206 579a97f7 bellard
            unlock_user(p2, arg4, 0);
3207 64f0ce4c ths
        }
3208 64f0ce4c ths
        break;
3209 64f0ce4c ths
#endif
3210 31e31b8a bellard
    case TARGET_NR_unlink:
3211 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3212 579a97f7 bellard
            goto efault;
3213 53a5960a pbrook
        ret = get_errno(unlink(p));
3214 53a5960a pbrook
        unlock_user(p, arg1, 0);
3215 31e31b8a bellard
        break;
3216 8170f56b ths
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3217 8170f56b ths
    case TARGET_NR_unlinkat:
3218 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
3219 579a97f7 bellard
            goto efault;
3220 579a97f7 bellard
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
3221 579a97f7 bellard
        unlock_user(p, arg2, 0);
3222 ed494d87 balrog
        break;
3223 b7d35e65 balrog
#endif
3224 31e31b8a bellard
    case TARGET_NR_execve:
3225 7854b056 bellard
        {
3226 7854b056 bellard
            char **argp, **envp;
3227 f7341ff4 bellard
            int argc, envc;
3228 992f48a0 blueswir1
            abi_ulong gp;
3229 992f48a0 blueswir1
            abi_ulong guest_argp;
3230 992f48a0 blueswir1
            abi_ulong guest_envp;
3231 992f48a0 blueswir1
            abi_ulong addr;
3232 7854b056 bellard
            char **q;
3233 7854b056 bellard
3234 f7341ff4 bellard
            argc = 0;
3235 53a5960a pbrook
            guest_argp = arg2;
3236 982f3ab6 ths
            for (gp = guest_argp; ; gp += sizeof(abi_ulong)) {
3237 03aa1976 ths
                if (get_user_ual(addr, gp))
3238 2f619698 bellard
                    goto efault;
3239 03aa1976 ths
                if (!addr)
3240 2f619698 bellard
                    break;
3241 7854b056 bellard
                argc++;
3242 2f619698 bellard
            }
3243 f7341ff4 bellard
            envc = 0;
3244 53a5960a pbrook
            guest_envp = arg3;
3245 982f3ab6 ths
            for (gp = guest_envp; ; gp += sizeof(abi_ulong)) {
3246 03aa1976 ths
                if (get_user_ual(addr, gp))
3247 2f619698 bellard
                    goto efault;
3248 03aa1976 ths
                if (!addr)
3249 2f619698 bellard
                    break;
3250 7854b056 bellard
                envc++;
3251 2f619698 bellard
            }
3252 7854b056 bellard
3253 f7341ff4 bellard
            argp = alloca((argc + 1) * sizeof(void *));
3254 f7341ff4 bellard
            envp = alloca((envc + 1) * sizeof(void *));
3255 7854b056 bellard
3256 53a5960a pbrook
            for (gp = guest_argp, q = argp; ;
3257 992f48a0 blueswir1
                  gp += sizeof(abi_ulong), q++) {
3258 2f619698 bellard
                if (get_user_ual(addr, gp))
3259 2f619698 bellard
                    goto execve_efault;
3260 53a5960a pbrook
                if (!addr)
3261 53a5960a pbrook
                    break;
3262 2f619698 bellard
                if (!(*q = lock_user_string(addr)))
3263 2f619698 bellard
                    goto execve_efault;
3264 53a5960a pbrook
            }
3265 f7341ff4 bellard
            *q = NULL;
3266 f7341ff4 bellard
3267 53a5960a pbrook
            for (gp = guest_envp, q = envp; ;
3268 992f48a0 blueswir1
                  gp += sizeof(abi_ulong), q++) {
3269 2f619698 bellard
                if (get_user_ual(addr, gp))
3270 2f619698 bellard
                    goto execve_efault;
3271 53a5960a pbrook
                if (!addr)
3272 53a5960a pbrook
                    break;
3273 2f619698 bellard
                if (!(*q = lock_user_string(addr)))
3274 2f619698 bellard
                    goto execve_efault;
3275 53a5960a pbrook
            }
3276 f7341ff4 bellard
            *q = NULL;
3277 7854b056 bellard
3278 2f619698 bellard
            if (!(p = lock_user_string(arg1)))
3279 2f619698 bellard
                goto execve_efault;
3280 53a5960a pbrook
            ret = get_errno(execve(p, argp, envp));
3281 53a5960a pbrook
            unlock_user(p, arg1, 0);
3282 53a5960a pbrook
3283 2f619698 bellard
            goto execve_end;
3284 2f619698 bellard
3285 2f619698 bellard
        execve_efault:
3286 2f619698 bellard
            ret = -TARGET_EFAULT;
3287 2f619698 bellard
3288 2f619698 bellard
        execve_end:
3289 53a5960a pbrook
            for (gp = guest_argp, q = argp; *q;
3290 992f48a0 blueswir1
                  gp += sizeof(abi_ulong), q++) {
3291 2f619698 bellard
                if (get_user_ual(addr, gp)
3292 2f619698 bellard
                    || !addr)
3293 2f619698 bellard
                    break;
3294 53a5960a pbrook
                unlock_user(*q, addr, 0);
3295 53a5960a pbrook
            }
3296 53a5960a pbrook
            for (gp = guest_envp, q = envp; *q;
3297 992f48a0 blueswir1
                  gp += sizeof(abi_ulong), q++) {
3298 2f619698 bellard
                if (get_user_ual(addr, gp)
3299 2f619698 bellard
                    || !addr)
3300 2f619698 bellard
                    break;
3301 53a5960a pbrook
                unlock_user(*q, addr, 0);
3302 53a5960a pbrook
            }
3303 7854b056 bellard
        }
3304 31e31b8a bellard
        break;
3305 31e31b8a bellard
    case TARGET_NR_chdir:
3306 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3307 579a97f7 bellard
            goto efault;
3308 53a5960a pbrook
        ret = get_errno(chdir(p));
3309 53a5960a pbrook
        unlock_user(p, arg1, 0);
3310 31e31b8a bellard
        break;
3311 a315a145 bellard
#ifdef TARGET_NR_time
3312 31e31b8a bellard
    case TARGET_NR_time:
3313 31e31b8a bellard
        {
3314 53a5960a pbrook
            time_t host_time;
3315 53a5960a pbrook
            ret = get_errno(time(&host_time));
3316 2f619698 bellard
            if (!is_error(ret)
3317 2f619698 bellard
                && arg1
3318 2f619698 bellard
                && put_user_sal(host_time, arg1))
3319 2f619698 bellard
                goto efault;
3320 31e31b8a bellard
        }
3321 31e31b8a bellard
        break;
3322 a315a145 bellard
#endif
3323 31e31b8a bellard
    case TARGET_NR_mknod:
3324 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3325 579a97f7 bellard
            goto efault;
3326 53a5960a pbrook
        ret = get_errno(mknod(p, arg2, arg3));
3327 53a5960a pbrook
        unlock_user(p, arg1, 0);
3328 31e31b8a bellard
        break;
3329 75ac37a0 ths
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3330 75ac37a0 ths
    case TARGET_NR_mknodat:
3331 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
3332 579a97f7 bellard
            goto efault;
3333 579a97f7 bellard
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3334 579a97f7 bellard
        unlock_user(p, arg2, 0);
3335 75ac37a0 ths
        break;
3336 75ac37a0 ths
#endif
3337 31e31b8a bellard
    case TARGET_NR_chmod:
3338 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3339 579a97f7 bellard
            goto efault;
3340 53a5960a pbrook
        ret = get_errno(chmod(p, arg2));
3341 53a5960a pbrook
        unlock_user(p, arg1, 0);
3342 31e31b8a bellard
        break;
3343 ebc05488 bellard
#ifdef TARGET_NR_break
3344 31e31b8a bellard
    case TARGET_NR_break:
3345 31e31b8a bellard
        goto unimplemented;
3346 ebc05488 bellard
#endif
3347 ebc05488 bellard
#ifdef TARGET_NR_oldstat
3348 31e31b8a bellard
    case TARGET_NR_oldstat:
3349 31e31b8a bellard
        goto unimplemented;
3350 ebc05488 bellard
#endif
3351 31e31b8a bellard
    case TARGET_NR_lseek:
3352 31e31b8a bellard
        ret = get_errno(lseek(arg1, arg2, arg3));
3353 31e31b8a bellard
        break;
3354 7a3148a9 j_mayer
#ifdef TARGET_NR_getxpid
3355 7a3148a9 j_mayer
    case TARGET_NR_getxpid:
3356 7a3148a9 j_mayer
#else
3357 31e31b8a bellard
    case TARGET_NR_getpid:
3358 7a3148a9 j_mayer
#endif
3359 31e31b8a bellard
        ret = get_errno(getpid());
3360 31e31b8a bellard
        break;
3361 31e31b8a bellard
    case TARGET_NR_mount:
3362 80265918 ths
                {
3363 80265918 ths
                        /* need to look at the data field */
3364 80265918 ths
                        void *p2, *p3;
3365 80265918 ths
                        p = lock_user_string(arg1);
3366 80265918 ths
                        p2 = lock_user_string(arg2);
3367 80265918 ths
                        p3 = lock_user_string(arg3);
3368 579a97f7 bellard
                        if (!p || !p2 || !p3)
3369 579a97f7 bellard
                            ret = -TARGET_EFAULT;
3370 579a97f7 bellard
                        else
3371 579a97f7 bellard
                            /* FIXME - arg5 should be locked, but it isn't clear how to
3372 579a97f7 bellard
                             * do that since it's not guaranteed to be a NULL-terminated
3373 579a97f7 bellard
                             * string.
3374 579a97f7 bellard
                             */
3375 579a97f7 bellard
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3376 579a97f7 bellard
                        unlock_user(p, arg1, 0);
3377 579a97f7 bellard
                        unlock_user(p2, arg2, 0);
3378 579a97f7 bellard
                        unlock_user(p3, arg3, 0);
3379 80265918 ths
                        break;
3380 80265918 ths
                }
3381 e5febef5 ths
#ifdef TARGET_NR_umount
3382 31e31b8a bellard
    case TARGET_NR_umount:
3383 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3384 579a97f7 bellard
            goto efault;
3385 53a5960a pbrook
        ret = get_errno(umount(p));
3386 53a5960a pbrook
        unlock_user(p, arg1, 0);
3387 31e31b8a bellard
        break;
3388 e5febef5 ths
#endif
3389 7a3148a9 j_mayer
#ifdef TARGET_NR_stime /* not on alpha */
3390 31e31b8a bellard
    case TARGET_NR_stime:
3391 31e31b8a bellard
        {
3392 53a5960a pbrook
            time_t host_time;
3393 2f619698 bellard
            if (get_user_sal(host_time, arg1))
3394 2f619698 bellard
                goto efault;
3395 53a5960a pbrook
            ret = get_errno(stime(&host_time));
3396 31e31b8a bellard
        }
3397 31e31b8a bellard
        break;
3398 7a3148a9 j_mayer
#endif
3399 31e31b8a bellard
    case TARGET_NR_ptrace:
3400 31e31b8a bellard
        goto unimplemented;
3401 7a3148a9 j_mayer
#ifdef TARGET_NR_alarm /* not on alpha */
3402 31e31b8a bellard
    case TARGET_NR_alarm:
3403 31e31b8a bellard
        ret = alarm(arg1);
3404 31e31b8a bellard
        break;
3405 7a3148a9 j_mayer
#endif
3406 ebc05488 bellard
#ifdef TARGET_NR_oldfstat
3407 31e31b8a bellard
    case TARGET_NR_oldfstat:
3408 31e31b8a bellard
        goto unimplemented;
3409 ebc05488 bellard
#endif
3410 7a3148a9 j_mayer
#ifdef TARGET_NR_pause /* not on alpha */
3411 31e31b8a bellard
    case TARGET_NR_pause:
3412 31e31b8a bellard
        ret = get_errno(pause());
3413 31e31b8a bellard
        break;
3414 7a3148a9 j_mayer
#endif
3415 e5febef5 ths
#ifdef TARGET_NR_utime
3416 31e31b8a bellard
    case TARGET_NR_utime:
3417 ebc05488 bellard
        {
3418 53a5960a pbrook
            struct utimbuf tbuf, *host_tbuf;
3419 53a5960a pbrook
            struct target_utimbuf *target_tbuf;
3420 53a5960a pbrook
            if (arg2) {
3421 579a97f7 bellard
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3422 579a97f7 bellard
                    goto efault;
3423 53a5960a pbrook
                tbuf.actime = tswapl(target_tbuf->actime);
3424 53a5960a pbrook
                tbuf.modtime = tswapl(target_tbuf->modtime);
3425 53a5960a pbrook
                unlock_user_struct(target_tbuf, arg2, 0);
3426 53a5960a pbrook
                host_tbuf = &tbuf;
3427 f72e8ff4 bellard
            } else {
3428 53a5960a pbrook
                host_tbuf = NULL;
3429 f72e8ff4 bellard
            }
3430 579a97f7 bellard
            if (!(p = lock_user_string(arg1)))
3431 579a97f7 bellard
                goto efault;
3432 53a5960a pbrook
            ret = get_errno(utime(p, host_tbuf));
3433 53a5960a pbrook
            unlock_user(p, arg1, 0);
3434 ebc05488 bellard
        }
3435 ebc05488 bellard
        break;
3436 e5febef5 ths
#endif
3437 978a66ff bellard
    case TARGET_NR_utimes:
3438 978a66ff bellard
        {
3439 978a66ff bellard
            struct timeval *tvp, tv[2];
3440 53a5960a pbrook
            if (arg2) {
3441 788f5ec4 ths
                if (copy_from_user_timeval(&tv[0], arg2)
3442 788f5ec4 ths
                    || copy_from_user_timeval(&tv[1],
3443 788f5ec4 ths
                                              arg2 + sizeof(struct target_timeval)))
3444 788f5ec4 ths
                    goto efault;
3445 978a66ff bellard
                tvp = tv;
3446 978a66ff bellard
            } else {
3447 978a66ff bellard
                tvp = NULL;
3448 978a66ff bellard
            }
3449 579a97f7 bellard
            if (!(p = lock_user_string(arg1)))
3450 579a97f7 bellard
                goto efault;
3451 53a5960a pbrook
            ret = get_errno(utimes(p, tvp));
3452 53a5960a pbrook
            unlock_user(p, arg1, 0);
3453 978a66ff bellard
        }
3454 978a66ff bellard
        break;
3455 ebc05488 bellard
#ifdef TARGET_NR_stty
3456 31e31b8a bellard
    case TARGET_NR_stty:
3457 31e31b8a bellard
        goto unimplemented;
3458 ebc05488 bellard
#endif
3459 ebc05488 bellard
#ifdef TARGET_NR_gtty
3460 31e31b8a bellard
    case TARGET_NR_gtty:
3461 31e31b8a bellard
        goto unimplemented;
3462 ebc05488 bellard
#endif
3463 31e31b8a bellard
    case TARGET_NR_access:
3464 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3465 579a97f7 bellard
            goto efault;
3466 53a5960a pbrook
        ret = get_errno(access(p, arg2));
3467 53a5960a pbrook
        unlock_user(p, arg1, 0);
3468 31e31b8a bellard
        break;
3469 92a34c10 ths
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3470 92a34c10 ths
    case TARGET_NR_faccessat:
3471 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
3472 579a97f7 bellard
            goto efault;
3473 579a97f7 bellard
        ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3474 579a97f7 bellard
        unlock_user(p, arg2, 0);
3475 92a34c10 ths
        break;
3476 92a34c10 ths
#endif
3477 7a3148a9 j_mayer
#ifdef TARGET_NR_nice /* not on alpha */
3478 31e31b8a bellard
    case TARGET_NR_nice:
3479 31e31b8a bellard
        ret = get_errno(nice(arg1));
3480 31e31b8a bellard
        break;
3481 7a3148a9 j_mayer
#endif
3482 ebc05488 bellard
#ifdef TARGET_NR_ftime
3483 31e31b8a bellard
    case TARGET_NR_ftime:
3484 31e31b8a bellard
        goto unimplemented;
3485 ebc05488 bellard
#endif
3486 31e31b8a bellard
    case TARGET_NR_sync:
3487 04369ff2 bellard
        sync();
3488 04369ff2 bellard
        ret = 0;
3489 31e31b8a bellard
        break;
3490 31e31b8a bellard
    case TARGET_NR_kill:
3491 4cb05961 pbrook
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3492 31e31b8a bellard
        break;
3493 31e31b8a bellard
    case TARGET_NR_rename:
3494 53a5960a pbrook
        {
3495 53a5960a pbrook
            void *p2;
3496 53a5960a pbrook
            p = lock_user_string(arg1);
3497 53a5960a pbrook
            p2 = lock_user_string(arg2);
3498 579a97f7 bellard
            if (!p || !p2)
3499 579a97f7 bellard
                ret = -TARGET_EFAULT;
3500 579a97f7 bellard
            else
3501 579a97f7 bellard
                ret = get_errno(rename(p, p2));
3502 53a5960a pbrook
            unlock_user(p2, arg2, 0);
3503 53a5960a pbrook
            unlock_user(p, arg1, 0);
3504 53a5960a pbrook
        }
3505 31e31b8a bellard
        break;
3506 722183f6 ths
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3507 722183f6 ths
    case TARGET_NR_renameat:
3508 722183f6 ths
        {
3509 579a97f7 bellard
            void *p2;
3510 722183f6 ths
            p  = lock_user_string(arg2);
3511 722183f6 ths
            p2 = lock_user_string(arg4);
3512 579a97f7 bellard
            if (!p || !p2)
3513 0da46a6e ths
                ret = -TARGET_EFAULT;
3514 722183f6 ths
            else
3515 722183f6 ths
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3516 579a97f7 bellard
            unlock_user(p2, arg4, 0);
3517 579a97f7 bellard
            unlock_user(p, arg2, 0);
3518 722183f6 ths
        }
3519 722183f6 ths
        break;
3520 722183f6 ths
#endif
3521 31e31b8a bellard
    case TARGET_NR_mkdir:
3522 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3523 579a97f7 bellard
            goto efault;
3524 53a5960a pbrook
        ret = get_errno(mkdir(p, arg2));
3525 53a5960a pbrook
        unlock_user(p, arg1, 0);
3526 31e31b8a bellard
        break;
3527 4472ad0d ths
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3528 4472ad0d ths
    case TARGET_NR_mkdirat:
3529 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
3530 579a97f7 bellard
            goto efault;
3531 579a97f7 bellard
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
3532 579a97f7 bellard
        unlock_user(p, arg2, 0);
3533 4472ad0d ths
        break;
3534 4472ad0d ths
#endif
3535 31e31b8a bellard
    case TARGET_NR_rmdir:
3536 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3537 579a97f7 bellard
            goto efault;
3538 53a5960a pbrook
        ret = get_errno(rmdir(p));
3539 53a5960a pbrook
        unlock_user(p, arg1, 0);
3540 31e31b8a bellard
        break;
3541 31e31b8a bellard
    case TARGET_NR_dup:
3542 31e31b8a bellard
        ret = get_errno(dup(arg1));
3543 31e31b8a bellard
        break;
3544 31e31b8a bellard
    case TARGET_NR_pipe:
3545 31e31b8a bellard
        {
3546 53a5960a pbrook
            int host_pipe[2];
3547 53a5960a pbrook
            ret = get_errno(pipe(host_pipe));
3548 31e31b8a bellard
            if (!is_error(ret)) {
3549 c12ab05c ths
#if defined(TARGET_MIPS)
3550 ead9360e ths
                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3551 d0dc7dc3 ths
                env->gpr[env->current_tc][3] = host_pipe[1];
3552 c12ab05c ths
                ret = host_pipe[0];
3553 b5eff355 aurel32
#elif defined(TARGET_SH4)
3554 b5eff355 aurel32
                ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3555 b5eff355 aurel32
                ret = host_pipe[0];
3556 c12ab05c ths
#else
3557 2f619698 bellard
                if (put_user_s32(host_pipe[0], arg1)
3558 2f619698 bellard
                    || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3559 2f619698 bellard
                    goto efault;
3560 c12ab05c ths
#endif
3561 31e31b8a bellard
            }
3562 31e31b8a bellard
        }
3563 31e31b8a bellard
        break;
3564 31e31b8a bellard
    case TARGET_NR_times:
3565 32f36bce bellard
        {
3566 53a5960a pbrook
            struct target_tms *tmsp;
3567 32f36bce bellard
            struct tms tms;
3568 32f36bce bellard
            ret = get_errno(times(&tms));
3569 53a5960a pbrook
            if (arg1) {
3570 579a97f7 bellard
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3571 579a97f7 bellard
                if (!tmsp)
3572 579a97f7 bellard
                    goto efault;
3573 c596ed17 bellard
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3574 c596ed17 bellard
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3575 c596ed17 bellard
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3576 c596ed17 bellard
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3577 32f36bce bellard
            }
3578 c596ed17 bellard
            if (!is_error(ret))
3579 c596ed17 bellard
                ret = host_to_target_clock_t(ret);
3580 32f36bce bellard
        }
3581 32f36bce bellard
        break;
3582 ebc05488 bellard
#ifdef TARGET_NR_prof
3583 31e31b8a bellard
    case TARGET_NR_prof:
3584 31e31b8a bellard
        goto unimplemented;
3585 ebc05488 bellard
#endif
3586 e5febef5 ths
#ifdef TARGET_NR_signal
3587 31e31b8a bellard
    case TARGET_NR_signal:
3588 31e31b8a bellard
        goto unimplemented;
3589 e5febef5 ths
#endif
3590 31e31b8a bellard
    case TARGET_NR_acct:
3591 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3592 579a97f7 bellard
            goto efault;
3593 24836689 pbrook
        ret = get_errno(acct(path(p)));
3594 24836689 pbrook
        unlock_user(p, arg1, 0);
3595 24836689 pbrook
        break;
3596 7a3148a9 j_mayer
#ifdef TARGET_NR_umount2 /* not on alpha */
3597 31e31b8a bellard
    case TARGET_NR_umount2:
3598 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3599 579a97f7 bellard
            goto efault;
3600 53a5960a pbrook
        ret = get_errno(umount2(p, arg2));
3601 53a5960a pbrook
        unlock_user(p, arg1, 0);
3602 31e31b8a bellard
        break;
3603 7a3148a9 j_mayer
#endif
3604 ebc05488 bellard
#ifdef TARGET_NR_lock
3605 31e31b8a bellard
    case TARGET_NR_lock:
3606 31e31b8a bellard
        goto unimplemented;
3607 ebc05488 bellard
#endif
3608 31e31b8a bellard
    case TARGET_NR_ioctl:
3609 31e31b8a bellard
        ret = do_ioctl(arg1, arg2, arg3);
3610 31e31b8a bellard
        break;
3611 31e31b8a bellard
    case TARGET_NR_fcntl:
3612 9ee1fa2c bellard
        ret = do_fcntl(arg1, arg2, arg3);
3613 31e31b8a bellard
        break;
3614 ebc05488 bellard
#ifdef TARGET_NR_mpx
3615 31e31b8a bellard
    case TARGET_NR_mpx:
3616 31e31b8a bellard
        goto unimplemented;
3617 ebc05488 bellard
#endif
3618 31e31b8a bellard
    case TARGET_NR_setpgid:
3619 31e31b8a bellard
        ret = get_errno(setpgid(arg1, arg2));
3620 31e31b8a bellard
        break;
3621 ebc05488 bellard
#ifdef TARGET_NR_ulimit
3622 31e31b8a bellard
    case TARGET_NR_ulimit:
3623 31e31b8a bellard
        goto unimplemented;
3624 ebc05488 bellard
#endif
3625 ebc05488 bellard
#ifdef TARGET_NR_oldolduname
3626 31e31b8a bellard
    case TARGET_NR_oldolduname:
3627 31e31b8a bellard
        goto unimplemented;
3628 ebc05488 bellard
#endif
3629 31e31b8a bellard
    case TARGET_NR_umask:
3630 31e31b8a bellard
        ret = get_errno(umask(arg1));
3631 31e31b8a bellard
        break;
3632 31e31b8a bellard
    case TARGET_NR_chroot:
3633 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3634 579a97f7 bellard
            goto efault;
3635 53a5960a pbrook
        ret = get_errno(chroot(p));
3636 53a5960a pbrook
        unlock_user(p, arg1, 0);
3637 31e31b8a bellard
        break;
3638 31e31b8a bellard
    case TARGET_NR_ustat:
3639 31e31b8a bellard
        goto unimplemented;
3640 31e31b8a bellard
    case TARGET_NR_dup2:
3641 31e31b8a bellard
        ret = get_errno(dup2(arg1, arg2));
3642 31e31b8a bellard
        break;
3643 7a3148a9 j_mayer
#ifdef TARGET_NR_getppid /* not on alpha */
3644 31e31b8a bellard
    case TARGET_NR_getppid:
3645 31e31b8a bellard
        ret = get_errno(getppid());
3646 31e31b8a bellard
        break;
3647 7a3148a9 j_mayer
#endif
3648 31e31b8a bellard
    case TARGET_NR_getpgrp:
3649 31e31b8a bellard
        ret = get_errno(getpgrp());
3650 31e31b8a bellard
        break;
3651 31e31b8a bellard
    case TARGET_NR_setsid:
3652 31e31b8a bellard
        ret = get_errno(setsid());
3653 31e31b8a bellard
        break;
3654 e5febef5 ths
#ifdef TARGET_NR_sigaction
3655 31e31b8a bellard
    case TARGET_NR_sigaction:
3656 31e31b8a bellard
        {
3657 388bb21a ths
#if !defined(TARGET_MIPS)
3658 53a5960a pbrook
            struct target_old_sigaction *old_act;
3659 66fb9763 bellard
            struct target_sigaction act, oact, *pact;
3660 53a5960a pbrook
            if (arg2) {
3661 579a97f7 bellard
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3662 579a97f7 bellard
                    goto efault;
3663 66fb9763 bellard
                act._sa_handler = old_act->_sa_handler;
3664 66fb9763 bellard
                target_siginitset(&act.sa_mask, old_act->sa_mask);
3665 66fb9763 bellard
                act.sa_flags = old_act->sa_flags;
3666 66fb9763 bellard
                act.sa_restorer = old_act->sa_restorer;
3667 53a5960a pbrook
                unlock_user_struct(old_act, arg2, 0);
3668 66fb9763 bellard
                pact = &act;
3669 66fb9763 bellard
            } else {
3670 66fb9763 bellard
                pact = NULL;
3671 66fb9763 bellard
            }
3672 66fb9763 bellard
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3673 53a5960a pbrook
            if (!is_error(ret) && arg3) {
3674 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3675 579a97f7 bellard
                    goto efault;
3676 53a5960a pbrook
                old_act->_sa_handler = oact._sa_handler;
3677 53a5960a pbrook
                old_act->sa_mask = oact.sa_mask.sig[0];
3678 53a5960a pbrook
                old_act->sa_flags = oact.sa_flags;
3679 53a5960a pbrook
                old_act->sa_restorer = oact.sa_restorer;
3680 53a5960a pbrook
                unlock_user_struct(old_act, arg3, 1);
3681 66fb9763 bellard
            }
3682 388bb21a ths
#else
3683 106ec879 bellard
            struct target_sigaction act, oact, *pact, *old_act;
3684 106ec879 bellard
3685 106ec879 bellard
            if (arg2) {
3686 579a97f7 bellard
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3687 579a97f7 bellard
                    goto efault;
3688 106ec879 bellard
                act._sa_handler = old_act->_sa_handler;
3689 106ec879 bellard
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3690 106ec879 bellard
                act.sa_flags = old_act->sa_flags;
3691 106ec879 bellard
                unlock_user_struct(old_act, arg2, 0);
3692 106ec879 bellard
                pact = &act;
3693 106ec879 bellard
            } else {
3694 106ec879 bellard
                pact = NULL;
3695 106ec879 bellard
            }
3696 106ec879 bellard
3697 106ec879 bellard
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3698 106ec879 bellard
3699 106ec879 bellard
            if (!is_error(ret) && arg3) {
3700 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3701 579a97f7 bellard
                    goto efault;
3702 106ec879 bellard
                old_act->_sa_handler = oact._sa_handler;
3703 106ec879 bellard
                old_act->sa_flags = oact.sa_flags;
3704 106ec879 bellard
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
3705 106ec879 bellard
                old_act->sa_mask.sig[1] = 0;
3706 106ec879 bellard
                old_act->sa_mask.sig[2] = 0;
3707 106ec879 bellard
                old_act->sa_mask.sig[3] = 0;
3708 106ec879 bellard
                unlock_user_struct(old_act, arg3, 1);
3709 106ec879 bellard
            }
3710 388bb21a ths
#endif
3711 31e31b8a bellard
        }
3712 31e31b8a bellard
        break;
3713 e5febef5 ths
#endif
3714 66fb9763 bellard
    case TARGET_NR_rt_sigaction:
3715 53a5960a pbrook
        {
3716 53a5960a pbrook
            struct target_sigaction *act;
3717 53a5960a pbrook
            struct target_sigaction *oact;
3718 53a5960a pbrook
3719 579a97f7 bellard
            if (arg2) {
3720 579a97f7 bellard
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
3721 579a97f7 bellard
                    goto efault;
3722 579a97f7 bellard
            } else
3723 53a5960a pbrook
                act = NULL;
3724 579a97f7 bellard
            if (arg3) {
3725 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
3726 579a97f7 bellard
                    ret = -TARGET_EFAULT;
3727 579a97f7 bellard
                    goto rt_sigaction_fail;
3728 579a97f7 bellard
                }
3729 579a97f7 bellard
            } else
3730 53a5960a pbrook
                oact = NULL;
3731 53a5960a pbrook
            ret = get_errno(do_sigaction(arg1, act, oact));
3732 579a97f7 bellard
        rt_sigaction_fail:
3733 579a97f7 bellard
            if (act)
3734 53a5960a pbrook
                unlock_user_struct(act, arg2, 0);
3735 579a97f7 bellard
            if (oact)
3736 53a5960a pbrook
                unlock_user_struct(oact, arg3, 1);
3737 53a5960a pbrook
        }
3738 66fb9763 bellard
        break;
3739 7a3148a9 j_mayer
#ifdef TARGET_NR_sgetmask /* not on alpha */
3740 31e31b8a bellard
    case TARGET_NR_sgetmask:
3741 66fb9763 bellard
        {
3742 66fb9763 bellard
            sigset_t cur_set;
3743 992f48a0 blueswir1
            abi_ulong target_set;
3744 66fb9763 bellard
            sigprocmask(0, NULL, &cur_set);
3745 66fb9763 bellard
            host_to_target_old_sigset(&target_set, &cur_set);
3746 66fb9763 bellard
            ret = target_set;
3747 66fb9763 bellard
        }
3748 66fb9763 bellard
        break;
3749 7a3148a9 j_mayer
#endif
3750 7a3148a9 j_mayer
#ifdef TARGET_NR_ssetmask /* not on alpha */
3751 31e31b8a bellard
    case TARGET_NR_ssetmask:
3752 66fb9763 bellard
        {
3753 66fb9763 bellard
            sigset_t set, oset, cur_set;
3754 992f48a0 blueswir1
            abi_ulong target_set = arg1;
3755 66fb9763 bellard
            sigprocmask(0, NULL, &cur_set);
3756 66fb9763 bellard
            target_to_host_old_sigset(&set, &target_set);
3757 66fb9763 bellard
            sigorset(&set, &set, &cur_set);
3758 66fb9763 bellard
            sigprocmask(SIG_SETMASK, &set, &oset);
3759 66fb9763 bellard
            host_to_target_old_sigset(&target_set, &oset);
3760 66fb9763 bellard
            ret = target_set;
3761 66fb9763 bellard
        }
3762 66fb9763 bellard
        break;
3763 7a3148a9 j_mayer
#endif
3764 e5febef5 ths
#ifdef TARGET_NR_sigprocmask
3765 66fb9763 bellard
    case TARGET_NR_sigprocmask:
3766 66fb9763 bellard
        {
3767 66fb9763 bellard
            int how = arg1;
3768 66fb9763 bellard
            sigset_t set, oldset, *set_ptr;
3769 3b46e624 ths
3770 53a5960a pbrook
            if (arg2) {
3771 66fb9763 bellard
                switch(how) {
3772 66fb9763 bellard
                case TARGET_SIG_BLOCK:
3773 66fb9763 bellard
                    how = SIG_BLOCK;
3774 66fb9763 bellard
                    break;
3775 66fb9763 bellard
                case TARGET_SIG_UNBLOCK:
3776 66fb9763 bellard
                    how = SIG_UNBLOCK;
3777 66fb9763 bellard
                    break;
3778 66fb9763 bellard
                case TARGET_SIG_SETMASK:
3779 66fb9763 bellard
                    how = SIG_SETMASK;
3780 66fb9763 bellard
                    break;
3781 66fb9763 bellard
                default:
3782 0da46a6e ths
                    ret = -TARGET_EINVAL;
3783 66fb9763 bellard
                    goto fail;
3784 66fb9763 bellard
                }
3785 579a97f7 bellard
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3786 579a97f7 bellard
                    goto efault;
3787 53a5960a pbrook
                target_to_host_old_sigset(&set, p);
3788 53a5960a pbrook
                unlock_user(p, arg2, 0);
3789 66fb9763 bellard
                set_ptr = &set;
3790 66fb9763 bellard
            } else {
3791 66fb9763 bellard
                how = 0;
3792 66fb9763 bellard
                set_ptr = NULL;
3793 66fb9763 bellard
            }
3794 66fb9763 bellard
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
3795 53a5960a pbrook
            if (!is_error(ret) && arg3) {
3796 579a97f7 bellard
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
3797 579a97f7 bellard
                    goto efault;
3798 53a5960a pbrook
                host_to_target_old_sigset(p, &oldset);
3799 53a5960a pbrook
                unlock_user(p, arg3, sizeof(target_sigset_t));
3800 66fb9763 bellard
            }
3801 66fb9763 bellard
        }
3802 66fb9763 bellard
        break;
3803 e5febef5 ths
#endif
3804 66fb9763 bellard
    case TARGET_NR_rt_sigprocmask:
3805 66fb9763 bellard
        {
3806 66fb9763 bellard
            int how = arg1;
3807 66fb9763 bellard
            sigset_t set, oldset, *set_ptr;
3808 3b46e624 ths
3809 53a5960a pbrook
            if (arg2) {
3810 66fb9763 bellard
                switch(how) {
3811 66fb9763 bellard
                case TARGET_SIG_BLOCK:
3812 66fb9763 bellard
                    how = SIG_BLOCK;
3813 66fb9763 bellard
                    break;
3814 66fb9763 bellard
                case TARGET_SIG_UNBLOCK:
3815 66fb9763 bellard
                    how = SIG_UNBLOCK;
3816 66fb9763 bellard
                    break;
3817 66fb9763 bellard
                case TARGET_SIG_SETMASK:
3818 66fb9763 bellard
                    how = SIG_SETMASK;
3819 66fb9763 bellard
                    break;
3820 66fb9763 bellard
                default:
3821 0da46a6e ths
                    ret = -TARGET_EINVAL;
3822 66fb9763 bellard
                    goto fail;
3823 66fb9763 bellard
                }
3824 579a97f7 bellard
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3825 579a97f7 bellard
                    goto efault;
3826 53a5960a pbrook
                target_to_host_sigset(&set, p);
3827 53a5960a pbrook
                unlock_user(p, arg2, 0);
3828 66fb9763 bellard
                set_ptr = &set;
3829 66fb9763 bellard
            } else {
3830 66fb9763 bellard
                how = 0;
3831 66fb9763 bellard
                set_ptr = NULL;
3832 66fb9763 bellard
            }
3833 66fb9763 bellard
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
3834 53a5960a pbrook
            if (!is_error(ret) && arg3) {
3835 579a97f7 bellard
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
3836 579a97f7 bellard
                    goto efault;
3837 53a5960a pbrook
                host_to_target_sigset(p, &oldset);
3838 53a5960a pbrook
                unlock_user(p, arg3, sizeof(target_sigset_t));
3839 66fb9763 bellard
            }
3840 66fb9763 bellard
        }
3841 66fb9763 bellard
        break;
3842 e5febef5 ths
#ifdef TARGET_NR_sigpending
3843 66fb9763 bellard
    case TARGET_NR_sigpending:
3844 66fb9763 bellard
        {
3845 66fb9763 bellard
            sigset_t set;
3846 66fb9763 bellard
            ret = get_errno(sigpending(&set));
3847 66fb9763 bellard
            if (!is_error(ret)) {
3848 579a97f7 bellard
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
3849 579a97f7 bellard
                    goto efault;
3850 53a5960a pbrook
                host_to_target_old_sigset(p, &set);
3851 53a5960a pbrook
                unlock_user(p, arg1, sizeof(target_sigset_t));
3852 66fb9763 bellard
            }
3853 66fb9763 bellard
        }
3854 66fb9763 bellard
        break;
3855 e5febef5 ths
#endif
3856 66fb9763 bellard
    case TARGET_NR_rt_sigpending:
3857 66fb9763 bellard
        {
3858 66fb9763 bellard
            sigset_t set;
3859 66fb9763 bellard
            ret = get_errno(sigpending(&set));
3860 66fb9763 bellard
            if (!is_error(ret)) {
3861 579a97f7 bellard
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
3862 579a97f7 bellard
                    goto efault;
3863 53a5960a pbrook
                host_to_target_sigset(p, &set);
3864 53a5960a pbrook
                unlock_user(p, arg1, sizeof(target_sigset_t));
3865 66fb9763 bellard
            }
3866 66fb9763 bellard
        }
3867 66fb9763 bellard
        break;
3868 e5febef5 ths
#ifdef TARGET_NR_sigsuspend
3869 66fb9763 bellard
    case TARGET_NR_sigsuspend:
3870 66fb9763 bellard
        {
3871 66fb9763 bellard
            sigset_t set;
3872 579a97f7 bellard
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
3873 579a97f7 bellard
                goto efault;
3874 53a5960a pbrook
            target_to_host_old_sigset(&set, p);
3875 53a5960a pbrook
            unlock_user(p, arg1, 0);
3876 66fb9763 bellard
            ret = get_errno(sigsuspend(&set));
3877 66fb9763 bellard
        }
3878 66fb9763 bellard
        break;
3879 e5febef5 ths
#endif
3880 66fb9763 bellard
    case TARGET_NR_rt_sigsuspend:
3881 66fb9763 bellard
        {
3882 66fb9763 bellard
            sigset_t set;
3883 579a97f7 bellard
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
3884 579a97f7 bellard
                goto efault;
3885 53a5960a pbrook
            target_to_host_sigset(&set, p);
3886 53a5960a pbrook
            unlock_user(p, arg1, 0);
3887 66fb9763 bellard
            ret = get_errno(sigsuspend(&set));
3888 66fb9763 bellard
        }
3889 66fb9763 bellard
        break;
3890 66fb9763 bellard
    case TARGET_NR_rt_sigtimedwait:
3891 66fb9763 bellard
        {
3892 66fb9763 bellard
            sigset_t set;
3893 66fb9763 bellard
            struct timespec uts, *puts;
3894 66fb9763 bellard
            siginfo_t uinfo;
3895 3b46e624 ths
3896 579a97f7 bellard
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
3897 579a97f7 bellard
                goto efault;
3898 53a5960a pbrook
            target_to_host_sigset(&set, p);
3899 53a5960a pbrook
            unlock_user(p, arg1, 0);
3900 53a5960a pbrook
            if (arg3) {
3901 66fb9763 bellard
                puts = &uts;
3902 53a5960a pbrook
                target_to_host_timespec(puts, arg3);
3903 66fb9763 bellard
            } else {
3904 66fb9763 bellard
                puts = NULL;
3905 66fb9763 bellard
            }
3906 66fb9763 bellard
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
3907 53a5960a pbrook
            if (!is_error(ret) && arg2) {
3908 579a97f7 bellard
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_sigset_t), 0)))
3909 579a97f7 bellard
                    goto efault;
3910 53a5960a pbrook
                host_to_target_siginfo(p, &uinfo);
3911 53a5960a pbrook
                unlock_user(p, arg2, sizeof(target_sigset_t));
3912 66fb9763 bellard
            }
3913 66fb9763 bellard
        }
3914 66fb9763 bellard
        break;
3915 66fb9763 bellard
    case TARGET_NR_rt_sigqueueinfo:
3916 66fb9763 bellard
        {
3917 66fb9763 bellard
            siginfo_t uinfo;
3918 579a97f7 bellard
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
3919 579a97f7 bellard
                goto efault;
3920 53a5960a pbrook
            target_to_host_siginfo(&uinfo, p);
3921 53a5960a pbrook
            unlock_user(p, arg1, 0);
3922 66fb9763 bellard
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
3923 66fb9763 bellard
        }
3924 66fb9763 bellard
        break;
3925 e5febef5 ths
#ifdef TARGET_NR_sigreturn
3926 66fb9763 bellard
    case TARGET_NR_sigreturn:
3927 66fb9763 bellard
        /* NOTE: ret is eax, so not transcoding must be done */
3928 66fb9763 bellard
        ret = do_sigreturn(cpu_env);
3929 66fb9763 bellard
        break;
3930 e5febef5 ths
#endif
3931 66fb9763 bellard
    case TARGET_NR_rt_sigreturn:
3932 66fb9763 bellard
        /* NOTE: ret is eax, so not transcoding must be done */
3933 66fb9763 bellard
        ret = do_rt_sigreturn(cpu_env);
3934 66fb9763 bellard
        break;
3935 31e31b8a bellard
    case TARGET_NR_sethostname:
3936 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
3937 579a97f7 bellard
            goto efault;
3938 53a5960a pbrook
        ret = get_errno(sethostname(p, arg2));
3939 53a5960a pbrook
        unlock_user(p, arg1, 0);
3940 31e31b8a bellard
        break;
3941 31e31b8a bellard
    case TARGET_NR_setrlimit:
3942 9de5e440 bellard
        {
3943 9de5e440 bellard
            /* XXX: convert resource ? */
3944 9de5e440 bellard
            int resource = arg1;
3945 53a5960a pbrook
            struct target_rlimit *target_rlim;
3946 9de5e440 bellard
            struct rlimit rlim;
3947 579a97f7 bellard
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
3948 579a97f7 bellard
                goto efault;
3949 9de5e440 bellard
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
3950 9de5e440 bellard
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
3951 53a5960a pbrook
            unlock_user_struct(target_rlim, arg2, 0);
3952 9de5e440 bellard
            ret = get_errno(setrlimit(resource, &rlim));
3953 9de5e440 bellard
        }
3954 9de5e440 bellard
        break;
3955 31e31b8a bellard
    case TARGET_NR_getrlimit:
3956 9de5e440 bellard
        {
3957 9de5e440 bellard
            /* XXX: convert resource ? */
3958 9de5e440 bellard
            int resource = arg1;
3959 53a5960a pbrook
            struct target_rlimit *target_rlim;
3960 9de5e440 bellard
            struct rlimit rlim;
3961 3b46e624 ths
3962 9de5e440 bellard
            ret = get_errno(getrlimit(resource, &rlim));
3963 9de5e440 bellard
            if (!is_error(ret)) {
3964 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
3965 579a97f7 bellard
                    goto efault;
3966 53a5960a pbrook
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
3967 53a5960a pbrook
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
3968 53a5960a pbrook
                unlock_user_struct(target_rlim, arg2, 1);
3969 9de5e440 bellard
            }
3970 9de5e440 bellard
        }
3971 9de5e440 bellard
        break;
3972 31e31b8a bellard
    case TARGET_NR_getrusage:
3973 b409186b bellard
        {
3974 b409186b bellard
            struct rusage rusage;
3975 b409186b bellard
            ret = get_errno(getrusage(arg1, &rusage));
3976 b409186b bellard
            if (!is_error(ret)) {
3977 53a5960a pbrook
                host_to_target_rusage(arg2, &rusage);
3978 b409186b bellard
            }
3979 b409186b bellard
        }
3980 b409186b bellard
        break;
3981 31e31b8a bellard
    case TARGET_NR_gettimeofday:
3982 31e31b8a bellard
        {
3983 31e31b8a bellard
            struct timeval tv;
3984 31e31b8a bellard
            ret = get_errno(gettimeofday(&tv, NULL));
3985 31e31b8a bellard
            if (!is_error(ret)) {
3986 788f5ec4 ths
                if (copy_to_user_timeval(arg1, &tv))
3987 788f5ec4 ths
                    goto efault;
3988 31e31b8a bellard
            }
3989 31e31b8a bellard
        }
3990 31e31b8a bellard
        break;
3991 31e31b8a bellard
    case TARGET_NR_settimeofday:
3992 31e31b8a bellard
        {
3993 31e31b8a bellard
            struct timeval tv;
3994 788f5ec4 ths
            if (copy_from_user_timeval(&tv, arg1))
3995 788f5ec4 ths
                goto efault;
3996 31e31b8a bellard
            ret = get_errno(settimeofday(&tv, NULL));
3997 31e31b8a bellard
        }
3998 31e31b8a bellard
        break;
3999 048f6b4d bellard
#ifdef TARGET_NR_select
4000 31e31b8a bellard
    case TARGET_NR_select:
4001 f2674e31 bellard
        {
4002 53a5960a pbrook
            struct target_sel_arg_struct *sel;
4003 992f48a0 blueswir1
            abi_ulong inp, outp, exp, tvp;
4004 53a5960a pbrook
            long nsel;
4005 53a5960a pbrook
4006 579a97f7 bellard
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4007 579a97f7 bellard
                goto efault;
4008 53a5960a pbrook
            nsel = tswapl(sel->n);
4009 53a5960a pbrook
            inp = tswapl(sel->inp);
4010 53a5960a pbrook
            outp = tswapl(sel->outp);
4011 53a5960a pbrook
            exp = tswapl(sel->exp);
4012 53a5960a pbrook
            tvp = tswapl(sel->tvp);
4013 53a5960a pbrook
            unlock_user_struct(sel, arg1, 0);
4014 53a5960a pbrook
            ret = do_select(nsel, inp, outp, exp, tvp);
4015 f2674e31 bellard
        }
4016 f2674e31 bellard
        break;
4017 048f6b4d bellard
#endif
4018 31e31b8a bellard
    case TARGET_NR_symlink:
4019 53a5960a pbrook
        {
4020 53a5960a pbrook
            void *p2;
4021 53a5960a pbrook
            p = lock_user_string(arg1);
4022 53a5960a pbrook
            p2 = lock_user_string(arg2);
4023 579a97f7 bellard
            if (!p || !p2)
4024 579a97f7 bellard
                ret = -TARGET_EFAULT;
4025 579a97f7 bellard
            else
4026 579a97f7 bellard
                ret = get_errno(symlink(p, p2));
4027 53a5960a pbrook
            unlock_user(p2, arg2, 0);
4028 53a5960a pbrook
            unlock_user(p, arg1, 0);
4029 53a5960a pbrook
        }
4030 31e31b8a bellard
        break;
4031 f0b6243d ths
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4032 f0b6243d ths
    case TARGET_NR_symlinkat:
4033 f0b6243d ths
        {
4034 579a97f7 bellard
            void *p2;
4035 f0b6243d ths
            p  = lock_user_string(arg1);
4036 f0b6243d ths
            p2 = lock_user_string(arg3);
4037 579a97f7 bellard
            if (!p || !p2)
4038 0da46a6e ths
                ret = -TARGET_EFAULT;
4039 f0b6243d ths
            else
4040 f0b6243d ths
                ret = get_errno(sys_symlinkat(p, arg2, p2));
4041 579a97f7 bellard
            unlock_user(p2, arg3, 0);
4042 579a97f7 bellard
            unlock_user(p, arg1, 0);
4043 f0b6243d ths
        }
4044 f0b6243d ths
        break;
4045 f0b6243d ths
#endif
4046 ebc05488 bellard
#ifdef TARGET_NR_oldlstat
4047 31e31b8a bellard
    case TARGET_NR_oldlstat:
4048 31e31b8a bellard
        goto unimplemented;
4049 ebc05488 bellard
#endif
4050 31e31b8a bellard
    case TARGET_NR_readlink:
4051 53a5960a pbrook
        {
4052 53a5960a pbrook
            void *p2;
4053 53a5960a pbrook
            p = lock_user_string(arg1);
4054 579a97f7 bellard
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4055 579a97f7 bellard
            if (!p || !p2)
4056 579a97f7 bellard
                ret = -TARGET_EFAULT;
4057 579a97f7 bellard
            else
4058 579a97f7 bellard
                ret = get_errno(readlink(path(p), p2, arg3));
4059 53a5960a pbrook
            unlock_user(p2, arg2, ret);
4060 53a5960a pbrook
            unlock_user(p, arg1, 0);
4061 53a5960a pbrook
        }
4062 31e31b8a bellard
        break;
4063 5e0ccb18 ths
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4064 5e0ccb18 ths
    case TARGET_NR_readlinkat:
4065 5e0ccb18 ths
        {
4066 579a97f7 bellard
            void *p2;
4067 5e0ccb18 ths
            p  = lock_user_string(arg2);
4068 579a97f7 bellard
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4069 579a97f7 bellard
            if (!p || !p2)
4070 0da46a6e ths
                ret = -TARGET_EFAULT;
4071 5e0ccb18 ths
            else
4072 5e0ccb18 ths
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4073 579a97f7 bellard
            unlock_user(p2, arg3, ret);
4074 579a97f7 bellard
            unlock_user(p, arg2, 0);
4075 5e0ccb18 ths
        }
4076 5e0ccb18 ths
        break;
4077 5e0ccb18 ths
#endif
4078 e5febef5 ths
#ifdef TARGET_NR_uselib
4079 31e31b8a bellard
    case TARGET_NR_uselib:
4080 31e31b8a bellard
        goto unimplemented;
4081 e5febef5 ths
#endif
4082 e5febef5 ths
#ifdef TARGET_NR_swapon
4083 31e31b8a bellard
    case TARGET_NR_swapon:
4084 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4085 579a97f7 bellard
            goto efault;
4086 53a5960a pbrook
        ret = get_errno(swapon(p, arg2));
4087 53a5960a pbrook
        unlock_user(p, arg1, 0);
4088 31e31b8a bellard
        break;
4089 e5febef5 ths
#endif
4090 31e31b8a bellard
    case TARGET_NR_reboot:
4091 31e31b8a bellard
        goto unimplemented;
4092 e5febef5 ths
#ifdef TARGET_NR_readdir
4093 31e31b8a bellard
    case TARGET_NR_readdir:
4094 31e31b8a bellard
        goto unimplemented;
4095 e5febef5 ths
#endif
4096 e5febef5 ths
#ifdef TARGET_NR_mmap
4097 31e31b8a bellard
    case TARGET_NR_mmap:
4098 d2fd1af7 bellard
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4099 31e31b8a bellard
        {
4100 992f48a0 blueswir1
            abi_ulong *v;
4101 992f48a0 blueswir1
            abi_ulong v1, v2, v3, v4, v5, v6;
4102 579a97f7 bellard
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4103 579a97f7 bellard
                goto efault;
4104 53a5960a pbrook
            v1 = tswapl(v[0]);
4105 53a5960a pbrook
            v2 = tswapl(v[1]);
4106 53a5960a pbrook
            v3 = tswapl(v[2]);
4107 53a5960a pbrook
            v4 = tswapl(v[3]);
4108 53a5960a pbrook
            v5 = tswapl(v[4]);
4109 53a5960a pbrook
            v6 = tswapl(v[5]);
4110 53a5960a pbrook
            unlock_user(v, arg1, 0);
4111 5fafdf24 ths
            ret = get_errno(target_mmap(v1, v2, v3,
4112 5286db75 bellard
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
4113 5286db75 bellard
                                        v5, v6));
4114 31e31b8a bellard
        }
4115 31e31b8a bellard
#else
4116 5fafdf24 ths
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4117 5fafdf24 ths
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4118 6fb883e8 bellard
                                    arg5,
4119 6fb883e8 bellard
                                    arg6));
4120 31e31b8a bellard
#endif
4121 6fb883e8 bellard
        break;
4122 e5febef5 ths
#endif
4123 a315a145 bellard
#ifdef TARGET_NR_mmap2
4124 6fb883e8 bellard
    case TARGET_NR_mmap2:
4125 bb7ec043 pbrook
#ifndef MMAP_SHIFT
4126 c573ff67 bellard
#define MMAP_SHIFT 12
4127 c573ff67 bellard
#endif
4128 5fafdf24 ths
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4129 5fafdf24 ths
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4130 5286db75 bellard
                                    arg5,
4131 c573ff67 bellard
                                    arg6 << MMAP_SHIFT));
4132 31e31b8a bellard
        break;
4133 a315a145 bellard
#endif
4134 31e31b8a bellard
    case TARGET_NR_munmap:
4135 54936004 bellard
        ret = get_errno(target_munmap(arg1, arg2));
4136 31e31b8a bellard
        break;
4137 9de5e440 bellard
    case TARGET_NR_mprotect:
4138 54936004 bellard
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
4139 9de5e440 bellard
        break;
4140 e5febef5 ths
#ifdef TARGET_NR_mremap
4141 9de5e440 bellard
    case TARGET_NR_mremap:
4142 54936004 bellard
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4143 9de5e440 bellard
        break;
4144 e5febef5 ths
#endif
4145 53a5960a pbrook
        /* ??? msync/mlock/munlock are broken for softmmu.  */
4146 e5febef5 ths
#ifdef TARGET_NR_msync
4147 9de5e440 bellard
    case TARGET_NR_msync:
4148 53a5960a pbrook
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
4149 9de5e440 bellard
        break;
4150 e5febef5 ths
#endif
4151 e5febef5 ths
#ifdef TARGET_NR_mlock
4152 9de5e440 bellard
    case TARGET_NR_mlock:
4153 53a5960a pbrook
        ret = get_errno(mlock(g2h(arg1), arg2));
4154 9de5e440 bellard
        break;
4155 e5febef5 ths
#endif
4156 e5febef5 ths
#ifdef TARGET_NR_munlock
4157 9de5e440 bellard
    case TARGET_NR_munlock:
4158 53a5960a pbrook
        ret = get_errno(munlock(g2h(arg1), arg2));
4159 9de5e440 bellard
        break;
4160 e5febef5 ths
#endif
4161 e5febef5 ths
#ifdef TARGET_NR_mlockall
4162 9de5e440 bellard
    case TARGET_NR_mlockall:
4163 9de5e440 bellard
        ret = get_errno(mlockall(arg1));
4164 9de5e440 bellard
        break;
4165 e5febef5 ths
#endif
4166 e5febef5 ths
#ifdef TARGET_NR_munlockall
4167 9de5e440 bellard
    case TARGET_NR_munlockall:
4168 9de5e440 bellard
        ret = get_errno(munlockall());
4169 9de5e440 bellard
        break;
4170 e5febef5 ths
#endif
4171 31e31b8a bellard
    case TARGET_NR_truncate:
4172 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4173 579a97f7 bellard
            goto efault;
4174 53a5960a pbrook
        ret = get_errno(truncate(p, arg2));
4175 53a5960a pbrook
        unlock_user(p, arg1, 0);
4176 31e31b8a bellard
        break;
4177 31e31b8a bellard
    case TARGET_NR_ftruncate:
4178 31e31b8a bellard
        ret = get_errno(ftruncate(arg1, arg2));
4179 31e31b8a bellard
        break;
4180 31e31b8a bellard
    case TARGET_NR_fchmod:
4181 31e31b8a bellard
        ret = get_errno(fchmod(arg1, arg2));
4182 31e31b8a bellard
        break;
4183 814d7977 ths
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4184 814d7977 ths
    case TARGET_NR_fchmodat:
4185 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
4186 579a97f7 bellard
            goto efault;
4187 579a97f7 bellard
        ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4188 579a97f7 bellard
        unlock_user(p, arg2, 0);
4189 814d7977 ths
        break;
4190 814d7977 ths
#endif
4191 31e31b8a bellard
    case TARGET_NR_getpriority:
4192 c6cda17a ths
        /* libc does special remapping of the return value of
4193 c6cda17a ths
         * sys_getpriority() so it's just easiest to call
4194 c6cda17a ths
         * sys_getpriority() directly rather than through libc. */
4195 c6cda17a ths
        ret = sys_getpriority(arg1, arg2);
4196 31e31b8a bellard
        break;
4197 31e31b8a bellard
    case TARGET_NR_setpriority:
4198 31e31b8a bellard
        ret = get_errno(setpriority(arg1, arg2, arg3));
4199 31e31b8a bellard
        break;
4200 ebc05488 bellard
#ifdef TARGET_NR_profil
4201 31e31b8a bellard
    case TARGET_NR_profil:
4202 31e31b8a bellard
        goto unimplemented;
4203 ebc05488 bellard
#endif
4204 31e31b8a bellard
    case TARGET_NR_statfs:
4205 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4206 579a97f7 bellard
            goto efault;
4207 53a5960a pbrook
        ret = get_errno(statfs(path(p), &stfs));
4208 53a5960a pbrook
        unlock_user(p, arg1, 0);
4209 31e31b8a bellard
    convert_statfs:
4210 31e31b8a bellard
        if (!is_error(ret)) {
4211 53a5960a pbrook
            struct target_statfs *target_stfs;
4212 3b46e624 ths
4213 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4214 579a97f7 bellard
                goto efault;
4215 579a97f7 bellard
            __put_user(stfs.f_type, &target_stfs->f_type);
4216 579a97f7 bellard
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4217 579a97f7 bellard
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4218 579a97f7 bellard
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4219 579a97f7 bellard
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4220 579a97f7 bellard
            __put_user(stfs.f_files, &target_stfs->f_files);
4221 579a97f7 bellard
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4222 579a97f7 bellard
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4223 579a97f7 bellard
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4224 579a97f7 bellard
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4225 53a5960a pbrook
            unlock_user_struct(target_stfs, arg2, 1);
4226 31e31b8a bellard
        }
4227 31e31b8a bellard
        break;
4228 31e31b8a bellard
    case TARGET_NR_fstatfs:
4229 56c8f68f bellard
        ret = get_errno(fstatfs(arg1, &stfs));
4230 31e31b8a bellard
        goto convert_statfs;
4231 56c8f68f bellard
#ifdef TARGET_NR_statfs64
4232 56c8f68f bellard
    case TARGET_NR_statfs64:
4233 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4234 579a97f7 bellard
            goto efault;
4235 53a5960a pbrook
        ret = get_errno(statfs(path(p), &stfs));
4236 53a5960a pbrook
        unlock_user(p, arg1, 0);
4237 56c8f68f bellard
    convert_statfs64:
4238 56c8f68f bellard
        if (!is_error(ret)) {
4239 53a5960a pbrook
            struct target_statfs64 *target_stfs;
4240 3b46e624 ths
4241 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4242 579a97f7 bellard
                goto efault;
4243 579a97f7 bellard
            __put_user(stfs.f_type, &target_stfs->f_type);
4244 579a97f7 bellard
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4245 579a97f7 bellard
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4246 579a97f7 bellard
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4247 579a97f7 bellard
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4248 579a97f7 bellard
            __put_user(stfs.f_files, &target_stfs->f_files);
4249 579a97f7 bellard
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4250 579a97f7 bellard
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4251 579a97f7 bellard
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4252 579a97f7 bellard
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4253 579a97f7 bellard
            unlock_user_struct(target_stfs, arg3, 1);
4254 56c8f68f bellard
        }
4255 56c8f68f bellard
        break;
4256 56c8f68f bellard
    case TARGET_NR_fstatfs64:
4257 56c8f68f bellard
        ret = get_errno(fstatfs(arg1, &stfs));
4258 56c8f68f bellard
        goto convert_statfs64;
4259 56c8f68f bellard
#endif
4260 ebc05488 bellard
#ifdef TARGET_NR_ioperm
4261 31e31b8a bellard
    case TARGET_NR_ioperm:
4262 31e31b8a bellard
        goto unimplemented;
4263 ebc05488 bellard
#endif
4264 e5febef5 ths
#ifdef TARGET_NR_socketcall
4265 31e31b8a bellard
    case TARGET_NR_socketcall:
4266 53a5960a pbrook
        ret = do_socketcall(arg1, arg2);
4267 31e31b8a bellard
        break;
4268 e5febef5 ths
#endif
4269 3532fa74 bellard
#ifdef TARGET_NR_accept
4270 3532fa74 bellard
    case TARGET_NR_accept:
4271 1be9e1dc pbrook
        ret = do_accept(arg1, arg2, arg3);
4272 3532fa74 bellard
        break;
4273 3532fa74 bellard
#endif
4274 3532fa74 bellard
#ifdef TARGET_NR_bind
4275 3532fa74 bellard
    case TARGET_NR_bind:
4276 3532fa74 bellard
        ret = do_bind(arg1, arg2, arg3);
4277 3532fa74 bellard
        break;
4278 3532fa74 bellard
#endif
4279 3532fa74 bellard
#ifdef TARGET_NR_connect
4280 3532fa74 bellard
    case TARGET_NR_connect:
4281 3532fa74 bellard
        ret = do_connect(arg1, arg2, arg3);
4282 3532fa74 bellard
        break;
4283 3532fa74 bellard
#endif
4284 3532fa74 bellard
#ifdef TARGET_NR_getpeername
4285 3532fa74 bellard
    case TARGET_NR_getpeername:
4286 1be9e1dc pbrook
        ret = do_getpeername(arg1, arg2, arg3);
4287 3532fa74 bellard
        break;
4288 3532fa74 bellard
#endif
4289 3532fa74 bellard
#ifdef TARGET_NR_getsockname
4290 3532fa74 bellard
    case TARGET_NR_getsockname:
4291 1be9e1dc pbrook
        ret = do_getsockname(arg1, arg2, arg3);
4292 3532fa74 bellard
        break;
4293 3532fa74 bellard
#endif
4294 3532fa74 bellard
#ifdef TARGET_NR_getsockopt
4295 3532fa74 bellard
    case TARGET_NR_getsockopt:
4296 3532fa74 bellard
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4297 3532fa74 bellard
        break;
4298 3532fa74 bellard
#endif
4299 3532fa74 bellard
#ifdef TARGET_NR_listen
4300 3532fa74 bellard
    case TARGET_NR_listen:
4301 1be9e1dc pbrook
        ret = get_errno(listen(arg1, arg2));
4302 3532fa74 bellard
        break;
4303 3532fa74 bellard
#endif
4304 3532fa74 bellard
#ifdef TARGET_NR_recv
4305 3532fa74 bellard
    case TARGET_NR_recv:
4306 214201bd pbrook
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4307 3532fa74 bellard
        break;
4308 3532fa74 bellard
#endif
4309 3532fa74 bellard
#ifdef TARGET_NR_recvfrom
4310 3532fa74 bellard
    case TARGET_NR_recvfrom:
4311 214201bd pbrook
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4312 3532fa74 bellard
        break;
4313 3532fa74 bellard
#endif
4314 3532fa74 bellard
#ifdef TARGET_NR_recvmsg
4315 3532fa74 bellard
    case TARGET_NR_recvmsg:
4316 3532fa74 bellard
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4317 3532fa74 bellard
        break;
4318 3532fa74 bellard
#endif
4319 3532fa74 bellard
#ifdef TARGET_NR_send
4320 3532fa74 bellard
    case TARGET_NR_send:
4321 1be9e1dc pbrook
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4322 3532fa74 bellard
        break;
4323 3532fa74 bellard
#endif
4324 3532fa74 bellard
#ifdef TARGET_NR_sendmsg
4325 3532fa74 bellard
    case TARGET_NR_sendmsg:
4326 3532fa74 bellard
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4327 3532fa74 bellard
        break;
4328 3532fa74 bellard
#endif
4329 3532fa74 bellard
#ifdef TARGET_NR_sendto
4330 3532fa74 bellard
    case TARGET_NR_sendto:
4331 1be9e1dc pbrook
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4332 3532fa74 bellard
        break;
4333 3532fa74 bellard
#endif
4334 3532fa74 bellard
#ifdef TARGET_NR_shutdown
4335 3532fa74 bellard
    case TARGET_NR_shutdown:
4336 1be9e1dc pbrook
        ret = get_errno(shutdown(arg1, arg2));
4337 3532fa74 bellard
        break;
4338 3532fa74 bellard
#endif
4339 3532fa74 bellard
#ifdef TARGET_NR_socket
4340 3532fa74 bellard
    case TARGET_NR_socket:
4341 3532fa74 bellard
        ret = do_socket(arg1, arg2, arg3);
4342 3532fa74 bellard
        break;
4343 3532fa74 bellard
#endif
4344 3532fa74 bellard
#ifdef TARGET_NR_socketpair
4345 3532fa74 bellard
    case TARGET_NR_socketpair:
4346 1be9e1dc pbrook
        ret = do_socketpair(arg1, arg2, arg3, arg4);
4347 3532fa74 bellard
        break;
4348 3532fa74 bellard
#endif
4349 3532fa74 bellard
#ifdef TARGET_NR_setsockopt
4350 3532fa74 bellard
    case TARGET_NR_setsockopt:
4351 3532fa74 bellard
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4352 3532fa74 bellard
        break;
4353 3532fa74 bellard
#endif
4354 7494b0f9 ths
4355 31e31b8a bellard
    case TARGET_NR_syslog:
4356 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
4357 579a97f7 bellard
            goto efault;
4358 e5574487 ths
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4359 e5574487 ths
        unlock_user(p, arg2, 0);
4360 7494b0f9 ths
        break;
4361 7494b0f9 ths
4362 31e31b8a bellard
    case TARGET_NR_setitimer:
4363 66fb9763 bellard
        {
4364 66fb9763 bellard
            struct itimerval value, ovalue, *pvalue;
4365 66fb9763 bellard
4366 53a5960a pbrook
            if (arg2) {
4367 66fb9763 bellard
                pvalue = &value;
4368 788f5ec4 ths
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4369 788f5ec4 ths
                    || copy_from_user_timeval(&pvalue->it_value,
4370 788f5ec4 ths
                                              arg2 + sizeof(struct target_timeval)))
4371 788f5ec4 ths
                    goto efault;
4372 66fb9763 bellard
            } else {
4373 66fb9763 bellard
                pvalue = NULL;
4374 66fb9763 bellard
            }
4375 66fb9763 bellard
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4376 53a5960a pbrook
            if (!is_error(ret) && arg3) {
4377 788f5ec4 ths
                if (copy_to_user_timeval(arg3,
4378 788f5ec4 ths
                                         &ovalue.it_interval)
4379 788f5ec4 ths
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4380 788f5ec4 ths
                                            &ovalue.it_value))
4381 788f5ec4 ths
                    goto efault;
4382 66fb9763 bellard
            }
4383 66fb9763 bellard
        }
4384 66fb9763 bellard
        break;
4385 31e31b8a bellard
    case TARGET_NR_getitimer:
4386 66fb9763 bellard
        {
4387 66fb9763 bellard
            struct itimerval value;
4388 3b46e624 ths
4389 66fb9763 bellard
            ret = get_errno(getitimer(arg1, &value));
4390 53a5960a pbrook
            if (!is_error(ret) && arg2) {
4391 788f5ec4 ths
                if (copy_to_user_timeval(arg2,
4392 788f5ec4 ths
                                         &value.it_interval)
4393 788f5ec4 ths
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4394 788f5ec4 ths
                                            &value.it_value))
4395 788f5ec4 ths
                    goto efault;
4396 66fb9763 bellard
            }
4397 66fb9763 bellard
        }
4398 66fb9763 bellard
        break;
4399 31e31b8a bellard
    case TARGET_NR_stat:
4400 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4401 579a97f7 bellard
            goto efault;
4402 53a5960a pbrook
        ret = get_errno(stat(path(p), &st));
4403 53a5960a pbrook
        unlock_user(p, arg1, 0);
4404 31e31b8a bellard
        goto do_stat;
4405 31e31b8a bellard
    case TARGET_NR_lstat:
4406 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4407 579a97f7 bellard
            goto efault;
4408 53a5960a pbrook
        ret = get_errno(lstat(path(p), &st));
4409 53a5960a pbrook
        unlock_user(p, arg1, 0);
4410 31e31b8a bellard
        goto do_stat;
4411 31e31b8a bellard
    case TARGET_NR_fstat:
4412 31e31b8a bellard
        {
4413 31e31b8a bellard
            ret = get_errno(fstat(arg1, &st));
4414 31e31b8a bellard
        do_stat:
4415 31e31b8a bellard
            if (!is_error(ret)) {
4416 53a5960a pbrook
                struct target_stat *target_st;
4417 e3584658 ths
4418 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4419 579a97f7 bellard
                    goto efault;
4420 d2fd1af7 bellard
                __put_user(st.st_dev, &target_st->st_dev);
4421 d2fd1af7 bellard
                __put_user(st.st_ino, &target_st->st_ino);
4422 d2fd1af7 bellard
                __put_user(st.st_mode, &target_st->st_mode);
4423 d2fd1af7 bellard
                __put_user(st.st_uid, &target_st->st_uid);
4424 d2fd1af7 bellard
                __put_user(st.st_gid, &target_st->st_gid);
4425 d2fd1af7 bellard
                __put_user(st.st_nlink, &target_st->st_nlink);
4426 d2fd1af7 bellard
                __put_user(st.st_rdev, &target_st->st_rdev);
4427 d2fd1af7 bellard
                __put_user(st.st_size, &target_st->st_size);
4428 d2fd1af7 bellard
                __put_user(st.st_blksize, &target_st->st_blksize);
4429 d2fd1af7 bellard
                __put_user(st.st_blocks, &target_st->st_blocks);
4430 d2fd1af7 bellard
                __put_user(st.st_atime, &target_st->target_st_atime);
4431 d2fd1af7 bellard
                __put_user(st.st_mtime, &target_st->target_st_mtime);
4432 d2fd1af7 bellard
                __put_user(st.st_ctime, &target_st->target_st_ctime);
4433 53a5960a pbrook
                unlock_user_struct(target_st, arg2, 1);
4434 31e31b8a bellard
            }
4435 31e31b8a bellard
        }
4436 31e31b8a bellard
        break;
4437 ebc05488 bellard
#ifdef TARGET_NR_olduname
4438 31e31b8a bellard
    case TARGET_NR_olduname:
4439 31e31b8a bellard
        goto unimplemented;
4440 ebc05488 bellard
#endif
4441 ebc05488 bellard
#ifdef TARGET_NR_iopl
4442 31e31b8a bellard
    case TARGET_NR_iopl:
4443 31e31b8a bellard
        goto unimplemented;
4444 ebc05488 bellard
#endif
4445 31e31b8a bellard
    case TARGET_NR_vhangup:
4446 31e31b8a bellard
        ret = get_errno(vhangup());
4447 31e31b8a bellard
        break;
4448 ebc05488 bellard
#ifdef TARGET_NR_idle
4449 31e31b8a bellard
    case TARGET_NR_idle:
4450 31e31b8a bellard
        goto unimplemented;
4451 ebc05488 bellard
#endif
4452 42ad6ae9 bellard
#ifdef TARGET_NR_syscall
4453 42ad6ae9 bellard
    case TARGET_NR_syscall:
4454 42ad6ae9 bellard
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4455 42ad6ae9 bellard
            break;
4456 42ad6ae9 bellard
#endif
4457 31e31b8a bellard
    case TARGET_NR_wait4:
4458 31e31b8a bellard
        {
4459 31e31b8a bellard
            int status;
4460 992f48a0 blueswir1
            abi_long status_ptr = arg2;
4461 31e31b8a bellard
            struct rusage rusage, *rusage_ptr;
4462 992f48a0 blueswir1
            abi_ulong target_rusage = arg4;
4463 31e31b8a bellard
            if (target_rusage)
4464 31e31b8a bellard
                rusage_ptr = &rusage;
4465 31e31b8a bellard
            else
4466 31e31b8a bellard
                rusage_ptr = NULL;
4467 31e31b8a bellard
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4468 31e31b8a bellard
            if (!is_error(ret)) {
4469 2f619698 bellard
                if (status_ptr) {
4470 2f619698 bellard
                    if (put_user_s32(status, status_ptr))
4471 2f619698 bellard
                        goto efault;
4472 31e31b8a bellard
                }
4473 2f619698 bellard
                if (target_rusage)
4474 2f619698 bellard
                    host_to_target_rusage(target_rusage, &rusage);
4475 31e31b8a bellard
            }
4476 31e31b8a bellard
        }
4477 31e31b8a bellard
        break;
4478 e5febef5 ths
#ifdef TARGET_NR_swapoff
4479 31e31b8a bellard
    case TARGET_NR_swapoff:
4480 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4481 579a97f7 bellard
            goto efault;
4482 53a5960a pbrook
        ret = get_errno(swapoff(p));
4483 53a5960a pbrook
        unlock_user(p, arg1, 0);
4484 31e31b8a bellard
        break;
4485 e5febef5 ths
#endif
4486 31e31b8a bellard
    case TARGET_NR_sysinfo:
4487 a5448a7d bellard
        {
4488 53a5960a pbrook
            struct target_sysinfo *target_value;
4489 a5448a7d bellard
            struct sysinfo value;
4490 a5448a7d bellard
            ret = get_errno(sysinfo(&value));
4491 53a5960a pbrook
            if (!is_error(ret) && arg1)
4492 a5448a7d bellard
            {
4493 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4494 579a97f7 bellard
                    goto efault;
4495 a5448a7d bellard
                __put_user(value.uptime, &target_value->uptime);
4496 a5448a7d bellard
                __put_user(value.loads[0], &target_value->loads[0]);
4497 a5448a7d bellard
                __put_user(value.loads[1], &target_value->loads[1]);
4498 a5448a7d bellard
                __put_user(value.loads[2], &target_value->loads[2]);
4499 a5448a7d bellard
                __put_user(value.totalram, &target_value->totalram);
4500 a5448a7d bellard
                __put_user(value.freeram, &target_value->freeram);
4501 a5448a7d bellard
                __put_user(value.sharedram, &target_value->sharedram);
4502 a5448a7d bellard
                __put_user(value.bufferram, &target_value->bufferram);
4503 a5448a7d bellard
                __put_user(value.totalswap, &target_value->totalswap);
4504 a5448a7d bellard
                __put_user(value.freeswap, &target_value->freeswap);
4505 a5448a7d bellard
                __put_user(value.procs, &target_value->procs);
4506 a5448a7d bellard
                __put_user(value.totalhigh, &target_value->totalhigh);
4507 a5448a7d bellard
                __put_user(value.freehigh, &target_value->freehigh);
4508 a5448a7d bellard
                __put_user(value.mem_unit, &target_value->mem_unit);
4509 53a5960a pbrook
                unlock_user_struct(target_value, arg1, 1);
4510 a5448a7d bellard
            }
4511 a5448a7d bellard
        }
4512 a5448a7d bellard
        break;
4513 e5febef5 ths
#ifdef TARGET_NR_ipc
4514 31e31b8a bellard
    case TARGET_NR_ipc:
4515 8853f86e bellard
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4516 8853f86e bellard
        break;
4517 e5febef5 ths
#endif
4518 31e31b8a bellard
    case TARGET_NR_fsync:
4519 31e31b8a bellard
        ret = get_errno(fsync(arg1));
4520 31e31b8a bellard
        break;
4521 31e31b8a bellard
    case TARGET_NR_clone:
4522 1b6b029e bellard
        ret = get_errno(do_fork(cpu_env, arg1, arg2));
4523 1b6b029e bellard
        break;
4524 ec86b0fb bellard
#ifdef __NR_exit_group
4525 ec86b0fb bellard
        /* new thread calls */
4526 ec86b0fb bellard
    case TARGET_NR_exit_group:
4527 e9009676 bellard
        gdb_exit(cpu_env, arg1);
4528 ec86b0fb bellard
        ret = get_errno(exit_group(arg1));
4529 ec86b0fb bellard
        break;
4530 ec86b0fb bellard
#endif
4531 31e31b8a bellard
    case TARGET_NR_setdomainname:
4532 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4533 579a97f7 bellard
            goto efault;
4534 53a5960a pbrook
        ret = get_errno(setdomainname(p, arg2));
4535 53a5960a pbrook
        unlock_user(p, arg1, 0);
4536 31e31b8a bellard
        break;
4537 31e31b8a bellard
    case TARGET_NR_uname:
4538 31e31b8a bellard
        /* no need to transcode because we use the linux syscall */
4539 29e619b1 bellard
        {
4540 29e619b1 bellard
            struct new_utsname * buf;
4541 3b46e624 ths
4542 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4543 579a97f7 bellard
                goto efault;
4544 29e619b1 bellard
            ret = get_errno(sys_uname(buf));
4545 29e619b1 bellard
            if (!is_error(ret)) {
4546 29e619b1 bellard
                /* Overrite the native machine name with whatever is being
4547 29e619b1 bellard
                   emulated. */
4548 29e619b1 bellard
                strcpy (buf->machine, UNAME_MACHINE);
4549 c5937220 pbrook
                /* Allow the user to override the reported release.  */
4550 c5937220 pbrook
                if (qemu_uname_release && *qemu_uname_release)
4551 c5937220 pbrook
                  strcpy (buf->release, qemu_uname_release);
4552 29e619b1 bellard
            }
4553 53a5960a pbrook
            unlock_user_struct(buf, arg1, 1);
4554 29e619b1 bellard
        }
4555 31e31b8a bellard
        break;
4556 6dbad63e bellard
#ifdef TARGET_I386
4557 31e31b8a bellard
    case TARGET_NR_modify_ldt:
4558 03acab66 bellard
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4559 5cd4393b bellard
        break;
4560 84409ddb j_mayer
#if !defined(TARGET_X86_64)
4561 5cd4393b bellard
    case TARGET_NR_vm86old:
4562 5cd4393b bellard
        goto unimplemented;
4563 5cd4393b bellard
    case TARGET_NR_vm86:
4564 53a5960a pbrook
        ret = do_vm86(cpu_env, arg1, arg2);
4565 6dbad63e bellard
        break;
4566 6dbad63e bellard
#endif
4567 84409ddb j_mayer
#endif
4568 31e31b8a bellard
    case TARGET_NR_adjtimex:
4569 31e31b8a bellard
        goto unimplemented;
4570 e5febef5 ths
#ifdef TARGET_NR_create_module
4571 31e31b8a bellard
    case TARGET_NR_create_module:
4572 e5febef5 ths
#endif
4573 31e31b8a bellard
    case TARGET_NR_init_module:
4574 31e31b8a bellard
    case TARGET_NR_delete_module:
4575 e5febef5 ths
#ifdef TARGET_NR_get_kernel_syms
4576 31e31b8a bellard
    case TARGET_NR_get_kernel_syms:
4577 e5febef5 ths
#endif
4578 31e31b8a bellard
        goto unimplemented;
4579 31e31b8a bellard
    case TARGET_NR_quotactl:
4580 31e31b8a bellard
        goto unimplemented;
4581 31e31b8a bellard
    case TARGET_NR_getpgid:
4582 31e31b8a bellard
        ret = get_errno(getpgid(arg1));
4583 31e31b8a bellard
        break;
4584 31e31b8a bellard
    case TARGET_NR_fchdir:
4585 31e31b8a bellard
        ret = get_errno(fchdir(arg1));
4586 31e31b8a bellard
        break;
4587 84409ddb j_mayer
#ifdef TARGET_NR_bdflush /* not on x86_64 */
4588 31e31b8a bellard
    case TARGET_NR_bdflush:
4589 31e31b8a bellard
        goto unimplemented;
4590 84409ddb j_mayer
#endif
4591 e5febef5 ths
#ifdef TARGET_NR_sysfs
4592 31e31b8a bellard
    case TARGET_NR_sysfs:
4593 31e31b8a bellard
        goto unimplemented;
4594 e5febef5 ths
#endif
4595 31e31b8a bellard
    case TARGET_NR_personality:
4596 1b6b029e bellard
        ret = get_errno(personality(arg1));
4597 31e31b8a bellard
        break;
4598 e5febef5 ths
#ifdef TARGET_NR_afs_syscall
4599 31e31b8a bellard
    case TARGET_NR_afs_syscall:
4600 31e31b8a bellard
        goto unimplemented;
4601 e5febef5 ths
#endif
4602 7a3148a9 j_mayer
#ifdef TARGET_NR__llseek /* Not on alpha */
4603 31e31b8a bellard
    case TARGET_NR__llseek:
4604 31e31b8a bellard
        {
4605 4f2ac237 bellard
#if defined (__x86_64__)
4606 4f2ac237 bellard
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4607 2f619698 bellard
            if (put_user_s64(ret, arg4))
4608 2f619698 bellard
                goto efault;
4609 4f2ac237 bellard
#else
4610 31e31b8a bellard
            int64_t res;
4611 31e31b8a bellard
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4612 2f619698 bellard
            if (put_user_s64(res, arg4))
4613 2f619698 bellard
                goto efault;
4614 4f2ac237 bellard
#endif
4615 31e31b8a bellard
        }
4616 31e31b8a bellard
        break;
4617 7a3148a9 j_mayer
#endif
4618 31e31b8a bellard
    case TARGET_NR_getdents:
4619 992f48a0 blueswir1
#if TARGET_ABI_BITS != 32
4620 53a5960a pbrook
        goto unimplemented;
4621 992f48a0 blueswir1
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4622 4add45b4 bellard
        {
4623 53a5960a pbrook
            struct target_dirent *target_dirp;
4624 4add45b4 bellard
            struct dirent *dirp;
4625 992f48a0 blueswir1
            abi_long count = arg3;
4626 4add45b4 bellard
4627 4add45b4 bellard
            dirp = malloc(count);
4628 0da46a6e ths
            if (!dirp) {
4629 579a97f7 bellard
                ret = -TARGET_ENOMEM;
4630 0da46a6e ths
                goto fail;
4631 0da46a6e ths
            }
4632 3b46e624 ths
4633 4add45b4 bellard
            ret = get_errno(sys_getdents(arg1, dirp, count));
4634 4add45b4 bellard
            if (!is_error(ret)) {
4635 4add45b4 bellard
                struct dirent *de;
4636 4add45b4 bellard
                struct target_dirent *tde;
4637 4add45b4 bellard
                int len = ret;
4638 4add45b4 bellard
                int reclen, treclen;
4639 4add45b4 bellard
                int count1, tnamelen;
4640 4add45b4 bellard
4641 4add45b4 bellard
                count1 = 0;
4642 4add45b4 bellard
                de = dirp;
4643 579a97f7 bellard
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4644 579a97f7 bellard
                    goto efault;
4645 4add45b4 bellard
                tde = target_dirp;
4646 4add45b4 bellard
                while (len > 0) {
4647 4add45b4 bellard
                    reclen = de->d_reclen;
4648 992f48a0 blueswir1
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4649 4add45b4 bellard
                    tde->d_reclen = tswap16(treclen);
4650 4add45b4 bellard
                    tde->d_ino = tswapl(de->d_ino);
4651 4add45b4 bellard
                    tde->d_off = tswapl(de->d_off);
4652 992f48a0 blueswir1
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4653 4add45b4 bellard
                    if (tnamelen > 256)
4654 4add45b4 bellard
                        tnamelen = 256;
4655 80a9d035 bellard
                    /* XXX: may not be correct */
4656 4add45b4 bellard
                    strncpy(tde->d_name, de->d_name, tnamelen);
4657 4add45b4 bellard
                    de = (struct dirent *)((char *)de + reclen);
4658 4add45b4 bellard
                    len -= reclen;
4659 1c5bf3bf j_mayer
                    tde = (struct target_dirent *)((char *)tde + treclen);
4660 4add45b4 bellard
                    count1 += treclen;
4661 4add45b4 bellard
                }
4662 4add45b4 bellard
                ret = count1;
4663 579a97f7 bellard
                unlock_user(target_dirp, arg2, ret);
4664 4add45b4 bellard
            }
4665 4add45b4 bellard
            free(dirp);
4666 4add45b4 bellard
        }
4667 4add45b4 bellard
#else
4668 31e31b8a bellard
        {
4669 53a5960a pbrook
            struct dirent *dirp;
4670 992f48a0 blueswir1
            abi_long count = arg3;
4671 dab2ed99 bellard
4672 579a97f7 bellard
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4673 579a97f7 bellard
                goto efault;
4674 72f03900 bellard
            ret = get_errno(sys_getdents(arg1, dirp, count));
4675 31e31b8a bellard
            if (!is_error(ret)) {
4676 31e31b8a bellard
                struct dirent *de;
4677 31e31b8a bellard
                int len = ret;
4678 31e31b8a bellard
                int reclen;
4679 31e31b8a bellard
                de = dirp;
4680 31e31b8a bellard
                while (len > 0) {
4681 8083a3e5 bellard
                    reclen = de->d_reclen;
4682 31e31b8a bellard
                    if (reclen > len)
4683 31e31b8a bellard
                        break;
4684 8083a3e5 bellard
                    de->d_reclen = tswap16(reclen);
4685 31e31b8a bellard
                    tswapls(&de->d_ino);
4686 31e31b8a bellard
                    tswapls(&de->d_off);
4687 31e31b8a bellard
                    de = (struct dirent *)((char *)de + reclen);
4688 31e31b8a bellard
                    len -= reclen;
4689 31e31b8a bellard
                }
4690 31e31b8a bellard
            }
4691 53a5960a pbrook
            unlock_user(dirp, arg2, ret);
4692 31e31b8a bellard
        }
4693 4add45b4 bellard
#endif
4694 31e31b8a bellard
        break;
4695 3ae43202 ths
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
4696 dab2ed99 bellard
    case TARGET_NR_getdents64:
4697 dab2ed99 bellard
        {
4698 53a5960a pbrook
            struct dirent64 *dirp;
4699 992f48a0 blueswir1
            abi_long count = arg3;
4700 579a97f7 bellard
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4701 579a97f7 bellard
                goto efault;
4702 dab2ed99 bellard
            ret = get_errno(sys_getdents64(arg1, dirp, count));
4703 dab2ed99 bellard
            if (!is_error(ret)) {
4704 dab2ed99 bellard
                struct dirent64 *de;
4705 dab2ed99 bellard
                int len = ret;
4706 dab2ed99 bellard
                int reclen;
4707 dab2ed99 bellard
                de = dirp;
4708 dab2ed99 bellard
                while (len > 0) {
4709 8083a3e5 bellard
                    reclen = de->d_reclen;
4710 dab2ed99 bellard
                    if (reclen > len)
4711 dab2ed99 bellard
                        break;
4712 8083a3e5 bellard
                    de->d_reclen = tswap16(reclen);
4713 8582a53a bellard
                    tswap64s((uint64_t *)&de->d_ino);
4714 8582a53a bellard
                    tswap64s((uint64_t *)&de->d_off);
4715 dab2ed99 bellard
                    de = (struct dirent64 *)((char *)de + reclen);
4716 dab2ed99 bellard
                    len -= reclen;
4717 dab2ed99 bellard
                }
4718 dab2ed99 bellard
            }
4719 53a5960a pbrook
            unlock_user(dirp, arg2, ret);
4720 dab2ed99 bellard
        }
4721 dab2ed99 bellard
        break;
4722 a541f297 bellard
#endif /* TARGET_NR_getdents64 */
4723 e5febef5 ths
#ifdef TARGET_NR__newselect
4724 31e31b8a bellard
    case TARGET_NR__newselect:
4725 53a5960a pbrook
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
4726 31e31b8a bellard
        break;
4727 e5febef5 ths
#endif
4728 e5febef5 ths
#ifdef TARGET_NR_poll
4729 9de5e440 bellard
    case TARGET_NR_poll:
4730 9de5e440 bellard
        {
4731 53a5960a pbrook
            struct target_pollfd *target_pfd;
4732 9de5e440 bellard
            unsigned int nfds = arg2;
4733 9de5e440 bellard
            int timeout = arg3;
4734 9de5e440 bellard
            struct pollfd *pfd;
4735 7854b056 bellard
            unsigned int i;
4736 9de5e440 bellard
4737 579a97f7 bellard
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
4738 579a97f7 bellard
            if (!target_pfd)
4739 579a97f7 bellard
                goto efault;
4740 9de5e440 bellard
            pfd = alloca(sizeof(struct pollfd) * nfds);
4741 9de5e440 bellard
            for(i = 0; i < nfds; i++) {
4742 5cd4393b bellard
                pfd[i].fd = tswap32(target_pfd[i].fd);
4743 5cd4393b bellard
                pfd[i].events = tswap16(target_pfd[i].events);
4744 9de5e440 bellard
            }
4745 9de5e440 bellard
            ret = get_errno(poll(pfd, nfds, timeout));
4746 9de5e440 bellard
            if (!is_error(ret)) {
4747 9de5e440 bellard
                for(i = 0; i < nfds; i++) {
4748 5cd4393b bellard
                    target_pfd[i].revents = tswap16(pfd[i].revents);
4749 9de5e440 bellard
                }
4750 53a5960a pbrook
                ret += nfds * (sizeof(struct target_pollfd)
4751 53a5960a pbrook
                               - sizeof(struct pollfd));
4752 9de5e440 bellard
            }
4753 53a5960a pbrook
            unlock_user(target_pfd, arg1, ret);
4754 9de5e440 bellard
        }
4755 9de5e440 bellard
        break;
4756 e5febef5 ths
#endif
4757 31e31b8a bellard
    case TARGET_NR_flock:
4758 9de5e440 bellard
        /* NOTE: the flock constant seems to be the same for every
4759 9de5e440 bellard
           Linux platform */
4760 9de5e440 bellard
        ret = get_errno(flock(arg1, arg2));
4761 31e31b8a bellard
        break;
4762 31e31b8a bellard
    case TARGET_NR_readv:
4763 31e31b8a bellard
        {
4764 31e31b8a bellard
            int count = arg3;
4765 31e31b8a bellard
            struct iovec *vec;
4766 31e31b8a bellard
4767 31e31b8a bellard
            vec = alloca(count * sizeof(struct iovec));
4768 41df8411 bellard
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
4769 41df8411 bellard
                goto efault;
4770 31e31b8a bellard
            ret = get_errno(readv(arg1, vec, count));
4771 53a5960a pbrook
            unlock_iovec(vec, arg2, count, 1);
4772 31e31b8a bellard
        }
4773 31e31b8a bellard
        break;
4774 31e31b8a bellard
    case TARGET_NR_writev:
4775 31e31b8a bellard
        {
4776 31e31b8a bellard
            int count = arg3;
4777 31e31b8a bellard
            struct iovec *vec;
4778 31e31b8a bellard
4779 31e31b8a bellard
            vec = alloca(count * sizeof(struct iovec));
4780 41df8411 bellard
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
4781 41df8411 bellard
                goto efault;
4782 31e31b8a bellard
            ret = get_errno(writev(arg1, vec, count));
4783 53a5960a pbrook
            unlock_iovec(vec, arg2, count, 0);
4784 31e31b8a bellard
        }
4785 31e31b8a bellard
        break;
4786 31e31b8a bellard
    case TARGET_NR_getsid:
4787 31e31b8a bellard
        ret = get_errno(getsid(arg1));
4788 31e31b8a bellard
        break;
4789 7a3148a9 j_mayer
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
4790 31e31b8a bellard
    case TARGET_NR_fdatasync:
4791 5cd4393b bellard
        ret = get_errno(fdatasync(arg1));
4792 5cd4393b bellard
        break;
4793 7a3148a9 j_mayer
#endif
4794 31e31b8a bellard
    case TARGET_NR__sysctl:
4795 0da46a6e ths
        /* We don't implement this, but ENOTDIR is always a safe
4796 29e619b1 bellard
           return value. */
4797 0da46a6e ths
        ret = -TARGET_ENOTDIR;
4798 0da46a6e ths
        break;
4799 31e31b8a bellard
    case TARGET_NR_sched_setparam:
4800 5cd4393b bellard
        {
4801 53a5960a pbrook
            struct sched_param *target_schp;
4802 5cd4393b bellard
            struct sched_param schp;
4803 53a5960a pbrook
4804 579a97f7 bellard
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
4805 579a97f7 bellard
                goto efault;
4806 5cd4393b bellard
            schp.sched_priority = tswap32(target_schp->sched_priority);
4807 53a5960a pbrook
            unlock_user_struct(target_schp, arg2, 0);
4808 5cd4393b bellard
            ret = get_errno(sched_setparam(arg1, &schp));
4809 5cd4393b bellard
        }
4810 5cd4393b bellard
        break;
4811 31e31b8a bellard
    case TARGET_NR_sched_getparam:
4812 5cd4393b bellard
        {
4813 53a5960a pbrook
            struct sched_param *target_schp;
4814 5cd4393b bellard
            struct sched_param schp;
4815 5cd4393b bellard
            ret = get_errno(sched_getparam(arg1, &schp));
4816 5cd4393b bellard
            if (!is_error(ret)) {
4817 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
4818 579a97f7 bellard
                    goto efault;
4819 5cd4393b bellard
                target_schp->sched_priority = tswap32(schp.sched_priority);
4820 53a5960a pbrook
                unlock_user_struct(target_schp, arg2, 1);
4821 5cd4393b bellard
            }
4822 5cd4393b bellard
        }
4823 5cd4393b bellard
        break;
4824 31e31b8a bellard
    case TARGET_NR_sched_setscheduler:
4825 5cd4393b bellard
        {
4826 53a5960a pbrook
            struct sched_param *target_schp;
4827 5cd4393b bellard
            struct sched_param schp;
4828 579a97f7 bellard
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
4829 579a97f7 bellard
                goto efault;
4830 5cd4393b bellard
            schp.sched_priority = tswap32(target_schp->sched_priority);
4831 53a5960a pbrook
            unlock_user_struct(target_schp, arg3, 0);
4832 5cd4393b bellard
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
4833 5cd4393b bellard
        }
4834 5cd4393b bellard
        break;
4835 31e31b8a bellard
    case TARGET_NR_sched_getscheduler:
4836 5cd4393b bellard
        ret = get_errno(sched_getscheduler(arg1));
4837 5cd4393b bellard
        break;
4838 31e31b8a bellard
    case TARGET_NR_sched_yield:
4839 31e31b8a bellard
        ret = get_errno(sched_yield());
4840 31e31b8a bellard
        break;
4841 31e31b8a bellard
    case TARGET_NR_sched_get_priority_max:
4842 5cd4393b bellard
        ret = get_errno(sched_get_priority_max(arg1));
4843 5cd4393b bellard
        break;
4844 31e31b8a bellard
    case TARGET_NR_sched_get_priority_min:
4845 5cd4393b bellard
        ret = get_errno(sched_get_priority_min(arg1));
4846 5cd4393b bellard
        break;
4847 31e31b8a bellard
    case TARGET_NR_sched_rr_get_interval:
4848 5cd4393b bellard
        {
4849 5cd4393b bellard
            struct timespec ts;
4850 5cd4393b bellard
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
4851 5cd4393b bellard
            if (!is_error(ret)) {
4852 53a5960a pbrook
                host_to_target_timespec(arg2, &ts);
4853 5cd4393b bellard
            }
4854 5cd4393b bellard
        }
4855 5cd4393b bellard
        break;
4856 31e31b8a bellard
    case TARGET_NR_nanosleep:
4857 1b6b029e bellard
        {
4858 1b6b029e bellard
            struct timespec req, rem;
4859 53a5960a pbrook
            target_to_host_timespec(&req, arg1);
4860 1b6b029e bellard
            ret = get_errno(nanosleep(&req, &rem));
4861 53a5960a pbrook
            if (is_error(ret) && arg2) {
4862 53a5960a pbrook
                host_to_target_timespec(arg2, &rem);
4863 1b6b029e bellard
            }
4864 1b6b029e bellard
        }
4865 1b6b029e bellard
        break;
4866 e5febef5 ths
#ifdef TARGET_NR_query_module
4867 31e31b8a bellard
    case TARGET_NR_query_module:
4868 5cd4393b bellard
        goto unimplemented;
4869 e5febef5 ths
#endif
4870 e5febef5 ths
#ifdef TARGET_NR_nfsservctl
4871 31e31b8a bellard
    case TARGET_NR_nfsservctl:
4872 5cd4393b bellard
        goto unimplemented;
4873 e5febef5 ths
#endif
4874 31e31b8a bellard
    case TARGET_NR_prctl:
4875 e5574487 ths
        switch (arg1)
4876 e5574487 ths
            {
4877 e5574487 ths
            case PR_GET_PDEATHSIG:
4878 e5574487 ths
                {
4879 e5574487 ths
                    int deathsig;
4880 e5574487 ths
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
4881 2f619698 bellard
                    if (!is_error(ret) && arg2
4882 2f619698 bellard
                        && put_user_ual(deathsig, arg2))
4883 2f619698 bellard
                        goto efault;
4884 e5574487 ths
                }
4885 e5574487 ths
                break;
4886 e5574487 ths
            default:
4887 e5574487 ths
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
4888 e5574487 ths
                break;
4889 e5574487 ths
            }
4890 39b9aae1 ths
        break;
4891 d2fd1af7 bellard
#ifdef TARGET_NR_arch_prctl
4892 d2fd1af7 bellard
    case TARGET_NR_arch_prctl:
4893 d2fd1af7 bellard
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
4894 d2fd1af7 bellard
        ret = do_arch_prctl(cpu_env, arg1, arg2);
4895 d2fd1af7 bellard
        break;
4896 d2fd1af7 bellard
#else
4897 d2fd1af7 bellard
        goto unimplemented;
4898 d2fd1af7 bellard
#endif
4899 d2fd1af7 bellard
#endif
4900 67867308 bellard
#ifdef TARGET_NR_pread
4901 31e31b8a bellard
    case TARGET_NR_pread:
4902 579a97f7 bellard
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4903 579a97f7 bellard
            goto efault;
4904 53a5960a pbrook
        ret = get_errno(pread(arg1, p, arg3, arg4));
4905 53a5960a pbrook
        unlock_user(p, arg2, ret);
4906 206f0fa7 bellard
        break;
4907 31e31b8a bellard
    case TARGET_NR_pwrite:
4908 579a97f7 bellard
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4909 579a97f7 bellard
            goto efault;
4910 53a5960a pbrook
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
4911 53a5960a pbrook
        unlock_user(p, arg2, 0);
4912 206f0fa7 bellard
        break;
4913 67867308 bellard
#endif
4914 f2c7ba15 aurel32
#ifdef TARGET_NR_pread64
4915 f2c7ba15 aurel32
    case TARGET_NR_pread64:
4916 f2c7ba15 aurel32
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4917 f2c7ba15 aurel32
            goto efault;
4918 f2c7ba15 aurel32
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
4919 f2c7ba15 aurel32
        unlock_user(p, arg2, ret);
4920 f2c7ba15 aurel32
        break;
4921 f2c7ba15 aurel32
    case TARGET_NR_pwrite64:
4922 f2c7ba15 aurel32
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4923 f2c7ba15 aurel32
            goto efault;
4924 f2c7ba15 aurel32
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
4925 f2c7ba15 aurel32
        unlock_user(p, arg2, 0);
4926 f2c7ba15 aurel32
        break;
4927 f2c7ba15 aurel32
#endif
4928 31e31b8a bellard
    case TARGET_NR_getcwd:
4929 579a97f7 bellard
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
4930 579a97f7 bellard
            goto efault;
4931 53a5960a pbrook
        ret = get_errno(sys_getcwd1(p, arg2));
4932 53a5960a pbrook
        unlock_user(p, arg1, ret);
4933 31e31b8a bellard
        break;
4934 31e31b8a bellard
    case TARGET_NR_capget:
4935 5cd4393b bellard
        goto unimplemented;
4936 31e31b8a bellard
    case TARGET_NR_capset:
4937 5cd4393b bellard
        goto unimplemented;
4938 31e31b8a bellard
    case TARGET_NR_sigaltstack:
4939 198a74de ths
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
4940 198a74de ths
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
4941 579a97f7 bellard
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
4942 a04e134a ths
        break;
4943 a04e134a ths
#else
4944 5cd4393b bellard
        goto unimplemented;
4945 a04e134a ths
#endif
4946 31e31b8a bellard
    case TARGET_NR_sendfile:
4947 5cd4393b bellard
        goto unimplemented;
4948 ebc05488 bellard
#ifdef TARGET_NR_getpmsg
4949 31e31b8a bellard
    case TARGET_NR_getpmsg:
4950 5cd4393b bellard
        goto unimplemented;
4951 ebc05488 bellard
#endif
4952 ebc05488 bellard
#ifdef TARGET_NR_putpmsg
4953 31e31b8a bellard
    case TARGET_NR_putpmsg:
4954 5cd4393b bellard
        goto unimplemented;
4955 ebc05488 bellard
#endif
4956 048f6b4d bellard
#ifdef TARGET_NR_vfork
4957 31e31b8a bellard
    case TARGET_NR_vfork:
4958 1b6b029e bellard
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
4959 31e31b8a bellard
        break;
4960 048f6b4d bellard
#endif
4961 ebc05488 bellard
#ifdef TARGET_NR_ugetrlimit
4962 31e31b8a bellard
    case TARGET_NR_ugetrlimit:
4963 728584be bellard
    {
4964 728584be bellard
        struct rlimit rlim;
4965 728584be bellard
        ret = get_errno(getrlimit(arg1, &rlim));
4966 728584be bellard
        if (!is_error(ret)) {
4967 53a5960a pbrook
            struct target_rlimit *target_rlim;
4968 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4969 579a97f7 bellard
                goto efault;
4970 728584be bellard
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
4971 728584be bellard
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
4972 53a5960a pbrook
            unlock_user_struct(target_rlim, arg2, 1);
4973 728584be bellard
        }
4974 728584be bellard
        break;
4975 728584be bellard
    }
4976 ebc05488 bellard
#endif
4977 a315a145 bellard
#ifdef TARGET_NR_truncate64
4978 31e31b8a bellard
    case TARGET_NR_truncate64:
4979 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4980 579a97f7 bellard
            goto efault;
4981 53a5960a pbrook
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
4982 53a5960a pbrook
        unlock_user(p, arg1, 0);
4983 667f38b1 bellard
        break;
4984 a315a145 bellard
#endif
4985 a315a145 bellard
#ifdef TARGET_NR_ftruncate64
4986 31e31b8a bellard
    case TARGET_NR_ftruncate64:
4987 ce4defa0 pbrook
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
4988 667f38b1 bellard
        break;
4989 a315a145 bellard
#endif
4990 a315a145 bellard
#ifdef TARGET_NR_stat64
4991 31e31b8a bellard
    case TARGET_NR_stat64:
4992 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4993 579a97f7 bellard
            goto efault;
4994 53a5960a pbrook
        ret = get_errno(stat(path(p), &st));
4995 53a5960a pbrook
        unlock_user(p, arg1, 0);
4996 60cd49d5 bellard
        goto do_stat64;
4997 a315a145 bellard
#endif
4998 a315a145 bellard
#ifdef TARGET_NR_lstat64
4999 31e31b8a bellard
    case TARGET_NR_lstat64:
5000 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5001 579a97f7 bellard
            goto efault;
5002 53a5960a pbrook
        ret = get_errno(lstat(path(p), &st));
5003 53a5960a pbrook
        unlock_user(p, arg1, 0);
5004 60cd49d5 bellard
        goto do_stat64;
5005 a315a145 bellard
#endif
5006 a315a145 bellard
#ifdef TARGET_NR_fstat64
5007 31e31b8a bellard
    case TARGET_NR_fstat64:
5008 60cd49d5 bellard
        {
5009 60cd49d5 bellard
            ret = get_errno(fstat(arg1, &st));
5010 60cd49d5 bellard
        do_stat64:
5011 60cd49d5 bellard
            if (!is_error(ret)) {
5012 ce4defa0 pbrook
#ifdef TARGET_ARM
5013 ce4defa0 pbrook
                if (((CPUARMState *)cpu_env)->eabi) {
5014 53a5960a pbrook
                    struct target_eabi_stat64 *target_st;
5015 579a97f7 bellard
5016 579a97f7 bellard
                    if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5017 579a97f7 bellard
                        goto efault;
5018 ce4defa0 pbrook
                    memset(target_st, 0, sizeof(struct target_eabi_stat64));
5019 579a97f7 bellard
                    __put_user(st.st_dev, &target_st->st_dev);
5020 579a97f7 bellard
                    __put_user(st.st_ino, &target_st->st_ino);
5021 ce4defa0 pbrook
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5022 579a97f7 bellard
                    __put_user(st.st_ino, &target_st->__st_ino);
5023 579a97f7 bellard
#endif
5024 579a97f7 bellard
                    __put_user(st.st_mode, &target_st->st_mode);
5025 579a97f7 bellard
                    __put_user(st.st_nlink, &target_st->st_nlink);
5026 579a97f7 bellard
                    __put_user(st.st_uid, &target_st->st_uid);
5027 579a97f7 bellard
                    __put_user(st.st_gid, &target_st->st_gid);
5028 579a97f7 bellard
                    __put_user(st.st_rdev, &target_st->st_rdev);
5029 579a97f7 bellard
                    __put_user(st.st_size, &target_st->st_size);
5030 579a97f7 bellard
                    __put_user(st.st_blksize, &target_st->st_blksize);
5031 579a97f7 bellard
                    __put_user(st.st_blocks, &target_st->st_blocks);
5032 579a97f7 bellard
                    __put_user(st.st_atime, &target_st->target_st_atime);
5033 579a97f7 bellard
                    __put_user(st.st_mtime, &target_st->target_st_mtime);
5034 579a97f7 bellard
                    __put_user(st.st_ctime, &target_st->target_st_ctime);
5035 579a97f7 bellard
                    unlock_user_struct(target_st, arg2, 1);
5036 ce4defa0 pbrook
                } else
5037 ce4defa0 pbrook
#endif
5038 ce4defa0 pbrook
                {
5039 53a5960a pbrook
                    struct target_stat64 *target_st;
5040 579a97f7 bellard
5041 579a97f7 bellard
                    if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5042 579a97f7 bellard
                        goto efault;
5043 ce4defa0 pbrook
                    memset(target_st, 0, sizeof(struct target_stat64));
5044 579a97f7 bellard
                    __put_user(st.st_dev, &target_st->st_dev);
5045 579a97f7 bellard
                    __put_user(st.st_ino, &target_st->st_ino);
5046 ec86b0fb bellard
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5047 579a97f7 bellard
                    __put_user(st.st_ino, &target_st->__st_ino);
5048 ce4defa0 pbrook
#endif
5049 579a97f7 bellard
                    __put_user(st.st_mode, &target_st->st_mode);
5050 579a97f7 bellard
                    __put_user(st.st_nlink, &target_st->st_nlink);
5051 579a97f7 bellard
                    __put_user(st.st_uid, &target_st->st_uid);
5052 579a97f7 bellard
                    __put_user(st.st_gid, &target_st->st_gid);
5053 579a97f7 bellard
                    __put_user(st.st_rdev, &target_st->st_rdev);
5054 ce4defa0 pbrook
                    /* XXX: better use of kernel struct */
5055 579a97f7 bellard
                    __put_user(st.st_size, &target_st->st_size);
5056 579a97f7 bellard
                    __put_user(st.st_blksize, &target_st->st_blksize);
5057 579a97f7 bellard
                    __put_user(st.st_blocks, &target_st->st_blocks);
5058 579a97f7 bellard
                    __put_user(st.st_atime, &target_st->target_st_atime);
5059 579a97f7 bellard
                    __put_user(st.st_mtime, &target_st->target_st_mtime);
5060 579a97f7 bellard
                    __put_user(st.st_ctime, &target_st->target_st_ctime);
5061 579a97f7 bellard
                    unlock_user_struct(target_st, arg2, 1);
5062 ce4defa0 pbrook
                }
5063 60cd49d5 bellard
            }
5064 60cd49d5 bellard
        }
5065 60cd49d5 bellard
        break;
5066 a315a145 bellard
#endif
5067 67867308 bellard
#ifdef USE_UID16
5068 67867308 bellard
    case TARGET_NR_lchown:
5069 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5070 579a97f7 bellard
            goto efault;
5071 53a5960a pbrook
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5072 53a5960a pbrook
        unlock_user(p, arg1, 0);
5073 67867308 bellard
        break;
5074 67867308 bellard
    case TARGET_NR_getuid:
5075 67867308 bellard
        ret = get_errno(high2lowuid(getuid()));
5076 67867308 bellard
        break;
5077 67867308 bellard
    case TARGET_NR_getgid:
5078 67867308 bellard
        ret = get_errno(high2lowgid(getgid()));
5079 67867308 bellard
        break;
5080 67867308 bellard
    case TARGET_NR_geteuid:
5081 67867308 bellard
        ret = get_errno(high2lowuid(geteuid()));
5082 67867308 bellard
        break;
5083 67867308 bellard
    case TARGET_NR_getegid:
5084 67867308 bellard
        ret = get_errno(high2lowgid(getegid()));
5085 67867308 bellard
        break;
5086 67867308 bellard
    case TARGET_NR_setreuid:
5087 67867308 bellard
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5088 67867308 bellard
        break;
5089 67867308 bellard
    case TARGET_NR_setregid:
5090 67867308 bellard
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5091 67867308 bellard
        break;
5092 67867308 bellard
    case TARGET_NR_getgroups:
5093 67867308 bellard
        {
5094 67867308 bellard
            int gidsetsize = arg1;
5095 53a5960a pbrook
            uint16_t *target_grouplist;
5096 67867308 bellard
            gid_t *grouplist;
5097 67867308 bellard
            int i;
5098 67867308 bellard
5099 67867308 bellard
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5100 67867308 bellard
            ret = get_errno(getgroups(gidsetsize, grouplist));
5101 67867308 bellard
            if (!is_error(ret)) {
5102 579a97f7 bellard
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5103 579a97f7 bellard
                if (!target_grouplist)
5104 579a97f7 bellard
                    goto efault;
5105 67867308 bellard
                for(i = 0;i < gidsetsize; i++)
5106 67867308 bellard
                    target_grouplist[i] = tswap16(grouplist[i]);
5107 53a5960a pbrook
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5108 67867308 bellard
            }
5109 67867308 bellard
        }
5110 67867308 bellard
        break;
5111 67867308 bellard
    case TARGET_NR_setgroups:
5112 67867308 bellard
        {
5113 67867308 bellard
            int gidsetsize = arg1;
5114 53a5960a pbrook
            uint16_t *target_grouplist;
5115 67867308 bellard
            gid_t *grouplist;
5116 67867308 bellard
            int i;
5117 67867308 bellard
5118 67867308 bellard
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5119 579a97f7 bellard
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5120 579a97f7 bellard
            if (!target_grouplist) {
5121 579a97f7 bellard
                ret = -TARGET_EFAULT;
5122 579a97f7 bellard
                goto fail;
5123 579a97f7 bellard
            }
5124 67867308 bellard
            for(i = 0;i < gidsetsize; i++)
5125 67867308 bellard
                grouplist[i] = tswap16(target_grouplist[i]);
5126 53a5960a pbrook
            unlock_user(target_grouplist, arg2, 0);
5127 67867308 bellard
            ret = get_errno(setgroups(gidsetsize, grouplist));
5128 67867308 bellard
        }
5129 67867308 bellard
        break;
5130 67867308 bellard
    case TARGET_NR_fchown:
5131 67867308 bellard
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5132 67867308 bellard
        break;
5133 ccfa72b7 ths
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5134 ccfa72b7 ths
    case TARGET_NR_fchownat:
5135 579a97f7 bellard
        if (!(p = lock_user_string(arg2))) 
5136 579a97f7 bellard
            goto efault;
5137 579a97f7 bellard
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5138 579a97f7 bellard
        unlock_user(p, arg2, 0);
5139 ccfa72b7 ths
        break;
5140 ccfa72b7 ths
#endif
5141 67867308 bellard
#ifdef TARGET_NR_setresuid
5142 67867308 bellard
    case TARGET_NR_setresuid:
5143 5fafdf24 ths
        ret = get_errno(setresuid(low2highuid(arg1),
5144 5fafdf24 ths
                                  low2highuid(arg2),
5145 67867308 bellard
                                  low2highuid(arg3)));
5146 67867308 bellard
        break;
5147 67867308 bellard
#endif
5148 67867308 bellard
#ifdef TARGET_NR_getresuid
5149 67867308 bellard
    case TARGET_NR_getresuid:
5150 67867308 bellard
        {
5151 53a5960a pbrook
            uid_t ruid, euid, suid;
5152 67867308 bellard
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5153 67867308 bellard
            if (!is_error(ret)) {
5154 2f619698 bellard
                if (put_user_u16(high2lowuid(ruid), arg1)
5155 2f619698 bellard
                    || put_user_u16(high2lowuid(euid), arg2)
5156 2f619698 bellard
                    || put_user_u16(high2lowuid(suid), arg3))
5157 2f619698 bellard
                    goto efault;
5158 67867308 bellard
            }
5159 67867308 bellard
        }
5160 67867308 bellard
        break;
5161 67867308 bellard
#endif
5162 67867308 bellard
#ifdef TARGET_NR_getresgid
5163 67867308 bellard
    case TARGET_NR_setresgid:
5164 5fafdf24 ths
        ret = get_errno(setresgid(low2highgid(arg1),
5165 5fafdf24 ths
                                  low2highgid(arg2),
5166 67867308 bellard
                                  low2highgid(arg3)));
5167 67867308 bellard
        break;
5168 67867308 bellard
#endif
5169 67867308 bellard
#ifdef TARGET_NR_getresgid
5170 67867308 bellard
    case TARGET_NR_getresgid:
5171 67867308 bellard
        {
5172 53a5960a pbrook
            gid_t rgid, egid, sgid;
5173 67867308 bellard
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5174 67867308 bellard
            if (!is_error(ret)) {
5175 2f619698 bellard
                if (put_user_u16(high2lowgid(rgid), arg1)
5176 2f619698 bellard
                    || put_user_u16(high2lowgid(egid), arg2)
5177 2f619698 bellard
                    || put_user_u16(high2lowgid(sgid), arg3))
5178 2f619698 bellard
                    goto efault;
5179 67867308 bellard
            }
5180 67867308 bellard
        }
5181 67867308 bellard
        break;
5182 67867308 bellard
#endif
5183 67867308 bellard
    case TARGET_NR_chown:
5184 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5185 579a97f7 bellard
            goto efault;
5186 53a5960a pbrook
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5187 53a5960a pbrook
        unlock_user(p, arg1, 0);
5188 67867308 bellard
        break;
5189 67867308 bellard
    case TARGET_NR_setuid:
5190 67867308 bellard
        ret = get_errno(setuid(low2highuid(arg1)));
5191 67867308 bellard
        break;
5192 67867308 bellard
    case TARGET_NR_setgid:
5193 67867308 bellard
        ret = get_errno(setgid(low2highgid(arg1)));
5194 67867308 bellard
        break;
5195 67867308 bellard
    case TARGET_NR_setfsuid:
5196 67867308 bellard
        ret = get_errno(setfsuid(arg1));
5197 67867308 bellard
        break;
5198 67867308 bellard
    case TARGET_NR_setfsgid:
5199 67867308 bellard
        ret = get_errno(setfsgid(arg1));
5200 67867308 bellard
        break;
5201 67867308 bellard
#endif /* USE_UID16 */
5202 67867308 bellard
5203 a315a145 bellard
#ifdef TARGET_NR_lchown32
5204 31e31b8a bellard
    case TARGET_NR_lchown32:
5205 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5206 579a97f7 bellard
            goto efault;
5207 53a5960a pbrook
        ret = get_errno(lchown(p, arg2, arg3));
5208 53a5960a pbrook
        unlock_user(p, arg1, 0);
5209 b03c60f3 bellard
        break;
5210 a315a145 bellard
#endif
5211 a315a145 bellard
#ifdef TARGET_NR_getuid32
5212 31e31b8a bellard
    case TARGET_NR_getuid32:
5213 b03c60f3 bellard
        ret = get_errno(getuid());
5214 b03c60f3 bellard
        break;
5215 a315a145 bellard
#endif
5216 a315a145 bellard
#ifdef TARGET_NR_getgid32
5217 31e31b8a bellard
    case TARGET_NR_getgid32:
5218 b03c60f3 bellard
        ret = get_errno(getgid());
5219 b03c60f3 bellard
        break;
5220 a315a145 bellard
#endif
5221 a315a145 bellard
#ifdef TARGET_NR_geteuid32
5222 31e31b8a bellard
    case TARGET_NR_geteuid32:
5223 b03c60f3 bellard
        ret = get_errno(geteuid());
5224 b03c60f3 bellard
        break;
5225 a315a145 bellard
#endif
5226 a315a145 bellard
#ifdef TARGET_NR_getegid32
5227 31e31b8a bellard
    case TARGET_NR_getegid32:
5228 b03c60f3 bellard
        ret = get_errno(getegid());
5229 b03c60f3 bellard
        break;
5230 a315a145 bellard
#endif
5231 a315a145 bellard
#ifdef TARGET_NR_setreuid32
5232 31e31b8a bellard
    case TARGET_NR_setreuid32:
5233 b03c60f3 bellard
        ret = get_errno(setreuid(arg1, arg2));
5234 b03c60f3 bellard
        break;
5235 a315a145 bellard
#endif
5236 a315a145 bellard
#ifdef TARGET_NR_setregid32
5237 31e31b8a bellard
    case TARGET_NR_setregid32:
5238 b03c60f3 bellard
        ret = get_errno(setregid(arg1, arg2));
5239 b03c60f3 bellard
        break;
5240 a315a145 bellard
#endif
5241 a315a145 bellard
#ifdef TARGET_NR_getgroups32
5242 31e31b8a bellard
    case TARGET_NR_getgroups32:
5243 99c475ab bellard
        {
5244 99c475ab bellard
            int gidsetsize = arg1;
5245 53a5960a pbrook
            uint32_t *target_grouplist;
5246 99c475ab bellard
            gid_t *grouplist;
5247 99c475ab bellard
            int i;
5248 99c475ab bellard
5249 99c475ab bellard
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5250 99c475ab bellard
            ret = get_errno(getgroups(gidsetsize, grouplist));
5251 99c475ab bellard
            if (!is_error(ret)) {
5252 579a97f7 bellard
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5253 579a97f7 bellard
                if (!target_grouplist) {
5254 579a97f7 bellard
                    ret = -TARGET_EFAULT;
5255 579a97f7 bellard
                    goto fail;
5256 579a97f7 bellard
                }
5257 99c475ab bellard
                for(i = 0;i < gidsetsize; i++)
5258 53a5960a pbrook
                    target_grouplist[i] = tswap32(grouplist[i]);
5259 53a5960a pbrook
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
5260 99c475ab bellard
            }
5261 99c475ab bellard
        }
5262 99c475ab bellard
        break;
5263 a315a145 bellard
#endif
5264 a315a145 bellard
#ifdef TARGET_NR_setgroups32
5265 31e31b8a bellard
    case TARGET_NR_setgroups32:
5266 99c475ab bellard
        {
5267 99c475ab bellard
            int gidsetsize = arg1;
5268 53a5960a pbrook
            uint32_t *target_grouplist;
5269 99c475ab bellard
            gid_t *grouplist;
5270 99c475ab bellard
            int i;
5271 3b46e624 ths
5272 99c475ab bellard
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5273 579a97f7 bellard
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5274 579a97f7 bellard
            if (!target_grouplist) {
5275 579a97f7 bellard
                ret = -TARGET_EFAULT;
5276 579a97f7 bellard
                goto fail;
5277 579a97f7 bellard
            }
5278 99c475ab bellard
            for(i = 0;i < gidsetsize; i++)
5279 53a5960a pbrook
                grouplist[i] = tswap32(target_grouplist[i]);
5280 53a5960a pbrook
            unlock_user(target_grouplist, arg2, 0);
5281 99c475ab bellard
            ret = get_errno(setgroups(gidsetsize, grouplist));
5282 99c475ab bellard
        }
5283 99c475ab bellard
        break;
5284 a315a145 bellard
#endif
5285 a315a145 bellard
#ifdef TARGET_NR_fchown32
5286 31e31b8a bellard
    case TARGET_NR_fchown32:
5287 b03c60f3 bellard
        ret = get_errno(fchown(arg1, arg2, arg3));
5288 b03c60f3 bellard
        break;
5289 a315a145 bellard
#endif
5290 a315a145 bellard
#ifdef TARGET_NR_setresuid32
5291 31e31b8a bellard
    case TARGET_NR_setresuid32:
5292 b03c60f3 bellard
        ret = get_errno(setresuid(arg1, arg2, arg3));
5293 b03c60f3 bellard
        break;
5294 a315a145 bellard
#endif
5295 a315a145 bellard
#ifdef TARGET_NR_getresuid32
5296 31e31b8a bellard
    case TARGET_NR_getresuid32:
5297 b03c60f3 bellard
        {
5298 53a5960a pbrook
            uid_t ruid, euid, suid;
5299 b03c60f3 bellard
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5300 b03c60f3 bellard
            if (!is_error(ret)) {
5301 2f619698 bellard
                if (put_user_u32(ruid, arg1)
5302 2f619698 bellard
                    || put_user_u32(euid, arg2)
5303 2f619698 bellard
                    || put_user_u32(suid, arg3))
5304 2f619698 bellard
                    goto efault;
5305 b03c60f3 bellard
            }
5306 b03c60f3 bellard
        }
5307 b03c60f3 bellard
        break;
5308 a315a145 bellard
#endif
5309 a315a145 bellard
#ifdef TARGET_NR_setresgid32
5310 31e31b8a bellard
    case TARGET_NR_setresgid32:
5311 b03c60f3 bellard
        ret = get_errno(setresgid(arg1, arg2, arg3));
5312 b03c60f3 bellard
        break;
5313 a315a145 bellard
#endif
5314 a315a145 bellard
#ifdef TARGET_NR_getresgid32
5315 31e31b8a bellard
    case TARGET_NR_getresgid32:
5316 b03c60f3 bellard
        {
5317 53a5960a pbrook
            gid_t rgid, egid, sgid;
5318 b03c60f3 bellard
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5319 b03c60f3 bellard
            if (!is_error(ret)) {
5320 2f619698 bellard
                if (put_user_u32(rgid, arg1)
5321 2f619698 bellard
                    || put_user_u32(egid, arg2)
5322 2f619698 bellard
                    || put_user_u32(sgid, arg3))
5323 2f619698 bellard
                    goto efault;
5324 b03c60f3 bellard
            }
5325 b03c60f3 bellard
        }
5326 b03c60f3 bellard
        break;
5327 a315a145 bellard
#endif
5328 a315a145 bellard
#ifdef TARGET_NR_chown32
5329 31e31b8a bellard
    case TARGET_NR_chown32:
5330 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5331 579a97f7 bellard
            goto efault;
5332 53a5960a pbrook
        ret = get_errno(chown(p, arg2, arg3));
5333 53a5960a pbrook
        unlock_user(p, arg1, 0);
5334 b03c60f3 bellard
        break;
5335 a315a145 bellard
#endif
5336 a315a145 bellard
#ifdef TARGET_NR_setuid32
5337 31e31b8a bellard
    case TARGET_NR_setuid32:
5338 b03c60f3 bellard
        ret = get_errno(setuid(arg1));
5339 b03c60f3 bellard
        break;
5340 a315a145 bellard
#endif
5341 a315a145 bellard
#ifdef TARGET_NR_setgid32
5342 31e31b8a bellard
    case TARGET_NR_setgid32:
5343 b03c60f3 bellard
        ret = get_errno(setgid(arg1));
5344 b03c60f3 bellard
        break;
5345 a315a145 bellard
#endif
5346 a315a145 bellard
#ifdef TARGET_NR_setfsuid32
5347 31e31b8a bellard
    case TARGET_NR_setfsuid32:
5348 b03c60f3 bellard
        ret = get_errno(setfsuid(arg1));
5349 b03c60f3 bellard
        break;
5350 a315a145 bellard
#endif
5351 a315a145 bellard
#ifdef TARGET_NR_setfsgid32
5352 31e31b8a bellard
    case TARGET_NR_setfsgid32:
5353 b03c60f3 bellard
        ret = get_errno(setfsgid(arg1));
5354 b03c60f3 bellard
        break;
5355 a315a145 bellard
#endif
5356 67867308 bellard
5357 31e31b8a bellard
    case TARGET_NR_pivot_root:
5358 b03c60f3 bellard
        goto unimplemented;
5359 ffa65c3b bellard
#ifdef TARGET_NR_mincore
5360 31e31b8a bellard
    case TARGET_NR_mincore:
5361 b03c60f3 bellard
        goto unimplemented;
5362 ffa65c3b bellard
#endif
5363 ffa65c3b bellard
#ifdef TARGET_NR_madvise
5364 31e31b8a bellard
    case TARGET_NR_madvise:
5365 24836689 pbrook
        /* A straight passthrough may not be safe because qemu sometimes
5366 24836689 pbrook
           turns private flie-backed mappings into anonymous mappings.
5367 24836689 pbrook
           This will break MADV_DONTNEED.
5368 24836689 pbrook
           This is a hint, so ignoring and returning success is ok.  */
5369 24836689 pbrook
        ret = get_errno(0);
5370 24836689 pbrook
        break;
5371 ffa65c3b bellard
#endif
5372 992f48a0 blueswir1
#if TARGET_ABI_BITS == 32
5373 31e31b8a bellard
    case TARGET_NR_fcntl64:
5374 77e4672d bellard
    {
5375 b1e341eb ths
        int cmd;
5376 77e4672d bellard
        struct flock64 fl;
5377 53a5960a pbrook
        struct target_flock64 *target_fl;
5378 ce4defa0 pbrook
#ifdef TARGET_ARM
5379 53a5960a pbrook
        struct target_eabi_flock64 *target_efl;
5380 ce4defa0 pbrook
#endif
5381 77e4672d bellard
5382 b1e341eb ths
        switch(arg2){
5383 b1e341eb ths
        case TARGET_F_GETLK64:
5384 b1e341eb ths
            cmd = F_GETLK64;
5385 a7222580 ths
            break;
5386 b1e341eb ths
        case TARGET_F_SETLK64:
5387 b1e341eb ths
            cmd = F_SETLK64;
5388 a7222580 ths
            break;
5389 b1e341eb ths
        case TARGET_F_SETLKW64:
5390 b1e341eb ths
            cmd = F_SETLK64;
5391 a7222580 ths
            break;
5392 b1e341eb ths
        default:
5393 b1e341eb ths
            cmd = arg2;
5394 a7222580 ths
            break;
5395 b1e341eb ths
        }
5396 b1e341eb ths
5397 60cd49d5 bellard
        switch(arg2) {
5398 b1e341eb ths
        case TARGET_F_GETLK64:
5399 5813427b ths
#ifdef TARGET_ARM
5400 5813427b ths
            if (((CPUARMState *)cpu_env)->eabi) {
5401 9ee1fa2c bellard
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5402 9ee1fa2c bellard
                    goto efault;
5403 5813427b ths
                fl.l_type = tswap16(target_efl->l_type);
5404 5813427b ths
                fl.l_whence = tswap16(target_efl->l_whence);
5405 5813427b ths
                fl.l_start = tswap64(target_efl->l_start);
5406 5813427b ths
                fl.l_len = tswap64(target_efl->l_len);
5407 5813427b ths
                fl.l_pid = tswapl(target_efl->l_pid);
5408 5813427b ths
                unlock_user_struct(target_efl, arg3, 0);
5409 5813427b ths
            } else
5410 5813427b ths
#endif
5411 5813427b ths
            {
5412 9ee1fa2c bellard
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5413 9ee1fa2c bellard
                    goto efault;
5414 5813427b ths
                fl.l_type = tswap16(target_fl->l_type);
5415 5813427b ths
                fl.l_whence = tswap16(target_fl->l_whence);
5416 5813427b ths
                fl.l_start = tswap64(target_fl->l_start);
5417 5813427b ths
                fl.l_len = tswap64(target_fl->l_len);
5418 5813427b ths
                fl.l_pid = tswapl(target_fl->l_pid);
5419 5813427b ths
                unlock_user_struct(target_fl, arg3, 0);
5420 5813427b ths
            }
5421 b1e341eb ths
            ret = get_errno(fcntl(arg1, cmd, &fl));
5422 77e4672d bellard
            if (ret == 0) {
5423 ce4defa0 pbrook
#ifdef TARGET_ARM
5424 ce4defa0 pbrook
                if (((CPUARMState *)cpu_env)->eabi) {
5425 9ee1fa2c bellard
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
5426 9ee1fa2c bellard
                        goto efault;
5427 ce4defa0 pbrook
                    target_efl->l_type = tswap16(fl.l_type);
5428 ce4defa0 pbrook
                    target_efl->l_whence = tswap16(fl.l_whence);
5429 ce4defa0 pbrook
                    target_efl->l_start = tswap64(fl.l_start);
5430 ce4defa0 pbrook
                    target_efl->l_len = tswap64(fl.l_len);
5431 ce4defa0 pbrook
                    target_efl->l_pid = tswapl(fl.l_pid);
5432 53a5960a pbrook
                    unlock_user_struct(target_efl, arg3, 1);
5433 ce4defa0 pbrook
                } else
5434 ce4defa0 pbrook
#endif
5435 ce4defa0 pbrook
                {
5436 9ee1fa2c bellard
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
5437 9ee1fa2c bellard
                        goto efault;
5438 ce4defa0 pbrook
                    target_fl->l_type = tswap16(fl.l_type);
5439 ce4defa0 pbrook
                    target_fl->l_whence = tswap16(fl.l_whence);
5440 ce4defa0 pbrook
                    target_fl->l_start = tswap64(fl.l_start);
5441 ce4defa0 pbrook
                    target_fl->l_len = tswap64(fl.l_len);
5442 ce4defa0 pbrook
                    target_fl->l_pid = tswapl(fl.l_pid);
5443 53a5960a pbrook
                    unlock_user_struct(target_fl, arg3, 1);
5444 ce4defa0 pbrook
                }
5445 77e4672d bellard
            }
5446 77e4672d bellard
            break;
5447 77e4672d bellard
5448 b1e341eb ths
        case TARGET_F_SETLK64:
5449 b1e341eb ths
        case TARGET_F_SETLKW64:
5450 ce4defa0 pbrook
#ifdef TARGET_ARM
5451 ce4defa0 pbrook
            if (((CPUARMState *)cpu_env)->eabi) {
5452 9ee1fa2c bellard
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5453 9ee1fa2c bellard
                    goto efault;
5454 ce4defa0 pbrook
                fl.l_type = tswap16(target_efl->l_type);
5455 ce4defa0 pbrook
                fl.l_whence = tswap16(target_efl->l_whence);
5456 ce4defa0 pbrook
                fl.l_start = tswap64(target_efl->l_start);
5457 ce4defa0 pbrook
                fl.l_len = tswap64(target_efl->l_len);
5458 ce4defa0 pbrook
                fl.l_pid = tswapl(target_efl->l_pid);
5459 53a5960a pbrook
                unlock_user_struct(target_efl, arg3, 0);
5460 ce4defa0 pbrook
            } else
5461 ce4defa0 pbrook
#endif
5462 ce4defa0 pbrook
            {
5463 9ee1fa2c bellard
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5464 9ee1fa2c bellard
                    goto efault;
5465 ce4defa0 pbrook
                fl.l_type = tswap16(target_fl->l_type);
5466 ce4defa0 pbrook
                fl.l_whence = tswap16(target_fl->l_whence);
5467 ce4defa0 pbrook
                fl.l_start = tswap64(target_fl->l_start);
5468 ce4defa0 pbrook
                fl.l_len = tswap64(target_fl->l_len);
5469 ce4defa0 pbrook
                fl.l_pid = tswapl(target_fl->l_pid);
5470 53a5960a pbrook
                unlock_user_struct(target_fl, arg3, 0);
5471 ce4defa0 pbrook
            }
5472 b1e341eb ths
            ret = get_errno(fcntl(arg1, cmd, &fl));
5473 77e4672d bellard
            break;
5474 60cd49d5 bellard
        default:
5475 9ee1fa2c bellard
            ret = do_fcntl(arg1, cmd, arg3);
5476 60cd49d5 bellard
            break;
5477 60cd49d5 bellard
        }
5478 77e4672d bellard
        break;
5479 77e4672d bellard
    }
5480 60cd49d5 bellard
#endif
5481 7d600c80 ths
#ifdef TARGET_NR_cacheflush
5482 7d600c80 ths
    case TARGET_NR_cacheflush:
5483 7d600c80 ths
        /* self-modifying code is handled automatically, so nothing needed */
5484 7d600c80 ths
        ret = 0;
5485 7d600c80 ths
        break;
5486 7d600c80 ths
#endif
5487 ebc05488 bellard
#ifdef TARGET_NR_security
5488 31e31b8a bellard
    case TARGET_NR_security:
5489 31e31b8a bellard
        goto unimplemented;
5490 ebc05488 bellard
#endif
5491 c573ff67 bellard
#ifdef TARGET_NR_getpagesize
5492 c573ff67 bellard
    case TARGET_NR_getpagesize:
5493 c573ff67 bellard
        ret = TARGET_PAGE_SIZE;
5494 c573ff67 bellard
        break;
5495 c573ff67 bellard
#endif
5496 31e31b8a bellard
    case TARGET_NR_gettid:
5497 31e31b8a bellard
        ret = get_errno(gettid());
5498 31e31b8a bellard
        break;
5499 e5febef5 ths
#ifdef TARGET_NR_readahead
5500 31e31b8a bellard
    case TARGET_NR_readahead:
5501 5cd4393b bellard
        goto unimplemented;
5502 e5febef5 ths
#endif
5503 ebc05488 bellard
#ifdef TARGET_NR_setxattr
5504 31e31b8a bellard
    case TARGET_NR_setxattr:
5505 31e31b8a bellard
    case TARGET_NR_lsetxattr:
5506 31e31b8a bellard
    case TARGET_NR_fsetxattr:
5507 31e31b8a bellard
    case TARGET_NR_getxattr:
5508 31e31b8a bellard
    case TARGET_NR_lgetxattr:
5509 31e31b8a bellard
    case TARGET_NR_fgetxattr:
5510 31e31b8a bellard
    case TARGET_NR_listxattr:
5511 31e31b8a bellard
    case TARGET_NR_llistxattr:
5512 31e31b8a bellard
    case TARGET_NR_flistxattr:
5513 31e31b8a bellard
    case TARGET_NR_removexattr:
5514 31e31b8a bellard
    case TARGET_NR_lremovexattr:
5515 31e31b8a bellard
    case TARGET_NR_fremovexattr:
5516 5cd4393b bellard
        goto unimplemented_nowarn;
5517 ebc05488 bellard
#endif
5518 ebc05488 bellard
#ifdef TARGET_NR_set_thread_area
5519 5cd4393b bellard
    case TARGET_NR_set_thread_area:
5520 8d18e893 bellard
#if defined(TARGET_MIPS)
5521 6f5b89a0 ths
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5522 6f5b89a0 ths
      ret = 0;
5523 6f5b89a0 ths
      break;
5524 8d18e893 bellard
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
5525 8d18e893 bellard
      ret = do_set_thread_area(cpu_env, arg1);
5526 8d18e893 bellard
      break;
5527 6f5b89a0 ths
#else
5528 6f5b89a0 ths
      goto unimplemented_nowarn;
5529 6f5b89a0 ths
#endif
5530 6f5b89a0 ths
#endif
5531 6f5b89a0 ths
#ifdef TARGET_NR_get_thread_area
5532 5cd4393b bellard
    case TARGET_NR_get_thread_area:
5533 8d18e893 bellard
#if defined(TARGET_I386) && defined(TARGET_ABI32)
5534 8d18e893 bellard
        ret = do_get_thread_area(cpu_env, arg1);
5535 8d18e893 bellard
#else
5536 5cd4393b bellard
        goto unimplemented_nowarn;
5537 ebc05488 bellard
#endif
5538 8d18e893 bellard
#endif
5539 48dc41eb bellard
#ifdef TARGET_NR_getdomainname
5540 48dc41eb bellard
    case TARGET_NR_getdomainname:
5541 48dc41eb bellard
        goto unimplemented_nowarn;
5542 48dc41eb bellard
#endif
5543 6f5b89a0 ths
5544 b5906f95 ths
#ifdef TARGET_NR_clock_gettime
5545 b5906f95 ths
    case TARGET_NR_clock_gettime:
5546 b5906f95 ths
    {
5547 b5906f95 ths
        struct timespec ts;
5548 b5906f95 ths
        ret = get_errno(clock_gettime(arg1, &ts));
5549 b5906f95 ths
        if (!is_error(ret)) {
5550 b5906f95 ths
            host_to_target_timespec(arg2, &ts);
5551 b5906f95 ths
        }
5552 b5906f95 ths
        break;
5553 b5906f95 ths
    }
5554 b5906f95 ths
#endif
5555 b5906f95 ths
#ifdef TARGET_NR_clock_getres
5556 b5906f95 ths
    case TARGET_NR_clock_getres:
5557 b5906f95 ths
    {
5558 b5906f95 ths
        struct timespec ts;
5559 b5906f95 ths
        ret = get_errno(clock_getres(arg1, &ts));
5560 b5906f95 ths
        if (!is_error(ret)) {
5561 b5906f95 ths
            host_to_target_timespec(arg2, &ts);
5562 b5906f95 ths
        }
5563 b5906f95 ths
        break;
5564 b5906f95 ths
    }
5565 b5906f95 ths
#endif
5566 63d7651b pbrook
#ifdef TARGET_NR_clock_nanosleep
5567 63d7651b pbrook
    case TARGET_NR_clock_nanosleep:
5568 63d7651b pbrook
    {
5569 63d7651b pbrook
        struct timespec ts;
5570 63d7651b pbrook
        target_to_host_timespec(&ts, arg3);
5571 63d7651b pbrook
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5572 63d7651b pbrook
        if (arg4)
5573 63d7651b pbrook
            host_to_target_timespec(arg4, &ts);
5574 63d7651b pbrook
        break;
5575 63d7651b pbrook
    }
5576 63d7651b pbrook
#endif
5577 b5906f95 ths
5578 6f5b89a0 ths
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5579 6f5b89a0 ths
    case TARGET_NR_set_tid_address:
5580 579a97f7 bellard
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
5581 579a97f7 bellard
        break;
5582 6f5b89a0 ths
#endif
5583 6f5b89a0 ths
5584 3ae43202 ths
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5585 4cae1d16 ths
    case TARGET_NR_tkill:
5586 4cb05961 pbrook
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5587 4cae1d16 ths
        break;
5588 4cae1d16 ths
#endif
5589 4cae1d16 ths
5590 3ae43202 ths
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5591 71455574 ths
    case TARGET_NR_tgkill:
5592 4cb05961 pbrook
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5593 4cb05961 pbrook
                        target_to_host_signal(arg3)));
5594 71455574 ths
        break;
5595 71455574 ths
#endif
5596 71455574 ths
5597 4f2b1fe8 ths
#ifdef TARGET_NR_set_robust_list
5598 4f2b1fe8 ths
    case TARGET_NR_set_robust_list:
5599 4f2b1fe8 ths
        goto unimplemented_nowarn;
5600 4f2b1fe8 ths
#endif
5601 4f2b1fe8 ths
5602 9007f0ef ths
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5603 9007f0ef ths
    case TARGET_NR_utimensat:
5604 9007f0ef ths
        {
5605 9007f0ef ths
            struct timespec ts[2];
5606 9007f0ef ths
            target_to_host_timespec(ts, arg3);
5607 9007f0ef ths
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5608 9007f0ef ths
            if (!arg2)
5609 9007f0ef ths
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5610 9007f0ef ths
            else {
5611 579a97f7 bellard
                if (!(p = lock_user_string(arg2))) {
5612 0da46a6e ths
                    ret = -TARGET_EFAULT;
5613 579a97f7 bellard
                    goto fail;
5614 579a97f7 bellard
                }
5615 579a97f7 bellard
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
5616 579a97f7 bellard
                unlock_user(p, arg2, 0);
5617 9007f0ef ths
            }
5618 9007f0ef ths
        }
5619 9007f0ef ths
        break;
5620 9007f0ef ths
#endif
5621 bd0c5661 pbrook
#if defined(USE_NPTL)
5622 bd0c5661 pbrook
    case TARGET_NR_futex:
5623 bd0c5661 pbrook
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
5624 bd0c5661 pbrook
        break;
5625 bd0c5661 pbrook
#endif
5626 9007f0ef ths
5627 31e31b8a bellard
    default:
5628 31e31b8a bellard
    unimplemented:
5629 5cd4393b bellard
        gemu_log("qemu: Unsupported syscall: %d\n", num);
5630 4f2b1fe8 ths
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
5631 5cd4393b bellard
    unimplemented_nowarn:
5632 80a9d035 bellard
#endif
5633 0da46a6e ths
        ret = -TARGET_ENOSYS;
5634 31e31b8a bellard
        break;
5635 31e31b8a bellard
    }
5636 579a97f7 bellard
fail:
5637 c573ff67 bellard
#ifdef DEBUG
5638 c573ff67 bellard
    gemu_log(" = %ld\n", ret);
5639 c573ff67 bellard
#endif
5640 b92c47c1 ths
    if(do_strace)
5641 b92c47c1 ths
        print_syscall_ret(num, ret);
5642 31e31b8a bellard
    return ret;
5643 579a97f7 bellard
efault:
5644 579a97f7 bellard
    ret = -TARGET_EFAULT;
5645 579a97f7 bellard
    goto fail;
5646 31e31b8a bellard
}