Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ b55266b5

History | View | Annotate | Download (182 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., 675 Mass Ave, Cambridge, MA 02139, USA.
19
 */
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <stdarg.h>
23
#include <string.h>
24
#include <elf.h>
25
#include <endian.h>
26
#include <errno.h>
27
#include <unistd.h>
28
#include <fcntl.h>
29
#include <time.h>
30
#include <limits.h>
31
#include <dirent.h>
32
#include <sys/types.h>
33
#include <sys/ipc.h>
34
#include <sys/msg.h>
35
#include <sys/wait.h>
36
#include <sys/time.h>
37
#include <sys/stat.h>
38
#include <sys/mount.h>
39
#include <sys/prctl.h>
40
#include <sys/resource.h>
41
#include <sys/mman.h>
42
#include <sys/swap.h>
43
#include <signal.h>
44
#include <sched.h>
45
#include <sys/socket.h>
46
#include <sys/uio.h>
47
#include <sys/poll.h>
48
#include <sys/times.h>
49
#include <sys/shm.h>
50
#include <sys/sem.h>
51
#include <sys/statfs.h>
52
#include <utime.h>
53
#include <sys/sysinfo.h>
54
//#include <sys/user.h>
55
#include <netinet/ip.h>
56
#include <netinet/tcp.h>
57
#include <qemu-common.h>
58

    
59
#define termios host_termios
60
#define winsize host_winsize
61
#define termio host_termio
62
#define sgttyb host_sgttyb /* same as target */
63
#define tchars host_tchars /* same as target */
64
#define ltchars host_ltchars /* same as target */
65

    
66
#include <linux/termios.h>
67
#include <linux/unistd.h>
68
#include <linux/utsname.h>
69
#include <linux/cdrom.h>
70
#include <linux/hdreg.h>
71
#include <linux/soundcard.h>
72
#include <linux/kd.h>
73
#include <linux/mtio.h>
74
#include "linux_loop.h"
75

    
76
#include "qemu.h"
77
#include "qemu-common.h"
78

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

    
88
//#define DEBUG
89

    
90
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
91
    || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
92
/* 16 bit uid wrappers emulation */
93
#define USE_UID16
94
#endif
95

    
96
//#include <linux/msdos_fs.h>
97
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct dirent [2])
98
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct dirent [2])
99

    
100

    
101
#undef _syscall0
102
#undef _syscall1
103
#undef _syscall2
104
#undef _syscall3
105
#undef _syscall4
106
#undef _syscall5
107
#undef _syscall6
108

    
109
#define _syscall0(type,name)                \
110
static type name (void)                        \
111
{                                        \
112
        return syscall(__NR_##name);        \
113
}
114

    
115
#define _syscall1(type,name,type1,arg1)                \
116
static type name (type1 arg1)                        \
117
{                                                \
118
        return syscall(__NR_##name, arg1);        \
119
}
120

    
121
#define _syscall2(type,name,type1,arg1,type2,arg2)        \
122
static type name (type1 arg1,type2 arg2)                \
123
{                                                        \
124
        return syscall(__NR_##name, arg1, arg2);        \
125
}
126

    
127
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)        \
128
static type name (type1 arg1,type2 arg2,type3 arg3)                \
129
{                                                                \
130
        return syscall(__NR_##name, arg1, arg2, arg3);                \
131
}
132

    
133
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)        \
134
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)                        \
135
{                                                                                \
136
        return syscall(__NR_##name, arg1, arg2, arg3, arg4);                        \
137
}
138

    
139
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
140
                  type5,arg5)                                                        \
141
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)        \
142
{                                                                                \
143
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);                \
144
}
145

    
146

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

    
155

    
156
#define __NR_sys_uname __NR_uname
157
#define __NR_sys_faccessat __NR_faccessat
158
#define __NR_sys_fchmodat __NR_fchmodat
159
#define __NR_sys_fchownat __NR_fchownat
160
#define __NR_sys_fstatat64 __NR_fstatat64
161
#define __NR_sys_futimesat __NR_futimesat
162
#define __NR_sys_getcwd1 __NR_getcwd
163
#define __NR_sys_getdents __NR_getdents
164
#define __NR_sys_getdents64 __NR_getdents64
165
#define __NR_sys_getpriority __NR_getpriority
166
#define __NR_sys_linkat __NR_linkat
167
#define __NR_sys_mkdirat __NR_mkdirat
168
#define __NR_sys_mknodat __NR_mknodat
169
#define __NR_sys_openat __NR_openat
170
#define __NR_sys_readlinkat __NR_readlinkat
171
#define __NR_sys_renameat __NR_renameat
172
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
173
#define __NR_sys_symlinkat __NR_symlinkat
174
#define __NR_sys_syslog __NR_syslog
175
#define __NR_sys_tgkill __NR_tgkill
176
#define __NR_sys_tkill __NR_tkill
177
#define __NR_sys_unlinkat __NR_unlinkat
178
#define __NR_sys_utimensat __NR_utimensat
179
#define __NR_sys_futex __NR_futex
180

    
181
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
182
#define __NR__llseek __NR_lseek
183
#endif
184

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

    
280
extern int personality(int);
281
extern int flock(int, int);
282
extern int setfsuid(int);
283
extern int setfsgid(int);
284
extern int setgroups(int, gid_t *);
285

    
286
#define ERRNO_TABLE_SIZE 1200
287

    
288
/* target_to_host_errno_table[] is initialized from
289
 * host_to_target_errno_table[] in syscall_init(). */
290
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
291
};
292

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

    
405
static inline int host_to_target_errno(int err)
406
{
407
    if(host_to_target_errno_table[err])
408
        return host_to_target_errno_table[err];
409
    return err;
410
}
411

    
412
static inline int target_to_host_errno(int err)
413
{
414
    if (target_to_host_errno_table[err])
415
        return target_to_host_errno_table[err];
416
    return err;
417
}
418

    
419
static inline abi_long get_errno(abi_long ret)
420
{
421
    if (ret == -1)
422
        return -host_to_target_errno(errno);
423
    else
424
        return ret;
425
}
426

    
427
static inline int is_error(abi_long ret)
428
{
429
    return (abi_ulong)ret >= (abi_ulong)(-4096);
430
}
431

    
432
char *target_strerror(int err)
433
{
434
    return strerror(target_to_host_errno(err));
435
}
436

    
437
static abi_ulong target_brk;
438
static abi_ulong target_original_brk;
439

    
440
void target_set_brk(abi_ulong new_brk)
441
{
442
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
443
}
444

    
445
/* do_brk() must return target values and target errnos. */
446
abi_long do_brk(abi_ulong new_brk)
447
{
448
    abi_ulong brk_page;
449
    abi_long mapped_addr;
450
    int        new_alloc_size;
451

    
452
    if (!new_brk)
453
        return target_brk;
454
    if (new_brk < target_original_brk)
455
        return target_brk;
456

    
457
    brk_page = HOST_PAGE_ALIGN(target_brk);
458

    
459
    /* If the new brk is less than this, set it and we're done... */
460
    if (new_brk < brk_page) {
461
        target_brk = new_brk;
462
            return target_brk;
463
    }
464

    
465
    /* We need to allocate more memory after the brk... */
466
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
467
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
468
                                        PROT_READ|PROT_WRITE,
469
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
470

    
471
    if (!is_error(mapped_addr))
472
        target_brk = new_brk;
473
    
474
    return target_brk;
475
}
476

    
477
static inline abi_long copy_from_user_fdset(fd_set *fds,
478
                                            abi_ulong target_fds_addr,
479
                                            int n)
480
{
481
    int i, nw, j, k;
482
    abi_ulong b, *target_fds;
483

    
484
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
485
    if (!(target_fds = lock_user(VERIFY_READ,
486
                                 target_fds_addr,
487
                                 sizeof(abi_ulong) * nw,
488
                                 1)))
489
        return -TARGET_EFAULT;
490

    
491
    FD_ZERO(fds);
492
    k = 0;
493
    for (i = 0; i < nw; i++) {
494
        /* grab the abi_ulong */
495
        __get_user(b, &target_fds[i]);
496
        for (j = 0; j < TARGET_ABI_BITS; j++) {
497
            /* check the bit inside the abi_ulong */
498
            if ((b >> j) & 1)
499
                FD_SET(k, fds);
500
            k++;
501
        }
502
    }
503

    
504
    unlock_user(target_fds, target_fds_addr, 0);
505

    
506
    return 0;
507
}
508

    
509
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
510
                                          const fd_set *fds,
511
                                          int n)
512
{
513
    int i, nw, j, k;
514
    abi_long v;
515
    abi_ulong *target_fds;
516

    
517
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
518
    if (!(target_fds = lock_user(VERIFY_WRITE,
519
                                 target_fds_addr,
520
                                 sizeof(abi_ulong) * nw,
521
                                 0)))
522
        return -TARGET_EFAULT;
523

    
524
    k = 0;
525
    for (i = 0; i < nw; i++) {
526
        v = 0;
527
        for (j = 0; j < TARGET_ABI_BITS; j++) {
528
            v |= ((FD_ISSET(k, fds) != 0) << j);
529
            k++;
530
        }
531
        __put_user(v, &target_fds[i]);
532
    }
533

    
534
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
535

    
536
    return 0;
537
}
538

    
539
#if defined(__alpha__)
540
#define HOST_HZ 1024
541
#else
542
#define HOST_HZ 100
543
#endif
544

    
545
static inline abi_long host_to_target_clock_t(long ticks)
546
{
547
#if HOST_HZ == TARGET_HZ
548
    return ticks;
549
#else
550
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
551
#endif
552
}
553

    
554
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
555
                                             const struct rusage *rusage)
556
{
557
    struct target_rusage *target_rusage;
558

    
559
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
560
        return -TARGET_EFAULT;
561
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
562
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
563
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
564
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
565
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
566
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
567
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
568
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
569
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
570
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
571
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
572
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
573
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
574
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
575
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
576
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
577
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
578
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
579
    unlock_user_struct(target_rusage, target_addr, 1);
580

    
581
    return 0;
582
}
583

    
584
static inline abi_long copy_from_user_timeval(struct timeval *tv,
585
                                              abi_ulong target_tv_addr)
586
{
587
    struct target_timeval *target_tv;
588

    
589
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
590
        return -TARGET_EFAULT;
591

    
592
    __get_user(tv->tv_sec, &target_tv->tv_sec);
593
    __get_user(tv->tv_usec, &target_tv->tv_usec);
594

    
595
    unlock_user_struct(target_tv, target_tv_addr, 0);
596

    
597
    return 0;
598
}
599

    
600
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
601
                                            const struct timeval *tv)
602
{
603
    struct target_timeval *target_tv;
604

    
605
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
606
        return -TARGET_EFAULT;
607

    
608
    __put_user(tv->tv_sec, &target_tv->tv_sec);
609
    __put_user(tv->tv_usec, &target_tv->tv_usec);
610

    
611
    unlock_user_struct(target_tv, target_tv_addr, 1);
612

    
613
    return 0;
614
}
615

    
616

    
617
/* do_select() must return target values and target errnos. */
618
static abi_long do_select(int n,
619
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
620
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
621
{
622
    fd_set rfds, wfds, efds;
623
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
624
    struct timeval tv, *tv_ptr;
625
    abi_long ret;
626

    
627
    if (rfd_addr) {
628
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
629
            return -TARGET_EFAULT;
630
        rfds_ptr = &rfds;
631
    } else {
632
        rfds_ptr = NULL;
633
    }
634
    if (wfd_addr) {
635
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
636
            return -TARGET_EFAULT;
637
        wfds_ptr = &wfds;
638
    } else {
639
        wfds_ptr = NULL;
640
    }
641
    if (efd_addr) {
642
        if (copy_from_user_fdset(&efds, efd_addr, n))
643
            return -TARGET_EFAULT;
644
        efds_ptr = &efds;
645
    } else {
646
        efds_ptr = NULL;
647
    }
648

    
649
    if (target_tv_addr) {
650
        if (copy_from_user_timeval(&tv, target_tv_addr))
651
            return -TARGET_EFAULT;
652
        tv_ptr = &tv;
653
    } else {
654
        tv_ptr = NULL;
655
    }
656

    
657
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
658

    
659
    if (!is_error(ret)) {
660
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
661
            return -TARGET_EFAULT;
662
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
663
            return -TARGET_EFAULT;
664
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
665
            return -TARGET_EFAULT;
666

    
667
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
668
            return -TARGET_EFAULT;
669
    }
670

    
671
    return ret;
672
}
673

    
674
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
675
                                               abi_ulong target_addr,
676
                                               socklen_t len)
677
{
678
    struct target_sockaddr *target_saddr;
679

    
680
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
681
    if (!target_saddr)
682
        return -TARGET_EFAULT;
683
    memcpy(addr, target_saddr, len);
684
    addr->sa_family = tswap16(target_saddr->sa_family);
685
    unlock_user(target_saddr, target_addr, 0);
686

    
687
    return 0;
688
}
689

    
690
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
691
                                               struct sockaddr *addr,
692
                                               socklen_t len)
693
{
694
    struct target_sockaddr *target_saddr;
695

    
696
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
697
    if (!target_saddr)
698
        return -TARGET_EFAULT;
699
    memcpy(target_saddr, addr, len);
700
    target_saddr->sa_family = tswap16(addr->sa_family);
701
    unlock_user(target_saddr, target_addr, len);
702

    
703
    return 0;
704
}
705

    
706
/* ??? Should this also swap msgh->name?  */
707
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
708
                                           struct target_msghdr *target_msgh)
709
{
710
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
711
    abi_long msg_controllen;
712
    abi_ulong target_cmsg_addr;
713
    struct target_cmsghdr *target_cmsg;
714
    socklen_t space = 0;
715
    
716
    msg_controllen = tswapl(target_msgh->msg_controllen);
717
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
718
        goto the_end;
719
    target_cmsg_addr = tswapl(target_msgh->msg_control);
720
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
721
    if (!target_cmsg)
722
        return -TARGET_EFAULT;
723

    
724
    while (cmsg && target_cmsg) {
725
        void *data = CMSG_DATA(cmsg);
726
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
727

    
728
        int len = tswapl(target_cmsg->cmsg_len)
729
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
730

    
731
        space += CMSG_SPACE(len);
732
        if (space > msgh->msg_controllen) {
733
            space -= CMSG_SPACE(len);
734
            gemu_log("Host cmsg overflow\n");
735
            break;
736
        }
737

    
738
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
739
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
740
        cmsg->cmsg_len = CMSG_LEN(len);
741

    
742
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
743
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
744
            memcpy(data, target_data, len);
745
        } else {
746
            int *fd = (int *)data;
747
            int *target_fd = (int *)target_data;
748
            int i, numfds = len / sizeof(int);
749

    
750
            for (i = 0; i < numfds; i++)
751
                fd[i] = tswap32(target_fd[i]);
752
        }
753

    
754
        cmsg = CMSG_NXTHDR(msgh, cmsg);
755
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
756
    }
757
    unlock_user(target_cmsg, target_cmsg_addr, 0);
758
 the_end:
759
    msgh->msg_controllen = space;
760
    return 0;
761
}
762

    
763
/* ??? Should this also swap msgh->name?  */
764
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
765
                                           struct msghdr *msgh)
766
{
767
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
768
    abi_long msg_controllen;
769
    abi_ulong target_cmsg_addr;
770
    struct target_cmsghdr *target_cmsg;
771
    socklen_t space = 0;
772

    
773
    msg_controllen = tswapl(target_msgh->msg_controllen);
774
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
775
        goto the_end;
776
    target_cmsg_addr = tswapl(target_msgh->msg_control);
777
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
778
    if (!target_cmsg)
779
        return -TARGET_EFAULT;
780

    
781
    while (cmsg && target_cmsg) {
782
        void *data = CMSG_DATA(cmsg);
783
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
784

    
785
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
786

    
787
        space += TARGET_CMSG_SPACE(len);
788
        if (space > msg_controllen) {
789
            space -= TARGET_CMSG_SPACE(len);
790
            gemu_log("Target cmsg overflow\n");
791
            break;
792
        }
793

    
794
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
795
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
796
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
797

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

    
806
            for (i = 0; i < numfds; i++)
807
                target_fd[i] = tswap32(fd[i]);
808
        }
809

    
810
        cmsg = CMSG_NXTHDR(msgh, cmsg);
811
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
812
    }
813
    unlock_user(target_cmsg, target_cmsg_addr, space);
814
 the_end:
815
    target_msgh->msg_controllen = tswapl(space);
816
    return 0;
817
}
818

    
819
/* do_setsockopt() Must return target values and target errnos. */
820
static abi_long do_setsockopt(int sockfd, int level, int optname,
821
                              abi_ulong optval_addr, socklen_t optlen)
822
{
823
    abi_long ret;
824
    int val;
825

    
826
    switch(level) {
827
    case SOL_TCP:
828
        /* TCP options all take an 'int' value.  */
829
        if (optlen < sizeof(uint32_t))
830
            return -TARGET_EINVAL;
831

    
832
        if (get_user_u32(val, optval_addr))
833
            return -TARGET_EFAULT;
834
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
835
        break;
836
    case SOL_IP:
837
        switch(optname) {
838
        case IP_TOS:
839
        case IP_TTL:
840
        case IP_HDRINCL:
841
        case IP_ROUTER_ALERT:
842
        case IP_RECVOPTS:
843
        case IP_RETOPTS:
844
        case IP_PKTINFO:
845
        case IP_MTU_DISCOVER:
846
        case IP_RECVERR:
847
        case IP_RECVTOS:
848
#ifdef IP_FREEBIND
849
        case IP_FREEBIND:
850
#endif
851
        case IP_MULTICAST_TTL:
852
        case IP_MULTICAST_LOOP:
853
            val = 0;
854
            if (optlen >= sizeof(uint32_t)) {
855
                if (get_user_u32(val, optval_addr))
856
                    return -TARGET_EFAULT;
857
            } else if (optlen >= 1) {
858
                if (get_user_u8(val, optval_addr))
859
                    return -TARGET_EFAULT;
860
            }
861
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
862
            break;
863
        default:
864
            goto unimplemented;
865
        }
866
        break;
867
    case TARGET_SOL_SOCKET:
868
        switch (optname) {
869
            /* Options with 'int' argument.  */
870
        case TARGET_SO_DEBUG:
871
                optname = SO_DEBUG;
872
                break;
873
        case TARGET_SO_REUSEADDR:
874
                optname = SO_REUSEADDR;
875
                break;
876
        case TARGET_SO_TYPE:
877
                optname = SO_TYPE;
878
                break;
879
        case TARGET_SO_ERROR:
880
                optname = SO_ERROR;
881
                break;
882
        case TARGET_SO_DONTROUTE:
883
                optname = SO_DONTROUTE;
884
                break;
885
        case TARGET_SO_BROADCAST:
886
                optname = SO_BROADCAST;
887
                break;
888
        case TARGET_SO_SNDBUF:
889
                optname = SO_SNDBUF;
890
                break;
891
        case TARGET_SO_RCVBUF:
892
                optname = SO_RCVBUF;
893
                break;
894
        case TARGET_SO_KEEPALIVE:
895
                optname = SO_KEEPALIVE;
896
                break;
897
        case TARGET_SO_OOBINLINE:
898
                optname = SO_OOBINLINE;
899
                break;
900
        case TARGET_SO_NO_CHECK:
901
                optname = SO_NO_CHECK;
902
                break;
903
        case TARGET_SO_PRIORITY:
904
                optname = SO_PRIORITY;
905
                break;
906
#ifdef SO_BSDCOMPAT
907
        case TARGET_SO_BSDCOMPAT:
908
                optname = SO_BSDCOMPAT;
909
                break;
910
#endif
911
        case TARGET_SO_PASSCRED:
912
                optname = SO_PASSCRED;
913
                break;
914
        case TARGET_SO_TIMESTAMP:
915
                optname = SO_TIMESTAMP;
916
                break;
917
        case TARGET_SO_RCVLOWAT:
918
                optname = SO_RCVLOWAT;
919
                break;
920
        case TARGET_SO_RCVTIMEO:
921
                optname = SO_RCVTIMEO;
922
                break;
923
        case TARGET_SO_SNDTIMEO:
924
                optname = SO_SNDTIMEO;
925
                break;
926
            break;
927
        default:
928
            goto unimplemented;
929
        }
930
        if (optlen < sizeof(uint32_t))
931
            return -TARGET_EINVAL;
932

    
933
        if (get_user_u32(val, optval_addr))
934
            return -TARGET_EFAULT;
935
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
936
        break;
937
    default:
938
    unimplemented:
939
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
940
        ret = -TARGET_ENOPROTOOPT;
941
    }
942
    return ret;
943
}
944

    
945
/* do_getsockopt() Must return target values and target errnos. */
946
static abi_long do_getsockopt(int sockfd, int level, int optname,
947
                              abi_ulong optval_addr, abi_ulong optlen)
948
{
949
    abi_long ret;
950
    int len, val;
951
    socklen_t lv;
952

    
953
    switch(level) {
954
    case TARGET_SOL_SOCKET:
955
            level = SOL_SOCKET;
956
        switch (optname) {
957
        case TARGET_SO_LINGER:
958
        case TARGET_SO_RCVTIMEO:
959
        case TARGET_SO_SNDTIMEO:
960
        case TARGET_SO_PEERCRED:
961
        case TARGET_SO_PEERNAME:
962
            /* These don't just return a single integer */
963
            goto unimplemented;
964
        default:
965
            goto int_case;
966
        }
967
        break;
968
    case SOL_TCP:
969
        /* TCP options all take an 'int' value.  */
970
    int_case:
971
        if (get_user_u32(len, optlen))
972
            return -TARGET_EFAULT;
973
        if (len < 0)
974
            return -TARGET_EINVAL;
975
        lv = sizeof(int);
976
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
977
        if (ret < 0)
978
            return ret;
979
        val = tswap32(val);
980
        if (len > lv)
981
            len = lv;
982
        if (len == 4) {
983
            if (put_user_u32(val, optval_addr))
984
                return -TARGET_EFAULT;
985
        } else {
986
            if (put_user_u8(val, optval_addr))
987
                return -TARGET_EFAULT;
988
        }
989
        if (put_user_u32(len, optlen))
990
            return -TARGET_EFAULT;
991
        break;
992
    case SOL_IP:
993
        switch(optname) {
994
        case IP_TOS:
995
        case IP_TTL:
996
        case IP_HDRINCL:
997
        case IP_ROUTER_ALERT:
998
        case IP_RECVOPTS:
999
        case IP_RETOPTS:
1000
        case IP_PKTINFO:
1001
        case IP_MTU_DISCOVER:
1002
        case IP_RECVERR:
1003
        case IP_RECVTOS:
1004
#ifdef IP_FREEBIND
1005
        case IP_FREEBIND:
1006
#endif
1007
        case IP_MULTICAST_TTL:
1008
        case IP_MULTICAST_LOOP:
1009
            if (get_user_u32(len, optlen))
1010
                return -TARGET_EFAULT;
1011
            if (len < 0)
1012
                return -TARGET_EINVAL;
1013
            lv = sizeof(int);
1014
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1015
            if (ret < 0)
1016
                return ret;
1017
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1018
                len = 1;
1019
                if (put_user_u32(len, optlen)
1020
                    || put_user_u8(val, optval_addr))
1021
                    return -TARGET_EFAULT;
1022
            } else {
1023
                if (len > sizeof(int))
1024
                    len = sizeof(int);
1025
                if (put_user_u32(len, optlen)
1026
                    || put_user_u32(val, optval_addr))
1027
                    return -TARGET_EFAULT;
1028
            }
1029
            break;
1030
        default:
1031
            ret = -TARGET_ENOPROTOOPT;
1032
            break;
1033
        }
1034
        break;
1035
    default:
1036
    unimplemented:
1037
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1038
                 level, optname);
1039
        ret = -TARGET_EOPNOTSUPP;
1040
        break;
1041
    }
1042
    return ret;
1043
}
1044

    
1045
/* FIXME
1046
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1047
 * other lock functions have a return code of 0 for failure.
1048
 */
1049
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1050
                           int count, int copy)
1051
{
1052
    struct target_iovec *target_vec;
1053
    abi_ulong base;
1054
    int i, j;
1055

    
1056
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1057
    if (!target_vec)
1058
        return -TARGET_EFAULT;
1059
    for(i = 0;i < count; i++) {
1060
        base = tswapl(target_vec[i].iov_base);
1061
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1062
        if (vec[i].iov_len != 0) {
1063
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1064
            if (!vec[i].iov_base && vec[i].iov_len) 
1065
                goto fail;
1066
        } else {
1067
            /* zero length pointer is ignored */
1068
            vec[i].iov_base = NULL;
1069
        }
1070
    }
1071
    unlock_user (target_vec, target_addr, 0);
1072
    return 0;
1073
 fail:
1074
    /* failure - unwind locks */
1075
    for (j = 0; j < i; j++) {
1076
        base = tswapl(target_vec[j].iov_base);
1077
        unlock_user(vec[j].iov_base, base, 0);
1078
    }
1079
    unlock_user (target_vec, target_addr, 0);
1080
    return -TARGET_EFAULT;
1081
}
1082

    
1083
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1084
                             int count, int copy)
1085
{
1086
    struct target_iovec *target_vec;
1087
    abi_ulong base;
1088
    int i;
1089

    
1090
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1091
    if (!target_vec)
1092
        return -TARGET_EFAULT;
1093
    for(i = 0;i < count; i++) {
1094
        base = tswapl(target_vec[i].iov_base);
1095
        unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1096
    }
1097
    unlock_user (target_vec, target_addr, 0);
1098

    
1099
    return 0;
1100
}
1101

    
1102
/* do_socket() Must return target values and target errnos. */
1103
static abi_long do_socket(int domain, int type, int protocol)
1104
{
1105
#if defined(TARGET_MIPS)
1106
    switch(type) {
1107
    case TARGET_SOCK_DGRAM:
1108
        type = SOCK_DGRAM;
1109
        break;
1110
    case TARGET_SOCK_STREAM:
1111
        type = SOCK_STREAM;
1112
        break;
1113
    case TARGET_SOCK_RAW:
1114
        type = SOCK_RAW;
1115
        break;
1116
    case TARGET_SOCK_RDM:
1117
        type = SOCK_RDM;
1118
        break;
1119
    case TARGET_SOCK_SEQPACKET:
1120
        type = SOCK_SEQPACKET;
1121
        break;
1122
    case TARGET_SOCK_PACKET:
1123
        type = SOCK_PACKET;
1124
        break;
1125
    }
1126
#endif
1127
    if (domain == PF_NETLINK)
1128
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1129
    return get_errno(socket(domain, type, protocol));
1130
}
1131

    
1132
/* do_bind() Must return target values and target errnos. */
1133
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1134
                        socklen_t addrlen)
1135
{
1136
    void *addr = alloca(addrlen);
1137

    
1138
    target_to_host_sockaddr(addr, target_addr, addrlen);
1139
    return get_errno(bind(sockfd, addr, addrlen));
1140
}
1141

    
1142
/* do_connect() Must return target values and target errnos. */
1143
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1144
                           socklen_t addrlen)
1145
{
1146
    void *addr = alloca(addrlen);
1147

    
1148
    target_to_host_sockaddr(addr, target_addr, addrlen);
1149
    return get_errno(connect(sockfd, addr, addrlen));
1150
}
1151

    
1152
/* do_sendrecvmsg() Must return target values and target errnos. */
1153
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1154
                               int flags, int send)
1155
{
1156
    abi_long ret;
1157
    struct target_msghdr *msgp;
1158
    struct msghdr msg;
1159
    int count;
1160
    struct iovec *vec;
1161
    abi_ulong target_vec;
1162

    
1163
    /* FIXME */
1164
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1165
                          msgp,
1166
                          target_msg,
1167
                          send ? 1 : 0))
1168
        return -TARGET_EFAULT;
1169
    if (msgp->msg_name) {
1170
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1171
        msg.msg_name = alloca(msg.msg_namelen);
1172
        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1173
                                msg.msg_namelen);
1174
    } else {
1175
        msg.msg_name = NULL;
1176
        msg.msg_namelen = 0;
1177
    }
1178
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1179
    msg.msg_control = alloca(msg.msg_controllen);
1180
    msg.msg_flags = tswap32(msgp->msg_flags);
1181

    
1182
    count = tswapl(msgp->msg_iovlen);
1183
    vec = alloca(count * sizeof(struct iovec));
1184
    target_vec = tswapl(msgp->msg_iov);
1185
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1186
    msg.msg_iovlen = count;
1187
    msg.msg_iov = vec;
1188

    
1189
    if (send) {
1190
        ret = target_to_host_cmsg(&msg, msgp);
1191
        if (ret == 0)
1192
            ret = get_errno(sendmsg(fd, &msg, flags));
1193
    } else {
1194
        ret = get_errno(recvmsg(fd, &msg, flags));
1195
        if (!is_error(ret))
1196
            ret = host_to_target_cmsg(msgp, &msg);
1197
    }
1198
    unlock_iovec(vec, target_vec, count, !send);
1199
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1200
    return ret;
1201
}
1202

    
1203
/* do_accept() Must return target values and target errnos. */
1204
static abi_long do_accept(int fd, abi_ulong target_addr,
1205
                          abi_ulong target_addrlen_addr)
1206
{
1207
    socklen_t addrlen;
1208
    void *addr;
1209
    abi_long ret;
1210

    
1211
    if (get_user_u32(addrlen, target_addrlen_addr))
1212
        return -TARGET_EFAULT;
1213

    
1214
    addr = alloca(addrlen);
1215

    
1216
    ret = get_errno(accept(fd, addr, &addrlen));
1217
    if (!is_error(ret)) {
1218
        host_to_target_sockaddr(target_addr, addr, addrlen);
1219
        if (put_user_u32(addrlen, target_addrlen_addr))
1220
            ret = -TARGET_EFAULT;
1221
    }
1222
    return ret;
1223
}
1224

    
1225
/* do_getpeername() Must return target values and target errnos. */
1226
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1227
                               abi_ulong target_addrlen_addr)
1228
{
1229
    socklen_t addrlen;
1230
    void *addr;
1231
    abi_long ret;
1232

    
1233
    if (get_user_u32(addrlen, target_addrlen_addr))
1234
        return -TARGET_EFAULT;
1235

    
1236
    addr = alloca(addrlen);
1237

    
1238
    ret = get_errno(getpeername(fd, addr, &addrlen));
1239
    if (!is_error(ret)) {
1240
        host_to_target_sockaddr(target_addr, addr, addrlen);
1241
        if (put_user_u32(addrlen, target_addrlen_addr))
1242
            ret = -TARGET_EFAULT;
1243
    }
1244
    return ret;
1245
}
1246

    
1247
/* do_getsockname() Must return target values and target errnos. */
1248
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1249
                               abi_ulong target_addrlen_addr)
1250
{
1251
    socklen_t addrlen;
1252
    void *addr;
1253
    abi_long ret;
1254

    
1255
    if (get_user_u32(addrlen, target_addrlen_addr))
1256
        return -TARGET_EFAULT;
1257

    
1258
    addr = alloca(addrlen);
1259

    
1260
    ret = get_errno(getsockname(fd, addr, &addrlen));
1261
    if (!is_error(ret)) {
1262
        host_to_target_sockaddr(target_addr, addr, addrlen);
1263
        if (put_user_u32(addrlen, target_addrlen_addr))
1264
            ret = -TARGET_EFAULT;
1265
    }
1266
    return ret;
1267
}
1268

    
1269
/* do_socketpair() Must return target values and target errnos. */
1270
static abi_long do_socketpair(int domain, int type, int protocol,
1271
                              abi_ulong target_tab_addr)
1272
{
1273
    int tab[2];
1274
    abi_long ret;
1275

    
1276
    ret = get_errno(socketpair(domain, type, protocol, tab));
1277
    if (!is_error(ret)) {
1278
        if (put_user_s32(tab[0], target_tab_addr)
1279
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1280
            ret = -TARGET_EFAULT;
1281
    }
1282
    return ret;
1283
}
1284

    
1285
/* do_sendto() Must return target values and target errnos. */
1286
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1287
                          abi_ulong target_addr, socklen_t addrlen)
1288
{
1289
    void *addr;
1290
    void *host_msg;
1291
    abi_long ret;
1292

    
1293
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1294
    if (!host_msg)
1295
        return -TARGET_EFAULT;
1296
    if (target_addr) {
1297
        addr = alloca(addrlen);
1298
        target_to_host_sockaddr(addr, target_addr, addrlen);
1299
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1300
    } else {
1301
        ret = get_errno(send(fd, host_msg, len, flags));
1302
    }
1303
    unlock_user(host_msg, msg, 0);
1304
    return ret;
1305
}
1306

    
1307
/* do_recvfrom() Must return target values and target errnos. */
1308
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1309
                            abi_ulong target_addr,
1310
                            abi_ulong target_addrlen)
1311
{
1312
    socklen_t addrlen;
1313
    void *addr;
1314
    void *host_msg;
1315
    abi_long ret;
1316

    
1317
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1318
    if (!host_msg)
1319
        return -TARGET_EFAULT;
1320
    if (target_addr) {
1321
        if (get_user_u32(addrlen, target_addrlen)) {
1322
            ret = -TARGET_EFAULT;
1323
            goto fail;
1324
        }
1325
        addr = alloca(addrlen);
1326
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1327
    } else {
1328
        addr = NULL; /* To keep compiler quiet.  */
1329
        ret = get_errno(recv(fd, host_msg, len, flags));
1330
    }
1331
    if (!is_error(ret)) {
1332
        if (target_addr) {
1333
            host_to_target_sockaddr(target_addr, addr, addrlen);
1334
            if (put_user_u32(addrlen, target_addrlen)) {
1335
                ret = -TARGET_EFAULT;
1336
                goto fail;
1337
            }
1338
        }
1339
        unlock_user(host_msg, msg, len);
1340
    } else {
1341
fail:
1342
        unlock_user(host_msg, msg, 0);
1343
    }
1344
    return ret;
1345
}
1346

    
1347
#ifdef TARGET_NR_socketcall
1348
/* do_socketcall() Must return target values and target errnos. */
1349
static abi_long do_socketcall(int num, abi_ulong vptr)
1350
{
1351
    abi_long ret;
1352
    const int n = sizeof(abi_ulong);
1353

    
1354
    switch(num) {
1355
    case SOCKOP_socket:
1356
        {
1357
            int domain, type, protocol;
1358

    
1359
            if (get_user_s32(domain, vptr)
1360
                || get_user_s32(type, vptr + n)
1361
                || get_user_s32(protocol, vptr + 2 * n))
1362
                return -TARGET_EFAULT;
1363

    
1364
            ret = do_socket(domain, type, protocol);
1365
        }
1366
        break;
1367
    case SOCKOP_bind:
1368
        {
1369
            int sockfd;
1370
            abi_ulong target_addr;
1371
            socklen_t addrlen;
1372

    
1373
            if (get_user_s32(sockfd, vptr)
1374
                || get_user_ual(target_addr, vptr + n)
1375
                || get_user_u32(addrlen, vptr + 2 * n))
1376
                return -TARGET_EFAULT;
1377

    
1378
            ret = do_bind(sockfd, target_addr, addrlen);
1379
        }
1380
        break;
1381
    case SOCKOP_connect:
1382
        {
1383
            int sockfd;
1384
            abi_ulong target_addr;
1385
            socklen_t addrlen;
1386

    
1387
            if (get_user_s32(sockfd, vptr)
1388
                || get_user_ual(target_addr, vptr + n)
1389
                || get_user_u32(addrlen, vptr + 2 * n))
1390
                return -TARGET_EFAULT;
1391

    
1392
            ret = do_connect(sockfd, target_addr, addrlen);
1393
        }
1394
        break;
1395
    case SOCKOP_listen:
1396
        {
1397
            int sockfd, backlog;
1398

    
1399
            if (get_user_s32(sockfd, vptr)
1400
                || get_user_s32(backlog, vptr + n))
1401
                return -TARGET_EFAULT;
1402

    
1403
            ret = get_errno(listen(sockfd, backlog));
1404
        }
1405
        break;
1406
    case SOCKOP_accept:
1407
        {
1408
            int sockfd;
1409
            abi_ulong target_addr, target_addrlen;
1410

    
1411
            if (get_user_s32(sockfd, vptr)
1412
                || get_user_ual(target_addr, vptr + n)
1413
                || get_user_u32(target_addrlen, vptr + 2 * n))
1414
                return -TARGET_EFAULT;
1415

    
1416
            ret = do_accept(sockfd, target_addr, target_addrlen);
1417
        }
1418
        break;
1419
    case SOCKOP_getsockname:
1420
        {
1421
            int sockfd;
1422
            abi_ulong target_addr, target_addrlen;
1423

    
1424
            if (get_user_s32(sockfd, vptr)
1425
                || get_user_ual(target_addr, vptr + n)
1426
                || get_user_u32(target_addrlen, vptr + 2 * n))
1427
                return -TARGET_EFAULT;
1428

    
1429
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1430
        }
1431
        break;
1432
    case SOCKOP_getpeername:
1433
        {
1434
            int sockfd;
1435
            abi_ulong target_addr, target_addrlen;
1436

    
1437
            if (get_user_s32(sockfd, vptr)
1438
                || get_user_ual(target_addr, vptr + n)
1439
                || get_user_u32(target_addrlen, vptr + 2 * n))
1440
                return -TARGET_EFAULT;
1441

    
1442
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1443
        }
1444
        break;
1445
    case SOCKOP_socketpair:
1446
        {
1447
            int domain, type, protocol;
1448
            abi_ulong tab;
1449

    
1450
            if (get_user_s32(domain, vptr)
1451
                || get_user_s32(type, vptr + n)
1452
                || get_user_s32(protocol, vptr + 2 * n)
1453
                || get_user_ual(tab, vptr + 3 * n))
1454
                return -TARGET_EFAULT;
1455

    
1456
            ret = do_socketpair(domain, type, protocol, tab);
1457
        }
1458
        break;
1459
    case SOCKOP_send:
1460
        {
1461
            int sockfd;
1462
            abi_ulong msg;
1463
            size_t len;
1464
            int flags;
1465

    
1466
            if (get_user_s32(sockfd, vptr)
1467
                || get_user_ual(msg, vptr + n)
1468
                || get_user_ual(len, vptr + 2 * n)
1469
                || get_user_s32(flags, vptr + 3 * n))
1470
                return -TARGET_EFAULT;
1471

    
1472
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1473
        }
1474
        break;
1475
    case SOCKOP_recv:
1476
        {
1477
            int sockfd;
1478
            abi_ulong msg;
1479
            size_t len;
1480
            int flags;
1481

    
1482
            if (get_user_s32(sockfd, vptr)
1483
                || get_user_ual(msg, vptr + n)
1484
                || get_user_ual(len, vptr + 2 * n)
1485
                || get_user_s32(flags, vptr + 3 * n))
1486
                return -TARGET_EFAULT;
1487

    
1488
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1489
        }
1490
        break;
1491
    case SOCKOP_sendto:
1492
        {
1493
            int sockfd;
1494
            abi_ulong msg;
1495
            size_t len;
1496
            int flags;
1497
            abi_ulong addr;
1498
            socklen_t addrlen;
1499

    
1500
            if (get_user_s32(sockfd, vptr)
1501
                || get_user_ual(msg, vptr + n)
1502
                || get_user_ual(len, vptr + 2 * n)
1503
                || get_user_s32(flags, vptr + 3 * n)
1504
                || get_user_ual(addr, vptr + 4 * n)
1505
                || get_user_u32(addrlen, vptr + 5 * n))
1506
                return -TARGET_EFAULT;
1507

    
1508
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1509
        }
1510
        break;
1511
    case SOCKOP_recvfrom:
1512
        {
1513
            int sockfd;
1514
            abi_ulong msg;
1515
            size_t len;
1516
            int flags;
1517
            abi_ulong addr;
1518
            socklen_t addrlen;
1519

    
1520
            if (get_user_s32(sockfd, vptr)
1521
                || get_user_ual(msg, vptr + n)
1522
                || get_user_ual(len, vptr + 2 * n)
1523
                || get_user_s32(flags, vptr + 3 * n)
1524
                || get_user_ual(addr, vptr + 4 * n)
1525
                || get_user_u32(addrlen, vptr + 5 * n))
1526
                return -TARGET_EFAULT;
1527

    
1528
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1529
        }
1530
        break;
1531
    case SOCKOP_shutdown:
1532
        {
1533
            int sockfd, how;
1534

    
1535
            if (get_user_s32(sockfd, vptr)
1536
                || get_user_s32(how, vptr + n))
1537
                return -TARGET_EFAULT;
1538

    
1539
            ret = get_errno(shutdown(sockfd, how));
1540
        }
1541
        break;
1542
    case SOCKOP_sendmsg:
1543
    case SOCKOP_recvmsg:
1544
        {
1545
            int fd;
1546
            abi_ulong target_msg;
1547
            int flags;
1548

    
1549
            if (get_user_s32(fd, vptr)
1550
                || get_user_ual(target_msg, vptr + n)
1551
                || get_user_s32(flags, vptr + 2 * n))
1552
                return -TARGET_EFAULT;
1553

    
1554
            ret = do_sendrecvmsg(fd, target_msg, flags,
1555
                                 (num == SOCKOP_sendmsg));
1556
        }
1557
        break;
1558
    case SOCKOP_setsockopt:
1559
        {
1560
            int sockfd;
1561
            int level;
1562
            int optname;
1563
            abi_ulong optval;
1564
            socklen_t optlen;
1565

    
1566
            if (get_user_s32(sockfd, vptr)
1567
                || get_user_s32(level, vptr + n)
1568
                || get_user_s32(optname, vptr + 2 * n)
1569
                || get_user_ual(optval, vptr + 3 * n)
1570
                || get_user_u32(optlen, vptr + 4 * n))
1571
                return -TARGET_EFAULT;
1572

    
1573
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1574
        }
1575
        break;
1576
    case SOCKOP_getsockopt:
1577
        {
1578
            int sockfd;
1579
            int level;
1580
            int optname;
1581
            abi_ulong optval;
1582
            socklen_t optlen;
1583

    
1584
            if (get_user_s32(sockfd, vptr)
1585
                || get_user_s32(level, vptr + n)
1586
                || get_user_s32(optname, vptr + 2 * n)
1587
                || get_user_ual(optval, vptr + 3 * n)
1588
                || get_user_u32(optlen, vptr + 4 * n))
1589
                return -TARGET_EFAULT;
1590

    
1591
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1592
        }
1593
        break;
1594
    default:
1595
        gemu_log("Unsupported socketcall: %d\n", num);
1596
        ret = -TARGET_ENOSYS;
1597
        break;
1598
    }
1599
    return ret;
1600
}
1601
#endif
1602

    
1603
#ifdef TARGET_NR_ipc
1604
#define N_SHM_REGIONS        32
1605

    
1606
static struct shm_region {
1607
    abi_ulong        start;
1608
    abi_ulong        size;
1609
} shm_regions[N_SHM_REGIONS];
1610

    
1611
struct target_ipc_perm
1612
{
1613
    abi_long __key;
1614
    abi_ulong uid;
1615
    abi_ulong gid;
1616
    abi_ulong cuid;
1617
    abi_ulong cgid;
1618
    unsigned short int mode;
1619
    unsigned short int __pad1;
1620
    unsigned short int __seq;
1621
    unsigned short int __pad2;
1622
    abi_ulong __unused1;
1623
    abi_ulong __unused2;
1624
};
1625

    
1626
struct target_semid_ds
1627
{
1628
  struct target_ipc_perm sem_perm;
1629
  abi_ulong sem_otime;
1630
  abi_ulong __unused1;
1631
  abi_ulong sem_ctime;
1632
  abi_ulong __unused2;
1633
  abi_ulong sem_nsems;
1634
  abi_ulong __unused3;
1635
  abi_ulong __unused4;
1636
};
1637

    
1638
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1639
                                               abi_ulong target_addr)
1640
{
1641
    struct target_ipc_perm *target_ip;
1642
    struct target_semid_ds *target_sd;
1643

    
1644
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1645
        return -TARGET_EFAULT;
1646
    target_ip=&(target_sd->sem_perm);
1647
    host_ip->__key = tswapl(target_ip->__key);
1648
    host_ip->uid = tswapl(target_ip->uid);
1649
    host_ip->gid = tswapl(target_ip->gid);
1650
    host_ip->cuid = tswapl(target_ip->cuid);
1651
    host_ip->cgid = tswapl(target_ip->cgid);
1652
    host_ip->mode = tswapl(target_ip->mode);
1653
    unlock_user_struct(target_sd, target_addr, 0);
1654
    return 0;
1655
}
1656

    
1657
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1658
                                               struct ipc_perm *host_ip)
1659
{
1660
    struct target_ipc_perm *target_ip;
1661
    struct target_semid_ds *target_sd;
1662

    
1663
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1664
        return -TARGET_EFAULT;
1665
    target_ip = &(target_sd->sem_perm);
1666
    target_ip->__key = tswapl(host_ip->__key);
1667
    target_ip->uid = tswapl(host_ip->uid);
1668
    target_ip->gid = tswapl(host_ip->gid);
1669
    target_ip->cuid = tswapl(host_ip->cuid);
1670
    target_ip->cgid = tswapl(host_ip->cgid);
1671
    target_ip->mode = tswapl(host_ip->mode);
1672
    unlock_user_struct(target_sd, target_addr, 1);
1673
    return 0;
1674
}
1675

    
1676
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1677
                                               abi_ulong target_addr)
1678
{
1679
    struct target_semid_ds *target_sd;
1680

    
1681
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1682
        return -TARGET_EFAULT;
1683
    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1684
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1685
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
1686
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1687
    unlock_user_struct(target_sd, target_addr, 0);
1688
    return 0;
1689
}
1690

    
1691
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1692
                                               struct semid_ds *host_sd)
1693
{
1694
    struct target_semid_ds *target_sd;
1695

    
1696
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1697
        return -TARGET_EFAULT;
1698
    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1699
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1700
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
1701
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1702
    unlock_user_struct(target_sd, target_addr, 1);
1703
    return 0;
1704
}
1705

    
1706
union semun {
1707
        int val;
1708
        struct semid_ds *buf;
1709
        unsigned short *array;
1710
};
1711

    
1712
union target_semun {
1713
        int val;
1714
        abi_long buf;
1715
        unsigned short int *array;
1716
};
1717

    
1718
static inline abi_long target_to_host_semun(int cmd,
1719
                                            union semun *host_su,
1720
                                            abi_ulong target_addr,
1721
                                            struct semid_ds *ds)
1722
{
1723
    union target_semun *target_su;
1724

    
1725
    switch( cmd ) {
1726
        case IPC_STAT:
1727
        case IPC_SET:
1728
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1729
               return -TARGET_EFAULT;
1730
           target_to_host_semid_ds(ds,target_su->buf);
1731
           host_su->buf = ds;
1732
           unlock_user_struct(target_su, target_addr, 0);
1733
           break;
1734
        case GETVAL:
1735
        case SETVAL:
1736
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1737
               return -TARGET_EFAULT;
1738
           host_su->val = tswapl(target_su->val);
1739
           unlock_user_struct(target_su, target_addr, 0);
1740
           break;
1741
        case GETALL:
1742
        case SETALL:
1743
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1744
               return -TARGET_EFAULT;
1745
           *host_su->array = tswap16(*target_su->array);
1746
           unlock_user_struct(target_su, target_addr, 0);
1747
           break;
1748
        default:
1749
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1750
    }
1751
    return 0;
1752
}
1753

    
1754
static inline abi_long host_to_target_semun(int cmd,
1755
                                            abi_ulong target_addr,
1756
                                            union semun *host_su,
1757
                                            struct semid_ds *ds)
1758
{
1759
    union target_semun *target_su;
1760

    
1761
    switch( cmd ) {
1762
        case IPC_STAT:
1763
        case IPC_SET:
1764
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1765
               return -TARGET_EFAULT;
1766
           host_to_target_semid_ds(target_su->buf,ds);
1767
           unlock_user_struct(target_su, target_addr, 1);
1768
           break;
1769
        case GETVAL:
1770
        case SETVAL:
1771
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1772
               return -TARGET_EFAULT;
1773
           target_su->val = tswapl(host_su->val);
1774
           unlock_user_struct(target_su, target_addr, 1);
1775
           break;
1776
        case GETALL:
1777
        case SETALL:
1778
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1779
               return -TARGET_EFAULT;
1780
           *target_su->array = tswap16(*host_su->array);
1781
           unlock_user_struct(target_su, target_addr, 1);
1782
           break;
1783
        default:
1784
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1785
    }
1786
    return 0;
1787
}
1788

    
1789
static inline abi_long do_semctl(int first, int second, int third,
1790
                                 abi_long ptr)
1791
{
1792
    union semun arg;
1793
    struct semid_ds dsarg;
1794
    int cmd = third&0xff;
1795
    abi_long ret = 0;
1796

    
1797
    switch( cmd ) {
1798
        case GETVAL:
1799
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1800
            ret = get_errno(semctl(first, second, cmd, arg));
1801
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1802
            break;
1803
        case SETVAL:
1804
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1805
            ret = get_errno(semctl(first, second, cmd, arg));
1806
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1807
            break;
1808
        case GETALL:
1809
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1810
            ret = get_errno(semctl(first, second, cmd, arg));
1811
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1812
            break;
1813
        case SETALL:
1814
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1815
            ret = get_errno(semctl(first, second, cmd, arg));
1816
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1817
            break;
1818
        case IPC_STAT:
1819
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1820
            ret = get_errno(semctl(first, second, cmd, arg));
1821
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1822
            break;
1823
        case IPC_SET:
1824
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1825
            ret = get_errno(semctl(first, second, cmd, arg));
1826
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1827
            break;
1828
    default:
1829
            ret = get_errno(semctl(first, second, cmd, arg));
1830
    }
1831

    
1832
    return ret;
1833
}
1834

    
1835
struct target_msqid_ds
1836
{
1837
  struct target_ipc_perm msg_perm;
1838
  abi_ulong msg_stime;
1839
  abi_ulong __unused1;
1840
  abi_ulong msg_rtime;
1841
  abi_ulong __unused2;
1842
  abi_ulong msg_ctime;
1843
  abi_ulong __unused3;
1844
  abi_ulong __msg_cbytes;
1845
  abi_ulong msg_qnum;
1846
  abi_ulong msg_qbytes;
1847
  abi_ulong msg_lspid;
1848
  abi_ulong msg_lrpid;
1849
  abi_ulong __unused4;
1850
  abi_ulong __unused5;
1851
};
1852

    
1853
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1854
                                               abi_ulong target_addr)
1855
{
1856
    struct target_msqid_ds *target_md;
1857

    
1858
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1859
        return -TARGET_EFAULT;
1860
    target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
1861
    host_md->msg_stime = tswapl(target_md->msg_stime);
1862
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
1863
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
1864
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1865
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
1866
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1867
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
1868
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1869
    unlock_user_struct(target_md, target_addr, 0);
1870
    return 0;
1871
}
1872

    
1873
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1874
                                               struct msqid_ds *host_md)
1875
{
1876
    struct target_msqid_ds *target_md;
1877

    
1878
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1879
        return -TARGET_EFAULT;
1880
    host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
1881
    target_md->msg_stime = tswapl(host_md->msg_stime);
1882
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
1883
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
1884
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1885
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
1886
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1887
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
1888
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1889
    unlock_user_struct(target_md, target_addr, 1);
1890
    return 0;
1891
}
1892

    
1893
static inline abi_long do_msgctl(int first, int second, abi_long ptr)
1894
{
1895
    struct msqid_ds dsarg;
1896
    int cmd = second&0xff;
1897
    abi_long ret = 0;
1898
    switch( cmd ) {
1899
    case IPC_STAT:
1900
    case IPC_SET:
1901
        target_to_host_msqid_ds(&dsarg,ptr);
1902
        ret = get_errno(msgctl(first, cmd, &dsarg));
1903
        host_to_target_msqid_ds(ptr,&dsarg);
1904
    default:
1905
        ret = get_errno(msgctl(first, cmd, &dsarg));
1906
    }
1907
    return ret;
1908
}
1909

    
1910
struct target_msgbuf {
1911
        abi_ulong mtype;
1912
        char        mtext[1];
1913
};
1914

    
1915
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1916
                                 unsigned int msgsz, int msgflg)
1917
{
1918
    struct target_msgbuf *target_mb;
1919
    struct msgbuf *host_mb;
1920
    abi_long ret = 0;
1921

    
1922
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1923
        return -TARGET_EFAULT;
1924
    host_mb = malloc(msgsz+sizeof(long));
1925
    host_mb->mtype = tswapl(target_mb->mtype);
1926
    memcpy(host_mb->mtext,target_mb->mtext,msgsz);
1927
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1928
    free(host_mb);
1929
    unlock_user_struct(target_mb, msgp, 0);
1930

    
1931
    return ret;
1932
}
1933

    
1934
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1935
                                 unsigned int msgsz, int msgtype,
1936
                                 int msgflg)
1937
{
1938
    struct target_msgbuf *target_mb;
1939
    char *target_mtext;
1940
    struct msgbuf *host_mb;
1941
    abi_long ret = 0;
1942

    
1943
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
1944
        return -TARGET_EFAULT;
1945
    host_mb = malloc(msgsz+sizeof(long));
1946
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
1947
    if (ret > 0) {
1948
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
1949
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
1950
        if (!target_mtext) {
1951
            ret = -TARGET_EFAULT;
1952
            goto end;
1953
        }
1954
            memcpy(target_mb->mtext, host_mb->mtext, ret);
1955
        unlock_user(target_mtext, target_mtext_addr, ret);
1956
    }
1957
    target_mb->mtype = tswapl(host_mb->mtype);
1958
    free(host_mb);
1959

    
1960
end:
1961
    if (target_mb)
1962
        unlock_user_struct(target_mb, msgp, 1);
1963
    return ret;
1964
}
1965

    
1966
/* ??? This only works with linear mappings.  */
1967
/* do_ipc() must return target values and target errnos. */
1968
static abi_long do_ipc(unsigned int call, int first,
1969
                       int second, int third,
1970
                       abi_long ptr, abi_long fifth)
1971
{
1972
    int version;
1973
    abi_long ret = 0;
1974
    struct shmid_ds shm_info;
1975
    int i;
1976

    
1977
    version = call >> 16;
1978
    call &= 0xffff;
1979

    
1980
    switch (call) {
1981
    case IPCOP_semop:
1982
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
1983
        break;
1984

    
1985
    case IPCOP_semget:
1986
        ret = get_errno(semget(first, second, third));
1987
        break;
1988

    
1989
    case IPCOP_semctl:
1990
        ret = do_semctl(first, second, third, ptr);
1991
        break;
1992

    
1993
    case IPCOP_semtimedop:
1994
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
1995
        ret = -TARGET_ENOSYS;
1996
        break;
1997

    
1998
        case IPCOP_msgget:
1999
                ret = get_errno(msgget(first, second));
2000
                break;
2001

    
2002
        case IPCOP_msgsnd:
2003
                ret = do_msgsnd(first, ptr, second, third);
2004
                break;
2005

    
2006
        case IPCOP_msgctl:
2007
                ret = do_msgctl(first, second, ptr);
2008
                break;
2009

    
2010
        case IPCOP_msgrcv:
2011
                {
2012
                      /* XXX: this code is not correct */
2013
                      struct ipc_kludge
2014
                      {
2015
                              void *__unbounded msgp;
2016
                              long int msgtyp;
2017
                      };
2018

    
2019
                      struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
2020
                      struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
2021

    
2022
                      ret = do_msgrcv(first, (long)msgp, second, 0, third);
2023

    
2024
                }
2025
                break;
2026

    
2027
    case IPCOP_shmat:
2028
        {
2029
            abi_ulong raddr;
2030
            void *host_addr;
2031
            /* SHM_* flags are the same on all linux platforms */
2032
            host_addr = shmat(first, (void *)g2h(ptr), second);
2033
            if (host_addr == (void *)-1) {
2034
                ret = get_errno((long)host_addr);
2035
                break;
2036
            }
2037
            raddr = h2g((unsigned long)host_addr);
2038
            /* find out the length of the shared memory segment */
2039
            
2040
            ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2041
            if (is_error(ret)) {
2042
                /* can't get length, bail out */
2043
                shmdt(host_addr);
2044
                break;
2045
            }
2046
            page_set_flags(raddr, raddr + shm_info.shm_segsz,
2047
                           PAGE_VALID | PAGE_READ |
2048
                           ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2049
            for (i = 0; i < N_SHM_REGIONS; ++i) {
2050
                if (shm_regions[i].start == 0) {
2051
                    shm_regions[i].start = raddr;
2052
                    shm_regions[i].size = shm_info.shm_segsz;
2053
                    break;
2054
                }
2055
            }
2056
            if (put_user_ual(raddr, third))
2057
                return -TARGET_EFAULT;
2058
            ret = 0;
2059
        }
2060
        break;
2061
    case IPCOP_shmdt:
2062
        for (i = 0; i < N_SHM_REGIONS; ++i) {
2063
            if (shm_regions[i].start == ptr) {
2064
                shm_regions[i].start = 0;
2065
                page_set_flags(ptr, shm_regions[i].size, 0);
2066
                break;
2067
            }
2068
        }
2069
        ret = get_errno(shmdt((void *)g2h(ptr)));
2070
        break;
2071

    
2072
    case IPCOP_shmget:
2073
        /* IPC_* flag values are the same on all linux platforms */
2074
        ret = get_errno(shmget(first, second, third));
2075
        break;
2076

    
2077
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2078
    case IPCOP_shmctl:
2079
        switch(second) {
2080
        case IPC_RMID:
2081
        case SHM_LOCK:
2082
        case SHM_UNLOCK:
2083
            ret = get_errno(shmctl(first, second, NULL));
2084
            break;
2085
        default:
2086
            goto unimplemented;
2087
        }
2088
        break;
2089
    default:
2090
    unimplemented:
2091
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2092
        ret = -TARGET_ENOSYS;
2093
        break;
2094
    }
2095
    return ret;
2096
}
2097
#endif
2098

    
2099
/* kernel structure types definitions */
2100
#define IFNAMSIZ        16
2101

    
2102
#define STRUCT(name, list...) STRUCT_ ## name,
2103
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2104
enum {
2105
#include "syscall_types.h"
2106
};
2107
#undef STRUCT
2108
#undef STRUCT_SPECIAL
2109

    
2110
#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2111
#define STRUCT_SPECIAL(name)
2112
#include "syscall_types.h"
2113
#undef STRUCT
2114
#undef STRUCT_SPECIAL
2115

    
2116
typedef struct IOCTLEntry {
2117
    unsigned int target_cmd;
2118
    unsigned int host_cmd;
2119
    const char *name;
2120
    int access;
2121
    const argtype arg_type[5];
2122
} IOCTLEntry;
2123

    
2124
#define IOC_R 0x0001
2125
#define IOC_W 0x0002
2126
#define IOC_RW (IOC_R | IOC_W)
2127

    
2128
#define MAX_STRUCT_SIZE 4096
2129

    
2130
IOCTLEntry ioctl_entries[] = {
2131
#define IOCTL(cmd, access, types...) \
2132
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2133
#include "ioctls.h"
2134
    { 0, 0, },
2135
};
2136

    
2137
/* ??? Implement proper locking for ioctls.  */
2138
/* do_ioctl() Must return target values and target errnos. */
2139
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2140
{
2141
    const IOCTLEntry *ie;
2142
    const argtype *arg_type;
2143
    abi_long ret;
2144
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2145
    int target_size;
2146
    void *argptr;
2147

    
2148
    ie = ioctl_entries;
2149
    for(;;) {
2150
        if (ie->target_cmd == 0) {
2151
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2152
            return -TARGET_ENOSYS;
2153
        }
2154
        if (ie->target_cmd == cmd)
2155
            break;
2156
        ie++;
2157
    }
2158
    arg_type = ie->arg_type;
2159
#if defined(DEBUG)
2160
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2161
#endif
2162
    switch(arg_type[0]) {
2163
    case TYPE_NULL:
2164
        /* no argument */
2165
        ret = get_errno(ioctl(fd, ie->host_cmd));
2166
        break;
2167
    case TYPE_PTRVOID:
2168
    case TYPE_INT:
2169
        /* int argment */
2170
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2171
        break;
2172
    case TYPE_PTR:
2173
        arg_type++;
2174
        target_size = thunk_type_size(arg_type, 0);
2175
        switch(ie->access) {
2176
        case IOC_R:
2177
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2178
            if (!is_error(ret)) {
2179
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2180
                if (!argptr)
2181
                    return -TARGET_EFAULT;
2182
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2183
                unlock_user(argptr, arg, target_size);
2184
            }
2185
            break;
2186
        case IOC_W:
2187
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2188
            if (!argptr)
2189
                return -TARGET_EFAULT;
2190
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2191
            unlock_user(argptr, arg, 0);
2192
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2193
            break;
2194
        default:
2195
        case IOC_RW:
2196
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2197
            if (!argptr)
2198
                return -TARGET_EFAULT;
2199
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2200
            unlock_user(argptr, arg, 0);
2201
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2202
            if (!is_error(ret)) {
2203
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2204
                if (!argptr)
2205
                    return -TARGET_EFAULT;
2206
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2207
                unlock_user(argptr, arg, target_size);
2208
            }
2209
            break;
2210
        }
2211
        break;
2212
    default:
2213
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2214
                 (long)cmd, arg_type[0]);
2215
        ret = -TARGET_ENOSYS;
2216
        break;
2217
    }
2218
    return ret;
2219
}
2220

    
2221
bitmask_transtbl iflag_tbl[] = {
2222
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2223
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2224
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2225
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2226
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2227
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2228
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2229
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2230
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2231
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2232
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2233
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2234
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2235
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2236
        { 0, 0, 0, 0 }
2237
};
2238

    
2239
bitmask_transtbl oflag_tbl[] = {
2240
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2241
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2242
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2243
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2244
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2245
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2246
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2247
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2248
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2249
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2250
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2251
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2252
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2253
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2254
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2255
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2256
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2257
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2258
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2259
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2260
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2261
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2262
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2263
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2264
        { 0, 0, 0, 0 }
2265
};
2266

    
2267
bitmask_transtbl cflag_tbl[] = {
2268
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2269
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2270
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2271
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2272
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2273
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2274
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2275
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2276
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2277
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2278
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2279
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2280
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2281
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2282
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2283
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2284
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2285
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2286
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2287
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2288
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2289
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2290
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2291
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2292
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2293
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2294
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2295
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2296
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2297
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2298
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2299
        { 0, 0, 0, 0 }
2300
};
2301

    
2302
bitmask_transtbl lflag_tbl[] = {
2303
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2304
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2305
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2306
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2307
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2308
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2309
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2310
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2311
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2312
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2313
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2314
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2315
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2316
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2317
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2318
        { 0, 0, 0, 0 }
2319
};
2320

    
2321
static void target_to_host_termios (void *dst, const void *src)
2322
{
2323
    struct host_termios *host = dst;
2324
    const struct target_termios *target = src;
2325

    
2326
    host->c_iflag =
2327
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2328
    host->c_oflag =
2329
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2330
    host->c_cflag =
2331
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2332
    host->c_lflag =
2333
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2334
    host->c_line = target->c_line;
2335

    
2336
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2337
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2338
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2339
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2340
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2341
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2342
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2343
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2344
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2345
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2346
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2347
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2348
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2349
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2350
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2351
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2352
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2353
}
2354

    
2355
static void host_to_target_termios (void *dst, const void *src)
2356
{
2357
    struct target_termios *target = dst;
2358
    const struct host_termios *host = src;
2359

    
2360
    target->c_iflag =
2361
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2362
    target->c_oflag =
2363
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2364
    target->c_cflag =
2365
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2366
    target->c_lflag =
2367
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2368
    target->c_line = host->c_line;
2369

    
2370
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2371
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2372
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2373
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2374
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2375
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2376
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2377
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2378
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2379
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2380
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2381
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2382
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2383
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2384
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2385
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2386
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2387
}
2388

    
2389
StructEntry struct_termios_def = {
2390
    .convert = { host_to_target_termios, target_to_host_termios },
2391
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2392
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2393
};
2394

    
2395
static bitmask_transtbl mmap_flags_tbl[] = {
2396
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2397
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2398
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2399
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2400
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2401
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2402
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2403
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2404
        { 0, 0, 0, 0 }
2405
};
2406

    
2407
static bitmask_transtbl fcntl_flags_tbl[] = {
2408
        { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
2409
        { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
2410
        { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
2411
        { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
2412
        { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
2413
        { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
2414
        { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
2415
        { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
2416
        { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
2417
        { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
2418
        { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2419
        { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
2420
        { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2421
#if defined(O_DIRECT)
2422
        { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
2423
#endif
2424
        { 0, 0, 0, 0 }
2425
};
2426

    
2427
#if defined(TARGET_I386)
2428

    
2429
/* NOTE: there is really one LDT for all the threads */
2430
uint8_t *ldt_table;
2431

    
2432
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2433
{
2434
    int size;
2435
    void *p;
2436

    
2437
    if (!ldt_table)
2438
        return 0;
2439
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2440
    if (size > bytecount)
2441
        size = bytecount;
2442
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
2443
    if (!p)
2444
        return -TARGET_EFAULT;
2445
    /* ??? Should this by byteswapped?  */
2446
    memcpy(p, ldt_table, size);
2447
    unlock_user(p, ptr, size);
2448
    return size;
2449
}
2450

    
2451
/* XXX: add locking support */
2452
static abi_long write_ldt(CPUX86State *env,
2453
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
2454
{
2455
    struct target_modify_ldt_ldt_s ldt_info;
2456
    struct target_modify_ldt_ldt_s *target_ldt_info;
2457
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2458
    int seg_not_present, useable, lm;
2459
    uint32_t *lp, entry_1, entry_2;
2460

    
2461
    if (bytecount != sizeof(ldt_info))
2462
        return -TARGET_EINVAL;
2463
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2464
        return -TARGET_EFAULT;
2465
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2466
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2467
    ldt_info.limit = tswap32(target_ldt_info->limit);
2468
    ldt_info.flags = tswap32(target_ldt_info->flags);
2469
    unlock_user_struct(target_ldt_info, ptr, 0);
2470

    
2471
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2472
        return -TARGET_EINVAL;
2473
    seg_32bit = ldt_info.flags & 1;
2474
    contents = (ldt_info.flags >> 1) & 3;
2475
    read_exec_only = (ldt_info.flags >> 3) & 1;
2476
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2477
    seg_not_present = (ldt_info.flags >> 5) & 1;
2478
    useable = (ldt_info.flags >> 6) & 1;
2479
#ifdef TARGET_ABI32
2480
    lm = 0;
2481
#else
2482
    lm = (ldt_info.flags >> 7) & 1;
2483
#endif
2484
    if (contents == 3) {
2485
        if (oldmode)
2486
            return -TARGET_EINVAL;
2487
        if (seg_not_present == 0)
2488
            return -TARGET_EINVAL;
2489
    }
2490
    /* allocate the LDT */
2491
    if (!ldt_table) {
2492
        ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2493
        if (!ldt_table)
2494
            return -TARGET_ENOMEM;
2495
        memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2496
        env->ldt.base = h2g((unsigned long)ldt_table);
2497
        env->ldt.limit = 0xffff;
2498
    }
2499

    
2500
    /* NOTE: same code as Linux kernel */
2501
    /* Allow LDTs to be cleared by the user. */
2502
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2503
        if (oldmode ||
2504
            (contents == 0                &&
2505
             read_exec_only == 1        &&
2506
             seg_32bit == 0                &&
2507
             limit_in_pages == 0        &&
2508
             seg_not_present == 1        &&
2509
             useable == 0 )) {
2510
            entry_1 = 0;
2511
            entry_2 = 0;
2512
            goto install;
2513
        }
2514
    }
2515

    
2516
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2517
        (ldt_info.limit & 0x0ffff);
2518
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2519
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2520
        (ldt_info.limit & 0xf0000) |
2521
        ((read_exec_only ^ 1) << 9) |
2522
        (contents << 10) |
2523
        ((seg_not_present ^ 1) << 15) |
2524
        (seg_32bit << 22) |
2525
        (limit_in_pages << 23) |
2526
        (lm << 21) |
2527
        0x7000;
2528
    if (!oldmode)
2529
        entry_2 |= (useable << 20);
2530

    
2531
    /* Install the new entry ...  */
2532
install:
2533
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2534
    lp[0] = tswap32(entry_1);
2535
    lp[1] = tswap32(entry_2);
2536
    return 0;
2537
}
2538

    
2539
/* specific and weird i386 syscalls */
2540
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2541
                              unsigned long bytecount)
2542
{
2543
    abi_long ret;
2544

    
2545
    switch (func) {
2546
    case 0:
2547
        ret = read_ldt(ptr, bytecount);
2548
        break;
2549
    case 1:
2550
        ret = write_ldt(env, ptr, bytecount, 1);
2551
        break;
2552
    case 0x11:
2553
        ret = write_ldt(env, ptr, bytecount, 0);
2554
        break;
2555
    default:
2556
        ret = -TARGET_ENOSYS;
2557
        break;
2558
    }
2559
    return ret;
2560
}
2561

    
2562
#if defined(TARGET_I386) && defined(TARGET_ABI32)
2563
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2564
{
2565
    uint64_t *gdt_table = g2h(env->gdt.base);
2566
    struct target_modify_ldt_ldt_s ldt_info;
2567
    struct target_modify_ldt_ldt_s *target_ldt_info;
2568
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2569
    int seg_not_present, useable, lm;
2570
    uint32_t *lp, entry_1, entry_2;
2571
    int i;
2572

    
2573
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2574
    if (!target_ldt_info)
2575
        return -TARGET_EFAULT;
2576
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2577
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2578
    ldt_info.limit = tswap32(target_ldt_info->limit);
2579
    ldt_info.flags = tswap32(target_ldt_info->flags);
2580
    if (ldt_info.entry_number == -1) {
2581
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2582
            if (gdt_table[i] == 0) {
2583
                ldt_info.entry_number = i;
2584
                target_ldt_info->entry_number = tswap32(i);
2585
                break;
2586
            }
2587
        }
2588
    }
2589
    unlock_user_struct(target_ldt_info, ptr, 1);
2590

    
2591
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
2592
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2593
           return -TARGET_EINVAL;
2594
    seg_32bit = ldt_info.flags & 1;
2595
    contents = (ldt_info.flags >> 1) & 3;
2596
    read_exec_only = (ldt_info.flags >> 3) & 1;
2597
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2598
    seg_not_present = (ldt_info.flags >> 5) & 1;
2599
    useable = (ldt_info.flags >> 6) & 1;
2600
#ifdef TARGET_ABI32
2601
    lm = 0;
2602
#else
2603
    lm = (ldt_info.flags >> 7) & 1;
2604
#endif
2605

    
2606
    if (contents == 3) {
2607
        if (seg_not_present == 0)
2608
            return -TARGET_EINVAL;
2609
    }
2610

    
2611
    /* NOTE: same code as Linux kernel */
2612
    /* Allow LDTs to be cleared by the user. */
2613
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2614
        if ((contents == 0             &&
2615
             read_exec_only == 1       &&
2616
             seg_32bit == 0            &&
2617
             limit_in_pages == 0       &&
2618
             seg_not_present == 1      &&
2619
             useable == 0 )) {
2620
            entry_1 = 0;
2621
            entry_2 = 0;
2622
            goto install;
2623
        }
2624
    }
2625

    
2626
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2627
        (ldt_info.limit & 0x0ffff);
2628
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2629
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2630
        (ldt_info.limit & 0xf0000) |
2631
        ((read_exec_only ^ 1) << 9) |
2632
        (contents << 10) |
2633
        ((seg_not_present ^ 1) << 15) |
2634
        (seg_32bit << 22) |
2635
        (limit_in_pages << 23) |
2636
        (useable << 20) |
2637
        (lm << 21) |
2638
        0x7000;
2639

    
2640
    /* Install the new entry ...  */
2641
install:
2642
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2643
    lp[0] = tswap32(entry_1);
2644
    lp[1] = tswap32(entry_2);
2645
    return 0;
2646
}
2647

    
2648
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2649
{
2650
    struct target_modify_ldt_ldt_s *target_ldt_info;
2651
    uint64_t *gdt_table = g2h(env->gdt.base);
2652
    uint32_t base_addr, limit, flags;
2653
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2654
    int seg_not_present, useable, lm;
2655
    uint32_t *lp, entry_1, entry_2;
2656

    
2657
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2658
    if (!target_ldt_info)
2659
        return -TARGET_EFAULT;
2660
    idx = tswap32(target_ldt_info->entry_number);
2661
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2662
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
2663
        unlock_user_struct(target_ldt_info, ptr, 1);
2664
        return -TARGET_EINVAL;
2665
    }
2666
    lp = (uint32_t *)(gdt_table + idx);
2667
    entry_1 = tswap32(lp[0]);
2668
    entry_2 = tswap32(lp[1]);
2669
    
2670
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2671
    contents = (entry_2 >> 10) & 3;
2672
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2673
    seg_32bit = (entry_2 >> 22) & 1;
2674
    limit_in_pages = (entry_2 >> 23) & 1;
2675
    useable = (entry_2 >> 20) & 1;
2676
#ifdef TARGET_ABI32
2677
    lm = 0;
2678
#else
2679
    lm = (entry_2 >> 21) & 1;
2680
#endif
2681
    flags = (seg_32bit << 0) | (contents << 1) |
2682
        (read_exec_only << 3) | (limit_in_pages << 4) |
2683
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
2684
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
2685
    base_addr = (entry_1 >> 16) | 
2686
        (entry_2 & 0xff000000) | 
2687
        ((entry_2 & 0xff) << 16);
2688
    target_ldt_info->base_addr = tswapl(base_addr);
2689
    target_ldt_info->limit = tswap32(limit);
2690
    target_ldt_info->flags = tswap32(flags);
2691
    unlock_user_struct(target_ldt_info, ptr, 1);
2692
    return 0;
2693
}
2694
#endif /* TARGET_I386 && TARGET_ABI32 */
2695

    
2696
#ifndef TARGET_ABI32
2697
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2698
{
2699
    abi_long ret;
2700
    abi_ulong val;
2701
    int idx;
2702
    
2703
    switch(code) {
2704
    case TARGET_ARCH_SET_GS:
2705
    case TARGET_ARCH_SET_FS:
2706
        if (code == TARGET_ARCH_SET_GS)
2707
            idx = R_GS;
2708
        else
2709
            idx = R_FS;
2710
        cpu_x86_load_seg(env, idx, 0);
2711
        env->segs[idx].base = addr;
2712
        break;
2713
    case TARGET_ARCH_GET_GS:
2714
    case TARGET_ARCH_GET_FS:
2715
        if (code == TARGET_ARCH_GET_GS)
2716
            idx = R_GS;
2717
        else
2718
            idx = R_FS;
2719
        val = env->segs[idx].base;
2720
        if (put_user(val, addr, abi_ulong))
2721
            return -TARGET_EFAULT;
2722
        break;
2723
    default:
2724
        ret = -TARGET_EINVAL;
2725
        break;
2726
    }
2727
    return 0;
2728
}
2729
#endif
2730

    
2731
#endif /* defined(TARGET_I386) */
2732

    
2733
#if defined(USE_NPTL)
2734

    
2735
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2736

    
2737
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2738
typedef struct {
2739
    CPUState *env;
2740
    pthread_mutex_t mutex;
2741
    pthread_cond_t cond;
2742
    pthread_t thread;
2743
    uint32_t tid;
2744
    abi_ulong child_tidptr;
2745
    abi_ulong parent_tidptr;
2746
    sigset_t sigmask;
2747
} new_thread_info;
2748

    
2749
static void *clone_func(void *arg)
2750
{
2751
    new_thread_info *info = arg;
2752
    CPUState *env;
2753

    
2754
    env = info->env;
2755
    thread_env = env;
2756
    info->tid = gettid();
2757
    if (info->child_tidptr)
2758
        put_user_u32(info->tid, info->child_tidptr);
2759
    if (info->parent_tidptr)
2760
        put_user_u32(info->tid, info->parent_tidptr);
2761
    /* Enable signals.  */
2762
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2763
    /* Signal to the parent that we're ready.  */
2764
    pthread_mutex_lock(&info->mutex);
2765
    pthread_cond_broadcast(&info->cond);
2766
    pthread_mutex_unlock(&info->mutex);
2767
    /* Wait until the parent has finshed initializing the tls state.  */
2768
    pthread_mutex_lock(&clone_lock);
2769
    pthread_mutex_unlock(&clone_lock);
2770
    cpu_loop(env);
2771
    /* never exits */
2772
    return NULL;
2773
}
2774
#else
2775
/* this stack is the equivalent of the kernel stack associated with a
2776
   thread/process */
2777
#define NEW_STACK_SIZE 8192
2778

    
2779
static int clone_func(void *arg)
2780
{
2781
    CPUState *env = arg;
2782
    cpu_loop(env);
2783
    /* never exits */
2784
    return 0;
2785
}
2786
#endif
2787

    
2788
/* do_fork() Must return host values and target errnos (unlike most
2789
   do_*() functions). */
2790
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2791
                   abi_ulong parent_tidptr, target_ulong newtls,
2792
                   abi_ulong child_tidptr)
2793
{
2794
    int ret;
2795
    TaskState *ts;
2796
    uint8_t *new_stack;
2797
    CPUState *new_env;
2798
#if defined(USE_NPTL)
2799
    unsigned int nptl_flags;
2800
    sigset_t sigmask;
2801
#endif
2802

    
2803
    if (flags & CLONE_VM) {
2804
#if defined(USE_NPTL)
2805
        new_thread_info info;
2806
        pthread_attr_t attr;
2807
#endif
2808
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2809
        init_task_state(ts);
2810
        new_stack = ts->stack;
2811
        /* we create a new CPU instance. */
2812
        new_env = cpu_copy(env);
2813
        /* Init regs that differ from the parent.  */
2814
        cpu_clone_regs(new_env, newsp);
2815
        new_env->opaque = ts;
2816
#if defined(USE_NPTL)
2817
        nptl_flags = flags;
2818
        flags &= ~CLONE_NPTL_FLAGS2;
2819

    
2820
        /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2821
        if (nptl_flags & CLONE_SETTLS)
2822
            cpu_set_tls (new_env, newtls);
2823

    
2824
        /* Grab a mutex so that thread setup appears atomic.  */
2825
        pthread_mutex_lock(&clone_lock);
2826

    
2827
        memset(&info, 0, sizeof(info));
2828
        pthread_mutex_init(&info.mutex, NULL);
2829
        pthread_mutex_lock(&info.mutex);
2830
        pthread_cond_init(&info.cond, NULL);
2831
        info.env = new_env;
2832
        if (nptl_flags & CLONE_CHILD_SETTID)
2833
            info.child_tidptr = child_tidptr;
2834
        if (nptl_flags & CLONE_PARENT_SETTID)
2835
            info.parent_tidptr = parent_tidptr;
2836

    
2837
        ret = pthread_attr_init(&attr);
2838
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2839
        /* It is not safe to deliver signals until the child has finished
2840
           initializing, so temporarily block all signals.  */
2841
        sigfillset(&sigmask);
2842
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2843

    
2844
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
2845

    
2846
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
2847
        pthread_attr_destroy(&attr);
2848
        if (ret == 0) {
2849
            /* Wait for the child to initialize.  */
2850
            pthread_cond_wait(&info.cond, &info.mutex);
2851
            ret = info.tid;
2852
            if (flags & CLONE_PARENT_SETTID)
2853
                put_user_u32(ret, parent_tidptr);
2854
        } else {
2855
            ret = -1;
2856
        }
2857
        pthread_mutex_unlock(&info.mutex);
2858
        pthread_cond_destroy(&info.cond);
2859
        pthread_mutex_destroy(&info.mutex);
2860
        pthread_mutex_unlock(&clone_lock);
2861
#else
2862
        if (flags & CLONE_NPTL_FLAGS2)
2863
            return -EINVAL;
2864
        /* This is probably going to die very quickly, but do it anyway.  */
2865
#ifdef __ia64__
2866
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2867
#else
2868
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2869
#endif
2870
#endif
2871
    } else {
2872
        /* if no CLONE_VM, we consider it is a fork */
2873
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
2874
            return -EINVAL;
2875
        fork_start();
2876
        ret = fork();
2877
#if defined(USE_NPTL)
2878
        /* There is a race condition here.  The parent process could
2879
           theoretically read the TID in the child process before the child
2880
           tid is set.  This would require using either ptrace
2881
           (not implemented) or having *_tidptr to point at a shared memory
2882
           mapping.  We can't repeat the spinlock hack used above because
2883
           the child process gets its own copy of the lock.  */
2884
        if (ret == 0) {
2885
            cpu_clone_regs(env, newsp);
2886
            fork_end(1);
2887
            /* Child Process.  */
2888
            if (flags & CLONE_CHILD_SETTID)
2889
                put_user_u32(gettid(), child_tidptr);
2890
            if (flags & CLONE_PARENT_SETTID)
2891
                put_user_u32(gettid(), parent_tidptr);
2892
            ts = (TaskState *)env->opaque;
2893
            if (flags & CLONE_SETTLS)
2894
                cpu_set_tls (env, newtls);
2895
            /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2896
        } else {
2897
            fork_end(0);
2898
        }
2899
#else
2900
        if (ret == 0) {
2901
            cpu_clone_regs(env, newsp);
2902
        }
2903
#endif
2904
    }
2905
    return ret;
2906
}
2907

    
2908
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2909
{
2910
    struct flock fl;
2911
    struct target_flock *target_fl;
2912
    struct flock64 fl64;
2913
    struct target_flock64 *target_fl64;
2914
    abi_long ret;
2915

    
2916
    switch(cmd) {
2917
    case TARGET_F_GETLK:
2918
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2919
            return -TARGET_EFAULT;
2920
        fl.l_type = tswap16(target_fl->l_type);
2921
        fl.l_whence = tswap16(target_fl->l_whence);
2922
        fl.l_start = tswapl(target_fl->l_start);
2923
        fl.l_len = tswapl(target_fl->l_len);
2924
        fl.l_pid = tswapl(target_fl->l_pid);
2925
        unlock_user_struct(target_fl, arg, 0);
2926
        ret = get_errno(fcntl(fd, cmd, &fl));
2927
        if (ret == 0) {
2928
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
2929
                return -TARGET_EFAULT;
2930
            target_fl->l_type = tswap16(fl.l_type);
2931
            target_fl->l_whence = tswap16(fl.l_whence);
2932
            target_fl->l_start = tswapl(fl.l_start);
2933
            target_fl->l_len = tswapl(fl.l_len);
2934
            target_fl->l_pid = tswapl(fl.l_pid);
2935
            unlock_user_struct(target_fl, arg, 1);
2936
        }
2937
        break;
2938

    
2939
    case TARGET_F_SETLK:
2940
    case TARGET_F_SETLKW:
2941
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2942
            return -TARGET_EFAULT;
2943
        fl.l_type = tswap16(target_fl->l_type);
2944
        fl.l_whence = tswap16(target_fl->l_whence);
2945
        fl.l_start = tswapl(target_fl->l_start);
2946
        fl.l_len = tswapl(target_fl->l_len);
2947
        fl.l_pid = tswapl(target_fl->l_pid);
2948
        unlock_user_struct(target_fl, arg, 0);
2949
        ret = get_errno(fcntl(fd, cmd, &fl));
2950
        break;
2951

    
2952
    case TARGET_F_GETLK64:
2953
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2954
            return -TARGET_EFAULT;
2955
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2956
        fl64.l_whence = tswap16(target_fl64->l_whence);
2957
        fl64.l_start = tswapl(target_fl64->l_start);
2958
        fl64.l_len = tswapl(target_fl64->l_len);
2959
        fl64.l_pid = tswap16(target_fl64->l_pid);
2960
        unlock_user_struct(target_fl64, arg, 0);
2961
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2962
        if (ret == 0) {
2963
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
2964
                return -TARGET_EFAULT;
2965
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
2966
            target_fl64->l_whence = tswap16(fl64.l_whence);
2967
            target_fl64->l_start = tswapl(fl64.l_start);
2968
            target_fl64->l_len = tswapl(fl64.l_len);
2969
            target_fl64->l_pid = tswapl(fl64.l_pid);
2970
            unlock_user_struct(target_fl64, arg, 1);
2971
        }
2972
        break;
2973
    case TARGET_F_SETLK64:
2974
    case TARGET_F_SETLKW64:
2975
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2976
            return -TARGET_EFAULT;
2977
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2978
        fl64.l_whence = tswap16(target_fl64->l_whence);
2979
        fl64.l_start = tswapl(target_fl64->l_start);
2980
        fl64.l_len = tswapl(target_fl64->l_len);
2981
        fl64.l_pid = tswap16(target_fl64->l_pid);
2982
        unlock_user_struct(target_fl64, arg, 0);
2983
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2984
        break;
2985

    
2986
    case F_GETFL:
2987
        ret = get_errno(fcntl(fd, cmd, arg));
2988
        if (ret >= 0) {
2989
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
2990
        }
2991
        break;
2992

    
2993
    case F_SETFL:
2994
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
2995
        break;
2996

    
2997
    default:
2998
        ret = get_errno(fcntl(fd, cmd, arg));
2999
        break;
3000
    }
3001
    return ret;
3002
}
3003

    
3004
#ifdef USE_UID16
3005

    
3006
static inline int high2lowuid(int uid)
3007
{
3008
    if (uid > 65535)
3009
        return 65534;
3010
    else
3011
        return uid;
3012
}
3013

    
3014
static inline int high2lowgid(int gid)
3015
{
3016
    if (gid > 65535)
3017
        return 65534;
3018
    else
3019
        return gid;
3020
}
3021

    
3022
static inline int low2highuid(int uid)
3023
{
3024
    if ((int16_t)uid == -1)
3025
        return -1;
3026
    else
3027
        return uid;
3028
}
3029

    
3030
static inline int low2highgid(int gid)
3031
{
3032
    if ((int16_t)gid == -1)
3033
        return -1;
3034
    else
3035
        return gid;
3036
}
3037

    
3038
#endif /* USE_UID16 */
3039

    
3040
void syscall_init(void)
3041
{
3042
    IOCTLEntry *ie;
3043
    const argtype *arg_type;
3044
    int size;
3045
    int i;
3046

    
3047
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3048
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3049
#include "syscall_types.h"
3050
#undef STRUCT
3051
#undef STRUCT_SPECIAL
3052

    
3053
    /* we patch the ioctl size if necessary. We rely on the fact that
3054
       no ioctl has all the bits at '1' in the size field */
3055
    ie = ioctl_entries;
3056
    while (ie->target_cmd != 0) {
3057
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3058
            TARGET_IOC_SIZEMASK) {
3059
            arg_type = ie->arg_type;
3060
            if (arg_type[0] != TYPE_PTR) {
3061
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3062
                        ie->target_cmd);
3063
                exit(1);
3064
            }
3065
            arg_type++;
3066
            size = thunk_type_size(arg_type, 0);
3067
            ie->target_cmd = (ie->target_cmd &
3068
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3069
                (size << TARGET_IOC_SIZESHIFT);
3070
        }
3071

    
3072
        /* Build target_to_host_errno_table[] table from
3073
         * host_to_target_errno_table[]. */
3074
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3075
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3076

    
3077
        /* automatic consistency check if same arch */
3078
#if defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)
3079
        if (ie->target_cmd != ie->host_cmd) {
3080
            fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",
3081
                    ie->target_cmd, ie->host_cmd);
3082
        }
3083
#endif
3084
        ie++;
3085
    }
3086
}
3087

    
3088
#if TARGET_ABI_BITS == 32
3089
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3090
{
3091
#ifdef TARGET_WORDS_BIGENDIAN
3092
    return ((uint64_t)word0 << 32) | word1;
3093
#else
3094
    return ((uint64_t)word1 << 32) | word0;
3095
#endif
3096
}
3097
#else /* TARGET_ABI_BITS == 32 */
3098
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3099
{
3100
    return word0;
3101
}
3102
#endif /* TARGET_ABI_BITS != 32 */
3103

    
3104
#ifdef TARGET_NR_truncate64
3105
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3106
                                         abi_long arg2,
3107
                                         abi_long arg3,
3108
                                         abi_long arg4)
3109
{
3110
#ifdef TARGET_ARM
3111
    if (((CPUARMState *)cpu_env)->eabi)
3112
      {
3113
        arg2 = arg3;
3114
        arg3 = arg4;
3115
      }
3116
#endif
3117
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3118
}
3119
#endif
3120

    
3121
#ifdef TARGET_NR_ftruncate64
3122
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3123
                                          abi_long arg2,
3124
                                          abi_long arg3,
3125
                                          abi_long arg4)
3126
{
3127
#ifdef TARGET_ARM
3128
    if (((CPUARMState *)cpu_env)->eabi)
3129
      {
3130
        arg2 = arg3;
3131
        arg3 = arg4;
3132
      }
3133
#endif
3134
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3135
}
3136
#endif
3137

    
3138
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3139
                                               abi_ulong target_addr)
3140
{
3141
    struct target_timespec *target_ts;
3142

    
3143
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3144
        return -TARGET_EFAULT;
3145
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3146
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3147
    unlock_user_struct(target_ts, target_addr, 0);
3148
    return 0;
3149
}
3150

    
3151
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3152
                                               struct timespec *host_ts)
3153
{
3154
    struct target_timespec *target_ts;
3155

    
3156
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3157
        return -TARGET_EFAULT;
3158
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3159
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3160
    unlock_user_struct(target_ts, target_addr, 1);
3161
    return 0;
3162
}
3163

    
3164
#ifdef TARGET_NR_stat64
3165
static inline abi_long host_to_target_stat64(void *cpu_env,
3166
                                             abi_ulong target_addr,
3167
                                             struct stat *host_st)
3168
{
3169
#ifdef TARGET_ARM
3170
    if (((CPUARMState *)cpu_env)->eabi) {
3171
        struct target_eabi_stat64 *target_st;
3172

    
3173
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3174
            return -TARGET_EFAULT;
3175
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3176
        __put_user(host_st->st_dev, &target_st->st_dev);
3177
        __put_user(host_st->st_ino, &target_st->st_ino);
3178
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3179
        __put_user(host_st->st_ino, &target_st->__st_ino);
3180
#endif
3181
        __put_user(host_st->st_mode, &target_st->st_mode);
3182
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3183
        __put_user(host_st->st_uid, &target_st->st_uid);
3184
        __put_user(host_st->st_gid, &target_st->st_gid);
3185
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3186
        __put_user(host_st->st_size, &target_st->st_size);
3187
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3188
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3189
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3190
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3191
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3192
        unlock_user_struct(target_st, target_addr, 1);
3193
    } else
3194
#endif
3195
    {
3196
        struct target_stat64 *target_st;
3197

    
3198
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3199
            return -TARGET_EFAULT;
3200
        memset(target_st, 0, sizeof(struct target_stat64));
3201
        __put_user(host_st->st_dev, &target_st->st_dev);
3202
        __put_user(host_st->st_ino, &target_st->st_ino);
3203
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3204
        __put_user(host_st->st_ino, &target_st->__st_ino);
3205
#endif
3206
        __put_user(host_st->st_mode, &target_st->st_mode);
3207
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3208
        __put_user(host_st->st_uid, &target_st->st_uid);
3209
        __put_user(host_st->st_gid, &target_st->st_gid);
3210
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3211
        /* XXX: better use of kernel struct */
3212
        __put_user(host_st->st_size, &target_st->st_size);
3213
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3214
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3215
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3216
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3217
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3218
        unlock_user_struct(target_st, target_addr, 1);
3219
    }
3220

    
3221
    return 0;
3222
}
3223
#endif
3224

    
3225
#if defined(USE_NPTL)
3226
/* ??? Using host futex calls even when target atomic operations
3227
   are not really atomic probably breaks things.  However implementing
3228
   futexes locally would make futexes shared between multiple processes
3229
   tricky.  However they're probably useless because guest atomic
3230
   operations won't work either.  */
3231
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3232
                    target_ulong uaddr2, int val3)
3233
{
3234
    struct timespec ts, *pts;
3235

    
3236
    /* ??? We assume FUTEX_* constants are the same on both host
3237
       and target.  */
3238
    switch (op) {
3239
    case FUTEX_WAIT:
3240
        if (timeout) {
3241
            pts = &ts;
3242
            target_to_host_timespec(pts, timeout);
3243
        } else {
3244
            pts = NULL;
3245
        }
3246
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3247
                         pts, NULL, 0));
3248
    case FUTEX_WAKE:
3249
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3250
    case FUTEX_FD:
3251
        return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3252
    case FUTEX_REQUEUE:
3253
        return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3254
                         NULL, g2h(uaddr2), 0));
3255
    case FUTEX_CMP_REQUEUE:
3256
        return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3257
                         NULL, g2h(uaddr2), tswap32(val3)));
3258
    default:
3259
        return -TARGET_ENOSYS;
3260
    }
3261
}
3262
#endif
3263

    
3264
int get_osversion(void)
3265
{
3266
    static int osversion;
3267
    struct new_utsname buf;
3268
    const char *s;
3269
    int i, n, tmp;
3270
    if (osversion)
3271
        return osversion;
3272
    if (qemu_uname_release && *qemu_uname_release) {
3273
        s = qemu_uname_release;
3274
    } else {
3275
        if (sys_uname(&buf))
3276
            return 0;
3277
        s = buf.release;
3278
    }
3279
    tmp = 0;
3280
    for (i = 0; i < 3; i++) {
3281
        n = 0;
3282
        while (*s >= '0' && *s <= '9') {
3283
            n *= 10;
3284
            n += *s - '0';
3285
            s++;
3286
        }
3287
        tmp = (tmp << 8) + n;
3288
        if (*s == '.')
3289
            s++;
3290
    }
3291
    osversion = tmp;
3292
    return osversion;
3293
}
3294

    
3295
/* do_syscall() should always have a single exit point at the end so
3296
   that actions, such as logging of syscall results, can be performed.
3297
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3298
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3299
                    abi_long arg2, abi_long arg3, abi_long arg4,
3300
                    abi_long arg5, abi_long arg6)
3301
{
3302
    abi_long ret;
3303
    struct stat st;
3304
    struct statfs stfs;
3305
    void *p;
3306

    
3307
#ifdef DEBUG
3308
    gemu_log("syscall %d", num);
3309
#endif
3310
    if(do_strace)
3311
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3312

    
3313
    switch(num) {
3314
    case TARGET_NR_exit:
3315
#ifdef HAVE_GPROF
3316
        _mcleanup();
3317
#endif
3318
        gdb_exit(cpu_env, arg1);
3319
        /* XXX: should free thread stack and CPU env */
3320
        _exit(arg1);
3321
        ret = 0; /* avoid warning */
3322
        break;
3323
    case TARGET_NR_read:
3324
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3325
            goto efault;
3326
        ret = get_errno(read(arg1, p, arg3));
3327
        unlock_user(p, arg2, ret);
3328
        break;
3329
    case TARGET_NR_write:
3330
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3331
            goto efault;
3332
        ret = get_errno(write(arg1, p, arg3));
3333
        unlock_user(p, arg2, 0);
3334
        break;
3335
    case TARGET_NR_open:
3336
        if (!(p = lock_user_string(arg1)))
3337
            goto efault;
3338
        ret = get_errno(open(path(p),
3339
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
3340
                             arg3));
3341
        unlock_user(p, arg1, 0);
3342
        break;
3343
#if defined(TARGET_NR_openat) && defined(__NR_openat)
3344
    case TARGET_NR_openat:
3345
        if (!(p = lock_user_string(arg2)))
3346
            goto efault;
3347
        ret = get_errno(sys_openat(arg1,
3348
                                   path(p),
3349
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
3350
                                   arg4));
3351
        unlock_user(p, arg2, 0);
3352
        break;
3353
#endif
3354
    case TARGET_NR_close:
3355
        ret = get_errno(close(arg1));
3356
        break;
3357
    case TARGET_NR_brk:
3358
        ret = do_brk(arg1);
3359
        break;
3360
    case TARGET_NR_fork:
3361
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3362
        break;
3363
#ifdef TARGET_NR_waitpid
3364
    case TARGET_NR_waitpid:
3365
        {
3366
            int status;
3367
            ret = get_errno(waitpid(arg1, &status, arg3));
3368
            if (!is_error(ret) && arg2
3369
                && put_user_s32(status, arg2))
3370
                goto efault;
3371
        }
3372
        break;
3373
#endif
3374
#ifdef TARGET_NR_waitid
3375
    case TARGET_NR_waitid:
3376
        {
3377
            siginfo_t info;
3378
            info.si_pid = 0;
3379
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
3380
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
3381
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3382
                    goto efault;
3383
                host_to_target_siginfo(p, &info);
3384
                unlock_user(p, arg3, sizeof(target_siginfo_t));
3385
            }
3386
        }
3387
        break;
3388
#endif
3389
#ifdef TARGET_NR_creat /* not on alpha */
3390
    case TARGET_NR_creat:
3391
        if (!(p = lock_user_string(arg1)))
3392
            goto efault;
3393
        ret = get_errno(creat(p, arg2));
3394
        unlock_user(p, arg1, 0);
3395
        break;
3396
#endif
3397
    case TARGET_NR_link:
3398
        {
3399
            void * p2;
3400
            p = lock_user_string(arg1);
3401
            p2 = lock_user_string(arg2);
3402
            if (!p || !p2)
3403
                ret = -TARGET_EFAULT;
3404
            else
3405
                ret = get_errno(link(p, p2));
3406
            unlock_user(p2, arg2, 0);
3407
            unlock_user(p, arg1, 0);
3408
        }
3409
        break;
3410
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3411
    case TARGET_NR_linkat:
3412
        {
3413
            void * p2 = NULL;
3414
            if (!arg2 || !arg4)
3415
                goto efault;
3416
            p  = lock_user_string(arg2);
3417
            p2 = lock_user_string(arg4);
3418
            if (!p || !p2)
3419
                ret = -TARGET_EFAULT;
3420
            else
3421
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3422
            unlock_user(p, arg2, 0);
3423
            unlock_user(p2, arg4, 0);
3424
        }
3425
        break;
3426
#endif
3427
    case TARGET_NR_unlink:
3428
        if (!(p = lock_user_string(arg1)))
3429
            goto efault;
3430
        ret = get_errno(unlink(p));
3431
        unlock_user(p, arg1, 0);
3432
        break;
3433
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3434
    case TARGET_NR_unlinkat:
3435
        if (!(p = lock_user_string(arg2)))
3436
            goto efault;
3437
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
3438
        unlock_user(p, arg2, 0);
3439
        break;
3440
#endif
3441
    case TARGET_NR_execve:
3442
        {
3443
            char **argp, **envp;
3444
            int argc, envc;
3445
            abi_ulong gp;
3446
            abi_ulong guest_argp;
3447
            abi_ulong guest_envp;
3448
            abi_ulong addr;
3449
            char **q;
3450

    
3451
            argc = 0;
3452
            guest_argp = arg2;
3453
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3454
                if (get_user_ual(addr, gp))
3455
                    goto efault;
3456
                if (!addr)
3457
                    break;
3458
                argc++;
3459
            }
3460
            envc = 0;
3461
            guest_envp = arg3;
3462
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3463
                if (get_user_ual(addr, gp))
3464
                    goto efault;
3465
                if (!addr)
3466
                    break;
3467
                envc++;
3468
            }
3469

    
3470
            argp = alloca((argc + 1) * sizeof(void *));
3471
            envp = alloca((envc + 1) * sizeof(void *));
3472

    
3473
            for (gp = guest_argp, q = argp; gp;
3474
                  gp += sizeof(abi_ulong), q++) {
3475
                if (get_user_ual(addr, gp))
3476
                    goto execve_efault;
3477
                if (!addr)
3478
                    break;
3479
                if (!(*q = lock_user_string(addr)))
3480
                    goto execve_efault;
3481
            }
3482
            *q = NULL;
3483

    
3484
            for (gp = guest_envp, q = envp; gp;
3485
                  gp += sizeof(abi_ulong), q++) {
3486
                if (get_user_ual(addr, gp))
3487
                    goto execve_efault;
3488
                if (!addr)
3489
                    break;
3490
                if (!(*q = lock_user_string(addr)))
3491
                    goto execve_efault;
3492
            }
3493
            *q = NULL;
3494

    
3495
            if (!(p = lock_user_string(arg1)))
3496
                goto execve_efault;
3497
            ret = get_errno(execve(p, argp, envp));
3498
            unlock_user(p, arg1, 0);
3499

    
3500
            goto execve_end;
3501

    
3502
        execve_efault:
3503
            ret = -TARGET_EFAULT;
3504

    
3505
        execve_end:
3506
            for (gp = guest_argp, q = argp; *q;
3507
                  gp += sizeof(abi_ulong), q++) {
3508
                if (get_user_ual(addr, gp)
3509
                    || !addr)
3510
                    break;
3511
                unlock_user(*q, addr, 0);
3512
            }
3513
            for (gp = guest_envp, q = envp; *q;
3514
                  gp += sizeof(abi_ulong), q++) {
3515
                if (get_user_ual(addr, gp)
3516
                    || !addr)
3517
                    break;
3518
                unlock_user(*q, addr, 0);
3519
            }
3520
        }
3521
        break;
3522
    case TARGET_NR_chdir:
3523
        if (!(p = lock_user_string(arg1)))
3524
            goto efault;
3525
        ret = get_errno(chdir(p));
3526
        unlock_user(p, arg1, 0);
3527
        break;
3528
#ifdef TARGET_NR_time
3529
    case TARGET_NR_time:
3530
        {
3531
            time_t host_time;
3532
            ret = get_errno(time(&host_time));
3533
            if (!is_error(ret)
3534
                && arg1
3535
                && put_user_sal(host_time, arg1))
3536
                goto efault;
3537
        }
3538
        break;
3539
#endif
3540
    case TARGET_NR_mknod:
3541
        if (!(p = lock_user_string(arg1)))
3542
            goto efault;
3543
        ret = get_errno(mknod(p, arg2, arg3));
3544
        unlock_user(p, arg1, 0);
3545
        break;
3546
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3547
    case TARGET_NR_mknodat:
3548
        if (!(p = lock_user_string(arg2)))
3549
            goto efault;
3550
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3551
        unlock_user(p, arg2, 0);
3552
        break;
3553
#endif
3554
    case TARGET_NR_chmod:
3555
        if (!(p = lock_user_string(arg1)))
3556
            goto efault;
3557
        ret = get_errno(chmod(p, arg2));
3558
        unlock_user(p, arg1, 0);
3559
        break;
3560
#ifdef TARGET_NR_break
3561
    case TARGET_NR_break:
3562
        goto unimplemented;
3563
#endif
3564
#ifdef TARGET_NR_oldstat
3565
    case TARGET_NR_oldstat:
3566
        goto unimplemented;
3567
#endif
3568
    case TARGET_NR_lseek:
3569
        ret = get_errno(lseek(arg1, arg2, arg3));
3570
        break;
3571
#ifdef TARGET_NR_getxpid
3572
    case TARGET_NR_getxpid:
3573
#else
3574
    case TARGET_NR_getpid:
3575
#endif
3576
        ret = get_errno(getpid());
3577
        break;
3578
    case TARGET_NR_mount:
3579
                {
3580
                        /* need to look at the data field */
3581
                        void *p2, *p3;
3582
                        p = lock_user_string(arg1);
3583
                        p2 = lock_user_string(arg2);
3584
                        p3 = lock_user_string(arg3);
3585
                        if (!p || !p2 || !p3)
3586
                            ret = -TARGET_EFAULT;
3587
                        else
3588
                            /* FIXME - arg5 should be locked, but it isn't clear how to
3589
                             * do that since it's not guaranteed to be a NULL-terminated
3590
                             * string.
3591
                             */
3592
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3593
                        unlock_user(p, arg1, 0);
3594
                        unlock_user(p2, arg2, 0);
3595
                        unlock_user(p3, arg3, 0);
3596
                        break;
3597
                }
3598
#ifdef TARGET_NR_umount
3599
    case TARGET_NR_umount:
3600
        if (!(p = lock_user_string(arg1)))
3601
            goto efault;
3602
        ret = get_errno(umount(p));
3603
        unlock_user(p, arg1, 0);
3604
        break;
3605
#endif
3606
#ifdef TARGET_NR_stime /* not on alpha */
3607
    case TARGET_NR_stime:
3608
        {
3609
            time_t host_time;
3610
            if (get_user_sal(host_time, arg1))
3611
                goto efault;
3612
            ret = get_errno(stime(&host_time));
3613
        }
3614
        break;
3615
#endif
3616
    case TARGET_NR_ptrace:
3617
        goto unimplemented;
3618
#ifdef TARGET_NR_alarm /* not on alpha */
3619
    case TARGET_NR_alarm:
3620
        ret = alarm(arg1);
3621
        break;
3622
#endif
3623
#ifdef TARGET_NR_oldfstat
3624
    case TARGET_NR_oldfstat:
3625
        goto unimplemented;
3626
#endif
3627
#ifdef TARGET_NR_pause /* not on alpha */
3628
    case TARGET_NR_pause:
3629
        ret = get_errno(pause());
3630
        break;
3631
#endif
3632
#ifdef TARGET_NR_utime
3633
    case TARGET_NR_utime:
3634
        {
3635
            struct utimbuf tbuf, *host_tbuf;
3636
            struct target_utimbuf *target_tbuf;
3637
            if (arg2) {
3638
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3639
                    goto efault;
3640
                tbuf.actime = tswapl(target_tbuf->actime);
3641
                tbuf.modtime = tswapl(target_tbuf->modtime);
3642
                unlock_user_struct(target_tbuf, arg2, 0);
3643
                host_tbuf = &tbuf;
3644
            } else {
3645
                host_tbuf = NULL;
3646
            }
3647
            if (!(p = lock_user_string(arg1)))
3648
                goto efault;
3649
            ret = get_errno(utime(p, host_tbuf));
3650
            unlock_user(p, arg1, 0);
3651
        }
3652
        break;
3653
#endif
3654
    case TARGET_NR_utimes:
3655
        {
3656
            struct timeval *tvp, tv[2];
3657
            if (arg2) {
3658
                if (copy_from_user_timeval(&tv[0], arg2)
3659
                    || copy_from_user_timeval(&tv[1],
3660
                                              arg2 + sizeof(struct target_timeval)))
3661
                    goto efault;
3662
                tvp = tv;
3663
            } else {
3664
                tvp = NULL;
3665
            }
3666
            if (!(p = lock_user_string(arg1)))
3667
                goto efault;
3668
            ret = get_errno(utimes(p, tvp));
3669
            unlock_user(p, arg1, 0);
3670
        }
3671
        break;
3672
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
3673
    case TARGET_NR_futimesat:
3674
        {
3675
            struct timeval *tvp, tv[2];
3676
            if (arg3) {
3677
                if (copy_from_user_timeval(&tv[0], arg3)
3678
                    || copy_from_user_timeval(&tv[1],
3679
                                              arg3 + sizeof(struct target_timeval)))
3680
                    goto efault;
3681
                tvp = tv;
3682
            } else {
3683
                tvp = NULL;
3684
            }
3685
            if (!(p = lock_user_string(arg2)))
3686
                goto efault;
3687
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
3688
            unlock_user(p, arg2, 0);
3689
        }
3690
        break;
3691
#endif
3692
#ifdef TARGET_NR_stty
3693
    case TARGET_NR_stty:
3694
        goto unimplemented;
3695
#endif
3696
#ifdef TARGET_NR_gtty
3697
    case TARGET_NR_gtty:
3698
        goto unimplemented;
3699
#endif
3700
    case TARGET_NR_access:
3701
        if (!(p = lock_user_string(arg1)))
3702
            goto efault;
3703
        ret = get_errno(access(p, arg2));
3704
        unlock_user(p, arg1, 0);
3705
        break;
3706
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3707
    case TARGET_NR_faccessat:
3708
        if (!(p = lock_user_string(arg2)))
3709
            goto efault;
3710
        ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3711
        unlock_user(p, arg2, 0);
3712
        break;
3713
#endif
3714
#ifdef TARGET_NR_nice /* not on alpha */
3715
    case TARGET_NR_nice:
3716
        ret = get_errno(nice(arg1));
3717
        break;
3718
#endif
3719
#ifdef TARGET_NR_ftime
3720
    case TARGET_NR_ftime:
3721
        goto unimplemented;
3722
#endif
3723
    case TARGET_NR_sync:
3724
        sync();
3725
        ret = 0;
3726
        break;
3727
    case TARGET_NR_kill:
3728
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3729
        break;
3730
    case TARGET_NR_rename:
3731
        {
3732
            void *p2;
3733
            p = lock_user_string(arg1);
3734
            p2 = lock_user_string(arg2);
3735
            if (!p || !p2)
3736
                ret = -TARGET_EFAULT;
3737
            else
3738
                ret = get_errno(rename(p, p2));
3739
            unlock_user(p2, arg2, 0);
3740
            unlock_user(p, arg1, 0);
3741
        }
3742
        break;
3743
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3744
    case TARGET_NR_renameat:
3745
        {
3746
            void *p2;
3747
            p  = lock_user_string(arg2);
3748
            p2 = lock_user_string(arg4);
3749
            if (!p || !p2)
3750
                ret = -TARGET_EFAULT;
3751
            else
3752
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3753
            unlock_user(p2, arg4, 0);
3754
            unlock_user(p, arg2, 0);
3755
        }
3756
        break;
3757
#endif
3758
    case TARGET_NR_mkdir:
3759
        if (!(p = lock_user_string(arg1)))
3760
            goto efault;
3761
        ret = get_errno(mkdir(p, arg2));
3762
        unlock_user(p, arg1, 0);
3763
        break;
3764
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3765
    case TARGET_NR_mkdirat:
3766
        if (!(p = lock_user_string(arg2)))
3767
            goto efault;
3768
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
3769
        unlock_user(p, arg2, 0);
3770
        break;
3771
#endif
3772
    case TARGET_NR_rmdir:
3773
        if (!(p = lock_user_string(arg1)))
3774
            goto efault;
3775
        ret = get_errno(rmdir(p));
3776
        unlock_user(p, arg1, 0);
3777
        break;
3778
    case TARGET_NR_dup:
3779
        ret = get_errno(dup(arg1));
3780
        break;
3781
    case TARGET_NR_pipe:
3782
        {
3783
            int host_pipe[2];
3784
            ret = get_errno(pipe(host_pipe));
3785
            if (!is_error(ret)) {
3786
#if defined(TARGET_MIPS)
3787
                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3788
                env->active_tc.gpr[3] = host_pipe[1];
3789
                ret = host_pipe[0];
3790
#elif defined(TARGET_SH4)
3791
                ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3792
                ret = host_pipe[0];
3793
#else
3794
                if (put_user_s32(host_pipe[0], arg1)
3795
                    || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3796
                    goto efault;
3797
#endif
3798
            }
3799
        }
3800
        break;
3801
    case TARGET_NR_times:
3802
        {
3803
            struct target_tms *tmsp;
3804
            struct tms tms;
3805
            ret = get_errno(times(&tms));
3806
            if (arg1) {
3807
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3808
                if (!tmsp)
3809
                    goto efault;
3810
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3811
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3812
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3813
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3814
            }
3815
            if (!is_error(ret))
3816
                ret = host_to_target_clock_t(ret);
3817
        }
3818
        break;
3819
#ifdef TARGET_NR_prof
3820
    case TARGET_NR_prof:
3821
        goto unimplemented;
3822
#endif
3823
#ifdef TARGET_NR_signal
3824
    case TARGET_NR_signal:
3825
        goto unimplemented;
3826
#endif
3827
    case TARGET_NR_acct:
3828
        if (!(p = lock_user_string(arg1)))
3829
            goto efault;
3830
        ret = get_errno(acct(path(p)));
3831
        unlock_user(p, arg1, 0);
3832
        break;
3833
#ifdef TARGET_NR_umount2 /* not on alpha */
3834
    case TARGET_NR_umount2:
3835
        if (!(p = lock_user_string(arg1)))
3836
            goto efault;
3837
        ret = get_errno(umount2(p, arg2));
3838
        unlock_user(p, arg1, 0);
3839
        break;
3840
#endif
3841
#ifdef TARGET_NR_lock
3842
    case TARGET_NR_lock:
3843
        goto unimplemented;
3844
#endif
3845
    case TARGET_NR_ioctl:
3846
        ret = do_ioctl(arg1, arg2, arg3);
3847
        break;
3848
    case TARGET_NR_fcntl:
3849
        ret = do_fcntl(arg1, arg2, arg3);
3850
        break;
3851
#ifdef TARGET_NR_mpx
3852
    case TARGET_NR_mpx:
3853
        goto unimplemented;
3854
#endif
3855
    case TARGET_NR_setpgid:
3856
        ret = get_errno(setpgid(arg1, arg2));
3857
        break;
3858
#ifdef TARGET_NR_ulimit
3859
    case TARGET_NR_ulimit:
3860
        goto unimplemented;
3861
#endif
3862
#ifdef TARGET_NR_oldolduname
3863
    case TARGET_NR_oldolduname:
3864
        goto unimplemented;
3865
#endif
3866
    case TARGET_NR_umask:
3867
        ret = get_errno(umask(arg1));
3868
        break;
3869
    case TARGET_NR_chroot:
3870
        if (!(p = lock_user_string(arg1)))
3871
            goto efault;
3872
        ret = get_errno(chroot(p));
3873
        unlock_user(p, arg1, 0);
3874
        break;
3875
    case TARGET_NR_ustat:
3876
        goto unimplemented;
3877
    case TARGET_NR_dup2:
3878
        ret = get_errno(dup2(arg1, arg2));
3879
        break;
3880
#ifdef TARGET_NR_getppid /* not on alpha */
3881
    case TARGET_NR_getppid:
3882
        ret = get_errno(getppid());
3883
        break;
3884
#endif
3885
    case TARGET_NR_getpgrp:
3886
        ret = get_errno(getpgrp());
3887
        break;
3888
    case TARGET_NR_setsid:
3889
        ret = get_errno(setsid());
3890
        break;
3891
#ifdef TARGET_NR_sigaction
3892
    case TARGET_NR_sigaction:
3893
        {
3894
#if !defined(TARGET_MIPS)
3895
            struct target_old_sigaction *old_act;
3896
            struct target_sigaction act, oact, *pact;
3897
            if (arg2) {
3898
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3899
                    goto efault;
3900
                act._sa_handler = old_act->_sa_handler;
3901
                target_siginitset(&act.sa_mask, old_act->sa_mask);
3902
                act.sa_flags = old_act->sa_flags;
3903
                act.sa_restorer = old_act->sa_restorer;
3904
                unlock_user_struct(old_act, arg2, 0);
3905
                pact = &act;
3906
            } else {
3907
                pact = NULL;
3908
            }
3909
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3910
            if (!is_error(ret) && arg3) {
3911
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3912
                    goto efault;
3913
                old_act->_sa_handler = oact._sa_handler;
3914
                old_act->sa_mask = oact.sa_mask.sig[0];
3915
                old_act->sa_flags = oact.sa_flags;
3916
                old_act->sa_restorer = oact.sa_restorer;
3917
                unlock_user_struct(old_act, arg3, 1);
3918
            }
3919
#else
3920
            struct target_sigaction act, oact, *pact, *old_act;
3921

    
3922
            if (arg2) {
3923
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3924
                    goto efault;
3925
                act._sa_handler = old_act->_sa_handler;
3926
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3927
                act.sa_flags = old_act->sa_flags;
3928
                unlock_user_struct(old_act, arg2, 0);
3929
                pact = &act;
3930
            } else {
3931
                pact = NULL;
3932
            }
3933

    
3934
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3935

    
3936
            if (!is_error(ret) && arg3) {
3937
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3938
                    goto efault;
3939
                old_act->_sa_handler = oact._sa_handler;
3940
                old_act->sa_flags = oact.sa_flags;
3941
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
3942
                old_act->sa_mask.sig[1] = 0;
3943
                old_act->sa_mask.sig[2] = 0;
3944
                old_act->sa_mask.sig[3] = 0;
3945
                unlock_user_struct(old_act, arg3, 1);
3946
            }
3947
#endif
3948
        }
3949
        break;
3950
#endif
3951
    case TARGET_NR_rt_sigaction:
3952
        {
3953
            struct target_sigaction *act;
3954
            struct target_sigaction *oact;
3955

    
3956
            if (arg2) {
3957
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
3958
                    goto efault;
3959
            } else
3960
                act = NULL;
3961
            if (arg3) {
3962
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
3963
                    ret = -TARGET_EFAULT;
3964
                    goto rt_sigaction_fail;
3965
                }
3966
            } else
3967
                oact = NULL;
3968
            ret = get_errno(do_sigaction(arg1, act, oact));
3969
        rt_sigaction_fail:
3970
            if (act)
3971
                unlock_user_struct(act, arg2, 0);
3972
            if (oact)
3973
                unlock_user_struct(oact, arg3, 1);
3974
        }
3975
        break;
3976
#ifdef TARGET_NR_sgetmask /* not on alpha */
3977
    case TARGET_NR_sgetmask:
3978
        {
3979
            sigset_t cur_set;
3980
            abi_ulong target_set;
3981
            sigprocmask(0, NULL, &cur_set);
3982
            host_to_target_old_sigset(&target_set, &cur_set);
3983
            ret = target_set;
3984
        }
3985
        break;
3986
#endif
3987
#ifdef TARGET_NR_ssetmask /* not on alpha */
3988
    case TARGET_NR_ssetmask:
3989
        {
3990
            sigset_t set, oset, cur_set;
3991
            abi_ulong target_set = arg1;
3992
            sigprocmask(0, NULL, &cur_set);
3993
            target_to_host_old_sigset(&set, &target_set);
3994
            sigorset(&set, &set, &cur_set);
3995
            sigprocmask(SIG_SETMASK, &set, &oset);
3996
            host_to_target_old_sigset(&target_set, &oset);
3997
            ret = target_set;
3998
        }
3999
        break;
4000
#endif
4001
#ifdef TARGET_NR_sigprocmask
4002
    case TARGET_NR_sigprocmask:
4003
        {
4004
            int how = arg1;
4005
            sigset_t set, oldset, *set_ptr;
4006

    
4007
            if (arg2) {
4008
                switch(how) {
4009
                case TARGET_SIG_BLOCK:
4010
                    how = SIG_BLOCK;
4011
                    break;
4012
                case TARGET_SIG_UNBLOCK:
4013
                    how = SIG_UNBLOCK;
4014
                    break;
4015
                case TARGET_SIG_SETMASK:
4016
                    how = SIG_SETMASK;
4017
                    break;
4018
                default:
4019
                    ret = -TARGET_EINVAL;
4020
                    goto fail;
4021
                }
4022
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4023
                    goto efault;
4024
                target_to_host_old_sigset(&set, p);
4025
                unlock_user(p, arg2, 0);
4026
                set_ptr = &set;
4027
            } else {
4028
                how = 0;
4029
                set_ptr = NULL;
4030
            }
4031
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4032
            if (!is_error(ret) && arg3) {
4033
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4034
                    goto efault;
4035
                host_to_target_old_sigset(p, &oldset);
4036
                unlock_user(p, arg3, sizeof(target_sigset_t));
4037
            }
4038
        }
4039
        break;
4040
#endif
4041
    case TARGET_NR_rt_sigprocmask:
4042
        {
4043
            int how = arg1;
4044
            sigset_t set, oldset, *set_ptr;
4045

    
4046
            if (arg2) {
4047
                switch(how) {
4048
                case TARGET_SIG_BLOCK:
4049
                    how = SIG_BLOCK;
4050
                    break;
4051
                case TARGET_SIG_UNBLOCK:
4052
                    how = SIG_UNBLOCK;
4053
                    break;
4054
                case TARGET_SIG_SETMASK:
4055
                    how = SIG_SETMASK;
4056
                    break;
4057
                default:
4058
                    ret = -TARGET_EINVAL;
4059
                    goto fail;
4060
                }
4061
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4062
                    goto efault;
4063
                target_to_host_sigset(&set, p);
4064
                unlock_user(p, arg2, 0);
4065
                set_ptr = &set;
4066
            } else {
4067
                how = 0;
4068
                set_ptr = NULL;
4069
            }
4070
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4071
            if (!is_error(ret) && arg3) {
4072
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4073
                    goto efault;
4074
                host_to_target_sigset(p, &oldset);
4075
                unlock_user(p, arg3, sizeof(target_sigset_t));
4076
            }
4077
        }
4078
        break;
4079
#ifdef TARGET_NR_sigpending
4080
    case TARGET_NR_sigpending:
4081
        {
4082
            sigset_t set;
4083
            ret = get_errno(sigpending(&set));
4084
            if (!is_error(ret)) {
4085
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4086
                    goto efault;
4087
                host_to_target_old_sigset(p, &set);
4088
                unlock_user(p, arg1, sizeof(target_sigset_t));
4089
            }
4090
        }
4091
        break;
4092
#endif
4093
    case TARGET_NR_rt_sigpending:
4094
        {
4095
            sigset_t set;
4096
            ret = get_errno(sigpending(&set));
4097
            if (!is_error(ret)) {
4098
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4099
                    goto efault;
4100
                host_to_target_sigset(p, &set);
4101
                unlock_user(p, arg1, sizeof(target_sigset_t));
4102
            }
4103
        }
4104
        break;
4105
#ifdef TARGET_NR_sigsuspend
4106
    case TARGET_NR_sigsuspend:
4107
        {
4108
            sigset_t set;
4109
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4110
                goto efault;
4111
            target_to_host_old_sigset(&set, p);
4112
            unlock_user(p, arg1, 0);
4113
            ret = get_errno(sigsuspend(&set));
4114
        }
4115
        break;
4116
#endif
4117
    case TARGET_NR_rt_sigsuspend:
4118
        {
4119
            sigset_t set;
4120
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4121
                goto efault;
4122
            target_to_host_sigset(&set, p);
4123
            unlock_user(p, arg1, 0);
4124
            ret = get_errno(sigsuspend(&set));
4125
        }
4126
        break;
4127
    case TARGET_NR_rt_sigtimedwait:
4128
        {
4129
            sigset_t set;
4130
            struct timespec uts, *puts;
4131
            siginfo_t uinfo;
4132

    
4133
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4134
                goto efault;
4135
            target_to_host_sigset(&set, p);
4136
            unlock_user(p, arg1, 0);
4137
            if (arg3) {
4138
                puts = &uts;
4139
                target_to_host_timespec(puts, arg3);
4140
            } else {
4141
                puts = NULL;
4142
            }
4143
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4144
            if (!is_error(ret) && arg2) {
4145
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4146
                    goto efault;
4147
                host_to_target_siginfo(p, &uinfo);
4148
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4149
            }
4150
        }
4151
        break;
4152
    case TARGET_NR_rt_sigqueueinfo:
4153
        {
4154
            siginfo_t uinfo;
4155
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4156
                goto efault;
4157
            target_to_host_siginfo(&uinfo, p);
4158
            unlock_user(p, arg1, 0);
4159
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4160
        }
4161
        break;
4162
#ifdef TARGET_NR_sigreturn
4163
    case TARGET_NR_sigreturn:
4164
        /* NOTE: ret is eax, so not transcoding must be done */
4165
        ret = do_sigreturn(cpu_env);
4166
        break;
4167
#endif
4168
    case TARGET_NR_rt_sigreturn:
4169
        /* NOTE: ret is eax, so not transcoding must be done */
4170
        ret = do_rt_sigreturn(cpu_env);
4171
        break;
4172
    case TARGET_NR_sethostname:
4173
        if (!(p = lock_user_string(arg1)))
4174
            goto efault;
4175
        ret = get_errno(sethostname(p, arg2));
4176
        unlock_user(p, arg1, 0);
4177
        break;
4178
    case TARGET_NR_setrlimit:
4179
        {
4180
            /* XXX: convert resource ? */
4181
            int resource = arg1;
4182
            struct target_rlimit *target_rlim;
4183
            struct rlimit rlim;
4184
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4185
                goto efault;
4186
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4187
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4188
            unlock_user_struct(target_rlim, arg2, 0);
4189
            ret = get_errno(setrlimit(resource, &rlim));
4190
        }
4191
        break;
4192
    case TARGET_NR_getrlimit:
4193
        {
4194
            /* XXX: convert resource ? */
4195
            int resource = arg1;
4196
            struct target_rlimit *target_rlim;
4197
            struct rlimit rlim;
4198

    
4199
            ret = get_errno(getrlimit(resource, &rlim));
4200
            if (!is_error(ret)) {
4201
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4202
                    goto efault;
4203
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4204
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4205
                unlock_user_struct(target_rlim, arg2, 1);
4206
            }
4207
        }
4208
        break;
4209
    case TARGET_NR_getrusage:
4210
        {
4211
            struct rusage rusage;
4212
            ret = get_errno(getrusage(arg1, &rusage));
4213
            if (!is_error(ret)) {
4214
                host_to_target_rusage(arg2, &rusage);
4215
            }
4216
        }
4217
        break;
4218
    case TARGET_NR_gettimeofday:
4219
        {
4220
            struct timeval tv;
4221
            ret = get_errno(gettimeofday(&tv, NULL));
4222
            if (!is_error(ret)) {
4223
                if (copy_to_user_timeval(arg1, &tv))
4224
                    goto efault;
4225
            }
4226
        }
4227
        break;
4228
    case TARGET_NR_settimeofday:
4229
        {
4230
            struct timeval tv;
4231
            if (copy_from_user_timeval(&tv, arg1))
4232
                goto efault;
4233
            ret = get_errno(settimeofday(&tv, NULL));
4234
        }
4235
        break;
4236
#ifdef TARGET_NR_select
4237
    case TARGET_NR_select:
4238
        {
4239
            struct target_sel_arg_struct *sel;
4240
            abi_ulong inp, outp, exp, tvp;
4241
            long nsel;
4242

    
4243
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4244
                goto efault;
4245
            nsel = tswapl(sel->n);
4246
            inp = tswapl(sel->inp);
4247
            outp = tswapl(sel->outp);
4248
            exp = tswapl(sel->exp);
4249
            tvp = tswapl(sel->tvp);
4250
            unlock_user_struct(sel, arg1, 0);
4251
            ret = do_select(nsel, inp, outp, exp, tvp);
4252
        }
4253
        break;
4254
#endif
4255
    case TARGET_NR_symlink:
4256
        {
4257
            void *p2;
4258
            p = lock_user_string(arg1);
4259
            p2 = lock_user_string(arg2);
4260
            if (!p || !p2)
4261
                ret = -TARGET_EFAULT;
4262
            else
4263
                ret = get_errno(symlink(p, p2));
4264
            unlock_user(p2, arg2, 0);
4265
            unlock_user(p, arg1, 0);
4266
        }
4267
        break;
4268
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4269
    case TARGET_NR_symlinkat:
4270
        {
4271
            void *p2;
4272
            p  = lock_user_string(arg1);
4273
            p2 = lock_user_string(arg3);
4274
            if (!p || !p2)
4275
                ret = -TARGET_EFAULT;
4276
            else
4277
                ret = get_errno(sys_symlinkat(p, arg2, p2));
4278
            unlock_user(p2, arg3, 0);
4279
            unlock_user(p, arg1, 0);
4280
        }
4281
        break;
4282
#endif
4283
#ifdef TARGET_NR_oldlstat
4284
    case TARGET_NR_oldlstat:
4285
        goto unimplemented;
4286
#endif
4287
    case TARGET_NR_readlink:
4288
        {
4289
            void *p2;
4290
            p = lock_user_string(arg1);
4291
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4292
            if (!p || !p2)
4293
                ret = -TARGET_EFAULT;
4294
            else
4295
                ret = get_errno(readlink(path(p), p2, arg3));
4296
            unlock_user(p2, arg2, ret);
4297
            unlock_user(p, arg1, 0);
4298
        }
4299
        break;
4300
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4301
    case TARGET_NR_readlinkat:
4302
        {
4303
            void *p2;
4304
            p  = lock_user_string(arg2);
4305
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4306
            if (!p || !p2)
4307
                ret = -TARGET_EFAULT;
4308
            else
4309
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4310
            unlock_user(p2, arg3, ret);
4311
            unlock_user(p, arg2, 0);
4312
        }
4313
        break;
4314
#endif
4315
#ifdef TARGET_NR_uselib
4316
    case TARGET_NR_uselib:
4317
        goto unimplemented;
4318
#endif
4319
#ifdef TARGET_NR_swapon
4320
    case TARGET_NR_swapon:
4321
        if (!(p = lock_user_string(arg1)))
4322
            goto efault;
4323
        ret = get_errno(swapon(p, arg2));
4324
        unlock_user(p, arg1, 0);
4325
        break;
4326
#endif
4327
    case TARGET_NR_reboot:
4328
        goto unimplemented;
4329
#ifdef TARGET_NR_readdir
4330
    case TARGET_NR_readdir:
4331
        goto unimplemented;
4332
#endif
4333
#ifdef TARGET_NR_mmap
4334
    case TARGET_NR_mmap:
4335
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4336
        {
4337
            abi_ulong *v;
4338
            abi_ulong v1, v2, v3, v4, v5, v6;
4339
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4340
                goto efault;
4341
            v1 = tswapl(v[0]);
4342
            v2 = tswapl(v[1]);
4343
            v3 = tswapl(v[2]);
4344
            v4 = tswapl(v[3]);
4345
            v5 = tswapl(v[4]);
4346
            v6 = tswapl(v[5]);
4347
            unlock_user(v, arg1, 0);
4348
            ret = get_errno(target_mmap(v1, v2, v3,
4349
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
4350
                                        v5, v6));
4351
        }
4352
#else
4353
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4354
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4355
                                    arg5,
4356
                                    arg6));
4357
#endif
4358
        break;
4359
#endif
4360
#ifdef TARGET_NR_mmap2
4361
    case TARGET_NR_mmap2:
4362
#ifndef MMAP_SHIFT
4363
#define MMAP_SHIFT 12
4364
#endif
4365
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4366
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4367
                                    arg5,
4368
                                    arg6 << MMAP_SHIFT));
4369
        break;
4370
#endif
4371
    case TARGET_NR_munmap:
4372
        ret = get_errno(target_munmap(arg1, arg2));
4373
        break;
4374
    case TARGET_NR_mprotect:
4375
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
4376
        break;
4377
#ifdef TARGET_NR_mremap
4378
    case TARGET_NR_mremap:
4379
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4380
        break;
4381
#endif
4382
        /* ??? msync/mlock/munlock are broken for softmmu.  */
4383
#ifdef TARGET_NR_msync
4384
    case TARGET_NR_msync:
4385
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
4386
        break;
4387
#endif
4388
#ifdef TARGET_NR_mlock
4389
    case TARGET_NR_mlock:
4390
        ret = get_errno(mlock(g2h(arg1), arg2));
4391
        break;
4392
#endif
4393
#ifdef TARGET_NR_munlock
4394
    case TARGET_NR_munlock:
4395
        ret = get_errno(munlock(g2h(arg1), arg2));
4396
        break;
4397
#endif
4398
#ifdef TARGET_NR_mlockall
4399
    case TARGET_NR_mlockall:
4400
        ret = get_errno(mlockall(arg1));
4401
        break;
4402
#endif
4403
#ifdef TARGET_NR_munlockall
4404
    case TARGET_NR_munlockall:
4405
        ret = get_errno(munlockall());
4406
        break;
4407
#endif
4408
    case TARGET_NR_truncate:
4409
        if (!(p = lock_user_string(arg1)))
4410
            goto efault;
4411
        ret = get_errno(truncate(p, arg2));
4412
        unlock_user(p, arg1, 0);
4413
        break;
4414
    case TARGET_NR_ftruncate:
4415
        ret = get_errno(ftruncate(arg1, arg2));
4416
        break;
4417
    case TARGET_NR_fchmod:
4418
        ret = get_errno(fchmod(arg1, arg2));
4419
        break;
4420
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4421
    case TARGET_NR_fchmodat:
4422
        if (!(p = lock_user_string(arg2)))
4423
            goto efault;
4424
        ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4425
        unlock_user(p, arg2, 0);
4426
        break;
4427
#endif
4428
    case TARGET_NR_getpriority:
4429
        /* libc does special remapping of the return value of
4430
         * sys_getpriority() so it's just easiest to call
4431
         * sys_getpriority() directly rather than through libc. */
4432
        ret = sys_getpriority(arg1, arg2);
4433
        break;
4434
    case TARGET_NR_setpriority:
4435
        ret = get_errno(setpriority(arg1, arg2, arg3));
4436
        break;
4437
#ifdef TARGET_NR_profil
4438
    case TARGET_NR_profil:
4439
        goto unimplemented;
4440
#endif
4441
    case TARGET_NR_statfs:
4442
        if (!(p = lock_user_string(arg1)))
4443
            goto efault;
4444
        ret = get_errno(statfs(path(p), &stfs));
4445
        unlock_user(p, arg1, 0);
4446
    convert_statfs:
4447
        if (!is_error(ret)) {
4448
            struct target_statfs *target_stfs;
4449

    
4450
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4451
                goto efault;
4452
            __put_user(stfs.f_type, &target_stfs->f_type);
4453
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4454
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4455
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4456
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4457
            __put_user(stfs.f_files, &target_stfs->f_files);
4458
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4459
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4460
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4461
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4462
            unlock_user_struct(target_stfs, arg2, 1);
4463
        }
4464
        break;
4465
    case TARGET_NR_fstatfs:
4466
        ret = get_errno(fstatfs(arg1, &stfs));
4467
        goto convert_statfs;
4468
#ifdef TARGET_NR_statfs64
4469
    case TARGET_NR_statfs64:
4470
        if (!(p = lock_user_string(arg1)))
4471
            goto efault;
4472
        ret = get_errno(statfs(path(p), &stfs));
4473
        unlock_user(p, arg1, 0);
4474
    convert_statfs64:
4475
        if (!is_error(ret)) {
4476
            struct target_statfs64 *target_stfs;
4477

    
4478
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4479
                goto efault;
4480
            __put_user(stfs.f_type, &target_stfs->f_type);
4481
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4482
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4483
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4484
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4485
            __put_user(stfs.f_files, &target_stfs->f_files);
4486
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4487
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4488
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4489
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4490
            unlock_user_struct(target_stfs, arg3, 1);
4491
        }
4492
        break;
4493
    case TARGET_NR_fstatfs64:
4494
        ret = get_errno(fstatfs(arg1, &stfs));
4495
        goto convert_statfs64;
4496
#endif
4497
#ifdef TARGET_NR_ioperm
4498
    case TARGET_NR_ioperm:
4499
        goto unimplemented;
4500
#endif
4501
#ifdef TARGET_NR_socketcall
4502
    case TARGET_NR_socketcall:
4503
        ret = do_socketcall(arg1, arg2);
4504
        break;
4505
#endif
4506
#ifdef TARGET_NR_accept
4507
    case TARGET_NR_accept:
4508
        ret = do_accept(arg1, arg2, arg3);
4509
        break;
4510
#endif
4511
#ifdef TARGET_NR_bind
4512
    case TARGET_NR_bind:
4513
        ret = do_bind(arg1, arg2, arg3);
4514
        break;
4515
#endif
4516
#ifdef TARGET_NR_connect
4517
    case TARGET_NR_connect:
4518
        ret = do_connect(arg1, arg2, arg3);
4519
        break;
4520
#endif
4521
#ifdef TARGET_NR_getpeername
4522
    case TARGET_NR_getpeername:
4523
        ret = do_getpeername(arg1, arg2, arg3);
4524
        break;
4525
#endif
4526
#ifdef TARGET_NR_getsockname
4527
    case TARGET_NR_getsockname:
4528
        ret = do_getsockname(arg1, arg2, arg3);
4529
        break;
4530
#endif
4531
#ifdef TARGET_NR_getsockopt
4532
    case TARGET_NR_getsockopt:
4533
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4534
        break;
4535
#endif
4536
#ifdef TARGET_NR_listen
4537
    case TARGET_NR_listen:
4538
        ret = get_errno(listen(arg1, arg2));
4539
        break;
4540
#endif
4541
#ifdef TARGET_NR_recv
4542
    case TARGET_NR_recv:
4543
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4544
        break;
4545
#endif
4546
#ifdef TARGET_NR_recvfrom
4547
    case TARGET_NR_recvfrom:
4548
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4549
        break;
4550
#endif
4551
#ifdef TARGET_NR_recvmsg
4552
    case TARGET_NR_recvmsg:
4553
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4554
        break;
4555
#endif
4556
#ifdef TARGET_NR_send
4557
    case TARGET_NR_send:
4558
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4559
        break;
4560
#endif
4561
#ifdef TARGET_NR_sendmsg
4562
    case TARGET_NR_sendmsg:
4563
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4564
        break;
4565
#endif
4566
#ifdef TARGET_NR_sendto
4567
    case TARGET_NR_sendto:
4568
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4569
        break;
4570
#endif
4571
#ifdef TARGET_NR_shutdown
4572
    case TARGET_NR_shutdown:
4573
        ret = get_errno(shutdown(arg1, arg2));
4574
        break;
4575
#endif
4576
#ifdef TARGET_NR_socket
4577
    case TARGET_NR_socket:
4578
        ret = do_socket(arg1, arg2, arg3);
4579
        break;
4580
#endif
4581
#ifdef TARGET_NR_socketpair
4582
    case TARGET_NR_socketpair:
4583
        ret = do_socketpair(arg1, arg2, arg3, arg4);
4584
        break;
4585
#endif
4586
#ifdef TARGET_NR_setsockopt
4587
    case TARGET_NR_setsockopt:
4588
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4589
        break;
4590
#endif
4591

    
4592
    case TARGET_NR_syslog:
4593
        if (!(p = lock_user_string(arg2)))
4594
            goto efault;
4595
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4596
        unlock_user(p, arg2, 0);
4597
        break;
4598

    
4599
    case TARGET_NR_setitimer:
4600
        {
4601
            struct itimerval value, ovalue, *pvalue;
4602

    
4603
            if (arg2) {
4604
                pvalue = &value;
4605
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4606
                    || copy_from_user_timeval(&pvalue->it_value,
4607
                                              arg2 + sizeof(struct target_timeval)))
4608
                    goto efault;
4609
            } else {
4610
                pvalue = NULL;
4611
            }
4612
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4613
            if (!is_error(ret) && arg3) {
4614
                if (copy_to_user_timeval(arg3,
4615
                                         &ovalue.it_interval)
4616
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4617
                                            &ovalue.it_value))
4618
                    goto efault;
4619
            }
4620
        }
4621
        break;
4622
    case TARGET_NR_getitimer:
4623
        {
4624
            struct itimerval value;
4625

    
4626
            ret = get_errno(getitimer(arg1, &value));
4627
            if (!is_error(ret) && arg2) {
4628
                if (copy_to_user_timeval(arg2,
4629
                                         &value.it_interval)
4630
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4631
                                            &value.it_value))
4632
                    goto efault;
4633
            }
4634
        }
4635
        break;
4636
    case TARGET_NR_stat:
4637
        if (!(p = lock_user_string(arg1)))
4638
            goto efault;
4639
        ret = get_errno(stat(path(p), &st));
4640
        unlock_user(p, arg1, 0);
4641
        goto do_stat;
4642
    case TARGET_NR_lstat:
4643
        if (!(p = lock_user_string(arg1)))
4644
            goto efault;
4645
        ret = get_errno(lstat(path(p), &st));
4646
        unlock_user(p, arg1, 0);
4647
        goto do_stat;
4648
    case TARGET_NR_fstat:
4649
        {
4650
            ret = get_errno(fstat(arg1, &st));
4651
        do_stat:
4652
            if (!is_error(ret)) {
4653
                struct target_stat *target_st;
4654

    
4655
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4656
                    goto efault;
4657
                __put_user(st.st_dev, &target_st->st_dev);
4658
                __put_user(st.st_ino, &target_st->st_ino);
4659
                __put_user(st.st_mode, &target_st->st_mode);
4660
                __put_user(st.st_uid, &target_st->st_uid);
4661
                __put_user(st.st_gid, &target_st->st_gid);
4662
                __put_user(st.st_nlink, &target_st->st_nlink);
4663
                __put_user(st.st_rdev, &target_st->st_rdev);
4664
                __put_user(st.st_size, &target_st->st_size);
4665
                __put_user(st.st_blksize, &target_st->st_blksize);
4666
                __put_user(st.st_blocks, &target_st->st_blocks);
4667
                __put_user(st.st_atime, &target_st->target_st_atime);
4668
                __put_user(st.st_mtime, &target_st->target_st_mtime);
4669
                __put_user(st.st_ctime, &target_st->target_st_ctime);
4670
                unlock_user_struct(target_st, arg2, 1);
4671
            }
4672
        }
4673
        break;
4674
#ifdef TARGET_NR_olduname
4675
    case TARGET_NR_olduname:
4676
        goto unimplemented;
4677
#endif
4678
#ifdef TARGET_NR_iopl
4679
    case TARGET_NR_iopl:
4680
        goto unimplemented;
4681
#endif
4682
    case TARGET_NR_vhangup:
4683
        ret = get_errno(vhangup());
4684
        break;
4685
#ifdef TARGET_NR_idle
4686
    case TARGET_NR_idle:
4687
        goto unimplemented;
4688
#endif
4689
#ifdef TARGET_NR_syscall
4690
    case TARGET_NR_syscall:
4691
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4692
            break;
4693
#endif
4694
    case TARGET_NR_wait4:
4695
        {
4696
            int status;
4697
            abi_long status_ptr = arg2;
4698
            struct rusage rusage, *rusage_ptr;
4699
            abi_ulong target_rusage = arg4;
4700
            if (target_rusage)
4701
                rusage_ptr = &rusage;
4702
            else
4703
                rusage_ptr = NULL;
4704
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4705
            if (!is_error(ret)) {
4706
                if (status_ptr) {
4707
                    if (put_user_s32(status, status_ptr))
4708
                        goto efault;
4709
                }
4710
                if (target_rusage)
4711
                    host_to_target_rusage(target_rusage, &rusage);
4712
            }
4713
        }
4714
        break;
4715
#ifdef TARGET_NR_swapoff
4716
    case TARGET_NR_swapoff:
4717
        if (!(p = lock_user_string(arg1)))
4718
            goto efault;
4719
        ret = get_errno(swapoff(p));
4720
        unlock_user(p, arg1, 0);
4721
        break;
4722
#endif
4723
    case TARGET_NR_sysinfo:
4724
        {
4725
            struct target_sysinfo *target_value;
4726
            struct sysinfo value;
4727
            ret = get_errno(sysinfo(&value));
4728
            if (!is_error(ret) && arg1)
4729
            {
4730
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4731
                    goto efault;
4732
                __put_user(value.uptime, &target_value->uptime);
4733
                __put_user(value.loads[0], &target_value->loads[0]);
4734
                __put_user(value.loads[1], &target_value->loads[1]);
4735
                __put_user(value.loads[2], &target_value->loads[2]);
4736
                __put_user(value.totalram, &target_value->totalram);
4737
                __put_user(value.freeram, &target_value->freeram);
4738
                __put_user(value.sharedram, &target_value->sharedram);
4739
                __put_user(value.bufferram, &target_value->bufferram);
4740
                __put_user(value.totalswap, &target_value->totalswap);
4741
                __put_user(value.freeswap, &target_value->freeswap);
4742
                __put_user(value.procs, &target_value->procs);
4743
                __put_user(value.totalhigh, &target_value->totalhigh);
4744
                __put_user(value.freehigh, &target_value->freehigh);
4745
                __put_user(value.mem_unit, &target_value->mem_unit);
4746
                unlock_user_struct(target_value, arg1, 1);
4747
            }
4748
        }
4749
        break;
4750
#ifdef TARGET_NR_ipc
4751
    case TARGET_NR_ipc:
4752
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4753
        break;
4754
#endif
4755
    case TARGET_NR_fsync:
4756
        ret = get_errno(fsync(arg1));
4757
        break;
4758
    case TARGET_NR_clone:
4759
#if defined(TARGET_SH4)
4760
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
4761
#else
4762
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4763
#endif
4764
        break;
4765
#ifdef __NR_exit_group
4766
        /* new thread calls */
4767
    case TARGET_NR_exit_group:
4768
        gdb_exit(cpu_env, arg1);
4769
        ret = get_errno(exit_group(arg1));
4770
        break;
4771
#endif
4772
    case TARGET_NR_setdomainname:
4773
        if (!(p = lock_user_string(arg1)))
4774
            goto efault;
4775
        ret = get_errno(setdomainname(p, arg2));
4776
        unlock_user(p, arg1, 0);
4777
        break;
4778
    case TARGET_NR_uname:
4779
        /* no need to transcode because we use the linux syscall */
4780
        {
4781
            struct new_utsname * buf;
4782

    
4783
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4784
                goto efault;
4785
            ret = get_errno(sys_uname(buf));
4786
            if (!is_error(ret)) {
4787
                /* Overrite the native machine name with whatever is being
4788
                   emulated. */
4789
                strcpy (buf->machine, UNAME_MACHINE);
4790
                /* Allow the user to override the reported release.  */
4791
                if (qemu_uname_release && *qemu_uname_release)
4792
                  strcpy (buf->release, qemu_uname_release);
4793
            }
4794
            unlock_user_struct(buf, arg1, 1);
4795
        }
4796
        break;
4797
#ifdef TARGET_I386
4798
    case TARGET_NR_modify_ldt:
4799
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4800
        break;
4801
#if !defined(TARGET_X86_64)
4802
    case TARGET_NR_vm86old:
4803
        goto unimplemented;
4804
    case TARGET_NR_vm86:
4805
        ret = do_vm86(cpu_env, arg1, arg2);
4806
        break;
4807
#endif
4808
#endif
4809
    case TARGET_NR_adjtimex:
4810
        goto unimplemented;
4811
#ifdef TARGET_NR_create_module
4812
    case TARGET_NR_create_module:
4813
#endif
4814
    case TARGET_NR_init_module:
4815
    case TARGET_NR_delete_module:
4816
#ifdef TARGET_NR_get_kernel_syms
4817
    case TARGET_NR_get_kernel_syms:
4818
#endif
4819
        goto unimplemented;
4820
    case TARGET_NR_quotactl:
4821
        goto unimplemented;
4822
    case TARGET_NR_getpgid:
4823
        ret = get_errno(getpgid(arg1));
4824
        break;
4825
    case TARGET_NR_fchdir:
4826
        ret = get_errno(fchdir(arg1));
4827
        break;
4828
#ifdef TARGET_NR_bdflush /* not on x86_64 */
4829
    case TARGET_NR_bdflush:
4830
        goto unimplemented;
4831
#endif
4832
#ifdef TARGET_NR_sysfs
4833
    case TARGET_NR_sysfs:
4834
        goto unimplemented;
4835
#endif
4836
    case TARGET_NR_personality:
4837
        ret = get_errno(personality(arg1));
4838
        break;
4839
#ifdef TARGET_NR_afs_syscall
4840
    case TARGET_NR_afs_syscall:
4841
        goto unimplemented;
4842
#endif
4843
#ifdef TARGET_NR__llseek /* Not on alpha */
4844
    case TARGET_NR__llseek:
4845
        {
4846
#if defined (__x86_64__)
4847
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4848
            if (put_user_s64(ret, arg4))
4849
                goto efault;
4850
#else
4851
            int64_t res;
4852
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4853
            if (put_user_s64(res, arg4))
4854
                goto efault;
4855
#endif
4856
        }
4857
        break;
4858
#endif
4859
    case TARGET_NR_getdents:
4860
#if TARGET_ABI_BITS != 32
4861
        goto unimplemented;
4862
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4863
        {
4864
            struct target_dirent *target_dirp;
4865
            struct dirent *dirp;
4866
            abi_long count = arg3;
4867

    
4868
            dirp = malloc(count);
4869
            if (!dirp) {
4870
                ret = -TARGET_ENOMEM;
4871
                goto fail;
4872
            }
4873

    
4874
            ret = get_errno(sys_getdents(arg1, dirp, count));
4875
            if (!is_error(ret)) {
4876
                struct dirent *de;
4877
                struct target_dirent *tde;
4878
                int len = ret;
4879
                int reclen, treclen;
4880
                int count1, tnamelen;
4881

    
4882
                count1 = 0;
4883
                de = dirp;
4884
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4885
                    goto efault;
4886
                tde = target_dirp;
4887
                while (len > 0) {
4888
                    reclen = de->d_reclen;
4889
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4890
                    tde->d_reclen = tswap16(treclen);
4891
                    tde->d_ino = tswapl(de->d_ino);
4892
                    tde->d_off = tswapl(de->d_off);
4893
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4894
                    if (tnamelen > 256)
4895
                        tnamelen = 256;
4896
                    /* XXX: may not be correct */
4897
                    strncpy(tde->d_name, de->d_name, tnamelen);
4898
                    de = (struct dirent *)((char *)de + reclen);
4899
                    len -= reclen;
4900
                    tde = (struct target_dirent *)((char *)tde + treclen);
4901
                    count1 += treclen;
4902
                }
4903
                ret = count1;
4904
                unlock_user(target_dirp, arg2, ret);
4905
            }
4906
            free(dirp);
4907
        }
4908
#else
4909
        {
4910
            struct dirent *dirp;
4911
            abi_long count = arg3;
4912

    
4913
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4914
                goto efault;
4915
            ret = get_errno(sys_getdents(arg1, dirp, count));
4916
            if (!is_error(ret)) {
4917
                struct dirent *de;
4918
                int len = ret;
4919
                int reclen;
4920
                de = dirp;
4921
                while (len > 0) {
4922
                    reclen = de->d_reclen;
4923
                    if (reclen > len)
4924
                        break;
4925
                    de->d_reclen = tswap16(reclen);
4926
                    tswapls(&de->d_ino);
4927
                    tswapls(&de->d_off);
4928
                    de = (struct dirent *)((char *)de + reclen);
4929
                    len -= reclen;
4930
                }
4931
            }
4932
            unlock_user(dirp, arg2, ret);
4933
        }
4934
#endif
4935
        break;
4936
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
4937
    case TARGET_NR_getdents64:
4938
        {
4939
            struct dirent64 *dirp;
4940
            abi_long count = arg3;
4941
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4942
                goto efault;
4943
            ret = get_errno(sys_getdents64(arg1, dirp, count));
4944
            if (!is_error(ret)) {
4945
                struct dirent64 *de;
4946
                int len = ret;
4947
                int reclen;
4948
                de = dirp;
4949
                while (len > 0) {
4950
                    reclen = de->d_reclen;
4951
                    if (reclen > len)
4952
                        break;
4953
                    de->d_reclen = tswap16(reclen);
4954
                    tswap64s((uint64_t *)&de->d_ino);
4955
                    tswap64s((uint64_t *)&de->d_off);
4956
                    de = (struct dirent64 *)((char *)de + reclen);
4957
                    len -= reclen;
4958
                }
4959
            }
4960
            unlock_user(dirp, arg2, ret);
4961
        }
4962
        break;
4963
#endif /* TARGET_NR_getdents64 */
4964
#ifdef TARGET_NR__newselect
4965
    case TARGET_NR__newselect:
4966
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
4967
        break;
4968
#endif
4969
#ifdef TARGET_NR_poll
4970
    case TARGET_NR_poll:
4971
        {
4972
            struct target_pollfd *target_pfd;
4973
            unsigned int nfds = arg2;
4974
            int timeout = arg3;
4975
            struct pollfd *pfd;
4976
            unsigned int i;
4977

    
4978
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
4979
            if (!target_pfd)
4980
                goto efault;
4981
            pfd = alloca(sizeof(struct pollfd) * nfds);
4982
            for(i = 0; i < nfds; i++) {
4983
                pfd[i].fd = tswap32(target_pfd[i].fd);
4984
                pfd[i].events = tswap16(target_pfd[i].events);
4985
            }
4986
            ret = get_errno(poll(pfd, nfds, timeout));
4987
            if (!is_error(ret)) {
4988
                for(i = 0; i < nfds; i++) {
4989
                    target_pfd[i].revents = tswap16(pfd[i].revents);
4990
                }
4991
                ret += nfds * (sizeof(struct target_pollfd)
4992
                               - sizeof(struct pollfd));
4993
            }
4994
            unlock_user(target_pfd, arg1, ret);
4995
        }
4996
        break;
4997
#endif
4998
    case TARGET_NR_flock:
4999
        /* NOTE: the flock constant seems to be the same for every
5000
           Linux platform */
5001
        ret = get_errno(flock(arg1, arg2));
5002
        break;
5003
    case TARGET_NR_readv:
5004
        {
5005
            int count = arg3;
5006
            struct iovec *vec;
5007

    
5008
            vec = alloca(count * sizeof(struct iovec));
5009
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5010
                goto efault;
5011
            ret = get_errno(readv(arg1, vec, count));
5012
            unlock_iovec(vec, arg2, count, 1);
5013
        }
5014
        break;
5015
    case TARGET_NR_writev:
5016
        {
5017
            int count = arg3;
5018
            struct iovec *vec;
5019

    
5020
            vec = alloca(count * sizeof(struct iovec));
5021
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5022
                goto efault;
5023
            ret = get_errno(writev(arg1, vec, count));
5024
            unlock_iovec(vec, arg2, count, 0);
5025
        }
5026
        break;
5027
    case TARGET_NR_getsid:
5028
        ret = get_errno(getsid(arg1));
5029
        break;
5030
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5031
    case TARGET_NR_fdatasync:
5032
        ret = get_errno(fdatasync(arg1));
5033
        break;
5034
#endif
5035
    case TARGET_NR__sysctl:
5036
        /* We don't implement this, but ENOTDIR is always a safe
5037
           return value. */
5038
        ret = -TARGET_ENOTDIR;
5039
        break;
5040
    case TARGET_NR_sched_setparam:
5041
        {
5042
            struct sched_param *target_schp;
5043
            struct sched_param schp;
5044

    
5045
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5046
                goto efault;
5047
            schp.sched_priority = tswap32(target_schp->sched_priority);
5048
            unlock_user_struct(target_schp, arg2, 0);
5049
            ret = get_errno(sched_setparam(arg1, &schp));
5050
        }
5051
        break;
5052
    case TARGET_NR_sched_getparam:
5053
        {
5054
            struct sched_param *target_schp;
5055
            struct sched_param schp;
5056
            ret = get_errno(sched_getparam(arg1, &schp));
5057
            if (!is_error(ret)) {
5058
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5059
                    goto efault;
5060
                target_schp->sched_priority = tswap32(schp.sched_priority);
5061
                unlock_user_struct(target_schp, arg2, 1);
5062
            }
5063
        }
5064
        break;
5065
    case TARGET_NR_sched_setscheduler:
5066
        {
5067
            struct sched_param *target_schp;
5068
            struct sched_param schp;
5069
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5070
                goto efault;
5071
            schp.sched_priority = tswap32(target_schp->sched_priority);
5072
            unlock_user_struct(target_schp, arg3, 0);
5073
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5074
        }
5075
        break;
5076
    case TARGET_NR_sched_getscheduler:
5077
        ret = get_errno(sched_getscheduler(arg1));
5078
        break;
5079
    case TARGET_NR_sched_yield:
5080
        ret = get_errno(sched_yield());
5081
        break;
5082
    case TARGET_NR_sched_get_priority_max:
5083
        ret = get_errno(sched_get_priority_max(arg1));
5084
        break;
5085
    case TARGET_NR_sched_get_priority_min:
5086
        ret = get_errno(sched_get_priority_min(arg1));
5087
        break;
5088
    case TARGET_NR_sched_rr_get_interval:
5089
        {
5090
            struct timespec ts;
5091
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
5092
            if (!is_error(ret)) {
5093
                host_to_target_timespec(arg2, &ts);
5094
            }
5095
        }
5096
        break;
5097
    case TARGET_NR_nanosleep:
5098
        {
5099
            struct timespec req, rem;
5100
            target_to_host_timespec(&req, arg1);
5101
            ret = get_errno(nanosleep(&req, &rem));
5102
            if (is_error(ret) && arg2) {
5103
                host_to_target_timespec(arg2, &rem);
5104
            }
5105
        }
5106
        break;
5107
#ifdef TARGET_NR_query_module
5108
    case TARGET_NR_query_module:
5109
        goto unimplemented;
5110
#endif
5111
#ifdef TARGET_NR_nfsservctl
5112
    case TARGET_NR_nfsservctl:
5113
        goto unimplemented;
5114
#endif
5115
    case TARGET_NR_prctl:
5116
        switch (arg1)
5117
            {
5118
            case PR_GET_PDEATHSIG:
5119
                {
5120
                    int deathsig;
5121
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5122
                    if (!is_error(ret) && arg2
5123
                        && put_user_ual(deathsig, arg2))
5124
                        goto efault;
5125
                }
5126
                break;
5127
            default:
5128
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5129
                break;
5130
            }
5131
        break;
5132
#ifdef TARGET_NR_arch_prctl
5133
    case TARGET_NR_arch_prctl:
5134
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
5135
        ret = do_arch_prctl(cpu_env, arg1, arg2);
5136
        break;
5137
#else
5138
        goto unimplemented;
5139
#endif
5140
#endif
5141
#ifdef TARGET_NR_pread
5142
    case TARGET_NR_pread:
5143
#ifdef TARGET_ARM
5144
        if (((CPUARMState *)cpu_env)->eabi)
5145
            arg4 = arg5;
5146
#endif
5147
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5148
            goto efault;
5149
        ret = get_errno(pread(arg1, p, arg3, arg4));
5150
        unlock_user(p, arg2, ret);
5151
        break;
5152
    case TARGET_NR_pwrite:
5153
#ifdef TARGET_ARM
5154
        if (((CPUARMState *)cpu_env)->eabi)
5155
            arg4 = arg5;
5156
#endif
5157
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5158
            goto efault;
5159
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
5160
        unlock_user(p, arg2, 0);
5161
        break;
5162
#endif
5163
#ifdef TARGET_NR_pread64
5164
    case TARGET_NR_pread64:
5165
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5166
            goto efault;
5167
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5168
        unlock_user(p, arg2, ret);
5169
        break;
5170
    case TARGET_NR_pwrite64:
5171
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5172
            goto efault;
5173
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5174
        unlock_user(p, arg2, 0);
5175
        break;
5176
#endif
5177
    case TARGET_NR_getcwd:
5178
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5179
            goto efault;
5180
        ret = get_errno(sys_getcwd1(p, arg2));
5181
        unlock_user(p, arg1, ret);
5182
        break;
5183
    case TARGET_NR_capget:
5184
        goto unimplemented;
5185
    case TARGET_NR_capset:
5186
        goto unimplemented;
5187
    case TARGET_NR_sigaltstack:
5188
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5189
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5190
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5191
        break;
5192
#else
5193
        goto unimplemented;
5194
#endif
5195
    case TARGET_NR_sendfile:
5196
        goto unimplemented;
5197
#ifdef TARGET_NR_getpmsg
5198
    case TARGET_NR_getpmsg:
5199
        goto unimplemented;
5200
#endif
5201
#ifdef TARGET_NR_putpmsg
5202
    case TARGET_NR_putpmsg:
5203
        goto unimplemented;
5204
#endif
5205
#ifdef TARGET_NR_vfork
5206
    case TARGET_NR_vfork:
5207
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5208
                        0, 0, 0, 0));
5209
        break;
5210
#endif
5211
#ifdef TARGET_NR_ugetrlimit
5212
    case TARGET_NR_ugetrlimit:
5213
    {
5214
        struct rlimit rlim;
5215
        ret = get_errno(getrlimit(arg1, &rlim));
5216
        if (!is_error(ret)) {
5217
            struct target_rlimit *target_rlim;
5218
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5219
                goto efault;
5220
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5221
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
5222
            unlock_user_struct(target_rlim, arg2, 1);
5223
        }
5224
        break;
5225
    }
5226
#endif
5227
#ifdef TARGET_NR_truncate64
5228
    case TARGET_NR_truncate64:
5229
        if (!(p = lock_user_string(arg1)))
5230
            goto efault;
5231
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5232
        unlock_user(p, arg1, 0);
5233
        break;
5234
#endif
5235
#ifdef TARGET_NR_ftruncate64
5236
    case TARGET_NR_ftruncate64:
5237
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5238
        break;
5239
#endif
5240
#ifdef TARGET_NR_stat64
5241
    case TARGET_NR_stat64:
5242
        if (!(p = lock_user_string(arg1)))
5243
            goto efault;
5244
        ret = get_errno(stat(path(p), &st));
5245
        unlock_user(p, arg1, 0);
5246
        if (!is_error(ret))
5247
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5248
        break;
5249
#endif
5250
#ifdef TARGET_NR_lstat64
5251
    case TARGET_NR_lstat64:
5252
        if (!(p = lock_user_string(arg1)))
5253
            goto efault;
5254
        ret = get_errno(lstat(path(p), &st));
5255
        unlock_user(p, arg1, 0);
5256
        if (!is_error(ret))
5257
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5258
        break;
5259
#endif
5260
#ifdef TARGET_NR_fstat64
5261
    case TARGET_NR_fstat64:
5262
        ret = get_errno(fstat(arg1, &st));
5263
        if (!is_error(ret))
5264
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5265
        break;
5266
#endif
5267
#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
5268
    case TARGET_NR_fstatat64:
5269
        if (!(p = lock_user_string(arg2)))
5270
            goto efault;
5271
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5272
        if (!is_error(ret))
5273
            ret = host_to_target_stat64(cpu_env, arg3, &st);
5274
        break;
5275
#endif
5276
#ifdef USE_UID16
5277
    case TARGET_NR_lchown:
5278
        if (!(p = lock_user_string(arg1)))
5279
            goto efault;
5280
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5281
        unlock_user(p, arg1, 0);
5282
        break;
5283
    case TARGET_NR_getuid:
5284
        ret = get_errno(high2lowuid(getuid()));
5285
        break;
5286
    case TARGET_NR_getgid:
5287
        ret = get_errno(high2lowgid(getgid()));
5288
        break;
5289
    case TARGET_NR_geteuid:
5290
        ret = get_errno(high2lowuid(geteuid()));
5291
        break;
5292
    case TARGET_NR_getegid:
5293
        ret = get_errno(high2lowgid(getegid()));
5294
        break;
5295
    case TARGET_NR_setreuid:
5296
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5297
        break;
5298
    case TARGET_NR_setregid:
5299
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5300
        break;
5301
    case TARGET_NR_getgroups:
5302
        {
5303
            int gidsetsize = arg1;
5304
            uint16_t *target_grouplist;
5305
            gid_t *grouplist;
5306
            int i;
5307

    
5308
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5309
            ret = get_errno(getgroups(gidsetsize, grouplist));
5310
            if (gidsetsize == 0)
5311
                break;
5312
            if (!is_error(ret)) {
5313
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5314
                if (!target_grouplist)
5315
                    goto efault;
5316
                for(i = 0;i < ret; i++)
5317
                    target_grouplist[i] = tswap16(grouplist[i]);
5318
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5319
            }
5320
        }
5321
        break;
5322
    case TARGET_NR_setgroups:
5323
        {
5324
            int gidsetsize = arg1;
5325
            uint16_t *target_grouplist;
5326
            gid_t *grouplist;
5327
            int i;
5328

    
5329
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5330
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5331
            if (!target_grouplist) {
5332
                ret = -TARGET_EFAULT;
5333
                goto fail;
5334
            }
5335
            for(i = 0;i < gidsetsize; i++)
5336
                grouplist[i] = tswap16(target_grouplist[i]);
5337
            unlock_user(target_grouplist, arg2, 0);
5338
            ret = get_errno(setgroups(gidsetsize, grouplist));
5339
        }
5340
        break;
5341
    case TARGET_NR_fchown:
5342
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5343
        break;
5344
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5345
    case TARGET_NR_fchownat:
5346
        if (!(p = lock_user_string(arg2))) 
5347
            goto efault;
5348
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5349
        unlock_user(p, arg2, 0);
5350
        break;
5351
#endif
5352
#ifdef TARGET_NR_setresuid
5353
    case TARGET_NR_setresuid:
5354
        ret = get_errno(setresuid(low2highuid(arg1),
5355
                                  low2highuid(arg2),
5356
                                  low2highuid(arg3)));
5357
        break;
5358
#endif
5359
#ifdef TARGET_NR_getresuid
5360
    case TARGET_NR_getresuid:
5361
        {
5362
            uid_t ruid, euid, suid;
5363
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5364
            if (!is_error(ret)) {
5365
                if (put_user_u16(high2lowuid(ruid), arg1)
5366
                    || put_user_u16(high2lowuid(euid), arg2)
5367
                    || put_user_u16(high2lowuid(suid), arg3))
5368
                    goto efault;
5369
            }
5370
        }
5371
        break;
5372
#endif
5373
#ifdef TARGET_NR_getresgid
5374
    case TARGET_NR_setresgid:
5375
        ret = get_errno(setresgid(low2highgid(arg1),
5376
                                  low2highgid(arg2),
5377
                                  low2highgid(arg3)));
5378
        break;
5379
#endif
5380
#ifdef TARGET_NR_getresgid
5381
    case TARGET_NR_getresgid:
5382
        {
5383
            gid_t rgid, egid, sgid;
5384
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5385
            if (!is_error(ret)) {
5386
                if (put_user_u16(high2lowgid(rgid), arg1)
5387
                    || put_user_u16(high2lowgid(egid), arg2)
5388
                    || put_user_u16(high2lowgid(sgid), arg3))
5389
                    goto efault;
5390
            }
5391
        }
5392
        break;
5393
#endif
5394
    case TARGET_NR_chown:
5395
        if (!(p = lock_user_string(arg1)))
5396
            goto efault;
5397
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5398
        unlock_user(p, arg1, 0);
5399
        break;
5400
    case TARGET_NR_setuid:
5401
        ret = get_errno(setuid(low2highuid(arg1)));
5402
        break;
5403
    case TARGET_NR_setgid:
5404
        ret = get_errno(setgid(low2highgid(arg1)));
5405
        break;
5406
    case TARGET_NR_setfsuid:
5407
        ret = get_errno(setfsuid(arg1));
5408
        break;
5409
    case TARGET_NR_setfsgid:
5410
        ret = get_errno(setfsgid(arg1));
5411
        break;
5412
#endif /* USE_UID16 */
5413

    
5414
#ifdef TARGET_NR_lchown32
5415
    case TARGET_NR_lchown32:
5416
        if (!(p = lock_user_string(arg1)))
5417
            goto efault;
5418
        ret = get_errno(lchown(p, arg2, arg3));
5419
        unlock_user(p, arg1, 0);
5420
        break;
5421
#endif
5422
#ifdef TARGET_NR_getuid32
5423
    case TARGET_NR_getuid32:
5424
        ret = get_errno(getuid());
5425
        break;
5426
#endif
5427
#ifdef TARGET_NR_getgid32
5428
    case TARGET_NR_getgid32:
5429
        ret = get_errno(getgid());
5430
        break;
5431
#endif
5432
#ifdef TARGET_NR_geteuid32
5433
    case TARGET_NR_geteuid32:
5434
        ret = get_errno(geteuid());
5435
        break;
5436
#endif
5437
#ifdef TARGET_NR_getegid32
5438
    case TARGET_NR_getegid32:
5439
        ret = get_errno(getegid());
5440
        break;
5441
#endif
5442
#ifdef TARGET_NR_setreuid32
5443
    case TARGET_NR_setreuid32:
5444
        ret = get_errno(setreuid(arg1, arg2));
5445
        break;
5446
#endif
5447
#ifdef TARGET_NR_setregid32
5448
    case TARGET_NR_setregid32:
5449
        ret = get_errno(setregid(arg1, arg2));
5450
        break;
5451
#endif
5452
#ifdef TARGET_NR_getgroups32
5453
    case TARGET_NR_getgroups32:
5454
        {
5455
            int gidsetsize = arg1;
5456
            uint32_t *target_grouplist;
5457
            gid_t *grouplist;
5458
            int i;
5459

    
5460
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5461
            ret = get_errno(getgroups(gidsetsize, grouplist));
5462
            if (gidsetsize == 0)
5463
                break;
5464
            if (!is_error(ret)) {
5465
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5466
                if (!target_grouplist) {
5467
                    ret = -TARGET_EFAULT;
5468
                    goto fail;
5469
                }
5470
                for(i = 0;i < ret; i++)
5471
                    target_grouplist[i] = tswap32(grouplist[i]);
5472
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
5473
            }
5474
        }
5475
        break;
5476
#endif
5477
#ifdef TARGET_NR_setgroups32
5478
    case TARGET_NR_setgroups32:
5479
        {
5480
            int gidsetsize = arg1;
5481
            uint32_t *target_grouplist;
5482
            gid_t *grouplist;
5483
            int i;
5484

    
5485
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5486
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5487
            if (!target_grouplist) {
5488
                ret = -TARGET_EFAULT;
5489
                goto fail;
5490
            }
5491
            for(i = 0;i < gidsetsize; i++)
5492
                grouplist[i] = tswap32(target_grouplist[i]);
5493
            unlock_user(target_grouplist, arg2, 0);
5494
            ret = get_errno(setgroups(gidsetsize, grouplist));
5495
        }
5496
        break;
5497
#endif
5498
#ifdef TARGET_NR_fchown32
5499
    case TARGET_NR_fchown32:
5500
        ret = get_errno(fchown(arg1, arg2, arg3));
5501
        break;
5502
#endif
5503
#ifdef TARGET_NR_setresuid32
5504
    case TARGET_NR_setresuid32:
5505
        ret = get_errno(setresuid(arg1, arg2, arg3));
5506
        break;
5507
#endif
5508
#ifdef TARGET_NR_getresuid32
5509
    case TARGET_NR_getresuid32:
5510
        {
5511
            uid_t ruid, euid, suid;
5512
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5513
            if (!is_error(ret)) {
5514
                if (put_user_u32(ruid, arg1)
5515
                    || put_user_u32(euid, arg2)
5516
                    || put_user_u32(suid, arg3))
5517
                    goto efault;
5518
            }
5519
        }
5520
        break;
5521
#endif
5522
#ifdef TARGET_NR_setresgid32
5523
    case TARGET_NR_setresgid32:
5524
        ret = get_errno(setresgid(arg1, arg2, arg3));
5525
        break;
5526
#endif
5527
#ifdef TARGET_NR_getresgid32
5528
    case TARGET_NR_getresgid32:
5529
        {
5530
            gid_t rgid, egid, sgid;
5531
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5532
            if (!is_error(ret)) {
5533
                if (put_user_u32(rgid, arg1)
5534
                    || put_user_u32(egid, arg2)
5535
                    || put_user_u32(sgid, arg3))
5536
                    goto efault;
5537
            }
5538
        }
5539
        break;
5540
#endif
5541
#ifdef TARGET_NR_chown32
5542
    case TARGET_NR_chown32:
5543
        if (!(p = lock_user_string(arg1)))
5544
            goto efault;
5545
        ret = get_errno(chown(p, arg2, arg3));
5546
        unlock_user(p, arg1, 0);
5547
        break;
5548
#endif
5549
#ifdef TARGET_NR_setuid32
5550
    case TARGET_NR_setuid32:
5551
        ret = get_errno(setuid(arg1));
5552
        break;
5553
#endif
5554
#ifdef TARGET_NR_setgid32
5555
    case TARGET_NR_setgid32:
5556
        ret = get_errno(setgid(arg1));
5557
        break;
5558
#endif
5559
#ifdef TARGET_NR_setfsuid32
5560
    case TARGET_NR_setfsuid32:
5561
        ret = get_errno(setfsuid(arg1));
5562
        break;
5563
#endif
5564
#ifdef TARGET_NR_setfsgid32
5565
    case TARGET_NR_setfsgid32:
5566
        ret = get_errno(setfsgid(arg1));
5567
        break;
5568
#endif
5569

    
5570
    case TARGET_NR_pivot_root:
5571
        goto unimplemented;
5572
#ifdef TARGET_NR_mincore
5573
    case TARGET_NR_mincore:
5574
        goto unimplemented;
5575
#endif
5576
#ifdef TARGET_NR_madvise
5577
    case TARGET_NR_madvise:
5578
        /* A straight passthrough may not be safe because qemu sometimes
5579
           turns private flie-backed mappings into anonymous mappings.
5580
           This will break MADV_DONTNEED.
5581
           This is a hint, so ignoring and returning success is ok.  */
5582
        ret = get_errno(0);
5583
        break;
5584
#endif
5585
#if TARGET_ABI_BITS == 32
5586
    case TARGET_NR_fcntl64:
5587
    {
5588
        int cmd;
5589
        struct flock64 fl;
5590
        struct target_flock64 *target_fl;
5591
#ifdef TARGET_ARM
5592
        struct target_eabi_flock64 *target_efl;
5593
#endif
5594

    
5595
        switch(arg2){
5596
        case TARGET_F_GETLK64:
5597
            cmd = F_GETLK64;
5598
            break;
5599
        case TARGET_F_SETLK64:
5600
            cmd = F_SETLK64;
5601
            break;
5602
        case TARGET_F_SETLKW64:
5603
            cmd = F_SETLK64;
5604
            break;
5605
        default:
5606
            cmd = arg2;
5607
            break;
5608
        }
5609

    
5610
        switch(arg2) {
5611
        case TARGET_F_GETLK64:
5612
#ifdef TARGET_ARM
5613
            if (((CPUARMState *)cpu_env)->eabi) {
5614
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5615
                    goto efault;
5616
                fl.l_type = tswap16(target_efl->l_type);
5617
                fl.l_whence = tswap16(target_efl->l_whence);
5618
                fl.l_start = tswap64(target_efl->l_start);
5619
                fl.l_len = tswap64(target_efl->l_len);
5620
                fl.l_pid = tswapl(target_efl->l_pid);
5621
                unlock_user_struct(target_efl, arg3, 0);
5622
            } else
5623
#endif
5624
            {
5625
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5626
                    goto efault;
5627
                fl.l_type = tswap16(target_fl->l_type);
5628
                fl.l_whence = tswap16(target_fl->l_whence);
5629
                fl.l_start = tswap64(target_fl->l_start);
5630
                fl.l_len = tswap64(target_fl->l_len);
5631
                fl.l_pid = tswapl(target_fl->l_pid);
5632
                unlock_user_struct(target_fl, arg3, 0);
5633
            }
5634
            ret = get_errno(fcntl(arg1, cmd, &fl));
5635
            if (ret == 0) {
5636
#ifdef TARGET_ARM
5637
                if (((CPUARMState *)cpu_env)->eabi) {
5638
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
5639
                        goto efault;
5640
                    target_efl->l_type = tswap16(fl.l_type);
5641
                    target_efl->l_whence = tswap16(fl.l_whence);
5642
                    target_efl->l_start = tswap64(fl.l_start);
5643
                    target_efl->l_len = tswap64(fl.l_len);
5644
                    target_efl->l_pid = tswapl(fl.l_pid);
5645
                    unlock_user_struct(target_efl, arg3, 1);
5646
                } else
5647
#endif
5648
                {
5649
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
5650
                        goto efault;
5651
                    target_fl->l_type = tswap16(fl.l_type);
5652
                    target_fl->l_whence = tswap16(fl.l_whence);
5653
                    target_fl->l_start = tswap64(fl.l_start);
5654
                    target_fl->l_len = tswap64(fl.l_len);
5655
                    target_fl->l_pid = tswapl(fl.l_pid);
5656
                    unlock_user_struct(target_fl, arg3, 1);
5657
                }
5658
            }
5659
            break;
5660

    
5661
        case TARGET_F_SETLK64:
5662
        case TARGET_F_SETLKW64:
5663
#ifdef TARGET_ARM
5664
            if (((CPUARMState *)cpu_env)->eabi) {
5665
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5666
                    goto efault;
5667
                fl.l_type = tswap16(target_efl->l_type);
5668
                fl.l_whence = tswap16(target_efl->l_whence);
5669
                fl.l_start = tswap64(target_efl->l_start);
5670
                fl.l_len = tswap64(target_efl->l_len);
5671
                fl.l_pid = tswapl(target_efl->l_pid);
5672
                unlock_user_struct(target_efl, arg3, 0);
5673
            } else
5674
#endif
5675
            {
5676
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5677
                    goto efault;
5678
                fl.l_type = tswap16(target_fl->l_type);
5679
                fl.l_whence = tswap16(target_fl->l_whence);
5680
                fl.l_start = tswap64(target_fl->l_start);
5681
                fl.l_len = tswap64(target_fl->l_len);
5682
                fl.l_pid = tswapl(target_fl->l_pid);
5683
                unlock_user_struct(target_fl, arg3, 0);
5684
            }
5685
            ret = get_errno(fcntl(arg1, cmd, &fl));
5686
            break;
5687
        default:
5688
            ret = do_fcntl(arg1, cmd, arg3);
5689
            break;
5690
        }
5691
        break;
5692
    }
5693
#endif
5694
#ifdef TARGET_NR_cacheflush
5695
    case TARGET_NR_cacheflush:
5696
        /* self-modifying code is handled automatically, so nothing needed */
5697
        ret = 0;
5698
        break;
5699
#endif
5700
#ifdef TARGET_NR_security
5701
    case TARGET_NR_security:
5702
        goto unimplemented;
5703
#endif
5704
#ifdef TARGET_NR_getpagesize
5705
    case TARGET_NR_getpagesize:
5706
        ret = TARGET_PAGE_SIZE;
5707
        break;
5708
#endif
5709
    case TARGET_NR_gettid:
5710
        ret = get_errno(gettid());
5711
        break;
5712
#ifdef TARGET_NR_readahead
5713
    case TARGET_NR_readahead:
5714
        goto unimplemented;
5715
#endif
5716
#ifdef TARGET_NR_setxattr
5717
    case TARGET_NR_setxattr:
5718
    case TARGET_NR_lsetxattr:
5719
    case TARGET_NR_fsetxattr:
5720
    case TARGET_NR_getxattr:
5721
    case TARGET_NR_lgetxattr:
5722
    case TARGET_NR_fgetxattr:
5723
    case TARGET_NR_listxattr:
5724
    case TARGET_NR_llistxattr:
5725
    case TARGET_NR_flistxattr:
5726
    case TARGET_NR_removexattr:
5727
    case TARGET_NR_lremovexattr:
5728
    case TARGET_NR_fremovexattr:
5729
        goto unimplemented_nowarn;
5730
#endif
5731
#ifdef TARGET_NR_set_thread_area
5732
    case TARGET_NR_set_thread_area:
5733
#if defined(TARGET_MIPS)
5734
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5735
      ret = 0;
5736
      break;
5737
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
5738
      ret = do_set_thread_area(cpu_env, arg1);
5739
      break;
5740
#else
5741
      goto unimplemented_nowarn;
5742
#endif
5743
#endif
5744
#ifdef TARGET_NR_get_thread_area
5745
    case TARGET_NR_get_thread_area:
5746
#if defined(TARGET_I386) && defined(TARGET_ABI32)
5747
        ret = do_get_thread_area(cpu_env, arg1);
5748
#else
5749
        goto unimplemented_nowarn;
5750
#endif
5751
#endif
5752
#ifdef TARGET_NR_getdomainname
5753
    case TARGET_NR_getdomainname:
5754
        goto unimplemented_nowarn;
5755
#endif
5756

    
5757
#ifdef TARGET_NR_clock_gettime
5758
    case TARGET_NR_clock_gettime:
5759
    {
5760
        struct timespec ts;
5761
        ret = get_errno(clock_gettime(arg1, &ts));
5762
        if (!is_error(ret)) {
5763
            host_to_target_timespec(arg2, &ts);
5764
        }
5765
        break;
5766
    }
5767
#endif
5768
#ifdef TARGET_NR_clock_getres
5769
    case TARGET_NR_clock_getres:
5770
    {
5771
        struct timespec ts;
5772
        ret = get_errno(clock_getres(arg1, &ts));
5773
        if (!is_error(ret)) {
5774
            host_to_target_timespec(arg2, &ts);
5775
        }
5776
        break;
5777
    }
5778
#endif
5779
#ifdef TARGET_NR_clock_nanosleep
5780
    case TARGET_NR_clock_nanosleep:
5781
    {
5782
        struct timespec ts;
5783
        target_to_host_timespec(&ts, arg3);
5784
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5785
        if (arg4)
5786
            host_to_target_timespec(arg4, &ts);
5787
        break;
5788
    }
5789
#endif
5790

    
5791
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5792
    case TARGET_NR_set_tid_address:
5793
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
5794
        break;
5795
#endif
5796

    
5797
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5798
    case TARGET_NR_tkill:
5799
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5800
        break;
5801
#endif
5802

    
5803
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5804
    case TARGET_NR_tgkill:
5805
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5806
                        target_to_host_signal(arg3)));
5807
        break;
5808
#endif
5809

    
5810
#ifdef TARGET_NR_set_robust_list
5811
    case TARGET_NR_set_robust_list:
5812
        goto unimplemented_nowarn;
5813
#endif
5814

    
5815
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5816
    case TARGET_NR_utimensat:
5817
        {
5818
            struct timespec ts[2];
5819
            target_to_host_timespec(ts, arg3);
5820
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5821
            if (!arg2)
5822
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5823
            else {
5824
                if (!(p = lock_user_string(arg2))) {
5825
                    ret = -TARGET_EFAULT;
5826
                    goto fail;
5827
                }
5828
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
5829
                unlock_user(p, arg2, 0);
5830
            }
5831
        }
5832
        break;
5833
#endif
5834
#if defined(USE_NPTL)
5835
    case TARGET_NR_futex:
5836
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
5837
        break;
5838
#endif
5839

    
5840
    default:
5841
    unimplemented:
5842
        gemu_log("qemu: Unsupported syscall: %d\n", num);
5843
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
5844
    unimplemented_nowarn:
5845
#endif
5846
        ret = -TARGET_ENOSYS;
5847
        break;
5848
    }
5849
fail:
5850
#ifdef DEBUG
5851
    gemu_log(" = %ld\n", ret);
5852
#endif
5853
    if(do_strace)
5854
        print_syscall_ret(num, ret);
5855
    return ret;
5856
efault:
5857
    ret = -TARGET_EFAULT;
5858
    goto fail;
5859
}