Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ ac8a6556

History | View | Annotate | Download (181.8 kB)

1
/*
2
 *  Linux syscalls
3
 *
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 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_fstatat64 __NR_fstatat64
160
#define __NR_sys_futimesat __NR_futimesat
161
#define __NR_sys_getcwd1 __NR_getcwd
162
#define __NR_sys_getdents __NR_getdents
163
#define __NR_sys_getdents64 __NR_getdents64
164
#define __NR_sys_getpriority __NR_getpriority
165
#define __NR_sys_linkat __NR_linkat
166
#define __NR_sys_mkdirat __NR_mkdirat
167
#define __NR_sys_mknodat __NR_mknodat
168
#define __NR_sys_openat __NR_openat
169
#define __NR_sys_readlinkat __NR_readlinkat
170
#define __NR_sys_renameat __NR_renameat
171
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
172
#define __NR_sys_symlinkat __NR_symlinkat
173
#define __NR_sys_syslog __NR_syslog
174
#define __NR_sys_tgkill __NR_tgkill
175
#define __NR_sys_tkill __NR_tkill
176
#define __NR_sys_unlinkat __NR_unlinkat
177
#define __NR_sys_utimensat __NR_utimensat
178
#define __NR_sys_futex __NR_futex
179

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

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

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

    
285
#define ERRNO_TABLE_SIZE 1200
286

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

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

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

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

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

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

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

    
436
static abi_ulong target_brk;
437
static abi_ulong target_original_brk;
438

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

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

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

    
456
    brk_page = HOST_PAGE_ALIGN(target_brk);
457

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

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

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

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

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

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

    
503
    unlock_user(target_fds, target_fds_addr, 0);
504

    
505
    return 0;
506
}
507

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

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

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

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

    
535
    return 0;
536
}
537

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

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

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

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

    
580
    return 0;
581
}
582

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

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

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

    
594
    unlock_user_struct(target_tv, target_tv_addr, 0);
595

    
596
    return 0;
597
}
598

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

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

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

    
610
    unlock_user_struct(target_tv, target_tv_addr, 1);
611

    
612
    return 0;
613
}
614

    
615

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

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

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

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

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

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

    
670
    return ret;
671
}
672

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

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

    
686
    return 0;
687
}
688

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

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

    
702
    return 0;
703
}
704

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1097
    return 0;
1098
}
1099

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

    
1130
/* do_bind() Must return target values and target errnos. */
1131
static abi_long do_bind(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(bind(sockfd, addr, addrlen));
1138
}
1139

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

    
1146
    target_to_host_sockaddr(addr, target_addr, addrlen);
1147
    return get_errno(connect(sockfd, addr, addrlen));
1148
}
1149

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

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

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

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

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

    
1209
    if (get_user_u32(addrlen, target_addrlen_addr))
1210
        return -TARGET_EFAULT;
1211

    
1212
    addr = alloca(addrlen);
1213

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

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

    
1231
    if (get_user_u32(addrlen, target_addrlen_addr))
1232
        return -TARGET_EFAULT;
1233

    
1234
    addr = alloca(addrlen);
1235

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

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

    
1253
    if (get_user_u32(addrlen, target_addrlen_addr))
1254
        return -TARGET_EFAULT;
1255

    
1256
    addr = alloca(addrlen);
1257

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1601
#ifdef TARGET_NR_ipc
1602
#define N_SHM_REGIONS        32
1603

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1795
    switch( cmd ) {
1796
        case GETVAL:
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 SETVAL:
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 GETALL:
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 SETALL:
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
        case IPC_STAT:
1817
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1818
            ret = get_errno(semctl(first, second, cmd, arg));
1819
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1820
            break;
1821
        case IPC_SET:
1822
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1823
            ret = get_errno(semctl(first, second, cmd, arg));
1824
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1825
            break;
1826
    default:
1827
            ret = get_errno(semctl(first, second, cmd, arg));
1828
    }
1829

    
1830
    return ret;
1831
}
1832

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

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

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

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

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

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

    
1908
struct target_msgbuf {
1909
        abi_ulong mtype;
1910
        char        mtext[1];
1911
};
1912

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

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

    
1929
    return ret;
1930
}
1931

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

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

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

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

    
1975
    version = call >> 16;
1976
    call &= 0xffff;
1977

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

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

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

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

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

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

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

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

    
2017
                      struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
2018
                      struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
2019

    
2020
                      ret = do_msgrcv(first, (long)msgp, second, 0, third);
2021

    
2022
                }
2023
                break;
2024

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

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

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

    
2097
/* kernel structure types definitions */
2098
#define IFNAMSIZ        16
2099

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

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

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

    
2122
#define IOC_R 0x0001
2123
#define IOC_W 0x0002
2124
#define IOC_RW (IOC_R | IOC_W)
2125

    
2126
#define MAX_STRUCT_SIZE 4096
2127

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2425
#if defined(TARGET_I386)
2426

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2729
#endif /* defined(TARGET_I386) */
2730

    
2731
#if defined(USE_NPTL)
2732

    
2733
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2734

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

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

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

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

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

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

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

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

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

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

    
2842
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
2843

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

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

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

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

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

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

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

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

    
3002
#ifdef USE_UID16
3003

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

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

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

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

    
3036
#endif /* USE_UID16 */
3037

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3219
    return 0;
3220
}
3221
#endif
3222

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

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

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

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

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

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

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

    
3468
            argp = alloca((argc + 1) * sizeof(void *));
3469
            envp = alloca((envc + 1) * sizeof(void *));
3470

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

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

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

    
3498
            goto execve_end;
3499

    
3500
        execve_efault:
3501
            ret = -TARGET_EFAULT;
3502

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

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

    
3932
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3933

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

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

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

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

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

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

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

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

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

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

    
4597
    case TARGET_NR_setitimer:
4598
        {
4599
            struct itimerval value, ovalue, *pvalue;
4600

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

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

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

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

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

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

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

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

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

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

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

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

    
5298
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5299
            ret = get_errno(getgroups(gidsetsize, grouplist));
5300
            if (gidsetsize == 0)
5301
                break;
5302
            if (!is_error(ret)) {
5303
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5304
                if (!target_grouplist)
5305
                    goto efault;
5306
                for(i = 0;i < ret; i++)
5307
                    target_grouplist[i] = tswap16(grouplist[i]);
5308
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5309
            }
5310
        }
5311
        break;
5312
    case TARGET_NR_setgroups:
5313
        {
5314
            int gidsetsize = arg1;
5315
            uint16_t *target_grouplist;
5316
            gid_t *grouplist;
5317
            int i;
5318

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

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

    
5450
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5451
            ret = get_errno(getgroups(gidsetsize, grouplist));
5452
            if (gidsetsize == 0)
5453
                break;
5454
            if (!is_error(ret)) {
5455
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5456
                if (!target_grouplist) {
5457
                    ret = -TARGET_EFAULT;
5458
                    goto fail;
5459
                }
5460
                for(i = 0;i < ret; i++)
5461
                    target_grouplist[i] = tswap32(grouplist[i]);
5462
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
5463
            }
5464
        }
5465
        break;
5466
#endif
5467
#ifdef TARGET_NR_setgroups32
5468
    case TARGET_NR_setgroups32:
5469
        {
5470
            int gidsetsize = arg1;
5471
            uint32_t *target_grouplist;
5472
            gid_t *grouplist;
5473
            int i;
5474

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

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

    
5585
        switch(arg2){
5586
        case TARGET_F_GETLK64:
5587
            cmd = F_GETLK64;
5588
            break;
5589
        case TARGET_F_SETLK64:
5590
            cmd = F_SETLK64;
5591
            break;
5592
        case TARGET_F_SETLKW64:
5593
            cmd = F_SETLK64;
5594
            break;
5595
        default:
5596
            cmd = arg2;
5597
            break;
5598
        }
5599

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

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

    
5747
#ifdef TARGET_NR_clock_gettime
5748
    case TARGET_NR_clock_gettime:
5749
    {
5750
        struct timespec ts;
5751
        ret = get_errno(clock_gettime(arg1, &ts));
5752
        if (!is_error(ret)) {
5753
            host_to_target_timespec(arg2, &ts);
5754
        }
5755
        break;
5756
    }
5757
#endif
5758
#ifdef TARGET_NR_clock_getres
5759
    case TARGET_NR_clock_getres:
5760
    {
5761
        struct timespec ts;
5762
        ret = get_errno(clock_getres(arg1, &ts));
5763
        if (!is_error(ret)) {
5764
            host_to_target_timespec(arg2, &ts);
5765
        }
5766
        break;
5767
    }
5768
#endif
5769
#ifdef TARGET_NR_clock_nanosleep
5770
    case TARGET_NR_clock_nanosleep:
5771
    {
5772
        struct timespec ts;
5773
        target_to_host_timespec(&ts, arg3);
5774
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5775
        if (arg4)
5776
            host_to_target_timespec(arg4, &ts);
5777
        break;
5778
    }
5779
#endif
5780

    
5781
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5782
    case TARGET_NR_set_tid_address:
5783
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
5784
        break;
5785
#endif
5786

    
5787
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5788
    case TARGET_NR_tkill:
5789
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5790
        break;
5791
#endif
5792

    
5793
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5794
    case TARGET_NR_tgkill:
5795
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5796
                        target_to_host_signal(arg3)));
5797
        break;
5798
#endif
5799

    
5800
#ifdef TARGET_NR_set_robust_list
5801
    case TARGET_NR_set_robust_list:
5802
        goto unimplemented_nowarn;
5803
#endif
5804

    
5805
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5806
    case TARGET_NR_utimensat:
5807
        {
5808
            struct timespec ts[2];
5809
            target_to_host_timespec(ts, arg3);
5810
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5811
            if (!arg2)
5812
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5813
            else {
5814
                if (!(p = lock_user_string(arg2))) {
5815
                    ret = -TARGET_EFAULT;
5816
                    goto fail;
5817
                }
5818
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
5819
                unlock_user(p, arg2, 0);
5820
            }
5821
        }
5822
        break;
5823
#endif
5824
#if defined(USE_NPTL)
5825
    case TARGET_NR_futex:
5826
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
5827
        break;
5828
#endif
5829

    
5830
    default:
5831
    unimplemented:
5832
        gemu_log("qemu: Unsupported syscall: %d\n", num);
5833
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
5834
    unimplemented_nowarn:
5835
#endif
5836
        ret = -TARGET_ENOSYS;
5837
        break;
5838
    }
5839
fail:
5840
#ifdef DEBUG
5841
    gemu_log(" = %ld\n", ret);
5842
#endif
5843
    if(do_strace)
5844
        print_syscall_ret(num, ret);
5845
    return ret;
5846
efault:
5847
    ret = -TARGET_EFAULT;
5848
    goto fail;
5849
}