Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ cb3bc233

History | View | Annotate | Download (180.3 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 <sys/types.h>
32
#include <sys/ipc.h>
33
#include <sys/msg.h>
34
#include <sys/wait.h>
35
#include <sys/time.h>
36
#include <sys/stat.h>
37
#include <sys/mount.h>
38
#include <sys/prctl.h>
39
#include <sys/resource.h>
40
#include <sys/mman.h>
41
#include <sys/swap.h>
42
#include <signal.h>
43
#include <sched.h>
44
#include <sys/socket.h>
45
#include <sys/uio.h>
46
#include <sys/poll.h>
47
#include <sys/times.h>
48
#include <sys/shm.h>
49
#include <sys/sem.h>
50
#include <sys/statfs.h>
51
#include <utime.h>
52
#include <sys/sysinfo.h>
53
//#include <sys/user.h>
54
#include <netinet/ip.h>
55
#include <netinet/tcp.h>
56
#include <qemu-common.h>
57

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

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

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

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

    
87
//#define DEBUG
88

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

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

    
99

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

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

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

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

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

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

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

    
145

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

    
154

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

    
178
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
179
#define __NR__llseek __NR_lseek
180
#endif
181

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

    
269
extern int personality(int);
270
extern int flock(int, int);
271
extern int setfsuid(int);
272
extern int setfsgid(int);
273
extern int setgroups(int, gid_t *);
274

    
275
#define ERRNO_TABLE_SIZE 1200
276

    
277
/* target_to_host_errno_table[] is initialized from
278
 * host_to_target_errno_table[] in syscall_init(). */
279
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
280
};
281

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

    
394
static inline int host_to_target_errno(int err)
395
{
396
    if(host_to_target_errno_table[err])
397
        return host_to_target_errno_table[err];
398
    return err;
399
}
400

    
401
static inline int target_to_host_errno(int err)
402
{
403
    if (target_to_host_errno_table[err])
404
        return target_to_host_errno_table[err];
405
    return err;
406
}
407

    
408
static inline abi_long get_errno(abi_long ret)
409
{
410
    if (ret == -1)
411
        return -host_to_target_errno(errno);
412
    else
413
        return ret;
414
}
415

    
416
static inline int is_error(abi_long ret)
417
{
418
    return (abi_ulong)ret >= (abi_ulong)(-4096);
419
}
420

    
421
char *target_strerror(int err)
422
{
423
    return strerror(target_to_host_errno(err));
424
}
425

    
426
static abi_ulong target_brk;
427
static abi_ulong target_original_brk;
428

    
429
void target_set_brk(abi_ulong new_brk)
430
{
431
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
432
}
433

    
434
/* do_brk() must return target values and target errnos. */
435
abi_long do_brk(abi_ulong new_brk)
436
{
437
    abi_ulong brk_page;
438
    abi_long mapped_addr;
439
    int        new_alloc_size;
440

    
441
    if (!new_brk)
442
        return target_brk;
443
    if (new_brk < target_original_brk)
444
        return target_brk;
445

    
446
    brk_page = HOST_PAGE_ALIGN(target_brk);
447

    
448
    /* If the new brk is less than this, set it and we're done... */
449
    if (new_brk < brk_page) {
450
        target_brk = new_brk;
451
            return target_brk;
452
    }
453

    
454
    /* We need to allocate more memory after the brk... */
455
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
456
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
457
                                        PROT_READ|PROT_WRITE,
458
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
459

    
460
    if (!is_error(mapped_addr))
461
        target_brk = new_brk;
462
    
463
    return target_brk;
464
}
465

    
466
static inline abi_long copy_from_user_fdset(fd_set *fds,
467
                                            abi_ulong target_fds_addr,
468
                                            int n)
469
{
470
    int i, nw, j, k;
471
    abi_ulong b, *target_fds;
472

    
473
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
474
    if (!(target_fds = lock_user(VERIFY_READ,
475
                                 target_fds_addr,
476
                                 sizeof(abi_ulong) * nw,
477
                                 1)))
478
        return -TARGET_EFAULT;
479

    
480
    FD_ZERO(fds);
481
    k = 0;
482
    for (i = 0; i < nw; i++) {
483
        /* grab the abi_ulong */
484
        __get_user(b, &target_fds[i]);
485
        for (j = 0; j < TARGET_ABI_BITS; j++) {
486
            /* check the bit inside the abi_ulong */
487
            if ((b >> j) & 1)
488
                FD_SET(k, fds);
489
            k++;
490
        }
491
    }
492

    
493
    unlock_user(target_fds, target_fds_addr, 0);
494

    
495
    return 0;
496
}
497

    
498
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
499
                                          const fd_set *fds,
500
                                          int n)
501
{
502
    int i, nw, j, k;
503
    abi_long v;
504
    abi_ulong *target_fds;
505

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

    
513
    k = 0;
514
    for (i = 0; i < nw; i++) {
515
        v = 0;
516
        for (j = 0; j < TARGET_ABI_BITS; j++) {
517
            v |= ((FD_ISSET(k, fds) != 0) << j);
518
            k++;
519
        }
520
        __put_user(v, &target_fds[i]);
521
    }
522

    
523
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
524

    
525
    return 0;
526
}
527

    
528
#if defined(__alpha__)
529
#define HOST_HZ 1024
530
#else
531
#define HOST_HZ 100
532
#endif
533

    
534
static inline abi_long host_to_target_clock_t(long ticks)
535
{
536
#if HOST_HZ == TARGET_HZ
537
    return ticks;
538
#else
539
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
540
#endif
541
}
542

    
543
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
544
                                             const struct rusage *rusage)
545
{
546
    struct target_rusage *target_rusage;
547

    
548
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
549
        return -TARGET_EFAULT;
550
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
551
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
552
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
553
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
554
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
555
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
556
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
557
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
558
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
559
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
560
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
561
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
562
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
563
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
564
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
565
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
566
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
567
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
568
    unlock_user_struct(target_rusage, target_addr, 1);
569

    
570
    return 0;
571
}
572

    
573
static inline abi_long copy_from_user_timeval(struct timeval *tv,
574
                                              abi_ulong target_tv_addr)
575
{
576
    struct target_timeval *target_tv;
577

    
578
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
579
        return -TARGET_EFAULT;
580

    
581
    __get_user(tv->tv_sec, &target_tv->tv_sec);
582
    __get_user(tv->tv_usec, &target_tv->tv_usec);
583

    
584
    unlock_user_struct(target_tv, target_tv_addr, 0);
585

    
586
    return 0;
587
}
588

    
589
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
590
                                            const struct timeval *tv)
591
{
592
    struct target_timeval *target_tv;
593

    
594
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
595
        return -TARGET_EFAULT;
596

    
597
    __put_user(tv->tv_sec, &target_tv->tv_sec);
598
    __put_user(tv->tv_usec, &target_tv->tv_usec);
599

    
600
    unlock_user_struct(target_tv, target_tv_addr, 1);
601

    
602
    return 0;
603
}
604

    
605

    
606
/* do_select() must return target values and target errnos. */
607
static abi_long do_select(int n,
608
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
609
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
610
{
611
    fd_set rfds, wfds, efds;
612
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
613
    struct timeval tv, *tv_ptr;
614
    abi_long ret;
615

    
616
    if (rfd_addr) {
617
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
618
            return -TARGET_EFAULT;
619
        rfds_ptr = &rfds;
620
    } else {
621
        rfds_ptr = NULL;
622
    }
623
    if (wfd_addr) {
624
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
625
            return -TARGET_EFAULT;
626
        wfds_ptr = &wfds;
627
    } else {
628
        wfds_ptr = NULL;
629
    }
630
    if (efd_addr) {
631
        if (copy_from_user_fdset(&efds, efd_addr, n))
632
            return -TARGET_EFAULT;
633
        efds_ptr = &efds;
634
    } else {
635
        efds_ptr = NULL;
636
    }
637

    
638
    if (target_tv_addr) {
639
        if (copy_from_user_timeval(&tv, target_tv_addr))
640
            return -TARGET_EFAULT;
641
        tv_ptr = &tv;
642
    } else {
643
        tv_ptr = NULL;
644
    }
645

    
646
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
647

    
648
    if (!is_error(ret)) {
649
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
650
            return -TARGET_EFAULT;
651
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
652
            return -TARGET_EFAULT;
653
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
654
            return -TARGET_EFAULT;
655

    
656
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
657
            return -TARGET_EFAULT;
658
    }
659

    
660
    return ret;
661
}
662

    
663
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
664
                                               abi_ulong target_addr,
665
                                               socklen_t len)
666
{
667
    struct target_sockaddr *target_saddr;
668

    
669
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
670
    if (!target_saddr)
671
        return -TARGET_EFAULT;
672
    memcpy(addr, target_saddr, len);
673
    addr->sa_family = tswap16(target_saddr->sa_family);
674
    unlock_user(target_saddr, target_addr, 0);
675

    
676
    return 0;
677
}
678

    
679
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
680
                                               struct sockaddr *addr,
681
                                               socklen_t len)
682
{
683
    struct target_sockaddr *target_saddr;
684

    
685
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
686
    if (!target_saddr)
687
        return -TARGET_EFAULT;
688
    memcpy(target_saddr, addr, len);
689
    target_saddr->sa_family = tswap16(addr->sa_family);
690
    unlock_user(target_saddr, target_addr, len);
691

    
692
    return 0;
693
}
694

    
695
/* ??? Should this also swap msgh->name?  */
696
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
697
                                           struct target_msghdr *target_msgh)
698
{
699
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
700
    abi_long msg_controllen;
701
    abi_ulong target_cmsg_addr;
702
    struct target_cmsghdr *target_cmsg;
703
    socklen_t space = 0;
704
    
705
    msg_controllen = tswapl(target_msgh->msg_controllen);
706
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
707
        goto the_end;
708
    target_cmsg_addr = tswapl(target_msgh->msg_control);
709
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
710
    if (!target_cmsg)
711
        return -TARGET_EFAULT;
712

    
713
    while (cmsg && target_cmsg) {
714
        void *data = CMSG_DATA(cmsg);
715
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
716

    
717
        int len = tswapl(target_cmsg->cmsg_len)
718
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
719

    
720
        space += CMSG_SPACE(len);
721
        if (space > msgh->msg_controllen) {
722
            space -= CMSG_SPACE(len);
723
            gemu_log("Host cmsg overflow\n");
724
            break;
725
        }
726

    
727
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
728
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
729
        cmsg->cmsg_len = CMSG_LEN(len);
730

    
731
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
732
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
733
            memcpy(data, target_data, len);
734
        } else {
735
            int *fd = (int *)data;
736
            int *target_fd = (int *)target_data;
737
            int i, numfds = len / sizeof(int);
738

    
739
            for (i = 0; i < numfds; i++)
740
                fd[i] = tswap32(target_fd[i]);
741
        }
742

    
743
        cmsg = CMSG_NXTHDR(msgh, cmsg);
744
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
745
    }
746
    unlock_user(target_cmsg, target_cmsg_addr, 0);
747
 the_end:
748
    msgh->msg_controllen = space;
749
    return 0;
750
}
751

    
752
/* ??? Should this also swap msgh->name?  */
753
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
754
                                           struct msghdr *msgh)
755
{
756
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
757
    abi_long msg_controllen;
758
    abi_ulong target_cmsg_addr;
759
    struct target_cmsghdr *target_cmsg;
760
    socklen_t space = 0;
761

    
762
    msg_controllen = tswapl(target_msgh->msg_controllen);
763
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
764
        goto the_end;
765
    target_cmsg_addr = tswapl(target_msgh->msg_control);
766
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
767
    if (!target_cmsg)
768
        return -TARGET_EFAULT;
769

    
770
    while (cmsg && target_cmsg) {
771
        void *data = CMSG_DATA(cmsg);
772
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
773

    
774
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
775

    
776
        space += TARGET_CMSG_SPACE(len);
777
        if (space > msg_controllen) {
778
            space -= TARGET_CMSG_SPACE(len);
779
            gemu_log("Target cmsg overflow\n");
780
            break;
781
        }
782

    
783
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
784
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
785
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
786

    
787
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
788
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
789
            memcpy(target_data, data, len);
790
        } else {
791
            int *fd = (int *)data;
792
            int *target_fd = (int *)target_data;
793
            int i, numfds = len / sizeof(int);
794

    
795
            for (i = 0; i < numfds; i++)
796
                target_fd[i] = tswap32(fd[i]);
797
        }
798

    
799
        cmsg = CMSG_NXTHDR(msgh, cmsg);
800
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
801
    }
802
    unlock_user(target_cmsg, target_cmsg_addr, space);
803
 the_end:
804
    target_msgh->msg_controllen = tswapl(space);
805
    return 0;
806
}
807

    
808
/* do_setsockopt() Must return target values and target errnos. */
809
static abi_long do_setsockopt(int sockfd, int level, int optname,
810
                              abi_ulong optval_addr, socklen_t optlen)
811
{
812
    abi_long ret;
813
    int val;
814

    
815
    switch(level) {
816
    case SOL_TCP:
817
        /* TCP options all take an 'int' value.  */
818
        if (optlen < sizeof(uint32_t))
819
            return -TARGET_EINVAL;
820

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

    
922
        if (get_user_u32(val, optval_addr))
923
            return -TARGET_EFAULT;
924
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
925
        break;
926
    default:
927
    unimplemented:
928
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
929
        ret = -TARGET_ENOPROTOOPT;
930
    }
931
    return ret;
932
}
933

    
934
/* do_getsockopt() Must return target values and target errnos. */
935
static abi_long do_getsockopt(int sockfd, int level, int optname,
936
                              abi_ulong optval_addr, abi_ulong optlen)
937
{
938
    abi_long ret;
939
    int len, lv, val;
940

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

    
1033
/* FIXME
1034
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1035
 * other lock functions have a return code of 0 for failure.
1036
 */
1037
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1038
                           int count, int copy)
1039
{
1040
    struct target_iovec *target_vec;
1041
    abi_ulong base;
1042
    int i, j;
1043

    
1044
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1045
    if (!target_vec)
1046
        return -TARGET_EFAULT;
1047
    for(i = 0;i < count; i++) {
1048
        base = tswapl(target_vec[i].iov_base);
1049
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1050
        if (vec[i].iov_len != 0) {
1051
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1052
            if (!vec[i].iov_base && vec[i].iov_len) 
1053
                goto fail;
1054
        } else {
1055
            /* zero length pointer is ignored */
1056
            vec[i].iov_base = NULL;
1057
        }
1058
    }
1059
    unlock_user (target_vec, target_addr, 0);
1060
    return 0;
1061
 fail:
1062
    /* failure - unwind locks */
1063
    for (j = 0; j < i; j++) {
1064
        base = tswapl(target_vec[j].iov_base);
1065
        unlock_user(vec[j].iov_base, base, 0);
1066
    }
1067
    unlock_user (target_vec, target_addr, 0);
1068
    return -TARGET_EFAULT;
1069
}
1070

    
1071
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1072
                             int count, int copy)
1073
{
1074
    struct target_iovec *target_vec;
1075
    abi_ulong base;
1076
    int i;
1077

    
1078
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1079
    if (!target_vec)
1080
        return -TARGET_EFAULT;
1081
    for(i = 0;i < count; i++) {
1082
        base = tswapl(target_vec[i].iov_base);
1083
        unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1084
    }
1085
    unlock_user (target_vec, target_addr, 0);
1086

    
1087
    return 0;
1088
}
1089

    
1090
/* do_socket() Must return target values and target errnos. */
1091
static abi_long do_socket(int domain, int type, int protocol)
1092
{
1093
#if defined(TARGET_MIPS)
1094
    switch(type) {
1095
    case TARGET_SOCK_DGRAM:
1096
        type = SOCK_DGRAM;
1097
        break;
1098
    case TARGET_SOCK_STREAM:
1099
        type = SOCK_STREAM;
1100
        break;
1101
    case TARGET_SOCK_RAW:
1102
        type = SOCK_RAW;
1103
        break;
1104
    case TARGET_SOCK_RDM:
1105
        type = SOCK_RDM;
1106
        break;
1107
    case TARGET_SOCK_SEQPACKET:
1108
        type = SOCK_SEQPACKET;
1109
        break;
1110
    case TARGET_SOCK_PACKET:
1111
        type = SOCK_PACKET;
1112
        break;
1113
    }
1114
#endif
1115
    if (domain == PF_NETLINK)
1116
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1117
    return get_errno(socket(domain, type, protocol));
1118
}
1119

    
1120
/* do_bind() Must return target values and target errnos. */
1121
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1122
                        socklen_t addrlen)
1123
{
1124
    void *addr = alloca(addrlen);
1125

    
1126
    target_to_host_sockaddr(addr, target_addr, addrlen);
1127
    return get_errno(bind(sockfd, addr, addrlen));
1128
}
1129

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

    
1136
    target_to_host_sockaddr(addr, target_addr, addrlen);
1137
    return get_errno(connect(sockfd, addr, addrlen));
1138
}
1139

    
1140
/* do_sendrecvmsg() Must return target values and target errnos. */
1141
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1142
                               int flags, int send)
1143
{
1144
    abi_long ret;
1145
    struct target_msghdr *msgp;
1146
    struct msghdr msg;
1147
    int count;
1148
    struct iovec *vec;
1149
    abi_ulong target_vec;
1150

    
1151
    /* FIXME */
1152
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1153
                          msgp,
1154
                          target_msg,
1155
                          send ? 1 : 0))
1156
        return -TARGET_EFAULT;
1157
    if (msgp->msg_name) {
1158
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1159
        msg.msg_name = alloca(msg.msg_namelen);
1160
        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1161
                                msg.msg_namelen);
1162
    } else {
1163
        msg.msg_name = NULL;
1164
        msg.msg_namelen = 0;
1165
    }
1166
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1167
    msg.msg_control = alloca(msg.msg_controllen);
1168
    msg.msg_flags = tswap32(msgp->msg_flags);
1169

    
1170
    count = tswapl(msgp->msg_iovlen);
1171
    vec = alloca(count * sizeof(struct iovec));
1172
    target_vec = tswapl(msgp->msg_iov);
1173
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1174
    msg.msg_iovlen = count;
1175
    msg.msg_iov = vec;
1176

    
1177
    if (send) {
1178
        ret = target_to_host_cmsg(&msg, msgp);
1179
        if (ret == 0)
1180
            ret = get_errno(sendmsg(fd, &msg, flags));
1181
    } else {
1182
        ret = get_errno(recvmsg(fd, &msg, flags));
1183
        if (!is_error(ret))
1184
            ret = host_to_target_cmsg(msgp, &msg);
1185
    }
1186
    unlock_iovec(vec, target_vec, count, !send);
1187
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1188
    return ret;
1189
}
1190

    
1191
/* do_accept() Must return target values and target errnos. */
1192
static abi_long do_accept(int fd, abi_ulong target_addr,
1193
                          abi_ulong target_addrlen_addr)
1194
{
1195
    socklen_t addrlen;
1196
    void *addr;
1197
    abi_long ret;
1198

    
1199
    if (get_user_u32(addrlen, target_addrlen_addr))
1200
        return -TARGET_EFAULT;
1201

    
1202
    addr = alloca(addrlen);
1203

    
1204
    ret = get_errno(accept(fd, addr, &addrlen));
1205
    if (!is_error(ret)) {
1206
        host_to_target_sockaddr(target_addr, addr, addrlen);
1207
        if (put_user_u32(addrlen, target_addrlen_addr))
1208
            ret = -TARGET_EFAULT;
1209
    }
1210
    return ret;
1211
}
1212

    
1213
/* do_getpeername() Must return target values and target errnos. */
1214
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1215
                               abi_ulong target_addrlen_addr)
1216
{
1217
    socklen_t addrlen;
1218
    void *addr;
1219
    abi_long ret;
1220

    
1221
    if (get_user_u32(addrlen, target_addrlen_addr))
1222
        return -TARGET_EFAULT;
1223

    
1224
    addr = alloca(addrlen);
1225

    
1226
    ret = get_errno(getpeername(fd, addr, &addrlen));
1227
    if (!is_error(ret)) {
1228
        host_to_target_sockaddr(target_addr, addr, addrlen);
1229
        if (put_user_u32(addrlen, target_addrlen_addr))
1230
            ret = -TARGET_EFAULT;
1231
    }
1232
    return ret;
1233
}
1234

    
1235
/* do_getsockname() Must return target values and target errnos. */
1236
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1237
                               abi_ulong target_addrlen_addr)
1238
{
1239
    socklen_t addrlen;
1240
    void *addr;
1241
    abi_long ret;
1242

    
1243
    if (get_user_u32(addrlen, target_addrlen_addr))
1244
        return -TARGET_EFAULT;
1245

    
1246
    addr = alloca(addrlen);
1247

    
1248
    ret = get_errno(getsockname(fd, addr, &addrlen));
1249
    if (!is_error(ret)) {
1250
        host_to_target_sockaddr(target_addr, addr, addrlen);
1251
        if (put_user_u32(addrlen, target_addrlen_addr))
1252
            ret = -TARGET_EFAULT;
1253
    }
1254
    return ret;
1255
}
1256

    
1257
/* do_socketpair() Must return target values and target errnos. */
1258
static abi_long do_socketpair(int domain, int type, int protocol,
1259
                              abi_ulong target_tab_addr)
1260
{
1261
    int tab[2];
1262
    abi_long ret;
1263

    
1264
    ret = get_errno(socketpair(domain, type, protocol, tab));
1265
    if (!is_error(ret)) {
1266
        if (put_user_s32(tab[0], target_tab_addr)
1267
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1268
            ret = -TARGET_EFAULT;
1269
    }
1270
    return ret;
1271
}
1272

    
1273
/* do_sendto() Must return target values and target errnos. */
1274
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1275
                          abi_ulong target_addr, socklen_t addrlen)
1276
{
1277
    void *addr;
1278
    void *host_msg;
1279
    abi_long ret;
1280

    
1281
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1282
    if (!host_msg)
1283
        return -TARGET_EFAULT;
1284
    if (target_addr) {
1285
        addr = alloca(addrlen);
1286
        target_to_host_sockaddr(addr, target_addr, addrlen);
1287
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1288
    } else {
1289
        ret = get_errno(send(fd, host_msg, len, flags));
1290
    }
1291
    unlock_user(host_msg, msg, 0);
1292
    return ret;
1293
}
1294

    
1295
/* do_recvfrom() Must return target values and target errnos. */
1296
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1297
                            abi_ulong target_addr,
1298
                            abi_ulong target_addrlen)
1299
{
1300
    socklen_t addrlen;
1301
    void *addr;
1302
    void *host_msg;
1303
    abi_long ret;
1304

    
1305
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1306
    if (!host_msg)
1307
        return -TARGET_EFAULT;
1308
    if (target_addr) {
1309
        if (get_user_u32(addrlen, target_addrlen)) {
1310
            ret = -TARGET_EFAULT;
1311
            goto fail;
1312
        }
1313
        addr = alloca(addrlen);
1314
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1315
    } else {
1316
        addr = NULL; /* To keep compiler quiet.  */
1317
        ret = get_errno(recv(fd, host_msg, len, flags));
1318
    }
1319
    if (!is_error(ret)) {
1320
        if (target_addr) {
1321
            host_to_target_sockaddr(target_addr, addr, addrlen);
1322
            if (put_user_u32(addrlen, target_addrlen)) {
1323
                ret = -TARGET_EFAULT;
1324
                goto fail;
1325
            }
1326
        }
1327
        unlock_user(host_msg, msg, len);
1328
    } else {
1329
fail:
1330
        unlock_user(host_msg, msg, 0);
1331
    }
1332
    return ret;
1333
}
1334

    
1335
#ifdef TARGET_NR_socketcall
1336
/* do_socketcall() Must return target values and target errnos. */
1337
static abi_long do_socketcall(int num, abi_ulong vptr)
1338
{
1339
    abi_long ret;
1340
    const int n = sizeof(abi_ulong);
1341

    
1342
    switch(num) {
1343
    case SOCKOP_socket:
1344
        {
1345
            int domain, type, protocol;
1346

    
1347
            if (get_user_s32(domain, vptr)
1348
                || get_user_s32(type, vptr + n)
1349
                || get_user_s32(protocol, vptr + 2 * n))
1350
                return -TARGET_EFAULT;
1351

    
1352
            ret = do_socket(domain, type, protocol);
1353
        }
1354
        break;
1355
    case SOCKOP_bind:
1356
        {
1357
            int sockfd;
1358
            abi_ulong target_addr;
1359
            socklen_t addrlen;
1360

    
1361
            if (get_user_s32(sockfd, vptr)
1362
                || get_user_ual(target_addr, vptr + n)
1363
                || get_user_u32(addrlen, vptr + 2 * n))
1364
                return -TARGET_EFAULT;
1365

    
1366
            ret = do_bind(sockfd, target_addr, addrlen);
1367
        }
1368
        break;
1369
    case SOCKOP_connect:
1370
        {
1371
            int sockfd;
1372
            abi_ulong target_addr;
1373
            socklen_t addrlen;
1374

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

    
1380
            ret = do_connect(sockfd, target_addr, addrlen);
1381
        }
1382
        break;
1383
    case SOCKOP_listen:
1384
        {
1385
            int sockfd, backlog;
1386

    
1387
            if (get_user_s32(sockfd, vptr)
1388
                || get_user_s32(backlog, vptr + n))
1389
                return -TARGET_EFAULT;
1390

    
1391
            ret = get_errno(listen(sockfd, backlog));
1392
        }
1393
        break;
1394
    case SOCKOP_accept:
1395
        {
1396
            int sockfd;
1397
            abi_ulong target_addr, target_addrlen;
1398

    
1399
            if (get_user_s32(sockfd, vptr)
1400
                || get_user_ual(target_addr, vptr + n)
1401
                || get_user_u32(target_addrlen, vptr + 2 * n))
1402
                return -TARGET_EFAULT;
1403

    
1404
            ret = do_accept(sockfd, target_addr, target_addrlen);
1405
        }
1406
        break;
1407
    case SOCKOP_getsockname:
1408
        {
1409
            int sockfd;
1410
            abi_ulong target_addr, target_addrlen;
1411

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

    
1417
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1418
        }
1419
        break;
1420
    case SOCKOP_getpeername:
1421
        {
1422
            int sockfd;
1423
            abi_ulong target_addr, target_addrlen;
1424

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

    
1430
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1431
        }
1432
        break;
1433
    case SOCKOP_socketpair:
1434
        {
1435
            int domain, type, protocol;
1436
            abi_ulong tab;
1437

    
1438
            if (get_user_s32(domain, vptr)
1439
                || get_user_s32(type, vptr + n)
1440
                || get_user_s32(protocol, vptr + 2 * n)
1441
                || get_user_ual(tab, vptr + 3 * n))
1442
                return -TARGET_EFAULT;
1443

    
1444
            ret = do_socketpair(domain, type, protocol, tab);
1445
        }
1446
        break;
1447
    case SOCKOP_send:
1448
        {
1449
            int sockfd;
1450
            abi_ulong msg;
1451
            size_t len;
1452
            int flags;
1453

    
1454
            if (get_user_s32(sockfd, vptr)
1455
                || get_user_ual(msg, vptr + n)
1456
                || get_user_ual(len, vptr + 2 * n)
1457
                || get_user_s32(flags, vptr + 3 * n))
1458
                return -TARGET_EFAULT;
1459

    
1460
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1461
        }
1462
        break;
1463
    case SOCKOP_recv:
1464
        {
1465
            int sockfd;
1466
            abi_ulong msg;
1467
            size_t len;
1468
            int flags;
1469

    
1470
            if (get_user_s32(sockfd, vptr)
1471
                || get_user_ual(msg, vptr + n)
1472
                || get_user_ual(len, vptr + 2 * n)
1473
                || get_user_s32(flags, vptr + 3 * n))
1474
                return -TARGET_EFAULT;
1475

    
1476
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1477
        }
1478
        break;
1479
    case SOCKOP_sendto:
1480
        {
1481
            int sockfd;
1482
            abi_ulong msg;
1483
            size_t len;
1484
            int flags;
1485
            abi_ulong addr;
1486
            socklen_t addrlen;
1487

    
1488
            if (get_user_s32(sockfd, vptr)
1489
                || get_user_ual(msg, vptr + n)
1490
                || get_user_ual(len, vptr + 2 * n)
1491
                || get_user_s32(flags, vptr + 3 * n)
1492
                || get_user_ual(addr, vptr + 4 * n)
1493
                || get_user_u32(addrlen, vptr + 5 * n))
1494
                return -TARGET_EFAULT;
1495

    
1496
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1497
        }
1498
        break;
1499
    case SOCKOP_recvfrom:
1500
        {
1501
            int sockfd;
1502
            abi_ulong msg;
1503
            size_t len;
1504
            int flags;
1505
            abi_ulong addr;
1506
            socklen_t addrlen;
1507

    
1508
            if (get_user_s32(sockfd, vptr)
1509
                || get_user_ual(msg, vptr + n)
1510
                || get_user_ual(len, vptr + 2 * n)
1511
                || get_user_s32(flags, vptr + 3 * n)
1512
                || get_user_ual(addr, vptr + 4 * n)
1513
                || get_user_u32(addrlen, vptr + 5 * n))
1514
                return -TARGET_EFAULT;
1515

    
1516
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1517
        }
1518
        break;
1519
    case SOCKOP_shutdown:
1520
        {
1521
            int sockfd, how;
1522

    
1523
            if (get_user_s32(sockfd, vptr)
1524
                || get_user_s32(how, vptr + n))
1525
                return -TARGET_EFAULT;
1526

    
1527
            ret = get_errno(shutdown(sockfd, how));
1528
        }
1529
        break;
1530
    case SOCKOP_sendmsg:
1531
    case SOCKOP_recvmsg:
1532
        {
1533
            int fd;
1534
            abi_ulong target_msg;
1535
            int flags;
1536

    
1537
            if (get_user_s32(fd, vptr)
1538
                || get_user_ual(target_msg, vptr + n)
1539
                || get_user_s32(flags, vptr + 2 * n))
1540
                return -TARGET_EFAULT;
1541

    
1542
            ret = do_sendrecvmsg(fd, target_msg, flags,
1543
                                 (num == SOCKOP_sendmsg));
1544
        }
1545
        break;
1546
    case SOCKOP_setsockopt:
1547
        {
1548
            int sockfd;
1549
            int level;
1550
            int optname;
1551
            abi_ulong optval;
1552
            socklen_t optlen;
1553

    
1554
            if (get_user_s32(sockfd, vptr)
1555
                || get_user_s32(level, vptr + n)
1556
                || get_user_s32(optname, vptr + 2 * n)
1557
                || get_user_ual(optval, vptr + 3 * n)
1558
                || get_user_u32(optlen, vptr + 4 * n))
1559
                return -TARGET_EFAULT;
1560

    
1561
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1562
        }
1563
        break;
1564
    case SOCKOP_getsockopt:
1565
        {
1566
            int sockfd;
1567
            int level;
1568
            int optname;
1569
            abi_ulong optval;
1570
            socklen_t optlen;
1571

    
1572
            if (get_user_s32(sockfd, vptr)
1573
                || get_user_s32(level, vptr + n)
1574
                || get_user_s32(optname, vptr + 2 * n)
1575
                || get_user_ual(optval, vptr + 3 * n)
1576
                || get_user_u32(optlen, vptr + 4 * n))
1577
                return -TARGET_EFAULT;
1578

    
1579
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1580
        }
1581
        break;
1582
    default:
1583
        gemu_log("Unsupported socketcall: %d\n", num);
1584
        ret = -TARGET_ENOSYS;
1585
        break;
1586
    }
1587
    return ret;
1588
}
1589
#endif
1590

    
1591
#ifdef TARGET_NR_ipc
1592
#define N_SHM_REGIONS        32
1593

    
1594
static struct shm_region {
1595
    abi_ulong        start;
1596
    abi_ulong        size;
1597
} shm_regions[N_SHM_REGIONS];
1598

    
1599
struct target_ipc_perm
1600
{
1601
    abi_long __key;
1602
    abi_ulong uid;
1603
    abi_ulong gid;
1604
    abi_ulong cuid;
1605
    abi_ulong cgid;
1606
    unsigned short int mode;
1607
    unsigned short int __pad1;
1608
    unsigned short int __seq;
1609
    unsigned short int __pad2;
1610
    abi_ulong __unused1;
1611
    abi_ulong __unused2;
1612
};
1613

    
1614
struct target_semid_ds
1615
{
1616
  struct target_ipc_perm sem_perm;
1617
  abi_ulong sem_otime;
1618
  abi_ulong __unused1;
1619
  abi_ulong sem_ctime;
1620
  abi_ulong __unused2;
1621
  abi_ulong sem_nsems;
1622
  abi_ulong __unused3;
1623
  abi_ulong __unused4;
1624
};
1625

    
1626
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1627
                                               abi_ulong target_addr)
1628
{
1629
    struct target_ipc_perm *target_ip;
1630
    struct target_semid_ds *target_sd;
1631

    
1632
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1633
        return -TARGET_EFAULT;
1634
    target_ip=&(target_sd->sem_perm);
1635
    host_ip->__key = tswapl(target_ip->__key);
1636
    host_ip->uid = tswapl(target_ip->uid);
1637
    host_ip->gid = tswapl(target_ip->gid);
1638
    host_ip->cuid = tswapl(target_ip->cuid);
1639
    host_ip->cgid = tswapl(target_ip->cgid);
1640
    host_ip->mode = tswapl(target_ip->mode);
1641
    unlock_user_struct(target_sd, target_addr, 0);
1642
    return 0;
1643
}
1644

    
1645
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1646
                                               struct ipc_perm *host_ip)
1647
{
1648
    struct target_ipc_perm *target_ip;
1649
    struct target_semid_ds *target_sd;
1650

    
1651
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1652
        return -TARGET_EFAULT;
1653
    target_ip = &(target_sd->sem_perm);
1654
    target_ip->__key = tswapl(host_ip->__key);
1655
    target_ip->uid = tswapl(host_ip->uid);
1656
    target_ip->gid = tswapl(host_ip->gid);
1657
    target_ip->cuid = tswapl(host_ip->cuid);
1658
    target_ip->cgid = tswapl(host_ip->cgid);
1659
    target_ip->mode = tswapl(host_ip->mode);
1660
    unlock_user_struct(target_sd, target_addr, 1);
1661
    return 0;
1662
}
1663

    
1664
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1665
                                               abi_ulong target_addr)
1666
{
1667
    struct target_semid_ds *target_sd;
1668

    
1669
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1670
        return -TARGET_EFAULT;
1671
    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1672
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1673
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
1674
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1675
    unlock_user_struct(target_sd, target_addr, 0);
1676
    return 0;
1677
}
1678

    
1679
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1680
                                               struct semid_ds *host_sd)
1681
{
1682
    struct target_semid_ds *target_sd;
1683

    
1684
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1685
        return -TARGET_EFAULT;
1686
    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1687
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1688
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
1689
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1690
    unlock_user_struct(target_sd, target_addr, 1);
1691
    return 0;
1692
}
1693

    
1694
union semun {
1695
        int val;
1696
        struct semid_ds *buf;
1697
        unsigned short *array;
1698
};
1699

    
1700
union target_semun {
1701
        int val;
1702
        abi_long buf;
1703
        unsigned short int *array;
1704
};
1705

    
1706
static inline abi_long target_to_host_semun(int cmd,
1707
                                            union semun *host_su,
1708
                                            abi_ulong target_addr,
1709
                                            struct semid_ds *ds)
1710
{
1711
    union target_semun *target_su;
1712

    
1713
    switch( cmd ) {
1714
        case IPC_STAT:
1715
        case IPC_SET:
1716
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1717
               return -TARGET_EFAULT;
1718
           target_to_host_semid_ds(ds,target_su->buf);
1719
           host_su->buf = ds;
1720
           unlock_user_struct(target_su, target_addr, 0);
1721
           break;
1722
        case GETVAL:
1723
        case SETVAL:
1724
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1725
               return -TARGET_EFAULT;
1726
           host_su->val = tswapl(target_su->val);
1727
           unlock_user_struct(target_su, target_addr, 0);
1728
           break;
1729
        case GETALL:
1730
        case SETALL:
1731
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1732
               return -TARGET_EFAULT;
1733
           *host_su->array = tswap16(*target_su->array);
1734
           unlock_user_struct(target_su, target_addr, 0);
1735
           break;
1736
        default:
1737
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1738
    }
1739
    return 0;
1740
}
1741

    
1742
static inline abi_long host_to_target_semun(int cmd,
1743
                                            abi_ulong target_addr,
1744
                                            union semun *host_su,
1745
                                            struct semid_ds *ds)
1746
{
1747
    union target_semun *target_su;
1748

    
1749
    switch( cmd ) {
1750
        case IPC_STAT:
1751
        case IPC_SET:
1752
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1753
               return -TARGET_EFAULT;
1754
           host_to_target_semid_ds(target_su->buf,ds);
1755
           unlock_user_struct(target_su, target_addr, 1);
1756
           break;
1757
        case GETVAL:
1758
        case SETVAL:
1759
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1760
               return -TARGET_EFAULT;
1761
           target_su->val = tswapl(host_su->val);
1762
           unlock_user_struct(target_su, target_addr, 1);
1763
           break;
1764
        case GETALL:
1765
        case SETALL:
1766
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1767
               return -TARGET_EFAULT;
1768
           *target_su->array = tswap16(*host_su->array);
1769
           unlock_user_struct(target_su, target_addr, 1);
1770
           break;
1771
        default:
1772
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1773
    }
1774
    return 0;
1775
}
1776

    
1777
static inline abi_long do_semctl(int first, int second, int third,
1778
                                 abi_long ptr)
1779
{
1780
    union semun arg;
1781
    struct semid_ds dsarg;
1782
    int cmd = third&0xff;
1783
    abi_long ret = 0;
1784

    
1785
    switch( cmd ) {
1786
        case GETVAL:
1787
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1788
            ret = get_errno(semctl(first, second, cmd, arg));
1789
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1790
            break;
1791
        case SETVAL:
1792
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1793
            ret = get_errno(semctl(first, second, cmd, arg));
1794
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1795
            break;
1796
        case GETALL:
1797
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1798
            ret = get_errno(semctl(first, second, cmd, arg));
1799
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1800
            break;
1801
        case SETALL:
1802
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1803
            ret = get_errno(semctl(first, second, cmd, arg));
1804
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1805
            break;
1806
        case IPC_STAT:
1807
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1808
            ret = get_errno(semctl(first, second, cmd, arg));
1809
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1810
            break;
1811
        case IPC_SET:
1812
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1813
            ret = get_errno(semctl(first, second, cmd, arg));
1814
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1815
            break;
1816
    default:
1817
            ret = get_errno(semctl(first, second, cmd, arg));
1818
    }
1819

    
1820
    return ret;
1821
}
1822

    
1823
struct target_msqid_ds
1824
{
1825
  struct target_ipc_perm msg_perm;
1826
  abi_ulong msg_stime;
1827
  abi_ulong __unused1;
1828
  abi_ulong msg_rtime;
1829
  abi_ulong __unused2;
1830
  abi_ulong msg_ctime;
1831
  abi_ulong __unused3;
1832
  abi_ulong __msg_cbytes;
1833
  abi_ulong msg_qnum;
1834
  abi_ulong msg_qbytes;
1835
  abi_ulong msg_lspid;
1836
  abi_ulong msg_lrpid;
1837
  abi_ulong __unused4;
1838
  abi_ulong __unused5;
1839
};
1840

    
1841
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1842
                                               abi_ulong target_addr)
1843
{
1844
    struct target_msqid_ds *target_md;
1845

    
1846
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1847
        return -TARGET_EFAULT;
1848
    target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
1849
    host_md->msg_stime = tswapl(target_md->msg_stime);
1850
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
1851
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
1852
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1853
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
1854
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1855
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
1856
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1857
    unlock_user_struct(target_md, target_addr, 0);
1858
    return 0;
1859
}
1860

    
1861
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1862
                                               struct msqid_ds *host_md)
1863
{
1864
    struct target_msqid_ds *target_md;
1865

    
1866
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1867
        return -TARGET_EFAULT;
1868
    host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
1869
    target_md->msg_stime = tswapl(host_md->msg_stime);
1870
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
1871
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
1872
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1873
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
1874
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1875
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
1876
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1877
    unlock_user_struct(target_md, target_addr, 1);
1878
    return 0;
1879
}
1880

    
1881
static inline abi_long do_msgctl(int first, int second, abi_long ptr)
1882
{
1883
    struct msqid_ds dsarg;
1884
    int cmd = second&0xff;
1885
    abi_long ret = 0;
1886
    switch( cmd ) {
1887
    case IPC_STAT:
1888
    case IPC_SET:
1889
        target_to_host_msqid_ds(&dsarg,ptr);
1890
        ret = get_errno(msgctl(first, cmd, &dsarg));
1891
        host_to_target_msqid_ds(ptr,&dsarg);
1892
    default:
1893
        ret = get_errno(msgctl(first, cmd, &dsarg));
1894
    }
1895
    return ret;
1896
}
1897

    
1898
struct target_msgbuf {
1899
        abi_ulong mtype;
1900
        char        mtext[1];
1901
};
1902

    
1903
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1904
                                 unsigned int msgsz, int msgflg)
1905
{
1906
    struct target_msgbuf *target_mb;
1907
    struct msgbuf *host_mb;
1908
    abi_long ret = 0;
1909

    
1910
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1911
        return -TARGET_EFAULT;
1912
    host_mb = malloc(msgsz+sizeof(long));
1913
    host_mb->mtype = tswapl(target_mb->mtype);
1914
    memcpy(host_mb->mtext,target_mb->mtext,msgsz);
1915
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1916
    free(host_mb);
1917
    unlock_user_struct(target_mb, msgp, 0);
1918

    
1919
    return ret;
1920
}
1921

    
1922
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1923
                                 unsigned int msgsz, int msgtype,
1924
                                 int msgflg)
1925
{
1926
    struct target_msgbuf *target_mb;
1927
    char *target_mtext;
1928
    struct msgbuf *host_mb;
1929
    abi_long ret = 0;
1930

    
1931
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
1932
        return -TARGET_EFAULT;
1933
    host_mb = malloc(msgsz+sizeof(long));
1934
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
1935
    if (ret > 0) {
1936
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
1937
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
1938
        if (!target_mtext) {
1939
            ret = -TARGET_EFAULT;
1940
            goto end;
1941
        }
1942
            memcpy(target_mb->mtext, host_mb->mtext, ret);
1943
        unlock_user(target_mtext, target_mtext_addr, ret);
1944
    }
1945
    target_mb->mtype = tswapl(host_mb->mtype);
1946
    free(host_mb);
1947

    
1948
end:
1949
    if (target_mb)
1950
        unlock_user_struct(target_mb, msgp, 1);
1951
    return ret;
1952
}
1953

    
1954
/* ??? This only works with linear mappings.  */
1955
/* do_ipc() must return target values and target errnos. */
1956
static abi_long do_ipc(unsigned int call, int first,
1957
                       int second, int third,
1958
                       abi_long ptr, abi_long fifth)
1959
{
1960
    int version;
1961
    abi_long ret = 0;
1962
    struct shmid_ds shm_info;
1963
    int i;
1964

    
1965
    version = call >> 16;
1966
    call &= 0xffff;
1967

    
1968
    switch (call) {
1969
    case IPCOP_semop:
1970
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
1971
        break;
1972

    
1973
    case IPCOP_semget:
1974
        ret = get_errno(semget(first, second, third));
1975
        break;
1976

    
1977
    case IPCOP_semctl:
1978
        ret = do_semctl(first, second, third, ptr);
1979
        break;
1980

    
1981
    case IPCOP_semtimedop:
1982
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
1983
        ret = -TARGET_ENOSYS;
1984
        break;
1985

    
1986
        case IPCOP_msgget:
1987
                ret = get_errno(msgget(first, second));
1988
                break;
1989

    
1990
        case IPCOP_msgsnd:
1991
                ret = do_msgsnd(first, ptr, second, third);
1992
                break;
1993

    
1994
        case IPCOP_msgctl:
1995
                ret = do_msgctl(first, second, ptr);
1996
                break;
1997

    
1998
        case IPCOP_msgrcv:
1999
                {
2000
                      /* XXX: this code is not correct */
2001
                      struct ipc_kludge
2002
                      {
2003
                              void *__unbounded msgp;
2004
                              long int msgtyp;
2005
                      };
2006

    
2007
                      struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
2008
                      struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
2009

    
2010
                      ret = do_msgrcv(first, (long)msgp, second, 0, third);
2011

    
2012
                }
2013
                break;
2014

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

    
2060
    case IPCOP_shmget:
2061
        /* IPC_* flag values are the same on all linux platforms */
2062
        ret = get_errno(shmget(first, second, third));
2063
        break;
2064

    
2065
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2066
    case IPCOP_shmctl:
2067
        switch(second) {
2068
        case IPC_RMID:
2069
        case SHM_LOCK:
2070
        case SHM_UNLOCK:
2071
            ret = get_errno(shmctl(first, second, NULL));
2072
            break;
2073
        default:
2074
            goto unimplemented;
2075
        }
2076
        break;
2077
    default:
2078
    unimplemented:
2079
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2080
        ret = -TARGET_ENOSYS;
2081
        break;
2082
    }
2083
    return ret;
2084
}
2085
#endif
2086

    
2087
/* kernel structure types definitions */
2088
#define IFNAMSIZ        16
2089

    
2090
#define STRUCT(name, list...) STRUCT_ ## name,
2091
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2092
enum {
2093
#include "syscall_types.h"
2094
};
2095
#undef STRUCT
2096
#undef STRUCT_SPECIAL
2097

    
2098
#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2099
#define STRUCT_SPECIAL(name)
2100
#include "syscall_types.h"
2101
#undef STRUCT
2102
#undef STRUCT_SPECIAL
2103

    
2104
typedef struct IOCTLEntry {
2105
    unsigned int target_cmd;
2106
    unsigned int host_cmd;
2107
    const char *name;
2108
    int access;
2109
    const argtype arg_type[5];
2110
} IOCTLEntry;
2111

    
2112
#define IOC_R 0x0001
2113
#define IOC_W 0x0002
2114
#define IOC_RW (IOC_R | IOC_W)
2115

    
2116
#define MAX_STRUCT_SIZE 4096
2117

    
2118
IOCTLEntry ioctl_entries[] = {
2119
#define IOCTL(cmd, access, types...) \
2120
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2121
#include "ioctls.h"
2122
    { 0, 0, },
2123
};
2124

    
2125
/* ??? Implement proper locking for ioctls.  */
2126
/* do_ioctl() Must return target values and target errnos. */
2127
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2128
{
2129
    const IOCTLEntry *ie;
2130
    const argtype *arg_type;
2131
    abi_long ret;
2132
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2133
    int target_size;
2134
    void *argptr;
2135

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

    
2209
bitmask_transtbl iflag_tbl[] = {
2210
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2211
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2212
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2213
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2214
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2215
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2216
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2217
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2218
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2219
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2220
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2221
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2222
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2223
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2224
        { 0, 0, 0, 0 }
2225
};
2226

    
2227
bitmask_transtbl oflag_tbl[] = {
2228
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2229
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2230
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2231
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2232
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2233
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2234
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2235
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2236
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2237
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2238
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2239
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2240
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2241
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2242
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2243
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2244
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2245
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2246
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2247
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2248
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2249
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2250
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2251
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2252
        { 0, 0, 0, 0 }
2253
};
2254

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

    
2290
bitmask_transtbl lflag_tbl[] = {
2291
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2292
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2293
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2294
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2295
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2296
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2297
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2298
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2299
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2300
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2301
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2302
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2303
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2304
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2305
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2306
        { 0, 0, 0, 0 }
2307
};
2308

    
2309
static void target_to_host_termios (void *dst, const void *src)
2310
{
2311
    struct host_termios *host = dst;
2312
    const struct target_termios *target = src;
2313

    
2314
    host->c_iflag =
2315
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2316
    host->c_oflag =
2317
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2318
    host->c_cflag =
2319
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2320
    host->c_lflag =
2321
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2322
    host->c_line = target->c_line;
2323

    
2324
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2325
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2326
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2327
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2328
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2329
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2330
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2331
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2332
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2333
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2334
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2335
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2336
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2337
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2338
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2339
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2340
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2341
}
2342

    
2343
static void host_to_target_termios (void *dst, const void *src)
2344
{
2345
    struct target_termios *target = dst;
2346
    const struct host_termios *host = src;
2347

    
2348
    target->c_iflag =
2349
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2350
    target->c_oflag =
2351
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2352
    target->c_cflag =
2353
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2354
    target->c_lflag =
2355
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2356
    target->c_line = host->c_line;
2357

    
2358
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2359
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2360
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2361
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2362
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2363
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2364
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2365
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2366
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2367
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2368
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2369
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2370
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2371
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2372
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2373
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2374
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2375
}
2376

    
2377
StructEntry struct_termios_def = {
2378
    .convert = { host_to_target_termios, target_to_host_termios },
2379
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2380
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2381
};
2382

    
2383
static bitmask_transtbl mmap_flags_tbl[] = {
2384
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2385
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2386
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2387
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2388
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2389
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2390
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2391
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2392
        { 0, 0, 0, 0 }
2393
};
2394

    
2395
static bitmask_transtbl fcntl_flags_tbl[] = {
2396
        { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
2397
        { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
2398
        { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
2399
        { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
2400
        { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
2401
        { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
2402
        { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
2403
        { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
2404
        { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
2405
        { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
2406
        { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2407
        { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
2408
        { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2409
#if defined(O_DIRECT)
2410
        { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
2411
#endif
2412
        { 0, 0, 0, 0 }
2413
};
2414

    
2415
#if defined(TARGET_I386)
2416

    
2417
/* NOTE: there is really one LDT for all the threads */
2418
uint8_t *ldt_table;
2419

    
2420
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2421
{
2422
    int size;
2423
    void *p;
2424

    
2425
    if (!ldt_table)
2426
        return 0;
2427
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2428
    if (size > bytecount)
2429
        size = bytecount;
2430
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
2431
    if (!p)
2432
        return -TARGET_EFAULT;
2433
    /* ??? Should this by byteswapped?  */
2434
    memcpy(p, ldt_table, size);
2435
    unlock_user(p, ptr, size);
2436
    return size;
2437
}
2438

    
2439
/* XXX: add locking support */
2440
static abi_long write_ldt(CPUX86State *env,
2441
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
2442
{
2443
    struct target_modify_ldt_ldt_s ldt_info;
2444
    struct target_modify_ldt_ldt_s *target_ldt_info;
2445
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2446
    int seg_not_present, useable, lm;
2447
    uint32_t *lp, entry_1, entry_2;
2448

    
2449
    if (bytecount != sizeof(ldt_info))
2450
        return -TARGET_EINVAL;
2451
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2452
        return -TARGET_EFAULT;
2453
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2454
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2455
    ldt_info.limit = tswap32(target_ldt_info->limit);
2456
    ldt_info.flags = tswap32(target_ldt_info->flags);
2457
    unlock_user_struct(target_ldt_info, ptr, 0);
2458

    
2459
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2460
        return -TARGET_EINVAL;
2461
    seg_32bit = ldt_info.flags & 1;
2462
    contents = (ldt_info.flags >> 1) & 3;
2463
    read_exec_only = (ldt_info.flags >> 3) & 1;
2464
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2465
    seg_not_present = (ldt_info.flags >> 5) & 1;
2466
    useable = (ldt_info.flags >> 6) & 1;
2467
#ifdef TARGET_ABI32
2468
    lm = 0;
2469
#else
2470
    lm = (ldt_info.flags >> 7) & 1;
2471
#endif
2472
    if (contents == 3) {
2473
        if (oldmode)
2474
            return -TARGET_EINVAL;
2475
        if (seg_not_present == 0)
2476
            return -TARGET_EINVAL;
2477
    }
2478
    /* allocate the LDT */
2479
    if (!ldt_table) {
2480
        ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2481
        if (!ldt_table)
2482
            return -TARGET_ENOMEM;
2483
        memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2484
        env->ldt.base = h2g((unsigned long)ldt_table);
2485
        env->ldt.limit = 0xffff;
2486
    }
2487

    
2488
    /* NOTE: same code as Linux kernel */
2489
    /* Allow LDTs to be cleared by the user. */
2490
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2491
        if (oldmode ||
2492
            (contents == 0                &&
2493
             read_exec_only == 1        &&
2494
             seg_32bit == 0                &&
2495
             limit_in_pages == 0        &&
2496
             seg_not_present == 1        &&
2497
             useable == 0 )) {
2498
            entry_1 = 0;
2499
            entry_2 = 0;
2500
            goto install;
2501
        }
2502
    }
2503

    
2504
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2505
        (ldt_info.limit & 0x0ffff);
2506
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2507
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2508
        (ldt_info.limit & 0xf0000) |
2509
        ((read_exec_only ^ 1) << 9) |
2510
        (contents << 10) |
2511
        ((seg_not_present ^ 1) << 15) |
2512
        (seg_32bit << 22) |
2513
        (limit_in_pages << 23) |
2514
        (lm << 21) |
2515
        0x7000;
2516
    if (!oldmode)
2517
        entry_2 |= (useable << 20);
2518

    
2519
    /* Install the new entry ...  */
2520
install:
2521
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2522
    lp[0] = tswap32(entry_1);
2523
    lp[1] = tswap32(entry_2);
2524
    return 0;
2525
}
2526

    
2527
/* specific and weird i386 syscalls */
2528
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2529
                              unsigned long bytecount)
2530
{
2531
    abi_long ret;
2532

    
2533
    switch (func) {
2534
    case 0:
2535
        ret = read_ldt(ptr, bytecount);
2536
        break;
2537
    case 1:
2538
        ret = write_ldt(env, ptr, bytecount, 1);
2539
        break;
2540
    case 0x11:
2541
        ret = write_ldt(env, ptr, bytecount, 0);
2542
        break;
2543
    default:
2544
        ret = -TARGET_ENOSYS;
2545
        break;
2546
    }
2547
    return ret;
2548
}
2549

    
2550
#if defined(TARGET_I386) && defined(TARGET_ABI32)
2551
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2552
{
2553
    uint64_t *gdt_table = g2h(env->gdt.base);
2554
    struct target_modify_ldt_ldt_s ldt_info;
2555
    struct target_modify_ldt_ldt_s *target_ldt_info;
2556
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2557
    int seg_not_present, useable, lm;
2558
    uint32_t *lp, entry_1, entry_2;
2559
    int i;
2560

    
2561
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2562
    if (!target_ldt_info)
2563
        return -TARGET_EFAULT;
2564
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2565
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2566
    ldt_info.limit = tswap32(target_ldt_info->limit);
2567
    ldt_info.flags = tswap32(target_ldt_info->flags);
2568
    if (ldt_info.entry_number == -1) {
2569
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2570
            if (gdt_table[i] == 0) {
2571
                ldt_info.entry_number = i;
2572
                target_ldt_info->entry_number = tswap32(i);
2573
                break;
2574
            }
2575
        }
2576
    }
2577
    unlock_user_struct(target_ldt_info, ptr, 1);
2578

    
2579
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
2580
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2581
           return -TARGET_EINVAL;
2582
    seg_32bit = ldt_info.flags & 1;
2583
    contents = (ldt_info.flags >> 1) & 3;
2584
    read_exec_only = (ldt_info.flags >> 3) & 1;
2585
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2586
    seg_not_present = (ldt_info.flags >> 5) & 1;
2587
    useable = (ldt_info.flags >> 6) & 1;
2588
#ifdef TARGET_ABI32
2589
    lm = 0;
2590
#else
2591
    lm = (ldt_info.flags >> 7) & 1;
2592
#endif
2593

    
2594
    if (contents == 3) {
2595
        if (seg_not_present == 0)
2596
            return -TARGET_EINVAL;
2597
    }
2598

    
2599
    /* NOTE: same code as Linux kernel */
2600
    /* Allow LDTs to be cleared by the user. */
2601
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2602
        if ((contents == 0             &&
2603
             read_exec_only == 1       &&
2604
             seg_32bit == 0            &&
2605
             limit_in_pages == 0       &&
2606
             seg_not_present == 1      &&
2607
             useable == 0 )) {
2608
            entry_1 = 0;
2609
            entry_2 = 0;
2610
            goto install;
2611
        }
2612
    }
2613

    
2614
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2615
        (ldt_info.limit & 0x0ffff);
2616
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2617
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2618
        (ldt_info.limit & 0xf0000) |
2619
        ((read_exec_only ^ 1) << 9) |
2620
        (contents << 10) |
2621
        ((seg_not_present ^ 1) << 15) |
2622
        (seg_32bit << 22) |
2623
        (limit_in_pages << 23) |
2624
        (useable << 20) |
2625
        (lm << 21) |
2626
        0x7000;
2627

    
2628
    /* Install the new entry ...  */
2629
install:
2630
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2631
    lp[0] = tswap32(entry_1);
2632
    lp[1] = tswap32(entry_2);
2633
    return 0;
2634
}
2635

    
2636
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2637
{
2638
    struct target_modify_ldt_ldt_s *target_ldt_info;
2639
    uint64_t *gdt_table = g2h(env->gdt.base);
2640
    uint32_t base_addr, limit, flags;
2641
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2642
    int seg_not_present, useable, lm;
2643
    uint32_t *lp, entry_1, entry_2;
2644

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

    
2684
#ifndef TARGET_ABI32
2685
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2686
{
2687
    abi_long ret;
2688
    abi_ulong val;
2689
    int idx;
2690
    
2691
    switch(code) {
2692
    case TARGET_ARCH_SET_GS:
2693
    case TARGET_ARCH_SET_FS:
2694
        if (code == TARGET_ARCH_SET_GS)
2695
            idx = R_GS;
2696
        else
2697
            idx = R_FS;
2698
        cpu_x86_load_seg(env, idx, 0);
2699
        env->segs[idx].base = addr;
2700
        break;
2701
    case TARGET_ARCH_GET_GS:
2702
    case TARGET_ARCH_GET_FS:
2703
        if (code == TARGET_ARCH_GET_GS)
2704
            idx = R_GS;
2705
        else
2706
            idx = R_FS;
2707
        val = env->segs[idx].base;
2708
        if (put_user(val, addr, abi_ulong))
2709
            return -TARGET_EFAULT;
2710
        break;
2711
    default:
2712
        ret = -TARGET_EINVAL;
2713
        break;
2714
    }
2715
    return 0;
2716
}
2717
#endif
2718

    
2719
#endif /* defined(TARGET_I386) */
2720

    
2721
#if defined(USE_NPTL)
2722

    
2723
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2724

    
2725
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2726
typedef struct {
2727
    CPUState *env;
2728
    pthread_mutex_t mutex;
2729
    pthread_cond_t cond;
2730
    pthread_t thread;
2731
    uint32_t tid;
2732
    abi_ulong child_tidptr;
2733
    abi_ulong parent_tidptr;
2734
    sigset_t sigmask;
2735
} new_thread_info;
2736

    
2737
static void *clone_func(void *arg)
2738
{
2739
    new_thread_info *info = arg;
2740
    CPUState *env;
2741

    
2742
    env = info->env;
2743
    thread_env = env;
2744
    info->tid = gettid();
2745
    if (info->child_tidptr)
2746
        put_user_u32(info->tid, info->child_tidptr);
2747
    if (info->parent_tidptr)
2748
        put_user_u32(info->tid, info->parent_tidptr);
2749
    /* Enable signals.  */
2750
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2751
    /* Signal to the parent that we're ready.  */
2752
    pthread_mutex_lock(&info->mutex);
2753
    pthread_cond_broadcast(&info->cond);
2754
    pthread_mutex_unlock(&info->mutex);
2755
    /* Wait until the parent has finshed initializing the tls state.  */
2756
    pthread_mutex_lock(&clone_lock);
2757
    pthread_mutex_unlock(&clone_lock);
2758
    cpu_loop(env);
2759
    /* never exits */
2760
    return NULL;
2761
}
2762
#else
2763
/* this stack is the equivalent of the kernel stack associated with a
2764
   thread/process */
2765
#define NEW_STACK_SIZE 8192
2766

    
2767
static int clone_func(void *arg)
2768
{
2769
    CPUState *env = arg;
2770
    cpu_loop(env);
2771
    /* never exits */
2772
    return 0;
2773
}
2774
#endif
2775

    
2776
/* do_fork() Must return host values and target errnos (unlike most
2777
   do_*() functions). */
2778
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2779
                   abi_ulong parent_tidptr, target_ulong newtls,
2780
                   abi_ulong child_tidptr)
2781
{
2782
    int ret;
2783
    TaskState *ts;
2784
    uint8_t *new_stack;
2785
    CPUState *new_env;
2786
#if defined(USE_NPTL)
2787
    unsigned int nptl_flags;
2788
    sigset_t sigmask;
2789
#endif
2790

    
2791
    if (flags & CLONE_VM) {
2792
#if defined(USE_NPTL)
2793
        new_thread_info info;
2794
        pthread_attr_t attr;
2795
#endif
2796
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2797
        init_task_state(ts);
2798
        new_stack = ts->stack;
2799
        /* we create a new CPU instance. */
2800
        new_env = cpu_copy(env);
2801
        /* Init regs that differ from the parent.  */
2802
        cpu_clone_regs(new_env, newsp);
2803
        new_env->opaque = ts;
2804
#if defined(USE_NPTL)
2805
        nptl_flags = flags;
2806
        flags &= ~CLONE_NPTL_FLAGS2;
2807

    
2808
        /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2809
        if (nptl_flags & CLONE_SETTLS)
2810
            cpu_set_tls (new_env, newtls);
2811

    
2812
        /* Grab a mutex so that thread setup appears atomic.  */
2813
        pthread_mutex_lock(&clone_lock);
2814

    
2815
        memset(&info, 0, sizeof(info));
2816
        pthread_mutex_init(&info.mutex, NULL);
2817
        pthread_mutex_lock(&info.mutex);
2818
        pthread_cond_init(&info.cond, NULL);
2819
        info.env = new_env;
2820
        if (nptl_flags & CLONE_CHILD_SETTID)
2821
            info.child_tidptr = child_tidptr;
2822
        if (nptl_flags & CLONE_PARENT_SETTID)
2823
            info.parent_tidptr = parent_tidptr;
2824

    
2825
        ret = pthread_attr_init(&attr);
2826
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2827
        /* It is not safe to deliver signals until the child has finished
2828
           initializing, so temporarily block all signals.  */
2829
        sigfillset(&sigmask);
2830
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2831

    
2832
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
2833

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

    
2896
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2897
{
2898
    struct flock fl;
2899
    struct target_flock *target_fl;
2900
    struct flock64 fl64;
2901
    struct target_flock64 *target_fl64;
2902
    abi_long ret;
2903

    
2904
    switch(cmd) {
2905
    case TARGET_F_GETLK:
2906
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2907
            return -TARGET_EFAULT;
2908
        fl.l_type = tswap16(target_fl->l_type);
2909
        fl.l_whence = tswap16(target_fl->l_whence);
2910
        fl.l_start = tswapl(target_fl->l_start);
2911
        fl.l_len = tswapl(target_fl->l_len);
2912
        fl.l_pid = tswapl(target_fl->l_pid);
2913
        unlock_user_struct(target_fl, arg, 0);
2914
        ret = get_errno(fcntl(fd, cmd, &fl));
2915
        if (ret == 0) {
2916
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
2917
                return -TARGET_EFAULT;
2918
            target_fl->l_type = tswap16(fl.l_type);
2919
            target_fl->l_whence = tswap16(fl.l_whence);
2920
            target_fl->l_start = tswapl(fl.l_start);
2921
            target_fl->l_len = tswapl(fl.l_len);
2922
            target_fl->l_pid = tswapl(fl.l_pid);
2923
            unlock_user_struct(target_fl, arg, 1);
2924
        }
2925
        break;
2926

    
2927
    case TARGET_F_SETLK:
2928
    case TARGET_F_SETLKW:
2929
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2930
            return -TARGET_EFAULT;
2931
        fl.l_type = tswap16(target_fl->l_type);
2932
        fl.l_whence = tswap16(target_fl->l_whence);
2933
        fl.l_start = tswapl(target_fl->l_start);
2934
        fl.l_len = tswapl(target_fl->l_len);
2935
        fl.l_pid = tswapl(target_fl->l_pid);
2936
        unlock_user_struct(target_fl, arg, 0);
2937
        ret = get_errno(fcntl(fd, cmd, &fl));
2938
        break;
2939

    
2940
    case TARGET_F_GETLK64:
2941
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2942
            return -TARGET_EFAULT;
2943
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2944
        fl64.l_whence = tswap16(target_fl64->l_whence);
2945
        fl64.l_start = tswapl(target_fl64->l_start);
2946
        fl64.l_len = tswapl(target_fl64->l_len);
2947
        fl64.l_pid = tswap16(target_fl64->l_pid);
2948
        unlock_user_struct(target_fl64, arg, 0);
2949
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2950
        if (ret == 0) {
2951
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
2952
                return -TARGET_EFAULT;
2953
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
2954
            target_fl64->l_whence = tswap16(fl64.l_whence);
2955
            target_fl64->l_start = tswapl(fl64.l_start);
2956
            target_fl64->l_len = tswapl(fl64.l_len);
2957
            target_fl64->l_pid = tswapl(fl64.l_pid);
2958
            unlock_user_struct(target_fl64, arg, 1);
2959
        }
2960
        break;
2961
    case TARGET_F_SETLK64:
2962
    case TARGET_F_SETLKW64:
2963
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2964
            return -TARGET_EFAULT;
2965
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2966
        fl64.l_whence = tswap16(target_fl64->l_whence);
2967
        fl64.l_start = tswapl(target_fl64->l_start);
2968
        fl64.l_len = tswapl(target_fl64->l_len);
2969
        fl64.l_pid = tswap16(target_fl64->l_pid);
2970
        unlock_user_struct(target_fl64, arg, 0);
2971
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2972
        break;
2973

    
2974
    case F_GETFL:
2975
        ret = get_errno(fcntl(fd, cmd, arg));
2976
        if (ret >= 0) {
2977
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
2978
        }
2979
        break;
2980

    
2981
    case F_SETFL:
2982
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
2983
        break;
2984

    
2985
    default:
2986
        ret = get_errno(fcntl(fd, cmd, arg));
2987
        break;
2988
    }
2989
    return ret;
2990
}
2991

    
2992
#ifdef USE_UID16
2993

    
2994
static inline int high2lowuid(int uid)
2995
{
2996
    if (uid > 65535)
2997
        return 65534;
2998
    else
2999
        return uid;
3000
}
3001

    
3002
static inline int high2lowgid(int gid)
3003
{
3004
    if (gid > 65535)
3005
        return 65534;
3006
    else
3007
        return gid;
3008
}
3009

    
3010
static inline int low2highuid(int uid)
3011
{
3012
    if ((int16_t)uid == -1)
3013
        return -1;
3014
    else
3015
        return uid;
3016
}
3017

    
3018
static inline int low2highgid(int gid)
3019
{
3020
    if ((int16_t)gid == -1)
3021
        return -1;
3022
    else
3023
        return gid;
3024
}
3025

    
3026
#endif /* USE_UID16 */
3027

    
3028
void syscall_init(void)
3029
{
3030
    IOCTLEntry *ie;
3031
    const argtype *arg_type;
3032
    int size;
3033
    int i;
3034

    
3035
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3036
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3037
#include "syscall_types.h"
3038
#undef STRUCT
3039
#undef STRUCT_SPECIAL
3040

    
3041
    /* we patch the ioctl size if necessary. We rely on the fact that
3042
       no ioctl has all the bits at '1' in the size field */
3043
    ie = ioctl_entries;
3044
    while (ie->target_cmd != 0) {
3045
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3046
            TARGET_IOC_SIZEMASK) {
3047
            arg_type = ie->arg_type;
3048
            if (arg_type[0] != TYPE_PTR) {
3049
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3050
                        ie->target_cmd);
3051
                exit(1);
3052
            }
3053
            arg_type++;
3054
            size = thunk_type_size(arg_type, 0);
3055
            ie->target_cmd = (ie->target_cmd &
3056
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3057
                (size << TARGET_IOC_SIZESHIFT);
3058
        }
3059

    
3060
        /* Build target_to_host_errno_table[] table from
3061
         * host_to_target_errno_table[]. */
3062
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3063
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3064

    
3065
        /* automatic consistency check if same arch */
3066
#if defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)
3067
        if (ie->target_cmd != ie->host_cmd) {
3068
            fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",
3069
                    ie->target_cmd, ie->host_cmd);
3070
        }
3071
#endif
3072
        ie++;
3073
    }
3074
}
3075

    
3076
#if TARGET_ABI_BITS == 32
3077
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3078
{
3079
#ifdef TARGET_WORDS_BIGENDIAN
3080
    return ((uint64_t)word0 << 32) | word1;
3081
#else
3082
    return ((uint64_t)word1 << 32) | word0;
3083
#endif
3084
}
3085
#else /* TARGET_ABI_BITS == 32 */
3086
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3087
{
3088
    return word0;
3089
}
3090
#endif /* TARGET_ABI_BITS != 32 */
3091

    
3092
#ifdef TARGET_NR_truncate64
3093
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3094
                                         abi_long arg2,
3095
                                         abi_long arg3,
3096
                                         abi_long arg4)
3097
{
3098
#ifdef TARGET_ARM
3099
    if (((CPUARMState *)cpu_env)->eabi)
3100
      {
3101
        arg2 = arg3;
3102
        arg3 = arg4;
3103
      }
3104
#endif
3105
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3106
}
3107
#endif
3108

    
3109
#ifdef TARGET_NR_ftruncate64
3110
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3111
                                          abi_long arg2,
3112
                                          abi_long arg3,
3113
                                          abi_long arg4)
3114
{
3115
#ifdef TARGET_ARM
3116
    if (((CPUARMState *)cpu_env)->eabi)
3117
      {
3118
        arg2 = arg3;
3119
        arg3 = arg4;
3120
      }
3121
#endif
3122
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3123
}
3124
#endif
3125

    
3126
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3127
                                               abi_ulong target_addr)
3128
{
3129
    struct target_timespec *target_ts;
3130

    
3131
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3132
        return -TARGET_EFAULT;
3133
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3134
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3135
    unlock_user_struct(target_ts, target_addr, 0);
3136
    return 0;
3137
}
3138

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

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

    
3152
#if defined(USE_NPTL)
3153
/* ??? Using host futex calls even when target atomic operations
3154
   are not really atomic probably breaks things.  However implementing
3155
   futexes locally would make futexes shared between multiple processes
3156
   tricky.  However they're probably useless because guest atomic
3157
   operations won't work either.  */
3158
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3159
                    target_ulong uaddr2, int val3)
3160
{
3161
    struct timespec ts, *pts;
3162

    
3163
    /* ??? We assume FUTEX_* constants are the same on both host
3164
       and target.  */
3165
    switch (op) {
3166
    case FUTEX_WAIT:
3167
        if (timeout) {
3168
            pts = &ts;
3169
            target_to_host_timespec(pts, timeout);
3170
        } else {
3171
            pts = NULL;
3172
        }
3173
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3174
                         pts, NULL, 0));
3175
    case FUTEX_WAKE:
3176
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3177
    case FUTEX_FD:
3178
        return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3179
    case FUTEX_REQUEUE:
3180
        return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3181
                         NULL, g2h(uaddr2), 0));
3182
    case FUTEX_CMP_REQUEUE:
3183
        return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3184
                         NULL, g2h(uaddr2), tswap32(val3)));
3185
    default:
3186
        return -TARGET_ENOSYS;
3187
    }
3188
}
3189
#endif
3190

    
3191
int get_osversion(void)
3192
{
3193
    static int osversion;
3194
    struct new_utsname buf;
3195
    const char *s;
3196
    int i, n, tmp;
3197
    if (osversion)
3198
        return osversion;
3199
    if (qemu_uname_release && *qemu_uname_release) {
3200
        s = qemu_uname_release;
3201
    } else {
3202
        if (sys_uname(&buf))
3203
            return 0;
3204
        s = buf.release;
3205
    }
3206
    tmp = 0;
3207
    for (i = 0; i < 3; i++) {
3208
        n = 0;
3209
        while (*s >= '0' && *s <= '9') {
3210
            n *= 10;
3211
            n += *s - '0';
3212
            s++;
3213
        }
3214
        tmp = (tmp << 8) + n;
3215
        if (*s == '.')
3216
            s++;
3217
    }
3218
    osversion = tmp;
3219
    return osversion;
3220
}
3221

    
3222
/* do_syscall() should always have a single exit point at the end so
3223
   that actions, such as logging of syscall results, can be performed.
3224
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3225
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3226
                    abi_long arg2, abi_long arg3, abi_long arg4,
3227
                    abi_long arg5, abi_long arg6)
3228
{
3229
    abi_long ret;
3230
    struct stat st;
3231
    struct statfs stfs;
3232
    void *p;
3233

    
3234
#ifdef DEBUG
3235
    gemu_log("syscall %d", num);
3236
#endif
3237
    if(do_strace)
3238
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3239

    
3240
    switch(num) {
3241
    case TARGET_NR_exit:
3242
#ifdef HAVE_GPROF
3243
        _mcleanup();
3244
#endif
3245
        gdb_exit(cpu_env, arg1);
3246
        /* XXX: should free thread stack and CPU env */
3247
        _exit(arg1);
3248
        ret = 0; /* avoid warning */
3249
        break;
3250
    case TARGET_NR_read:
3251
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3252
            goto efault;
3253
        ret = get_errno(read(arg1, p, arg3));
3254
        unlock_user(p, arg2, ret);
3255
        break;
3256
    case TARGET_NR_write:
3257
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3258
            goto efault;
3259
        ret = get_errno(write(arg1, p, arg3));
3260
        unlock_user(p, arg2, 0);
3261
        break;
3262
    case TARGET_NR_open:
3263
        if (!(p = lock_user_string(arg1)))
3264
            goto efault;
3265
        ret = get_errno(open(path(p),
3266
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
3267
                             arg3));
3268
        unlock_user(p, arg1, 0);
3269
        break;
3270
#if defined(TARGET_NR_openat) && defined(__NR_openat)
3271
    case TARGET_NR_openat:
3272
        if (!(p = lock_user_string(arg2)))
3273
            goto efault;
3274
        ret = get_errno(sys_openat(arg1,
3275
                                   path(p),
3276
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
3277
                                   arg4));
3278
        unlock_user(p, arg2, 0);
3279
        break;
3280
#endif
3281
    case TARGET_NR_close:
3282
        ret = get_errno(close(arg1));
3283
        break;
3284
    case TARGET_NR_brk:
3285
        ret = do_brk(arg1);
3286
        break;
3287
    case TARGET_NR_fork:
3288
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3289
        break;
3290
#ifdef TARGET_NR_waitpid
3291
    case TARGET_NR_waitpid:
3292
        {
3293
            int status;
3294
            ret = get_errno(waitpid(arg1, &status, arg3));
3295
            if (!is_error(ret) && arg2
3296
                && put_user_s32(status, arg2))
3297
                goto efault;
3298
        }
3299
        break;
3300
#endif
3301
#ifdef TARGET_NR_waitid
3302
    case TARGET_NR_waitid:
3303
        {
3304
            siginfo_t info;
3305
            info.si_pid = 0;
3306
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
3307
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
3308
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3309
                    goto efault;
3310
                host_to_target_siginfo(p, &info);
3311
                unlock_user(p, arg3, sizeof(target_siginfo_t));
3312
            }
3313
        }
3314
        break;
3315
#endif
3316
#ifdef TARGET_NR_creat /* not on alpha */
3317
    case TARGET_NR_creat:
3318
        if (!(p = lock_user_string(arg1)))
3319
            goto efault;
3320
        ret = get_errno(creat(p, arg2));
3321
        unlock_user(p, arg1, 0);
3322
        break;
3323
#endif
3324
    case TARGET_NR_link:
3325
        {
3326
            void * p2;
3327
            p = lock_user_string(arg1);
3328
            p2 = lock_user_string(arg2);
3329
            if (!p || !p2)
3330
                ret = -TARGET_EFAULT;
3331
            else
3332
                ret = get_errno(link(p, p2));
3333
            unlock_user(p2, arg2, 0);
3334
            unlock_user(p, arg1, 0);
3335
        }
3336
        break;
3337
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3338
    case TARGET_NR_linkat:
3339
        {
3340
            void * p2 = NULL;
3341
            if (!arg2 || !arg4)
3342
                goto efault;
3343
            p  = lock_user_string(arg2);
3344
            p2 = lock_user_string(arg4);
3345
            if (!p || !p2)
3346
                ret = -TARGET_EFAULT;
3347
            else
3348
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3349
            unlock_user(p, arg2, 0);
3350
            unlock_user(p2, arg4, 0);
3351
        }
3352
        break;
3353
#endif
3354
    case TARGET_NR_unlink:
3355
        if (!(p = lock_user_string(arg1)))
3356
            goto efault;
3357
        ret = get_errno(unlink(p));
3358
        unlock_user(p, arg1, 0);
3359
        break;
3360
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3361
    case TARGET_NR_unlinkat:
3362
        if (!(p = lock_user_string(arg2)))
3363
            goto efault;
3364
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
3365
        unlock_user(p, arg2, 0);
3366
        break;
3367
#endif
3368
    case TARGET_NR_execve:
3369
        {
3370
            char **argp, **envp;
3371
            int argc, envc;
3372
            abi_ulong gp;
3373
            abi_ulong guest_argp;
3374
            abi_ulong guest_envp;
3375
            abi_ulong addr;
3376
            char **q;
3377

    
3378
            argc = 0;
3379
            guest_argp = arg2;
3380
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3381
                if (get_user_ual(addr, gp))
3382
                    goto efault;
3383
                if (!addr)
3384
                    break;
3385
                argc++;
3386
            }
3387
            envc = 0;
3388
            guest_envp = arg3;
3389
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3390
                if (get_user_ual(addr, gp))
3391
                    goto efault;
3392
                if (!addr)
3393
                    break;
3394
                envc++;
3395
            }
3396

    
3397
            argp = alloca((argc + 1) * sizeof(void *));
3398
            envp = alloca((envc + 1) * sizeof(void *));
3399

    
3400
            for (gp = guest_argp, q = argp; gp;
3401
                  gp += sizeof(abi_ulong), q++) {
3402
                if (get_user_ual(addr, gp))
3403
                    goto execve_efault;
3404
                if (!addr)
3405
                    break;
3406
                if (!(*q = lock_user_string(addr)))
3407
                    goto execve_efault;
3408
            }
3409
            *q = NULL;
3410

    
3411
            for (gp = guest_envp, q = envp; gp;
3412
                  gp += sizeof(abi_ulong), q++) {
3413
                if (get_user_ual(addr, gp))
3414
                    goto execve_efault;
3415
                if (!addr)
3416
                    break;
3417
                if (!(*q = lock_user_string(addr)))
3418
                    goto execve_efault;
3419
            }
3420
            *q = NULL;
3421

    
3422
            if (!(p = lock_user_string(arg1)))
3423
                goto execve_efault;
3424
            ret = get_errno(execve(p, argp, envp));
3425
            unlock_user(p, arg1, 0);
3426

    
3427
            goto execve_end;
3428

    
3429
        execve_efault:
3430
            ret = -TARGET_EFAULT;
3431

    
3432
        execve_end:
3433
            for (gp = guest_argp, q = argp; *q;
3434
                  gp += sizeof(abi_ulong), q++) {
3435
                if (get_user_ual(addr, gp)
3436
                    || !addr)
3437
                    break;
3438
                unlock_user(*q, addr, 0);
3439
            }
3440
            for (gp = guest_envp, q = envp; *q;
3441
                  gp += sizeof(abi_ulong), q++) {
3442
                if (get_user_ual(addr, gp)
3443
                    || !addr)
3444
                    break;
3445
                unlock_user(*q, addr, 0);
3446
            }
3447
        }
3448
        break;
3449
    case TARGET_NR_chdir:
3450
        if (!(p = lock_user_string(arg1)))
3451
            goto efault;
3452
        ret = get_errno(chdir(p));
3453
        unlock_user(p, arg1, 0);
3454
        break;
3455
#ifdef TARGET_NR_time
3456
    case TARGET_NR_time:
3457
        {
3458
            time_t host_time;
3459
            ret = get_errno(time(&host_time));
3460
            if (!is_error(ret)
3461
                && arg1
3462
                && put_user_sal(host_time, arg1))
3463
                goto efault;
3464
        }
3465
        break;
3466
#endif
3467
    case TARGET_NR_mknod:
3468
        if (!(p = lock_user_string(arg1)))
3469
            goto efault;
3470
        ret = get_errno(mknod(p, arg2, arg3));
3471
        unlock_user(p, arg1, 0);
3472
        break;
3473
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3474
    case TARGET_NR_mknodat:
3475
        if (!(p = lock_user_string(arg2)))
3476
            goto efault;
3477
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3478
        unlock_user(p, arg2, 0);
3479
        break;
3480
#endif
3481
    case TARGET_NR_chmod:
3482
        if (!(p = lock_user_string(arg1)))
3483
            goto efault;
3484
        ret = get_errno(chmod(p, arg2));
3485
        unlock_user(p, arg1, 0);
3486
        break;
3487
#ifdef TARGET_NR_break
3488
    case TARGET_NR_break:
3489
        goto unimplemented;
3490
#endif
3491
#ifdef TARGET_NR_oldstat
3492
    case TARGET_NR_oldstat:
3493
        goto unimplemented;
3494
#endif
3495
    case TARGET_NR_lseek:
3496
        ret = get_errno(lseek(arg1, arg2, arg3));
3497
        break;
3498
#ifdef TARGET_NR_getxpid
3499
    case TARGET_NR_getxpid:
3500
#else
3501
    case TARGET_NR_getpid:
3502
#endif
3503
        ret = get_errno(getpid());
3504
        break;
3505
    case TARGET_NR_mount:
3506
                {
3507
                        /* need to look at the data field */
3508
                        void *p2, *p3;
3509
                        p = lock_user_string(arg1);
3510
                        p2 = lock_user_string(arg2);
3511
                        p3 = lock_user_string(arg3);
3512
                        if (!p || !p2 || !p3)
3513
                            ret = -TARGET_EFAULT;
3514
                        else
3515
                            /* FIXME - arg5 should be locked, but it isn't clear how to
3516
                             * do that since it's not guaranteed to be a NULL-terminated
3517
                             * string.
3518
                             */
3519
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3520
                        unlock_user(p, arg1, 0);
3521
                        unlock_user(p2, arg2, 0);
3522
                        unlock_user(p3, arg3, 0);
3523
                        break;
3524
                }
3525
#ifdef TARGET_NR_umount
3526
    case TARGET_NR_umount:
3527
        if (!(p = lock_user_string(arg1)))
3528
            goto efault;
3529
        ret = get_errno(umount(p));
3530
        unlock_user(p, arg1, 0);
3531
        break;
3532
#endif
3533
#ifdef TARGET_NR_stime /* not on alpha */
3534
    case TARGET_NR_stime:
3535
        {
3536
            time_t host_time;
3537
            if (get_user_sal(host_time, arg1))
3538
                goto efault;
3539
            ret = get_errno(stime(&host_time));
3540
        }
3541
        break;
3542
#endif
3543
    case TARGET_NR_ptrace:
3544
        goto unimplemented;
3545
#ifdef TARGET_NR_alarm /* not on alpha */
3546
    case TARGET_NR_alarm:
3547
        ret = alarm(arg1);
3548
        break;
3549
#endif
3550
#ifdef TARGET_NR_oldfstat
3551
    case TARGET_NR_oldfstat:
3552
        goto unimplemented;
3553
#endif
3554
#ifdef TARGET_NR_pause /* not on alpha */
3555
    case TARGET_NR_pause:
3556
        ret = get_errno(pause());
3557
        break;
3558
#endif
3559
#ifdef TARGET_NR_utime
3560
    case TARGET_NR_utime:
3561
        {
3562
            struct utimbuf tbuf, *host_tbuf;
3563
            struct target_utimbuf *target_tbuf;
3564
            if (arg2) {
3565
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3566
                    goto efault;
3567
                tbuf.actime = tswapl(target_tbuf->actime);
3568
                tbuf.modtime = tswapl(target_tbuf->modtime);
3569
                unlock_user_struct(target_tbuf, arg2, 0);
3570
                host_tbuf = &tbuf;
3571
            } else {
3572
                host_tbuf = NULL;
3573
            }
3574
            if (!(p = lock_user_string(arg1)))
3575
                goto efault;
3576
            ret = get_errno(utime(p, host_tbuf));
3577
            unlock_user(p, arg1, 0);
3578
        }
3579
        break;
3580
#endif
3581
    case TARGET_NR_utimes:
3582
        {
3583
            struct timeval *tvp, tv[2];
3584
            if (arg2) {
3585
                if (copy_from_user_timeval(&tv[0], arg2)
3586
                    || copy_from_user_timeval(&tv[1],
3587
                                              arg2 + sizeof(struct target_timeval)))
3588
                    goto efault;
3589
                tvp = tv;
3590
            } else {
3591
                tvp = NULL;
3592
            }
3593
            if (!(p = lock_user_string(arg1)))
3594
                goto efault;
3595
            ret = get_errno(utimes(p, tvp));
3596
            unlock_user(p, arg1, 0);
3597
        }
3598
        break;
3599
#ifdef TARGET_NR_stty
3600
    case TARGET_NR_stty:
3601
        goto unimplemented;
3602
#endif
3603
#ifdef TARGET_NR_gtty
3604
    case TARGET_NR_gtty:
3605
        goto unimplemented;
3606
#endif
3607
    case TARGET_NR_access:
3608
        if (!(p = lock_user_string(arg1)))
3609
            goto efault;
3610
        ret = get_errno(access(p, arg2));
3611
        unlock_user(p, arg1, 0);
3612
        break;
3613
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3614
    case TARGET_NR_faccessat:
3615
        if (!(p = lock_user_string(arg2)))
3616
            goto efault;
3617
        ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3618
        unlock_user(p, arg2, 0);
3619
        break;
3620
#endif
3621
#ifdef TARGET_NR_nice /* not on alpha */
3622
    case TARGET_NR_nice:
3623
        ret = get_errno(nice(arg1));
3624
        break;
3625
#endif
3626
#ifdef TARGET_NR_ftime
3627
    case TARGET_NR_ftime:
3628
        goto unimplemented;
3629
#endif
3630
    case TARGET_NR_sync:
3631
        sync();
3632
        ret = 0;
3633
        break;
3634
    case TARGET_NR_kill:
3635
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3636
        break;
3637
    case TARGET_NR_rename:
3638
        {
3639
            void *p2;
3640
            p = lock_user_string(arg1);
3641
            p2 = lock_user_string(arg2);
3642
            if (!p || !p2)
3643
                ret = -TARGET_EFAULT;
3644
            else
3645
                ret = get_errno(rename(p, p2));
3646
            unlock_user(p2, arg2, 0);
3647
            unlock_user(p, arg1, 0);
3648
        }
3649
        break;
3650
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3651
    case TARGET_NR_renameat:
3652
        {
3653
            void *p2;
3654
            p  = lock_user_string(arg2);
3655
            p2 = lock_user_string(arg4);
3656
            if (!p || !p2)
3657
                ret = -TARGET_EFAULT;
3658
            else
3659
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3660
            unlock_user(p2, arg4, 0);
3661
            unlock_user(p, arg2, 0);
3662
        }
3663
        break;
3664
#endif
3665
    case TARGET_NR_mkdir:
3666
        if (!(p = lock_user_string(arg1)))
3667
            goto efault;
3668
        ret = get_errno(mkdir(p, arg2));
3669
        unlock_user(p, arg1, 0);
3670
        break;
3671
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3672
    case TARGET_NR_mkdirat:
3673
        if (!(p = lock_user_string(arg2)))
3674
            goto efault;
3675
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
3676
        unlock_user(p, arg2, 0);
3677
        break;
3678
#endif
3679
    case TARGET_NR_rmdir:
3680
        if (!(p = lock_user_string(arg1)))
3681
            goto efault;
3682
        ret = get_errno(rmdir(p));
3683
        unlock_user(p, arg1, 0);
3684
        break;
3685
    case TARGET_NR_dup:
3686
        ret = get_errno(dup(arg1));
3687
        break;
3688
    case TARGET_NR_pipe:
3689
        {
3690
            int host_pipe[2];
3691
            ret = get_errno(pipe(host_pipe));
3692
            if (!is_error(ret)) {
3693
#if defined(TARGET_MIPS)
3694
                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3695
                env->active_tc.gpr[3] = host_pipe[1];
3696
                ret = host_pipe[0];
3697
#elif defined(TARGET_SH4)
3698
                ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3699
                ret = host_pipe[0];
3700
#else
3701
                if (put_user_s32(host_pipe[0], arg1)
3702
                    || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3703
                    goto efault;
3704
#endif
3705
            }
3706
        }
3707
        break;
3708
    case TARGET_NR_times:
3709
        {
3710
            struct target_tms *tmsp;
3711
            struct tms tms;
3712
            ret = get_errno(times(&tms));
3713
            if (arg1) {
3714
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3715
                if (!tmsp)
3716
                    goto efault;
3717
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3718
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3719
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3720
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3721
            }
3722
            if (!is_error(ret))
3723
                ret = host_to_target_clock_t(ret);
3724
        }
3725
        break;
3726
#ifdef TARGET_NR_prof
3727
    case TARGET_NR_prof:
3728
        goto unimplemented;
3729
#endif
3730
#ifdef TARGET_NR_signal
3731
    case TARGET_NR_signal:
3732
        goto unimplemented;
3733
#endif
3734
    case TARGET_NR_acct:
3735
        if (!(p = lock_user_string(arg1)))
3736
            goto efault;
3737
        ret = get_errno(acct(path(p)));
3738
        unlock_user(p, arg1, 0);
3739
        break;
3740
#ifdef TARGET_NR_umount2 /* not on alpha */
3741
    case TARGET_NR_umount2:
3742
        if (!(p = lock_user_string(arg1)))
3743
            goto efault;
3744
        ret = get_errno(umount2(p, arg2));
3745
        unlock_user(p, arg1, 0);
3746
        break;
3747
#endif
3748
#ifdef TARGET_NR_lock
3749
    case TARGET_NR_lock:
3750
        goto unimplemented;
3751
#endif
3752
    case TARGET_NR_ioctl:
3753
        ret = do_ioctl(arg1, arg2, arg3);
3754
        break;
3755
    case TARGET_NR_fcntl:
3756
        ret = do_fcntl(arg1, arg2, arg3);
3757
        break;
3758
#ifdef TARGET_NR_mpx
3759
    case TARGET_NR_mpx:
3760
        goto unimplemented;
3761
#endif
3762
    case TARGET_NR_setpgid:
3763
        ret = get_errno(setpgid(arg1, arg2));
3764
        break;
3765
#ifdef TARGET_NR_ulimit
3766
    case TARGET_NR_ulimit:
3767
        goto unimplemented;
3768
#endif
3769
#ifdef TARGET_NR_oldolduname
3770
    case TARGET_NR_oldolduname:
3771
        goto unimplemented;
3772
#endif
3773
    case TARGET_NR_umask:
3774
        ret = get_errno(umask(arg1));
3775
        break;
3776
    case TARGET_NR_chroot:
3777
        if (!(p = lock_user_string(arg1)))
3778
            goto efault;
3779
        ret = get_errno(chroot(p));
3780
        unlock_user(p, arg1, 0);
3781
        break;
3782
    case TARGET_NR_ustat:
3783
        goto unimplemented;
3784
    case TARGET_NR_dup2:
3785
        ret = get_errno(dup2(arg1, arg2));
3786
        break;
3787
#ifdef TARGET_NR_getppid /* not on alpha */
3788
    case TARGET_NR_getppid:
3789
        ret = get_errno(getppid());
3790
        break;
3791
#endif
3792
    case TARGET_NR_getpgrp:
3793
        ret = get_errno(getpgrp());
3794
        break;
3795
    case TARGET_NR_setsid:
3796
        ret = get_errno(setsid());
3797
        break;
3798
#ifdef TARGET_NR_sigaction
3799
    case TARGET_NR_sigaction:
3800
        {
3801
#if !defined(TARGET_MIPS)
3802
            struct target_old_sigaction *old_act;
3803
            struct target_sigaction act, oact, *pact;
3804
            if (arg2) {
3805
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3806
                    goto efault;
3807
                act._sa_handler = old_act->_sa_handler;
3808
                target_siginitset(&act.sa_mask, old_act->sa_mask);
3809
                act.sa_flags = old_act->sa_flags;
3810
                act.sa_restorer = old_act->sa_restorer;
3811
                unlock_user_struct(old_act, arg2, 0);
3812
                pact = &act;
3813
            } else {
3814
                pact = NULL;
3815
            }
3816
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3817
            if (!is_error(ret) && arg3) {
3818
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3819
                    goto efault;
3820
                old_act->_sa_handler = oact._sa_handler;
3821
                old_act->sa_mask = oact.sa_mask.sig[0];
3822
                old_act->sa_flags = oact.sa_flags;
3823
                old_act->sa_restorer = oact.sa_restorer;
3824
                unlock_user_struct(old_act, arg3, 1);
3825
            }
3826
#else
3827
            struct target_sigaction act, oact, *pact, *old_act;
3828

    
3829
            if (arg2) {
3830
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3831
                    goto efault;
3832
                act._sa_handler = old_act->_sa_handler;
3833
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3834
                act.sa_flags = old_act->sa_flags;
3835
                unlock_user_struct(old_act, arg2, 0);
3836
                pact = &act;
3837
            } else {
3838
                pact = NULL;
3839
            }
3840

    
3841
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3842

    
3843
            if (!is_error(ret) && arg3) {
3844
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3845
                    goto efault;
3846
                old_act->_sa_handler = oact._sa_handler;
3847
                old_act->sa_flags = oact.sa_flags;
3848
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
3849
                old_act->sa_mask.sig[1] = 0;
3850
                old_act->sa_mask.sig[2] = 0;
3851
                old_act->sa_mask.sig[3] = 0;
3852
                unlock_user_struct(old_act, arg3, 1);
3853
            }
3854
#endif
3855
        }
3856
        break;
3857
#endif
3858
    case TARGET_NR_rt_sigaction:
3859
        {
3860
            struct target_sigaction *act;
3861
            struct target_sigaction *oact;
3862

    
3863
            if (arg2) {
3864
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
3865
                    goto efault;
3866
            } else
3867
                act = NULL;
3868
            if (arg3) {
3869
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
3870
                    ret = -TARGET_EFAULT;
3871
                    goto rt_sigaction_fail;
3872
                }
3873
            } else
3874
                oact = NULL;
3875
            ret = get_errno(do_sigaction(arg1, act, oact));
3876
        rt_sigaction_fail:
3877
            if (act)
3878
                unlock_user_struct(act, arg2, 0);
3879
            if (oact)
3880
                unlock_user_struct(oact, arg3, 1);
3881
        }
3882
        break;
3883
#ifdef TARGET_NR_sgetmask /* not on alpha */
3884
    case TARGET_NR_sgetmask:
3885
        {
3886
            sigset_t cur_set;
3887
            abi_ulong target_set;
3888
            sigprocmask(0, NULL, &cur_set);
3889
            host_to_target_old_sigset(&target_set, &cur_set);
3890
            ret = target_set;
3891
        }
3892
        break;
3893
#endif
3894
#ifdef TARGET_NR_ssetmask /* not on alpha */
3895
    case TARGET_NR_ssetmask:
3896
        {
3897
            sigset_t set, oset, cur_set;
3898
            abi_ulong target_set = arg1;
3899
            sigprocmask(0, NULL, &cur_set);
3900
            target_to_host_old_sigset(&set, &target_set);
3901
            sigorset(&set, &set, &cur_set);
3902
            sigprocmask(SIG_SETMASK, &set, &oset);
3903
            host_to_target_old_sigset(&target_set, &oset);
3904
            ret = target_set;
3905
        }
3906
        break;
3907
#endif
3908
#ifdef TARGET_NR_sigprocmask
3909
    case TARGET_NR_sigprocmask:
3910
        {
3911
            int how = arg1;
3912
            sigset_t set, oldset, *set_ptr;
3913

    
3914
            if (arg2) {
3915
                switch(how) {
3916
                case TARGET_SIG_BLOCK:
3917
                    how = SIG_BLOCK;
3918
                    break;
3919
                case TARGET_SIG_UNBLOCK:
3920
                    how = SIG_UNBLOCK;
3921
                    break;
3922
                case TARGET_SIG_SETMASK:
3923
                    how = SIG_SETMASK;
3924
                    break;
3925
                default:
3926
                    ret = -TARGET_EINVAL;
3927
                    goto fail;
3928
                }
3929
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3930
                    goto efault;
3931
                target_to_host_old_sigset(&set, p);
3932
                unlock_user(p, arg2, 0);
3933
                set_ptr = &set;
3934
            } else {
3935
                how = 0;
3936
                set_ptr = NULL;
3937
            }
3938
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
3939
            if (!is_error(ret) && arg3) {
3940
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
3941
                    goto efault;
3942
                host_to_target_old_sigset(p, &oldset);
3943
                unlock_user(p, arg3, sizeof(target_sigset_t));
3944
            }
3945
        }
3946
        break;
3947
#endif
3948
    case TARGET_NR_rt_sigprocmask:
3949
        {
3950
            int how = arg1;
3951
            sigset_t set, oldset, *set_ptr;
3952

    
3953
            if (arg2) {
3954
                switch(how) {
3955
                case TARGET_SIG_BLOCK:
3956
                    how = SIG_BLOCK;
3957
                    break;
3958
                case TARGET_SIG_UNBLOCK:
3959
                    how = SIG_UNBLOCK;
3960
                    break;
3961
                case TARGET_SIG_SETMASK:
3962
                    how = SIG_SETMASK;
3963
                    break;
3964
                default:
3965
                    ret = -TARGET_EINVAL;
3966
                    goto fail;
3967
                }
3968
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3969
                    goto efault;
3970
                target_to_host_sigset(&set, p);
3971
                unlock_user(p, arg2, 0);
3972
                set_ptr = &set;
3973
            } else {
3974
                how = 0;
3975
                set_ptr = NULL;
3976
            }
3977
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
3978
            if (!is_error(ret) && arg3) {
3979
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
3980
                    goto efault;
3981
                host_to_target_sigset(p, &oldset);
3982
                unlock_user(p, arg3, sizeof(target_sigset_t));
3983
            }
3984
        }
3985
        break;
3986
#ifdef TARGET_NR_sigpending
3987
    case TARGET_NR_sigpending:
3988
        {
3989
            sigset_t set;
3990
            ret = get_errno(sigpending(&set));
3991
            if (!is_error(ret)) {
3992
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
3993
                    goto efault;
3994
                host_to_target_old_sigset(p, &set);
3995
                unlock_user(p, arg1, sizeof(target_sigset_t));
3996
            }
3997
        }
3998
        break;
3999
#endif
4000
    case TARGET_NR_rt_sigpending:
4001
        {
4002
            sigset_t set;
4003
            ret = get_errno(sigpending(&set));
4004
            if (!is_error(ret)) {
4005
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4006
                    goto efault;
4007
                host_to_target_sigset(p, &set);
4008
                unlock_user(p, arg1, sizeof(target_sigset_t));
4009
            }
4010
        }
4011
        break;
4012
#ifdef TARGET_NR_sigsuspend
4013
    case TARGET_NR_sigsuspend:
4014
        {
4015
            sigset_t set;
4016
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4017
                goto efault;
4018
            target_to_host_old_sigset(&set, p);
4019
            unlock_user(p, arg1, 0);
4020
            ret = get_errno(sigsuspend(&set));
4021
        }
4022
        break;
4023
#endif
4024
    case TARGET_NR_rt_sigsuspend:
4025
        {
4026
            sigset_t set;
4027
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4028
                goto efault;
4029
            target_to_host_sigset(&set, p);
4030
            unlock_user(p, arg1, 0);
4031
            ret = get_errno(sigsuspend(&set));
4032
        }
4033
        break;
4034
    case TARGET_NR_rt_sigtimedwait:
4035
        {
4036
            sigset_t set;
4037
            struct timespec uts, *puts;
4038
            siginfo_t uinfo;
4039

    
4040
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4041
                goto efault;
4042
            target_to_host_sigset(&set, p);
4043
            unlock_user(p, arg1, 0);
4044
            if (arg3) {
4045
                puts = &uts;
4046
                target_to_host_timespec(puts, arg3);
4047
            } else {
4048
                puts = NULL;
4049
            }
4050
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4051
            if (!is_error(ret) && arg2) {
4052
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4053
                    goto efault;
4054
                host_to_target_siginfo(p, &uinfo);
4055
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4056
            }
4057
        }
4058
        break;
4059
    case TARGET_NR_rt_sigqueueinfo:
4060
        {
4061
            siginfo_t uinfo;
4062
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4063
                goto efault;
4064
            target_to_host_siginfo(&uinfo, p);
4065
            unlock_user(p, arg1, 0);
4066
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4067
        }
4068
        break;
4069
#ifdef TARGET_NR_sigreturn
4070
    case TARGET_NR_sigreturn:
4071
        /* NOTE: ret is eax, so not transcoding must be done */
4072
        ret = do_sigreturn(cpu_env);
4073
        break;
4074
#endif
4075
    case TARGET_NR_rt_sigreturn:
4076
        /* NOTE: ret is eax, so not transcoding must be done */
4077
        ret = do_rt_sigreturn(cpu_env);
4078
        break;
4079
    case TARGET_NR_sethostname:
4080
        if (!(p = lock_user_string(arg1)))
4081
            goto efault;
4082
        ret = get_errno(sethostname(p, arg2));
4083
        unlock_user(p, arg1, 0);
4084
        break;
4085
    case TARGET_NR_setrlimit:
4086
        {
4087
            /* XXX: convert resource ? */
4088
            int resource = arg1;
4089
            struct target_rlimit *target_rlim;
4090
            struct rlimit rlim;
4091
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4092
                goto efault;
4093
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4094
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4095
            unlock_user_struct(target_rlim, arg2, 0);
4096
            ret = get_errno(setrlimit(resource, &rlim));
4097
        }
4098
        break;
4099
    case TARGET_NR_getrlimit:
4100
        {
4101
            /* XXX: convert resource ? */
4102
            int resource = arg1;
4103
            struct target_rlimit *target_rlim;
4104
            struct rlimit rlim;
4105

    
4106
            ret = get_errno(getrlimit(resource, &rlim));
4107
            if (!is_error(ret)) {
4108
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4109
                    goto efault;
4110
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4111
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4112
                unlock_user_struct(target_rlim, arg2, 1);
4113
            }
4114
        }
4115
        break;
4116
    case TARGET_NR_getrusage:
4117
        {
4118
            struct rusage rusage;
4119
            ret = get_errno(getrusage(arg1, &rusage));
4120
            if (!is_error(ret)) {
4121
                host_to_target_rusage(arg2, &rusage);
4122
            }
4123
        }
4124
        break;
4125
    case TARGET_NR_gettimeofday:
4126
        {
4127
            struct timeval tv;
4128
            ret = get_errno(gettimeofday(&tv, NULL));
4129
            if (!is_error(ret)) {
4130
                if (copy_to_user_timeval(arg1, &tv))
4131
                    goto efault;
4132
            }
4133
        }
4134
        break;
4135
    case TARGET_NR_settimeofday:
4136
        {
4137
            struct timeval tv;
4138
            if (copy_from_user_timeval(&tv, arg1))
4139
                goto efault;
4140
            ret = get_errno(settimeofday(&tv, NULL));
4141
        }
4142
        break;
4143
#ifdef TARGET_NR_select
4144
    case TARGET_NR_select:
4145
        {
4146
            struct target_sel_arg_struct *sel;
4147
            abi_ulong inp, outp, exp, tvp;
4148
            long nsel;
4149

    
4150
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4151
                goto efault;
4152
            nsel = tswapl(sel->n);
4153
            inp = tswapl(sel->inp);
4154
            outp = tswapl(sel->outp);
4155
            exp = tswapl(sel->exp);
4156
            tvp = tswapl(sel->tvp);
4157
            unlock_user_struct(sel, arg1, 0);
4158
            ret = do_select(nsel, inp, outp, exp, tvp);
4159
        }
4160
        break;
4161
#endif
4162
    case TARGET_NR_symlink:
4163
        {
4164
            void *p2;
4165
            p = lock_user_string(arg1);
4166
            p2 = lock_user_string(arg2);
4167
            if (!p || !p2)
4168
                ret = -TARGET_EFAULT;
4169
            else
4170
                ret = get_errno(symlink(p, p2));
4171
            unlock_user(p2, arg2, 0);
4172
            unlock_user(p, arg1, 0);
4173
        }
4174
        break;
4175
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4176
    case TARGET_NR_symlinkat:
4177
        {
4178
            void *p2;
4179
            p  = lock_user_string(arg1);
4180
            p2 = lock_user_string(arg3);
4181
            if (!p || !p2)
4182
                ret = -TARGET_EFAULT;
4183
            else
4184
                ret = get_errno(sys_symlinkat(p, arg2, p2));
4185
            unlock_user(p2, arg3, 0);
4186
            unlock_user(p, arg1, 0);
4187
        }
4188
        break;
4189
#endif
4190
#ifdef TARGET_NR_oldlstat
4191
    case TARGET_NR_oldlstat:
4192
        goto unimplemented;
4193
#endif
4194
    case TARGET_NR_readlink:
4195
        {
4196
            void *p2;
4197
            p = lock_user_string(arg1);
4198
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4199
            if (!p || !p2)
4200
                ret = -TARGET_EFAULT;
4201
            else
4202
                ret = get_errno(readlink(path(p), p2, arg3));
4203
            unlock_user(p2, arg2, ret);
4204
            unlock_user(p, arg1, 0);
4205
        }
4206
        break;
4207
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4208
    case TARGET_NR_readlinkat:
4209
        {
4210
            void *p2;
4211
            p  = lock_user_string(arg2);
4212
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4213
            if (!p || !p2)
4214
                ret = -TARGET_EFAULT;
4215
            else
4216
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4217
            unlock_user(p2, arg3, ret);
4218
            unlock_user(p, arg2, 0);
4219
        }
4220
        break;
4221
#endif
4222
#ifdef TARGET_NR_uselib
4223
    case TARGET_NR_uselib:
4224
        goto unimplemented;
4225
#endif
4226
#ifdef TARGET_NR_swapon
4227
    case TARGET_NR_swapon:
4228
        if (!(p = lock_user_string(arg1)))
4229
            goto efault;
4230
        ret = get_errno(swapon(p, arg2));
4231
        unlock_user(p, arg1, 0);
4232
        break;
4233
#endif
4234
    case TARGET_NR_reboot:
4235
        goto unimplemented;
4236
#ifdef TARGET_NR_readdir
4237
    case TARGET_NR_readdir:
4238
        goto unimplemented;
4239
#endif
4240
#ifdef TARGET_NR_mmap
4241
    case TARGET_NR_mmap:
4242
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4243
        {
4244
            abi_ulong *v;
4245
            abi_ulong v1, v2, v3, v4, v5, v6;
4246
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4247
                goto efault;
4248
            v1 = tswapl(v[0]);
4249
            v2 = tswapl(v[1]);
4250
            v3 = tswapl(v[2]);
4251
            v4 = tswapl(v[3]);
4252
            v5 = tswapl(v[4]);
4253
            v6 = tswapl(v[5]);
4254
            unlock_user(v, arg1, 0);
4255
            ret = get_errno(target_mmap(v1, v2, v3,
4256
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
4257
                                        v5, v6));
4258
        }
4259
#else
4260
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4261
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4262
                                    arg5,
4263
                                    arg6));
4264
#endif
4265
        break;
4266
#endif
4267
#ifdef TARGET_NR_mmap2
4268
    case TARGET_NR_mmap2:
4269
#ifndef MMAP_SHIFT
4270
#define MMAP_SHIFT 12
4271
#endif
4272
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4273
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4274
                                    arg5,
4275
                                    arg6 << MMAP_SHIFT));
4276
        break;
4277
#endif
4278
    case TARGET_NR_munmap:
4279
        ret = get_errno(target_munmap(arg1, arg2));
4280
        break;
4281
    case TARGET_NR_mprotect:
4282
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
4283
        break;
4284
#ifdef TARGET_NR_mremap
4285
    case TARGET_NR_mremap:
4286
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4287
        break;
4288
#endif
4289
        /* ??? msync/mlock/munlock are broken for softmmu.  */
4290
#ifdef TARGET_NR_msync
4291
    case TARGET_NR_msync:
4292
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
4293
        break;
4294
#endif
4295
#ifdef TARGET_NR_mlock
4296
    case TARGET_NR_mlock:
4297
        ret = get_errno(mlock(g2h(arg1), arg2));
4298
        break;
4299
#endif
4300
#ifdef TARGET_NR_munlock
4301
    case TARGET_NR_munlock:
4302
        ret = get_errno(munlock(g2h(arg1), arg2));
4303
        break;
4304
#endif
4305
#ifdef TARGET_NR_mlockall
4306
    case TARGET_NR_mlockall:
4307
        ret = get_errno(mlockall(arg1));
4308
        break;
4309
#endif
4310
#ifdef TARGET_NR_munlockall
4311
    case TARGET_NR_munlockall:
4312
        ret = get_errno(munlockall());
4313
        break;
4314
#endif
4315
    case TARGET_NR_truncate:
4316
        if (!(p = lock_user_string(arg1)))
4317
            goto efault;
4318
        ret = get_errno(truncate(p, arg2));
4319
        unlock_user(p, arg1, 0);
4320
        break;
4321
    case TARGET_NR_ftruncate:
4322
        ret = get_errno(ftruncate(arg1, arg2));
4323
        break;
4324
    case TARGET_NR_fchmod:
4325
        ret = get_errno(fchmod(arg1, arg2));
4326
        break;
4327
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4328
    case TARGET_NR_fchmodat:
4329
        if (!(p = lock_user_string(arg2)))
4330
            goto efault;
4331
        ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4332
        unlock_user(p, arg2, 0);
4333
        break;
4334
#endif
4335
    case TARGET_NR_getpriority:
4336
        /* libc does special remapping of the return value of
4337
         * sys_getpriority() so it's just easiest to call
4338
         * sys_getpriority() directly rather than through libc. */
4339
        ret = sys_getpriority(arg1, arg2);
4340
        break;
4341
    case TARGET_NR_setpriority:
4342
        ret = get_errno(setpriority(arg1, arg2, arg3));
4343
        break;
4344
#ifdef TARGET_NR_profil
4345
    case TARGET_NR_profil:
4346
        goto unimplemented;
4347
#endif
4348
    case TARGET_NR_statfs:
4349
        if (!(p = lock_user_string(arg1)))
4350
            goto efault;
4351
        ret = get_errno(statfs(path(p), &stfs));
4352
        unlock_user(p, arg1, 0);
4353
    convert_statfs:
4354
        if (!is_error(ret)) {
4355
            struct target_statfs *target_stfs;
4356

    
4357
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4358
                goto efault;
4359
            __put_user(stfs.f_type, &target_stfs->f_type);
4360
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4361
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4362
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4363
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4364
            __put_user(stfs.f_files, &target_stfs->f_files);
4365
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4366
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4367
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4368
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4369
            unlock_user_struct(target_stfs, arg2, 1);
4370
        }
4371
        break;
4372
    case TARGET_NR_fstatfs:
4373
        ret = get_errno(fstatfs(arg1, &stfs));
4374
        goto convert_statfs;
4375
#ifdef TARGET_NR_statfs64
4376
    case TARGET_NR_statfs64:
4377
        if (!(p = lock_user_string(arg1)))
4378
            goto efault;
4379
        ret = get_errno(statfs(path(p), &stfs));
4380
        unlock_user(p, arg1, 0);
4381
    convert_statfs64:
4382
        if (!is_error(ret)) {
4383
            struct target_statfs64 *target_stfs;
4384

    
4385
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4386
                goto efault;
4387
            __put_user(stfs.f_type, &target_stfs->f_type);
4388
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4389
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4390
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4391
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4392
            __put_user(stfs.f_files, &target_stfs->f_files);
4393
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4394
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4395
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4396
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4397
            unlock_user_struct(target_stfs, arg3, 1);
4398
        }
4399
        break;
4400
    case TARGET_NR_fstatfs64:
4401
        ret = get_errno(fstatfs(arg1, &stfs));
4402
        goto convert_statfs64;
4403
#endif
4404
#ifdef TARGET_NR_ioperm
4405
    case TARGET_NR_ioperm:
4406
        goto unimplemented;
4407
#endif
4408
#ifdef TARGET_NR_socketcall
4409
    case TARGET_NR_socketcall:
4410
        ret = do_socketcall(arg1, arg2);
4411
        break;
4412
#endif
4413
#ifdef TARGET_NR_accept
4414
    case TARGET_NR_accept:
4415
        ret = do_accept(arg1, arg2, arg3);
4416
        break;
4417
#endif
4418
#ifdef TARGET_NR_bind
4419
    case TARGET_NR_bind:
4420
        ret = do_bind(arg1, arg2, arg3);
4421
        break;
4422
#endif
4423
#ifdef TARGET_NR_connect
4424
    case TARGET_NR_connect:
4425
        ret = do_connect(arg1, arg2, arg3);
4426
        break;
4427
#endif
4428
#ifdef TARGET_NR_getpeername
4429
    case TARGET_NR_getpeername:
4430
        ret = do_getpeername(arg1, arg2, arg3);
4431
        break;
4432
#endif
4433
#ifdef TARGET_NR_getsockname
4434
    case TARGET_NR_getsockname:
4435
        ret = do_getsockname(arg1, arg2, arg3);
4436
        break;
4437
#endif
4438
#ifdef TARGET_NR_getsockopt
4439
    case TARGET_NR_getsockopt:
4440
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4441
        break;
4442
#endif
4443
#ifdef TARGET_NR_listen
4444
    case TARGET_NR_listen:
4445
        ret = get_errno(listen(arg1, arg2));
4446
        break;
4447
#endif
4448
#ifdef TARGET_NR_recv
4449
    case TARGET_NR_recv:
4450
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4451
        break;
4452
#endif
4453
#ifdef TARGET_NR_recvfrom
4454
    case TARGET_NR_recvfrom:
4455
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4456
        break;
4457
#endif
4458
#ifdef TARGET_NR_recvmsg
4459
    case TARGET_NR_recvmsg:
4460
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4461
        break;
4462
#endif
4463
#ifdef TARGET_NR_send
4464
    case TARGET_NR_send:
4465
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4466
        break;
4467
#endif
4468
#ifdef TARGET_NR_sendmsg
4469
    case TARGET_NR_sendmsg:
4470
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4471
        break;
4472
#endif
4473
#ifdef TARGET_NR_sendto
4474
    case TARGET_NR_sendto:
4475
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4476
        break;
4477
#endif
4478
#ifdef TARGET_NR_shutdown
4479
    case TARGET_NR_shutdown:
4480
        ret = get_errno(shutdown(arg1, arg2));
4481
        break;
4482
#endif
4483
#ifdef TARGET_NR_socket
4484
    case TARGET_NR_socket:
4485
        ret = do_socket(arg1, arg2, arg3);
4486
        break;
4487
#endif
4488
#ifdef TARGET_NR_socketpair
4489
    case TARGET_NR_socketpair:
4490
        ret = do_socketpair(arg1, arg2, arg3, arg4);
4491
        break;
4492
#endif
4493
#ifdef TARGET_NR_setsockopt
4494
    case TARGET_NR_setsockopt:
4495
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4496
        break;
4497
#endif
4498

    
4499
    case TARGET_NR_syslog:
4500
        if (!(p = lock_user_string(arg2)))
4501
            goto efault;
4502
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4503
        unlock_user(p, arg2, 0);
4504
        break;
4505

    
4506
    case TARGET_NR_setitimer:
4507
        {
4508
            struct itimerval value, ovalue, *pvalue;
4509

    
4510
            if (arg2) {
4511
                pvalue = &value;
4512
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4513
                    || copy_from_user_timeval(&pvalue->it_value,
4514
                                              arg2 + sizeof(struct target_timeval)))
4515
                    goto efault;
4516
            } else {
4517
                pvalue = NULL;
4518
            }
4519
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4520
            if (!is_error(ret) && arg3) {
4521
                if (copy_to_user_timeval(arg3,
4522
                                         &ovalue.it_interval)
4523
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4524
                                            &ovalue.it_value))
4525
                    goto efault;
4526
            }
4527
        }
4528
        break;
4529
    case TARGET_NR_getitimer:
4530
        {
4531
            struct itimerval value;
4532

    
4533
            ret = get_errno(getitimer(arg1, &value));
4534
            if (!is_error(ret) && arg2) {
4535
                if (copy_to_user_timeval(arg2,
4536
                                         &value.it_interval)
4537
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4538
                                            &value.it_value))
4539
                    goto efault;
4540
            }
4541
        }
4542
        break;
4543
    case TARGET_NR_stat:
4544
        if (!(p = lock_user_string(arg1)))
4545
            goto efault;
4546
        ret = get_errno(stat(path(p), &st));
4547
        unlock_user(p, arg1, 0);
4548
        goto do_stat;
4549
    case TARGET_NR_lstat:
4550
        if (!(p = lock_user_string(arg1)))
4551
            goto efault;
4552
        ret = get_errno(lstat(path(p), &st));
4553
        unlock_user(p, arg1, 0);
4554
        goto do_stat;
4555
    case TARGET_NR_fstat:
4556
        {
4557
            ret = get_errno(fstat(arg1, &st));
4558
        do_stat:
4559
            if (!is_error(ret)) {
4560
                struct target_stat *target_st;
4561

    
4562
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4563
                    goto efault;
4564
                __put_user(st.st_dev, &target_st->st_dev);
4565
                __put_user(st.st_ino, &target_st->st_ino);
4566
                __put_user(st.st_mode, &target_st->st_mode);
4567
                __put_user(st.st_uid, &target_st->st_uid);
4568
                __put_user(st.st_gid, &target_st->st_gid);
4569
                __put_user(st.st_nlink, &target_st->st_nlink);
4570
                __put_user(st.st_rdev, &target_st->st_rdev);
4571
                __put_user(st.st_size, &target_st->st_size);
4572
                __put_user(st.st_blksize, &target_st->st_blksize);
4573
                __put_user(st.st_blocks, &target_st->st_blocks);
4574
                __put_user(st.st_atime, &target_st->target_st_atime);
4575
                __put_user(st.st_mtime, &target_st->target_st_mtime);
4576
                __put_user(st.st_ctime, &target_st->target_st_ctime);
4577
                unlock_user_struct(target_st, arg2, 1);
4578
            }
4579
        }
4580
        break;
4581
#ifdef TARGET_NR_olduname
4582
    case TARGET_NR_olduname:
4583
        goto unimplemented;
4584
#endif
4585
#ifdef TARGET_NR_iopl
4586
    case TARGET_NR_iopl:
4587
        goto unimplemented;
4588
#endif
4589
    case TARGET_NR_vhangup:
4590
        ret = get_errno(vhangup());
4591
        break;
4592
#ifdef TARGET_NR_idle
4593
    case TARGET_NR_idle:
4594
        goto unimplemented;
4595
#endif
4596
#ifdef TARGET_NR_syscall
4597
    case TARGET_NR_syscall:
4598
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4599
            break;
4600
#endif
4601
    case TARGET_NR_wait4:
4602
        {
4603
            int status;
4604
            abi_long status_ptr = arg2;
4605
            struct rusage rusage, *rusage_ptr;
4606
            abi_ulong target_rusage = arg4;
4607
            if (target_rusage)
4608
                rusage_ptr = &rusage;
4609
            else
4610
                rusage_ptr = NULL;
4611
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4612
            if (!is_error(ret)) {
4613
                if (status_ptr) {
4614
                    if (put_user_s32(status, status_ptr))
4615
                        goto efault;
4616
                }
4617
                if (target_rusage)
4618
                    host_to_target_rusage(target_rusage, &rusage);
4619
            }
4620
        }
4621
        break;
4622
#ifdef TARGET_NR_swapoff
4623
    case TARGET_NR_swapoff:
4624
        if (!(p = lock_user_string(arg1)))
4625
            goto efault;
4626
        ret = get_errno(swapoff(p));
4627
        unlock_user(p, arg1, 0);
4628
        break;
4629
#endif
4630
    case TARGET_NR_sysinfo:
4631
        {
4632
            struct target_sysinfo *target_value;
4633
            struct sysinfo value;
4634
            ret = get_errno(sysinfo(&value));
4635
            if (!is_error(ret) && arg1)
4636
            {
4637
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4638
                    goto efault;
4639
                __put_user(value.uptime, &target_value->uptime);
4640
                __put_user(value.loads[0], &target_value->loads[0]);
4641
                __put_user(value.loads[1], &target_value->loads[1]);
4642
                __put_user(value.loads[2], &target_value->loads[2]);
4643
                __put_user(value.totalram, &target_value->totalram);
4644
                __put_user(value.freeram, &target_value->freeram);
4645
                __put_user(value.sharedram, &target_value->sharedram);
4646
                __put_user(value.bufferram, &target_value->bufferram);
4647
                __put_user(value.totalswap, &target_value->totalswap);
4648
                __put_user(value.freeswap, &target_value->freeswap);
4649
                __put_user(value.procs, &target_value->procs);
4650
                __put_user(value.totalhigh, &target_value->totalhigh);
4651
                __put_user(value.freehigh, &target_value->freehigh);
4652
                __put_user(value.mem_unit, &target_value->mem_unit);
4653
                unlock_user_struct(target_value, arg1, 1);
4654
            }
4655
        }
4656
        break;
4657
#ifdef TARGET_NR_ipc
4658
    case TARGET_NR_ipc:
4659
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4660
        break;
4661
#endif
4662
    case TARGET_NR_fsync:
4663
        ret = get_errno(fsync(arg1));
4664
        break;
4665
    case TARGET_NR_clone:
4666
#if defined(TARGET_SH4)
4667
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
4668
#else
4669
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4670
#endif
4671
        break;
4672
#ifdef __NR_exit_group
4673
        /* new thread calls */
4674
    case TARGET_NR_exit_group:
4675
        gdb_exit(cpu_env, arg1);
4676
        ret = get_errno(exit_group(arg1));
4677
        break;
4678
#endif
4679
    case TARGET_NR_setdomainname:
4680
        if (!(p = lock_user_string(arg1)))
4681
            goto efault;
4682
        ret = get_errno(setdomainname(p, arg2));
4683
        unlock_user(p, arg1, 0);
4684
        break;
4685
    case TARGET_NR_uname:
4686
        /* no need to transcode because we use the linux syscall */
4687
        {
4688
            struct new_utsname * buf;
4689

    
4690
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4691
                goto efault;
4692
            ret = get_errno(sys_uname(buf));
4693
            if (!is_error(ret)) {
4694
                /* Overrite the native machine name with whatever is being
4695
                   emulated. */
4696
                strcpy (buf->machine, UNAME_MACHINE);
4697
                /* Allow the user to override the reported release.  */
4698
                if (qemu_uname_release && *qemu_uname_release)
4699
                  strcpy (buf->release, qemu_uname_release);
4700
            }
4701
            unlock_user_struct(buf, arg1, 1);
4702
        }
4703
        break;
4704
#ifdef TARGET_I386
4705
    case TARGET_NR_modify_ldt:
4706
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4707
        break;
4708
#if !defined(TARGET_X86_64)
4709
    case TARGET_NR_vm86old:
4710
        goto unimplemented;
4711
    case TARGET_NR_vm86:
4712
        ret = do_vm86(cpu_env, arg1, arg2);
4713
        break;
4714
#endif
4715
#endif
4716
    case TARGET_NR_adjtimex:
4717
        goto unimplemented;
4718
#ifdef TARGET_NR_create_module
4719
    case TARGET_NR_create_module:
4720
#endif
4721
    case TARGET_NR_init_module:
4722
    case TARGET_NR_delete_module:
4723
#ifdef TARGET_NR_get_kernel_syms
4724
    case TARGET_NR_get_kernel_syms:
4725
#endif
4726
        goto unimplemented;
4727
    case TARGET_NR_quotactl:
4728
        goto unimplemented;
4729
    case TARGET_NR_getpgid:
4730
        ret = get_errno(getpgid(arg1));
4731
        break;
4732
    case TARGET_NR_fchdir:
4733
        ret = get_errno(fchdir(arg1));
4734
        break;
4735
#ifdef TARGET_NR_bdflush /* not on x86_64 */
4736
    case TARGET_NR_bdflush:
4737
        goto unimplemented;
4738
#endif
4739
#ifdef TARGET_NR_sysfs
4740
    case TARGET_NR_sysfs:
4741
        goto unimplemented;
4742
#endif
4743
    case TARGET_NR_personality:
4744
        ret = get_errno(personality(arg1));
4745
        break;
4746
#ifdef TARGET_NR_afs_syscall
4747
    case TARGET_NR_afs_syscall:
4748
        goto unimplemented;
4749
#endif
4750
#ifdef TARGET_NR__llseek /* Not on alpha */
4751
    case TARGET_NR__llseek:
4752
        {
4753
#if defined (__x86_64__)
4754
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4755
            if (put_user_s64(ret, arg4))
4756
                goto efault;
4757
#else
4758
            int64_t res;
4759
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4760
            if (put_user_s64(res, arg4))
4761
                goto efault;
4762
#endif
4763
        }
4764
        break;
4765
#endif
4766
    case TARGET_NR_getdents:
4767
#if TARGET_ABI_BITS != 32
4768
        goto unimplemented;
4769
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4770
        {
4771
            struct target_dirent *target_dirp;
4772
            struct dirent *dirp;
4773
            abi_long count = arg3;
4774

    
4775
            dirp = malloc(count);
4776
            if (!dirp) {
4777
                ret = -TARGET_ENOMEM;
4778
                goto fail;
4779
            }
4780

    
4781
            ret = get_errno(sys_getdents(arg1, dirp, count));
4782
            if (!is_error(ret)) {
4783
                struct dirent *de;
4784
                struct target_dirent *tde;
4785
                int len = ret;
4786
                int reclen, treclen;
4787
                int count1, tnamelen;
4788

    
4789
                count1 = 0;
4790
                de = dirp;
4791
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4792
                    goto efault;
4793
                tde = target_dirp;
4794
                while (len > 0) {
4795
                    reclen = de->d_reclen;
4796
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4797
                    tde->d_reclen = tswap16(treclen);
4798
                    tde->d_ino = tswapl(de->d_ino);
4799
                    tde->d_off = tswapl(de->d_off);
4800
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4801
                    if (tnamelen > 256)
4802
                        tnamelen = 256;
4803
                    /* XXX: may not be correct */
4804
                    strncpy(tde->d_name, de->d_name, tnamelen);
4805
                    de = (struct dirent *)((char *)de + reclen);
4806
                    len -= reclen;
4807
                    tde = (struct target_dirent *)((char *)tde + treclen);
4808
                    count1 += treclen;
4809
                }
4810
                ret = count1;
4811
                unlock_user(target_dirp, arg2, ret);
4812
            }
4813
            free(dirp);
4814
        }
4815
#else
4816
        {
4817
            struct dirent *dirp;
4818
            abi_long count = arg3;
4819

    
4820
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4821
                goto efault;
4822
            ret = get_errno(sys_getdents(arg1, dirp, count));
4823
            if (!is_error(ret)) {
4824
                struct dirent *de;
4825
                int len = ret;
4826
                int reclen;
4827
                de = dirp;
4828
                while (len > 0) {
4829
                    reclen = de->d_reclen;
4830
                    if (reclen > len)
4831
                        break;
4832
                    de->d_reclen = tswap16(reclen);
4833
                    tswapls(&de->d_ino);
4834
                    tswapls(&de->d_off);
4835
                    de = (struct dirent *)((char *)de + reclen);
4836
                    len -= reclen;
4837
                }
4838
            }
4839
            unlock_user(dirp, arg2, ret);
4840
        }
4841
#endif
4842
        break;
4843
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
4844
    case TARGET_NR_getdents64:
4845
        {
4846
            struct dirent64 *dirp;
4847
            abi_long count = arg3;
4848
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4849
                goto efault;
4850
            ret = get_errno(sys_getdents64(arg1, dirp, count));
4851
            if (!is_error(ret)) {
4852
                struct dirent64 *de;
4853
                int len = ret;
4854
                int reclen;
4855
                de = dirp;
4856
                while (len > 0) {
4857
                    reclen = de->d_reclen;
4858
                    if (reclen > len)
4859
                        break;
4860
                    de->d_reclen = tswap16(reclen);
4861
                    tswap64s((uint64_t *)&de->d_ino);
4862
                    tswap64s((uint64_t *)&de->d_off);
4863
                    de = (struct dirent64 *)((char *)de + reclen);
4864
                    len -= reclen;
4865
                }
4866
            }
4867
            unlock_user(dirp, arg2, ret);
4868
        }
4869
        break;
4870
#endif /* TARGET_NR_getdents64 */
4871
#ifdef TARGET_NR__newselect
4872
    case TARGET_NR__newselect:
4873
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
4874
        break;
4875
#endif
4876
#ifdef TARGET_NR_poll
4877
    case TARGET_NR_poll:
4878
        {
4879
            struct target_pollfd *target_pfd;
4880
            unsigned int nfds = arg2;
4881
            int timeout = arg3;
4882
            struct pollfd *pfd;
4883
            unsigned int i;
4884

    
4885
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
4886
            if (!target_pfd)
4887
                goto efault;
4888
            pfd = alloca(sizeof(struct pollfd) * nfds);
4889
            for(i = 0; i < nfds; i++) {
4890
                pfd[i].fd = tswap32(target_pfd[i].fd);
4891
                pfd[i].events = tswap16(target_pfd[i].events);
4892
            }
4893
            ret = get_errno(poll(pfd, nfds, timeout));
4894
            if (!is_error(ret)) {
4895
                for(i = 0; i < nfds; i++) {
4896
                    target_pfd[i].revents = tswap16(pfd[i].revents);
4897
                }
4898
                ret += nfds * (sizeof(struct target_pollfd)
4899
                               - sizeof(struct pollfd));
4900
            }
4901
            unlock_user(target_pfd, arg1, ret);
4902
        }
4903
        break;
4904
#endif
4905
    case TARGET_NR_flock:
4906
        /* NOTE: the flock constant seems to be the same for every
4907
           Linux platform */
4908
        ret = get_errno(flock(arg1, arg2));
4909
        break;
4910
    case TARGET_NR_readv:
4911
        {
4912
            int count = arg3;
4913
            struct iovec *vec;
4914

    
4915
            vec = alloca(count * sizeof(struct iovec));
4916
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
4917
                goto efault;
4918
            ret = get_errno(readv(arg1, vec, count));
4919
            unlock_iovec(vec, arg2, count, 1);
4920
        }
4921
        break;
4922
    case TARGET_NR_writev:
4923
        {
4924
            int count = arg3;
4925
            struct iovec *vec;
4926

    
4927
            vec = alloca(count * sizeof(struct iovec));
4928
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
4929
                goto efault;
4930
            ret = get_errno(writev(arg1, vec, count));
4931
            unlock_iovec(vec, arg2, count, 0);
4932
        }
4933
        break;
4934
    case TARGET_NR_getsid:
4935
        ret = get_errno(getsid(arg1));
4936
        break;
4937
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
4938
    case TARGET_NR_fdatasync:
4939
        ret = get_errno(fdatasync(arg1));
4940
        break;
4941
#endif
4942
    case TARGET_NR__sysctl:
4943
        /* We don't implement this, but ENOTDIR is always a safe
4944
           return value. */
4945
        ret = -TARGET_ENOTDIR;
4946
        break;
4947
    case TARGET_NR_sched_setparam:
4948
        {
4949
            struct sched_param *target_schp;
4950
            struct sched_param schp;
4951

    
4952
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
4953
                goto efault;
4954
            schp.sched_priority = tswap32(target_schp->sched_priority);
4955
            unlock_user_struct(target_schp, arg2, 0);
4956
            ret = get_errno(sched_setparam(arg1, &schp));
4957
        }
4958
        break;
4959
    case TARGET_NR_sched_getparam:
4960
        {
4961
            struct sched_param *target_schp;
4962
            struct sched_param schp;
4963
            ret = get_errno(sched_getparam(arg1, &schp));
4964
            if (!is_error(ret)) {
4965
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
4966
                    goto efault;
4967
                target_schp->sched_priority = tswap32(schp.sched_priority);
4968
                unlock_user_struct(target_schp, arg2, 1);
4969
            }
4970
        }
4971
        break;
4972
    case TARGET_NR_sched_setscheduler:
4973
        {
4974
            struct sched_param *target_schp;
4975
            struct sched_param schp;
4976
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
4977
                goto efault;
4978
            schp.sched_priority = tswap32(target_schp->sched_priority);
4979
            unlock_user_struct(target_schp, arg3, 0);
4980
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
4981
        }
4982
        break;
4983
    case TARGET_NR_sched_getscheduler:
4984
        ret = get_errno(sched_getscheduler(arg1));
4985
        break;
4986
    case TARGET_NR_sched_yield:
4987
        ret = get_errno(sched_yield());
4988
        break;
4989
    case TARGET_NR_sched_get_priority_max:
4990
        ret = get_errno(sched_get_priority_max(arg1));
4991
        break;
4992
    case TARGET_NR_sched_get_priority_min:
4993
        ret = get_errno(sched_get_priority_min(arg1));
4994
        break;
4995
    case TARGET_NR_sched_rr_get_interval:
4996
        {
4997
            struct timespec ts;
4998
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
4999
            if (!is_error(ret)) {
5000
                host_to_target_timespec(arg2, &ts);
5001
            }
5002
        }
5003
        break;
5004
    case TARGET_NR_nanosleep:
5005
        {
5006
            struct timespec req, rem;
5007
            target_to_host_timespec(&req, arg1);
5008
            ret = get_errno(nanosleep(&req, &rem));
5009
            if (is_error(ret) && arg2) {
5010
                host_to_target_timespec(arg2, &rem);
5011
            }
5012
        }
5013
        break;
5014
#ifdef TARGET_NR_query_module
5015
    case TARGET_NR_query_module:
5016
        goto unimplemented;
5017
#endif
5018
#ifdef TARGET_NR_nfsservctl
5019
    case TARGET_NR_nfsservctl:
5020
        goto unimplemented;
5021
#endif
5022
    case TARGET_NR_prctl:
5023
        switch (arg1)
5024
            {
5025
            case PR_GET_PDEATHSIG:
5026
                {
5027
                    int deathsig;
5028
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5029
                    if (!is_error(ret) && arg2
5030
                        && put_user_ual(deathsig, arg2))
5031
                        goto efault;
5032
                }
5033
                break;
5034
            default:
5035
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5036
                break;
5037
            }
5038
        break;
5039
#ifdef TARGET_NR_arch_prctl
5040
    case TARGET_NR_arch_prctl:
5041
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
5042
        ret = do_arch_prctl(cpu_env, arg1, arg2);
5043
        break;
5044
#else
5045
        goto unimplemented;
5046
#endif
5047
#endif
5048
#ifdef TARGET_NR_pread
5049
    case TARGET_NR_pread:
5050
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5051
            goto efault;
5052
        ret = get_errno(pread(arg1, p, arg3, arg4));
5053
        unlock_user(p, arg2, ret);
5054
        break;
5055
    case TARGET_NR_pwrite:
5056
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5057
            goto efault;
5058
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
5059
        unlock_user(p, arg2, 0);
5060
        break;
5061
#endif
5062
#ifdef TARGET_NR_pread64
5063
    case TARGET_NR_pread64:
5064
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5065
            goto efault;
5066
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5067
        unlock_user(p, arg2, ret);
5068
        break;
5069
    case TARGET_NR_pwrite64:
5070
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5071
            goto efault;
5072
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5073
        unlock_user(p, arg2, 0);
5074
        break;
5075
#endif
5076
    case TARGET_NR_getcwd:
5077
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5078
            goto efault;
5079
        ret = get_errno(sys_getcwd1(p, arg2));
5080
        unlock_user(p, arg1, ret);
5081
        break;
5082
    case TARGET_NR_capget:
5083
        goto unimplemented;
5084
    case TARGET_NR_capset:
5085
        goto unimplemented;
5086
    case TARGET_NR_sigaltstack:
5087
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5088
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5089
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5090
        break;
5091
#else
5092
        goto unimplemented;
5093
#endif
5094
    case TARGET_NR_sendfile:
5095
        goto unimplemented;
5096
#ifdef TARGET_NR_getpmsg
5097
    case TARGET_NR_getpmsg:
5098
        goto unimplemented;
5099
#endif
5100
#ifdef TARGET_NR_putpmsg
5101
    case TARGET_NR_putpmsg:
5102
        goto unimplemented;
5103
#endif
5104
#ifdef TARGET_NR_vfork
5105
    case TARGET_NR_vfork:
5106
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5107
                        0, 0, 0, 0));
5108
        break;
5109
#endif
5110
#ifdef TARGET_NR_ugetrlimit
5111
    case TARGET_NR_ugetrlimit:
5112
    {
5113
        struct rlimit rlim;
5114
        ret = get_errno(getrlimit(arg1, &rlim));
5115
        if (!is_error(ret)) {
5116
            struct target_rlimit *target_rlim;
5117
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5118
                goto efault;
5119
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5120
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
5121
            unlock_user_struct(target_rlim, arg2, 1);
5122
        }
5123
        break;
5124
    }
5125
#endif
5126
#ifdef TARGET_NR_truncate64
5127
    case TARGET_NR_truncate64:
5128
        if (!(p = lock_user_string(arg1)))
5129
            goto efault;
5130
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5131
        unlock_user(p, arg1, 0);
5132
        break;
5133
#endif
5134
#ifdef TARGET_NR_ftruncate64
5135
    case TARGET_NR_ftruncate64:
5136
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5137
        break;
5138
#endif
5139
#ifdef TARGET_NR_stat64
5140
    case TARGET_NR_stat64:
5141
        if (!(p = lock_user_string(arg1)))
5142
            goto efault;
5143
        ret = get_errno(stat(path(p), &st));
5144
        unlock_user(p, arg1, 0);
5145
        goto do_stat64;
5146
#endif
5147
#ifdef TARGET_NR_lstat64
5148
    case TARGET_NR_lstat64:
5149
        if (!(p = lock_user_string(arg1)))
5150
            goto efault;
5151
        ret = get_errno(lstat(path(p), &st));
5152
        unlock_user(p, arg1, 0);
5153
        goto do_stat64;
5154
#endif
5155
#ifdef TARGET_NR_fstat64
5156
    case TARGET_NR_fstat64:
5157
        {
5158
            ret = get_errno(fstat(arg1, &st));
5159
        do_stat64:
5160
            if (!is_error(ret)) {
5161
#ifdef TARGET_ARM
5162
                if (((CPUARMState *)cpu_env)->eabi) {
5163
                    struct target_eabi_stat64 *target_st;
5164

    
5165
                    if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5166
                        goto efault;
5167
                    memset(target_st, 0, sizeof(struct target_eabi_stat64));
5168
                    __put_user(st.st_dev, &target_st->st_dev);
5169
                    __put_user(st.st_ino, &target_st->st_ino);
5170
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5171
                    __put_user(st.st_ino, &target_st->__st_ino);
5172
#endif
5173
                    __put_user(st.st_mode, &target_st->st_mode);
5174
                    __put_user(st.st_nlink, &target_st->st_nlink);
5175
                    __put_user(st.st_uid, &target_st->st_uid);
5176
                    __put_user(st.st_gid, &target_st->st_gid);
5177
                    __put_user(st.st_rdev, &target_st->st_rdev);
5178
                    __put_user(st.st_size, &target_st->st_size);
5179
                    __put_user(st.st_blksize, &target_st->st_blksize);
5180
                    __put_user(st.st_blocks, &target_st->st_blocks);
5181
                    __put_user(st.st_atime, &target_st->target_st_atime);
5182
                    __put_user(st.st_mtime, &target_st->target_st_mtime);
5183
                    __put_user(st.st_ctime, &target_st->target_st_ctime);
5184
                    unlock_user_struct(target_st, arg2, 1);
5185
                } else
5186
#endif
5187
                {
5188
                    struct target_stat64 *target_st;
5189

    
5190
                    if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5191
                        goto efault;
5192
                    memset(target_st, 0, sizeof(struct target_stat64));
5193
                    __put_user(st.st_dev, &target_st->st_dev);
5194
                    __put_user(st.st_ino, &target_st->st_ino);
5195
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5196
                    __put_user(st.st_ino, &target_st->__st_ino);
5197
#endif
5198
                    __put_user(st.st_mode, &target_st->st_mode);
5199
                    __put_user(st.st_nlink, &target_st->st_nlink);
5200
                    __put_user(st.st_uid, &target_st->st_uid);
5201
                    __put_user(st.st_gid, &target_st->st_gid);
5202
                    __put_user(st.st_rdev, &target_st->st_rdev);
5203
                    /* XXX: better use of kernel struct */
5204
                    __put_user(st.st_size, &target_st->st_size);
5205
                    __put_user(st.st_blksize, &target_st->st_blksize);
5206
                    __put_user(st.st_blocks, &target_st->st_blocks);
5207
                    __put_user(st.st_atime, &target_st->target_st_atime);
5208
                    __put_user(st.st_mtime, &target_st->target_st_mtime);
5209
                    __put_user(st.st_ctime, &target_st->target_st_ctime);
5210
                    unlock_user_struct(target_st, arg2, 1);
5211
                }
5212
            }
5213
        }
5214
        break;
5215
#endif
5216
#ifdef USE_UID16
5217
    case TARGET_NR_lchown:
5218
        if (!(p = lock_user_string(arg1)))
5219
            goto efault;
5220
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5221
        unlock_user(p, arg1, 0);
5222
        break;
5223
    case TARGET_NR_getuid:
5224
        ret = get_errno(high2lowuid(getuid()));
5225
        break;
5226
    case TARGET_NR_getgid:
5227
        ret = get_errno(high2lowgid(getgid()));
5228
        break;
5229
    case TARGET_NR_geteuid:
5230
        ret = get_errno(high2lowuid(geteuid()));
5231
        break;
5232
    case TARGET_NR_getegid:
5233
        ret = get_errno(high2lowgid(getegid()));
5234
        break;
5235
    case TARGET_NR_setreuid:
5236
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5237
        break;
5238
    case TARGET_NR_setregid:
5239
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5240
        break;
5241
    case TARGET_NR_getgroups:
5242
        {
5243
            int gidsetsize = arg1;
5244
            uint16_t *target_grouplist;
5245
            gid_t *grouplist;
5246
            int i;
5247

    
5248
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5249
            ret = get_errno(getgroups(gidsetsize, grouplist));
5250
            if (gidsetsize == 0)
5251
                break;
5252
            if (!is_error(ret)) {
5253
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5254
                if (!target_grouplist)
5255
                    goto efault;
5256
                for(i = 0;i < gidsetsize; i++)
5257
                    target_grouplist[i] = tswap16(grouplist[i]);
5258
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5259
            }
5260
        }
5261
        break;
5262
    case TARGET_NR_setgroups:
5263
        {
5264
            int gidsetsize = arg1;
5265
            uint16_t *target_grouplist;
5266
            gid_t *grouplist;
5267
            int i;
5268

    
5269
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5270
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5271
            if (!target_grouplist) {
5272
                ret = -TARGET_EFAULT;
5273
                goto fail;
5274
            }
5275
            for(i = 0;i < gidsetsize; i++)
5276
                grouplist[i] = tswap16(target_grouplist[i]);
5277
            unlock_user(target_grouplist, arg2, 0);
5278
            ret = get_errno(setgroups(gidsetsize, grouplist));
5279
        }
5280
        break;
5281
    case TARGET_NR_fchown:
5282
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5283
        break;
5284
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5285
    case TARGET_NR_fchownat:
5286
        if (!(p = lock_user_string(arg2))) 
5287
            goto efault;
5288
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5289
        unlock_user(p, arg2, 0);
5290
        break;
5291
#endif
5292
#ifdef TARGET_NR_setresuid
5293
    case TARGET_NR_setresuid:
5294
        ret = get_errno(setresuid(low2highuid(arg1),
5295
                                  low2highuid(arg2),
5296
                                  low2highuid(arg3)));
5297
        break;
5298
#endif
5299
#ifdef TARGET_NR_getresuid
5300
    case TARGET_NR_getresuid:
5301
        {
5302
            uid_t ruid, euid, suid;
5303
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5304
            if (!is_error(ret)) {
5305
                if (put_user_u16(high2lowuid(ruid), arg1)
5306
                    || put_user_u16(high2lowuid(euid), arg2)
5307
                    || put_user_u16(high2lowuid(suid), arg3))
5308
                    goto efault;
5309
            }
5310
        }
5311
        break;
5312
#endif
5313
#ifdef TARGET_NR_getresgid
5314
    case TARGET_NR_setresgid:
5315
        ret = get_errno(setresgid(low2highgid(arg1),
5316
                                  low2highgid(arg2),
5317
                                  low2highgid(arg3)));
5318
        break;
5319
#endif
5320
#ifdef TARGET_NR_getresgid
5321
    case TARGET_NR_getresgid:
5322
        {
5323
            gid_t rgid, egid, sgid;
5324
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5325
            if (!is_error(ret)) {
5326
                if (put_user_u16(high2lowgid(rgid), arg1)
5327
                    || put_user_u16(high2lowgid(egid), arg2)
5328
                    || put_user_u16(high2lowgid(sgid), arg3))
5329
                    goto efault;
5330
            }
5331
        }
5332
        break;
5333
#endif
5334
    case TARGET_NR_chown:
5335
        if (!(p = lock_user_string(arg1)))
5336
            goto efault;
5337
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5338
        unlock_user(p, arg1, 0);
5339
        break;
5340
    case TARGET_NR_setuid:
5341
        ret = get_errno(setuid(low2highuid(arg1)));
5342
        break;
5343
    case TARGET_NR_setgid:
5344
        ret = get_errno(setgid(low2highgid(arg1)));
5345
        break;
5346
    case TARGET_NR_setfsuid:
5347
        ret = get_errno(setfsuid(arg1));
5348
        break;
5349
    case TARGET_NR_setfsgid:
5350
        ret = get_errno(setfsgid(arg1));
5351
        break;
5352
#endif /* USE_UID16 */
5353

    
5354
#ifdef TARGET_NR_lchown32
5355
    case TARGET_NR_lchown32:
5356
        if (!(p = lock_user_string(arg1)))
5357
            goto efault;
5358
        ret = get_errno(lchown(p, arg2, arg3));
5359
        unlock_user(p, arg1, 0);
5360
        break;
5361
#endif
5362
#ifdef TARGET_NR_getuid32
5363
    case TARGET_NR_getuid32:
5364
        ret = get_errno(getuid());
5365
        break;
5366
#endif
5367
#ifdef TARGET_NR_getgid32
5368
    case TARGET_NR_getgid32:
5369
        ret = get_errno(getgid());
5370
        break;
5371
#endif
5372
#ifdef TARGET_NR_geteuid32
5373
    case TARGET_NR_geteuid32:
5374
        ret = get_errno(geteuid());
5375
        break;
5376
#endif
5377
#ifdef TARGET_NR_getegid32
5378
    case TARGET_NR_getegid32:
5379
        ret = get_errno(getegid());
5380
        break;
5381
#endif
5382
#ifdef TARGET_NR_setreuid32
5383
    case TARGET_NR_setreuid32:
5384
        ret = get_errno(setreuid(arg1, arg2));
5385
        break;
5386
#endif
5387
#ifdef TARGET_NR_setregid32
5388
    case TARGET_NR_setregid32:
5389
        ret = get_errno(setregid(arg1, arg2));
5390
        break;
5391
#endif
5392
#ifdef TARGET_NR_getgroups32
5393
    case TARGET_NR_getgroups32:
5394
        {
5395
            int gidsetsize = arg1;
5396
            uint32_t *target_grouplist;
5397
            gid_t *grouplist;
5398
            int i;
5399

    
5400
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5401
            ret = get_errno(getgroups(gidsetsize, grouplist));
5402
            if (gidsetsize == 0)
5403
                break;
5404
            if (!is_error(ret)) {
5405
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5406
                if (!target_grouplist) {
5407
                    ret = -TARGET_EFAULT;
5408
                    goto fail;
5409
                }
5410
                for(i = 0;i < gidsetsize; i++)
5411
                    target_grouplist[i] = tswap32(grouplist[i]);
5412
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
5413
            }
5414
        }
5415
        break;
5416
#endif
5417
#ifdef TARGET_NR_setgroups32
5418
    case TARGET_NR_setgroups32:
5419
        {
5420
            int gidsetsize = arg1;
5421
            uint32_t *target_grouplist;
5422
            gid_t *grouplist;
5423
            int i;
5424

    
5425
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5426
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5427
            if (!target_grouplist) {
5428
                ret = -TARGET_EFAULT;
5429
                goto fail;
5430
            }
5431
            for(i = 0;i < gidsetsize; i++)
5432
                grouplist[i] = tswap32(target_grouplist[i]);
5433
            unlock_user(target_grouplist, arg2, 0);
5434
            ret = get_errno(setgroups(gidsetsize, grouplist));
5435
        }
5436
        break;
5437
#endif
5438
#ifdef TARGET_NR_fchown32
5439
    case TARGET_NR_fchown32:
5440
        ret = get_errno(fchown(arg1, arg2, arg3));
5441
        break;
5442
#endif
5443
#ifdef TARGET_NR_setresuid32
5444
    case TARGET_NR_setresuid32:
5445
        ret = get_errno(setresuid(arg1, arg2, arg3));
5446
        break;
5447
#endif
5448
#ifdef TARGET_NR_getresuid32
5449
    case TARGET_NR_getresuid32:
5450
        {
5451
            uid_t ruid, euid, suid;
5452
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5453
            if (!is_error(ret)) {
5454
                if (put_user_u32(ruid, arg1)
5455
                    || put_user_u32(euid, arg2)
5456
                    || put_user_u32(suid, arg3))
5457
                    goto efault;
5458
            }
5459
        }
5460
        break;
5461
#endif
5462
#ifdef TARGET_NR_setresgid32
5463
    case TARGET_NR_setresgid32:
5464
        ret = get_errno(setresgid(arg1, arg2, arg3));
5465
        break;
5466
#endif
5467
#ifdef TARGET_NR_getresgid32
5468
    case TARGET_NR_getresgid32:
5469
        {
5470
            gid_t rgid, egid, sgid;
5471
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5472
            if (!is_error(ret)) {
5473
                if (put_user_u32(rgid, arg1)
5474
                    || put_user_u32(egid, arg2)
5475
                    || put_user_u32(sgid, arg3))
5476
                    goto efault;
5477
            }
5478
        }
5479
        break;
5480
#endif
5481
#ifdef TARGET_NR_chown32
5482
    case TARGET_NR_chown32:
5483
        if (!(p = lock_user_string(arg1)))
5484
            goto efault;
5485
        ret = get_errno(chown(p, arg2, arg3));
5486
        unlock_user(p, arg1, 0);
5487
        break;
5488
#endif
5489
#ifdef TARGET_NR_setuid32
5490
    case TARGET_NR_setuid32:
5491
        ret = get_errno(setuid(arg1));
5492
        break;
5493
#endif
5494
#ifdef TARGET_NR_setgid32
5495
    case TARGET_NR_setgid32:
5496
        ret = get_errno(setgid(arg1));
5497
        break;
5498
#endif
5499
#ifdef TARGET_NR_setfsuid32
5500
    case TARGET_NR_setfsuid32:
5501
        ret = get_errno(setfsuid(arg1));
5502
        break;
5503
#endif
5504
#ifdef TARGET_NR_setfsgid32
5505
    case TARGET_NR_setfsgid32:
5506
        ret = get_errno(setfsgid(arg1));
5507
        break;
5508
#endif
5509

    
5510
    case TARGET_NR_pivot_root:
5511
        goto unimplemented;
5512
#ifdef TARGET_NR_mincore
5513
    case TARGET_NR_mincore:
5514
        goto unimplemented;
5515
#endif
5516
#ifdef TARGET_NR_madvise
5517
    case TARGET_NR_madvise:
5518
        /* A straight passthrough may not be safe because qemu sometimes
5519
           turns private flie-backed mappings into anonymous mappings.
5520
           This will break MADV_DONTNEED.
5521
           This is a hint, so ignoring and returning success is ok.  */
5522
        ret = get_errno(0);
5523
        break;
5524
#endif
5525
#if TARGET_ABI_BITS == 32
5526
    case TARGET_NR_fcntl64:
5527
    {
5528
        int cmd;
5529
        struct flock64 fl;
5530
        struct target_flock64 *target_fl;
5531
#ifdef TARGET_ARM
5532
        struct target_eabi_flock64 *target_efl;
5533
#endif
5534

    
5535
        switch(arg2){
5536
        case TARGET_F_GETLK64:
5537
            cmd = F_GETLK64;
5538
            break;
5539
        case TARGET_F_SETLK64:
5540
            cmd = F_SETLK64;
5541
            break;
5542
        case TARGET_F_SETLKW64:
5543
            cmd = F_SETLK64;
5544
            break;
5545
        default:
5546
            cmd = arg2;
5547
            break;
5548
        }
5549

    
5550
        switch(arg2) {
5551
        case TARGET_F_GETLK64:
5552
#ifdef TARGET_ARM
5553
            if (((CPUARMState *)cpu_env)->eabi) {
5554
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5555
                    goto efault;
5556
                fl.l_type = tswap16(target_efl->l_type);
5557
                fl.l_whence = tswap16(target_efl->l_whence);
5558
                fl.l_start = tswap64(target_efl->l_start);
5559
                fl.l_len = tswap64(target_efl->l_len);
5560
                fl.l_pid = tswapl(target_efl->l_pid);
5561
                unlock_user_struct(target_efl, arg3, 0);
5562
            } else
5563
#endif
5564
            {
5565
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5566
                    goto efault;
5567
                fl.l_type = tswap16(target_fl->l_type);
5568
                fl.l_whence = tswap16(target_fl->l_whence);
5569
                fl.l_start = tswap64(target_fl->l_start);
5570
                fl.l_len = tswap64(target_fl->l_len);
5571
                fl.l_pid = tswapl(target_fl->l_pid);
5572
                unlock_user_struct(target_fl, arg3, 0);
5573
            }
5574
            ret = get_errno(fcntl(arg1, cmd, &fl));
5575
            if (ret == 0) {
5576
#ifdef TARGET_ARM
5577
                if (((CPUARMState *)cpu_env)->eabi) {
5578
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
5579
                        goto efault;
5580
                    target_efl->l_type = tswap16(fl.l_type);
5581
                    target_efl->l_whence = tswap16(fl.l_whence);
5582
                    target_efl->l_start = tswap64(fl.l_start);
5583
                    target_efl->l_len = tswap64(fl.l_len);
5584
                    target_efl->l_pid = tswapl(fl.l_pid);
5585
                    unlock_user_struct(target_efl, arg3, 1);
5586
                } else
5587
#endif
5588
                {
5589
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
5590
                        goto efault;
5591
                    target_fl->l_type = tswap16(fl.l_type);
5592
                    target_fl->l_whence = tswap16(fl.l_whence);
5593
                    target_fl->l_start = tswap64(fl.l_start);
5594
                    target_fl->l_len = tswap64(fl.l_len);
5595
                    target_fl->l_pid = tswapl(fl.l_pid);
5596
                    unlock_user_struct(target_fl, arg3, 1);
5597
                }
5598
            }
5599
            break;
5600

    
5601
        case TARGET_F_SETLK64:
5602
        case TARGET_F_SETLKW64:
5603
#ifdef TARGET_ARM
5604
            if (((CPUARMState *)cpu_env)->eabi) {
5605
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5606
                    goto efault;
5607
                fl.l_type = tswap16(target_efl->l_type);
5608
                fl.l_whence = tswap16(target_efl->l_whence);
5609
                fl.l_start = tswap64(target_efl->l_start);
5610
                fl.l_len = tswap64(target_efl->l_len);
5611
                fl.l_pid = tswapl(target_efl->l_pid);
5612
                unlock_user_struct(target_efl, arg3, 0);
5613
            } else
5614
#endif
5615
            {
5616
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5617
                    goto efault;
5618
                fl.l_type = tswap16(target_fl->l_type);
5619
                fl.l_whence = tswap16(target_fl->l_whence);
5620
                fl.l_start = tswap64(target_fl->l_start);
5621
                fl.l_len = tswap64(target_fl->l_len);
5622
                fl.l_pid = tswapl(target_fl->l_pid);
5623
                unlock_user_struct(target_fl, arg3, 0);
5624
            }
5625
            ret = get_errno(fcntl(arg1, cmd, &fl));
5626
            break;
5627
        default:
5628
            ret = do_fcntl(arg1, cmd, arg3);
5629
            break;
5630
        }
5631
        break;
5632
    }
5633
#endif
5634
#ifdef TARGET_NR_cacheflush
5635
    case TARGET_NR_cacheflush:
5636
        /* self-modifying code is handled automatically, so nothing needed */
5637
        ret = 0;
5638
        break;
5639
#endif
5640
#ifdef TARGET_NR_security
5641
    case TARGET_NR_security:
5642
        goto unimplemented;
5643
#endif
5644
#ifdef TARGET_NR_getpagesize
5645
    case TARGET_NR_getpagesize:
5646
        ret = TARGET_PAGE_SIZE;
5647
        break;
5648
#endif
5649
    case TARGET_NR_gettid:
5650
        ret = get_errno(gettid());
5651
        break;
5652
#ifdef TARGET_NR_readahead
5653
    case TARGET_NR_readahead:
5654
        goto unimplemented;
5655
#endif
5656
#ifdef TARGET_NR_setxattr
5657
    case TARGET_NR_setxattr:
5658
    case TARGET_NR_lsetxattr:
5659
    case TARGET_NR_fsetxattr:
5660
    case TARGET_NR_getxattr:
5661
    case TARGET_NR_lgetxattr:
5662
    case TARGET_NR_fgetxattr:
5663
    case TARGET_NR_listxattr:
5664
    case TARGET_NR_llistxattr:
5665
    case TARGET_NR_flistxattr:
5666
    case TARGET_NR_removexattr:
5667
    case TARGET_NR_lremovexattr:
5668
    case TARGET_NR_fremovexattr:
5669
        goto unimplemented_nowarn;
5670
#endif
5671
#ifdef TARGET_NR_set_thread_area
5672
    case TARGET_NR_set_thread_area:
5673
#if defined(TARGET_MIPS)
5674
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5675
      ret = 0;
5676
      break;
5677
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
5678
      ret = do_set_thread_area(cpu_env, arg1);
5679
      break;
5680
#else
5681
      goto unimplemented_nowarn;
5682
#endif
5683
#endif
5684
#ifdef TARGET_NR_get_thread_area
5685
    case TARGET_NR_get_thread_area:
5686
#if defined(TARGET_I386) && defined(TARGET_ABI32)
5687
        ret = do_get_thread_area(cpu_env, arg1);
5688
#else
5689
        goto unimplemented_nowarn;
5690
#endif
5691
#endif
5692
#ifdef TARGET_NR_getdomainname
5693
    case TARGET_NR_getdomainname:
5694
        goto unimplemented_nowarn;
5695
#endif
5696

    
5697
#ifdef TARGET_NR_clock_gettime
5698
    case TARGET_NR_clock_gettime:
5699
    {
5700
        struct timespec ts;
5701
        ret = get_errno(clock_gettime(arg1, &ts));
5702
        if (!is_error(ret)) {
5703
            host_to_target_timespec(arg2, &ts);
5704
        }
5705
        break;
5706
    }
5707
#endif
5708
#ifdef TARGET_NR_clock_getres
5709
    case TARGET_NR_clock_getres:
5710
    {
5711
        struct timespec ts;
5712
        ret = get_errno(clock_getres(arg1, &ts));
5713
        if (!is_error(ret)) {
5714
            host_to_target_timespec(arg2, &ts);
5715
        }
5716
        break;
5717
    }
5718
#endif
5719
#ifdef TARGET_NR_clock_nanosleep
5720
    case TARGET_NR_clock_nanosleep:
5721
    {
5722
        struct timespec ts;
5723
        target_to_host_timespec(&ts, arg3);
5724
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5725
        if (arg4)
5726
            host_to_target_timespec(arg4, &ts);
5727
        break;
5728
    }
5729
#endif
5730

    
5731
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5732
    case TARGET_NR_set_tid_address:
5733
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
5734
        break;
5735
#endif
5736

    
5737
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5738
    case TARGET_NR_tkill:
5739
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5740
        break;
5741
#endif
5742

    
5743
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5744
    case TARGET_NR_tgkill:
5745
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5746
                        target_to_host_signal(arg3)));
5747
        break;
5748
#endif
5749

    
5750
#ifdef TARGET_NR_set_robust_list
5751
    case TARGET_NR_set_robust_list:
5752
        goto unimplemented_nowarn;
5753
#endif
5754

    
5755
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5756
    case TARGET_NR_utimensat:
5757
        {
5758
            struct timespec ts[2];
5759
            target_to_host_timespec(ts, arg3);
5760
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5761
            if (!arg2)
5762
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5763
            else {
5764
                if (!(p = lock_user_string(arg2))) {
5765
                    ret = -TARGET_EFAULT;
5766
                    goto fail;
5767
                }
5768
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
5769
                unlock_user(p, arg2, 0);
5770
            }
5771
        }
5772
        break;
5773
#endif
5774
#if defined(USE_NPTL)
5775
    case TARGET_NR_futex:
5776
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
5777
        break;
5778
#endif
5779

    
5780
    default:
5781
    unimplemented:
5782
        gemu_log("qemu: Unsupported syscall: %d\n", num);
5783
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
5784
    unimplemented_nowarn:
5785
#endif
5786
        ret = -TARGET_ENOSYS;
5787
        break;
5788
    }
5789
fail:
5790
#ifdef DEBUG
5791
    gemu_log(" = %ld\n", ret);
5792
#endif
5793
    if(do_strace)
5794
        print_syscall_ret(num, ret);
5795
    return ret;
5796
efault:
5797
    ret = -TARGET_EFAULT;
5798
    goto fail;
5799
}