Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 24e1003a

History | View | Annotate | Download (194.8 kB)

1
/*
2
 *  Linux syscalls
3
 *
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
 *  MA 02110-1301, USA.
20
 */
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <stdarg.h>
24
#include <string.h>
25
#include <elf.h>
26
#include <endian.h>
27
#include <errno.h>
28
#include <unistd.h>
29
#include <fcntl.h>
30
#include <time.h>
31
#include <limits.h>
32
#include <mqueue.h>
33
#include <sys/types.h>
34
#include <sys/ipc.h>
35
#include <sys/msg.h>
36
#include <sys/wait.h>
37
#include <sys/time.h>
38
#include <sys/stat.h>
39
#include <sys/mount.h>
40
#include <sys/prctl.h>
41
#include <sys/resource.h>
42
#include <sys/mman.h>
43
#include <sys/swap.h>
44
#include <signal.h>
45
#include <sched.h>
46
#include <sys/socket.h>
47
#include <sys/uio.h>
48
#include <sys/poll.h>
49
#include <sys/times.h>
50
#include <sys/shm.h>
51
#include <sys/sem.h>
52
#include <sys/statfs.h>
53
#include <utime.h>
54
#include <sys/sysinfo.h>
55
//#include <sys/user.h>
56
#include <netinet/ip.h>
57
#include <netinet/tcp.h>
58
#include <qemu-common.h>
59
#ifdef HAVE_GPROF
60
#include <sys/gmon.h>
61
#endif
62

    
63
#define termios host_termios
64
#define winsize host_winsize
65
#define termio host_termio
66
#define sgttyb host_sgttyb /* same as target */
67
#define tchars host_tchars /* same as target */
68
#define ltchars host_ltchars /* same as target */
69

    
70
#include <linux/termios.h>
71
#include <linux/unistd.h>
72
#include <linux/utsname.h>
73
#include <linux/cdrom.h>
74
#include <linux/hdreg.h>
75
#include <linux/soundcard.h>
76
#include <linux/kd.h>
77
#include <linux/mtio.h>
78
#include "linux_loop.h"
79

    
80
#include "qemu.h"
81
#include "qemu-common.h"
82

    
83
#if defined(USE_NPTL)
84
#include <linux/futex.h>
85
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
86
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
87
#else
88
/* XXX: Hardcode the above values.  */
89
#define CLONE_NPTL_FLAGS2 0
90
#endif
91

    
92
//#define DEBUG
93

    
94
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
95
    || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
96
/* 16 bit uid wrappers emulation */
97
#define USE_UID16
98
#endif
99

    
100
//#include <linux/msdos_fs.h>
101
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
102
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
103

    
104

    
105
#undef _syscall0
106
#undef _syscall1
107
#undef _syscall2
108
#undef _syscall3
109
#undef _syscall4
110
#undef _syscall5
111
#undef _syscall6
112

    
113
#define _syscall0(type,name)                \
114
static type name (void)                        \
115
{                                        \
116
        return syscall(__NR_##name);        \
117
}
118

    
119
#define _syscall1(type,name,type1,arg1)                \
120
static type name (type1 arg1)                        \
121
{                                                \
122
        return syscall(__NR_##name, arg1);        \
123
}
124

    
125
#define _syscall2(type,name,type1,arg1,type2,arg2)        \
126
static type name (type1 arg1,type2 arg2)                \
127
{                                                        \
128
        return syscall(__NR_##name, arg1, arg2);        \
129
}
130

    
131
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)        \
132
static type name (type1 arg1,type2 arg2,type3 arg3)                \
133
{                                                                \
134
        return syscall(__NR_##name, arg1, arg2, arg3);                \
135
}
136

    
137
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)        \
138
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)                        \
139
{                                                                                \
140
        return syscall(__NR_##name, arg1, arg2, arg3, arg4);                        \
141
}
142

    
143
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
144
                  type5,arg5)                                                        \
145
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)        \
146
{                                                                                \
147
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);                \
148
}
149

    
150

    
151
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
152
                  type5,arg5,type6,arg6)                                        \
153
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,        \
154
                  type6 arg6)                                                        \
155
{                                                                                \
156
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
157
}
158

    
159

    
160
#define __NR_sys_uname __NR_uname
161
#define __NR_sys_faccessat __NR_faccessat
162
#define __NR_sys_fchmodat __NR_fchmodat
163
#define __NR_sys_fchownat __NR_fchownat
164
#define __NR_sys_fstatat64 __NR_fstatat64
165
#define __NR_sys_futimesat __NR_futimesat
166
#define __NR_sys_getcwd1 __NR_getcwd
167
#define __NR_sys_getdents __NR_getdents
168
#define __NR_sys_getdents64 __NR_getdents64
169
#define __NR_sys_getpriority __NR_getpriority
170
#define __NR_sys_linkat __NR_linkat
171
#define __NR_sys_mkdirat __NR_mkdirat
172
#define __NR_sys_mknodat __NR_mknodat
173
#define __NR_sys_newfstatat __NR_newfstatat
174
#define __NR_sys_openat __NR_openat
175
#define __NR_sys_readlinkat __NR_readlinkat
176
#define __NR_sys_renameat __NR_renameat
177
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
178
#define __NR_sys_symlinkat __NR_symlinkat
179
#define __NR_sys_syslog __NR_syslog
180
#define __NR_sys_tgkill __NR_tgkill
181
#define __NR_sys_tkill __NR_tkill
182
#define __NR_sys_unlinkat __NR_unlinkat
183
#define __NR_sys_utimensat __NR_utimensat
184
#define __NR_sys_futex __NR_futex
185
#define __NR_sys_inotify_init __NR_inotify_init
186
#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
187
#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
188

    
189
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
190
#define __NR__llseek __NR_lseek
191
#endif
192

    
193
#ifdef __NR_gettid
194
_syscall0(int, gettid)
195
#else
196
/* This is a replacement for the host gettid() and must return a host
197
   errno. */
198
static int gettid(void) {
199
    return -ENOSYS;
200
}
201
#endif
202
_syscall1(int,sys_uname,struct new_utsname *,buf)
203
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
204
_syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
205
#endif
206
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
207
_syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
208
          mode_t,mode,int,flags)
209
#endif
210
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
211
_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
212
          uid_t,owner,gid_t,group,int,flags)
213
#endif
214
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
215
        defined(__NR_fstatat64)
216
_syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
217
          struct stat *,buf,int,flags)
218
#endif
219
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
220
_syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
221
         const struct timeval *,times)
222
#endif
223
_syscall2(int,sys_getcwd1,char *,buf,size_t,size)
224
#if TARGET_ABI_BITS == 32
225
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
226
#endif
227
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
228
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
229
#endif
230
_syscall2(int, sys_getpriority, int, which, int, who);
231
#if !defined (__x86_64__)
232
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
233
          loff_t *, res, uint, wh);
234
#endif
235
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
236
_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
237
          int,newdirfd,const char *,newpath,int,flags)
238
#endif
239
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
240
_syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
241
#endif
242
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
243
_syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
244
          mode_t,mode,dev_t,dev)
245
#endif
246
#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
247
        defined(__NR_newfstatat)
248
_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
249
          struct stat *,buf,int,flags)
250
#endif
251
#if defined(TARGET_NR_openat) && defined(__NR_openat)
252
_syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
253
#endif
254
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
255
_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
256
          char *,buf,size_t,bufsize)
257
#endif
258
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
259
_syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
260
          int,newdirfd,const char *,newpath)
261
#endif
262
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
263
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
264
_syscall3(int,sys_symlinkat,const char *,oldpath,
265
          int,newdirfd,const char *,newpath)
266
#endif
267
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
268
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
269
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
270
#endif
271
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
272
_syscall2(int,sys_tkill,int,tid,int,sig)
273
#endif
274
#ifdef __NR_exit_group
275
_syscall1(int,exit_group,int,error_code)
276
#endif
277
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
278
_syscall1(int,set_tid_address,int *,tidptr)
279
#endif
280
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
281
_syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
282
#endif
283
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
284
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
285
          const struct timespec *,tsp,int,flags)
286
#endif
287
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
288
_syscall0(int,sys_inotify_init)
289
#endif
290
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
291
_syscall3(int,sys_inotify_add_watch,int,fd,const char *,pathname,uint32_t,mask)
292
#endif
293
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
294
_syscall2(int,sys_inotify_rm_watch,int,fd,uint32_t,wd)
295
#endif
296
#if defined(USE_NPTL)
297
#if defined(TARGET_NR_futex) && defined(__NR_futex)
298
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
299
          const struct timespec *,timeout,int *,uaddr2,int,val3)
300
#endif
301
#endif
302

    
303
extern int personality(int);
304
extern int flock(int, int);
305
extern int setfsuid(int);
306
extern int setfsgid(int);
307
extern int setgroups(int, gid_t *);
308

    
309
#define ERRNO_TABLE_SIZE 1200
310

    
311
/* target_to_host_errno_table[] is initialized from
312
 * host_to_target_errno_table[] in syscall_init(). */
313
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
314
};
315

    
316
/*
317
 * This list is the union of errno values overridden in asm-<arch>/errno.h
318
 * minus the errnos that are not actually generic to all archs.
319
 */
320
static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
321
    [EIDRM]                = TARGET_EIDRM,
322
    [ECHRNG]                = TARGET_ECHRNG,
323
    [EL2NSYNC]                = TARGET_EL2NSYNC,
324
    [EL3HLT]                = TARGET_EL3HLT,
325
    [EL3RST]                = TARGET_EL3RST,
326
    [ELNRNG]                = TARGET_ELNRNG,
327
    [EUNATCH]                = TARGET_EUNATCH,
328
    [ENOCSI]                = TARGET_ENOCSI,
329
    [EL2HLT]                = TARGET_EL2HLT,
330
    [EDEADLK]                = TARGET_EDEADLK,
331
    [ENOLCK]                = TARGET_ENOLCK,
332
    [EBADE]                = TARGET_EBADE,
333
    [EBADR]                = TARGET_EBADR,
334
    [EXFULL]                = TARGET_EXFULL,
335
    [ENOANO]                = TARGET_ENOANO,
336
    [EBADRQC]                = TARGET_EBADRQC,
337
    [EBADSLT]                = TARGET_EBADSLT,
338
    [EBFONT]                = TARGET_EBFONT,
339
    [ENOSTR]                = TARGET_ENOSTR,
340
    [ENODATA]                = TARGET_ENODATA,
341
    [ETIME]                = TARGET_ETIME,
342
    [ENOSR]                = TARGET_ENOSR,
343
    [ENONET]                = TARGET_ENONET,
344
    [ENOPKG]                = TARGET_ENOPKG,
345
    [EREMOTE]                = TARGET_EREMOTE,
346
    [ENOLINK]                = TARGET_ENOLINK,
347
    [EADV]                = TARGET_EADV,
348
    [ESRMNT]                = TARGET_ESRMNT,
349
    [ECOMM]                = TARGET_ECOMM,
350
    [EPROTO]                = TARGET_EPROTO,
351
    [EDOTDOT]                = TARGET_EDOTDOT,
352
    [EMULTIHOP]                = TARGET_EMULTIHOP,
353
    [EBADMSG]                = TARGET_EBADMSG,
354
    [ENAMETOOLONG]        = TARGET_ENAMETOOLONG,
355
    [EOVERFLOW]                = TARGET_EOVERFLOW,
356
    [ENOTUNIQ]                = TARGET_ENOTUNIQ,
357
    [EBADFD]                = TARGET_EBADFD,
358
    [EREMCHG]                = TARGET_EREMCHG,
359
    [ELIBACC]                = TARGET_ELIBACC,
360
    [ELIBBAD]                = TARGET_ELIBBAD,
361
    [ELIBSCN]                = TARGET_ELIBSCN,
362
    [ELIBMAX]                = TARGET_ELIBMAX,
363
    [ELIBEXEC]                = TARGET_ELIBEXEC,
364
    [EILSEQ]                = TARGET_EILSEQ,
365
    [ENOSYS]                = TARGET_ENOSYS,
366
    [ELOOP]                = TARGET_ELOOP,
367
    [ERESTART]                = TARGET_ERESTART,
368
    [ESTRPIPE]                = TARGET_ESTRPIPE,
369
    [ENOTEMPTY]                = TARGET_ENOTEMPTY,
370
    [EUSERS]                = TARGET_EUSERS,
371
    [ENOTSOCK]                = TARGET_ENOTSOCK,
372
    [EDESTADDRREQ]        = TARGET_EDESTADDRREQ,
373
    [EMSGSIZE]                = TARGET_EMSGSIZE,
374
    [EPROTOTYPE]        = TARGET_EPROTOTYPE,
375
    [ENOPROTOOPT]        = TARGET_ENOPROTOOPT,
376
    [EPROTONOSUPPORT]        = TARGET_EPROTONOSUPPORT,
377
    [ESOCKTNOSUPPORT]        = TARGET_ESOCKTNOSUPPORT,
378
    [EOPNOTSUPP]        = TARGET_EOPNOTSUPP,
379
    [EPFNOSUPPORT]        = TARGET_EPFNOSUPPORT,
380
    [EAFNOSUPPORT]        = TARGET_EAFNOSUPPORT,
381
    [EADDRINUSE]        = TARGET_EADDRINUSE,
382
    [EADDRNOTAVAIL]        = TARGET_EADDRNOTAVAIL,
383
    [ENETDOWN]                = TARGET_ENETDOWN,
384
    [ENETUNREACH]        = TARGET_ENETUNREACH,
385
    [ENETRESET]                = TARGET_ENETRESET,
386
    [ECONNABORTED]        = TARGET_ECONNABORTED,
387
    [ECONNRESET]        = TARGET_ECONNRESET,
388
    [ENOBUFS]                = TARGET_ENOBUFS,
389
    [EISCONN]                = TARGET_EISCONN,
390
    [ENOTCONN]                = TARGET_ENOTCONN,
391
    [EUCLEAN]                = TARGET_EUCLEAN,
392
    [ENOTNAM]                = TARGET_ENOTNAM,
393
    [ENAVAIL]                = TARGET_ENAVAIL,
394
    [EISNAM]                = TARGET_EISNAM,
395
    [EREMOTEIO]                = TARGET_EREMOTEIO,
396
    [ESHUTDOWN]                = TARGET_ESHUTDOWN,
397
    [ETOOMANYREFS]        = TARGET_ETOOMANYREFS,
398
    [ETIMEDOUT]                = TARGET_ETIMEDOUT,
399
    [ECONNREFUSED]        = TARGET_ECONNREFUSED,
400
    [EHOSTDOWN]                = TARGET_EHOSTDOWN,
401
    [EHOSTUNREACH]        = TARGET_EHOSTUNREACH,
402
    [EALREADY]                = TARGET_EALREADY,
403
    [EINPROGRESS]        = TARGET_EINPROGRESS,
404
    [ESTALE]                = TARGET_ESTALE,
405
    [ECANCELED]                = TARGET_ECANCELED,
406
    [ENOMEDIUM]                = TARGET_ENOMEDIUM,
407
    [EMEDIUMTYPE]        = TARGET_EMEDIUMTYPE,
408
#ifdef ENOKEY
409
    [ENOKEY]                = TARGET_ENOKEY,
410
#endif
411
#ifdef EKEYEXPIRED
412
    [EKEYEXPIRED]        = TARGET_EKEYEXPIRED,
413
#endif
414
#ifdef EKEYREVOKED
415
    [EKEYREVOKED]        = TARGET_EKEYREVOKED,
416
#endif
417
#ifdef EKEYREJECTED
418
    [EKEYREJECTED]        = TARGET_EKEYREJECTED,
419
#endif
420
#ifdef EOWNERDEAD
421
    [EOWNERDEAD]        = TARGET_EOWNERDEAD,
422
#endif
423
#ifdef ENOTRECOVERABLE
424
    [ENOTRECOVERABLE]        = TARGET_ENOTRECOVERABLE,
425
#endif
426
};
427

    
428
static inline int host_to_target_errno(int err)
429
{
430
    if(host_to_target_errno_table[err])
431
        return host_to_target_errno_table[err];
432
    return err;
433
}
434

    
435
static inline int target_to_host_errno(int err)
436
{
437
    if (target_to_host_errno_table[err])
438
        return target_to_host_errno_table[err];
439
    return err;
440
}
441

    
442
static inline abi_long get_errno(abi_long ret)
443
{
444
    if (ret == -1)
445
        return -host_to_target_errno(errno);
446
    else
447
        return ret;
448
}
449

    
450
static inline int is_error(abi_long ret)
451
{
452
    return (abi_ulong)ret >= (abi_ulong)(-4096);
453
}
454

    
455
char *target_strerror(int err)
456
{
457
    return strerror(target_to_host_errno(err));
458
}
459

    
460
static abi_ulong target_brk;
461
static abi_ulong target_original_brk;
462

    
463
void target_set_brk(abi_ulong new_brk)
464
{
465
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
466
}
467

    
468
/* do_brk() must return target values and target errnos. */
469
abi_long do_brk(abi_ulong new_brk)
470
{
471
    abi_ulong brk_page;
472
    abi_long mapped_addr;
473
    int        new_alloc_size;
474

    
475
    if (!new_brk)
476
        return target_brk;
477
    if (new_brk < target_original_brk)
478
        return target_brk;
479

    
480
    brk_page = HOST_PAGE_ALIGN(target_brk);
481

    
482
    /* If the new brk is less than this, set it and we're done... */
483
    if (new_brk < brk_page) {
484
        target_brk = new_brk;
485
            return target_brk;
486
    }
487

    
488
    /* We need to allocate more memory after the brk... */
489
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
490
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
491
                                        PROT_READ|PROT_WRITE,
492
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
493

    
494
    if (!is_error(mapped_addr))
495
        target_brk = new_brk;
496
    
497
    return target_brk;
498
}
499

    
500
static inline abi_long copy_from_user_fdset(fd_set *fds,
501
                                            abi_ulong target_fds_addr,
502
                                            int n)
503
{
504
    int i, nw, j, k;
505
    abi_ulong b, *target_fds;
506

    
507
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
508
    if (!(target_fds = lock_user(VERIFY_READ,
509
                                 target_fds_addr,
510
                                 sizeof(abi_ulong) * nw,
511
                                 1)))
512
        return -TARGET_EFAULT;
513

    
514
    FD_ZERO(fds);
515
    k = 0;
516
    for (i = 0; i < nw; i++) {
517
        /* grab the abi_ulong */
518
        __get_user(b, &target_fds[i]);
519
        for (j = 0; j < TARGET_ABI_BITS; j++) {
520
            /* check the bit inside the abi_ulong */
521
            if ((b >> j) & 1)
522
                FD_SET(k, fds);
523
            k++;
524
        }
525
    }
526

    
527
    unlock_user(target_fds, target_fds_addr, 0);
528

    
529
    return 0;
530
}
531

    
532
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
533
                                          const fd_set *fds,
534
                                          int n)
535
{
536
    int i, nw, j, k;
537
    abi_long v;
538
    abi_ulong *target_fds;
539

    
540
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
541
    if (!(target_fds = lock_user(VERIFY_WRITE,
542
                                 target_fds_addr,
543
                                 sizeof(abi_ulong) * nw,
544
                                 0)))
545
        return -TARGET_EFAULT;
546

    
547
    k = 0;
548
    for (i = 0; i < nw; i++) {
549
        v = 0;
550
        for (j = 0; j < TARGET_ABI_BITS; j++) {
551
            v |= ((FD_ISSET(k, fds) != 0) << j);
552
            k++;
553
        }
554
        __put_user(v, &target_fds[i]);
555
    }
556

    
557
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
558

    
559
    return 0;
560
}
561

    
562
#if defined(__alpha__)
563
#define HOST_HZ 1024
564
#else
565
#define HOST_HZ 100
566
#endif
567

    
568
static inline abi_long host_to_target_clock_t(long ticks)
569
{
570
#if HOST_HZ == TARGET_HZ
571
    return ticks;
572
#else
573
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
574
#endif
575
}
576

    
577
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
578
                                             const struct rusage *rusage)
579
{
580
    struct target_rusage *target_rusage;
581

    
582
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
583
        return -TARGET_EFAULT;
584
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
585
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
586
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
587
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
588
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
589
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
590
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
591
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
592
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
593
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
594
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
595
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
596
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
597
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
598
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
599
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
600
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
601
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
602
    unlock_user_struct(target_rusage, target_addr, 1);
603

    
604
    return 0;
605
}
606

    
607
static inline abi_long copy_from_user_timeval(struct timeval *tv,
608
                                              abi_ulong target_tv_addr)
609
{
610
    struct target_timeval *target_tv;
611

    
612
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
613
        return -TARGET_EFAULT;
614

    
615
    __get_user(tv->tv_sec, &target_tv->tv_sec);
616
    __get_user(tv->tv_usec, &target_tv->tv_usec);
617

    
618
    unlock_user_struct(target_tv, target_tv_addr, 0);
619

    
620
    return 0;
621
}
622

    
623
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
624
                                            const struct timeval *tv)
625
{
626
    struct target_timeval *target_tv;
627

    
628
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
629
        return -TARGET_EFAULT;
630

    
631
    __put_user(tv->tv_sec, &target_tv->tv_sec);
632
    __put_user(tv->tv_usec, &target_tv->tv_usec);
633

    
634
    unlock_user_struct(target_tv, target_tv_addr, 1);
635

    
636
    return 0;
637
}
638

    
639
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
640
                                              abi_ulong target_mq_attr_addr)
641
{
642
    struct target_mq_attr *target_mq_attr;
643

    
644
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
645
                          target_mq_attr_addr, 1))
646
        return -TARGET_EFAULT;
647

    
648
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
649
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
650
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
651
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
652

    
653
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
654

    
655
    return 0;
656
}
657

    
658
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
659
                                            const struct mq_attr *attr)
660
{
661
    struct target_mq_attr *target_mq_attr;
662

    
663
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
664
                          target_mq_attr_addr, 0))
665
        return -TARGET_EFAULT;
666

    
667
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
668
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
669
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
670
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
671

    
672
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
673

    
674
    return 0;
675
}
676

    
677
/* do_select() must return target values and target errnos. */
678
static abi_long do_select(int n,
679
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
680
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
681
{
682
    fd_set rfds, wfds, efds;
683
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
684
    struct timeval tv, *tv_ptr;
685
    abi_long ret;
686

    
687
    if (rfd_addr) {
688
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
689
            return -TARGET_EFAULT;
690
        rfds_ptr = &rfds;
691
    } else {
692
        rfds_ptr = NULL;
693
    }
694
    if (wfd_addr) {
695
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
696
            return -TARGET_EFAULT;
697
        wfds_ptr = &wfds;
698
    } else {
699
        wfds_ptr = NULL;
700
    }
701
    if (efd_addr) {
702
        if (copy_from_user_fdset(&efds, efd_addr, n))
703
            return -TARGET_EFAULT;
704
        efds_ptr = &efds;
705
    } else {
706
        efds_ptr = NULL;
707
    }
708

    
709
    if (target_tv_addr) {
710
        if (copy_from_user_timeval(&tv, target_tv_addr))
711
            return -TARGET_EFAULT;
712
        tv_ptr = &tv;
713
    } else {
714
        tv_ptr = NULL;
715
    }
716

    
717
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
718

    
719
    if (!is_error(ret)) {
720
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
721
            return -TARGET_EFAULT;
722
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
723
            return -TARGET_EFAULT;
724
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
725
            return -TARGET_EFAULT;
726

    
727
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
728
            return -TARGET_EFAULT;
729
    }
730

    
731
    return ret;
732
}
733

    
734
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
735
                                               abi_ulong target_addr,
736
                                               socklen_t len)
737
{
738
    struct target_sockaddr *target_saddr;
739

    
740
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
741
    if (!target_saddr)
742
        return -TARGET_EFAULT;
743
    memcpy(addr, target_saddr, len);
744
    addr->sa_family = tswap16(target_saddr->sa_family);
745
    unlock_user(target_saddr, target_addr, 0);
746

    
747
    return 0;
748
}
749

    
750
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
751
                                               struct sockaddr *addr,
752
                                               socklen_t len)
753
{
754
    struct target_sockaddr *target_saddr;
755

    
756
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
757
    if (!target_saddr)
758
        return -TARGET_EFAULT;
759
    memcpy(target_saddr, addr, len);
760
    target_saddr->sa_family = tswap16(addr->sa_family);
761
    unlock_user(target_saddr, target_addr, len);
762

    
763
    return 0;
764
}
765

    
766
/* ??? Should this also swap msgh->name?  */
767
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
768
                                           struct target_msghdr *target_msgh)
769
{
770
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
771
    abi_long msg_controllen;
772
    abi_ulong target_cmsg_addr;
773
    struct target_cmsghdr *target_cmsg;
774
    socklen_t space = 0;
775
    
776
    msg_controllen = tswapl(target_msgh->msg_controllen);
777
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
778
        goto the_end;
779
    target_cmsg_addr = tswapl(target_msgh->msg_control);
780
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
781
    if (!target_cmsg)
782
        return -TARGET_EFAULT;
783

    
784
    while (cmsg && target_cmsg) {
785
        void *data = CMSG_DATA(cmsg);
786
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
787

    
788
        int len = tswapl(target_cmsg->cmsg_len)
789
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
790

    
791
        space += CMSG_SPACE(len);
792
        if (space > msgh->msg_controllen) {
793
            space -= CMSG_SPACE(len);
794
            gemu_log("Host cmsg overflow\n");
795
            break;
796
        }
797

    
798
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
799
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
800
        cmsg->cmsg_len = CMSG_LEN(len);
801

    
802
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
803
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
804
            memcpy(data, target_data, len);
805
        } else {
806
            int *fd = (int *)data;
807
            int *target_fd = (int *)target_data;
808
            int i, numfds = len / sizeof(int);
809

    
810
            for (i = 0; i < numfds; i++)
811
                fd[i] = tswap32(target_fd[i]);
812
        }
813

    
814
        cmsg = CMSG_NXTHDR(msgh, cmsg);
815
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
816
    }
817
    unlock_user(target_cmsg, target_cmsg_addr, 0);
818
 the_end:
819
    msgh->msg_controllen = space;
820
    return 0;
821
}
822

    
823
/* ??? Should this also swap msgh->name?  */
824
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
825
                                           struct msghdr *msgh)
826
{
827
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
828
    abi_long msg_controllen;
829
    abi_ulong target_cmsg_addr;
830
    struct target_cmsghdr *target_cmsg;
831
    socklen_t space = 0;
832

    
833
    msg_controllen = tswapl(target_msgh->msg_controllen);
834
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
835
        goto the_end;
836
    target_cmsg_addr = tswapl(target_msgh->msg_control);
837
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
838
    if (!target_cmsg)
839
        return -TARGET_EFAULT;
840

    
841
    while (cmsg && target_cmsg) {
842
        void *data = CMSG_DATA(cmsg);
843
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
844

    
845
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
846

    
847
        space += TARGET_CMSG_SPACE(len);
848
        if (space > msg_controllen) {
849
            space -= TARGET_CMSG_SPACE(len);
850
            gemu_log("Target cmsg overflow\n");
851
            break;
852
        }
853

    
854
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
855
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
856
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
857

    
858
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
859
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
860
            memcpy(target_data, data, len);
861
        } else {
862
            int *fd = (int *)data;
863
            int *target_fd = (int *)target_data;
864
            int i, numfds = len / sizeof(int);
865

    
866
            for (i = 0; i < numfds; i++)
867
                target_fd[i] = tswap32(fd[i]);
868
        }
869

    
870
        cmsg = CMSG_NXTHDR(msgh, cmsg);
871
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
872
    }
873
    unlock_user(target_cmsg, target_cmsg_addr, space);
874
 the_end:
875
    target_msgh->msg_controllen = tswapl(space);
876
    return 0;
877
}
878

    
879
/* do_setsockopt() Must return target values and target errnos. */
880
static abi_long do_setsockopt(int sockfd, int level, int optname,
881
                              abi_ulong optval_addr, socklen_t optlen)
882
{
883
    abi_long ret;
884
    int val;
885

    
886
    switch(level) {
887
    case SOL_TCP:
888
        /* TCP options all take an 'int' value.  */
889
        if (optlen < sizeof(uint32_t))
890
            return -TARGET_EINVAL;
891

    
892
        if (get_user_u32(val, optval_addr))
893
            return -TARGET_EFAULT;
894
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
895
        break;
896
    case SOL_IP:
897
        switch(optname) {
898
        case IP_TOS:
899
        case IP_TTL:
900
        case IP_HDRINCL:
901
        case IP_ROUTER_ALERT:
902
        case IP_RECVOPTS:
903
        case IP_RETOPTS:
904
        case IP_PKTINFO:
905
        case IP_MTU_DISCOVER:
906
        case IP_RECVERR:
907
        case IP_RECVTOS:
908
#ifdef IP_FREEBIND
909
        case IP_FREEBIND:
910
#endif
911
        case IP_MULTICAST_TTL:
912
        case IP_MULTICAST_LOOP:
913
            val = 0;
914
            if (optlen >= sizeof(uint32_t)) {
915
                if (get_user_u32(val, optval_addr))
916
                    return -TARGET_EFAULT;
917
            } else if (optlen >= 1) {
918
                if (get_user_u8(val, optval_addr))
919
                    return -TARGET_EFAULT;
920
            }
921
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
922
            break;
923
        default:
924
            goto unimplemented;
925
        }
926
        break;
927
    case TARGET_SOL_SOCKET:
928
        switch (optname) {
929
            /* Options with 'int' argument.  */
930
        case TARGET_SO_DEBUG:
931
                optname = SO_DEBUG;
932
                break;
933
        case TARGET_SO_REUSEADDR:
934
                optname = SO_REUSEADDR;
935
                break;
936
        case TARGET_SO_TYPE:
937
                optname = SO_TYPE;
938
                break;
939
        case TARGET_SO_ERROR:
940
                optname = SO_ERROR;
941
                break;
942
        case TARGET_SO_DONTROUTE:
943
                optname = SO_DONTROUTE;
944
                break;
945
        case TARGET_SO_BROADCAST:
946
                optname = SO_BROADCAST;
947
                break;
948
        case TARGET_SO_SNDBUF:
949
                optname = SO_SNDBUF;
950
                break;
951
        case TARGET_SO_RCVBUF:
952
                optname = SO_RCVBUF;
953
                break;
954
        case TARGET_SO_KEEPALIVE:
955
                optname = SO_KEEPALIVE;
956
                break;
957
        case TARGET_SO_OOBINLINE:
958
                optname = SO_OOBINLINE;
959
                break;
960
        case TARGET_SO_NO_CHECK:
961
                optname = SO_NO_CHECK;
962
                break;
963
        case TARGET_SO_PRIORITY:
964
                optname = SO_PRIORITY;
965
                break;
966
#ifdef SO_BSDCOMPAT
967
        case TARGET_SO_BSDCOMPAT:
968
                optname = SO_BSDCOMPAT;
969
                break;
970
#endif
971
        case TARGET_SO_PASSCRED:
972
                optname = SO_PASSCRED;
973
                break;
974
        case TARGET_SO_TIMESTAMP:
975
                optname = SO_TIMESTAMP;
976
                break;
977
        case TARGET_SO_RCVLOWAT:
978
                optname = SO_RCVLOWAT;
979
                break;
980
        case TARGET_SO_RCVTIMEO:
981
                optname = SO_RCVTIMEO;
982
                break;
983
        case TARGET_SO_SNDTIMEO:
984
                optname = SO_SNDTIMEO;
985
                break;
986
            break;
987
        default:
988
            goto unimplemented;
989
        }
990
        if (optlen < sizeof(uint32_t))
991
            return -TARGET_EINVAL;
992

    
993
        if (get_user_u32(val, optval_addr))
994
            return -TARGET_EFAULT;
995
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
996
        break;
997
    default:
998
    unimplemented:
999
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1000
        ret = -TARGET_ENOPROTOOPT;
1001
    }
1002
    return ret;
1003
}
1004

    
1005
/* do_getsockopt() Must return target values and target errnos. */
1006
static abi_long do_getsockopt(int sockfd, int level, int optname,
1007
                              abi_ulong optval_addr, abi_ulong optlen)
1008
{
1009
    abi_long ret;
1010
    int len, val;
1011
    socklen_t lv;
1012

    
1013
    switch(level) {
1014
    case TARGET_SOL_SOCKET:
1015
            level = SOL_SOCKET;
1016
        switch (optname) {
1017
        case TARGET_SO_LINGER:
1018
        case TARGET_SO_RCVTIMEO:
1019
        case TARGET_SO_SNDTIMEO:
1020
        case TARGET_SO_PEERCRED:
1021
        case TARGET_SO_PEERNAME:
1022
            /* These don't just return a single integer */
1023
            goto unimplemented;
1024
        default:
1025
            goto int_case;
1026
        }
1027
        break;
1028
    case SOL_TCP:
1029
        /* TCP options all take an 'int' value.  */
1030
    int_case:
1031
        if (get_user_u32(len, optlen))
1032
            return -TARGET_EFAULT;
1033
        if (len < 0)
1034
            return -TARGET_EINVAL;
1035
        lv = sizeof(int);
1036
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1037
        if (ret < 0)
1038
            return ret;
1039
        val = tswap32(val);
1040
        if (len > lv)
1041
            len = lv;
1042
        if (len == 4) {
1043
            if (put_user_u32(val, optval_addr))
1044
                return -TARGET_EFAULT;
1045
        } else {
1046
            if (put_user_u8(val, optval_addr))
1047
                return -TARGET_EFAULT;
1048
        }
1049
        if (put_user_u32(len, optlen))
1050
            return -TARGET_EFAULT;
1051
        break;
1052
    case SOL_IP:
1053
        switch(optname) {
1054
        case IP_TOS:
1055
        case IP_TTL:
1056
        case IP_HDRINCL:
1057
        case IP_ROUTER_ALERT:
1058
        case IP_RECVOPTS:
1059
        case IP_RETOPTS:
1060
        case IP_PKTINFO:
1061
        case IP_MTU_DISCOVER:
1062
        case IP_RECVERR:
1063
        case IP_RECVTOS:
1064
#ifdef IP_FREEBIND
1065
        case IP_FREEBIND:
1066
#endif
1067
        case IP_MULTICAST_TTL:
1068
        case IP_MULTICAST_LOOP:
1069
            if (get_user_u32(len, optlen))
1070
                return -TARGET_EFAULT;
1071
            if (len < 0)
1072
                return -TARGET_EINVAL;
1073
            lv = sizeof(int);
1074
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1075
            if (ret < 0)
1076
                return ret;
1077
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1078
                len = 1;
1079
                if (put_user_u32(len, optlen)
1080
                    || put_user_u8(val, optval_addr))
1081
                    return -TARGET_EFAULT;
1082
            } else {
1083
                if (len > sizeof(int))
1084
                    len = sizeof(int);
1085
                if (put_user_u32(len, optlen)
1086
                    || put_user_u32(val, optval_addr))
1087
                    return -TARGET_EFAULT;
1088
            }
1089
            break;
1090
        default:
1091
            ret = -TARGET_ENOPROTOOPT;
1092
            break;
1093
        }
1094
        break;
1095
    default:
1096
    unimplemented:
1097
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1098
                 level, optname);
1099
        ret = -TARGET_EOPNOTSUPP;
1100
        break;
1101
    }
1102
    return ret;
1103
}
1104

    
1105
/* FIXME
1106
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1107
 * other lock functions have a return code of 0 for failure.
1108
 */
1109
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1110
                           int count, int copy)
1111
{
1112
    struct target_iovec *target_vec;
1113
    abi_ulong base;
1114
    int i;
1115

    
1116
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1117
    if (!target_vec)
1118
        return -TARGET_EFAULT;
1119
    for(i = 0;i < count; i++) {
1120
        base = tswapl(target_vec[i].iov_base);
1121
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1122
        if (vec[i].iov_len != 0) {
1123
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1124
            /* Don't check lock_user return value. We must call writev even
1125
               if a element has invalid base address. */
1126
        } else {
1127
            /* zero length pointer is ignored */
1128
            vec[i].iov_base = NULL;
1129
        }
1130
    }
1131
    unlock_user (target_vec, target_addr, 0);
1132
    return 0;
1133
}
1134

    
1135
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1136
                             int count, int copy)
1137
{
1138
    struct target_iovec *target_vec;
1139
    abi_ulong base;
1140
    int i;
1141

    
1142
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1143
    if (!target_vec)
1144
        return -TARGET_EFAULT;
1145
    for(i = 0;i < count; i++) {
1146
        if (target_vec[i].iov_base) {
1147
            base = tswapl(target_vec[i].iov_base);
1148
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1149
        }
1150
    }
1151
    unlock_user (target_vec, target_addr, 0);
1152

    
1153
    return 0;
1154
}
1155

    
1156
/* do_socket() Must return target values and target errnos. */
1157
static abi_long do_socket(int domain, int type, int protocol)
1158
{
1159
#if defined(TARGET_MIPS)
1160
    switch(type) {
1161
    case TARGET_SOCK_DGRAM:
1162
        type = SOCK_DGRAM;
1163
        break;
1164
    case TARGET_SOCK_STREAM:
1165
        type = SOCK_STREAM;
1166
        break;
1167
    case TARGET_SOCK_RAW:
1168
        type = SOCK_RAW;
1169
        break;
1170
    case TARGET_SOCK_RDM:
1171
        type = SOCK_RDM;
1172
        break;
1173
    case TARGET_SOCK_SEQPACKET:
1174
        type = SOCK_SEQPACKET;
1175
        break;
1176
    case TARGET_SOCK_PACKET:
1177
        type = SOCK_PACKET;
1178
        break;
1179
    }
1180
#endif
1181
    if (domain == PF_NETLINK)
1182
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1183
    return get_errno(socket(domain, type, protocol));
1184
}
1185

    
1186
/* MAX_SOCK_ADDR from linux/net/socket.c */
1187
#define MAX_SOCK_ADDR        128
1188

    
1189
/* do_bind() Must return target values and target errnos. */
1190
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1191
                        socklen_t addrlen)
1192
{
1193
    void *addr;
1194

    
1195
    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1196
        return -TARGET_EINVAL;
1197

    
1198
    addr = alloca(addrlen);
1199

    
1200
    target_to_host_sockaddr(addr, target_addr, addrlen);
1201
    return get_errno(bind(sockfd, addr, addrlen));
1202
}
1203

    
1204
/* do_connect() Must return target values and target errnos. */
1205
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1206
                           socklen_t addrlen)
1207
{
1208
    void *addr;
1209

    
1210
    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1211
        return -TARGET_EINVAL;
1212

    
1213
    addr = alloca(addrlen);
1214

    
1215
    target_to_host_sockaddr(addr, target_addr, addrlen);
1216
    return get_errno(connect(sockfd, addr, addrlen));
1217
}
1218

    
1219
/* do_sendrecvmsg() Must return target values and target errnos. */
1220
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1221
                               int flags, int send)
1222
{
1223
    abi_long ret, len;
1224
    struct target_msghdr *msgp;
1225
    struct msghdr msg;
1226
    int count;
1227
    struct iovec *vec;
1228
    abi_ulong target_vec;
1229

    
1230
    /* FIXME */
1231
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1232
                          msgp,
1233
                          target_msg,
1234
                          send ? 1 : 0))
1235
        return -TARGET_EFAULT;
1236
    if (msgp->msg_name) {
1237
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1238
        msg.msg_name = alloca(msg.msg_namelen);
1239
        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1240
                                msg.msg_namelen);
1241
    } else {
1242
        msg.msg_name = NULL;
1243
        msg.msg_namelen = 0;
1244
    }
1245
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1246
    msg.msg_control = alloca(msg.msg_controllen);
1247
    msg.msg_flags = tswap32(msgp->msg_flags);
1248

    
1249
    count = tswapl(msgp->msg_iovlen);
1250
    vec = alloca(count * sizeof(struct iovec));
1251
    target_vec = tswapl(msgp->msg_iov);
1252
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1253
    msg.msg_iovlen = count;
1254
    msg.msg_iov = vec;
1255

    
1256
    if (send) {
1257
        ret = target_to_host_cmsg(&msg, msgp);
1258
        if (ret == 0)
1259
            ret = get_errno(sendmsg(fd, &msg, flags));
1260
    } else {
1261
        ret = get_errno(recvmsg(fd, &msg, flags));
1262
        if (!is_error(ret)) {
1263
            len = ret;
1264
            ret = host_to_target_cmsg(msgp, &msg);
1265
            if (!is_error(ret))
1266
                ret = len;
1267
        }
1268
    }
1269
    unlock_iovec(vec, target_vec, count, !send);
1270
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1271
    return ret;
1272
}
1273

    
1274
/* do_accept() Must return target values and target errnos. */
1275
static abi_long do_accept(int fd, abi_ulong target_addr,
1276
                          abi_ulong target_addrlen_addr)
1277
{
1278
    socklen_t addrlen;
1279
    void *addr;
1280
    abi_long ret;
1281

    
1282
    if (get_user_u32(addrlen, target_addrlen_addr))
1283
        return -TARGET_EFAULT;
1284

    
1285
    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1286
        return -TARGET_EINVAL;
1287

    
1288
    addr = alloca(addrlen);
1289

    
1290
    ret = get_errno(accept(fd, addr, &addrlen));
1291
    if (!is_error(ret)) {
1292
        host_to_target_sockaddr(target_addr, addr, addrlen);
1293
        if (put_user_u32(addrlen, target_addrlen_addr))
1294
            ret = -TARGET_EFAULT;
1295
    }
1296
    return ret;
1297
}
1298

    
1299
/* do_getpeername() Must return target values and target errnos. */
1300
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1301
                               abi_ulong target_addrlen_addr)
1302
{
1303
    socklen_t addrlen;
1304
    void *addr;
1305
    abi_long ret;
1306

    
1307
    if (get_user_u32(addrlen, target_addrlen_addr))
1308
        return -TARGET_EFAULT;
1309

    
1310
    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1311
        return -TARGET_EINVAL;
1312

    
1313
    addr = alloca(addrlen);
1314

    
1315
    ret = get_errno(getpeername(fd, addr, &addrlen));
1316
    if (!is_error(ret)) {
1317
        host_to_target_sockaddr(target_addr, addr, addrlen);
1318
        if (put_user_u32(addrlen, target_addrlen_addr))
1319
            ret = -TARGET_EFAULT;
1320
    }
1321
    return ret;
1322
}
1323

    
1324
/* do_getsockname() Must return target values and target errnos. */
1325
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1326
                               abi_ulong target_addrlen_addr)
1327
{
1328
    socklen_t addrlen;
1329
    void *addr;
1330
    abi_long ret;
1331

    
1332
    if (target_addr == 0)
1333
       return get_errno(accept(fd, NULL, NULL));
1334

    
1335
    if (get_user_u32(addrlen, target_addrlen_addr))
1336
        return -TARGET_EFAULT;
1337

    
1338
    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1339
        return -TARGET_EINVAL;
1340

    
1341
    addr = alloca(addrlen);
1342

    
1343
    ret = get_errno(getsockname(fd, addr, &addrlen));
1344
    if (!is_error(ret)) {
1345
        host_to_target_sockaddr(target_addr, addr, addrlen);
1346
        if (put_user_u32(addrlen, target_addrlen_addr))
1347
            ret = -TARGET_EFAULT;
1348
    }
1349
    return ret;
1350
}
1351

    
1352
/* do_socketpair() Must return target values and target errnos. */
1353
static abi_long do_socketpair(int domain, int type, int protocol,
1354
                              abi_ulong target_tab_addr)
1355
{
1356
    int tab[2];
1357
    abi_long ret;
1358

    
1359
    ret = get_errno(socketpair(domain, type, protocol, tab));
1360
    if (!is_error(ret)) {
1361
        if (put_user_s32(tab[0], target_tab_addr)
1362
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1363
            ret = -TARGET_EFAULT;
1364
    }
1365
    return ret;
1366
}
1367

    
1368
/* do_sendto() Must return target values and target errnos. */
1369
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1370
                          abi_ulong target_addr, socklen_t addrlen)
1371
{
1372
    void *addr;
1373
    void *host_msg;
1374
    abi_long ret;
1375

    
1376
    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1377
        return -TARGET_EINVAL;
1378

    
1379
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1380
    if (!host_msg)
1381
        return -TARGET_EFAULT;
1382
    if (target_addr) {
1383
        addr = alloca(addrlen);
1384
        target_to_host_sockaddr(addr, target_addr, addrlen);
1385
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1386
    } else {
1387
        ret = get_errno(send(fd, host_msg, len, flags));
1388
    }
1389
    unlock_user(host_msg, msg, 0);
1390
    return ret;
1391
}
1392

    
1393
/* do_recvfrom() Must return target values and target errnos. */
1394
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1395
                            abi_ulong target_addr,
1396
                            abi_ulong target_addrlen)
1397
{
1398
    socklen_t addrlen;
1399
    void *addr;
1400
    void *host_msg;
1401
    abi_long ret;
1402

    
1403
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1404
    if (!host_msg)
1405
        return -TARGET_EFAULT;
1406
    if (target_addr) {
1407
        if (get_user_u32(addrlen, target_addrlen)) {
1408
            ret = -TARGET_EFAULT;
1409
            goto fail;
1410
        }
1411
        if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) {
1412
            ret = -TARGET_EINVAL;
1413
            goto fail;
1414
        }
1415
        addr = alloca(addrlen);
1416
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1417
    } else {
1418
        addr = NULL; /* To keep compiler quiet.  */
1419
        ret = get_errno(recv(fd, host_msg, len, flags));
1420
    }
1421
    if (!is_error(ret)) {
1422
        if (target_addr) {
1423
            host_to_target_sockaddr(target_addr, addr, addrlen);
1424
            if (put_user_u32(addrlen, target_addrlen)) {
1425
                ret = -TARGET_EFAULT;
1426
                goto fail;
1427
            }
1428
        }
1429
        unlock_user(host_msg, msg, len);
1430
    } else {
1431
fail:
1432
        unlock_user(host_msg, msg, 0);
1433
    }
1434
    return ret;
1435
}
1436

    
1437
#ifdef TARGET_NR_socketcall
1438
/* do_socketcall() Must return target values and target errnos. */
1439
static abi_long do_socketcall(int num, abi_ulong vptr)
1440
{
1441
    abi_long ret;
1442
    const int n = sizeof(abi_ulong);
1443

    
1444
    switch(num) {
1445
    case SOCKOP_socket:
1446
        {
1447
            int domain, type, protocol;
1448

    
1449
            if (get_user_s32(domain, vptr)
1450
                || get_user_s32(type, vptr + n)
1451
                || get_user_s32(protocol, vptr + 2 * n))
1452
                return -TARGET_EFAULT;
1453

    
1454
            ret = do_socket(domain, type, protocol);
1455
        }
1456
        break;
1457
    case SOCKOP_bind:
1458
        {
1459
            int sockfd;
1460
            abi_ulong target_addr;
1461
            socklen_t addrlen;
1462

    
1463
            if (get_user_s32(sockfd, vptr)
1464
                || get_user_ual(target_addr, vptr + n)
1465
                || get_user_u32(addrlen, vptr + 2 * n))
1466
                return -TARGET_EFAULT;
1467

    
1468
            ret = do_bind(sockfd, target_addr, addrlen);
1469
        }
1470
        break;
1471
    case SOCKOP_connect:
1472
        {
1473
            int sockfd;
1474
            abi_ulong target_addr;
1475
            socklen_t addrlen;
1476

    
1477
            if (get_user_s32(sockfd, vptr)
1478
                || get_user_ual(target_addr, vptr + n)
1479
                || get_user_u32(addrlen, vptr + 2 * n))
1480
                return -TARGET_EFAULT;
1481

    
1482
            ret = do_connect(sockfd, target_addr, addrlen);
1483
        }
1484
        break;
1485
    case SOCKOP_listen:
1486
        {
1487
            int sockfd, backlog;
1488

    
1489
            if (get_user_s32(sockfd, vptr)
1490
                || get_user_s32(backlog, vptr + n))
1491
                return -TARGET_EFAULT;
1492

    
1493
            ret = get_errno(listen(sockfd, backlog));
1494
        }
1495
        break;
1496
    case SOCKOP_accept:
1497
        {
1498
            int sockfd;
1499
            abi_ulong target_addr, target_addrlen;
1500

    
1501
            if (get_user_s32(sockfd, vptr)
1502
                || get_user_ual(target_addr, vptr + n)
1503
                || get_user_u32(target_addrlen, vptr + 2 * n))
1504
                return -TARGET_EFAULT;
1505

    
1506
            ret = do_accept(sockfd, target_addr, target_addrlen);
1507
        }
1508
        break;
1509
    case SOCKOP_getsockname:
1510
        {
1511
            int sockfd;
1512
            abi_ulong target_addr, target_addrlen;
1513

    
1514
            if (get_user_s32(sockfd, vptr)
1515
                || get_user_ual(target_addr, vptr + n)
1516
                || get_user_u32(target_addrlen, vptr + 2 * n))
1517
                return -TARGET_EFAULT;
1518

    
1519
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1520
        }
1521
        break;
1522
    case SOCKOP_getpeername:
1523
        {
1524
            int sockfd;
1525
            abi_ulong target_addr, target_addrlen;
1526

    
1527
            if (get_user_s32(sockfd, vptr)
1528
                || get_user_ual(target_addr, vptr + n)
1529
                || get_user_u32(target_addrlen, vptr + 2 * n))
1530
                return -TARGET_EFAULT;
1531

    
1532
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1533
        }
1534
        break;
1535
    case SOCKOP_socketpair:
1536
        {
1537
            int domain, type, protocol;
1538
            abi_ulong tab;
1539

    
1540
            if (get_user_s32(domain, vptr)
1541
                || get_user_s32(type, vptr + n)
1542
                || get_user_s32(protocol, vptr + 2 * n)
1543
                || get_user_ual(tab, vptr + 3 * n))
1544
                return -TARGET_EFAULT;
1545

    
1546
            ret = do_socketpair(domain, type, protocol, tab);
1547
        }
1548
        break;
1549
    case SOCKOP_send:
1550
        {
1551
            int sockfd;
1552
            abi_ulong msg;
1553
            size_t len;
1554
            int flags;
1555

    
1556
            if (get_user_s32(sockfd, vptr)
1557
                || get_user_ual(msg, vptr + n)
1558
                || get_user_ual(len, vptr + 2 * n)
1559
                || get_user_s32(flags, vptr + 3 * n))
1560
                return -TARGET_EFAULT;
1561

    
1562
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1563
        }
1564
        break;
1565
    case SOCKOP_recv:
1566
        {
1567
            int sockfd;
1568
            abi_ulong msg;
1569
            size_t len;
1570
            int flags;
1571

    
1572
            if (get_user_s32(sockfd, vptr)
1573
                || get_user_ual(msg, vptr + n)
1574
                || get_user_ual(len, vptr + 2 * n)
1575
                || get_user_s32(flags, vptr + 3 * n))
1576
                return -TARGET_EFAULT;
1577

    
1578
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1579
        }
1580
        break;
1581
    case SOCKOP_sendto:
1582
        {
1583
            int sockfd;
1584
            abi_ulong msg;
1585
            size_t len;
1586
            int flags;
1587
            abi_ulong addr;
1588
            socklen_t addrlen;
1589

    
1590
            if (get_user_s32(sockfd, vptr)
1591
                || get_user_ual(msg, vptr + n)
1592
                || get_user_ual(len, vptr + 2 * n)
1593
                || get_user_s32(flags, vptr + 3 * n)
1594
                || get_user_ual(addr, vptr + 4 * n)
1595
                || get_user_u32(addrlen, vptr + 5 * n))
1596
                return -TARGET_EFAULT;
1597

    
1598
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1599
        }
1600
        break;
1601
    case SOCKOP_recvfrom:
1602
        {
1603
            int sockfd;
1604
            abi_ulong msg;
1605
            size_t len;
1606
            int flags;
1607
            abi_ulong addr;
1608
            socklen_t addrlen;
1609

    
1610
            if (get_user_s32(sockfd, vptr)
1611
                || get_user_ual(msg, vptr + n)
1612
                || get_user_ual(len, vptr + 2 * n)
1613
                || get_user_s32(flags, vptr + 3 * n)
1614
                || get_user_ual(addr, vptr + 4 * n)
1615
                || get_user_u32(addrlen, vptr + 5 * n))
1616
                return -TARGET_EFAULT;
1617

    
1618
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1619
        }
1620
        break;
1621
    case SOCKOP_shutdown:
1622
        {
1623
            int sockfd, how;
1624

    
1625
            if (get_user_s32(sockfd, vptr)
1626
                || get_user_s32(how, vptr + n))
1627
                return -TARGET_EFAULT;
1628

    
1629
            ret = get_errno(shutdown(sockfd, how));
1630
        }
1631
        break;
1632
    case SOCKOP_sendmsg:
1633
    case SOCKOP_recvmsg:
1634
        {
1635
            int fd;
1636
            abi_ulong target_msg;
1637
            int flags;
1638

    
1639
            if (get_user_s32(fd, vptr)
1640
                || get_user_ual(target_msg, vptr + n)
1641
                || get_user_s32(flags, vptr + 2 * n))
1642
                return -TARGET_EFAULT;
1643

    
1644
            ret = do_sendrecvmsg(fd, target_msg, flags,
1645
                                 (num == SOCKOP_sendmsg));
1646
        }
1647
        break;
1648
    case SOCKOP_setsockopt:
1649
        {
1650
            int sockfd;
1651
            int level;
1652
            int optname;
1653
            abi_ulong optval;
1654
            socklen_t optlen;
1655

    
1656
            if (get_user_s32(sockfd, vptr)
1657
                || get_user_s32(level, vptr + n)
1658
                || get_user_s32(optname, vptr + 2 * n)
1659
                || get_user_ual(optval, vptr + 3 * n)
1660
                || get_user_u32(optlen, vptr + 4 * n))
1661
                return -TARGET_EFAULT;
1662

    
1663
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1664
        }
1665
        break;
1666
    case SOCKOP_getsockopt:
1667
        {
1668
            int sockfd;
1669
            int level;
1670
            int optname;
1671
            abi_ulong optval;
1672
            socklen_t optlen;
1673

    
1674
            if (get_user_s32(sockfd, vptr)
1675
                || get_user_s32(level, vptr + n)
1676
                || get_user_s32(optname, vptr + 2 * n)
1677
                || get_user_ual(optval, vptr + 3 * n)
1678
                || get_user_u32(optlen, vptr + 4 * n))
1679
                return -TARGET_EFAULT;
1680

    
1681
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1682
        }
1683
        break;
1684
    default:
1685
        gemu_log("Unsupported socketcall: %d\n", num);
1686
        ret = -TARGET_ENOSYS;
1687
        break;
1688
    }
1689
    return ret;
1690
}
1691
#endif
1692

    
1693
#ifdef TARGET_NR_ipc
1694
#define N_SHM_REGIONS        32
1695

    
1696
static struct shm_region {
1697
    abi_ulong        start;
1698
    abi_ulong        size;
1699
} shm_regions[N_SHM_REGIONS];
1700
#endif
1701

    
1702
struct target_ipc_perm
1703
{
1704
    abi_long __key;
1705
    abi_ulong uid;
1706
    abi_ulong gid;
1707
    abi_ulong cuid;
1708
    abi_ulong cgid;
1709
    unsigned short int mode;
1710
    unsigned short int __pad1;
1711
    unsigned short int __seq;
1712
    unsigned short int __pad2;
1713
    abi_ulong __unused1;
1714
    abi_ulong __unused2;
1715
};
1716

    
1717
struct target_semid_ds
1718
{
1719
  struct target_ipc_perm sem_perm;
1720
  abi_ulong sem_otime;
1721
  abi_ulong __unused1;
1722
  abi_ulong sem_ctime;
1723
  abi_ulong __unused2;
1724
  abi_ulong sem_nsems;
1725
  abi_ulong __unused3;
1726
  abi_ulong __unused4;
1727
};
1728

    
1729
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1730
                                               abi_ulong target_addr)
1731
{
1732
    struct target_ipc_perm *target_ip;
1733
    struct target_semid_ds *target_sd;
1734

    
1735
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1736
        return -TARGET_EFAULT;
1737
    target_ip=&(target_sd->sem_perm);
1738
    host_ip->__key = tswapl(target_ip->__key);
1739
    host_ip->uid = tswapl(target_ip->uid);
1740
    host_ip->gid = tswapl(target_ip->gid);
1741
    host_ip->cuid = tswapl(target_ip->cuid);
1742
    host_ip->cgid = tswapl(target_ip->cgid);
1743
    host_ip->mode = tswapl(target_ip->mode);
1744
    unlock_user_struct(target_sd, target_addr, 0);
1745
    return 0;
1746
}
1747

    
1748
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1749
                                               struct ipc_perm *host_ip)
1750
{
1751
    struct target_ipc_perm *target_ip;
1752
    struct target_semid_ds *target_sd;
1753

    
1754
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1755
        return -TARGET_EFAULT;
1756
    target_ip = &(target_sd->sem_perm);
1757
    target_ip->__key = tswapl(host_ip->__key);
1758
    target_ip->uid = tswapl(host_ip->uid);
1759
    target_ip->gid = tswapl(host_ip->gid);
1760
    target_ip->cuid = tswapl(host_ip->cuid);
1761
    target_ip->cgid = tswapl(host_ip->cgid);
1762
    target_ip->mode = tswapl(host_ip->mode);
1763
    unlock_user_struct(target_sd, target_addr, 1);
1764
    return 0;
1765
}
1766

    
1767
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1768
                                               abi_ulong target_addr)
1769
{
1770
    struct target_semid_ds *target_sd;
1771

    
1772
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1773
        return -TARGET_EFAULT;
1774
    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1775
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1776
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
1777
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1778
    unlock_user_struct(target_sd, target_addr, 0);
1779
    return 0;
1780
}
1781

    
1782
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1783
                                               struct semid_ds *host_sd)
1784
{
1785
    struct target_semid_ds *target_sd;
1786

    
1787
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1788
        return -TARGET_EFAULT;
1789
    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1790
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1791
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
1792
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1793
    unlock_user_struct(target_sd, target_addr, 1);
1794
    return 0;
1795
}
1796

    
1797
union semun {
1798
        int val;
1799
        struct semid_ds *buf;
1800
        unsigned short *array;
1801
};
1802

    
1803
union target_semun {
1804
        int val;
1805
        abi_long buf;
1806
        unsigned short int *array;
1807
};
1808

    
1809
static inline abi_long target_to_host_semun(int cmd,
1810
                                            union semun *host_su,
1811
                                            abi_ulong target_addr,
1812
                                            struct semid_ds *ds)
1813
{
1814
    union target_semun *target_su;
1815

    
1816
    switch( cmd ) {
1817
        case IPC_STAT:
1818
        case IPC_SET:
1819
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1820
               return -TARGET_EFAULT;
1821
           target_to_host_semid_ds(ds,target_su->buf);
1822
           host_su->buf = ds;
1823
           unlock_user_struct(target_su, target_addr, 0);
1824
           break;
1825
        case GETVAL:
1826
        case SETVAL:
1827
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1828
               return -TARGET_EFAULT;
1829
           host_su->val = tswapl(target_su->val);
1830
           unlock_user_struct(target_su, target_addr, 0);
1831
           break;
1832
        case GETALL:
1833
        case SETALL:
1834
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1835
               return -TARGET_EFAULT;
1836
           *host_su->array = tswap16(*target_su->array);
1837
           unlock_user_struct(target_su, target_addr, 0);
1838
           break;
1839
        default:
1840
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1841
    }
1842
    return 0;
1843
}
1844

    
1845
static inline abi_long host_to_target_semun(int cmd,
1846
                                            abi_ulong target_addr,
1847
                                            union semun *host_su,
1848
                                            struct semid_ds *ds)
1849
{
1850
    union target_semun *target_su;
1851

    
1852
    switch( cmd ) {
1853
        case IPC_STAT:
1854
        case IPC_SET:
1855
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1856
               return -TARGET_EFAULT;
1857
           host_to_target_semid_ds(target_su->buf,ds);
1858
           unlock_user_struct(target_su, target_addr, 1);
1859
           break;
1860
        case GETVAL:
1861
        case SETVAL:
1862
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1863
               return -TARGET_EFAULT;
1864
           target_su->val = tswapl(host_su->val);
1865
           unlock_user_struct(target_su, target_addr, 1);
1866
           break;
1867
        case GETALL:
1868
        case SETALL:
1869
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1870
               return -TARGET_EFAULT;
1871
           *target_su->array = tswap16(*host_su->array);
1872
           unlock_user_struct(target_su, target_addr, 1);
1873
           break;
1874
        default:
1875
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1876
    }
1877
    return 0;
1878
}
1879

    
1880
static inline abi_long do_semctl(int first, int second, int third,
1881
                                 abi_long ptr)
1882
{
1883
    union semun arg;
1884
    struct semid_ds dsarg;
1885
    int cmd = third&0xff;
1886
    abi_long ret = 0;
1887

    
1888
    switch( cmd ) {
1889
        case GETVAL:
1890
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1891
            ret = get_errno(semctl(first, second, cmd, arg));
1892
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1893
            break;
1894
        case SETVAL:
1895
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1896
            ret = get_errno(semctl(first, second, cmd, arg));
1897
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1898
            break;
1899
        case GETALL:
1900
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1901
            ret = get_errno(semctl(first, second, cmd, arg));
1902
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1903
            break;
1904
        case SETALL:
1905
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1906
            ret = get_errno(semctl(first, second, cmd, arg));
1907
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1908
            break;
1909
        case IPC_STAT:
1910
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1911
            ret = get_errno(semctl(first, second, cmd, arg));
1912
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1913
            break;
1914
        case IPC_SET:
1915
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1916
            ret = get_errno(semctl(first, second, cmd, arg));
1917
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1918
            break;
1919
    default:
1920
            ret = get_errno(semctl(first, second, cmd, arg));
1921
    }
1922

    
1923
    return ret;
1924
}
1925

    
1926
struct target_msqid_ds
1927
{
1928
    struct target_ipc_perm msg_perm;
1929
    abi_ulong msg_stime;
1930
#if TARGET_ABI_BITS == 32
1931
    abi_ulong __unused1;
1932
#endif
1933
    abi_ulong msg_rtime;
1934
#if TARGET_ABI_BITS == 32
1935
    abi_ulong __unused2;
1936
#endif
1937
    abi_ulong msg_ctime;
1938
#if TARGET_ABI_BITS == 32
1939
    abi_ulong __unused3;
1940
#endif
1941
    abi_ulong __msg_cbytes;
1942
    abi_ulong msg_qnum;
1943
    abi_ulong msg_qbytes;
1944
    abi_ulong msg_lspid;
1945
    abi_ulong msg_lrpid;
1946
    abi_ulong __unused4;
1947
    abi_ulong __unused5;
1948
};
1949

    
1950
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1951
                                               abi_ulong target_addr)
1952
{
1953
    struct target_msqid_ds *target_md;
1954

    
1955
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1956
        return -TARGET_EFAULT;
1957
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
1958
        return -TARGET_EFAULT;
1959
    host_md->msg_stime = tswapl(target_md->msg_stime);
1960
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
1961
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
1962
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1963
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
1964
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1965
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
1966
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1967
    unlock_user_struct(target_md, target_addr, 0);
1968
    return 0;
1969
}
1970

    
1971
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1972
                                               struct msqid_ds *host_md)
1973
{
1974
    struct target_msqid_ds *target_md;
1975

    
1976
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1977
        return -TARGET_EFAULT;
1978
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
1979
        return -TARGET_EFAULT;
1980
    target_md->msg_stime = tswapl(host_md->msg_stime);
1981
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
1982
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
1983
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1984
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
1985
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1986
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
1987
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1988
    unlock_user_struct(target_md, target_addr, 1);
1989
    return 0;
1990
}
1991

    
1992
struct target_msginfo {
1993
    int msgpool;
1994
    int msgmap;
1995
    int msgmax;
1996
    int msgmnb;
1997
    int msgmni;
1998
    int msgssz;
1999
    int msgtql;
2000
    unsigned short int msgseg;
2001
};
2002

    
2003
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2004
                                              struct msginfo *host_msginfo)
2005
{
2006
    struct target_msginfo *target_msginfo;
2007
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2008
        return -TARGET_EFAULT;
2009
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2010
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2011
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2012
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2013
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2014
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2015
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2016
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2017
    unlock_user_struct(target_msginfo, target_addr, 1);
2018
    return 0;
2019
}
2020

    
2021
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2022
{
2023
    struct msqid_ds dsarg;
2024
    struct msginfo msginfo;
2025
    abi_long ret = -TARGET_EINVAL;
2026

    
2027
    cmd &= 0xff;
2028

    
2029
    switch (cmd) {
2030
    case IPC_STAT:
2031
    case IPC_SET:
2032
    case MSG_STAT:
2033
        if (target_to_host_msqid_ds(&dsarg,ptr))
2034
            return -TARGET_EFAULT;
2035
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2036
        if (host_to_target_msqid_ds(ptr,&dsarg))
2037
            return -TARGET_EFAULT;
2038
        break;
2039
    case IPC_RMID:
2040
        ret = get_errno(msgctl(msgid, cmd, NULL));
2041
        break;
2042
    case IPC_INFO:
2043
    case MSG_INFO:
2044
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2045
        if (host_to_target_msginfo(ptr, &msginfo))
2046
            return -TARGET_EFAULT;
2047
        break;
2048
    }
2049

    
2050
    return ret;
2051
}
2052

    
2053
struct target_msgbuf {
2054
    abi_long mtype;
2055
    char        mtext[1];
2056
};
2057

    
2058
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2059
                                 unsigned int msgsz, int msgflg)
2060
{
2061
    struct target_msgbuf *target_mb;
2062
    struct msgbuf *host_mb;
2063
    abi_long ret = 0;
2064

    
2065
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2066
        return -TARGET_EFAULT;
2067
    host_mb = malloc(msgsz+sizeof(long));
2068
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2069
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2070
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2071
    free(host_mb);
2072
    unlock_user_struct(target_mb, msgp, 0);
2073

    
2074
    return ret;
2075
}
2076

    
2077
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2078
                                 unsigned int msgsz, abi_long msgtyp,
2079
                                 int msgflg)
2080
{
2081
    struct target_msgbuf *target_mb;
2082
    char *target_mtext;
2083
    struct msgbuf *host_mb;
2084
    abi_long ret = 0;
2085

    
2086
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2087
        return -TARGET_EFAULT;
2088

    
2089
    host_mb = malloc(msgsz+sizeof(long));
2090
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2091

    
2092
    if (ret > 0) {
2093
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2094
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2095
        if (!target_mtext) {
2096
            ret = -TARGET_EFAULT;
2097
            goto end;
2098
        }
2099
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2100
        unlock_user(target_mtext, target_mtext_addr, ret);
2101
    }
2102

    
2103
    target_mb->mtype = tswapl(host_mb->mtype);
2104
    free(host_mb);
2105

    
2106
end:
2107
    if (target_mb)
2108
        unlock_user_struct(target_mb, msgp, 1);
2109
    return ret;
2110
}
2111

    
2112
#ifdef TARGET_NR_ipc
2113
/* ??? This only works with linear mappings.  */
2114
/* do_ipc() must return target values and target errnos. */
2115
static abi_long do_ipc(unsigned int call, int first,
2116
                       int second, int third,
2117
                       abi_long ptr, abi_long fifth)
2118
{
2119
    int version;
2120
    abi_long ret = 0;
2121
    struct shmid_ds shm_info;
2122
    int i;
2123

    
2124
    version = call >> 16;
2125
    call &= 0xffff;
2126

    
2127
    switch (call) {
2128
    case IPCOP_semop:
2129
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
2130
        break;
2131

    
2132
    case IPCOP_semget:
2133
        ret = get_errno(semget(first, second, third));
2134
        break;
2135

    
2136
    case IPCOP_semctl:
2137
        ret = do_semctl(first, second, third, ptr);
2138
        break;
2139

    
2140
    case IPCOP_semtimedop:
2141
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2142
        ret = -TARGET_ENOSYS;
2143
        break;
2144

    
2145
    case IPCOP_msgget:
2146
        ret = get_errno(msgget(first, second));
2147
        break;
2148

    
2149
    case IPCOP_msgsnd:
2150
        ret = do_msgsnd(first, ptr, second, third);
2151
        break;
2152

    
2153
    case IPCOP_msgctl:
2154
        ret = do_msgctl(first, second, ptr);
2155
        break;
2156

    
2157
    case IPCOP_msgrcv:
2158
        switch (version) {
2159
        case 0:
2160
            {
2161
                struct target_ipc_kludge {
2162
                    abi_long msgp;
2163
                    abi_long msgtyp;
2164
                } *tmp;
2165

    
2166
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2167
                    ret = -TARGET_EFAULT;
2168
                    break;
2169
                }
2170

    
2171
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2172

    
2173
                unlock_user_struct(tmp, ptr, 0);
2174
                break;
2175
            }
2176
        default:
2177
            ret = do_msgrcv(first, ptr, second, fifth, third);
2178
        }
2179
        break;
2180

    
2181
    case IPCOP_shmat:
2182
        {
2183
            abi_ulong raddr;
2184
            void *host_addr;
2185
            /* SHM_* flags are the same on all linux platforms */
2186
            host_addr = shmat(first, (void *)g2h(ptr), second);
2187
            if (host_addr == (void *)-1) {
2188
                ret = get_errno((long)host_addr);
2189
                break;
2190
            }
2191
            raddr = h2g((unsigned long)host_addr);
2192
            /* find out the length of the shared memory segment */
2193
            
2194
            ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2195
            if (is_error(ret)) {
2196
                /* can't get length, bail out */
2197
                shmdt(host_addr);
2198
                break;
2199
            }
2200
            page_set_flags(raddr, raddr + shm_info.shm_segsz,
2201
                           PAGE_VALID | PAGE_READ |
2202
                           ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2203
            for (i = 0; i < N_SHM_REGIONS; ++i) {
2204
                if (shm_regions[i].start == 0) {
2205
                    shm_regions[i].start = raddr;
2206
                    shm_regions[i].size = shm_info.shm_segsz;
2207
                    break;
2208
                }
2209
            }
2210
            if (put_user_ual(raddr, third))
2211
                return -TARGET_EFAULT;
2212
            ret = 0;
2213
        }
2214
        break;
2215
    case IPCOP_shmdt:
2216
        for (i = 0; i < N_SHM_REGIONS; ++i) {
2217
            if (shm_regions[i].start == ptr) {
2218
                shm_regions[i].start = 0;
2219
                page_set_flags(ptr, shm_regions[i].size, 0);
2220
                break;
2221
            }
2222
        }
2223
        ret = get_errno(shmdt((void *)g2h(ptr)));
2224
        break;
2225

    
2226
    case IPCOP_shmget:
2227
        /* IPC_* flag values are the same on all linux platforms */
2228
        ret = get_errno(shmget(first, second, third));
2229
        break;
2230

    
2231
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2232
    case IPCOP_shmctl:
2233
        switch(second) {
2234
        case IPC_RMID:
2235
        case SHM_LOCK:
2236
        case SHM_UNLOCK:
2237
            ret = get_errno(shmctl(first, second, NULL));
2238
            break;
2239
        default:
2240
            goto unimplemented;
2241
        }
2242
        break;
2243
    default:
2244
    unimplemented:
2245
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2246
        ret = -TARGET_ENOSYS;
2247
        break;
2248
    }
2249
    return ret;
2250
}
2251
#endif
2252

    
2253
/* kernel structure types definitions */
2254
#define IFNAMSIZ        16
2255

    
2256
#define STRUCT(name, list...) STRUCT_ ## name,
2257
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2258
enum {
2259
#include "syscall_types.h"
2260
};
2261
#undef STRUCT
2262
#undef STRUCT_SPECIAL
2263

    
2264
#define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2265
#define STRUCT_SPECIAL(name)
2266
#include "syscall_types.h"
2267
#undef STRUCT
2268
#undef STRUCT_SPECIAL
2269

    
2270
typedef struct IOCTLEntry {
2271
    unsigned int target_cmd;
2272
    unsigned int host_cmd;
2273
    const char *name;
2274
    int access;
2275
    const argtype arg_type[5];
2276
} IOCTLEntry;
2277

    
2278
#define IOC_R 0x0001
2279
#define IOC_W 0x0002
2280
#define IOC_RW (IOC_R | IOC_W)
2281

    
2282
#define MAX_STRUCT_SIZE 4096
2283

    
2284
static IOCTLEntry ioctl_entries[] = {
2285
#define IOCTL(cmd, access, types...) \
2286
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2287
#include "ioctls.h"
2288
    { 0, 0, },
2289
};
2290

    
2291
/* ??? Implement proper locking for ioctls.  */
2292
/* do_ioctl() Must return target values and target errnos. */
2293
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2294
{
2295
    const IOCTLEntry *ie;
2296
    const argtype *arg_type;
2297
    abi_long ret;
2298
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2299
    int target_size;
2300
    void *argptr;
2301

    
2302
    ie = ioctl_entries;
2303
    for(;;) {
2304
        if (ie->target_cmd == 0) {
2305
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2306
            return -TARGET_ENOSYS;
2307
        }
2308
        if (ie->target_cmd == cmd)
2309
            break;
2310
        ie++;
2311
    }
2312
    arg_type = ie->arg_type;
2313
#if defined(DEBUG)
2314
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2315
#endif
2316
    switch(arg_type[0]) {
2317
    case TYPE_NULL:
2318
        /* no argument */
2319
        ret = get_errno(ioctl(fd, ie->host_cmd));
2320
        break;
2321
    case TYPE_PTRVOID:
2322
    case TYPE_INT:
2323
        /* int argment */
2324
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2325
        break;
2326
    case TYPE_PTR:
2327
        arg_type++;
2328
        target_size = thunk_type_size(arg_type, 0);
2329
        switch(ie->access) {
2330
        case IOC_R:
2331
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2332
            if (!is_error(ret)) {
2333
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2334
                if (!argptr)
2335
                    return -TARGET_EFAULT;
2336
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2337
                unlock_user(argptr, arg, target_size);
2338
            }
2339
            break;
2340
        case IOC_W:
2341
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2342
            if (!argptr)
2343
                return -TARGET_EFAULT;
2344
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2345
            unlock_user(argptr, arg, 0);
2346
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2347
            break;
2348
        default:
2349
        case IOC_RW:
2350
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2351
            if (!argptr)
2352
                return -TARGET_EFAULT;
2353
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2354
            unlock_user(argptr, arg, 0);
2355
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2356
            if (!is_error(ret)) {
2357
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2358
                if (!argptr)
2359
                    return -TARGET_EFAULT;
2360
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2361
                unlock_user(argptr, arg, target_size);
2362
            }
2363
            break;
2364
        }
2365
        break;
2366
    default:
2367
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2368
                 (long)cmd, arg_type[0]);
2369
        ret = -TARGET_ENOSYS;
2370
        break;
2371
    }
2372
    return ret;
2373
}
2374

    
2375
static const bitmask_transtbl iflag_tbl[] = {
2376
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2377
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2378
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2379
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2380
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2381
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2382
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2383
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2384
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2385
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2386
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2387
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2388
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2389
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2390
        { 0, 0, 0, 0 }
2391
};
2392

    
2393
static const bitmask_transtbl oflag_tbl[] = {
2394
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2395
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2396
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2397
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2398
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2399
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2400
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2401
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2402
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2403
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2404
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2405
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2406
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2407
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2408
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2409
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2410
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2411
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2412
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2413
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2414
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2415
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2416
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2417
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2418
        { 0, 0, 0, 0 }
2419
};
2420

    
2421
static const bitmask_transtbl cflag_tbl[] = {
2422
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2423
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2424
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2425
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2426
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2427
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2428
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2429
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2430
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2431
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2432
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2433
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2434
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2435
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2436
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2437
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2438
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2439
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2440
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2441
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2442
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2443
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2444
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2445
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2446
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2447
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2448
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2449
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2450
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2451
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2452
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2453
        { 0, 0, 0, 0 }
2454
};
2455

    
2456
static const bitmask_transtbl lflag_tbl[] = {
2457
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2458
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2459
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2460
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2461
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2462
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2463
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2464
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2465
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2466
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2467
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2468
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2469
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2470
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2471
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2472
        { 0, 0, 0, 0 }
2473
};
2474

    
2475
static void target_to_host_termios (void *dst, const void *src)
2476
{
2477
    struct host_termios *host = dst;
2478
    const struct target_termios *target = src;
2479

    
2480
    host->c_iflag =
2481
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2482
    host->c_oflag =
2483
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2484
    host->c_cflag =
2485
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2486
    host->c_lflag =
2487
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2488
    host->c_line = target->c_line;
2489

    
2490
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2491
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2492
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2493
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2494
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2495
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2496
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2497
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2498
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2499
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2500
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2501
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2502
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2503
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2504
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2505
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2506
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2507
}
2508

    
2509
static void host_to_target_termios (void *dst, const void *src)
2510
{
2511
    struct target_termios *target = dst;
2512
    const struct host_termios *host = src;
2513

    
2514
    target->c_iflag =
2515
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2516
    target->c_oflag =
2517
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2518
    target->c_cflag =
2519
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2520
    target->c_lflag =
2521
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2522
    target->c_line = host->c_line;
2523

    
2524
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2525
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2526
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2527
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2528
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2529
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2530
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2531
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2532
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2533
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2534
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2535
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2536
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2537
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2538
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2539
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2540
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2541
}
2542

    
2543
static const StructEntry struct_termios_def = {
2544
    .convert = { host_to_target_termios, target_to_host_termios },
2545
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2546
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2547
};
2548

    
2549
static bitmask_transtbl mmap_flags_tbl[] = {
2550
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2551
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2552
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2553
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2554
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2555
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2556
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2557
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2558
        { 0, 0, 0, 0 }
2559
};
2560

    
2561
static bitmask_transtbl fcntl_flags_tbl[] = {
2562
        { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
2563
        { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
2564
        { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
2565
        { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
2566
        { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
2567
        { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
2568
        { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
2569
        { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
2570
        { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
2571
        { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
2572
        { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2573
        { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
2574
        { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2575
#if defined(O_DIRECT)
2576
        { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
2577
#endif
2578
        { 0, 0, 0, 0 }
2579
};
2580

    
2581
#if defined(TARGET_I386)
2582

    
2583
/* NOTE: there is really one LDT for all the threads */
2584
static uint8_t *ldt_table;
2585

    
2586
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2587
{
2588
    int size;
2589
    void *p;
2590

    
2591
    if (!ldt_table)
2592
        return 0;
2593
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2594
    if (size > bytecount)
2595
        size = bytecount;
2596
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
2597
    if (!p)
2598
        return -TARGET_EFAULT;
2599
    /* ??? Should this by byteswapped?  */
2600
    memcpy(p, ldt_table, size);
2601
    unlock_user(p, ptr, size);
2602
    return size;
2603
}
2604

    
2605
/* XXX: add locking support */
2606
static abi_long write_ldt(CPUX86State *env,
2607
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
2608
{
2609
    struct target_modify_ldt_ldt_s ldt_info;
2610
    struct target_modify_ldt_ldt_s *target_ldt_info;
2611
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2612
    int seg_not_present, useable, lm;
2613
    uint32_t *lp, entry_1, entry_2;
2614

    
2615
    if (bytecount != sizeof(ldt_info))
2616
        return -TARGET_EINVAL;
2617
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2618
        return -TARGET_EFAULT;
2619
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2620
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2621
    ldt_info.limit = tswap32(target_ldt_info->limit);
2622
    ldt_info.flags = tswap32(target_ldt_info->flags);
2623
    unlock_user_struct(target_ldt_info, ptr, 0);
2624

    
2625
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2626
        return -TARGET_EINVAL;
2627
    seg_32bit = ldt_info.flags & 1;
2628
    contents = (ldt_info.flags >> 1) & 3;
2629
    read_exec_only = (ldt_info.flags >> 3) & 1;
2630
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2631
    seg_not_present = (ldt_info.flags >> 5) & 1;
2632
    useable = (ldt_info.flags >> 6) & 1;
2633
#ifdef TARGET_ABI32
2634
    lm = 0;
2635
#else
2636
    lm = (ldt_info.flags >> 7) & 1;
2637
#endif
2638
    if (contents == 3) {
2639
        if (oldmode)
2640
            return -TARGET_EINVAL;
2641
        if (seg_not_present == 0)
2642
            return -TARGET_EINVAL;
2643
    }
2644
    /* allocate the LDT */
2645
    if (!ldt_table) {
2646
        env->ldt.base = target_mmap(0,
2647
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
2648
                                    PROT_READ|PROT_WRITE,
2649
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2650
        if (env->ldt.base == -1)
2651
            return -TARGET_ENOMEM;
2652
        memset(g2h(env->ldt.base), 0,
2653
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2654
        env->ldt.limit = 0xffff;
2655
        ldt_table = g2h(env->ldt.base);
2656
    }
2657

    
2658
    /* NOTE: same code as Linux kernel */
2659
    /* Allow LDTs to be cleared by the user. */
2660
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2661
        if (oldmode ||
2662
            (contents == 0                &&
2663
             read_exec_only == 1        &&
2664
             seg_32bit == 0                &&
2665
             limit_in_pages == 0        &&
2666
             seg_not_present == 1        &&
2667
             useable == 0 )) {
2668
            entry_1 = 0;
2669
            entry_2 = 0;
2670
            goto install;
2671
        }
2672
    }
2673

    
2674
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2675
        (ldt_info.limit & 0x0ffff);
2676
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2677
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2678
        (ldt_info.limit & 0xf0000) |
2679
        ((read_exec_only ^ 1) << 9) |
2680
        (contents << 10) |
2681
        ((seg_not_present ^ 1) << 15) |
2682
        (seg_32bit << 22) |
2683
        (limit_in_pages << 23) |
2684
        (lm << 21) |
2685
        0x7000;
2686
    if (!oldmode)
2687
        entry_2 |= (useable << 20);
2688

    
2689
    /* Install the new entry ...  */
2690
install:
2691
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2692
    lp[0] = tswap32(entry_1);
2693
    lp[1] = tswap32(entry_2);
2694
    return 0;
2695
}
2696

    
2697
/* specific and weird i386 syscalls */
2698
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2699
                              unsigned long bytecount)
2700
{
2701
    abi_long ret;
2702

    
2703
    switch (func) {
2704
    case 0:
2705
        ret = read_ldt(ptr, bytecount);
2706
        break;
2707
    case 1:
2708
        ret = write_ldt(env, ptr, bytecount, 1);
2709
        break;
2710
    case 0x11:
2711
        ret = write_ldt(env, ptr, bytecount, 0);
2712
        break;
2713
    default:
2714
        ret = -TARGET_ENOSYS;
2715
        break;
2716
    }
2717
    return ret;
2718
}
2719

    
2720
#if defined(TARGET_I386) && defined(TARGET_ABI32)
2721
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2722
{
2723
    uint64_t *gdt_table = g2h(env->gdt.base);
2724
    struct target_modify_ldt_ldt_s ldt_info;
2725
    struct target_modify_ldt_ldt_s *target_ldt_info;
2726
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2727
    int seg_not_present, useable, lm;
2728
    uint32_t *lp, entry_1, entry_2;
2729
    int i;
2730

    
2731
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2732
    if (!target_ldt_info)
2733
        return -TARGET_EFAULT;
2734
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2735
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2736
    ldt_info.limit = tswap32(target_ldt_info->limit);
2737
    ldt_info.flags = tswap32(target_ldt_info->flags);
2738
    if (ldt_info.entry_number == -1) {
2739
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2740
            if (gdt_table[i] == 0) {
2741
                ldt_info.entry_number = i;
2742
                target_ldt_info->entry_number = tswap32(i);
2743
                break;
2744
            }
2745
        }
2746
    }
2747
    unlock_user_struct(target_ldt_info, ptr, 1);
2748

    
2749
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
2750
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2751
           return -TARGET_EINVAL;
2752
    seg_32bit = ldt_info.flags & 1;
2753
    contents = (ldt_info.flags >> 1) & 3;
2754
    read_exec_only = (ldt_info.flags >> 3) & 1;
2755
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2756
    seg_not_present = (ldt_info.flags >> 5) & 1;
2757
    useable = (ldt_info.flags >> 6) & 1;
2758
#ifdef TARGET_ABI32
2759
    lm = 0;
2760
#else
2761
    lm = (ldt_info.flags >> 7) & 1;
2762
#endif
2763

    
2764
    if (contents == 3) {
2765
        if (seg_not_present == 0)
2766
            return -TARGET_EINVAL;
2767
    }
2768

    
2769
    /* NOTE: same code as Linux kernel */
2770
    /* Allow LDTs to be cleared by the user. */
2771
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2772
        if ((contents == 0             &&
2773
             read_exec_only == 1       &&
2774
             seg_32bit == 0            &&
2775
             limit_in_pages == 0       &&
2776
             seg_not_present == 1      &&
2777
             useable == 0 )) {
2778
            entry_1 = 0;
2779
            entry_2 = 0;
2780
            goto install;
2781
        }
2782
    }
2783

    
2784
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2785
        (ldt_info.limit & 0x0ffff);
2786
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2787
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2788
        (ldt_info.limit & 0xf0000) |
2789
        ((read_exec_only ^ 1) << 9) |
2790
        (contents << 10) |
2791
        ((seg_not_present ^ 1) << 15) |
2792
        (seg_32bit << 22) |
2793
        (limit_in_pages << 23) |
2794
        (useable << 20) |
2795
        (lm << 21) |
2796
        0x7000;
2797

    
2798
    /* Install the new entry ...  */
2799
install:
2800
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2801
    lp[0] = tswap32(entry_1);
2802
    lp[1] = tswap32(entry_2);
2803
    return 0;
2804
}
2805

    
2806
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2807
{
2808
    struct target_modify_ldt_ldt_s *target_ldt_info;
2809
    uint64_t *gdt_table = g2h(env->gdt.base);
2810
    uint32_t base_addr, limit, flags;
2811
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2812
    int seg_not_present, useable, lm;
2813
    uint32_t *lp, entry_1, entry_2;
2814

    
2815
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2816
    if (!target_ldt_info)
2817
        return -TARGET_EFAULT;
2818
    idx = tswap32(target_ldt_info->entry_number);
2819
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2820
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
2821
        unlock_user_struct(target_ldt_info, ptr, 1);
2822
        return -TARGET_EINVAL;
2823
    }
2824
    lp = (uint32_t *)(gdt_table + idx);
2825
    entry_1 = tswap32(lp[0]);
2826
    entry_2 = tswap32(lp[1]);
2827
    
2828
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2829
    contents = (entry_2 >> 10) & 3;
2830
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2831
    seg_32bit = (entry_2 >> 22) & 1;
2832
    limit_in_pages = (entry_2 >> 23) & 1;
2833
    useable = (entry_2 >> 20) & 1;
2834
#ifdef TARGET_ABI32
2835
    lm = 0;
2836
#else
2837
    lm = (entry_2 >> 21) & 1;
2838
#endif
2839
    flags = (seg_32bit << 0) | (contents << 1) |
2840
        (read_exec_only << 3) | (limit_in_pages << 4) |
2841
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
2842
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
2843
    base_addr = (entry_1 >> 16) | 
2844
        (entry_2 & 0xff000000) | 
2845
        ((entry_2 & 0xff) << 16);
2846
    target_ldt_info->base_addr = tswapl(base_addr);
2847
    target_ldt_info->limit = tswap32(limit);
2848
    target_ldt_info->flags = tswap32(flags);
2849
    unlock_user_struct(target_ldt_info, ptr, 1);
2850
    return 0;
2851
}
2852
#endif /* TARGET_I386 && TARGET_ABI32 */
2853

    
2854
#ifndef TARGET_ABI32
2855
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2856
{
2857
    abi_long ret;
2858
    abi_ulong val;
2859
    int idx;
2860
    
2861
    switch(code) {
2862
    case TARGET_ARCH_SET_GS:
2863
    case TARGET_ARCH_SET_FS:
2864
        if (code == TARGET_ARCH_SET_GS)
2865
            idx = R_GS;
2866
        else
2867
            idx = R_FS;
2868
        cpu_x86_load_seg(env, idx, 0);
2869
        env->segs[idx].base = addr;
2870
        break;
2871
    case TARGET_ARCH_GET_GS:
2872
    case TARGET_ARCH_GET_FS:
2873
        if (code == TARGET_ARCH_GET_GS)
2874
            idx = R_GS;
2875
        else
2876
            idx = R_FS;
2877
        val = env->segs[idx].base;
2878
        if (put_user(val, addr, abi_ulong))
2879
            return -TARGET_EFAULT;
2880
        break;
2881
    default:
2882
        ret = -TARGET_EINVAL;
2883
        break;
2884
    }
2885
    return 0;
2886
}
2887
#endif
2888

    
2889
#endif /* defined(TARGET_I386) */
2890

    
2891
#if defined(USE_NPTL)
2892

    
2893
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2894

    
2895
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2896
typedef struct {
2897
    CPUState *env;
2898
    pthread_mutex_t mutex;
2899
    pthread_cond_t cond;
2900
    pthread_t thread;
2901
    uint32_t tid;
2902
    abi_ulong child_tidptr;
2903
    abi_ulong parent_tidptr;
2904
    sigset_t sigmask;
2905
} new_thread_info;
2906

    
2907
static void *clone_func(void *arg)
2908
{
2909
    new_thread_info *info = arg;
2910
    CPUState *env;
2911

    
2912
    env = info->env;
2913
    thread_env = env;
2914
    info->tid = gettid();
2915
    if (info->child_tidptr)
2916
        put_user_u32(info->tid, info->child_tidptr);
2917
    if (info->parent_tidptr)
2918
        put_user_u32(info->tid, info->parent_tidptr);
2919
    /* Enable signals.  */
2920
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2921
    /* Signal to the parent that we're ready.  */
2922
    pthread_mutex_lock(&info->mutex);
2923
    pthread_cond_broadcast(&info->cond);
2924
    pthread_mutex_unlock(&info->mutex);
2925
    /* Wait until the parent has finshed initializing the tls state.  */
2926
    pthread_mutex_lock(&clone_lock);
2927
    pthread_mutex_unlock(&clone_lock);
2928
    cpu_loop(env);
2929
    /* never exits */
2930
    return NULL;
2931
}
2932
#else
2933
/* this stack is the equivalent of the kernel stack associated with a
2934
   thread/process */
2935
#define NEW_STACK_SIZE 8192
2936

    
2937
static int clone_func(void *arg)
2938
{
2939
    CPUState *env = arg;
2940
    cpu_loop(env);
2941
    /* never exits */
2942
    return 0;
2943
}
2944
#endif
2945

    
2946
/* do_fork() Must return host values and target errnos (unlike most
2947
   do_*() functions). */
2948
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2949
                   abi_ulong parent_tidptr, target_ulong newtls,
2950
                   abi_ulong child_tidptr)
2951
{
2952
    int ret;
2953
    TaskState *ts;
2954
    uint8_t *new_stack;
2955
    CPUState *new_env;
2956
#if defined(USE_NPTL)
2957
    unsigned int nptl_flags;
2958
    sigset_t sigmask;
2959
#endif
2960

    
2961
    /* Emulate vfork() with fork() */
2962
    if (flags & CLONE_VFORK)
2963
        flags &= ~(CLONE_VFORK | CLONE_VM);
2964

    
2965
    if (flags & CLONE_VM) {
2966
#if defined(USE_NPTL)
2967
        new_thread_info info;
2968
        pthread_attr_t attr;
2969
#endif
2970
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2971
        init_task_state(ts);
2972
        new_stack = ts->stack;
2973
        /* we create a new CPU instance. */
2974
        new_env = cpu_copy(env);
2975
        /* Init regs that differ from the parent.  */
2976
        cpu_clone_regs(new_env, newsp);
2977
        new_env->opaque = ts;
2978
#if defined(USE_NPTL)
2979
        nptl_flags = flags;
2980
        flags &= ~CLONE_NPTL_FLAGS2;
2981

    
2982
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
2983
            ts->child_tidptr = child_tidptr;
2984
        }
2985

    
2986
        if (nptl_flags & CLONE_SETTLS)
2987
            cpu_set_tls (new_env, newtls);
2988

    
2989
        /* Grab a mutex so that thread setup appears atomic.  */
2990
        pthread_mutex_lock(&clone_lock);
2991

    
2992
        memset(&info, 0, sizeof(info));
2993
        pthread_mutex_init(&info.mutex, NULL);
2994
        pthread_mutex_lock(&info.mutex);
2995
        pthread_cond_init(&info.cond, NULL);
2996
        info.env = new_env;
2997
        if (nptl_flags & CLONE_CHILD_SETTID)
2998
            info.child_tidptr = child_tidptr;
2999
        if (nptl_flags & CLONE_PARENT_SETTID)
3000
            info.parent_tidptr = parent_tidptr;
3001

    
3002
        ret = pthread_attr_init(&attr);
3003
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3004
        /* It is not safe to deliver signals until the child has finished
3005
           initializing, so temporarily block all signals.  */
3006
        sigfillset(&sigmask);
3007
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3008

    
3009
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
3010
        /* TODO: Free new CPU state if thread creation failed.  */
3011

    
3012
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3013
        pthread_attr_destroy(&attr);
3014
        if (ret == 0) {
3015
            /* Wait for the child to initialize.  */
3016
            pthread_cond_wait(&info.cond, &info.mutex);
3017
            ret = info.tid;
3018
            if (flags & CLONE_PARENT_SETTID)
3019
                put_user_u32(ret, parent_tidptr);
3020
        } else {
3021
            ret = -1;
3022
        }
3023
        pthread_mutex_unlock(&info.mutex);
3024
        pthread_cond_destroy(&info.cond);
3025
        pthread_mutex_destroy(&info.mutex);
3026
        pthread_mutex_unlock(&clone_lock);
3027
#else
3028
        if (flags & CLONE_NPTL_FLAGS2)
3029
            return -EINVAL;
3030
        /* This is probably going to die very quickly, but do it anyway.  */
3031
#ifdef __ia64__
3032
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3033
#else
3034
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3035
#endif
3036
#endif
3037
    } else {
3038
        /* if no CLONE_VM, we consider it is a fork */
3039
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3040
            return -EINVAL;
3041
        fork_start();
3042
        ret = fork();
3043
        if (ret == 0) {
3044
            /* Child Process.  */
3045
            cpu_clone_regs(env, newsp);
3046
            fork_end(1);
3047
#if defined(USE_NPTL)
3048
            /* There is a race condition here.  The parent process could
3049
               theoretically read the TID in the child process before the child
3050
               tid is set.  This would require using either ptrace
3051
               (not implemented) or having *_tidptr to point at a shared memory
3052
               mapping.  We can't repeat the spinlock hack used above because
3053
               the child process gets its own copy of the lock.  */
3054
            if (flags & CLONE_CHILD_SETTID)
3055
                put_user_u32(gettid(), child_tidptr);
3056
            if (flags & CLONE_PARENT_SETTID)
3057
                put_user_u32(gettid(), parent_tidptr);
3058
            ts = (TaskState *)env->opaque;
3059
            if (flags & CLONE_SETTLS)
3060
                cpu_set_tls (env, newtls);
3061
            if (flags & CLONE_CHILD_CLEARTID)
3062
                ts->child_tidptr = child_tidptr;
3063
#endif
3064
        } else {
3065
            fork_end(0);
3066
        }
3067
    }
3068
    return ret;
3069
}
3070

    
3071
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3072
{
3073
    struct flock fl;
3074
    struct target_flock *target_fl;
3075
    struct flock64 fl64;
3076
    struct target_flock64 *target_fl64;
3077
    abi_long ret;
3078

    
3079
    switch(cmd) {
3080
    case TARGET_F_GETLK:
3081
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3082
            return -TARGET_EFAULT;
3083
        fl.l_type = tswap16(target_fl->l_type);
3084
        fl.l_whence = tswap16(target_fl->l_whence);
3085
        fl.l_start = tswapl(target_fl->l_start);
3086
        fl.l_len = tswapl(target_fl->l_len);
3087
        fl.l_pid = tswapl(target_fl->l_pid);
3088
        unlock_user_struct(target_fl, arg, 0);
3089
        ret = get_errno(fcntl(fd, cmd, &fl));
3090
        if (ret == 0) {
3091
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3092
                return -TARGET_EFAULT;
3093
            target_fl->l_type = tswap16(fl.l_type);
3094
            target_fl->l_whence = tswap16(fl.l_whence);
3095
            target_fl->l_start = tswapl(fl.l_start);
3096
            target_fl->l_len = tswapl(fl.l_len);
3097
            target_fl->l_pid = tswapl(fl.l_pid);
3098
            unlock_user_struct(target_fl, arg, 1);
3099
        }
3100
        break;
3101

    
3102
    case TARGET_F_SETLK:
3103
    case TARGET_F_SETLKW:
3104
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3105
            return -TARGET_EFAULT;
3106
        fl.l_type = tswap16(target_fl->l_type);
3107
        fl.l_whence = tswap16(target_fl->l_whence);
3108
        fl.l_start = tswapl(target_fl->l_start);
3109
        fl.l_len = tswapl(target_fl->l_len);
3110
        fl.l_pid = tswapl(target_fl->l_pid);
3111
        unlock_user_struct(target_fl, arg, 0);
3112
        ret = get_errno(fcntl(fd, cmd, &fl));
3113
        break;
3114

    
3115
    case TARGET_F_GETLK64:
3116
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3117
            return -TARGET_EFAULT;
3118
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3119
        fl64.l_whence = tswap16(target_fl64->l_whence);
3120
        fl64.l_start = tswapl(target_fl64->l_start);
3121
        fl64.l_len = tswapl(target_fl64->l_len);
3122
        fl64.l_pid = tswap16(target_fl64->l_pid);
3123
        unlock_user_struct(target_fl64, arg, 0);
3124
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3125
        if (ret == 0) {
3126
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3127
                return -TARGET_EFAULT;
3128
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3129
            target_fl64->l_whence = tswap16(fl64.l_whence);
3130
            target_fl64->l_start = tswapl(fl64.l_start);
3131
            target_fl64->l_len = tswapl(fl64.l_len);
3132
            target_fl64->l_pid = tswapl(fl64.l_pid);
3133
            unlock_user_struct(target_fl64, arg, 1);
3134
        }
3135
        break;
3136
    case TARGET_F_SETLK64:
3137
    case TARGET_F_SETLKW64:
3138
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3139
            return -TARGET_EFAULT;
3140
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3141
        fl64.l_whence = tswap16(target_fl64->l_whence);
3142
        fl64.l_start = tswapl(target_fl64->l_start);
3143
        fl64.l_len = tswapl(target_fl64->l_len);
3144
        fl64.l_pid = tswap16(target_fl64->l_pid);
3145
        unlock_user_struct(target_fl64, arg, 0);
3146
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3147
        break;
3148

    
3149
    case F_GETFL:
3150
        ret = get_errno(fcntl(fd, cmd, arg));
3151
        if (ret >= 0) {
3152
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3153
        }
3154
        break;
3155

    
3156
    case F_SETFL:
3157
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3158
        break;
3159

    
3160
    default:
3161
        ret = get_errno(fcntl(fd, cmd, arg));
3162
        break;
3163
    }
3164
    return ret;
3165
}
3166

    
3167
#ifdef USE_UID16
3168

    
3169
static inline int high2lowuid(int uid)
3170
{
3171
    if (uid > 65535)
3172
        return 65534;
3173
    else
3174
        return uid;
3175
}
3176

    
3177
static inline int high2lowgid(int gid)
3178
{
3179
    if (gid > 65535)
3180
        return 65534;
3181
    else
3182
        return gid;
3183
}
3184

    
3185
static inline int low2highuid(int uid)
3186
{
3187
    if ((int16_t)uid == -1)
3188
        return -1;
3189
    else
3190
        return uid;
3191
}
3192

    
3193
static inline int low2highgid(int gid)
3194
{
3195
    if ((int16_t)gid == -1)
3196
        return -1;
3197
    else
3198
        return gid;
3199
}
3200

    
3201
#endif /* USE_UID16 */
3202

    
3203
void syscall_init(void)
3204
{
3205
    IOCTLEntry *ie;
3206
    const argtype *arg_type;
3207
    int size;
3208
    int i;
3209

    
3210
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3211
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3212
#include "syscall_types.h"
3213
#undef STRUCT
3214
#undef STRUCT_SPECIAL
3215

    
3216
    /* we patch the ioctl size if necessary. We rely on the fact that
3217
       no ioctl has all the bits at '1' in the size field */
3218
    ie = ioctl_entries;
3219
    while (ie->target_cmd != 0) {
3220
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3221
            TARGET_IOC_SIZEMASK) {
3222
            arg_type = ie->arg_type;
3223
            if (arg_type[0] != TYPE_PTR) {
3224
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3225
                        ie->target_cmd);
3226
                exit(1);
3227
            }
3228
            arg_type++;
3229
            size = thunk_type_size(arg_type, 0);
3230
            ie->target_cmd = (ie->target_cmd &
3231
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3232
                (size << TARGET_IOC_SIZESHIFT);
3233
        }
3234

    
3235
        /* Build target_to_host_errno_table[] table from
3236
         * host_to_target_errno_table[]. */
3237
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3238
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3239

    
3240
        /* automatic consistency check if same arch */
3241
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3242
    (defined(__x86_64__) && defined(TARGET_X86_64))
3243
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3244
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3245
                    ie->name, ie->target_cmd, ie->host_cmd);
3246
        }
3247
#endif
3248
        ie++;
3249
    }
3250
}
3251

    
3252
#if TARGET_ABI_BITS == 32
3253
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3254
{
3255
#ifdef TARGET_WORDS_BIGENDIAN
3256
    return ((uint64_t)word0 << 32) | word1;
3257
#else
3258
    return ((uint64_t)word1 << 32) | word0;
3259
#endif
3260
}
3261
#else /* TARGET_ABI_BITS == 32 */
3262
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3263
{
3264
    return word0;
3265
}
3266
#endif /* TARGET_ABI_BITS != 32 */
3267

    
3268
#ifdef TARGET_NR_truncate64
3269
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3270
                                         abi_long arg2,
3271
                                         abi_long arg3,
3272
                                         abi_long arg4)
3273
{
3274
#ifdef TARGET_ARM
3275
    if (((CPUARMState *)cpu_env)->eabi)
3276
      {
3277
        arg2 = arg3;
3278
        arg3 = arg4;
3279
      }
3280
#endif
3281
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3282
}
3283
#endif
3284

    
3285
#ifdef TARGET_NR_ftruncate64
3286
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3287
                                          abi_long arg2,
3288
                                          abi_long arg3,
3289
                                          abi_long arg4)
3290
{
3291
#ifdef TARGET_ARM
3292
    if (((CPUARMState *)cpu_env)->eabi)
3293
      {
3294
        arg2 = arg3;
3295
        arg3 = arg4;
3296
      }
3297
#endif
3298
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3299
}
3300
#endif
3301

    
3302
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3303
                                               abi_ulong target_addr)
3304
{
3305
    struct target_timespec *target_ts;
3306

    
3307
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3308
        return -TARGET_EFAULT;
3309
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3310
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3311
    unlock_user_struct(target_ts, target_addr, 0);
3312
    return 0;
3313
}
3314

    
3315
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3316
                                               struct timespec *host_ts)
3317
{
3318
    struct target_timespec *target_ts;
3319

    
3320
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3321
        return -TARGET_EFAULT;
3322
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3323
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3324
    unlock_user_struct(target_ts, target_addr, 1);
3325
    return 0;
3326
}
3327

    
3328
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3329
static inline abi_long host_to_target_stat64(void *cpu_env,
3330
                                             abi_ulong target_addr,
3331
                                             struct stat *host_st)
3332
{
3333
#ifdef TARGET_ARM
3334
    if (((CPUARMState *)cpu_env)->eabi) {
3335
        struct target_eabi_stat64 *target_st;
3336

    
3337
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3338
            return -TARGET_EFAULT;
3339
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3340
        __put_user(host_st->st_dev, &target_st->st_dev);
3341
        __put_user(host_st->st_ino, &target_st->st_ino);
3342
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3343
        __put_user(host_st->st_ino, &target_st->__st_ino);
3344
#endif
3345
        __put_user(host_st->st_mode, &target_st->st_mode);
3346
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3347
        __put_user(host_st->st_uid, &target_st->st_uid);
3348
        __put_user(host_st->st_gid, &target_st->st_gid);
3349
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3350
        __put_user(host_st->st_size, &target_st->st_size);
3351
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3352
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3353
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3354
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3355
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3356
        unlock_user_struct(target_st, target_addr, 1);
3357
    } else
3358
#endif
3359
    {
3360
#if TARGET_LONG_BITS == 64
3361
        struct target_stat *target_st;
3362
#else
3363
        struct target_stat64 *target_st;
3364
#endif
3365

    
3366
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3367
            return -TARGET_EFAULT;
3368
        memset(target_st, 0, sizeof(*target_st));
3369
        __put_user(host_st->st_dev, &target_st->st_dev);
3370
        __put_user(host_st->st_ino, &target_st->st_ino);
3371
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3372
        __put_user(host_st->st_ino, &target_st->__st_ino);
3373
#endif
3374
        __put_user(host_st->st_mode, &target_st->st_mode);
3375
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3376
        __put_user(host_st->st_uid, &target_st->st_uid);
3377
        __put_user(host_st->st_gid, &target_st->st_gid);
3378
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3379
        /* XXX: better use of kernel struct */
3380
        __put_user(host_st->st_size, &target_st->st_size);
3381
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3382
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3383
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3384
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3385
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3386
        unlock_user_struct(target_st, target_addr, 1);
3387
    }
3388

    
3389
    return 0;
3390
}
3391
#endif
3392

    
3393
#if defined(USE_NPTL)
3394
/* ??? Using host futex calls even when target atomic operations
3395
   are not really atomic probably breaks things.  However implementing
3396
   futexes locally would make futexes shared between multiple processes
3397
   tricky.  However they're probably useless because guest atomic
3398
   operations won't work either.  */
3399
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3400
                    target_ulong uaddr2, int val3)
3401
{
3402
    struct timespec ts, *pts;
3403

    
3404
    /* ??? We assume FUTEX_* constants are the same on both host
3405
       and target.  */
3406
    switch (op) {
3407
    case FUTEX_WAIT:
3408
        if (timeout) {
3409
            pts = &ts;
3410
            target_to_host_timespec(pts, timeout);
3411
        } else {
3412
            pts = NULL;
3413
        }
3414
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3415
                         pts, NULL, 0));
3416
    case FUTEX_WAKE:
3417
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3418
    case FUTEX_FD:
3419
        return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3420
    case FUTEX_REQUEUE:
3421
        return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3422
                         NULL, g2h(uaddr2), 0));
3423
    case FUTEX_CMP_REQUEUE:
3424
        return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3425
                         NULL, g2h(uaddr2), tswap32(val3)));
3426
    default:
3427
        return -TARGET_ENOSYS;
3428
    }
3429
}
3430
#endif
3431

    
3432
int get_osversion(void)
3433
{
3434
    static int osversion;
3435
    struct new_utsname buf;
3436
    const char *s;
3437
    int i, n, tmp;
3438
    if (osversion)
3439
        return osversion;
3440
    if (qemu_uname_release && *qemu_uname_release) {
3441
        s = qemu_uname_release;
3442
    } else {
3443
        if (sys_uname(&buf))
3444
            return 0;
3445
        s = buf.release;
3446
    }
3447
    tmp = 0;
3448
    for (i = 0; i < 3; i++) {
3449
        n = 0;
3450
        while (*s >= '0' && *s <= '9') {
3451
            n *= 10;
3452
            n += *s - '0';
3453
            s++;
3454
        }
3455
        tmp = (tmp << 8) + n;
3456
        if (*s == '.')
3457
            s++;
3458
    }
3459
    osversion = tmp;
3460
    return osversion;
3461
}
3462

    
3463
/* do_syscall() should always have a single exit point at the end so
3464
   that actions, such as logging of syscall results, can be performed.
3465
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3466
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3467
                    abi_long arg2, abi_long arg3, abi_long arg4,
3468
                    abi_long arg5, abi_long arg6)
3469
{
3470
    abi_long ret;
3471
    struct stat st;
3472
    struct statfs stfs;
3473
    void *p;
3474

    
3475
#ifdef DEBUG
3476
    gemu_log("syscall %d", num);
3477
#endif
3478
    if(do_strace)
3479
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3480

    
3481
    switch(num) {
3482
    case TARGET_NR_exit:
3483
#ifdef USE_NPTL
3484
      /* In old applications this may be used to implement _exit(2).
3485
         However in threaded applictions it is used for thread termination,
3486
         and _exit_group is used for application termination.
3487
         Do thread termination if we have more then one thread.  */
3488
      /* FIXME: This probably breaks if a signal arrives.  We should probably
3489
         be disabling signals.  */
3490
      if (first_cpu->next_cpu) {
3491
          CPUState **lastp;
3492
          CPUState *p;
3493

    
3494
          cpu_list_lock();
3495
          lastp = &first_cpu;
3496
          p = first_cpu;
3497
          while (p && p != (CPUState *)cpu_env) {
3498
              lastp = &p->next_cpu;
3499
              p = p->next_cpu;
3500
          }
3501
          /* If we didn't find the CPU for this thread then something is
3502
             horribly wrong.  */
3503
          if (!p)
3504
              abort();
3505
          /* Remove the CPU from the list.  */
3506
          *lastp = p->next_cpu;
3507
          cpu_list_unlock();
3508
          TaskState *ts = ((CPUState *)cpu_env)->opaque;
3509
          if (ts->child_tidptr) {
3510
              put_user_u32(0, ts->child_tidptr);
3511
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
3512
                        NULL, NULL, 0);
3513
          }
3514
          /* TODO: Free CPU state.  */
3515
          pthread_exit(NULL);
3516
      }
3517
#endif
3518
#ifdef HAVE_GPROF
3519
        _mcleanup();
3520
#endif
3521
        gdb_exit(cpu_env, arg1);
3522
        _exit(arg1);
3523
        ret = 0; /* avoid warning */
3524
        break;
3525
    case TARGET_NR_read:
3526
        if (arg3 == 0)
3527
            ret = 0;
3528
        else {
3529
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3530
                goto efault;
3531
            ret = get_errno(read(arg1, p, arg3));
3532
            unlock_user(p, arg2, ret);
3533
        }
3534
        break;
3535
    case TARGET_NR_write:
3536
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3537
            goto efault;
3538
        ret = get_errno(write(arg1, p, arg3));
3539
        unlock_user(p, arg2, 0);
3540
        break;
3541
    case TARGET_NR_open:
3542
        if (!(p = lock_user_string(arg1)))
3543
            goto efault;
3544
        ret = get_errno(open(path(p),
3545
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
3546
                             arg3));
3547
        unlock_user(p, arg1, 0);
3548
        break;
3549
#if defined(TARGET_NR_openat) && defined(__NR_openat)
3550
    case TARGET_NR_openat:
3551
        if (!(p = lock_user_string(arg2)))
3552
            goto efault;
3553
        ret = get_errno(sys_openat(arg1,
3554
                                   path(p),
3555
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
3556
                                   arg4));
3557
        unlock_user(p, arg2, 0);
3558
        break;
3559
#endif
3560
    case TARGET_NR_close:
3561
        ret = get_errno(close(arg1));
3562
        break;
3563
    case TARGET_NR_brk:
3564
        ret = do_brk(arg1);
3565
        break;
3566
    case TARGET_NR_fork:
3567
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3568
        break;
3569
#ifdef TARGET_NR_waitpid
3570
    case TARGET_NR_waitpid:
3571
        {
3572
            int status;
3573
            ret = get_errno(waitpid(arg1, &status, arg3));
3574
            if (!is_error(ret) && arg2
3575
                && put_user_s32(status, arg2))
3576
                goto efault;
3577
        }
3578
        break;
3579
#endif
3580
#ifdef TARGET_NR_waitid
3581
    case TARGET_NR_waitid:
3582
        {
3583
            siginfo_t info;
3584
            info.si_pid = 0;
3585
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
3586
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
3587
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3588
                    goto efault;
3589
                host_to_target_siginfo(p, &info);
3590
                unlock_user(p, arg3, sizeof(target_siginfo_t));
3591
            }
3592
        }
3593
        break;
3594
#endif
3595
#ifdef TARGET_NR_creat /* not on alpha */
3596
    case TARGET_NR_creat:
3597
        if (!(p = lock_user_string(arg1)))
3598
            goto efault;
3599
        ret = get_errno(creat(p, arg2));
3600
        unlock_user(p, arg1, 0);
3601
        break;
3602
#endif
3603
    case TARGET_NR_link:
3604
        {
3605
            void * p2;
3606
            p = lock_user_string(arg1);
3607
            p2 = lock_user_string(arg2);
3608
            if (!p || !p2)
3609
                ret = -TARGET_EFAULT;
3610
            else
3611
                ret = get_errno(link(p, p2));
3612
            unlock_user(p2, arg2, 0);
3613
            unlock_user(p, arg1, 0);
3614
        }
3615
        break;
3616
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3617
    case TARGET_NR_linkat:
3618
        {
3619
            void * p2 = NULL;
3620
            if (!arg2 || !arg4)
3621
                goto efault;
3622
            p  = lock_user_string(arg2);
3623
            p2 = lock_user_string(arg4);
3624
            if (!p || !p2)
3625
                ret = -TARGET_EFAULT;
3626
            else
3627
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3628
            unlock_user(p, arg2, 0);
3629
            unlock_user(p2, arg4, 0);
3630
        }
3631
        break;
3632
#endif
3633
    case TARGET_NR_unlink:
3634
        if (!(p = lock_user_string(arg1)))
3635
            goto efault;
3636
        ret = get_errno(unlink(p));
3637
        unlock_user(p, arg1, 0);
3638
        break;
3639
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3640
    case TARGET_NR_unlinkat:
3641
        if (!(p = lock_user_string(arg2)))
3642
            goto efault;
3643
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
3644
        unlock_user(p, arg2, 0);
3645
        break;
3646
#endif
3647
    case TARGET_NR_execve:
3648
        {
3649
            char **argp, **envp;
3650
            int argc, envc;
3651
            abi_ulong gp;
3652
            abi_ulong guest_argp;
3653
            abi_ulong guest_envp;
3654
            abi_ulong addr;
3655
            char **q;
3656

    
3657
            argc = 0;
3658
            guest_argp = arg2;
3659
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3660
                if (get_user_ual(addr, gp))
3661
                    goto efault;
3662
                if (!addr)
3663
                    break;
3664
                argc++;
3665
            }
3666
            envc = 0;
3667
            guest_envp = arg3;
3668
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3669
                if (get_user_ual(addr, gp))
3670
                    goto efault;
3671
                if (!addr)
3672
                    break;
3673
                envc++;
3674
            }
3675

    
3676
            argp = alloca((argc + 1) * sizeof(void *));
3677
            envp = alloca((envc + 1) * sizeof(void *));
3678

    
3679
            for (gp = guest_argp, q = argp; gp;
3680
                  gp += sizeof(abi_ulong), q++) {
3681
                if (get_user_ual(addr, gp))
3682
                    goto execve_efault;
3683
                if (!addr)
3684
                    break;
3685
                if (!(*q = lock_user_string(addr)))
3686
                    goto execve_efault;
3687
            }
3688
            *q = NULL;
3689

    
3690
            for (gp = guest_envp, q = envp; gp;
3691
                  gp += sizeof(abi_ulong), q++) {
3692
                if (get_user_ual(addr, gp))
3693
                    goto execve_efault;
3694
                if (!addr)
3695
                    break;
3696
                if (!(*q = lock_user_string(addr)))
3697
                    goto execve_efault;
3698
            }
3699
            *q = NULL;
3700

    
3701
            if (!(p = lock_user_string(arg1)))
3702
                goto execve_efault;
3703
            ret = get_errno(execve(p, argp, envp));
3704
            unlock_user(p, arg1, 0);
3705

    
3706
            goto execve_end;
3707

    
3708
        execve_efault:
3709
            ret = -TARGET_EFAULT;
3710

    
3711
        execve_end:
3712
            for (gp = guest_argp, q = argp; *q;
3713
                  gp += sizeof(abi_ulong), q++) {
3714
                if (get_user_ual(addr, gp)
3715
                    || !addr)
3716
                    break;
3717
                unlock_user(*q, addr, 0);
3718
            }
3719
            for (gp = guest_envp, q = envp; *q;
3720
                  gp += sizeof(abi_ulong), q++) {
3721
                if (get_user_ual(addr, gp)
3722
                    || !addr)
3723
                    break;
3724
                unlock_user(*q, addr, 0);
3725
            }
3726
        }
3727
        break;
3728
    case TARGET_NR_chdir:
3729
        if (!(p = lock_user_string(arg1)))
3730
            goto efault;
3731
        ret = get_errno(chdir(p));
3732
        unlock_user(p, arg1, 0);
3733
        break;
3734
#ifdef TARGET_NR_time
3735
    case TARGET_NR_time:
3736
        {
3737
            time_t host_time;
3738
            ret = get_errno(time(&host_time));
3739
            if (!is_error(ret)
3740
                && arg1
3741
                && put_user_sal(host_time, arg1))
3742
                goto efault;
3743
        }
3744
        break;
3745
#endif
3746
    case TARGET_NR_mknod:
3747
        if (!(p = lock_user_string(arg1)))
3748
            goto efault;
3749
        ret = get_errno(mknod(p, arg2, arg3));
3750
        unlock_user(p, arg1, 0);
3751
        break;
3752
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3753
    case TARGET_NR_mknodat:
3754
        if (!(p = lock_user_string(arg2)))
3755
            goto efault;
3756
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3757
        unlock_user(p, arg2, 0);
3758
        break;
3759
#endif
3760
    case TARGET_NR_chmod:
3761
        if (!(p = lock_user_string(arg1)))
3762
            goto efault;
3763
        ret = get_errno(chmod(p, arg2));
3764
        unlock_user(p, arg1, 0);
3765
        break;
3766
#ifdef TARGET_NR_break
3767
    case TARGET_NR_break:
3768
        goto unimplemented;
3769
#endif
3770
#ifdef TARGET_NR_oldstat
3771
    case TARGET_NR_oldstat:
3772
        goto unimplemented;
3773
#endif
3774
    case TARGET_NR_lseek:
3775
        ret = get_errno(lseek(arg1, arg2, arg3));
3776
        break;
3777
#ifdef TARGET_NR_getxpid
3778
    case TARGET_NR_getxpid:
3779
#else
3780
    case TARGET_NR_getpid:
3781
#endif
3782
        ret = get_errno(getpid());
3783
        break;
3784
    case TARGET_NR_mount:
3785
                {
3786
                        /* need to look at the data field */
3787
                        void *p2, *p3;
3788
                        p = lock_user_string(arg1);
3789
                        p2 = lock_user_string(arg2);
3790
                        p3 = lock_user_string(arg3);
3791
                        if (!p || !p2 || !p3)
3792
                            ret = -TARGET_EFAULT;
3793
                        else
3794
                            /* FIXME - arg5 should be locked, but it isn't clear how to
3795
                             * do that since it's not guaranteed to be a NULL-terminated
3796
                             * string.
3797
                             */
3798
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3799
                        unlock_user(p, arg1, 0);
3800
                        unlock_user(p2, arg2, 0);
3801
                        unlock_user(p3, arg3, 0);
3802
                        break;
3803
                }
3804
#ifdef TARGET_NR_umount
3805
    case TARGET_NR_umount:
3806
        if (!(p = lock_user_string(arg1)))
3807
            goto efault;
3808
        ret = get_errno(umount(p));
3809
        unlock_user(p, arg1, 0);
3810
        break;
3811
#endif
3812
#ifdef TARGET_NR_stime /* not on alpha */
3813
    case TARGET_NR_stime:
3814
        {
3815
            time_t host_time;
3816
            if (get_user_sal(host_time, arg1))
3817
                goto efault;
3818
            ret = get_errno(stime(&host_time));
3819
        }
3820
        break;
3821
#endif
3822
    case TARGET_NR_ptrace:
3823
        goto unimplemented;
3824
#ifdef TARGET_NR_alarm /* not on alpha */
3825
    case TARGET_NR_alarm:
3826
        ret = alarm(arg1);
3827
        break;
3828
#endif
3829
#ifdef TARGET_NR_oldfstat
3830
    case TARGET_NR_oldfstat:
3831
        goto unimplemented;
3832
#endif
3833
#ifdef TARGET_NR_pause /* not on alpha */
3834
    case TARGET_NR_pause:
3835
        ret = get_errno(pause());
3836
        break;
3837
#endif
3838
#ifdef TARGET_NR_utime
3839
    case TARGET_NR_utime:
3840
        {
3841
            struct utimbuf tbuf, *host_tbuf;
3842
            struct target_utimbuf *target_tbuf;
3843
            if (arg2) {
3844
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3845
                    goto efault;
3846
                tbuf.actime = tswapl(target_tbuf->actime);
3847
                tbuf.modtime = tswapl(target_tbuf->modtime);
3848
                unlock_user_struct(target_tbuf, arg2, 0);
3849
                host_tbuf = &tbuf;
3850
            } else {
3851
                host_tbuf = NULL;
3852
            }
3853
            if (!(p = lock_user_string(arg1)))
3854
                goto efault;
3855
            ret = get_errno(utime(p, host_tbuf));
3856
            unlock_user(p, arg1, 0);
3857
        }
3858
        break;
3859
#endif
3860
    case TARGET_NR_utimes:
3861
        {
3862
            struct timeval *tvp, tv[2];
3863
            if (arg2) {
3864
                if (copy_from_user_timeval(&tv[0], arg2)
3865
                    || copy_from_user_timeval(&tv[1],
3866
                                              arg2 + sizeof(struct target_timeval)))
3867
                    goto efault;
3868
                tvp = tv;
3869
            } else {
3870
                tvp = NULL;
3871
            }
3872
            if (!(p = lock_user_string(arg1)))
3873
                goto efault;
3874
            ret = get_errno(utimes(p, tvp));
3875
            unlock_user(p, arg1, 0);
3876
        }
3877
        break;
3878
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
3879
    case TARGET_NR_futimesat:
3880
        {
3881
            struct timeval *tvp, tv[2];
3882
            if (arg3) {
3883
                if (copy_from_user_timeval(&tv[0], arg3)
3884
                    || copy_from_user_timeval(&tv[1],
3885
                                              arg3 + sizeof(struct target_timeval)))
3886
                    goto efault;
3887
                tvp = tv;
3888
            } else {
3889
                tvp = NULL;
3890
            }
3891
            if (!(p = lock_user_string(arg2)))
3892
                goto efault;
3893
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
3894
            unlock_user(p, arg2, 0);
3895
        }
3896
        break;
3897
#endif
3898
#ifdef TARGET_NR_stty
3899
    case TARGET_NR_stty:
3900
        goto unimplemented;
3901
#endif
3902
#ifdef TARGET_NR_gtty
3903
    case TARGET_NR_gtty:
3904
        goto unimplemented;
3905
#endif
3906
    case TARGET_NR_access:
3907
        if (!(p = lock_user_string(arg1)))
3908
            goto efault;
3909
        ret = get_errno(access(p, arg2));
3910
        unlock_user(p, arg1, 0);
3911
        break;
3912
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3913
    case TARGET_NR_faccessat:
3914
        if (!(p = lock_user_string(arg2)))
3915
            goto efault;
3916
        ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3917
        unlock_user(p, arg2, 0);
3918
        break;
3919
#endif
3920
#ifdef TARGET_NR_nice /* not on alpha */
3921
    case TARGET_NR_nice:
3922
        ret = get_errno(nice(arg1));
3923
        break;
3924
#endif
3925
#ifdef TARGET_NR_ftime
3926
    case TARGET_NR_ftime:
3927
        goto unimplemented;
3928
#endif
3929
    case TARGET_NR_sync:
3930
        sync();
3931
        ret = 0;
3932
        break;
3933
    case TARGET_NR_kill:
3934
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3935
        break;
3936
    case TARGET_NR_rename:
3937
        {
3938
            void *p2;
3939
            p = lock_user_string(arg1);
3940
            p2 = lock_user_string(arg2);
3941
            if (!p || !p2)
3942
                ret = -TARGET_EFAULT;
3943
            else
3944
                ret = get_errno(rename(p, p2));
3945
            unlock_user(p2, arg2, 0);
3946
            unlock_user(p, arg1, 0);
3947
        }
3948
        break;
3949
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3950
    case TARGET_NR_renameat:
3951
        {
3952
            void *p2;
3953
            p  = lock_user_string(arg2);
3954
            p2 = lock_user_string(arg4);
3955
            if (!p || !p2)
3956
                ret = -TARGET_EFAULT;
3957
            else
3958
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3959
            unlock_user(p2, arg4, 0);
3960
            unlock_user(p, arg2, 0);
3961
        }
3962
        break;
3963
#endif
3964
    case TARGET_NR_mkdir:
3965
        if (!(p = lock_user_string(arg1)))
3966
            goto efault;
3967
        ret = get_errno(mkdir(p, arg2));
3968
        unlock_user(p, arg1, 0);
3969
        break;
3970
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3971
    case TARGET_NR_mkdirat:
3972
        if (!(p = lock_user_string(arg2)))
3973
            goto efault;
3974
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
3975
        unlock_user(p, arg2, 0);
3976
        break;
3977
#endif
3978
    case TARGET_NR_rmdir:
3979
        if (!(p = lock_user_string(arg1)))
3980
            goto efault;
3981
        ret = get_errno(rmdir(p));
3982
        unlock_user(p, arg1, 0);
3983
        break;
3984
    case TARGET_NR_dup:
3985
        ret = get_errno(dup(arg1));
3986
        break;
3987
    case TARGET_NR_pipe:
3988
        {
3989
            int host_pipe[2];
3990
            ret = get_errno(pipe(host_pipe));
3991
            if (!is_error(ret)) {
3992
#if defined(TARGET_MIPS)
3993
                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3994
                env->active_tc.gpr[3] = host_pipe[1];
3995
                ret = host_pipe[0];
3996
#elif defined(TARGET_SH4)
3997
                ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3998
                ret = host_pipe[0];
3999
#else
4000
                if (put_user_s32(host_pipe[0], arg1)
4001
                    || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
4002
                    goto efault;
4003
#endif
4004
            }
4005
        }
4006
        break;
4007
    case TARGET_NR_times:
4008
        {
4009
            struct target_tms *tmsp;
4010
            struct tms tms;
4011
            ret = get_errno(times(&tms));
4012
            if (arg1) {
4013
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4014
                if (!tmsp)
4015
                    goto efault;
4016
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4017
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4018
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4019
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4020
            }
4021
            if (!is_error(ret))
4022
                ret = host_to_target_clock_t(ret);
4023
        }
4024
        break;
4025
#ifdef TARGET_NR_prof
4026
    case TARGET_NR_prof:
4027
        goto unimplemented;
4028
#endif
4029
#ifdef TARGET_NR_signal
4030
    case TARGET_NR_signal:
4031
        goto unimplemented;
4032
#endif
4033
    case TARGET_NR_acct:
4034
        if (arg1 == 0) {
4035
            ret = get_errno(acct(NULL));
4036
        } else {
4037
            if (!(p = lock_user_string(arg1)))
4038
                goto efault;
4039
            ret = get_errno(acct(path(p)));
4040
            unlock_user(p, arg1, 0);
4041
        }
4042
        break;
4043
#ifdef TARGET_NR_umount2 /* not on alpha */
4044
    case TARGET_NR_umount2:
4045
        if (!(p = lock_user_string(arg1)))
4046
            goto efault;
4047
        ret = get_errno(umount2(p, arg2));
4048
        unlock_user(p, arg1, 0);
4049
        break;
4050
#endif
4051
#ifdef TARGET_NR_lock
4052
    case TARGET_NR_lock:
4053
        goto unimplemented;
4054
#endif
4055
    case TARGET_NR_ioctl:
4056
        ret = do_ioctl(arg1, arg2, arg3);
4057
        break;
4058
    case TARGET_NR_fcntl:
4059
        ret = do_fcntl(arg1, arg2, arg3);
4060
        break;
4061
#ifdef TARGET_NR_mpx
4062
    case TARGET_NR_mpx:
4063
        goto unimplemented;
4064
#endif
4065
    case TARGET_NR_setpgid:
4066
        ret = get_errno(setpgid(arg1, arg2));
4067
        break;
4068
#ifdef TARGET_NR_ulimit
4069
    case TARGET_NR_ulimit:
4070
        goto unimplemented;
4071
#endif
4072
#ifdef TARGET_NR_oldolduname
4073
    case TARGET_NR_oldolduname:
4074
        goto unimplemented;
4075
#endif
4076
    case TARGET_NR_umask:
4077
        ret = get_errno(umask(arg1));
4078
        break;
4079
    case TARGET_NR_chroot:
4080
        if (!(p = lock_user_string(arg1)))
4081
            goto efault;
4082
        ret = get_errno(chroot(p));
4083
        unlock_user(p, arg1, 0);
4084
        break;
4085
    case TARGET_NR_ustat:
4086
        goto unimplemented;
4087
    case TARGET_NR_dup2:
4088
        ret = get_errno(dup2(arg1, arg2));
4089
        break;
4090
#ifdef TARGET_NR_getppid /* not on alpha */
4091
    case TARGET_NR_getppid:
4092
        ret = get_errno(getppid());
4093
        break;
4094
#endif
4095
    case TARGET_NR_getpgrp:
4096
        ret = get_errno(getpgrp());
4097
        break;
4098
    case TARGET_NR_setsid:
4099
        ret = get_errno(setsid());
4100
        break;
4101
#ifdef TARGET_NR_sigaction
4102
    case TARGET_NR_sigaction:
4103
        {
4104
#if !defined(TARGET_MIPS)
4105
            struct target_old_sigaction *old_act;
4106
            struct target_sigaction act, oact, *pact;
4107
            if (arg2) {
4108
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4109
                    goto efault;
4110
                act._sa_handler = old_act->_sa_handler;
4111
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4112
                act.sa_flags = old_act->sa_flags;
4113
                act.sa_restorer = old_act->sa_restorer;
4114
                unlock_user_struct(old_act, arg2, 0);
4115
                pact = &act;
4116
            } else {
4117
                pact = NULL;
4118
            }
4119
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4120
            if (!is_error(ret) && arg3) {
4121
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4122
                    goto efault;
4123
                old_act->_sa_handler = oact._sa_handler;
4124
                old_act->sa_mask = oact.sa_mask.sig[0];
4125
                old_act->sa_flags = oact.sa_flags;
4126
                old_act->sa_restorer = oact.sa_restorer;
4127
                unlock_user_struct(old_act, arg3, 1);
4128
            }
4129
#else
4130
            struct target_sigaction act, oact, *pact, *old_act;
4131

    
4132
            if (arg2) {
4133
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4134
                    goto efault;
4135
                act._sa_handler = old_act->_sa_handler;
4136
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4137
                act.sa_flags = old_act->sa_flags;
4138
                unlock_user_struct(old_act, arg2, 0);
4139
                pact = &act;
4140
            } else {
4141
                pact = NULL;
4142
            }
4143

    
4144
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4145

    
4146
            if (!is_error(ret) && arg3) {
4147
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4148
                    goto efault;
4149
                old_act->_sa_handler = oact._sa_handler;
4150
                old_act->sa_flags = oact.sa_flags;
4151
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4152
                old_act->sa_mask.sig[1] = 0;
4153
                old_act->sa_mask.sig[2] = 0;
4154
                old_act->sa_mask.sig[3] = 0;
4155
                unlock_user_struct(old_act, arg3, 1);
4156
            }
4157
#endif
4158
        }
4159
        break;
4160
#endif
4161
    case TARGET_NR_rt_sigaction:
4162
        {
4163
            struct target_sigaction *act;
4164
            struct target_sigaction *oact;
4165

    
4166
            if (arg2) {
4167
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4168
                    goto efault;
4169
            } else
4170
                act = NULL;
4171
            if (arg3) {
4172
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4173
                    ret = -TARGET_EFAULT;
4174
                    goto rt_sigaction_fail;
4175
                }
4176
            } else
4177
                oact = NULL;
4178
            ret = get_errno(do_sigaction(arg1, act, oact));
4179
        rt_sigaction_fail:
4180
            if (act)
4181
                unlock_user_struct(act, arg2, 0);
4182
            if (oact)
4183
                unlock_user_struct(oact, arg3, 1);
4184
        }
4185
        break;
4186
#ifdef TARGET_NR_sgetmask /* not on alpha */
4187
    case TARGET_NR_sgetmask:
4188
        {
4189
            sigset_t cur_set;
4190
            abi_ulong target_set;
4191
            sigprocmask(0, NULL, &cur_set);
4192
            host_to_target_old_sigset(&target_set, &cur_set);
4193
            ret = target_set;
4194
        }
4195
        break;
4196
#endif
4197
#ifdef TARGET_NR_ssetmask /* not on alpha */
4198
    case TARGET_NR_ssetmask:
4199
        {
4200
            sigset_t set, oset, cur_set;
4201
            abi_ulong target_set = arg1;
4202
            sigprocmask(0, NULL, &cur_set);
4203
            target_to_host_old_sigset(&set, &target_set);
4204
            sigorset(&set, &set, &cur_set);
4205
            sigprocmask(SIG_SETMASK, &set, &oset);
4206
            host_to_target_old_sigset(&target_set, &oset);
4207
            ret = target_set;
4208
        }
4209
        break;
4210
#endif
4211
#ifdef TARGET_NR_sigprocmask
4212
    case TARGET_NR_sigprocmask:
4213
        {
4214
            int how = arg1;
4215
            sigset_t set, oldset, *set_ptr;
4216

    
4217
            if (arg2) {
4218
                switch(how) {
4219
                case TARGET_SIG_BLOCK:
4220
                    how = SIG_BLOCK;
4221
                    break;
4222
                case TARGET_SIG_UNBLOCK:
4223
                    how = SIG_UNBLOCK;
4224
                    break;
4225
                case TARGET_SIG_SETMASK:
4226
                    how = SIG_SETMASK;
4227
                    break;
4228
                default:
4229
                    ret = -TARGET_EINVAL;
4230
                    goto fail;
4231
                }
4232
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4233
                    goto efault;
4234
                target_to_host_old_sigset(&set, p);
4235
                unlock_user(p, arg2, 0);
4236
                set_ptr = &set;
4237
            } else {
4238
                how = 0;
4239
                set_ptr = NULL;
4240
            }
4241
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4242
            if (!is_error(ret) && arg3) {
4243
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4244
                    goto efault;
4245
                host_to_target_old_sigset(p, &oldset);
4246
                unlock_user(p, arg3, sizeof(target_sigset_t));
4247
            }
4248
        }
4249
        break;
4250
#endif
4251
    case TARGET_NR_rt_sigprocmask:
4252
        {
4253
            int how = arg1;
4254
            sigset_t set, oldset, *set_ptr;
4255

    
4256
            if (arg2) {
4257
                switch(how) {
4258
                case TARGET_SIG_BLOCK:
4259
                    how = SIG_BLOCK;
4260
                    break;
4261
                case TARGET_SIG_UNBLOCK:
4262
                    how = SIG_UNBLOCK;
4263
                    break;
4264
                case TARGET_SIG_SETMASK:
4265
                    how = SIG_SETMASK;
4266
                    break;
4267
                default:
4268
                    ret = -TARGET_EINVAL;
4269
                    goto fail;
4270
                }
4271
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4272
                    goto efault;
4273
                target_to_host_sigset(&set, p);
4274
                unlock_user(p, arg2, 0);
4275
                set_ptr = &set;
4276
            } else {
4277
                how = 0;
4278
                set_ptr = NULL;
4279
            }
4280
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4281
            if (!is_error(ret) && arg3) {
4282
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4283
                    goto efault;
4284
                host_to_target_sigset(p, &oldset);
4285
                unlock_user(p, arg3, sizeof(target_sigset_t));
4286
            }
4287
        }
4288
        break;
4289
#ifdef TARGET_NR_sigpending
4290
    case TARGET_NR_sigpending:
4291
        {
4292
            sigset_t set;
4293
            ret = get_errno(sigpending(&set));
4294
            if (!is_error(ret)) {
4295
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4296
                    goto efault;
4297
                host_to_target_old_sigset(p, &set);
4298
                unlock_user(p, arg1, sizeof(target_sigset_t));
4299
            }
4300
        }
4301
        break;
4302
#endif
4303
    case TARGET_NR_rt_sigpending:
4304
        {
4305
            sigset_t set;
4306
            ret = get_errno(sigpending(&set));
4307
            if (!is_error(ret)) {
4308
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4309
                    goto efault;
4310
                host_to_target_sigset(p, &set);
4311
                unlock_user(p, arg1, sizeof(target_sigset_t));
4312
            }
4313
        }
4314
        break;
4315
#ifdef TARGET_NR_sigsuspend
4316
    case TARGET_NR_sigsuspend:
4317
        {
4318
            sigset_t set;
4319
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4320
                goto efault;
4321
            target_to_host_old_sigset(&set, p);
4322
            unlock_user(p, arg1, 0);
4323
            ret = get_errno(sigsuspend(&set));
4324
        }
4325
        break;
4326
#endif
4327
    case TARGET_NR_rt_sigsuspend:
4328
        {
4329
            sigset_t set;
4330
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4331
                goto efault;
4332
            target_to_host_sigset(&set, p);
4333
            unlock_user(p, arg1, 0);
4334
            ret = get_errno(sigsuspend(&set));
4335
        }
4336
        break;
4337
    case TARGET_NR_rt_sigtimedwait:
4338
        {
4339
            sigset_t set;
4340
            struct timespec uts, *puts;
4341
            siginfo_t uinfo;
4342

    
4343
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4344
                goto efault;
4345
            target_to_host_sigset(&set, p);
4346
            unlock_user(p, arg1, 0);
4347
            if (arg3) {
4348
                puts = &uts;
4349
                target_to_host_timespec(puts, arg3);
4350
            } else {
4351
                puts = NULL;
4352
            }
4353
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4354
            if (!is_error(ret) && arg2) {
4355
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4356
                    goto efault;
4357
                host_to_target_siginfo(p, &uinfo);
4358
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4359
            }
4360
        }
4361
        break;
4362
    case TARGET_NR_rt_sigqueueinfo:
4363
        {
4364
            siginfo_t uinfo;
4365
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4366
                goto efault;
4367
            target_to_host_siginfo(&uinfo, p);
4368
            unlock_user(p, arg1, 0);
4369
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4370
        }
4371
        break;
4372
#ifdef TARGET_NR_sigreturn
4373
    case TARGET_NR_sigreturn:
4374
        /* NOTE: ret is eax, so not transcoding must be done */
4375
        ret = do_sigreturn(cpu_env);
4376
        break;
4377
#endif
4378
    case TARGET_NR_rt_sigreturn:
4379
        /* NOTE: ret is eax, so not transcoding must be done */
4380
        ret = do_rt_sigreturn(cpu_env);
4381
        break;
4382
    case TARGET_NR_sethostname:
4383
        if (!(p = lock_user_string(arg1)))
4384
            goto efault;
4385
        ret = get_errno(sethostname(p, arg2));
4386
        unlock_user(p, arg1, 0);
4387
        break;
4388
    case TARGET_NR_setrlimit:
4389
        {
4390
            /* XXX: convert resource ? */
4391
            int resource = arg1;
4392
            struct target_rlimit *target_rlim;
4393
            struct rlimit rlim;
4394
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4395
                goto efault;
4396
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4397
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4398
            unlock_user_struct(target_rlim, arg2, 0);
4399
            ret = get_errno(setrlimit(resource, &rlim));
4400
        }
4401
        break;
4402
    case TARGET_NR_getrlimit:
4403
        {
4404
            /* XXX: convert resource ? */
4405
            int resource = arg1;
4406
            struct target_rlimit *target_rlim;
4407
            struct rlimit rlim;
4408

    
4409
            ret = get_errno(getrlimit(resource, &rlim));
4410
            if (!is_error(ret)) {
4411
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4412
                    goto efault;
4413
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4414
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4415
                unlock_user_struct(target_rlim, arg2, 1);
4416
            }
4417
        }
4418
        break;
4419
    case TARGET_NR_getrusage:
4420
        {
4421
            struct rusage rusage;
4422
            ret = get_errno(getrusage(arg1, &rusage));
4423
            if (!is_error(ret)) {
4424
                host_to_target_rusage(arg2, &rusage);
4425
            }
4426
        }
4427
        break;
4428
    case TARGET_NR_gettimeofday:
4429
        {
4430
            struct timeval tv;
4431
            ret = get_errno(gettimeofday(&tv, NULL));
4432
            if (!is_error(ret)) {
4433
                if (copy_to_user_timeval(arg1, &tv))
4434
                    goto efault;
4435
            }
4436
        }
4437
        break;
4438
    case TARGET_NR_settimeofday:
4439
        {
4440
            struct timeval tv;
4441
            if (copy_from_user_timeval(&tv, arg1))
4442
                goto efault;
4443
            ret = get_errno(settimeofday(&tv, NULL));
4444
        }
4445
        break;
4446
#ifdef TARGET_NR_select
4447
    case TARGET_NR_select:
4448
        {
4449
            struct target_sel_arg_struct *sel;
4450
            abi_ulong inp, outp, exp, tvp;
4451
            long nsel;
4452

    
4453
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4454
                goto efault;
4455
            nsel = tswapl(sel->n);
4456
            inp = tswapl(sel->inp);
4457
            outp = tswapl(sel->outp);
4458
            exp = tswapl(sel->exp);
4459
            tvp = tswapl(sel->tvp);
4460
            unlock_user_struct(sel, arg1, 0);
4461
            ret = do_select(nsel, inp, outp, exp, tvp);
4462
        }
4463
        break;
4464
#endif
4465
    case TARGET_NR_symlink:
4466
        {
4467
            void *p2;
4468
            p = lock_user_string(arg1);
4469
            p2 = lock_user_string(arg2);
4470
            if (!p || !p2)
4471
                ret = -TARGET_EFAULT;
4472
            else
4473
                ret = get_errno(symlink(p, p2));
4474
            unlock_user(p2, arg2, 0);
4475
            unlock_user(p, arg1, 0);
4476
        }
4477
        break;
4478
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4479
    case TARGET_NR_symlinkat:
4480
        {
4481
            void *p2;
4482
            p  = lock_user_string(arg1);
4483
            p2 = lock_user_string(arg3);
4484
            if (!p || !p2)
4485
                ret = -TARGET_EFAULT;
4486
            else
4487
                ret = get_errno(sys_symlinkat(p, arg2, p2));
4488
            unlock_user(p2, arg3, 0);
4489
            unlock_user(p, arg1, 0);
4490
        }
4491
        break;
4492
#endif
4493
#ifdef TARGET_NR_oldlstat
4494
    case TARGET_NR_oldlstat:
4495
        goto unimplemented;
4496
#endif
4497
    case TARGET_NR_readlink:
4498
        {
4499
            void *p2, *temp;
4500
            p = lock_user_string(arg1);
4501
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4502
            if (!p || !p2)
4503
                ret = -TARGET_EFAULT;
4504
            else {
4505
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
4506
                    char real[PATH_MAX];
4507
                    temp = realpath(exec_path,real);
4508
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
4509
                    snprintf((char *)p2, arg3, "%s", real);
4510
                    }
4511
                else
4512
                    ret = get_errno(readlink(path(p), p2, arg3));
4513
            }
4514
            unlock_user(p2, arg2, ret);
4515
            unlock_user(p, arg1, 0);
4516
        }
4517
        break;
4518
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4519
    case TARGET_NR_readlinkat:
4520
        {
4521
            void *p2;
4522
            p  = lock_user_string(arg2);
4523
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4524
            if (!p || !p2)
4525
                ret = -TARGET_EFAULT;
4526
            else
4527
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4528
            unlock_user(p2, arg3, ret);
4529
            unlock_user(p, arg2, 0);
4530
        }
4531
        break;
4532
#endif
4533
#ifdef TARGET_NR_uselib
4534
    case TARGET_NR_uselib:
4535
        goto unimplemented;
4536
#endif
4537
#ifdef TARGET_NR_swapon
4538
    case TARGET_NR_swapon:
4539
        if (!(p = lock_user_string(arg1)))
4540
            goto efault;
4541
        ret = get_errno(swapon(p, arg2));
4542
        unlock_user(p, arg1, 0);
4543
        break;
4544
#endif
4545
    case TARGET_NR_reboot:
4546
        goto unimplemented;
4547
#ifdef TARGET_NR_readdir
4548
    case TARGET_NR_readdir:
4549
        goto unimplemented;
4550
#endif
4551
#ifdef TARGET_NR_mmap
4552
    case TARGET_NR_mmap:
4553
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4554
        {
4555
            abi_ulong *v;
4556
            abi_ulong v1, v2, v3, v4, v5, v6;
4557
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4558
                goto efault;
4559
            v1 = tswapl(v[0]);
4560
            v2 = tswapl(v[1]);
4561
            v3 = tswapl(v[2]);
4562
            v4 = tswapl(v[3]);
4563
            v5 = tswapl(v[4]);
4564
            v6 = tswapl(v[5]);
4565
            unlock_user(v, arg1, 0);
4566
            ret = get_errno(target_mmap(v1, v2, v3,
4567
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
4568
                                        v5, v6));
4569
        }
4570
#else
4571
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4572
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4573
                                    arg5,
4574
                                    arg6));
4575
#endif
4576
        break;
4577
#endif
4578
#ifdef TARGET_NR_mmap2
4579
    case TARGET_NR_mmap2:
4580
#ifndef MMAP_SHIFT
4581
#define MMAP_SHIFT 12
4582
#endif
4583
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4584
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4585
                                    arg5,
4586
                                    arg6 << MMAP_SHIFT));
4587
        break;
4588
#endif
4589
    case TARGET_NR_munmap:
4590
        ret = get_errno(target_munmap(arg1, arg2));
4591
        break;
4592
    case TARGET_NR_mprotect:
4593
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
4594
        break;
4595
#ifdef TARGET_NR_mremap
4596
    case TARGET_NR_mremap:
4597
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4598
        break;
4599
#endif
4600
        /* ??? msync/mlock/munlock are broken for softmmu.  */
4601
#ifdef TARGET_NR_msync
4602
    case TARGET_NR_msync:
4603
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
4604
        break;
4605
#endif
4606
#ifdef TARGET_NR_mlock
4607
    case TARGET_NR_mlock:
4608
        ret = get_errno(mlock(g2h(arg1), arg2));
4609
        break;
4610
#endif
4611
#ifdef TARGET_NR_munlock
4612
    case TARGET_NR_munlock:
4613
        ret = get_errno(munlock(g2h(arg1), arg2));
4614
        break;
4615
#endif
4616
#ifdef TARGET_NR_mlockall
4617
    case TARGET_NR_mlockall:
4618
        ret = get_errno(mlockall(arg1));
4619
        break;
4620
#endif
4621
#ifdef TARGET_NR_munlockall
4622
    case TARGET_NR_munlockall:
4623
        ret = get_errno(munlockall());
4624
        break;
4625
#endif
4626
    case TARGET_NR_truncate:
4627
        if (!(p = lock_user_string(arg1)))
4628
            goto efault;
4629
        ret = get_errno(truncate(p, arg2));
4630
        unlock_user(p, arg1, 0);
4631
        break;
4632
    case TARGET_NR_ftruncate:
4633
        ret = get_errno(ftruncate(arg1, arg2));
4634
        break;
4635
    case TARGET_NR_fchmod:
4636
        ret = get_errno(fchmod(arg1, arg2));
4637
        break;
4638
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4639
    case TARGET_NR_fchmodat:
4640
        if (!(p = lock_user_string(arg2)))
4641
            goto efault;
4642
        ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4643
        unlock_user(p, arg2, 0);
4644
        break;
4645
#endif
4646
    case TARGET_NR_getpriority:
4647
        /* libc does special remapping of the return value of
4648
         * sys_getpriority() so it's just easiest to call
4649
         * sys_getpriority() directly rather than through libc. */
4650
        ret = sys_getpriority(arg1, arg2);
4651
        break;
4652
    case TARGET_NR_setpriority:
4653
        ret = get_errno(setpriority(arg1, arg2, arg3));
4654
        break;
4655
#ifdef TARGET_NR_profil
4656
    case TARGET_NR_profil:
4657
        goto unimplemented;
4658
#endif
4659
    case TARGET_NR_statfs:
4660
        if (!(p = lock_user_string(arg1)))
4661
            goto efault;
4662
        ret = get_errno(statfs(path(p), &stfs));
4663
        unlock_user(p, arg1, 0);
4664
    convert_statfs:
4665
        if (!is_error(ret)) {
4666
            struct target_statfs *target_stfs;
4667

    
4668
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4669
                goto efault;
4670
            __put_user(stfs.f_type, &target_stfs->f_type);
4671
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4672
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4673
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4674
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4675
            __put_user(stfs.f_files, &target_stfs->f_files);
4676
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4677
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4678
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4679
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4680
            unlock_user_struct(target_stfs, arg2, 1);
4681
        }
4682
        break;
4683
    case TARGET_NR_fstatfs:
4684
        ret = get_errno(fstatfs(arg1, &stfs));
4685
        goto convert_statfs;
4686
#ifdef TARGET_NR_statfs64
4687
    case TARGET_NR_statfs64:
4688
        if (!(p = lock_user_string(arg1)))
4689
            goto efault;
4690
        ret = get_errno(statfs(path(p), &stfs));
4691
        unlock_user(p, arg1, 0);
4692
    convert_statfs64:
4693
        if (!is_error(ret)) {
4694
            struct target_statfs64 *target_stfs;
4695

    
4696
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4697
                goto efault;
4698
            __put_user(stfs.f_type, &target_stfs->f_type);
4699
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4700
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4701
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4702
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4703
            __put_user(stfs.f_files, &target_stfs->f_files);
4704
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4705
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4706
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4707
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4708
            unlock_user_struct(target_stfs, arg3, 1);
4709
        }
4710
        break;
4711
    case TARGET_NR_fstatfs64:
4712
        ret = get_errno(fstatfs(arg1, &stfs));
4713
        goto convert_statfs64;
4714
#endif
4715
#ifdef TARGET_NR_ioperm
4716
    case TARGET_NR_ioperm:
4717
        goto unimplemented;
4718
#endif
4719
#ifdef TARGET_NR_socketcall
4720
    case TARGET_NR_socketcall:
4721
        ret = do_socketcall(arg1, arg2);
4722
        break;
4723
#endif
4724
#ifdef TARGET_NR_accept
4725
    case TARGET_NR_accept:
4726
        ret = do_accept(arg1, arg2, arg3);
4727
        break;
4728
#endif
4729
#ifdef TARGET_NR_bind
4730
    case TARGET_NR_bind:
4731
        ret = do_bind(arg1, arg2, arg3);
4732
        break;
4733
#endif
4734
#ifdef TARGET_NR_connect
4735
    case TARGET_NR_connect:
4736
        ret = do_connect(arg1, arg2, arg3);
4737
        break;
4738
#endif
4739
#ifdef TARGET_NR_getpeername
4740
    case TARGET_NR_getpeername:
4741
        ret = do_getpeername(arg1, arg2, arg3);
4742
        break;
4743
#endif
4744
#ifdef TARGET_NR_getsockname
4745
    case TARGET_NR_getsockname:
4746
        ret = do_getsockname(arg1, arg2, arg3);
4747
        break;
4748
#endif
4749
#ifdef TARGET_NR_getsockopt
4750
    case TARGET_NR_getsockopt:
4751
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4752
        break;
4753
#endif
4754
#ifdef TARGET_NR_listen
4755
    case TARGET_NR_listen:
4756
        ret = get_errno(listen(arg1, arg2));
4757
        break;
4758
#endif
4759
#ifdef TARGET_NR_recv
4760
    case TARGET_NR_recv:
4761
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4762
        break;
4763
#endif
4764
#ifdef TARGET_NR_recvfrom
4765
    case TARGET_NR_recvfrom:
4766
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4767
        break;
4768
#endif
4769
#ifdef TARGET_NR_recvmsg
4770
    case TARGET_NR_recvmsg:
4771
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4772
        break;
4773
#endif
4774
#ifdef TARGET_NR_send
4775
    case TARGET_NR_send:
4776
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4777
        break;
4778
#endif
4779
#ifdef TARGET_NR_sendmsg
4780
    case TARGET_NR_sendmsg:
4781
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4782
        break;
4783
#endif
4784
#ifdef TARGET_NR_sendto
4785
    case TARGET_NR_sendto:
4786
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4787
        break;
4788
#endif
4789
#ifdef TARGET_NR_shutdown
4790
    case TARGET_NR_shutdown:
4791
        ret = get_errno(shutdown(arg1, arg2));
4792
        break;
4793
#endif
4794
#ifdef TARGET_NR_socket
4795
    case TARGET_NR_socket:
4796
        ret = do_socket(arg1, arg2, arg3);
4797
        break;
4798
#endif
4799
#ifdef TARGET_NR_socketpair
4800
    case TARGET_NR_socketpair:
4801
        ret = do_socketpair(arg1, arg2, arg3, arg4);
4802
        break;
4803
#endif
4804
#ifdef TARGET_NR_setsockopt
4805
    case TARGET_NR_setsockopt:
4806
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4807
        break;
4808
#endif
4809

    
4810
    case TARGET_NR_syslog:
4811
        if (!(p = lock_user_string(arg2)))
4812
            goto efault;
4813
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4814
        unlock_user(p, arg2, 0);
4815
        break;
4816

    
4817
    case TARGET_NR_setitimer:
4818
        {
4819
            struct itimerval value, ovalue, *pvalue;
4820

    
4821
            if (arg2) {
4822
                pvalue = &value;
4823
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4824
                    || copy_from_user_timeval(&pvalue->it_value,
4825
                                              arg2 + sizeof(struct target_timeval)))
4826
                    goto efault;
4827
            } else {
4828
                pvalue = NULL;
4829
            }
4830
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4831
            if (!is_error(ret) && arg3) {
4832
                if (copy_to_user_timeval(arg3,
4833
                                         &ovalue.it_interval)
4834
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4835
                                            &ovalue.it_value))
4836
                    goto efault;
4837
            }
4838
        }
4839
        break;
4840
    case TARGET_NR_getitimer:
4841
        {
4842
            struct itimerval value;
4843

    
4844
            ret = get_errno(getitimer(arg1, &value));
4845
            if (!is_error(ret) && arg2) {
4846
                if (copy_to_user_timeval(arg2,
4847
                                         &value.it_interval)
4848
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4849
                                            &value.it_value))
4850
                    goto efault;
4851
            }
4852
        }
4853
        break;
4854
    case TARGET_NR_stat:
4855
        if (!(p = lock_user_string(arg1)))
4856
            goto efault;
4857
        ret = get_errno(stat(path(p), &st));
4858
        unlock_user(p, arg1, 0);
4859
        goto do_stat;
4860
    case TARGET_NR_lstat:
4861
        if (!(p = lock_user_string(arg1)))
4862
            goto efault;
4863
        ret = get_errno(lstat(path(p), &st));
4864
        unlock_user(p, arg1, 0);
4865
        goto do_stat;
4866
    case TARGET_NR_fstat:
4867
        {
4868
            ret = get_errno(fstat(arg1, &st));
4869
        do_stat:
4870
            if (!is_error(ret)) {
4871
                struct target_stat *target_st;
4872

    
4873
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4874
                    goto efault;
4875
                __put_user(st.st_dev, &target_st->st_dev);
4876
                __put_user(st.st_ino, &target_st->st_ino);
4877
                __put_user(st.st_mode, &target_st->st_mode);
4878
                __put_user(st.st_uid, &target_st->st_uid);
4879
                __put_user(st.st_gid, &target_st->st_gid);
4880
                __put_user(st.st_nlink, &target_st->st_nlink);
4881
                __put_user(st.st_rdev, &target_st->st_rdev);
4882
                __put_user(st.st_size, &target_st->st_size);
4883
                __put_user(st.st_blksize, &target_st->st_blksize);
4884
                __put_user(st.st_blocks, &target_st->st_blocks);
4885
                __put_user(st.st_atime, &target_st->target_st_atime);
4886
                __put_user(st.st_mtime, &target_st->target_st_mtime);
4887
                __put_user(st.st_ctime, &target_st->target_st_ctime);
4888
                unlock_user_struct(target_st, arg2, 1);
4889
            }
4890
        }
4891
        break;
4892
#ifdef TARGET_NR_olduname
4893
    case TARGET_NR_olduname:
4894
        goto unimplemented;
4895
#endif
4896
#ifdef TARGET_NR_iopl
4897
    case TARGET_NR_iopl:
4898
        goto unimplemented;
4899
#endif
4900
    case TARGET_NR_vhangup:
4901
        ret = get_errno(vhangup());
4902
        break;
4903
#ifdef TARGET_NR_idle
4904
    case TARGET_NR_idle:
4905
        goto unimplemented;
4906
#endif
4907
#ifdef TARGET_NR_syscall
4908
    case TARGET_NR_syscall:
4909
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4910
            break;
4911
#endif
4912
    case TARGET_NR_wait4:
4913
        {
4914
            int status;
4915
            abi_long status_ptr = arg2;
4916
            struct rusage rusage, *rusage_ptr;
4917
            abi_ulong target_rusage = arg4;
4918
            if (target_rusage)
4919
                rusage_ptr = &rusage;
4920
            else
4921
                rusage_ptr = NULL;
4922
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4923
            if (!is_error(ret)) {
4924
                if (status_ptr) {
4925
                    if (put_user_s32(status, status_ptr))
4926
                        goto efault;
4927
                }
4928
                if (target_rusage)
4929
                    host_to_target_rusage(target_rusage, &rusage);
4930
            }
4931
        }
4932
        break;
4933
#ifdef TARGET_NR_swapoff
4934
    case TARGET_NR_swapoff:
4935
        if (!(p = lock_user_string(arg1)))
4936
            goto efault;
4937
        ret = get_errno(swapoff(p));
4938
        unlock_user(p, arg1, 0);
4939
        break;
4940
#endif
4941
    case TARGET_NR_sysinfo:
4942
        {
4943
            struct target_sysinfo *target_value;
4944
            struct sysinfo value;
4945
            ret = get_errno(sysinfo(&value));
4946
            if (!is_error(ret) && arg1)
4947
            {
4948
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4949
                    goto efault;
4950
                __put_user(value.uptime, &target_value->uptime);
4951
                __put_user(value.loads[0], &target_value->loads[0]);
4952
                __put_user(value.loads[1], &target_value->loads[1]);
4953
                __put_user(value.loads[2], &target_value->loads[2]);
4954
                __put_user(value.totalram, &target_value->totalram);
4955
                __put_user(value.freeram, &target_value->freeram);
4956
                __put_user(value.sharedram, &target_value->sharedram);
4957
                __put_user(value.bufferram, &target_value->bufferram);
4958
                __put_user(value.totalswap, &target_value->totalswap);
4959
                __put_user(value.freeswap, &target_value->freeswap);
4960
                __put_user(value.procs, &target_value->procs);
4961
                __put_user(value.totalhigh, &target_value->totalhigh);
4962
                __put_user(value.freehigh, &target_value->freehigh);
4963
                __put_user(value.mem_unit, &target_value->mem_unit);
4964
                unlock_user_struct(target_value, arg1, 1);
4965
            }
4966
        }
4967
        break;
4968
#ifdef TARGET_NR_ipc
4969
    case TARGET_NR_ipc:
4970
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4971
        break;
4972
#endif
4973

    
4974
#ifdef TARGET_NR_msgctl
4975
    case TARGET_NR_msgctl:
4976
        ret = do_msgctl(arg1, arg2, arg3);
4977
        break;
4978
#endif
4979
#ifdef TARGET_NR_msgget
4980
    case TARGET_NR_msgget:
4981
        ret = get_errno(msgget(arg1, arg2));
4982
        break;
4983
#endif
4984
#ifdef TARGET_NR_msgrcv
4985
    case TARGET_NR_msgrcv:
4986
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
4987
        break;
4988
#endif
4989
#ifdef TARGET_NR_msgsnd
4990
    case TARGET_NR_msgsnd:
4991
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
4992
        break;
4993
#endif
4994
    case TARGET_NR_fsync:
4995
        ret = get_errno(fsync(arg1));
4996
        break;
4997
    case TARGET_NR_clone:
4998
#if defined(TARGET_SH4)
4999
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5000
#elif defined(TARGET_CRIS)
5001
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5002
#else
5003
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5004
#endif
5005
        break;
5006
#ifdef __NR_exit_group
5007
        /* new thread calls */
5008
    case TARGET_NR_exit_group:
5009
#ifdef HAVE_GPROF
5010
        _mcleanup();
5011
#endif
5012
        gdb_exit(cpu_env, arg1);
5013
        ret = get_errno(exit_group(arg1));
5014
        break;
5015
#endif
5016
    case TARGET_NR_setdomainname:
5017
        if (!(p = lock_user_string(arg1)))
5018
            goto efault;
5019
        ret = get_errno(setdomainname(p, arg2));
5020
        unlock_user(p, arg1, 0);
5021
        break;
5022
    case TARGET_NR_uname:
5023
        /* no need to transcode because we use the linux syscall */
5024
        {
5025
            struct new_utsname * buf;
5026

    
5027
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5028
                goto efault;
5029
            ret = get_errno(sys_uname(buf));
5030
            if (!is_error(ret)) {
5031
                /* Overrite the native machine name with whatever is being
5032
                   emulated. */
5033
                strcpy (buf->machine, UNAME_MACHINE);
5034
                /* Allow the user to override the reported release.  */
5035
                if (qemu_uname_release && *qemu_uname_release)
5036
                  strcpy (buf->release, qemu_uname_release);
5037
            }
5038
            unlock_user_struct(buf, arg1, 1);
5039
        }
5040
        break;
5041
#ifdef TARGET_I386
5042
    case TARGET_NR_modify_ldt:
5043
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5044
        break;
5045
#if !defined(TARGET_X86_64)
5046
    case TARGET_NR_vm86old:
5047
        goto unimplemented;
5048
    case TARGET_NR_vm86:
5049
        ret = do_vm86(cpu_env, arg1, arg2);
5050
        break;
5051
#endif
5052
#endif
5053
    case TARGET_NR_adjtimex:
5054
        goto unimplemented;
5055
#ifdef TARGET_NR_create_module
5056
    case TARGET_NR_create_module:
5057
#endif
5058
    case TARGET_NR_init_module:
5059
    case TARGET_NR_delete_module:
5060
#ifdef TARGET_NR_get_kernel_syms
5061
    case TARGET_NR_get_kernel_syms:
5062
#endif
5063
        goto unimplemented;
5064
    case TARGET_NR_quotactl:
5065
        goto unimplemented;
5066
    case TARGET_NR_getpgid:
5067
        ret = get_errno(getpgid(arg1));
5068
        break;
5069
    case TARGET_NR_fchdir:
5070
        ret = get_errno(fchdir(arg1));
5071
        break;
5072
#ifdef TARGET_NR_bdflush /* not on x86_64 */
5073
    case TARGET_NR_bdflush:
5074
        goto unimplemented;
5075
#endif
5076
#ifdef TARGET_NR_sysfs
5077
    case TARGET_NR_sysfs:
5078
        goto unimplemented;
5079
#endif
5080
    case TARGET_NR_personality:
5081
        ret = get_errno(personality(arg1));
5082
        break;
5083
#ifdef TARGET_NR_afs_syscall
5084
    case TARGET_NR_afs_syscall:
5085
        goto unimplemented;
5086
#endif
5087
#ifdef TARGET_NR__llseek /* Not on alpha */
5088
    case TARGET_NR__llseek:
5089
        {
5090
#if defined (__x86_64__)
5091
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5092
            if (put_user_s64(ret, arg4))
5093
                goto efault;
5094
#else
5095
            int64_t res;
5096
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5097
            if (put_user_s64(res, arg4))
5098
                goto efault;
5099
#endif
5100
        }
5101
        break;
5102
#endif
5103
    case TARGET_NR_getdents:
5104
#if TARGET_ABI_BITS != 32
5105
        goto unimplemented;
5106
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5107
        {
5108
            struct target_dirent *target_dirp;
5109
            struct linux_dirent *dirp;
5110
            abi_long count = arg3;
5111

    
5112
            dirp = malloc(count);
5113
            if (!dirp) {
5114
                ret = -TARGET_ENOMEM;
5115
                goto fail;
5116
            }
5117

    
5118
            ret = get_errno(sys_getdents(arg1, dirp, count));
5119
            if (!is_error(ret)) {
5120
                struct linux_dirent *de;
5121
                struct target_dirent *tde;
5122
                int len = ret;
5123
                int reclen, treclen;
5124
                int count1, tnamelen;
5125

    
5126
                count1 = 0;
5127
                de = dirp;
5128
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5129
                    goto efault;
5130
                tde = target_dirp;
5131
                while (len > 0) {
5132
                    reclen = de->d_reclen;
5133
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5134
                    tde->d_reclen = tswap16(treclen);
5135
                    tde->d_ino = tswapl(de->d_ino);
5136
                    tde->d_off = tswapl(de->d_off);
5137
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5138
                    if (tnamelen > 256)
5139
                        tnamelen = 256;
5140
                    /* XXX: may not be correct */
5141
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5142
                    de = (struct linux_dirent *)((char *)de + reclen);
5143
                    len -= reclen;
5144
                    tde = (struct target_dirent *)((char *)tde + treclen);
5145
                    count1 += treclen;
5146
                }
5147
                ret = count1;
5148
                unlock_user(target_dirp, arg2, ret);
5149
            }
5150
            free(dirp);
5151
        }
5152
#else
5153
        {
5154
            struct linux_dirent *dirp;
5155
            abi_long count = arg3;
5156

    
5157
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5158
                goto efault;
5159
            ret = get_errno(sys_getdents(arg1, dirp, count));
5160
            if (!is_error(ret)) {
5161
                struct linux_dirent *de;
5162
                int len = ret;
5163
                int reclen;
5164
                de = dirp;
5165
                while (len > 0) {
5166
                    reclen = de->d_reclen;
5167
                    if (reclen > len)
5168
                        break;
5169
                    de->d_reclen = tswap16(reclen);
5170
                    tswapls(&de->d_ino);
5171
                    tswapls(&de->d_off);
5172
                    de = (struct linux_dirent *)((char *)de + reclen);
5173
                    len -= reclen;
5174
                }
5175
            }
5176
            unlock_user(dirp, arg2, ret);
5177
        }
5178
#endif
5179
        break;
5180
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5181
    case TARGET_NR_getdents64:
5182
        {
5183
            struct linux_dirent64 *dirp;
5184
            abi_long count = arg3;
5185
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5186
                goto efault;
5187
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5188
            if (!is_error(ret)) {
5189
                struct linux_dirent64 *de;
5190
                int len = ret;
5191
                int reclen;
5192
                de = dirp;
5193
                while (len > 0) {
5194
                    reclen = de->d_reclen;
5195
                    if (reclen > len)
5196
                        break;
5197
                    de->d_reclen = tswap16(reclen);
5198
                    tswap64s((uint64_t *)&de->d_ino);
5199
                    tswap64s((uint64_t *)&de->d_off);
5200
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5201
                    len -= reclen;
5202
                }
5203
            }
5204
            unlock_user(dirp, arg2, ret);
5205
        }
5206
        break;
5207
#endif /* TARGET_NR_getdents64 */
5208
#ifdef TARGET_NR__newselect
5209
    case TARGET_NR__newselect:
5210
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5211
        break;
5212
#endif
5213
#ifdef TARGET_NR_poll
5214
    case TARGET_NR_poll:
5215
        {
5216
            struct target_pollfd *target_pfd;
5217
            unsigned int nfds = arg2;
5218
            int timeout = arg3;
5219
            struct pollfd *pfd;
5220
            unsigned int i;
5221

    
5222
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5223
            if (!target_pfd)
5224
                goto efault;
5225
            pfd = alloca(sizeof(struct pollfd) * nfds);
5226
            for(i = 0; i < nfds; i++) {
5227
                pfd[i].fd = tswap32(target_pfd[i].fd);
5228
                pfd[i].events = tswap16(target_pfd[i].events);
5229
            }
5230
            ret = get_errno(poll(pfd, nfds, timeout));
5231
            if (!is_error(ret)) {
5232
                for(i = 0; i < nfds; i++) {
5233
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5234
                }
5235
                ret += nfds * (sizeof(struct target_pollfd)
5236
                               - sizeof(struct pollfd));
5237
            }
5238
            unlock_user(target_pfd, arg1, ret);
5239
        }
5240
        break;
5241
#endif
5242
    case TARGET_NR_flock:
5243
        /* NOTE: the flock constant seems to be the same for every
5244
           Linux platform */
5245
        ret = get_errno(flock(arg1, arg2));
5246
        break;
5247
    case TARGET_NR_readv:
5248
        {
5249
            int count = arg3;
5250
            struct iovec *vec;
5251

    
5252
            vec = alloca(count * sizeof(struct iovec));
5253
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5254
                goto efault;
5255
            ret = get_errno(readv(arg1, vec, count));
5256
            unlock_iovec(vec, arg2, count, 1);
5257
        }
5258
        break;
5259
    case TARGET_NR_writev:
5260
        {
5261
            int count = arg3;
5262
            struct iovec *vec;
5263

    
5264
            vec = alloca(count * sizeof(struct iovec));
5265
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5266
                goto efault;
5267
            ret = get_errno(writev(arg1, vec, count));
5268
            unlock_iovec(vec, arg2, count, 0);
5269
        }
5270
        break;
5271
    case TARGET_NR_getsid:
5272
        ret = get_errno(getsid(arg1));
5273
        break;
5274
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5275
    case TARGET_NR_fdatasync:
5276
        ret = get_errno(fdatasync(arg1));
5277
        break;
5278
#endif
5279
    case TARGET_NR__sysctl:
5280
        /* We don't implement this, but ENOTDIR is always a safe
5281
           return value. */
5282
        ret = -TARGET_ENOTDIR;
5283
        break;
5284
    case TARGET_NR_sched_setparam:
5285
        {
5286
            struct sched_param *target_schp;
5287
            struct sched_param schp;
5288

    
5289
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5290
                goto efault;
5291
            schp.sched_priority = tswap32(target_schp->sched_priority);
5292
            unlock_user_struct(target_schp, arg2, 0);
5293
            ret = get_errno(sched_setparam(arg1, &schp));
5294
        }
5295
        break;
5296
    case TARGET_NR_sched_getparam:
5297
        {
5298
            struct sched_param *target_schp;
5299
            struct sched_param schp;
5300
            ret = get_errno(sched_getparam(arg1, &schp));
5301
            if (!is_error(ret)) {
5302
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5303
                    goto efault;
5304
                target_schp->sched_priority = tswap32(schp.sched_priority);
5305
                unlock_user_struct(target_schp, arg2, 1);
5306
            }
5307
        }
5308
        break;
5309
    case TARGET_NR_sched_setscheduler:
5310
        {
5311
            struct sched_param *target_schp;
5312
            struct sched_param schp;
5313
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5314
                goto efault;
5315
            schp.sched_priority = tswap32(target_schp->sched_priority);
5316
            unlock_user_struct(target_schp, arg3, 0);
5317
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5318
        }
5319
        break;
5320
    case TARGET_NR_sched_getscheduler:
5321
        ret = get_errno(sched_getscheduler(arg1));
5322
        break;
5323
    case TARGET_NR_sched_yield:
5324
        ret = get_errno(sched_yield());
5325
        break;
5326
    case TARGET_NR_sched_get_priority_max:
5327
        ret = get_errno(sched_get_priority_max(arg1));
5328
        break;
5329
    case TARGET_NR_sched_get_priority_min:
5330
        ret = get_errno(sched_get_priority_min(arg1));
5331
        break;
5332
    case TARGET_NR_sched_rr_get_interval:
5333
        {
5334
            struct timespec ts;
5335
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
5336
            if (!is_error(ret)) {
5337
                host_to_target_timespec(arg2, &ts);
5338
            }
5339
        }
5340
        break;
5341
    case TARGET_NR_nanosleep:
5342
        {
5343
            struct timespec req, rem;
5344
            target_to_host_timespec(&req, arg1);
5345
            ret = get_errno(nanosleep(&req, &rem));
5346
            if (is_error(ret) && arg2) {
5347
                host_to_target_timespec(arg2, &rem);
5348
            }
5349
        }
5350
        break;
5351
#ifdef TARGET_NR_query_module
5352
    case TARGET_NR_query_module:
5353
        goto unimplemented;
5354
#endif
5355
#ifdef TARGET_NR_nfsservctl
5356
    case TARGET_NR_nfsservctl:
5357
        goto unimplemented;
5358
#endif
5359
    case TARGET_NR_prctl:
5360
        switch (arg1)
5361
            {
5362
            case PR_GET_PDEATHSIG:
5363
                {
5364
                    int deathsig;
5365
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5366
                    if (!is_error(ret) && arg2
5367
                        && put_user_ual(deathsig, arg2))
5368
                        goto efault;
5369
                }
5370
                break;
5371
            default:
5372
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5373
                break;
5374
            }
5375
        break;
5376
#ifdef TARGET_NR_arch_prctl
5377
    case TARGET_NR_arch_prctl:
5378
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
5379
        ret = do_arch_prctl(cpu_env, arg1, arg2);
5380
        break;
5381
#else
5382
        goto unimplemented;
5383
#endif
5384
#endif
5385
#ifdef TARGET_NR_pread
5386
    case TARGET_NR_pread:
5387
#ifdef TARGET_ARM
5388
        if (((CPUARMState *)cpu_env)->eabi)
5389
            arg4 = arg5;
5390
#endif
5391
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5392
            goto efault;
5393
        ret = get_errno(pread(arg1, p, arg3, arg4));
5394
        unlock_user(p, arg2, ret);
5395
        break;
5396
    case TARGET_NR_pwrite:
5397
#ifdef TARGET_ARM
5398
        if (((CPUARMState *)cpu_env)->eabi)
5399
            arg4 = arg5;
5400
#endif
5401
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5402
            goto efault;
5403
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
5404
        unlock_user(p, arg2, 0);
5405
        break;
5406
#endif
5407
#ifdef TARGET_NR_pread64
5408
    case TARGET_NR_pread64:
5409
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5410
            goto efault;
5411
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5412
        unlock_user(p, arg2, ret);
5413
        break;
5414
    case TARGET_NR_pwrite64:
5415
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5416
            goto efault;
5417
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5418
        unlock_user(p, arg2, 0);
5419
        break;
5420
#endif
5421
    case TARGET_NR_getcwd:
5422
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5423
            goto efault;
5424
        ret = get_errno(sys_getcwd1(p, arg2));
5425
        unlock_user(p, arg1, ret);
5426
        break;
5427
    case TARGET_NR_capget:
5428
        goto unimplemented;
5429
    case TARGET_NR_capset:
5430
        goto unimplemented;
5431
    case TARGET_NR_sigaltstack:
5432
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5433
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5434
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5435
        break;
5436
#else
5437
        goto unimplemented;
5438
#endif
5439
    case TARGET_NR_sendfile:
5440
        goto unimplemented;
5441
#ifdef TARGET_NR_getpmsg
5442
    case TARGET_NR_getpmsg:
5443
        goto unimplemented;
5444
#endif
5445
#ifdef TARGET_NR_putpmsg
5446
    case TARGET_NR_putpmsg:
5447
        goto unimplemented;
5448
#endif
5449
#ifdef TARGET_NR_vfork
5450
    case TARGET_NR_vfork:
5451
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5452
                        0, 0, 0, 0));
5453
        break;
5454
#endif
5455
#ifdef TARGET_NR_ugetrlimit
5456
    case TARGET_NR_ugetrlimit:
5457
    {
5458
        struct rlimit rlim;
5459
        ret = get_errno(getrlimit(arg1, &rlim));
5460
        if (!is_error(ret)) {
5461
            struct target_rlimit *target_rlim;
5462
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5463
                goto efault;
5464
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5465
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
5466
            unlock_user_struct(target_rlim, arg2, 1);
5467
        }
5468
        break;
5469
    }
5470
#endif
5471
#ifdef TARGET_NR_truncate64
5472
    case TARGET_NR_truncate64:
5473
        if (!(p = lock_user_string(arg1)))
5474
            goto efault;
5475
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5476
        unlock_user(p, arg1, 0);
5477
        break;
5478
#endif
5479
#ifdef TARGET_NR_ftruncate64
5480
    case TARGET_NR_ftruncate64:
5481
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5482
        break;
5483
#endif
5484
#ifdef TARGET_NR_stat64
5485
    case TARGET_NR_stat64:
5486
        if (!(p = lock_user_string(arg1)))
5487
            goto efault;
5488
        ret = get_errno(stat(path(p), &st));
5489
        unlock_user(p, arg1, 0);
5490
        if (!is_error(ret))
5491
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5492
        break;
5493
#endif
5494
#ifdef TARGET_NR_lstat64
5495
    case TARGET_NR_lstat64:
5496
        if (!(p = lock_user_string(arg1)))
5497
            goto efault;
5498
        ret = get_errno(lstat(path(p), &st));
5499
        unlock_user(p, arg1, 0);
5500
        if (!is_error(ret))
5501
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5502
        break;
5503
#endif
5504
#ifdef TARGET_NR_fstat64
5505
    case TARGET_NR_fstat64:
5506
        ret = get_errno(fstat(arg1, &st));
5507
        if (!is_error(ret))
5508
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5509
        break;
5510
#endif
5511
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
5512
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
5513
#ifdef TARGET_NR_fstatat64
5514
    case TARGET_NR_fstatat64:
5515
#endif
5516
#ifdef TARGET_NR_newfstatat
5517
    case TARGET_NR_newfstatat:
5518
#endif
5519
        if (!(p = lock_user_string(arg2)))
5520
            goto efault;
5521
#ifdef __NR_fstatat64
5522
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5523
#else
5524
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
5525
#endif
5526
        if (!is_error(ret))
5527
            ret = host_to_target_stat64(cpu_env, arg3, &st);
5528
        break;
5529
#endif
5530
#ifdef USE_UID16
5531
    case TARGET_NR_lchown:
5532
        if (!(p = lock_user_string(arg1)))
5533
            goto efault;
5534
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5535
        unlock_user(p, arg1, 0);
5536
        break;
5537
    case TARGET_NR_getuid:
5538
        ret = get_errno(high2lowuid(getuid()));
5539
        break;
5540
    case TARGET_NR_getgid:
5541
        ret = get_errno(high2lowgid(getgid()));
5542
        break;
5543
    case TARGET_NR_geteuid:
5544
        ret = get_errno(high2lowuid(geteuid()));
5545
        break;
5546
    case TARGET_NR_getegid:
5547
        ret = get_errno(high2lowgid(getegid()));
5548
        break;
5549
    case TARGET_NR_setreuid:
5550
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5551
        break;
5552
    case TARGET_NR_setregid:
5553
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5554
        break;
5555
    case TARGET_NR_getgroups:
5556
        {
5557
            int gidsetsize = arg1;
5558
            uint16_t *target_grouplist;
5559
            gid_t *grouplist;
5560
            int i;
5561

    
5562
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5563
            ret = get_errno(getgroups(gidsetsize, grouplist));
5564
            if (gidsetsize == 0)
5565
                break;
5566
            if (!is_error(ret)) {
5567
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5568
                if (!target_grouplist)
5569
                    goto efault;
5570
                for(i = 0;i < ret; i++)
5571
                    target_grouplist[i] = tswap16(grouplist[i]);
5572
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5573
            }
5574
        }
5575
        break;
5576
    case TARGET_NR_setgroups:
5577
        {
5578
            int gidsetsize = arg1;
5579
            uint16_t *target_grouplist;
5580
            gid_t *grouplist;
5581
            int i;
5582

    
5583
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5584
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5585
            if (!target_grouplist) {
5586
                ret = -TARGET_EFAULT;
5587
                goto fail;
5588
            }
5589
            for(i = 0;i < gidsetsize; i++)
5590
                grouplist[i] = tswap16(target_grouplist[i]);
5591
            unlock_user(target_grouplist, arg2, 0);
5592
            ret = get_errno(setgroups(gidsetsize, grouplist));
5593
        }
5594
        break;
5595
    case TARGET_NR_fchown:
5596
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5597
        break;
5598
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5599
    case TARGET_NR_fchownat:
5600
        if (!(p = lock_user_string(arg2))) 
5601
            goto efault;
5602
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5603
        unlock_user(p, arg2, 0);
5604
        break;
5605
#endif
5606
#ifdef TARGET_NR_setresuid
5607
    case TARGET_NR_setresuid:
5608
        ret = get_errno(setresuid(low2highuid(arg1),
5609
                                  low2highuid(arg2),
5610
                                  low2highuid(arg3)));
5611
        break;
5612
#endif
5613
#ifdef TARGET_NR_getresuid
5614
    case TARGET_NR_getresuid:
5615
        {
5616
            uid_t ruid, euid, suid;
5617
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5618
            if (!is_error(ret)) {
5619
                if (put_user_u16(high2lowuid(ruid), arg1)
5620
                    || put_user_u16(high2lowuid(euid), arg2)
5621
                    || put_user_u16(high2lowuid(suid), arg3))
5622
                    goto efault;
5623
            }
5624
        }
5625
        break;
5626
#endif
5627
#ifdef TARGET_NR_getresgid
5628
    case TARGET_NR_setresgid:
5629
        ret = get_errno(setresgid(low2highgid(arg1),
5630
                                  low2highgid(arg2),
5631
                                  low2highgid(arg3)));
5632
        break;
5633
#endif
5634
#ifdef TARGET_NR_getresgid
5635
    case TARGET_NR_getresgid:
5636
        {
5637
            gid_t rgid, egid, sgid;
5638
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5639
            if (!is_error(ret)) {
5640
                if (put_user_u16(high2lowgid(rgid), arg1)
5641
                    || put_user_u16(high2lowgid(egid), arg2)
5642
                    || put_user_u16(high2lowgid(sgid), arg3))
5643
                    goto efault;
5644
            }
5645
        }
5646
        break;
5647
#endif
5648
    case TARGET_NR_chown:
5649
        if (!(p = lock_user_string(arg1)))
5650
            goto efault;
5651
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5652
        unlock_user(p, arg1, 0);
5653
        break;
5654
    case TARGET_NR_setuid:
5655
        ret = get_errno(setuid(low2highuid(arg1)));
5656
        break;
5657
    case TARGET_NR_setgid:
5658
        ret = get_errno(setgid(low2highgid(arg1)));
5659
        break;
5660
    case TARGET_NR_setfsuid:
5661
        ret = get_errno(setfsuid(arg1));
5662
        break;
5663
    case TARGET_NR_setfsgid:
5664
        ret = get_errno(setfsgid(arg1));
5665
        break;
5666
#endif /* USE_UID16 */
5667

    
5668
#ifdef TARGET_NR_lchown32
5669
    case TARGET_NR_lchown32:
5670
        if (!(p = lock_user_string(arg1)))
5671
            goto efault;
5672
        ret = get_errno(lchown(p, arg2, arg3));
5673
        unlock_user(p, arg1, 0);
5674
        break;
5675
#endif
5676
#ifdef TARGET_NR_getuid32
5677
    case TARGET_NR_getuid32:
5678
        ret = get_errno(getuid());
5679
        break;
5680
#endif
5681

    
5682
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
5683
   /* Alpha specific */
5684
    case TARGET_NR_getxuid:
5685
         {
5686
            uid_t euid;
5687
            euid=geteuid();
5688
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
5689
         }
5690
        ret = get_errno(getuid());
5691
        break;
5692
#endif
5693
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
5694
   /* Alpha specific */
5695
    case TARGET_NR_getxgid:
5696
         {
5697
            uid_t egid;
5698
            egid=getegid();
5699
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
5700
         }
5701
        ret = get_errno(getgid());
5702
        break;
5703
#endif
5704

    
5705
#ifdef TARGET_NR_getgid32
5706
    case TARGET_NR_getgid32:
5707
        ret = get_errno(getgid());
5708
        break;
5709
#endif
5710
#ifdef TARGET_NR_geteuid32
5711
    case TARGET_NR_geteuid32:
5712
        ret = get_errno(geteuid());
5713
        break;
5714
#endif
5715
#ifdef TARGET_NR_getegid32
5716
    case TARGET_NR_getegid32:
5717
        ret = get_errno(getegid());
5718
        break;
5719
#endif
5720
#ifdef TARGET_NR_setreuid32
5721
    case TARGET_NR_setreuid32:
5722
        ret = get_errno(setreuid(arg1, arg2));
5723
        break;
5724
#endif
5725
#ifdef TARGET_NR_setregid32
5726
    case TARGET_NR_setregid32:
5727
        ret = get_errno(setregid(arg1, arg2));
5728
        break;
5729
#endif
5730
#ifdef TARGET_NR_getgroups32
5731
    case TARGET_NR_getgroups32:
5732
        {
5733
            int gidsetsize = arg1;
5734
            uint32_t *target_grouplist;
5735
            gid_t *grouplist;
5736
            int i;
5737

    
5738
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5739
            ret = get_errno(getgroups(gidsetsize, grouplist));
5740
            if (gidsetsize == 0)
5741
                break;
5742
            if (!is_error(ret)) {
5743
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5744
                if (!target_grouplist) {
5745
                    ret = -TARGET_EFAULT;
5746
                    goto fail;
5747
                }
5748
                for(i = 0;i < ret; i++)
5749
                    target_grouplist[i] = tswap32(grouplist[i]);
5750
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
5751
            }
5752
        }
5753
        break;
5754
#endif
5755
#ifdef TARGET_NR_setgroups32
5756
    case TARGET_NR_setgroups32:
5757
        {
5758
            int gidsetsize = arg1;
5759
            uint32_t *target_grouplist;
5760
            gid_t *grouplist;
5761
            int i;
5762

    
5763
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5764
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5765
            if (!target_grouplist) {
5766
                ret = -TARGET_EFAULT;
5767
                goto fail;
5768
            }
5769
            for(i = 0;i < gidsetsize; i++)
5770
                grouplist[i] = tswap32(target_grouplist[i]);
5771
            unlock_user(target_grouplist, arg2, 0);
5772
            ret = get_errno(setgroups(gidsetsize, grouplist));
5773
        }
5774
        break;
5775
#endif
5776
#ifdef TARGET_NR_fchown32
5777
    case TARGET_NR_fchown32:
5778
        ret = get_errno(fchown(arg1, arg2, arg3));
5779
        break;
5780
#endif
5781
#ifdef TARGET_NR_setresuid32
5782
    case TARGET_NR_setresuid32:
5783
        ret = get_errno(setresuid(arg1, arg2, arg3));
5784
        break;
5785
#endif
5786
#ifdef TARGET_NR_getresuid32
5787
    case TARGET_NR_getresuid32:
5788
        {
5789
            uid_t ruid, euid, suid;
5790
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5791
            if (!is_error(ret)) {
5792
                if (put_user_u32(ruid, arg1)
5793
                    || put_user_u32(euid, arg2)
5794
                    || put_user_u32(suid, arg3))
5795
                    goto efault;
5796
            }
5797
        }
5798
        break;
5799
#endif
5800
#ifdef TARGET_NR_setresgid32
5801
    case TARGET_NR_setresgid32:
5802
        ret = get_errno(setresgid(arg1, arg2, arg3));
5803
        break;
5804
#endif
5805
#ifdef TARGET_NR_getresgid32
5806
    case TARGET_NR_getresgid32:
5807
        {
5808
            gid_t rgid, egid, sgid;
5809
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5810
            if (!is_error(ret)) {
5811
                if (put_user_u32(rgid, arg1)
5812
                    || put_user_u32(egid, arg2)
5813
                    || put_user_u32(sgid, arg3))
5814
                    goto efault;
5815
            }
5816
        }
5817
        break;
5818
#endif
5819
#ifdef TARGET_NR_chown32
5820
    case TARGET_NR_chown32:
5821
        if (!(p = lock_user_string(arg1)))
5822
            goto efault;
5823
        ret = get_errno(chown(p, arg2, arg3));
5824
        unlock_user(p, arg1, 0);
5825
        break;
5826
#endif
5827
#ifdef TARGET_NR_setuid32
5828
    case TARGET_NR_setuid32:
5829
        ret = get_errno(setuid(arg1));
5830
        break;
5831
#endif
5832
#ifdef TARGET_NR_setgid32
5833
    case TARGET_NR_setgid32:
5834
        ret = get_errno(setgid(arg1));
5835
        break;
5836
#endif
5837
#ifdef TARGET_NR_setfsuid32
5838
    case TARGET_NR_setfsuid32:
5839
        ret = get_errno(setfsuid(arg1));
5840
        break;
5841
#endif
5842
#ifdef TARGET_NR_setfsgid32
5843
    case TARGET_NR_setfsgid32:
5844
        ret = get_errno(setfsgid(arg1));
5845
        break;
5846
#endif
5847

    
5848
    case TARGET_NR_pivot_root:
5849
        goto unimplemented;
5850
#ifdef TARGET_NR_mincore
5851
    case TARGET_NR_mincore:
5852
        {
5853
            void *a;
5854
            ret = -TARGET_EFAULT;
5855
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5856
                goto efault;
5857
            if (!(p = lock_user_string(arg3)))
5858
                goto mincore_fail;
5859
            ret = get_errno(mincore(a, arg2, p));
5860
            unlock_user(p, arg3, ret);
5861
            mincore_fail:
5862
            unlock_user(a, arg1, 0);
5863
        }
5864
        break;
5865
#endif
5866
#ifdef TARGET_NR_arm_fadvise64_64
5867
    case TARGET_NR_arm_fadvise64_64:
5868
        {
5869
                /*
5870
                 * arm_fadvise64_64 looks like fadvise64_64 but
5871
                 * with different argument order
5872
                 */
5873
                abi_long temp;
5874
                temp = arg3;
5875
                arg3 = arg4;
5876
                arg4 = temp;
5877
        }
5878
#endif
5879
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5880
#ifdef TARGET_NR_fadvise64_64
5881
    case TARGET_NR_fadvise64_64:
5882
#endif
5883
        /* This is a hint, so ignoring and returning success is ok.  */
5884
        ret = get_errno(0);
5885
        break;
5886
#endif
5887
#ifdef TARGET_NR_madvise
5888
    case TARGET_NR_madvise:
5889
        /* A straight passthrough may not be safe because qemu sometimes
5890
           turns private flie-backed mappings into anonymous mappings.
5891
           This will break MADV_DONTNEED.
5892
           This is a hint, so ignoring and returning success is ok.  */
5893
        ret = get_errno(0);
5894
        break;
5895
#endif
5896
#if TARGET_ABI_BITS == 32
5897
    case TARGET_NR_fcntl64:
5898
    {
5899
        int cmd;
5900
        struct flock64 fl;
5901
        struct target_flock64 *target_fl;
5902
#ifdef TARGET_ARM
5903
        struct target_eabi_flock64 *target_efl;
5904
#endif
5905

    
5906
        switch(arg2){
5907
        case TARGET_F_GETLK64:
5908
            cmd = F_GETLK64;
5909
            break;
5910
        case TARGET_F_SETLK64:
5911
            cmd = F_SETLK64;
5912
            break;
5913
        case TARGET_F_SETLKW64:
5914
            cmd = F_SETLK64;
5915
            break;
5916
        default:
5917
            cmd = arg2;
5918
            break;
5919
        }
5920

    
5921
        switch(arg2) {
5922
        case TARGET_F_GETLK64:
5923
#ifdef TARGET_ARM
5924
            if (((CPUARMState *)cpu_env)->eabi) {
5925
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5926
                    goto efault;
5927
                fl.l_type = tswap16(target_efl->l_type);
5928
                fl.l_whence = tswap16(target_efl->l_whence);
5929
                fl.l_start = tswap64(target_efl->l_start);
5930
                fl.l_len = tswap64(target_efl->l_len);
5931
                fl.l_pid = tswapl(target_efl->l_pid);
5932
                unlock_user_struct(target_efl, arg3, 0);
5933
            } else
5934
#endif
5935
            {
5936
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5937
                    goto efault;
5938
                fl.l_type = tswap16(target_fl->l_type);
5939
                fl.l_whence = tswap16(target_fl->l_whence);
5940
                fl.l_start = tswap64(target_fl->l_start);
5941
                fl.l_len = tswap64(target_fl->l_len);
5942
                fl.l_pid = tswapl(target_fl->l_pid);
5943
                unlock_user_struct(target_fl, arg3, 0);
5944
            }
5945
            ret = get_errno(fcntl(arg1, cmd, &fl));
5946
            if (ret == 0) {
5947
#ifdef TARGET_ARM
5948
                if (((CPUARMState *)cpu_env)->eabi) {
5949
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
5950
                        goto efault;
5951
                    target_efl->l_type = tswap16(fl.l_type);
5952
                    target_efl->l_whence = tswap16(fl.l_whence);
5953
                    target_efl->l_start = tswap64(fl.l_start);
5954
                    target_efl->l_len = tswap64(fl.l_len);
5955
                    target_efl->l_pid = tswapl(fl.l_pid);
5956
                    unlock_user_struct(target_efl, arg3, 1);
5957
                } else
5958
#endif
5959
                {
5960
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
5961
                        goto efault;
5962
                    target_fl->l_type = tswap16(fl.l_type);
5963
                    target_fl->l_whence = tswap16(fl.l_whence);
5964
                    target_fl->l_start = tswap64(fl.l_start);
5965
                    target_fl->l_len = tswap64(fl.l_len);
5966
                    target_fl->l_pid = tswapl(fl.l_pid);
5967
                    unlock_user_struct(target_fl, arg3, 1);
5968
                }
5969
            }
5970
            break;
5971

    
5972
        case TARGET_F_SETLK64:
5973
        case TARGET_F_SETLKW64:
5974
#ifdef TARGET_ARM
5975
            if (((CPUARMState *)cpu_env)->eabi) {
5976
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5977
                    goto efault;
5978
                fl.l_type = tswap16(target_efl->l_type);
5979
                fl.l_whence = tswap16(target_efl->l_whence);
5980
                fl.l_start = tswap64(target_efl->l_start);
5981
                fl.l_len = tswap64(target_efl->l_len);
5982
                fl.l_pid = tswapl(target_efl->l_pid);
5983
                unlock_user_struct(target_efl, arg3, 0);
5984
            } else
5985
#endif
5986
            {
5987
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5988
                    goto efault;
5989
                fl.l_type = tswap16(target_fl->l_type);
5990
                fl.l_whence = tswap16(target_fl->l_whence);
5991
                fl.l_start = tswap64(target_fl->l_start);
5992
                fl.l_len = tswap64(target_fl->l_len);
5993
                fl.l_pid = tswapl(target_fl->l_pid);
5994
                unlock_user_struct(target_fl, arg3, 0);
5995
            }
5996
            ret = get_errno(fcntl(arg1, cmd, &fl));
5997
            break;
5998
        default:
5999
            ret = do_fcntl(arg1, cmd, arg3);
6000
            break;
6001
        }
6002
        break;
6003
    }
6004
#endif
6005
#ifdef TARGET_NR_cacheflush
6006
    case TARGET_NR_cacheflush:
6007
        /* self-modifying code is handled automatically, so nothing needed */
6008
        ret = 0;
6009
        break;
6010
#endif
6011
#ifdef TARGET_NR_security
6012
    case TARGET_NR_security:
6013
        goto unimplemented;
6014
#endif
6015
#ifdef TARGET_NR_getpagesize
6016
    case TARGET_NR_getpagesize:
6017
        ret = TARGET_PAGE_SIZE;
6018
        break;
6019
#endif
6020
    case TARGET_NR_gettid:
6021
        ret = get_errno(gettid());
6022
        break;
6023
#ifdef TARGET_NR_readahead
6024
    case TARGET_NR_readahead:
6025
#if TARGET_ABI_BITS == 32
6026
#ifdef TARGET_ARM
6027
        if (((CPUARMState *)cpu_env)->eabi)
6028
        {
6029
            arg2 = arg3;
6030
            arg3 = arg4;
6031
            arg4 = arg5;
6032
        }
6033
#endif
6034
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6035
#else
6036
        ret = get_errno(readahead(arg1, arg2, arg3));
6037
#endif
6038
        break;
6039
#endif
6040
#ifdef TARGET_NR_setxattr
6041
    case TARGET_NR_setxattr:
6042
    case TARGET_NR_lsetxattr:
6043
    case TARGET_NR_fsetxattr:
6044
    case TARGET_NR_getxattr:
6045
    case TARGET_NR_lgetxattr:
6046
    case TARGET_NR_fgetxattr:
6047
    case TARGET_NR_listxattr:
6048
    case TARGET_NR_llistxattr:
6049
    case TARGET_NR_flistxattr:
6050
    case TARGET_NR_removexattr:
6051
    case TARGET_NR_lremovexattr:
6052
    case TARGET_NR_fremovexattr:
6053
        goto unimplemented_nowarn;
6054
#endif
6055
#ifdef TARGET_NR_set_thread_area
6056
    case TARGET_NR_set_thread_area:
6057
#if defined(TARGET_MIPS)
6058
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6059
      ret = 0;
6060
      break;
6061
#elif defined(TARGET_CRIS)
6062
      if (arg1 & 0xff)
6063
          ret = -TARGET_EINVAL;
6064
      else {
6065
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6066
          ret = 0;
6067
      }
6068
      break;
6069
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
6070
      ret = do_set_thread_area(cpu_env, arg1);
6071
      break;
6072
#else
6073
      goto unimplemented_nowarn;
6074
#endif
6075
#endif
6076
#ifdef TARGET_NR_get_thread_area
6077
    case TARGET_NR_get_thread_area:
6078
#if defined(TARGET_I386) && defined(TARGET_ABI32)
6079
        ret = do_get_thread_area(cpu_env, arg1);
6080
#else
6081
        goto unimplemented_nowarn;
6082
#endif
6083
#endif
6084
#ifdef TARGET_NR_getdomainname
6085
    case TARGET_NR_getdomainname:
6086
        goto unimplemented_nowarn;
6087
#endif
6088

    
6089
#ifdef TARGET_NR_clock_gettime
6090
    case TARGET_NR_clock_gettime:
6091
    {
6092
        struct timespec ts;
6093
        ret = get_errno(clock_gettime(arg1, &ts));
6094
        if (!is_error(ret)) {
6095
            host_to_target_timespec(arg2, &ts);
6096
        }
6097
        break;
6098
    }
6099
#endif
6100
#ifdef TARGET_NR_clock_getres
6101
    case TARGET_NR_clock_getres:
6102
    {
6103
        struct timespec ts;
6104
        ret = get_errno(clock_getres(arg1, &ts));
6105
        if (!is_error(ret)) {
6106
            host_to_target_timespec(arg2, &ts);
6107
        }
6108
        break;
6109
    }
6110
#endif
6111
#ifdef TARGET_NR_clock_nanosleep
6112
    case TARGET_NR_clock_nanosleep:
6113
    {
6114
        struct timespec ts;
6115
        target_to_host_timespec(&ts, arg3);
6116
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6117
        if (arg4)
6118
            host_to_target_timespec(arg4, &ts);
6119
        break;
6120
    }
6121
#endif
6122

    
6123
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6124
    case TARGET_NR_set_tid_address:
6125
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
6126
        break;
6127
#endif
6128

    
6129
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6130
    case TARGET_NR_tkill:
6131
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6132
        break;
6133
#endif
6134

    
6135
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6136
    case TARGET_NR_tgkill:
6137
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6138
                        target_to_host_signal(arg3)));
6139
        break;
6140
#endif
6141

    
6142
#ifdef TARGET_NR_set_robust_list
6143
    case TARGET_NR_set_robust_list:
6144
        goto unimplemented_nowarn;
6145
#endif
6146

    
6147
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6148
    case TARGET_NR_utimensat:
6149
        {
6150
            struct timespec ts[2];
6151
            target_to_host_timespec(ts, arg3);
6152
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6153
            if (!arg2)
6154
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
6155
            else {
6156
                if (!(p = lock_user_string(arg2))) {
6157
                    ret = -TARGET_EFAULT;
6158
                    goto fail;
6159
                }
6160
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
6161
                unlock_user(p, arg2, 0);
6162
            }
6163
        }
6164
        break;
6165
#endif
6166
#if defined(USE_NPTL)
6167
    case TARGET_NR_futex:
6168
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6169
        break;
6170
#endif
6171
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6172
    case TARGET_NR_inotify_init:
6173
        ret = get_errno(sys_inotify_init());
6174
        break;
6175
#endif
6176
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6177
    case TARGET_NR_inotify_add_watch:
6178
        p = lock_user_string(arg2);
6179
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6180
        unlock_user(p, arg2, 0);
6181
        break;
6182
#endif
6183
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6184
    case TARGET_NR_inotify_rm_watch:
6185
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6186
        break;
6187
#endif
6188

    
6189
#ifdef TARGET_NR_mq_open
6190
    case TARGET_NR_mq_open:
6191
        {
6192
            struct mq_attr posix_mq_attr;
6193

    
6194
            p = lock_user_string(arg1 - 1);
6195
            if (arg4 != 0)
6196
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
6197
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6198
            unlock_user (p, arg1, 0);
6199
        }
6200
        break;
6201

    
6202
    case TARGET_NR_mq_unlink:
6203
        p = lock_user_string(arg1 - 1);
6204
        ret = get_errno(mq_unlink(p));
6205
        unlock_user (p, arg1, 0);
6206
        break;
6207

    
6208
    case TARGET_NR_mq_timedsend:
6209
        {
6210
            struct timespec ts;
6211

    
6212
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6213
            if (arg5 != 0) {
6214
                target_to_host_timespec(&ts, arg5);
6215
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
6216
                host_to_target_timespec(arg5, &ts);
6217
            }
6218
            else
6219
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
6220
            unlock_user (p, arg2, arg3);
6221
        }
6222
        break;
6223

    
6224
    case TARGET_NR_mq_timedreceive:
6225
        {
6226
            struct timespec ts;
6227
            unsigned int prio;
6228

    
6229
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6230
            if (arg5 != 0) {
6231
                target_to_host_timespec(&ts, arg5);
6232
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6233
                host_to_target_timespec(arg5, &ts);
6234
            }
6235
            else
6236
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6237
            unlock_user (p, arg2, arg3);
6238
            if (arg4 != 0)
6239
                put_user_u32(prio, arg4);
6240
        }
6241
        break;
6242

    
6243
    /* Not implemented for now... */
6244
/*     case TARGET_NR_mq_notify: */
6245
/*         break; */
6246

    
6247
    case TARGET_NR_mq_getsetattr:
6248
        {
6249
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6250
            ret = 0;
6251
            if (arg3 != 0) {
6252
                ret = mq_getattr(arg1, &posix_mq_attr_out);
6253
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6254
            }
6255
            if (arg2 != 0) {
6256
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6257
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6258
            }
6259

    
6260
        }
6261
        break;
6262
#endif
6263

    
6264
    default:
6265
    unimplemented:
6266
        gemu_log("qemu: Unsupported syscall: %d\n", num);
6267
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6268
    unimplemented_nowarn:
6269
#endif
6270
        ret = -TARGET_ENOSYS;
6271
        break;
6272
    }
6273
fail:
6274
#ifdef DEBUG
6275
    gemu_log(" = %ld\n", ret);
6276
#endif
6277
    if(do_strace)
6278
        print_syscall_ret(num, ret);
6279
    return ret;
6280
efault:
6281
    ret = -TARGET_EFAULT;
6282
    goto fail;
6283
}