Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 8fbd6b52

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

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

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

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

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

    
88
//#define DEBUG
89

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

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

    
100

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

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

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

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

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

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

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

    
146

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

    
155

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

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

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

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

    
286
#define ERRNO_TABLE_SIZE 1200
287

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

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

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

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

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

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

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

    
437
static abi_ulong target_brk;
438
static abi_ulong target_original_brk;
439

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

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

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

    
457
    brk_page = HOST_PAGE_ALIGN(target_brk);
458

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

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

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

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

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

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

    
504
    unlock_user(target_fds, target_fds_addr, 0);
505

    
506
    return 0;
507
}
508

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

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

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

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

    
536
    return 0;
537
}
538

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

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

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

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

    
581
    return 0;
582
}
583

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

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

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

    
595
    unlock_user_struct(target_tv, target_tv_addr, 0);
596

    
597
    return 0;
598
}
599

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

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

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

    
611
    unlock_user_struct(target_tv, target_tv_addr, 1);
612

    
613
    return 0;
614
}
615

    
616

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

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

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

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

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

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

    
671
    return ret;
672
}
673

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

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

    
687
    return 0;
688
}
689

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

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

    
703
    return 0;
704
}
705

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1098
    return 0;
1099
}
1100

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

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

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

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

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

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

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

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

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

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

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

    
1213
    addr = alloca(addrlen);
1214

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

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

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

    
1235
    addr = alloca(addrlen);
1236

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

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

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

    
1257
    addr = alloca(addrlen);
1258

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1602
#ifdef TARGET_NR_ipc
1603
#define N_SHM_REGIONS        32
1604

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1831
    return ret;
1832
}
1833

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

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

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

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

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

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

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

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

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

    
1930
    return ret;
1931
}
1932

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2023
                }
2024
                break;
2025

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

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

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

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

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

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

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

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

    
2127
#define MAX_STRUCT_SIZE 4096
2128

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2426
#if defined(TARGET_I386)
2427

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2732
#if defined(USE_NPTL)
2733

    
2734
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2735

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3003
#ifdef USE_UID16
3004

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

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

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

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

    
3037
#endif /* USE_UID16 */
3038

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3220
    return 0;
3221
}
3222
#endif
3223

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

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

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

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

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

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

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

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

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

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

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

    
3499
            goto execve_end;
3500

    
3501
        execve_efault:
3502
            ret = -TARGET_EFAULT;
3503

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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