Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ b1d8e52e

History | View | Annotate | Download (186.8 kB)

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

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

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

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

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

    
87
//#define DEBUG
88

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

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

    
99

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

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

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

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

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

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

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

    
145

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

    
154

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

    
183
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
184
#define __NR__llseek __NR_lseek
185
#endif
186

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

    
291
extern int personality(int);
292
extern int flock(int, int);
293
extern int setfsuid(int);
294
extern int setfsgid(int);
295
extern int setgroups(int, gid_t *);
296

    
297
#define ERRNO_TABLE_SIZE 1200
298

    
299
/* target_to_host_errno_table[] is initialized from
300
 * host_to_target_errno_table[] in syscall_init(). */
301
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
302
};
303

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

    
416
static inline int host_to_target_errno(int err)
417
{
418
    if(host_to_target_errno_table[err])
419
        return host_to_target_errno_table[err];
420
    return err;
421
}
422

    
423
static inline int target_to_host_errno(int err)
424
{
425
    if (target_to_host_errno_table[err])
426
        return target_to_host_errno_table[err];
427
    return err;
428
}
429

    
430
static inline abi_long get_errno(abi_long ret)
431
{
432
    if (ret == -1)
433
        return -host_to_target_errno(errno);
434
    else
435
        return ret;
436
}
437

    
438
static inline int is_error(abi_long ret)
439
{
440
    return (abi_ulong)ret >= (abi_ulong)(-4096);
441
}
442

    
443
char *target_strerror(int err)
444
{
445
    return strerror(target_to_host_errno(err));
446
}
447

    
448
static abi_ulong target_brk;
449
static abi_ulong target_original_brk;
450

    
451
void target_set_brk(abi_ulong new_brk)
452
{
453
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
454
}
455

    
456
/* do_brk() must return target values and target errnos. */
457
abi_long do_brk(abi_ulong new_brk)
458
{
459
    abi_ulong brk_page;
460
    abi_long mapped_addr;
461
    int        new_alloc_size;
462

    
463
    if (!new_brk)
464
        return target_brk;
465
    if (new_brk < target_original_brk)
466
        return target_brk;
467

    
468
    brk_page = HOST_PAGE_ALIGN(target_brk);
469

    
470
    /* If the new brk is less than this, set it and we're done... */
471
    if (new_brk < brk_page) {
472
        target_brk = new_brk;
473
            return target_brk;
474
    }
475

    
476
    /* We need to allocate more memory after the brk... */
477
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
478
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
479
                                        PROT_READ|PROT_WRITE,
480
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
481

    
482
    if (!is_error(mapped_addr))
483
        target_brk = new_brk;
484
    
485
    return target_brk;
486
}
487

    
488
static inline abi_long copy_from_user_fdset(fd_set *fds,
489
                                            abi_ulong target_fds_addr,
490
                                            int n)
491
{
492
    int i, nw, j, k;
493
    abi_ulong b, *target_fds;
494

    
495
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
496
    if (!(target_fds = lock_user(VERIFY_READ,
497
                                 target_fds_addr,
498
                                 sizeof(abi_ulong) * nw,
499
                                 1)))
500
        return -TARGET_EFAULT;
501

    
502
    FD_ZERO(fds);
503
    k = 0;
504
    for (i = 0; i < nw; i++) {
505
        /* grab the abi_ulong */
506
        __get_user(b, &target_fds[i]);
507
        for (j = 0; j < TARGET_ABI_BITS; j++) {
508
            /* check the bit inside the abi_ulong */
509
            if ((b >> j) & 1)
510
                FD_SET(k, fds);
511
            k++;
512
        }
513
    }
514

    
515
    unlock_user(target_fds, target_fds_addr, 0);
516

    
517
    return 0;
518
}
519

    
520
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
521
                                          const fd_set *fds,
522
                                          int n)
523
{
524
    int i, nw, j, k;
525
    abi_long v;
526
    abi_ulong *target_fds;
527

    
528
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
529
    if (!(target_fds = lock_user(VERIFY_WRITE,
530
                                 target_fds_addr,
531
                                 sizeof(abi_ulong) * nw,
532
                                 0)))
533
        return -TARGET_EFAULT;
534

    
535
    k = 0;
536
    for (i = 0; i < nw; i++) {
537
        v = 0;
538
        for (j = 0; j < TARGET_ABI_BITS; j++) {
539
            v |= ((FD_ISSET(k, fds) != 0) << j);
540
            k++;
541
        }
542
        __put_user(v, &target_fds[i]);
543
    }
544

    
545
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
546

    
547
    return 0;
548
}
549

    
550
#if defined(__alpha__)
551
#define HOST_HZ 1024
552
#else
553
#define HOST_HZ 100
554
#endif
555

    
556
static inline abi_long host_to_target_clock_t(long ticks)
557
{
558
#if HOST_HZ == TARGET_HZ
559
    return ticks;
560
#else
561
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
562
#endif
563
}
564

    
565
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
566
                                             const struct rusage *rusage)
567
{
568
    struct target_rusage *target_rusage;
569

    
570
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
571
        return -TARGET_EFAULT;
572
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
573
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
574
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
575
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
576
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
577
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
578
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
579
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
580
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
581
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
582
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
583
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
584
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
585
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
586
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
587
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
588
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
589
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
590
    unlock_user_struct(target_rusage, target_addr, 1);
591

    
592
    return 0;
593
}
594

    
595
static inline abi_long copy_from_user_timeval(struct timeval *tv,
596
                                              abi_ulong target_tv_addr)
597
{
598
    struct target_timeval *target_tv;
599

    
600
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
601
        return -TARGET_EFAULT;
602

    
603
    __get_user(tv->tv_sec, &target_tv->tv_sec);
604
    __get_user(tv->tv_usec, &target_tv->tv_usec);
605

    
606
    unlock_user_struct(target_tv, target_tv_addr, 0);
607

    
608
    return 0;
609
}
610

    
611
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
612
                                            const struct timeval *tv)
613
{
614
    struct target_timeval *target_tv;
615

    
616
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
617
        return -TARGET_EFAULT;
618

    
619
    __put_user(tv->tv_sec, &target_tv->tv_sec);
620
    __put_user(tv->tv_usec, &target_tv->tv_usec);
621

    
622
    unlock_user_struct(target_tv, target_tv_addr, 1);
623

    
624
    return 0;
625
}
626

    
627

    
628
/* do_select() must return target values and target errnos. */
629
static abi_long do_select(int n,
630
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
631
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
632
{
633
    fd_set rfds, wfds, efds;
634
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
635
    struct timeval tv, *tv_ptr;
636
    abi_long ret;
637

    
638
    if (rfd_addr) {
639
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
640
            return -TARGET_EFAULT;
641
        rfds_ptr = &rfds;
642
    } else {
643
        rfds_ptr = NULL;
644
    }
645
    if (wfd_addr) {
646
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
647
            return -TARGET_EFAULT;
648
        wfds_ptr = &wfds;
649
    } else {
650
        wfds_ptr = NULL;
651
    }
652
    if (efd_addr) {
653
        if (copy_from_user_fdset(&efds, efd_addr, n))
654
            return -TARGET_EFAULT;
655
        efds_ptr = &efds;
656
    } else {
657
        efds_ptr = NULL;
658
    }
659

    
660
    if (target_tv_addr) {
661
        if (copy_from_user_timeval(&tv, target_tv_addr))
662
            return -TARGET_EFAULT;
663
        tv_ptr = &tv;
664
    } else {
665
        tv_ptr = NULL;
666
    }
667

    
668
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
669

    
670
    if (!is_error(ret)) {
671
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
672
            return -TARGET_EFAULT;
673
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
674
            return -TARGET_EFAULT;
675
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
676
            return -TARGET_EFAULT;
677

    
678
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
679
            return -TARGET_EFAULT;
680
    }
681

    
682
    return ret;
683
}
684

    
685
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
686
                                               abi_ulong target_addr,
687
                                               socklen_t len)
688
{
689
    struct target_sockaddr *target_saddr;
690

    
691
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
692
    if (!target_saddr)
693
        return -TARGET_EFAULT;
694
    memcpy(addr, target_saddr, len);
695
    addr->sa_family = tswap16(target_saddr->sa_family);
696
    unlock_user(target_saddr, target_addr, 0);
697

    
698
    return 0;
699
}
700

    
701
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
702
                                               struct sockaddr *addr,
703
                                               socklen_t len)
704
{
705
    struct target_sockaddr *target_saddr;
706

    
707
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
708
    if (!target_saddr)
709
        return -TARGET_EFAULT;
710
    memcpy(target_saddr, addr, len);
711
    target_saddr->sa_family = tswap16(addr->sa_family);
712
    unlock_user(target_saddr, target_addr, len);
713

    
714
    return 0;
715
}
716

    
717
/* ??? Should this also swap msgh->name?  */
718
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
719
                                           struct target_msghdr *target_msgh)
720
{
721
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
722
    abi_long msg_controllen;
723
    abi_ulong target_cmsg_addr;
724
    struct target_cmsghdr *target_cmsg;
725
    socklen_t space = 0;
726
    
727
    msg_controllen = tswapl(target_msgh->msg_controllen);
728
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
729
        goto the_end;
730
    target_cmsg_addr = tswapl(target_msgh->msg_control);
731
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
732
    if (!target_cmsg)
733
        return -TARGET_EFAULT;
734

    
735
    while (cmsg && target_cmsg) {
736
        void *data = CMSG_DATA(cmsg);
737
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
738

    
739
        int len = tswapl(target_cmsg->cmsg_len)
740
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
741

    
742
        space += CMSG_SPACE(len);
743
        if (space > msgh->msg_controllen) {
744
            space -= CMSG_SPACE(len);
745
            gemu_log("Host cmsg overflow\n");
746
            break;
747
        }
748

    
749
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
750
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
751
        cmsg->cmsg_len = CMSG_LEN(len);
752

    
753
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
754
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
755
            memcpy(data, target_data, len);
756
        } else {
757
            int *fd = (int *)data;
758
            int *target_fd = (int *)target_data;
759
            int i, numfds = len / sizeof(int);
760

    
761
            for (i = 0; i < numfds; i++)
762
                fd[i] = tswap32(target_fd[i]);
763
        }
764

    
765
        cmsg = CMSG_NXTHDR(msgh, cmsg);
766
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
767
    }
768
    unlock_user(target_cmsg, target_cmsg_addr, 0);
769
 the_end:
770
    msgh->msg_controllen = space;
771
    return 0;
772
}
773

    
774
/* ??? Should this also swap msgh->name?  */
775
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
776
                                           struct msghdr *msgh)
777
{
778
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
779
    abi_long msg_controllen;
780
    abi_ulong target_cmsg_addr;
781
    struct target_cmsghdr *target_cmsg;
782
    socklen_t space = 0;
783

    
784
    msg_controllen = tswapl(target_msgh->msg_controllen);
785
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
786
        goto the_end;
787
    target_cmsg_addr = tswapl(target_msgh->msg_control);
788
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
789
    if (!target_cmsg)
790
        return -TARGET_EFAULT;
791

    
792
    while (cmsg && target_cmsg) {
793
        void *data = CMSG_DATA(cmsg);
794
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
795

    
796
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
797

    
798
        space += TARGET_CMSG_SPACE(len);
799
        if (space > msg_controllen) {
800
            space -= TARGET_CMSG_SPACE(len);
801
            gemu_log("Target cmsg overflow\n");
802
            break;
803
        }
804

    
805
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
806
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
807
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
808

    
809
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
810
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
811
            memcpy(target_data, data, len);
812
        } else {
813
            int *fd = (int *)data;
814
            int *target_fd = (int *)target_data;
815
            int i, numfds = len / sizeof(int);
816

    
817
            for (i = 0; i < numfds; i++)
818
                target_fd[i] = tswap32(fd[i]);
819
        }
820

    
821
        cmsg = CMSG_NXTHDR(msgh, cmsg);
822
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
823
    }
824
    unlock_user(target_cmsg, target_cmsg_addr, space);
825
 the_end:
826
    target_msgh->msg_controllen = tswapl(space);
827
    return 0;
828
}
829

    
830
/* do_setsockopt() Must return target values and target errnos. */
831
static abi_long do_setsockopt(int sockfd, int level, int optname,
832
                              abi_ulong optval_addr, socklen_t optlen)
833
{
834
    abi_long ret;
835
    int val;
836

    
837
    switch(level) {
838
    case SOL_TCP:
839
        /* TCP options all take an 'int' value.  */
840
        if (optlen < sizeof(uint32_t))
841
            return -TARGET_EINVAL;
842

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

    
944
        if (get_user_u32(val, optval_addr))
945
            return -TARGET_EFAULT;
946
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
947
        break;
948
    default:
949
    unimplemented:
950
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
951
        ret = -TARGET_ENOPROTOOPT;
952
    }
953
    return ret;
954
}
955

    
956
/* do_getsockopt() Must return target values and target errnos. */
957
static abi_long do_getsockopt(int sockfd, int level, int optname,
958
                              abi_ulong optval_addr, abi_ulong optlen)
959
{
960
    abi_long ret;
961
    int len, val;
962
    socklen_t lv;
963

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

    
1056
/* FIXME
1057
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1058
 * other lock functions have a return code of 0 for failure.
1059
 */
1060
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1061
                           int count, int copy)
1062
{
1063
    struct target_iovec *target_vec;
1064
    abi_ulong base;
1065
    int i, j;
1066

    
1067
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1068
    if (!target_vec)
1069
        return -TARGET_EFAULT;
1070
    for(i = 0;i < count; i++) {
1071
        base = tswapl(target_vec[i].iov_base);
1072
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1073
        if (vec[i].iov_len != 0) {
1074
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1075
            if (!vec[i].iov_base && vec[i].iov_len) 
1076
                goto fail;
1077
        } else {
1078
            /* zero length pointer is ignored */
1079
            vec[i].iov_base = NULL;
1080
        }
1081
    }
1082
    unlock_user (target_vec, target_addr, 0);
1083
    return 0;
1084
 fail:
1085
    /* failure - unwind locks */
1086
    for (j = 0; j < i; j++) {
1087
        base = tswapl(target_vec[j].iov_base);
1088
        unlock_user(vec[j].iov_base, base, 0);
1089
    }
1090
    unlock_user (target_vec, target_addr, 0);
1091
    return -TARGET_EFAULT;
1092
}
1093

    
1094
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1095
                             int count, int copy)
1096
{
1097
    struct target_iovec *target_vec;
1098
    abi_ulong base;
1099
    int i;
1100

    
1101
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1102
    if (!target_vec)
1103
        return -TARGET_EFAULT;
1104
    for(i = 0;i < count; i++) {
1105
        base = tswapl(target_vec[i].iov_base);
1106
        unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1107
    }
1108
    unlock_user (target_vec, target_addr, 0);
1109

    
1110
    return 0;
1111
}
1112

    
1113
/* do_socket() Must return target values and target errnos. */
1114
static abi_long do_socket(int domain, int type, int protocol)
1115
{
1116
#if defined(TARGET_MIPS)
1117
    switch(type) {
1118
    case TARGET_SOCK_DGRAM:
1119
        type = SOCK_DGRAM;
1120
        break;
1121
    case TARGET_SOCK_STREAM:
1122
        type = SOCK_STREAM;
1123
        break;
1124
    case TARGET_SOCK_RAW:
1125
        type = SOCK_RAW;
1126
        break;
1127
    case TARGET_SOCK_RDM:
1128
        type = SOCK_RDM;
1129
        break;
1130
    case TARGET_SOCK_SEQPACKET:
1131
        type = SOCK_SEQPACKET;
1132
        break;
1133
    case TARGET_SOCK_PACKET:
1134
        type = SOCK_PACKET;
1135
        break;
1136
    }
1137
#endif
1138
    if (domain == PF_NETLINK)
1139
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1140
    return get_errno(socket(domain, type, protocol));
1141
}
1142

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

    
1149
    target_to_host_sockaddr(addr, target_addr, addrlen);
1150
    return get_errno(bind(sockfd, addr, addrlen));
1151
}
1152

    
1153
/* do_connect() Must return target values and target errnos. */
1154
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1155
                           socklen_t addrlen)
1156
{
1157
    void *addr = alloca(addrlen);
1158

    
1159
    target_to_host_sockaddr(addr, target_addr, addrlen);
1160
    return get_errno(connect(sockfd, addr, addrlen));
1161
}
1162

    
1163
/* do_sendrecvmsg() Must return target values and target errnos. */
1164
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1165
                               int flags, int send)
1166
{
1167
    abi_long ret;
1168
    struct target_msghdr *msgp;
1169
    struct msghdr msg;
1170
    int count;
1171
    struct iovec *vec;
1172
    abi_ulong target_vec;
1173

    
1174
    /* FIXME */
1175
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1176
                          msgp,
1177
                          target_msg,
1178
                          send ? 1 : 0))
1179
        return -TARGET_EFAULT;
1180
    if (msgp->msg_name) {
1181
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1182
        msg.msg_name = alloca(msg.msg_namelen);
1183
        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1184
                                msg.msg_namelen);
1185
    } else {
1186
        msg.msg_name = NULL;
1187
        msg.msg_namelen = 0;
1188
    }
1189
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1190
    msg.msg_control = alloca(msg.msg_controllen);
1191
    msg.msg_flags = tswap32(msgp->msg_flags);
1192

    
1193
    count = tswapl(msgp->msg_iovlen);
1194
    vec = alloca(count * sizeof(struct iovec));
1195
    target_vec = tswapl(msgp->msg_iov);
1196
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1197
    msg.msg_iovlen = count;
1198
    msg.msg_iov = vec;
1199

    
1200
    if (send) {
1201
        ret = target_to_host_cmsg(&msg, msgp);
1202
        if (ret == 0)
1203
            ret = get_errno(sendmsg(fd, &msg, flags));
1204
    } else {
1205
        ret = get_errno(recvmsg(fd, &msg, flags));
1206
        if (!is_error(ret))
1207
            ret = host_to_target_cmsg(msgp, &msg);
1208
    }
1209
    unlock_iovec(vec, target_vec, count, !send);
1210
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1211
    return ret;
1212
}
1213

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

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

    
1225
    addr = alloca(addrlen);
1226

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

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

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

    
1247
    addr = alloca(addrlen);
1248

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

    
1258
/* do_getsockname() Must return target values and target errnos. */
1259
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1260
                               abi_ulong target_addrlen_addr)
1261
{
1262
    socklen_t addrlen;
1263
    void *addr;
1264
    abi_long ret;
1265

    
1266
    if (get_user_u32(addrlen, target_addrlen_addr))
1267
        return -TARGET_EFAULT;
1268

    
1269
    addr = alloca(addrlen);
1270

    
1271
    ret = get_errno(getsockname(fd, addr, &addrlen));
1272
    if (!is_error(ret)) {
1273
        host_to_target_sockaddr(target_addr, addr, addrlen);
1274
        if (put_user_u32(addrlen, target_addrlen_addr))
1275
            ret = -TARGET_EFAULT;
1276
    }
1277
    return ret;
1278
}
1279

    
1280
/* do_socketpair() Must return target values and target errnos. */
1281
static abi_long do_socketpair(int domain, int type, int protocol,
1282
                              abi_ulong target_tab_addr)
1283
{
1284
    int tab[2];
1285
    abi_long ret;
1286

    
1287
    ret = get_errno(socketpair(domain, type, protocol, tab));
1288
    if (!is_error(ret)) {
1289
        if (put_user_s32(tab[0], target_tab_addr)
1290
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1291
            ret = -TARGET_EFAULT;
1292
    }
1293
    return ret;
1294
}
1295

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

    
1304
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1305
    if (!host_msg)
1306
        return -TARGET_EFAULT;
1307
    if (target_addr) {
1308
        addr = alloca(addrlen);
1309
        target_to_host_sockaddr(addr, target_addr, addrlen);
1310
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1311
    } else {
1312
        ret = get_errno(send(fd, host_msg, len, flags));
1313
    }
1314
    unlock_user(host_msg, msg, 0);
1315
    return ret;
1316
}
1317

    
1318
/* do_recvfrom() Must return target values and target errnos. */
1319
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1320
                            abi_ulong target_addr,
1321
                            abi_ulong target_addrlen)
1322
{
1323
    socklen_t addrlen;
1324
    void *addr;
1325
    void *host_msg;
1326
    abi_long ret;
1327

    
1328
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1329
    if (!host_msg)
1330
        return -TARGET_EFAULT;
1331
    if (target_addr) {
1332
        if (get_user_u32(addrlen, target_addrlen)) {
1333
            ret = -TARGET_EFAULT;
1334
            goto fail;
1335
        }
1336
        addr = alloca(addrlen);
1337
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1338
    } else {
1339
        addr = NULL; /* To keep compiler quiet.  */
1340
        ret = get_errno(recv(fd, host_msg, len, flags));
1341
    }
1342
    if (!is_error(ret)) {
1343
        if (target_addr) {
1344
            host_to_target_sockaddr(target_addr, addr, addrlen);
1345
            if (put_user_u32(addrlen, target_addrlen)) {
1346
                ret = -TARGET_EFAULT;
1347
                goto fail;
1348
            }
1349
        }
1350
        unlock_user(host_msg, msg, len);
1351
    } else {
1352
fail:
1353
        unlock_user(host_msg, msg, 0);
1354
    }
1355
    return ret;
1356
}
1357

    
1358
#ifdef TARGET_NR_socketcall
1359
/* do_socketcall() Must return target values and target errnos. */
1360
static abi_long do_socketcall(int num, abi_ulong vptr)
1361
{
1362
    abi_long ret;
1363
    const int n = sizeof(abi_ulong);
1364

    
1365
    switch(num) {
1366
    case SOCKOP_socket:
1367
        {
1368
            int domain, type, protocol;
1369

    
1370
            if (get_user_s32(domain, vptr)
1371
                || get_user_s32(type, vptr + n)
1372
                || get_user_s32(protocol, vptr + 2 * n))
1373
                return -TARGET_EFAULT;
1374

    
1375
            ret = do_socket(domain, type, protocol);
1376
        }
1377
        break;
1378
    case SOCKOP_bind:
1379
        {
1380
            int sockfd;
1381
            abi_ulong target_addr;
1382
            socklen_t addrlen;
1383

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

    
1389
            ret = do_bind(sockfd, target_addr, addrlen);
1390
        }
1391
        break;
1392
    case SOCKOP_connect:
1393
        {
1394
            int sockfd;
1395
            abi_ulong target_addr;
1396
            socklen_t addrlen;
1397

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

    
1403
            ret = do_connect(sockfd, target_addr, addrlen);
1404
        }
1405
        break;
1406
    case SOCKOP_listen:
1407
        {
1408
            int sockfd, backlog;
1409

    
1410
            if (get_user_s32(sockfd, vptr)
1411
                || get_user_s32(backlog, vptr + n))
1412
                return -TARGET_EFAULT;
1413

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

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

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

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

    
1440
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1441
        }
1442
        break;
1443
    case SOCKOP_getpeername:
1444
        {
1445
            int sockfd;
1446
            abi_ulong target_addr, target_addrlen;
1447

    
1448
            if (get_user_s32(sockfd, vptr)
1449
                || get_user_ual(target_addr, vptr + n)
1450
                || get_user_u32(target_addrlen, vptr + 2 * n))
1451
                return -TARGET_EFAULT;
1452

    
1453
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1454
        }
1455
        break;
1456
    case SOCKOP_socketpair:
1457
        {
1458
            int domain, type, protocol;
1459
            abi_ulong tab;
1460

    
1461
            if (get_user_s32(domain, vptr)
1462
                || get_user_s32(type, vptr + n)
1463
                || get_user_s32(protocol, vptr + 2 * n)
1464
                || get_user_ual(tab, vptr + 3 * n))
1465
                return -TARGET_EFAULT;
1466

    
1467
            ret = do_socketpair(domain, type, protocol, tab);
1468
        }
1469
        break;
1470
    case SOCKOP_send:
1471
        {
1472
            int sockfd;
1473
            abi_ulong msg;
1474
            size_t len;
1475
            int flags;
1476

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

    
1483
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1484
        }
1485
        break;
1486
    case SOCKOP_recv:
1487
        {
1488
            int sockfd;
1489
            abi_ulong msg;
1490
            size_t len;
1491
            int flags;
1492

    
1493
            if (get_user_s32(sockfd, vptr)
1494
                || get_user_ual(msg, vptr + n)
1495
                || get_user_ual(len, vptr + 2 * n)
1496
                || get_user_s32(flags, vptr + 3 * n))
1497
                return -TARGET_EFAULT;
1498

    
1499
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1500
        }
1501
        break;
1502
    case SOCKOP_sendto:
1503
        {
1504
            int sockfd;
1505
            abi_ulong msg;
1506
            size_t len;
1507
            int flags;
1508
            abi_ulong addr;
1509
            socklen_t addrlen;
1510

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

    
1519
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1520
        }
1521
        break;
1522
    case SOCKOP_recvfrom:
1523
        {
1524
            int sockfd;
1525
            abi_ulong msg;
1526
            size_t len;
1527
            int flags;
1528
            abi_ulong addr;
1529
            socklen_t addrlen;
1530

    
1531
            if (get_user_s32(sockfd, vptr)
1532
                || get_user_ual(msg, vptr + n)
1533
                || get_user_ual(len, vptr + 2 * n)
1534
                || get_user_s32(flags, vptr + 3 * n)
1535
                || get_user_ual(addr, vptr + 4 * n)
1536
                || get_user_u32(addrlen, vptr + 5 * n))
1537
                return -TARGET_EFAULT;
1538

    
1539
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1540
        }
1541
        break;
1542
    case SOCKOP_shutdown:
1543
        {
1544
            int sockfd, how;
1545

    
1546
            if (get_user_s32(sockfd, vptr)
1547
                || get_user_s32(how, vptr + n))
1548
                return -TARGET_EFAULT;
1549

    
1550
            ret = get_errno(shutdown(sockfd, how));
1551
        }
1552
        break;
1553
    case SOCKOP_sendmsg:
1554
    case SOCKOP_recvmsg:
1555
        {
1556
            int fd;
1557
            abi_ulong target_msg;
1558
            int flags;
1559

    
1560
            if (get_user_s32(fd, vptr)
1561
                || get_user_ual(target_msg, vptr + n)
1562
                || get_user_s32(flags, vptr + 2 * n))
1563
                return -TARGET_EFAULT;
1564

    
1565
            ret = do_sendrecvmsg(fd, target_msg, flags,
1566
                                 (num == SOCKOP_sendmsg));
1567
        }
1568
        break;
1569
    case SOCKOP_setsockopt:
1570
        {
1571
            int sockfd;
1572
            int level;
1573
            int optname;
1574
            abi_ulong optval;
1575
            socklen_t optlen;
1576

    
1577
            if (get_user_s32(sockfd, vptr)
1578
                || get_user_s32(level, vptr + n)
1579
                || get_user_s32(optname, vptr + 2 * n)
1580
                || get_user_ual(optval, vptr + 3 * n)
1581
                || get_user_u32(optlen, vptr + 4 * n))
1582
                return -TARGET_EFAULT;
1583

    
1584
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1585
        }
1586
        break;
1587
    case SOCKOP_getsockopt:
1588
        {
1589
            int sockfd;
1590
            int level;
1591
            int optname;
1592
            abi_ulong optval;
1593
            socklen_t optlen;
1594

    
1595
            if (get_user_s32(sockfd, vptr)
1596
                || get_user_s32(level, vptr + n)
1597
                || get_user_s32(optname, vptr + 2 * n)
1598
                || get_user_ual(optval, vptr + 3 * n)
1599
                || get_user_u32(optlen, vptr + 4 * n))
1600
                return -TARGET_EFAULT;
1601

    
1602
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1603
        }
1604
        break;
1605
    default:
1606
        gemu_log("Unsupported socketcall: %d\n", num);
1607
        ret = -TARGET_ENOSYS;
1608
        break;
1609
    }
1610
    return ret;
1611
}
1612
#endif
1613

    
1614
#define N_SHM_REGIONS        32
1615

    
1616
static struct shm_region {
1617
    abi_ulong        start;
1618
    abi_ulong        size;
1619
} shm_regions[N_SHM_REGIONS];
1620

    
1621
struct target_ipc_perm
1622
{
1623
    abi_long __key;
1624
    abi_ulong uid;
1625
    abi_ulong gid;
1626
    abi_ulong cuid;
1627
    abi_ulong cgid;
1628
    unsigned short int mode;
1629
    unsigned short int __pad1;
1630
    unsigned short int __seq;
1631
    unsigned short int __pad2;
1632
    abi_ulong __unused1;
1633
    abi_ulong __unused2;
1634
};
1635

    
1636
struct target_semid_ds
1637
{
1638
  struct target_ipc_perm sem_perm;
1639
  abi_ulong sem_otime;
1640
  abi_ulong __unused1;
1641
  abi_ulong sem_ctime;
1642
  abi_ulong __unused2;
1643
  abi_ulong sem_nsems;
1644
  abi_ulong __unused3;
1645
  abi_ulong __unused4;
1646
};
1647

    
1648
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1649
                                               abi_ulong target_addr)
1650
{
1651
    struct target_ipc_perm *target_ip;
1652
    struct target_semid_ds *target_sd;
1653

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

    
1667
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1668
                                               struct ipc_perm *host_ip)
1669
{
1670
    struct target_ipc_perm *target_ip;
1671
    struct target_semid_ds *target_sd;
1672

    
1673
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1674
        return -TARGET_EFAULT;
1675
    target_ip = &(target_sd->sem_perm);
1676
    target_ip->__key = tswapl(host_ip->__key);
1677
    target_ip->uid = tswapl(host_ip->uid);
1678
    target_ip->gid = tswapl(host_ip->gid);
1679
    target_ip->cuid = tswapl(host_ip->cuid);
1680
    target_ip->cgid = tswapl(host_ip->cgid);
1681
    target_ip->mode = tswapl(host_ip->mode);
1682
    unlock_user_struct(target_sd, target_addr, 1);
1683
    return 0;
1684
}
1685

    
1686
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1687
                                               abi_ulong target_addr)
1688
{
1689
    struct target_semid_ds *target_sd;
1690

    
1691
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1692
        return -TARGET_EFAULT;
1693
    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1694
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1695
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
1696
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1697
    unlock_user_struct(target_sd, target_addr, 0);
1698
    return 0;
1699
}
1700

    
1701
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1702
                                               struct semid_ds *host_sd)
1703
{
1704
    struct target_semid_ds *target_sd;
1705

    
1706
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1707
        return -TARGET_EFAULT;
1708
    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1709
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1710
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
1711
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1712
    unlock_user_struct(target_sd, target_addr, 1);
1713
    return 0;
1714
}
1715

    
1716
union semun {
1717
        int val;
1718
        struct semid_ds *buf;
1719
        unsigned short *array;
1720
};
1721

    
1722
union target_semun {
1723
        int val;
1724
        abi_long buf;
1725
        unsigned short int *array;
1726
};
1727

    
1728
static inline abi_long target_to_host_semun(int cmd,
1729
                                            union semun *host_su,
1730
                                            abi_ulong target_addr,
1731
                                            struct semid_ds *ds)
1732
{
1733
    union target_semun *target_su;
1734

    
1735
    switch( cmd ) {
1736
        case IPC_STAT:
1737
        case IPC_SET:
1738
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1739
               return -TARGET_EFAULT;
1740
           target_to_host_semid_ds(ds,target_su->buf);
1741
           host_su->buf = ds;
1742
           unlock_user_struct(target_su, target_addr, 0);
1743
           break;
1744
        case GETVAL:
1745
        case SETVAL:
1746
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1747
               return -TARGET_EFAULT;
1748
           host_su->val = tswapl(target_su->val);
1749
           unlock_user_struct(target_su, target_addr, 0);
1750
           break;
1751
        case GETALL:
1752
        case SETALL:
1753
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1754
               return -TARGET_EFAULT;
1755
           *host_su->array = tswap16(*target_su->array);
1756
           unlock_user_struct(target_su, target_addr, 0);
1757
           break;
1758
        default:
1759
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1760
    }
1761
    return 0;
1762
}
1763

    
1764
static inline abi_long host_to_target_semun(int cmd,
1765
                                            abi_ulong target_addr,
1766
                                            union semun *host_su,
1767
                                            struct semid_ds *ds)
1768
{
1769
    union target_semun *target_su;
1770

    
1771
    switch( cmd ) {
1772
        case IPC_STAT:
1773
        case IPC_SET:
1774
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1775
               return -TARGET_EFAULT;
1776
           host_to_target_semid_ds(target_su->buf,ds);
1777
           unlock_user_struct(target_su, target_addr, 1);
1778
           break;
1779
        case GETVAL:
1780
        case SETVAL:
1781
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1782
               return -TARGET_EFAULT;
1783
           target_su->val = tswapl(host_su->val);
1784
           unlock_user_struct(target_su, target_addr, 1);
1785
           break;
1786
        case GETALL:
1787
        case SETALL:
1788
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1789
               return -TARGET_EFAULT;
1790
           *target_su->array = tswap16(*host_su->array);
1791
           unlock_user_struct(target_su, target_addr, 1);
1792
           break;
1793
        default:
1794
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1795
    }
1796
    return 0;
1797
}
1798

    
1799
static inline abi_long do_semctl(int first, int second, int third,
1800
                                 abi_long ptr)
1801
{
1802
    union semun arg;
1803
    struct semid_ds dsarg;
1804
    int cmd = third&0xff;
1805
    abi_long ret = 0;
1806

    
1807
    switch( cmd ) {
1808
        case GETVAL:
1809
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1810
            ret = get_errno(semctl(first, second, cmd, arg));
1811
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1812
            break;
1813
        case SETVAL:
1814
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1815
            ret = get_errno(semctl(first, second, cmd, arg));
1816
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1817
            break;
1818
        case GETALL:
1819
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1820
            ret = get_errno(semctl(first, second, cmd, arg));
1821
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1822
            break;
1823
        case SETALL:
1824
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1825
            ret = get_errno(semctl(first, second, cmd, arg));
1826
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1827
            break;
1828
        case IPC_STAT:
1829
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1830
            ret = get_errno(semctl(first, second, cmd, arg));
1831
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1832
            break;
1833
        case IPC_SET:
1834
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1835
            ret = get_errno(semctl(first, second, cmd, arg));
1836
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1837
            break;
1838
    default:
1839
            ret = get_errno(semctl(first, second, cmd, arg));
1840
    }
1841

    
1842
    return ret;
1843
}
1844

    
1845
struct target_msqid_ds
1846
{
1847
    struct target_ipc_perm msg_perm;
1848
    abi_ulong msg_stime;
1849
#if TARGET_ABI_BITS == 32
1850
    abi_ulong __unused1;
1851
#endif
1852
    abi_ulong msg_rtime;
1853
#if TARGET_ABI_BITS == 32
1854
    abi_ulong __unused2;
1855
#endif
1856
    abi_ulong msg_ctime;
1857
#if TARGET_ABI_BITS == 32
1858
    abi_ulong __unused3;
1859
#endif
1860
    abi_ulong __msg_cbytes;
1861
    abi_ulong msg_qnum;
1862
    abi_ulong msg_qbytes;
1863
    abi_ulong msg_lspid;
1864
    abi_ulong msg_lrpid;
1865
    abi_ulong __unused4;
1866
    abi_ulong __unused5;
1867
};
1868

    
1869
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1870
                                               abi_ulong target_addr)
1871
{
1872
    struct target_msqid_ds *target_md;
1873

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

    
1890
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1891
                                               struct msqid_ds *host_md)
1892
{
1893
    struct target_msqid_ds *target_md;
1894

    
1895
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1896
        return -TARGET_EFAULT;
1897
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
1898
        return -TARGET_EFAULT;
1899
    target_md->msg_stime = tswapl(host_md->msg_stime);
1900
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
1901
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
1902
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1903
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
1904
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1905
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
1906
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1907
    unlock_user_struct(target_md, target_addr, 1);
1908
    return 0;
1909
}
1910

    
1911
struct target_msginfo {
1912
    int msgpool;
1913
    int msgmap;
1914
    int msgmax;
1915
    int msgmnb;
1916
    int msgmni;
1917
    int msgssz;
1918
    int msgtql;
1919
    unsigned short int msgseg;
1920
};
1921

    
1922
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
1923
                                              struct msginfo *host_msginfo)
1924
{
1925
    struct target_msginfo *target_msginfo;
1926
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
1927
        return -TARGET_EFAULT;
1928
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
1929
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
1930
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
1931
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
1932
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
1933
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
1934
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
1935
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
1936
    unlock_user_struct(target_msginfo, target_addr, 1);
1937
    return 0;
1938
}
1939

    
1940
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1941
{
1942
    struct msqid_ds dsarg;
1943
    struct msginfo msginfo;
1944
    abi_long ret = -TARGET_EINVAL;
1945

    
1946
    cmd &= 0xff;
1947

    
1948
    switch (cmd) {
1949
    case IPC_STAT:
1950
    case IPC_SET:
1951
    case MSG_STAT:
1952
        if (target_to_host_msqid_ds(&dsarg,ptr))
1953
            return -TARGET_EFAULT;
1954
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
1955
        if (host_to_target_msqid_ds(ptr,&dsarg))
1956
            return -TARGET_EFAULT;
1957
        break;
1958
    case IPC_RMID:
1959
        ret = get_errno(msgctl(msgid, cmd, NULL));
1960
        break;
1961
    case IPC_INFO:
1962
    case MSG_INFO:
1963
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
1964
        if (host_to_target_msginfo(ptr, &msginfo))
1965
            return -TARGET_EFAULT;
1966
        break;
1967
    }
1968

    
1969
    return ret;
1970
}
1971

    
1972
struct target_msgbuf {
1973
    abi_long mtype;
1974
    char        mtext[1];
1975
};
1976

    
1977
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1978
                                 unsigned int msgsz, int msgflg)
1979
{
1980
    struct target_msgbuf *target_mb;
1981
    struct msgbuf *host_mb;
1982
    abi_long ret = 0;
1983

    
1984
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1985
        return -TARGET_EFAULT;
1986
    host_mb = malloc(msgsz+sizeof(long));
1987
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
1988
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
1989
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1990
    free(host_mb);
1991
    unlock_user_struct(target_mb, msgp, 0);
1992

    
1993
    return ret;
1994
}
1995

    
1996
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1997
                                 unsigned int msgsz, abi_long msgtyp,
1998
                                 int msgflg)
1999
{
2000
    struct target_msgbuf *target_mb;
2001
    char *target_mtext;
2002
    struct msgbuf *host_mb;
2003
    abi_long ret = 0;
2004

    
2005
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2006
        return -TARGET_EFAULT;
2007

    
2008
    host_mb = malloc(msgsz+sizeof(long));
2009
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2010

    
2011
    if (ret > 0) {
2012
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2013
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2014
        if (!target_mtext) {
2015
            ret = -TARGET_EFAULT;
2016
            goto end;
2017
        }
2018
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2019
        unlock_user(target_mtext, target_mtext_addr, ret);
2020
    }
2021

    
2022
    target_mb->mtype = tswapl(host_mb->mtype);
2023
    free(host_mb);
2024

    
2025
end:
2026
    if (target_mb)
2027
        unlock_user_struct(target_mb, msgp, 1);
2028
    return ret;
2029
}
2030

    
2031
#ifdef TARGET_NR_ipc
2032
/* ??? This only works with linear mappings.  */
2033
/* do_ipc() must return target values and target errnos. */
2034
static abi_long do_ipc(unsigned int call, int first,
2035
                       int second, int third,
2036
                       abi_long ptr, abi_long fifth)
2037
{
2038
    int version;
2039
    abi_long ret = 0;
2040
    struct shmid_ds shm_info;
2041
    int i;
2042

    
2043
    version = call >> 16;
2044
    call &= 0xffff;
2045

    
2046
    switch (call) {
2047
    case IPCOP_semop:
2048
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
2049
        break;
2050

    
2051
    case IPCOP_semget:
2052
        ret = get_errno(semget(first, second, third));
2053
        break;
2054

    
2055
    case IPCOP_semctl:
2056
        ret = do_semctl(first, second, third, ptr);
2057
        break;
2058

    
2059
    case IPCOP_semtimedop:
2060
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2061
        ret = -TARGET_ENOSYS;
2062
        break;
2063

    
2064
    case IPCOP_msgget:
2065
        ret = get_errno(msgget(first, second));
2066
        break;
2067

    
2068
    case IPCOP_msgsnd:
2069
        ret = do_msgsnd(first, ptr, second, third);
2070
        break;
2071

    
2072
    case IPCOP_msgctl:
2073
        ret = do_msgctl(first, second, ptr);
2074
        break;
2075

    
2076
    case IPCOP_msgrcv:
2077
        switch (version) {
2078
        case 0:
2079
            {
2080
                struct target_ipc_kludge {
2081
                    abi_long msgp;
2082
                    abi_long msgtyp;
2083
                } *tmp;
2084

    
2085
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2086
                    ret = -TARGET_EFAULT;
2087
                    break;
2088
                }
2089

    
2090
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2091

    
2092
                unlock_user_struct(tmp, ptr, 0);
2093
                break;
2094
            }
2095
        default:
2096
            ret = do_msgrcv(first, ptr, second, fifth, third);
2097
        }
2098
        break;
2099

    
2100
    case IPCOP_shmat:
2101
        {
2102
            abi_ulong raddr;
2103
            void *host_addr;
2104
            /* SHM_* flags are the same on all linux platforms */
2105
            host_addr = shmat(first, (void *)g2h(ptr), second);
2106
            if (host_addr == (void *)-1) {
2107
                ret = get_errno((long)host_addr);
2108
                break;
2109
            }
2110
            raddr = h2g((unsigned long)host_addr);
2111
            /* find out the length of the shared memory segment */
2112
            
2113
            ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2114
            if (is_error(ret)) {
2115
                /* can't get length, bail out */
2116
                shmdt(host_addr);
2117
                break;
2118
            }
2119
            page_set_flags(raddr, raddr + shm_info.shm_segsz,
2120
                           PAGE_VALID | PAGE_READ |
2121
                           ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2122
            for (i = 0; i < N_SHM_REGIONS; ++i) {
2123
                if (shm_regions[i].start == 0) {
2124
                    shm_regions[i].start = raddr;
2125
                    shm_regions[i].size = shm_info.shm_segsz;
2126
                    break;
2127
                }
2128
            }
2129
            if (put_user_ual(raddr, third))
2130
                return -TARGET_EFAULT;
2131
            ret = 0;
2132
        }
2133
        break;
2134
    case IPCOP_shmdt:
2135
        for (i = 0; i < N_SHM_REGIONS; ++i) {
2136
            if (shm_regions[i].start == ptr) {
2137
                shm_regions[i].start = 0;
2138
                page_set_flags(ptr, shm_regions[i].size, 0);
2139
                break;
2140
            }
2141
        }
2142
        ret = get_errno(shmdt((void *)g2h(ptr)));
2143
        break;
2144

    
2145
    case IPCOP_shmget:
2146
        /* IPC_* flag values are the same on all linux platforms */
2147
        ret = get_errno(shmget(first, second, third));
2148
        break;
2149

    
2150
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2151
    case IPCOP_shmctl:
2152
        switch(second) {
2153
        case IPC_RMID:
2154
        case SHM_LOCK:
2155
        case SHM_UNLOCK:
2156
            ret = get_errno(shmctl(first, second, NULL));
2157
            break;
2158
        default:
2159
            goto unimplemented;
2160
        }
2161
        break;
2162
    default:
2163
    unimplemented:
2164
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2165
        ret = -TARGET_ENOSYS;
2166
        break;
2167
    }
2168
    return ret;
2169
}
2170
#endif
2171

    
2172
/* kernel structure types definitions */
2173
#define IFNAMSIZ        16
2174

    
2175
#define STRUCT(name, list...) STRUCT_ ## name,
2176
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2177
enum {
2178
#include "syscall_types.h"
2179
};
2180
#undef STRUCT
2181
#undef STRUCT_SPECIAL
2182

    
2183
#define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2184
#define STRUCT_SPECIAL(name)
2185
#include "syscall_types.h"
2186
#undef STRUCT
2187
#undef STRUCT_SPECIAL
2188

    
2189
typedef struct IOCTLEntry {
2190
    unsigned int target_cmd;
2191
    unsigned int host_cmd;
2192
    const char *name;
2193
    int access;
2194
    const argtype arg_type[5];
2195
} IOCTLEntry;
2196

    
2197
#define IOC_R 0x0001
2198
#define IOC_W 0x0002
2199
#define IOC_RW (IOC_R | IOC_W)
2200

    
2201
#define MAX_STRUCT_SIZE 4096
2202

    
2203
static IOCTLEntry ioctl_entries[] = {
2204
#define IOCTL(cmd, access, types...) \
2205
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2206
#include "ioctls.h"
2207
    { 0, 0, },
2208
};
2209

    
2210
/* ??? Implement proper locking for ioctls.  */
2211
/* do_ioctl() Must return target values and target errnos. */
2212
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2213
{
2214
    const IOCTLEntry *ie;
2215
    const argtype *arg_type;
2216
    abi_long ret;
2217
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2218
    int target_size;
2219
    void *argptr;
2220

    
2221
    ie = ioctl_entries;
2222
    for(;;) {
2223
        if (ie->target_cmd == 0) {
2224
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2225
            return -TARGET_ENOSYS;
2226
        }
2227
        if (ie->target_cmd == cmd)
2228
            break;
2229
        ie++;
2230
    }
2231
    arg_type = ie->arg_type;
2232
#if defined(DEBUG)
2233
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2234
#endif
2235
    switch(arg_type[0]) {
2236
    case TYPE_NULL:
2237
        /* no argument */
2238
        ret = get_errno(ioctl(fd, ie->host_cmd));
2239
        break;
2240
    case TYPE_PTRVOID:
2241
    case TYPE_INT:
2242
        /* int argment */
2243
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2244
        break;
2245
    case TYPE_PTR:
2246
        arg_type++;
2247
        target_size = thunk_type_size(arg_type, 0);
2248
        switch(ie->access) {
2249
        case IOC_R:
2250
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2251
            if (!is_error(ret)) {
2252
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2253
                if (!argptr)
2254
                    return -TARGET_EFAULT;
2255
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2256
                unlock_user(argptr, arg, target_size);
2257
            }
2258
            break;
2259
        case IOC_W:
2260
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2261
            if (!argptr)
2262
                return -TARGET_EFAULT;
2263
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2264
            unlock_user(argptr, arg, 0);
2265
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2266
            break;
2267
        default:
2268
        case IOC_RW:
2269
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2270
            if (!argptr)
2271
                return -TARGET_EFAULT;
2272
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2273
            unlock_user(argptr, arg, 0);
2274
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2275
            if (!is_error(ret)) {
2276
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2277
                if (!argptr)
2278
                    return -TARGET_EFAULT;
2279
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2280
                unlock_user(argptr, arg, target_size);
2281
            }
2282
            break;
2283
        }
2284
        break;
2285
    default:
2286
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2287
                 (long)cmd, arg_type[0]);
2288
        ret = -TARGET_ENOSYS;
2289
        break;
2290
    }
2291
    return ret;
2292
}
2293

    
2294
static const bitmask_transtbl iflag_tbl[] = {
2295
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2296
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2297
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2298
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2299
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2300
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2301
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2302
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2303
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2304
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2305
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2306
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2307
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2308
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2309
        { 0, 0, 0, 0 }
2310
};
2311

    
2312
static const bitmask_transtbl oflag_tbl[] = {
2313
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2314
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2315
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2316
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2317
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2318
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2319
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2320
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2321
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2322
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2323
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2324
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2325
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2326
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2327
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2328
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2329
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2330
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2331
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2332
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2333
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2334
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2335
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2336
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2337
        { 0, 0, 0, 0 }
2338
};
2339

    
2340
static const bitmask_transtbl cflag_tbl[] = {
2341
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2342
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2343
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2344
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2345
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2346
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2347
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2348
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2349
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2350
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2351
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2352
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2353
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2354
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2355
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2356
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2357
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2358
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2359
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2360
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2361
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2362
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2363
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2364
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2365
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2366
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2367
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2368
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2369
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2370
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2371
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2372
        { 0, 0, 0, 0 }
2373
};
2374

    
2375
static const bitmask_transtbl lflag_tbl[] = {
2376
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2377
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2378
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2379
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2380
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2381
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2382
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2383
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2384
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2385
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2386
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2387
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2388
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2389
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2390
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2391
        { 0, 0, 0, 0 }
2392
};
2393

    
2394
static void target_to_host_termios (void *dst, const void *src)
2395
{
2396
    struct host_termios *host = dst;
2397
    const struct target_termios *target = src;
2398

    
2399
    host->c_iflag =
2400
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2401
    host->c_oflag =
2402
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2403
    host->c_cflag =
2404
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2405
    host->c_lflag =
2406
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2407
    host->c_line = target->c_line;
2408

    
2409
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2410
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2411
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2412
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2413
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2414
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2415
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2416
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2417
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2418
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2419
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2420
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2421
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2422
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2423
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2424
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2425
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2426
}
2427

    
2428
static void host_to_target_termios (void *dst, const void *src)
2429
{
2430
    struct target_termios *target = dst;
2431
    const struct host_termios *host = src;
2432

    
2433
    target->c_iflag =
2434
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2435
    target->c_oflag =
2436
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2437
    target->c_cflag =
2438
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2439
    target->c_lflag =
2440
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2441
    target->c_line = host->c_line;
2442

    
2443
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2444
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2445
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2446
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2447
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2448
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2449
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2450
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2451
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2452
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2453
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2454
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2455
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2456
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2457
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2458
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2459
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2460
}
2461

    
2462
static const StructEntry struct_termios_def = {
2463
    .convert = { host_to_target_termios, target_to_host_termios },
2464
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2465
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2466
};
2467

    
2468
static bitmask_transtbl mmap_flags_tbl[] = {
2469
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2470
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2471
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2472
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2473
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2474
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2475
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2476
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2477
        { 0, 0, 0, 0 }
2478
};
2479

    
2480
static bitmask_transtbl fcntl_flags_tbl[] = {
2481
        { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
2482
        { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
2483
        { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
2484
        { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
2485
        { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
2486
        { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
2487
        { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
2488
        { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
2489
        { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
2490
        { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
2491
        { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2492
        { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
2493
        { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2494
#if defined(O_DIRECT)
2495
        { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
2496
#endif
2497
        { 0, 0, 0, 0 }
2498
};
2499

    
2500
#if defined(TARGET_I386)
2501

    
2502
/* NOTE: there is really one LDT for all the threads */
2503
static uint8_t *ldt_table;
2504

    
2505
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2506
{
2507
    int size;
2508
    void *p;
2509

    
2510
    if (!ldt_table)
2511
        return 0;
2512
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2513
    if (size > bytecount)
2514
        size = bytecount;
2515
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
2516
    if (!p)
2517
        return -TARGET_EFAULT;
2518
    /* ??? Should this by byteswapped?  */
2519
    memcpy(p, ldt_table, size);
2520
    unlock_user(p, ptr, size);
2521
    return size;
2522
}
2523

    
2524
/* XXX: add locking support */
2525
static abi_long write_ldt(CPUX86State *env,
2526
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
2527
{
2528
    struct target_modify_ldt_ldt_s ldt_info;
2529
    struct target_modify_ldt_ldt_s *target_ldt_info;
2530
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2531
    int seg_not_present, useable, lm;
2532
    uint32_t *lp, entry_1, entry_2;
2533

    
2534
    if (bytecount != sizeof(ldt_info))
2535
        return -TARGET_EINVAL;
2536
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2537
        return -TARGET_EFAULT;
2538
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2539
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2540
    ldt_info.limit = tswap32(target_ldt_info->limit);
2541
    ldt_info.flags = tswap32(target_ldt_info->flags);
2542
    unlock_user_struct(target_ldt_info, ptr, 0);
2543

    
2544
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2545
        return -TARGET_EINVAL;
2546
    seg_32bit = ldt_info.flags & 1;
2547
    contents = (ldt_info.flags >> 1) & 3;
2548
    read_exec_only = (ldt_info.flags >> 3) & 1;
2549
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2550
    seg_not_present = (ldt_info.flags >> 5) & 1;
2551
    useable = (ldt_info.flags >> 6) & 1;
2552
#ifdef TARGET_ABI32
2553
    lm = 0;
2554
#else
2555
    lm = (ldt_info.flags >> 7) & 1;
2556
#endif
2557
    if (contents == 3) {
2558
        if (oldmode)
2559
            return -TARGET_EINVAL;
2560
        if (seg_not_present == 0)
2561
            return -TARGET_EINVAL;
2562
    }
2563
    /* allocate the LDT */
2564
    if (!ldt_table) {
2565
        ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2566
        if (!ldt_table)
2567
            return -TARGET_ENOMEM;
2568
        memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2569
        env->ldt.base = h2g((unsigned long)ldt_table);
2570
        env->ldt.limit = 0xffff;
2571
    }
2572

    
2573
    /* NOTE: same code as Linux kernel */
2574
    /* Allow LDTs to be cleared by the user. */
2575
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2576
        if (oldmode ||
2577
            (contents == 0                &&
2578
             read_exec_only == 1        &&
2579
             seg_32bit == 0                &&
2580
             limit_in_pages == 0        &&
2581
             seg_not_present == 1        &&
2582
             useable == 0 )) {
2583
            entry_1 = 0;
2584
            entry_2 = 0;
2585
            goto install;
2586
        }
2587
    }
2588

    
2589
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2590
        (ldt_info.limit & 0x0ffff);
2591
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2592
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2593
        (ldt_info.limit & 0xf0000) |
2594
        ((read_exec_only ^ 1) << 9) |
2595
        (contents << 10) |
2596
        ((seg_not_present ^ 1) << 15) |
2597
        (seg_32bit << 22) |
2598
        (limit_in_pages << 23) |
2599
        (lm << 21) |
2600
        0x7000;
2601
    if (!oldmode)
2602
        entry_2 |= (useable << 20);
2603

    
2604
    /* Install the new entry ...  */
2605
install:
2606
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2607
    lp[0] = tswap32(entry_1);
2608
    lp[1] = tswap32(entry_2);
2609
    return 0;
2610
}
2611

    
2612
/* specific and weird i386 syscalls */
2613
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2614
                              unsigned long bytecount)
2615
{
2616
    abi_long ret;
2617

    
2618
    switch (func) {
2619
    case 0:
2620
        ret = read_ldt(ptr, bytecount);
2621
        break;
2622
    case 1:
2623
        ret = write_ldt(env, ptr, bytecount, 1);
2624
        break;
2625
    case 0x11:
2626
        ret = write_ldt(env, ptr, bytecount, 0);
2627
        break;
2628
    default:
2629
        ret = -TARGET_ENOSYS;
2630
        break;
2631
    }
2632
    return ret;
2633
}
2634

    
2635
#if defined(TARGET_I386) && defined(TARGET_ABI32)
2636
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2637
{
2638
    uint64_t *gdt_table = g2h(env->gdt.base);
2639
    struct target_modify_ldt_ldt_s ldt_info;
2640
    struct target_modify_ldt_ldt_s *target_ldt_info;
2641
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2642
    int seg_not_present, useable, lm;
2643
    uint32_t *lp, entry_1, entry_2;
2644
    int i;
2645

    
2646
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2647
    if (!target_ldt_info)
2648
        return -TARGET_EFAULT;
2649
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2650
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2651
    ldt_info.limit = tswap32(target_ldt_info->limit);
2652
    ldt_info.flags = tswap32(target_ldt_info->flags);
2653
    if (ldt_info.entry_number == -1) {
2654
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2655
            if (gdt_table[i] == 0) {
2656
                ldt_info.entry_number = i;
2657
                target_ldt_info->entry_number = tswap32(i);
2658
                break;
2659
            }
2660
        }
2661
    }
2662
    unlock_user_struct(target_ldt_info, ptr, 1);
2663

    
2664
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
2665
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2666
           return -TARGET_EINVAL;
2667
    seg_32bit = ldt_info.flags & 1;
2668
    contents = (ldt_info.flags >> 1) & 3;
2669
    read_exec_only = (ldt_info.flags >> 3) & 1;
2670
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2671
    seg_not_present = (ldt_info.flags >> 5) & 1;
2672
    useable = (ldt_info.flags >> 6) & 1;
2673
#ifdef TARGET_ABI32
2674
    lm = 0;
2675
#else
2676
    lm = (ldt_info.flags >> 7) & 1;
2677
#endif
2678

    
2679
    if (contents == 3) {
2680
        if (seg_not_present == 0)
2681
            return -TARGET_EINVAL;
2682
    }
2683

    
2684
    /* NOTE: same code as Linux kernel */
2685
    /* Allow LDTs to be cleared by the user. */
2686
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2687
        if ((contents == 0             &&
2688
             read_exec_only == 1       &&
2689
             seg_32bit == 0            &&
2690
             limit_in_pages == 0       &&
2691
             seg_not_present == 1      &&
2692
             useable == 0 )) {
2693
            entry_1 = 0;
2694
            entry_2 = 0;
2695
            goto install;
2696
        }
2697
    }
2698

    
2699
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2700
        (ldt_info.limit & 0x0ffff);
2701
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2702
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2703
        (ldt_info.limit & 0xf0000) |
2704
        ((read_exec_only ^ 1) << 9) |
2705
        (contents << 10) |
2706
        ((seg_not_present ^ 1) << 15) |
2707
        (seg_32bit << 22) |
2708
        (limit_in_pages << 23) |
2709
        (useable << 20) |
2710
        (lm << 21) |
2711
        0x7000;
2712

    
2713
    /* Install the new entry ...  */
2714
install:
2715
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2716
    lp[0] = tswap32(entry_1);
2717
    lp[1] = tswap32(entry_2);
2718
    return 0;
2719
}
2720

    
2721
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2722
{
2723
    struct target_modify_ldt_ldt_s *target_ldt_info;
2724
    uint64_t *gdt_table = g2h(env->gdt.base);
2725
    uint32_t base_addr, limit, flags;
2726
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2727
    int seg_not_present, useable, lm;
2728
    uint32_t *lp, entry_1, entry_2;
2729

    
2730
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2731
    if (!target_ldt_info)
2732
        return -TARGET_EFAULT;
2733
    idx = tswap32(target_ldt_info->entry_number);
2734
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2735
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
2736
        unlock_user_struct(target_ldt_info, ptr, 1);
2737
        return -TARGET_EINVAL;
2738
    }
2739
    lp = (uint32_t *)(gdt_table + idx);
2740
    entry_1 = tswap32(lp[0]);
2741
    entry_2 = tswap32(lp[1]);
2742
    
2743
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2744
    contents = (entry_2 >> 10) & 3;
2745
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2746
    seg_32bit = (entry_2 >> 22) & 1;
2747
    limit_in_pages = (entry_2 >> 23) & 1;
2748
    useable = (entry_2 >> 20) & 1;
2749
#ifdef TARGET_ABI32
2750
    lm = 0;
2751
#else
2752
    lm = (entry_2 >> 21) & 1;
2753
#endif
2754
    flags = (seg_32bit << 0) | (contents << 1) |
2755
        (read_exec_only << 3) | (limit_in_pages << 4) |
2756
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
2757
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
2758
    base_addr = (entry_1 >> 16) | 
2759
        (entry_2 & 0xff000000) | 
2760
        ((entry_2 & 0xff) << 16);
2761
    target_ldt_info->base_addr = tswapl(base_addr);
2762
    target_ldt_info->limit = tswap32(limit);
2763
    target_ldt_info->flags = tswap32(flags);
2764
    unlock_user_struct(target_ldt_info, ptr, 1);
2765
    return 0;
2766
}
2767
#endif /* TARGET_I386 && TARGET_ABI32 */
2768

    
2769
#ifndef TARGET_ABI32
2770
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2771
{
2772
    abi_long ret;
2773
    abi_ulong val;
2774
    int idx;
2775
    
2776
    switch(code) {
2777
    case TARGET_ARCH_SET_GS:
2778
    case TARGET_ARCH_SET_FS:
2779
        if (code == TARGET_ARCH_SET_GS)
2780
            idx = R_GS;
2781
        else
2782
            idx = R_FS;
2783
        cpu_x86_load_seg(env, idx, 0);
2784
        env->segs[idx].base = addr;
2785
        break;
2786
    case TARGET_ARCH_GET_GS:
2787
    case TARGET_ARCH_GET_FS:
2788
        if (code == TARGET_ARCH_GET_GS)
2789
            idx = R_GS;
2790
        else
2791
            idx = R_FS;
2792
        val = env->segs[idx].base;
2793
        if (put_user(val, addr, abi_ulong))
2794
            return -TARGET_EFAULT;
2795
        break;
2796
    default:
2797
        ret = -TARGET_EINVAL;
2798
        break;
2799
    }
2800
    return 0;
2801
}
2802
#endif
2803

    
2804
#endif /* defined(TARGET_I386) */
2805

    
2806
#if defined(USE_NPTL)
2807

    
2808
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2809

    
2810
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2811
typedef struct {
2812
    CPUState *env;
2813
    pthread_mutex_t mutex;
2814
    pthread_cond_t cond;
2815
    pthread_t thread;
2816
    uint32_t tid;
2817
    abi_ulong child_tidptr;
2818
    abi_ulong parent_tidptr;
2819
    sigset_t sigmask;
2820
} new_thread_info;
2821

    
2822
static void *clone_func(void *arg)
2823
{
2824
    new_thread_info *info = arg;
2825
    CPUState *env;
2826

    
2827
    env = info->env;
2828
    thread_env = env;
2829
    info->tid = gettid();
2830
    if (info->child_tidptr)
2831
        put_user_u32(info->tid, info->child_tidptr);
2832
    if (info->parent_tidptr)
2833
        put_user_u32(info->tid, info->parent_tidptr);
2834
    /* Enable signals.  */
2835
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2836
    /* Signal to the parent that we're ready.  */
2837
    pthread_mutex_lock(&info->mutex);
2838
    pthread_cond_broadcast(&info->cond);
2839
    pthread_mutex_unlock(&info->mutex);
2840
    /* Wait until the parent has finshed initializing the tls state.  */
2841
    pthread_mutex_lock(&clone_lock);
2842
    pthread_mutex_unlock(&clone_lock);
2843
    cpu_loop(env);
2844
    /* never exits */
2845
    return NULL;
2846
}
2847
#else
2848
/* this stack is the equivalent of the kernel stack associated with a
2849
   thread/process */
2850
#define NEW_STACK_SIZE 8192
2851

    
2852
static int clone_func(void *arg)
2853
{
2854
    CPUState *env = arg;
2855
    cpu_loop(env);
2856
    /* never exits */
2857
    return 0;
2858
}
2859
#endif
2860

    
2861
/* do_fork() Must return host values and target errnos (unlike most
2862
   do_*() functions). */
2863
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2864
                   abi_ulong parent_tidptr, target_ulong newtls,
2865
                   abi_ulong child_tidptr)
2866
{
2867
    int ret;
2868
    TaskState *ts;
2869
    uint8_t *new_stack;
2870
    CPUState *new_env;
2871
#if defined(USE_NPTL)
2872
    unsigned int nptl_flags;
2873
    sigset_t sigmask;
2874
#endif
2875

    
2876
    /* Emulate vfork() with fork() */
2877
    if (flags & CLONE_VFORK)
2878
        flags &= ~(CLONE_VFORK | CLONE_VM);
2879

    
2880
    if (flags & CLONE_VM) {
2881
#if defined(USE_NPTL)
2882
        new_thread_info info;
2883
        pthread_attr_t attr;
2884
#endif
2885
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2886
        init_task_state(ts);
2887
        new_stack = ts->stack;
2888
        /* we create a new CPU instance. */
2889
        new_env = cpu_copy(env);
2890
        /* Init regs that differ from the parent.  */
2891
        cpu_clone_regs(new_env, newsp);
2892
        new_env->opaque = ts;
2893
#if defined(USE_NPTL)
2894
        nptl_flags = flags;
2895
        flags &= ~CLONE_NPTL_FLAGS2;
2896

    
2897
        /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2898
        if (nptl_flags & CLONE_SETTLS)
2899
            cpu_set_tls (new_env, newtls);
2900

    
2901
        /* Grab a mutex so that thread setup appears atomic.  */
2902
        pthread_mutex_lock(&clone_lock);
2903

    
2904
        memset(&info, 0, sizeof(info));
2905
        pthread_mutex_init(&info.mutex, NULL);
2906
        pthread_mutex_lock(&info.mutex);
2907
        pthread_cond_init(&info.cond, NULL);
2908
        info.env = new_env;
2909
        if (nptl_flags & CLONE_CHILD_SETTID)
2910
            info.child_tidptr = child_tidptr;
2911
        if (nptl_flags & CLONE_PARENT_SETTID)
2912
            info.parent_tidptr = parent_tidptr;
2913

    
2914
        ret = pthread_attr_init(&attr);
2915
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2916
        /* It is not safe to deliver signals until the child has finished
2917
           initializing, so temporarily block all signals.  */
2918
        sigfillset(&sigmask);
2919
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2920

    
2921
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
2922

    
2923
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
2924
        pthread_attr_destroy(&attr);
2925
        if (ret == 0) {
2926
            /* Wait for the child to initialize.  */
2927
            pthread_cond_wait(&info.cond, &info.mutex);
2928
            ret = info.tid;
2929
            if (flags & CLONE_PARENT_SETTID)
2930
                put_user_u32(ret, parent_tidptr);
2931
        } else {
2932
            ret = -1;
2933
        }
2934
        pthread_mutex_unlock(&info.mutex);
2935
        pthread_cond_destroy(&info.cond);
2936
        pthread_mutex_destroy(&info.mutex);
2937
        pthread_mutex_unlock(&clone_lock);
2938
#else
2939
        if (flags & CLONE_NPTL_FLAGS2)
2940
            return -EINVAL;
2941
        /* This is probably going to die very quickly, but do it anyway.  */
2942
#ifdef __ia64__
2943
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2944
#else
2945
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2946
#endif
2947
#endif
2948
    } else {
2949
        /* if no CLONE_VM, we consider it is a fork */
2950
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
2951
            return -EINVAL;
2952
        fork_start();
2953
        ret = fork();
2954
#if defined(USE_NPTL)
2955
        /* There is a race condition here.  The parent process could
2956
           theoretically read the TID in the child process before the child
2957
           tid is set.  This would require using either ptrace
2958
           (not implemented) or having *_tidptr to point at a shared memory
2959
           mapping.  We can't repeat the spinlock hack used above because
2960
           the child process gets its own copy of the lock.  */
2961
        if (ret == 0) {
2962
            cpu_clone_regs(env, newsp);
2963
            fork_end(1);
2964
            /* Child Process.  */
2965
            if (flags & CLONE_CHILD_SETTID)
2966
                put_user_u32(gettid(), child_tidptr);
2967
            if (flags & CLONE_PARENT_SETTID)
2968
                put_user_u32(gettid(), parent_tidptr);
2969
            ts = (TaskState *)env->opaque;
2970
            if (flags & CLONE_SETTLS)
2971
                cpu_set_tls (env, newtls);
2972
            /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2973
        } else {
2974
            fork_end(0);
2975
        }
2976
#else
2977
        if (ret == 0) {
2978
            cpu_clone_regs(env, newsp);
2979
        }
2980
#endif
2981
    }
2982
    return ret;
2983
}
2984

    
2985
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2986
{
2987
    struct flock fl;
2988
    struct target_flock *target_fl;
2989
    struct flock64 fl64;
2990
    struct target_flock64 *target_fl64;
2991
    abi_long ret;
2992

    
2993
    switch(cmd) {
2994
    case TARGET_F_GETLK:
2995
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2996
            return -TARGET_EFAULT;
2997
        fl.l_type = tswap16(target_fl->l_type);
2998
        fl.l_whence = tswap16(target_fl->l_whence);
2999
        fl.l_start = tswapl(target_fl->l_start);
3000
        fl.l_len = tswapl(target_fl->l_len);
3001
        fl.l_pid = tswapl(target_fl->l_pid);
3002
        unlock_user_struct(target_fl, arg, 0);
3003
        ret = get_errno(fcntl(fd, cmd, &fl));
3004
        if (ret == 0) {
3005
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3006
                return -TARGET_EFAULT;
3007
            target_fl->l_type = tswap16(fl.l_type);
3008
            target_fl->l_whence = tswap16(fl.l_whence);
3009
            target_fl->l_start = tswapl(fl.l_start);
3010
            target_fl->l_len = tswapl(fl.l_len);
3011
            target_fl->l_pid = tswapl(fl.l_pid);
3012
            unlock_user_struct(target_fl, arg, 1);
3013
        }
3014
        break;
3015

    
3016
    case TARGET_F_SETLK:
3017
    case TARGET_F_SETLKW:
3018
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3019
            return -TARGET_EFAULT;
3020
        fl.l_type = tswap16(target_fl->l_type);
3021
        fl.l_whence = tswap16(target_fl->l_whence);
3022
        fl.l_start = tswapl(target_fl->l_start);
3023
        fl.l_len = tswapl(target_fl->l_len);
3024
        fl.l_pid = tswapl(target_fl->l_pid);
3025
        unlock_user_struct(target_fl, arg, 0);
3026
        ret = get_errno(fcntl(fd, cmd, &fl));
3027
        break;
3028

    
3029
    case TARGET_F_GETLK64:
3030
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3031
            return -TARGET_EFAULT;
3032
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3033
        fl64.l_whence = tswap16(target_fl64->l_whence);
3034
        fl64.l_start = tswapl(target_fl64->l_start);
3035
        fl64.l_len = tswapl(target_fl64->l_len);
3036
        fl64.l_pid = tswap16(target_fl64->l_pid);
3037
        unlock_user_struct(target_fl64, arg, 0);
3038
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3039
        if (ret == 0) {
3040
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3041
                return -TARGET_EFAULT;
3042
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3043
            target_fl64->l_whence = tswap16(fl64.l_whence);
3044
            target_fl64->l_start = tswapl(fl64.l_start);
3045
            target_fl64->l_len = tswapl(fl64.l_len);
3046
            target_fl64->l_pid = tswapl(fl64.l_pid);
3047
            unlock_user_struct(target_fl64, arg, 1);
3048
        }
3049
        break;
3050
    case TARGET_F_SETLK64:
3051
    case TARGET_F_SETLKW64:
3052
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3053
            return -TARGET_EFAULT;
3054
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3055
        fl64.l_whence = tswap16(target_fl64->l_whence);
3056
        fl64.l_start = tswapl(target_fl64->l_start);
3057
        fl64.l_len = tswapl(target_fl64->l_len);
3058
        fl64.l_pid = tswap16(target_fl64->l_pid);
3059
        unlock_user_struct(target_fl64, arg, 0);
3060
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3061
        break;
3062

    
3063
    case F_GETFL:
3064
        ret = get_errno(fcntl(fd, cmd, arg));
3065
        if (ret >= 0) {
3066
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3067
        }
3068
        break;
3069

    
3070
    case F_SETFL:
3071
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3072
        break;
3073

    
3074
    default:
3075
        ret = get_errno(fcntl(fd, cmd, arg));
3076
        break;
3077
    }
3078
    return ret;
3079
}
3080

    
3081
#ifdef USE_UID16
3082

    
3083
static inline int high2lowuid(int uid)
3084
{
3085
    if (uid > 65535)
3086
        return 65534;
3087
    else
3088
        return uid;
3089
}
3090

    
3091
static inline int high2lowgid(int gid)
3092
{
3093
    if (gid > 65535)
3094
        return 65534;
3095
    else
3096
        return gid;
3097
}
3098

    
3099
static inline int low2highuid(int uid)
3100
{
3101
    if ((int16_t)uid == -1)
3102
        return -1;
3103
    else
3104
        return uid;
3105
}
3106

    
3107
static inline int low2highgid(int gid)
3108
{
3109
    if ((int16_t)gid == -1)
3110
        return -1;
3111
    else
3112
        return gid;
3113
}
3114

    
3115
#endif /* USE_UID16 */
3116

    
3117
void syscall_init(void)
3118
{
3119
    IOCTLEntry *ie;
3120
    const argtype *arg_type;
3121
    int size;
3122
    int i;
3123

    
3124
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3125
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3126
#include "syscall_types.h"
3127
#undef STRUCT
3128
#undef STRUCT_SPECIAL
3129

    
3130
    /* we patch the ioctl size if necessary. We rely on the fact that
3131
       no ioctl has all the bits at '1' in the size field */
3132
    ie = ioctl_entries;
3133
    while (ie->target_cmd != 0) {
3134
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3135
            TARGET_IOC_SIZEMASK) {
3136
            arg_type = ie->arg_type;
3137
            if (arg_type[0] != TYPE_PTR) {
3138
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3139
                        ie->target_cmd);
3140
                exit(1);
3141
            }
3142
            arg_type++;
3143
            size = thunk_type_size(arg_type, 0);
3144
            ie->target_cmd = (ie->target_cmd &
3145
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3146
                (size << TARGET_IOC_SIZESHIFT);
3147
        }
3148

    
3149
        /* Build target_to_host_errno_table[] table from
3150
         * host_to_target_errno_table[]. */
3151
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3152
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3153

    
3154
        /* automatic consistency check if same arch */
3155
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3156
    (defined(__x86_64__) && defined(TARGET_X86_64))
3157
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3158
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3159
                    ie->name, ie->target_cmd, ie->host_cmd);
3160
        }
3161
#endif
3162
        ie++;
3163
    }
3164
}
3165

    
3166
#if TARGET_ABI_BITS == 32
3167
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3168
{
3169
#ifdef TARGET_WORDS_BIGENDIAN
3170
    return ((uint64_t)word0 << 32) | word1;
3171
#else
3172
    return ((uint64_t)word1 << 32) | word0;
3173
#endif
3174
}
3175
#else /* TARGET_ABI_BITS == 32 */
3176
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3177
{
3178
    return word0;
3179
}
3180
#endif /* TARGET_ABI_BITS != 32 */
3181

    
3182
#ifdef TARGET_NR_truncate64
3183
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3184
                                         abi_long arg2,
3185
                                         abi_long arg3,
3186
                                         abi_long arg4)
3187
{
3188
#ifdef TARGET_ARM
3189
    if (((CPUARMState *)cpu_env)->eabi)
3190
      {
3191
        arg2 = arg3;
3192
        arg3 = arg4;
3193
      }
3194
#endif
3195
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3196
}
3197
#endif
3198

    
3199
#ifdef TARGET_NR_ftruncate64
3200
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3201
                                          abi_long arg2,
3202
                                          abi_long arg3,
3203
                                          abi_long arg4)
3204
{
3205
#ifdef TARGET_ARM
3206
    if (((CPUARMState *)cpu_env)->eabi)
3207
      {
3208
        arg2 = arg3;
3209
        arg3 = arg4;
3210
      }
3211
#endif
3212
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3213
}
3214
#endif
3215

    
3216
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3217
                                               abi_ulong target_addr)
3218
{
3219
    struct target_timespec *target_ts;
3220

    
3221
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3222
        return -TARGET_EFAULT;
3223
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3224
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3225
    unlock_user_struct(target_ts, target_addr, 0);
3226
    return 0;
3227
}
3228

    
3229
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3230
                                               struct timespec *host_ts)
3231
{
3232
    struct target_timespec *target_ts;
3233

    
3234
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3235
        return -TARGET_EFAULT;
3236
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3237
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3238
    unlock_user_struct(target_ts, target_addr, 1);
3239
    return 0;
3240
}
3241

    
3242
#ifdef TARGET_NR_stat64
3243
static inline abi_long host_to_target_stat64(void *cpu_env,
3244
                                             abi_ulong target_addr,
3245
                                             struct stat *host_st)
3246
{
3247
#ifdef TARGET_ARM
3248
    if (((CPUARMState *)cpu_env)->eabi) {
3249
        struct target_eabi_stat64 *target_st;
3250

    
3251
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3252
            return -TARGET_EFAULT;
3253
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3254
        __put_user(host_st->st_dev, &target_st->st_dev);
3255
        __put_user(host_st->st_ino, &target_st->st_ino);
3256
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3257
        __put_user(host_st->st_ino, &target_st->__st_ino);
3258
#endif
3259
        __put_user(host_st->st_mode, &target_st->st_mode);
3260
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3261
        __put_user(host_st->st_uid, &target_st->st_uid);
3262
        __put_user(host_st->st_gid, &target_st->st_gid);
3263
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3264
        __put_user(host_st->st_size, &target_st->st_size);
3265
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3266
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3267
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3268
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3269
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3270
        unlock_user_struct(target_st, target_addr, 1);
3271
    } else
3272
#endif
3273
    {
3274
        struct target_stat64 *target_st;
3275

    
3276
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3277
            return -TARGET_EFAULT;
3278
        memset(target_st, 0, sizeof(struct target_stat64));
3279
        __put_user(host_st->st_dev, &target_st->st_dev);
3280
        __put_user(host_st->st_ino, &target_st->st_ino);
3281
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3282
        __put_user(host_st->st_ino, &target_st->__st_ino);
3283
#endif
3284
        __put_user(host_st->st_mode, &target_st->st_mode);
3285
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3286
        __put_user(host_st->st_uid, &target_st->st_uid);
3287
        __put_user(host_st->st_gid, &target_st->st_gid);
3288
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3289
        /* XXX: better use of kernel struct */
3290
        __put_user(host_st->st_size, &target_st->st_size);
3291
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3292
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3293
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3294
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3295
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3296
        unlock_user_struct(target_st, target_addr, 1);
3297
    }
3298

    
3299
    return 0;
3300
}
3301
#endif
3302

    
3303
#if defined(USE_NPTL)
3304
/* ??? Using host futex calls even when target atomic operations
3305
   are not really atomic probably breaks things.  However implementing
3306
   futexes locally would make futexes shared between multiple processes
3307
   tricky.  However they're probably useless because guest atomic
3308
   operations won't work either.  */
3309
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3310
                    target_ulong uaddr2, int val3)
3311
{
3312
    struct timespec ts, *pts;
3313

    
3314
    /* ??? We assume FUTEX_* constants are the same on both host
3315
       and target.  */
3316
    switch (op) {
3317
    case FUTEX_WAIT:
3318
        if (timeout) {
3319
            pts = &ts;
3320
            target_to_host_timespec(pts, timeout);
3321
        } else {
3322
            pts = NULL;
3323
        }
3324
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3325
                         pts, NULL, 0));
3326
    case FUTEX_WAKE:
3327
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3328
    case FUTEX_FD:
3329
        return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3330
    case FUTEX_REQUEUE:
3331
        return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3332
                         NULL, g2h(uaddr2), 0));
3333
    case FUTEX_CMP_REQUEUE:
3334
        return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3335
                         NULL, g2h(uaddr2), tswap32(val3)));
3336
    default:
3337
        return -TARGET_ENOSYS;
3338
    }
3339
}
3340
#endif
3341

    
3342
int get_osversion(void)
3343
{
3344
    static int osversion;
3345
    struct new_utsname buf;
3346
    const char *s;
3347
    int i, n, tmp;
3348
    if (osversion)
3349
        return osversion;
3350
    if (qemu_uname_release && *qemu_uname_release) {
3351
        s = qemu_uname_release;
3352
    } else {
3353
        if (sys_uname(&buf))
3354
            return 0;
3355
        s = buf.release;
3356
    }
3357
    tmp = 0;
3358
    for (i = 0; i < 3; i++) {
3359
        n = 0;
3360
        while (*s >= '0' && *s <= '9') {
3361
            n *= 10;
3362
            n += *s - '0';
3363
            s++;
3364
        }
3365
        tmp = (tmp << 8) + n;
3366
        if (*s == '.')
3367
            s++;
3368
    }
3369
    osversion = tmp;
3370
    return osversion;
3371
}
3372

    
3373
/* do_syscall() should always have a single exit point at the end so
3374
   that actions, such as logging of syscall results, can be performed.
3375
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3376
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3377
                    abi_long arg2, abi_long arg3, abi_long arg4,
3378
                    abi_long arg5, abi_long arg6)
3379
{
3380
    abi_long ret;
3381
    struct stat st;
3382
    struct statfs stfs;
3383
    void *p;
3384

    
3385
#ifdef DEBUG
3386
    gemu_log("syscall %d", num);
3387
#endif
3388
    if(do_strace)
3389
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3390

    
3391
    switch(num) {
3392
    case TARGET_NR_exit:
3393
#ifdef HAVE_GPROF
3394
        _mcleanup();
3395
#endif
3396
        gdb_exit(cpu_env, arg1);
3397
        /* XXX: should free thread stack and CPU env */
3398
        _exit(arg1);
3399
        ret = 0; /* avoid warning */
3400
        break;
3401
    case TARGET_NR_read:
3402
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3403
            goto efault;
3404
        ret = get_errno(read(arg1, p, arg3));
3405
        unlock_user(p, arg2, ret);
3406
        break;
3407
    case TARGET_NR_write:
3408
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3409
            goto efault;
3410
        ret = get_errno(write(arg1, p, arg3));
3411
        unlock_user(p, arg2, 0);
3412
        break;
3413
    case TARGET_NR_open:
3414
        if (!(p = lock_user_string(arg1)))
3415
            goto efault;
3416
        ret = get_errno(open(path(p),
3417
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
3418
                             arg3));
3419
        unlock_user(p, arg1, 0);
3420
        break;
3421
#if defined(TARGET_NR_openat) && defined(__NR_openat)
3422
    case TARGET_NR_openat:
3423
        if (!(p = lock_user_string(arg2)))
3424
            goto efault;
3425
        ret = get_errno(sys_openat(arg1,
3426
                                   path(p),
3427
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
3428
                                   arg4));
3429
        unlock_user(p, arg2, 0);
3430
        break;
3431
#endif
3432
    case TARGET_NR_close:
3433
        ret = get_errno(close(arg1));
3434
        break;
3435
    case TARGET_NR_brk:
3436
        ret = do_brk(arg1);
3437
        break;
3438
    case TARGET_NR_fork:
3439
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3440
        break;
3441
#ifdef TARGET_NR_waitpid
3442
    case TARGET_NR_waitpid:
3443
        {
3444
            int status;
3445
            ret = get_errno(waitpid(arg1, &status, arg3));
3446
            if (!is_error(ret) && arg2
3447
                && put_user_s32(status, arg2))
3448
                goto efault;
3449
        }
3450
        break;
3451
#endif
3452
#ifdef TARGET_NR_waitid
3453
    case TARGET_NR_waitid:
3454
        {
3455
            siginfo_t info;
3456
            info.si_pid = 0;
3457
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
3458
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
3459
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3460
                    goto efault;
3461
                host_to_target_siginfo(p, &info);
3462
                unlock_user(p, arg3, sizeof(target_siginfo_t));
3463
            }
3464
        }
3465
        break;
3466
#endif
3467
#ifdef TARGET_NR_creat /* not on alpha */
3468
    case TARGET_NR_creat:
3469
        if (!(p = lock_user_string(arg1)))
3470
            goto efault;
3471
        ret = get_errno(creat(p, arg2));
3472
        unlock_user(p, arg1, 0);
3473
        break;
3474
#endif
3475
    case TARGET_NR_link:
3476
        {
3477
            void * p2;
3478
            p = lock_user_string(arg1);
3479
            p2 = lock_user_string(arg2);
3480
            if (!p || !p2)
3481
                ret = -TARGET_EFAULT;
3482
            else
3483
                ret = get_errno(link(p, p2));
3484
            unlock_user(p2, arg2, 0);
3485
            unlock_user(p, arg1, 0);
3486
        }
3487
        break;
3488
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3489
    case TARGET_NR_linkat:
3490
        {
3491
            void * p2 = NULL;
3492
            if (!arg2 || !arg4)
3493
                goto efault;
3494
            p  = lock_user_string(arg2);
3495
            p2 = lock_user_string(arg4);
3496
            if (!p || !p2)
3497
                ret = -TARGET_EFAULT;
3498
            else
3499
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3500
            unlock_user(p, arg2, 0);
3501
            unlock_user(p2, arg4, 0);
3502
        }
3503
        break;
3504
#endif
3505
    case TARGET_NR_unlink:
3506
        if (!(p = lock_user_string(arg1)))
3507
            goto efault;
3508
        ret = get_errno(unlink(p));
3509
        unlock_user(p, arg1, 0);
3510
        break;
3511
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3512
    case TARGET_NR_unlinkat:
3513
        if (!(p = lock_user_string(arg2)))
3514
            goto efault;
3515
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
3516
        unlock_user(p, arg2, 0);
3517
        break;
3518
#endif
3519
    case TARGET_NR_execve:
3520
        {
3521
            char **argp, **envp;
3522
            int argc, envc;
3523
            abi_ulong gp;
3524
            abi_ulong guest_argp;
3525
            abi_ulong guest_envp;
3526
            abi_ulong addr;
3527
            char **q;
3528

    
3529
            argc = 0;
3530
            guest_argp = arg2;
3531
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3532
                if (get_user_ual(addr, gp))
3533
                    goto efault;
3534
                if (!addr)
3535
                    break;
3536
                argc++;
3537
            }
3538
            envc = 0;
3539
            guest_envp = arg3;
3540
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3541
                if (get_user_ual(addr, gp))
3542
                    goto efault;
3543
                if (!addr)
3544
                    break;
3545
                envc++;
3546
            }
3547

    
3548
            argp = alloca((argc + 1) * sizeof(void *));
3549
            envp = alloca((envc + 1) * sizeof(void *));
3550

    
3551
            for (gp = guest_argp, q = argp; gp;
3552
                  gp += sizeof(abi_ulong), q++) {
3553
                if (get_user_ual(addr, gp))
3554
                    goto execve_efault;
3555
                if (!addr)
3556
                    break;
3557
                if (!(*q = lock_user_string(addr)))
3558
                    goto execve_efault;
3559
            }
3560
            *q = NULL;
3561

    
3562
            for (gp = guest_envp, q = envp; gp;
3563
                  gp += sizeof(abi_ulong), q++) {
3564
                if (get_user_ual(addr, gp))
3565
                    goto execve_efault;
3566
                if (!addr)
3567
                    break;
3568
                if (!(*q = lock_user_string(addr)))
3569
                    goto execve_efault;
3570
            }
3571
            *q = NULL;
3572

    
3573
            if (!(p = lock_user_string(arg1)))
3574
                goto execve_efault;
3575
            ret = get_errno(execve(p, argp, envp));
3576
            unlock_user(p, arg1, 0);
3577

    
3578
            goto execve_end;
3579

    
3580
        execve_efault:
3581
            ret = -TARGET_EFAULT;
3582

    
3583
        execve_end:
3584
            for (gp = guest_argp, q = argp; *q;
3585
                  gp += sizeof(abi_ulong), q++) {
3586
                if (get_user_ual(addr, gp)
3587
                    || !addr)
3588
                    break;
3589
                unlock_user(*q, addr, 0);
3590
            }
3591
            for (gp = guest_envp, q = envp; *q;
3592
                  gp += sizeof(abi_ulong), q++) {
3593
                if (get_user_ual(addr, gp)
3594
                    || !addr)
3595
                    break;
3596
                unlock_user(*q, addr, 0);
3597
            }
3598
        }
3599
        break;
3600
    case TARGET_NR_chdir:
3601
        if (!(p = lock_user_string(arg1)))
3602
            goto efault;
3603
        ret = get_errno(chdir(p));
3604
        unlock_user(p, arg1, 0);
3605
        break;
3606
#ifdef TARGET_NR_time
3607
    case TARGET_NR_time:
3608
        {
3609
            time_t host_time;
3610
            ret = get_errno(time(&host_time));
3611
            if (!is_error(ret)
3612
                && arg1
3613
                && put_user_sal(host_time, arg1))
3614
                goto efault;
3615
        }
3616
        break;
3617
#endif
3618
    case TARGET_NR_mknod:
3619
        if (!(p = lock_user_string(arg1)))
3620
            goto efault;
3621
        ret = get_errno(mknod(p, arg2, arg3));
3622
        unlock_user(p, arg1, 0);
3623
        break;
3624
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3625
    case TARGET_NR_mknodat:
3626
        if (!(p = lock_user_string(arg2)))
3627
            goto efault;
3628
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3629
        unlock_user(p, arg2, 0);
3630
        break;
3631
#endif
3632
    case TARGET_NR_chmod:
3633
        if (!(p = lock_user_string(arg1)))
3634
            goto efault;
3635
        ret = get_errno(chmod(p, arg2));
3636
        unlock_user(p, arg1, 0);
3637
        break;
3638
#ifdef TARGET_NR_break
3639
    case TARGET_NR_break:
3640
        goto unimplemented;
3641
#endif
3642
#ifdef TARGET_NR_oldstat
3643
    case TARGET_NR_oldstat:
3644
        goto unimplemented;
3645
#endif
3646
    case TARGET_NR_lseek:
3647
        ret = get_errno(lseek(arg1, arg2, arg3));
3648
        break;
3649
#ifdef TARGET_NR_getxpid
3650
    case TARGET_NR_getxpid:
3651
#else
3652
    case TARGET_NR_getpid:
3653
#endif
3654
        ret = get_errno(getpid());
3655
        break;
3656
    case TARGET_NR_mount:
3657
                {
3658
                        /* need to look at the data field */
3659
                        void *p2, *p3;
3660
                        p = lock_user_string(arg1);
3661
                        p2 = lock_user_string(arg2);
3662
                        p3 = lock_user_string(arg3);
3663
                        if (!p || !p2 || !p3)
3664
                            ret = -TARGET_EFAULT;
3665
                        else
3666
                            /* FIXME - arg5 should be locked, but it isn't clear how to
3667
                             * do that since it's not guaranteed to be a NULL-terminated
3668
                             * string.
3669
                             */
3670
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3671
                        unlock_user(p, arg1, 0);
3672
                        unlock_user(p2, arg2, 0);
3673
                        unlock_user(p3, arg3, 0);
3674
                        break;
3675
                }
3676
#ifdef TARGET_NR_umount
3677
    case TARGET_NR_umount:
3678
        if (!(p = lock_user_string(arg1)))
3679
            goto efault;
3680
        ret = get_errno(umount(p));
3681
        unlock_user(p, arg1, 0);
3682
        break;
3683
#endif
3684
#ifdef TARGET_NR_stime /* not on alpha */
3685
    case TARGET_NR_stime:
3686
        {
3687
            time_t host_time;
3688
            if (get_user_sal(host_time, arg1))
3689
                goto efault;
3690
            ret = get_errno(stime(&host_time));
3691
        }
3692
        break;
3693
#endif
3694
    case TARGET_NR_ptrace:
3695
        goto unimplemented;
3696
#ifdef TARGET_NR_alarm /* not on alpha */
3697
    case TARGET_NR_alarm:
3698
        ret = alarm(arg1);
3699
        break;
3700
#endif
3701
#ifdef TARGET_NR_oldfstat
3702
    case TARGET_NR_oldfstat:
3703
        goto unimplemented;
3704
#endif
3705
#ifdef TARGET_NR_pause /* not on alpha */
3706
    case TARGET_NR_pause:
3707
        ret = get_errno(pause());
3708
        break;
3709
#endif
3710
#ifdef TARGET_NR_utime
3711
    case TARGET_NR_utime:
3712
        {
3713
            struct utimbuf tbuf, *host_tbuf;
3714
            struct target_utimbuf *target_tbuf;
3715
            if (arg2) {
3716
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3717
                    goto efault;
3718
                tbuf.actime = tswapl(target_tbuf->actime);
3719
                tbuf.modtime = tswapl(target_tbuf->modtime);
3720
                unlock_user_struct(target_tbuf, arg2, 0);
3721
                host_tbuf = &tbuf;
3722
            } else {
3723
                host_tbuf = NULL;
3724
            }
3725
            if (!(p = lock_user_string(arg1)))
3726
                goto efault;
3727
            ret = get_errno(utime(p, host_tbuf));
3728
            unlock_user(p, arg1, 0);
3729
        }
3730
        break;
3731
#endif
3732
    case TARGET_NR_utimes:
3733
        {
3734
            struct timeval *tvp, tv[2];
3735
            if (arg2) {
3736
                if (copy_from_user_timeval(&tv[0], arg2)
3737
                    || copy_from_user_timeval(&tv[1],
3738
                                              arg2 + sizeof(struct target_timeval)))
3739
                    goto efault;
3740
                tvp = tv;
3741
            } else {
3742
                tvp = NULL;
3743
            }
3744
            if (!(p = lock_user_string(arg1)))
3745
                goto efault;
3746
            ret = get_errno(utimes(p, tvp));
3747
            unlock_user(p, arg1, 0);
3748
        }
3749
        break;
3750
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
3751
    case TARGET_NR_futimesat:
3752
        {
3753
            struct timeval *tvp, tv[2];
3754
            if (arg3) {
3755
                if (copy_from_user_timeval(&tv[0], arg3)
3756
                    || copy_from_user_timeval(&tv[1],
3757
                                              arg3 + sizeof(struct target_timeval)))
3758
                    goto efault;
3759
                tvp = tv;
3760
            } else {
3761
                tvp = NULL;
3762
            }
3763
            if (!(p = lock_user_string(arg2)))
3764
                goto efault;
3765
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
3766
            unlock_user(p, arg2, 0);
3767
        }
3768
        break;
3769
#endif
3770
#ifdef TARGET_NR_stty
3771
    case TARGET_NR_stty:
3772
        goto unimplemented;
3773
#endif
3774
#ifdef TARGET_NR_gtty
3775
    case TARGET_NR_gtty:
3776
        goto unimplemented;
3777
#endif
3778
    case TARGET_NR_access:
3779
        if (!(p = lock_user_string(arg1)))
3780
            goto efault;
3781
        ret = get_errno(access(p, arg2));
3782
        unlock_user(p, arg1, 0);
3783
        break;
3784
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3785
    case TARGET_NR_faccessat:
3786
        if (!(p = lock_user_string(arg2)))
3787
            goto efault;
3788
        ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3789
        unlock_user(p, arg2, 0);
3790
        break;
3791
#endif
3792
#ifdef TARGET_NR_nice /* not on alpha */
3793
    case TARGET_NR_nice:
3794
        ret = get_errno(nice(arg1));
3795
        break;
3796
#endif
3797
#ifdef TARGET_NR_ftime
3798
    case TARGET_NR_ftime:
3799
        goto unimplemented;
3800
#endif
3801
    case TARGET_NR_sync:
3802
        sync();
3803
        ret = 0;
3804
        break;
3805
    case TARGET_NR_kill:
3806
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3807
        break;
3808
    case TARGET_NR_rename:
3809
        {
3810
            void *p2;
3811
            p = lock_user_string(arg1);
3812
            p2 = lock_user_string(arg2);
3813
            if (!p || !p2)
3814
                ret = -TARGET_EFAULT;
3815
            else
3816
                ret = get_errno(rename(p, p2));
3817
            unlock_user(p2, arg2, 0);
3818
            unlock_user(p, arg1, 0);
3819
        }
3820
        break;
3821
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3822
    case TARGET_NR_renameat:
3823
        {
3824
            void *p2;
3825
            p  = lock_user_string(arg2);
3826
            p2 = lock_user_string(arg4);
3827
            if (!p || !p2)
3828
                ret = -TARGET_EFAULT;
3829
            else
3830
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3831
            unlock_user(p2, arg4, 0);
3832
            unlock_user(p, arg2, 0);
3833
        }
3834
        break;
3835
#endif
3836
    case TARGET_NR_mkdir:
3837
        if (!(p = lock_user_string(arg1)))
3838
            goto efault;
3839
        ret = get_errno(mkdir(p, arg2));
3840
        unlock_user(p, arg1, 0);
3841
        break;
3842
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3843
    case TARGET_NR_mkdirat:
3844
        if (!(p = lock_user_string(arg2)))
3845
            goto efault;
3846
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
3847
        unlock_user(p, arg2, 0);
3848
        break;
3849
#endif
3850
    case TARGET_NR_rmdir:
3851
        if (!(p = lock_user_string(arg1)))
3852
            goto efault;
3853
        ret = get_errno(rmdir(p));
3854
        unlock_user(p, arg1, 0);
3855
        break;
3856
    case TARGET_NR_dup:
3857
        ret = get_errno(dup(arg1));
3858
        break;
3859
    case TARGET_NR_pipe:
3860
        {
3861
            int host_pipe[2];
3862
            ret = get_errno(pipe(host_pipe));
3863
            if (!is_error(ret)) {
3864
#if defined(TARGET_MIPS)
3865
                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3866
                env->active_tc.gpr[3] = host_pipe[1];
3867
                ret = host_pipe[0];
3868
#elif defined(TARGET_SH4)
3869
                ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3870
                ret = host_pipe[0];
3871
#else
3872
                if (put_user_s32(host_pipe[0], arg1)
3873
                    || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3874
                    goto efault;
3875
#endif
3876
            }
3877
        }
3878
        break;
3879
    case TARGET_NR_times:
3880
        {
3881
            struct target_tms *tmsp;
3882
            struct tms tms;
3883
            ret = get_errno(times(&tms));
3884
            if (arg1) {
3885
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3886
                if (!tmsp)
3887
                    goto efault;
3888
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3889
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3890
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3891
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3892
            }
3893
            if (!is_error(ret))
3894
                ret = host_to_target_clock_t(ret);
3895
        }
3896
        break;
3897
#ifdef TARGET_NR_prof
3898
    case TARGET_NR_prof:
3899
        goto unimplemented;
3900
#endif
3901
#ifdef TARGET_NR_signal
3902
    case TARGET_NR_signal:
3903
        goto unimplemented;
3904
#endif
3905
    case TARGET_NR_acct:
3906
        if (!(p = lock_user_string(arg1)))
3907
            goto efault;
3908
        ret = get_errno(acct(path(p)));
3909
        unlock_user(p, arg1, 0);
3910
        break;
3911
#ifdef TARGET_NR_umount2 /* not on alpha */
3912
    case TARGET_NR_umount2:
3913
        if (!(p = lock_user_string(arg1)))
3914
            goto efault;
3915
        ret = get_errno(umount2(p, arg2));
3916
        unlock_user(p, arg1, 0);
3917
        break;
3918
#endif
3919
#ifdef TARGET_NR_lock
3920
    case TARGET_NR_lock:
3921
        goto unimplemented;
3922
#endif
3923
    case TARGET_NR_ioctl:
3924
        ret = do_ioctl(arg1, arg2, arg3);
3925
        break;
3926
    case TARGET_NR_fcntl:
3927
        ret = do_fcntl(arg1, arg2, arg3);
3928
        break;
3929
#ifdef TARGET_NR_mpx
3930
    case TARGET_NR_mpx:
3931
        goto unimplemented;
3932
#endif
3933
    case TARGET_NR_setpgid:
3934
        ret = get_errno(setpgid(arg1, arg2));
3935
        break;
3936
#ifdef TARGET_NR_ulimit
3937
    case TARGET_NR_ulimit:
3938
        goto unimplemented;
3939
#endif
3940
#ifdef TARGET_NR_oldolduname
3941
    case TARGET_NR_oldolduname:
3942
        goto unimplemented;
3943
#endif
3944
    case TARGET_NR_umask:
3945
        ret = get_errno(umask(arg1));
3946
        break;
3947
    case TARGET_NR_chroot:
3948
        if (!(p = lock_user_string(arg1)))
3949
            goto efault;
3950
        ret = get_errno(chroot(p));
3951
        unlock_user(p, arg1, 0);
3952
        break;
3953
    case TARGET_NR_ustat:
3954
        goto unimplemented;
3955
    case TARGET_NR_dup2:
3956
        ret = get_errno(dup2(arg1, arg2));
3957
        break;
3958
#ifdef TARGET_NR_getppid /* not on alpha */
3959
    case TARGET_NR_getppid:
3960
        ret = get_errno(getppid());
3961
        break;
3962
#endif
3963
    case TARGET_NR_getpgrp:
3964
        ret = get_errno(getpgrp());
3965
        break;
3966
    case TARGET_NR_setsid:
3967
        ret = get_errno(setsid());
3968
        break;
3969
#ifdef TARGET_NR_sigaction
3970
    case TARGET_NR_sigaction:
3971
        {
3972
#if !defined(TARGET_MIPS)
3973
            struct target_old_sigaction *old_act;
3974
            struct target_sigaction act, oact, *pact;
3975
            if (arg2) {
3976
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3977
                    goto efault;
3978
                act._sa_handler = old_act->_sa_handler;
3979
                target_siginitset(&act.sa_mask, old_act->sa_mask);
3980
                act.sa_flags = old_act->sa_flags;
3981
                act.sa_restorer = old_act->sa_restorer;
3982
                unlock_user_struct(old_act, arg2, 0);
3983
                pact = &act;
3984
            } else {
3985
                pact = NULL;
3986
            }
3987
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3988
            if (!is_error(ret) && arg3) {
3989
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3990
                    goto efault;
3991
                old_act->_sa_handler = oact._sa_handler;
3992
                old_act->sa_mask = oact.sa_mask.sig[0];
3993
                old_act->sa_flags = oact.sa_flags;
3994
                old_act->sa_restorer = oact.sa_restorer;
3995
                unlock_user_struct(old_act, arg3, 1);
3996
            }
3997
#else
3998
            struct target_sigaction act, oact, *pact, *old_act;
3999

    
4000
            if (arg2) {
4001
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4002
                    goto efault;
4003
                act._sa_handler = old_act->_sa_handler;
4004
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4005
                act.sa_flags = old_act->sa_flags;
4006
                unlock_user_struct(old_act, arg2, 0);
4007
                pact = &act;
4008
            } else {
4009
                pact = NULL;
4010
            }
4011

    
4012
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4013

    
4014
            if (!is_error(ret) && arg3) {
4015
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4016
                    goto efault;
4017
                old_act->_sa_handler = oact._sa_handler;
4018
                old_act->sa_flags = oact.sa_flags;
4019
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4020
                old_act->sa_mask.sig[1] = 0;
4021
                old_act->sa_mask.sig[2] = 0;
4022
                old_act->sa_mask.sig[3] = 0;
4023
                unlock_user_struct(old_act, arg3, 1);
4024
            }
4025
#endif
4026
        }
4027
        break;
4028
#endif
4029
    case TARGET_NR_rt_sigaction:
4030
        {
4031
            struct target_sigaction *act;
4032
            struct target_sigaction *oact;
4033

    
4034
            if (arg2) {
4035
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4036
                    goto efault;
4037
            } else
4038
                act = NULL;
4039
            if (arg3) {
4040
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4041
                    ret = -TARGET_EFAULT;
4042
                    goto rt_sigaction_fail;
4043
                }
4044
            } else
4045
                oact = NULL;
4046
            ret = get_errno(do_sigaction(arg1, act, oact));
4047
        rt_sigaction_fail:
4048
            if (act)
4049
                unlock_user_struct(act, arg2, 0);
4050
            if (oact)
4051
                unlock_user_struct(oact, arg3, 1);
4052
        }
4053
        break;
4054
#ifdef TARGET_NR_sgetmask /* not on alpha */
4055
    case TARGET_NR_sgetmask:
4056
        {
4057
            sigset_t cur_set;
4058
            abi_ulong target_set;
4059
            sigprocmask(0, NULL, &cur_set);
4060
            host_to_target_old_sigset(&target_set, &cur_set);
4061
            ret = target_set;
4062
        }
4063
        break;
4064
#endif
4065
#ifdef TARGET_NR_ssetmask /* not on alpha */
4066
    case TARGET_NR_ssetmask:
4067
        {
4068
            sigset_t set, oset, cur_set;
4069
            abi_ulong target_set = arg1;
4070
            sigprocmask(0, NULL, &cur_set);
4071
            target_to_host_old_sigset(&set, &target_set);
4072
            sigorset(&set, &set, &cur_set);
4073
            sigprocmask(SIG_SETMASK, &set, &oset);
4074
            host_to_target_old_sigset(&target_set, &oset);
4075
            ret = target_set;
4076
        }
4077
        break;
4078
#endif
4079
#ifdef TARGET_NR_sigprocmask
4080
    case TARGET_NR_sigprocmask:
4081
        {
4082
            int how = arg1;
4083
            sigset_t set, oldset, *set_ptr;
4084

    
4085
            if (arg2) {
4086
                switch(how) {
4087
                case TARGET_SIG_BLOCK:
4088
                    how = SIG_BLOCK;
4089
                    break;
4090
                case TARGET_SIG_UNBLOCK:
4091
                    how = SIG_UNBLOCK;
4092
                    break;
4093
                case TARGET_SIG_SETMASK:
4094
                    how = SIG_SETMASK;
4095
                    break;
4096
                default:
4097
                    ret = -TARGET_EINVAL;
4098
                    goto fail;
4099
                }
4100
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4101
                    goto efault;
4102
                target_to_host_old_sigset(&set, p);
4103
                unlock_user(p, arg2, 0);
4104
                set_ptr = &set;
4105
            } else {
4106
                how = 0;
4107
                set_ptr = NULL;
4108
            }
4109
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4110
            if (!is_error(ret) && arg3) {
4111
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4112
                    goto efault;
4113
                host_to_target_old_sigset(p, &oldset);
4114
                unlock_user(p, arg3, sizeof(target_sigset_t));
4115
            }
4116
        }
4117
        break;
4118
#endif
4119
    case TARGET_NR_rt_sigprocmask:
4120
        {
4121
            int how = arg1;
4122
            sigset_t set, oldset, *set_ptr;
4123

    
4124
            if (arg2) {
4125
                switch(how) {
4126
                case TARGET_SIG_BLOCK:
4127
                    how = SIG_BLOCK;
4128
                    break;
4129
                case TARGET_SIG_UNBLOCK:
4130
                    how = SIG_UNBLOCK;
4131
                    break;
4132
                case TARGET_SIG_SETMASK:
4133
                    how = SIG_SETMASK;
4134
                    break;
4135
                default:
4136
                    ret = -TARGET_EINVAL;
4137
                    goto fail;
4138
                }
4139
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4140
                    goto efault;
4141
                target_to_host_sigset(&set, p);
4142
                unlock_user(p, arg2, 0);
4143
                set_ptr = &set;
4144
            } else {
4145
                how = 0;
4146
                set_ptr = NULL;
4147
            }
4148
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4149
            if (!is_error(ret) && arg3) {
4150
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4151
                    goto efault;
4152
                host_to_target_sigset(p, &oldset);
4153
                unlock_user(p, arg3, sizeof(target_sigset_t));
4154
            }
4155
        }
4156
        break;
4157
#ifdef TARGET_NR_sigpending
4158
    case TARGET_NR_sigpending:
4159
        {
4160
            sigset_t set;
4161
            ret = get_errno(sigpending(&set));
4162
            if (!is_error(ret)) {
4163
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4164
                    goto efault;
4165
                host_to_target_old_sigset(p, &set);
4166
                unlock_user(p, arg1, sizeof(target_sigset_t));
4167
            }
4168
        }
4169
        break;
4170
#endif
4171
    case TARGET_NR_rt_sigpending:
4172
        {
4173
            sigset_t set;
4174
            ret = get_errno(sigpending(&set));
4175
            if (!is_error(ret)) {
4176
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4177
                    goto efault;
4178
                host_to_target_sigset(p, &set);
4179
                unlock_user(p, arg1, sizeof(target_sigset_t));
4180
            }
4181
        }
4182
        break;
4183
#ifdef TARGET_NR_sigsuspend
4184
    case TARGET_NR_sigsuspend:
4185
        {
4186
            sigset_t set;
4187
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4188
                goto efault;
4189
            target_to_host_old_sigset(&set, p);
4190
            unlock_user(p, arg1, 0);
4191
            ret = get_errno(sigsuspend(&set));
4192
        }
4193
        break;
4194
#endif
4195
    case TARGET_NR_rt_sigsuspend:
4196
        {
4197
            sigset_t set;
4198
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4199
                goto efault;
4200
            target_to_host_sigset(&set, p);
4201
            unlock_user(p, arg1, 0);
4202
            ret = get_errno(sigsuspend(&set));
4203
        }
4204
        break;
4205
    case TARGET_NR_rt_sigtimedwait:
4206
        {
4207
            sigset_t set;
4208
            struct timespec uts, *puts;
4209
            siginfo_t uinfo;
4210

    
4211
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4212
                goto efault;
4213
            target_to_host_sigset(&set, p);
4214
            unlock_user(p, arg1, 0);
4215
            if (arg3) {
4216
                puts = &uts;
4217
                target_to_host_timespec(puts, arg3);
4218
            } else {
4219
                puts = NULL;
4220
            }
4221
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4222
            if (!is_error(ret) && arg2) {
4223
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4224
                    goto efault;
4225
                host_to_target_siginfo(p, &uinfo);
4226
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4227
            }
4228
        }
4229
        break;
4230
    case TARGET_NR_rt_sigqueueinfo:
4231
        {
4232
            siginfo_t uinfo;
4233
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4234
                goto efault;
4235
            target_to_host_siginfo(&uinfo, p);
4236
            unlock_user(p, arg1, 0);
4237
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4238
        }
4239
        break;
4240
#ifdef TARGET_NR_sigreturn
4241
    case TARGET_NR_sigreturn:
4242
        /* NOTE: ret is eax, so not transcoding must be done */
4243
        ret = do_sigreturn(cpu_env);
4244
        break;
4245
#endif
4246
    case TARGET_NR_rt_sigreturn:
4247
        /* NOTE: ret is eax, so not transcoding must be done */
4248
        ret = do_rt_sigreturn(cpu_env);
4249
        break;
4250
    case TARGET_NR_sethostname:
4251
        if (!(p = lock_user_string(arg1)))
4252
            goto efault;
4253
        ret = get_errno(sethostname(p, arg2));
4254
        unlock_user(p, arg1, 0);
4255
        break;
4256
    case TARGET_NR_setrlimit:
4257
        {
4258
            /* XXX: convert resource ? */
4259
            int resource = arg1;
4260
            struct target_rlimit *target_rlim;
4261
            struct rlimit rlim;
4262
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4263
                goto efault;
4264
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4265
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4266
            unlock_user_struct(target_rlim, arg2, 0);
4267
            ret = get_errno(setrlimit(resource, &rlim));
4268
        }
4269
        break;
4270
    case TARGET_NR_getrlimit:
4271
        {
4272
            /* XXX: convert resource ? */
4273
            int resource = arg1;
4274
            struct target_rlimit *target_rlim;
4275
            struct rlimit rlim;
4276

    
4277
            ret = get_errno(getrlimit(resource, &rlim));
4278
            if (!is_error(ret)) {
4279
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4280
                    goto efault;
4281
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4282
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4283
                unlock_user_struct(target_rlim, arg2, 1);
4284
            }
4285
        }
4286
        break;
4287
    case TARGET_NR_getrusage:
4288
        {
4289
            struct rusage rusage;
4290
            ret = get_errno(getrusage(arg1, &rusage));
4291
            if (!is_error(ret)) {
4292
                host_to_target_rusage(arg2, &rusage);
4293
            }
4294
        }
4295
        break;
4296
    case TARGET_NR_gettimeofday:
4297
        {
4298
            struct timeval tv;
4299
            ret = get_errno(gettimeofday(&tv, NULL));
4300
            if (!is_error(ret)) {
4301
                if (copy_to_user_timeval(arg1, &tv))
4302
                    goto efault;
4303
            }
4304
        }
4305
        break;
4306
    case TARGET_NR_settimeofday:
4307
        {
4308
            struct timeval tv;
4309
            if (copy_from_user_timeval(&tv, arg1))
4310
                goto efault;
4311
            ret = get_errno(settimeofday(&tv, NULL));
4312
        }
4313
        break;
4314
#ifdef TARGET_NR_select
4315
    case TARGET_NR_select:
4316
        {
4317
            struct target_sel_arg_struct *sel;
4318
            abi_ulong inp, outp, exp, tvp;
4319
            long nsel;
4320

    
4321
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4322
                goto efault;
4323
            nsel = tswapl(sel->n);
4324
            inp = tswapl(sel->inp);
4325
            outp = tswapl(sel->outp);
4326
            exp = tswapl(sel->exp);
4327
            tvp = tswapl(sel->tvp);
4328
            unlock_user_struct(sel, arg1, 0);
4329
            ret = do_select(nsel, inp, outp, exp, tvp);
4330
        }
4331
        break;
4332
#endif
4333
    case TARGET_NR_symlink:
4334
        {
4335
            void *p2;
4336
            p = lock_user_string(arg1);
4337
            p2 = lock_user_string(arg2);
4338
            if (!p || !p2)
4339
                ret = -TARGET_EFAULT;
4340
            else
4341
                ret = get_errno(symlink(p, p2));
4342
            unlock_user(p2, arg2, 0);
4343
            unlock_user(p, arg1, 0);
4344
        }
4345
        break;
4346
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4347
    case TARGET_NR_symlinkat:
4348
        {
4349
            void *p2;
4350
            p  = lock_user_string(arg1);
4351
            p2 = lock_user_string(arg3);
4352
            if (!p || !p2)
4353
                ret = -TARGET_EFAULT;
4354
            else
4355
                ret = get_errno(sys_symlinkat(p, arg2, p2));
4356
            unlock_user(p2, arg3, 0);
4357
            unlock_user(p, arg1, 0);
4358
        }
4359
        break;
4360
#endif
4361
#ifdef TARGET_NR_oldlstat
4362
    case TARGET_NR_oldlstat:
4363
        goto unimplemented;
4364
#endif
4365
    case TARGET_NR_readlink:
4366
        {
4367
            void *p2;
4368
            p = lock_user_string(arg1);
4369
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4370
            if (!p || !p2)
4371
                ret = -TARGET_EFAULT;
4372
            else
4373
                ret = get_errno(readlink(path(p), p2, arg3));
4374
            unlock_user(p2, arg2, ret);
4375
            unlock_user(p, arg1, 0);
4376
        }
4377
        break;
4378
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4379
    case TARGET_NR_readlinkat:
4380
        {
4381
            void *p2;
4382
            p  = lock_user_string(arg2);
4383
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4384
            if (!p || !p2)
4385
                ret = -TARGET_EFAULT;
4386
            else
4387
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4388
            unlock_user(p2, arg3, ret);
4389
            unlock_user(p, arg2, 0);
4390
        }
4391
        break;
4392
#endif
4393
#ifdef TARGET_NR_uselib
4394
    case TARGET_NR_uselib:
4395
        goto unimplemented;
4396
#endif
4397
#ifdef TARGET_NR_swapon
4398
    case TARGET_NR_swapon:
4399
        if (!(p = lock_user_string(arg1)))
4400
            goto efault;
4401
        ret = get_errno(swapon(p, arg2));
4402
        unlock_user(p, arg1, 0);
4403
        break;
4404
#endif
4405
    case TARGET_NR_reboot:
4406
        goto unimplemented;
4407
#ifdef TARGET_NR_readdir
4408
    case TARGET_NR_readdir:
4409
        goto unimplemented;
4410
#endif
4411
#ifdef TARGET_NR_mmap
4412
    case TARGET_NR_mmap:
4413
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4414
        {
4415
            abi_ulong *v;
4416
            abi_ulong v1, v2, v3, v4, v5, v6;
4417
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4418
                goto efault;
4419
            v1 = tswapl(v[0]);
4420
            v2 = tswapl(v[1]);
4421
            v3 = tswapl(v[2]);
4422
            v4 = tswapl(v[3]);
4423
            v5 = tswapl(v[4]);
4424
            v6 = tswapl(v[5]);
4425
            unlock_user(v, arg1, 0);
4426
            ret = get_errno(target_mmap(v1, v2, v3,
4427
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
4428
                                        v5, v6));
4429
        }
4430
#else
4431
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4432
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4433
                                    arg5,
4434
                                    arg6));
4435
#endif
4436
        break;
4437
#endif
4438
#ifdef TARGET_NR_mmap2
4439
    case TARGET_NR_mmap2:
4440
#ifndef MMAP_SHIFT
4441
#define MMAP_SHIFT 12
4442
#endif
4443
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4444
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4445
                                    arg5,
4446
                                    arg6 << MMAP_SHIFT));
4447
        break;
4448
#endif
4449
    case TARGET_NR_munmap:
4450
        ret = get_errno(target_munmap(arg1, arg2));
4451
        break;
4452
    case TARGET_NR_mprotect:
4453
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
4454
        break;
4455
#ifdef TARGET_NR_mremap
4456
    case TARGET_NR_mremap:
4457
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4458
        break;
4459
#endif
4460
        /* ??? msync/mlock/munlock are broken for softmmu.  */
4461
#ifdef TARGET_NR_msync
4462
    case TARGET_NR_msync:
4463
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
4464
        break;
4465
#endif
4466
#ifdef TARGET_NR_mlock
4467
    case TARGET_NR_mlock:
4468
        ret = get_errno(mlock(g2h(arg1), arg2));
4469
        break;
4470
#endif
4471
#ifdef TARGET_NR_munlock
4472
    case TARGET_NR_munlock:
4473
        ret = get_errno(munlock(g2h(arg1), arg2));
4474
        break;
4475
#endif
4476
#ifdef TARGET_NR_mlockall
4477
    case TARGET_NR_mlockall:
4478
        ret = get_errno(mlockall(arg1));
4479
        break;
4480
#endif
4481
#ifdef TARGET_NR_munlockall
4482
    case TARGET_NR_munlockall:
4483
        ret = get_errno(munlockall());
4484
        break;
4485
#endif
4486
    case TARGET_NR_truncate:
4487
        if (!(p = lock_user_string(arg1)))
4488
            goto efault;
4489
        ret = get_errno(truncate(p, arg2));
4490
        unlock_user(p, arg1, 0);
4491
        break;
4492
    case TARGET_NR_ftruncate:
4493
        ret = get_errno(ftruncate(arg1, arg2));
4494
        break;
4495
    case TARGET_NR_fchmod:
4496
        ret = get_errno(fchmod(arg1, arg2));
4497
        break;
4498
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4499
    case TARGET_NR_fchmodat:
4500
        if (!(p = lock_user_string(arg2)))
4501
            goto efault;
4502
        ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4503
        unlock_user(p, arg2, 0);
4504
        break;
4505
#endif
4506
    case TARGET_NR_getpriority:
4507
        /* libc does special remapping of the return value of
4508
         * sys_getpriority() so it's just easiest to call
4509
         * sys_getpriority() directly rather than through libc. */
4510
        ret = sys_getpriority(arg1, arg2);
4511
        break;
4512
    case TARGET_NR_setpriority:
4513
        ret = get_errno(setpriority(arg1, arg2, arg3));
4514
        break;
4515
#ifdef TARGET_NR_profil
4516
    case TARGET_NR_profil:
4517
        goto unimplemented;
4518
#endif
4519
    case TARGET_NR_statfs:
4520
        if (!(p = lock_user_string(arg1)))
4521
            goto efault;
4522
        ret = get_errno(statfs(path(p), &stfs));
4523
        unlock_user(p, arg1, 0);
4524
    convert_statfs:
4525
        if (!is_error(ret)) {
4526
            struct target_statfs *target_stfs;
4527

    
4528
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4529
                goto efault;
4530
            __put_user(stfs.f_type, &target_stfs->f_type);
4531
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4532
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4533
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4534
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4535
            __put_user(stfs.f_files, &target_stfs->f_files);
4536
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4537
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4538
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4539
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4540
            unlock_user_struct(target_stfs, arg2, 1);
4541
        }
4542
        break;
4543
    case TARGET_NR_fstatfs:
4544
        ret = get_errno(fstatfs(arg1, &stfs));
4545
        goto convert_statfs;
4546
#ifdef TARGET_NR_statfs64
4547
    case TARGET_NR_statfs64:
4548
        if (!(p = lock_user_string(arg1)))
4549
            goto efault;
4550
        ret = get_errno(statfs(path(p), &stfs));
4551
        unlock_user(p, arg1, 0);
4552
    convert_statfs64:
4553
        if (!is_error(ret)) {
4554
            struct target_statfs64 *target_stfs;
4555

    
4556
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4557
                goto efault;
4558
            __put_user(stfs.f_type, &target_stfs->f_type);
4559
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4560
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4561
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4562
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4563
            __put_user(stfs.f_files, &target_stfs->f_files);
4564
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4565
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4566
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4567
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4568
            unlock_user_struct(target_stfs, arg3, 1);
4569
        }
4570
        break;
4571
    case TARGET_NR_fstatfs64:
4572
        ret = get_errno(fstatfs(arg1, &stfs));
4573
        goto convert_statfs64;
4574
#endif
4575
#ifdef TARGET_NR_ioperm
4576
    case TARGET_NR_ioperm:
4577
        goto unimplemented;
4578
#endif
4579
#ifdef TARGET_NR_socketcall
4580
    case TARGET_NR_socketcall:
4581
        ret = do_socketcall(arg1, arg2);
4582
        break;
4583
#endif
4584
#ifdef TARGET_NR_accept
4585
    case TARGET_NR_accept:
4586
        ret = do_accept(arg1, arg2, arg3);
4587
        break;
4588
#endif
4589
#ifdef TARGET_NR_bind
4590
    case TARGET_NR_bind:
4591
        ret = do_bind(arg1, arg2, arg3);
4592
        break;
4593
#endif
4594
#ifdef TARGET_NR_connect
4595
    case TARGET_NR_connect:
4596
        ret = do_connect(arg1, arg2, arg3);
4597
        break;
4598
#endif
4599
#ifdef TARGET_NR_getpeername
4600
    case TARGET_NR_getpeername:
4601
        ret = do_getpeername(arg1, arg2, arg3);
4602
        break;
4603
#endif
4604
#ifdef TARGET_NR_getsockname
4605
    case TARGET_NR_getsockname:
4606
        ret = do_getsockname(arg1, arg2, arg3);
4607
        break;
4608
#endif
4609
#ifdef TARGET_NR_getsockopt
4610
    case TARGET_NR_getsockopt:
4611
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4612
        break;
4613
#endif
4614
#ifdef TARGET_NR_listen
4615
    case TARGET_NR_listen:
4616
        ret = get_errno(listen(arg1, arg2));
4617
        break;
4618
#endif
4619
#ifdef TARGET_NR_recv
4620
    case TARGET_NR_recv:
4621
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4622
        break;
4623
#endif
4624
#ifdef TARGET_NR_recvfrom
4625
    case TARGET_NR_recvfrom:
4626
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4627
        break;
4628
#endif
4629
#ifdef TARGET_NR_recvmsg
4630
    case TARGET_NR_recvmsg:
4631
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4632
        break;
4633
#endif
4634
#ifdef TARGET_NR_send
4635
    case TARGET_NR_send:
4636
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4637
        break;
4638
#endif
4639
#ifdef TARGET_NR_sendmsg
4640
    case TARGET_NR_sendmsg:
4641
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4642
        break;
4643
#endif
4644
#ifdef TARGET_NR_sendto
4645
    case TARGET_NR_sendto:
4646
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4647
        break;
4648
#endif
4649
#ifdef TARGET_NR_shutdown
4650
    case TARGET_NR_shutdown:
4651
        ret = get_errno(shutdown(arg1, arg2));
4652
        break;
4653
#endif
4654
#ifdef TARGET_NR_socket
4655
    case TARGET_NR_socket:
4656
        ret = do_socket(arg1, arg2, arg3);
4657
        break;
4658
#endif
4659
#ifdef TARGET_NR_socketpair
4660
    case TARGET_NR_socketpair:
4661
        ret = do_socketpair(arg1, arg2, arg3, arg4);
4662
        break;
4663
#endif
4664
#ifdef TARGET_NR_setsockopt
4665
    case TARGET_NR_setsockopt:
4666
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4667
        break;
4668
#endif
4669

    
4670
    case TARGET_NR_syslog:
4671
        if (!(p = lock_user_string(arg2)))
4672
            goto efault;
4673
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4674
        unlock_user(p, arg2, 0);
4675
        break;
4676

    
4677
    case TARGET_NR_setitimer:
4678
        {
4679
            struct itimerval value, ovalue, *pvalue;
4680

    
4681
            if (arg2) {
4682
                pvalue = &value;
4683
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4684
                    || copy_from_user_timeval(&pvalue->it_value,
4685
                                              arg2 + sizeof(struct target_timeval)))
4686
                    goto efault;
4687
            } else {
4688
                pvalue = NULL;
4689
            }
4690
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4691
            if (!is_error(ret) && arg3) {
4692
                if (copy_to_user_timeval(arg3,
4693
                                         &ovalue.it_interval)
4694
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4695
                                            &ovalue.it_value))
4696
                    goto efault;
4697
            }
4698
        }
4699
        break;
4700
    case TARGET_NR_getitimer:
4701
        {
4702
            struct itimerval value;
4703

    
4704
            ret = get_errno(getitimer(arg1, &value));
4705
            if (!is_error(ret) && arg2) {
4706
                if (copy_to_user_timeval(arg2,
4707
                                         &value.it_interval)
4708
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4709
                                            &value.it_value))
4710
                    goto efault;
4711
            }
4712
        }
4713
        break;
4714
    case TARGET_NR_stat:
4715
        if (!(p = lock_user_string(arg1)))
4716
            goto efault;
4717
        ret = get_errno(stat(path(p), &st));
4718
        unlock_user(p, arg1, 0);
4719
        goto do_stat;
4720
    case TARGET_NR_lstat:
4721
        if (!(p = lock_user_string(arg1)))
4722
            goto efault;
4723
        ret = get_errno(lstat(path(p), &st));
4724
        unlock_user(p, arg1, 0);
4725
        goto do_stat;
4726
    case TARGET_NR_fstat:
4727
        {
4728
            ret = get_errno(fstat(arg1, &st));
4729
        do_stat:
4730
            if (!is_error(ret)) {
4731
                struct target_stat *target_st;
4732

    
4733
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4734
                    goto efault;
4735
                __put_user(st.st_dev, &target_st->st_dev);
4736
                __put_user(st.st_ino, &target_st->st_ino);
4737
                __put_user(st.st_mode, &target_st->st_mode);
4738
                __put_user(st.st_uid, &target_st->st_uid);
4739
                __put_user(st.st_gid, &target_st->st_gid);
4740
                __put_user(st.st_nlink, &target_st->st_nlink);
4741
                __put_user(st.st_rdev, &target_st->st_rdev);
4742
                __put_user(st.st_size, &target_st->st_size);
4743
                __put_user(st.st_blksize, &target_st->st_blksize);
4744
                __put_user(st.st_blocks, &target_st->st_blocks);
4745
                __put_user(st.st_atime, &target_st->target_st_atime);
4746
                __put_user(st.st_mtime, &target_st->target_st_mtime);
4747
                __put_user(st.st_ctime, &target_st->target_st_ctime);
4748
                unlock_user_struct(target_st, arg2, 1);
4749
            }
4750
        }
4751
        break;
4752
#ifdef TARGET_NR_olduname
4753
    case TARGET_NR_olduname:
4754
        goto unimplemented;
4755
#endif
4756
#ifdef TARGET_NR_iopl
4757
    case TARGET_NR_iopl:
4758
        goto unimplemented;
4759
#endif
4760
    case TARGET_NR_vhangup:
4761
        ret = get_errno(vhangup());
4762
        break;
4763
#ifdef TARGET_NR_idle
4764
    case TARGET_NR_idle:
4765
        goto unimplemented;
4766
#endif
4767
#ifdef TARGET_NR_syscall
4768
    case TARGET_NR_syscall:
4769
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4770
            break;
4771
#endif
4772
    case TARGET_NR_wait4:
4773
        {
4774
            int status;
4775
            abi_long status_ptr = arg2;
4776
            struct rusage rusage, *rusage_ptr;
4777
            abi_ulong target_rusage = arg4;
4778
            if (target_rusage)
4779
                rusage_ptr = &rusage;
4780
            else
4781
                rusage_ptr = NULL;
4782
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4783
            if (!is_error(ret)) {
4784
                if (status_ptr) {
4785
                    if (put_user_s32(status, status_ptr))
4786
                        goto efault;
4787
                }
4788
                if (target_rusage)
4789
                    host_to_target_rusage(target_rusage, &rusage);
4790
            }
4791
        }
4792
        break;
4793
#ifdef TARGET_NR_swapoff
4794
    case TARGET_NR_swapoff:
4795
        if (!(p = lock_user_string(arg1)))
4796
            goto efault;
4797
        ret = get_errno(swapoff(p));
4798
        unlock_user(p, arg1, 0);
4799
        break;
4800
#endif
4801
    case TARGET_NR_sysinfo:
4802
        {
4803
            struct target_sysinfo *target_value;
4804
            struct sysinfo value;
4805
            ret = get_errno(sysinfo(&value));
4806
            if (!is_error(ret) && arg1)
4807
            {
4808
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4809
                    goto efault;
4810
                __put_user(value.uptime, &target_value->uptime);
4811
                __put_user(value.loads[0], &target_value->loads[0]);
4812
                __put_user(value.loads[1], &target_value->loads[1]);
4813
                __put_user(value.loads[2], &target_value->loads[2]);
4814
                __put_user(value.totalram, &target_value->totalram);
4815
                __put_user(value.freeram, &target_value->freeram);
4816
                __put_user(value.sharedram, &target_value->sharedram);
4817
                __put_user(value.bufferram, &target_value->bufferram);
4818
                __put_user(value.totalswap, &target_value->totalswap);
4819
                __put_user(value.freeswap, &target_value->freeswap);
4820
                __put_user(value.procs, &target_value->procs);
4821
                __put_user(value.totalhigh, &target_value->totalhigh);
4822
                __put_user(value.freehigh, &target_value->freehigh);
4823
                __put_user(value.mem_unit, &target_value->mem_unit);
4824
                unlock_user_struct(target_value, arg1, 1);
4825
            }
4826
        }
4827
        break;
4828
#ifdef TARGET_NR_ipc
4829
    case TARGET_NR_ipc:
4830
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4831
        break;
4832
#endif
4833

    
4834
#ifdef TARGET_NR_msgctl
4835
    case TARGET_NR_msgctl:
4836
        ret = do_msgctl(arg1, arg2, arg3);
4837
        break;
4838
#endif
4839
#ifdef TARGET_NR_msgget
4840
    case TARGET_NR_msgget:
4841
        ret = get_errno(msgget(arg1, arg2));
4842
        break;
4843
#endif
4844
#ifdef TARGET_NR_msgrcv
4845
    case TARGET_NR_msgrcv:
4846
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
4847
        break;
4848
#endif
4849
#ifdef TARGET_NR_msgsnd
4850
    case TARGET_NR_msgsnd:
4851
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
4852
        break;
4853
#endif
4854
    case TARGET_NR_fsync:
4855
        ret = get_errno(fsync(arg1));
4856
        break;
4857
    case TARGET_NR_clone:
4858
#if defined(TARGET_SH4)
4859
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
4860
#else
4861
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4862
#endif
4863
        break;
4864
#ifdef __NR_exit_group
4865
        /* new thread calls */
4866
    case TARGET_NR_exit_group:
4867
        gdb_exit(cpu_env, arg1);
4868
        ret = get_errno(exit_group(arg1));
4869
        break;
4870
#endif
4871
    case TARGET_NR_setdomainname:
4872
        if (!(p = lock_user_string(arg1)))
4873
            goto efault;
4874
        ret = get_errno(setdomainname(p, arg2));
4875
        unlock_user(p, arg1, 0);
4876
        break;
4877
    case TARGET_NR_uname:
4878
        /* no need to transcode because we use the linux syscall */
4879
        {
4880
            struct new_utsname * buf;
4881

    
4882
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4883
                goto efault;
4884
            ret = get_errno(sys_uname(buf));
4885
            if (!is_error(ret)) {
4886
                /* Overrite the native machine name with whatever is being
4887
                   emulated. */
4888
                strcpy (buf->machine, UNAME_MACHINE);
4889
                /* Allow the user to override the reported release.  */
4890
                if (qemu_uname_release && *qemu_uname_release)
4891
                  strcpy (buf->release, qemu_uname_release);
4892
            }
4893
            unlock_user_struct(buf, arg1, 1);
4894
        }
4895
        break;
4896
#ifdef TARGET_I386
4897
    case TARGET_NR_modify_ldt:
4898
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4899
        break;
4900
#if !defined(TARGET_X86_64)
4901
    case TARGET_NR_vm86old:
4902
        goto unimplemented;
4903
    case TARGET_NR_vm86:
4904
        ret = do_vm86(cpu_env, arg1, arg2);
4905
        break;
4906
#endif
4907
#endif
4908
    case TARGET_NR_adjtimex:
4909
        goto unimplemented;
4910
#ifdef TARGET_NR_create_module
4911
    case TARGET_NR_create_module:
4912
#endif
4913
    case TARGET_NR_init_module:
4914
    case TARGET_NR_delete_module:
4915
#ifdef TARGET_NR_get_kernel_syms
4916
    case TARGET_NR_get_kernel_syms:
4917
#endif
4918
        goto unimplemented;
4919
    case TARGET_NR_quotactl:
4920
        goto unimplemented;
4921
    case TARGET_NR_getpgid:
4922
        ret = get_errno(getpgid(arg1));
4923
        break;
4924
    case TARGET_NR_fchdir:
4925
        ret = get_errno(fchdir(arg1));
4926
        break;
4927
#ifdef TARGET_NR_bdflush /* not on x86_64 */
4928
    case TARGET_NR_bdflush:
4929
        goto unimplemented;
4930
#endif
4931
#ifdef TARGET_NR_sysfs
4932
    case TARGET_NR_sysfs:
4933
        goto unimplemented;
4934
#endif
4935
    case TARGET_NR_personality:
4936
        ret = get_errno(personality(arg1));
4937
        break;
4938
#ifdef TARGET_NR_afs_syscall
4939
    case TARGET_NR_afs_syscall:
4940
        goto unimplemented;
4941
#endif
4942
#ifdef TARGET_NR__llseek /* Not on alpha */
4943
    case TARGET_NR__llseek:
4944
        {
4945
#if defined (__x86_64__)
4946
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4947
            if (put_user_s64(ret, arg4))
4948
                goto efault;
4949
#else
4950
            int64_t res;
4951
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4952
            if (put_user_s64(res, arg4))
4953
                goto efault;
4954
#endif
4955
        }
4956
        break;
4957
#endif
4958
    case TARGET_NR_getdents:
4959
#if TARGET_ABI_BITS != 32
4960
        goto unimplemented;
4961
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4962
        {
4963
            struct target_dirent *target_dirp;
4964
            struct linux_dirent *dirp;
4965
            abi_long count = arg3;
4966

    
4967
            dirp = malloc(count);
4968
            if (!dirp) {
4969
                ret = -TARGET_ENOMEM;
4970
                goto fail;
4971
            }
4972

    
4973
            ret = get_errno(sys_getdents(arg1, dirp, count));
4974
            if (!is_error(ret)) {
4975
                struct linux_dirent *de;
4976
                struct target_dirent *tde;
4977
                int len = ret;
4978
                int reclen, treclen;
4979
                int count1, tnamelen;
4980

    
4981
                count1 = 0;
4982
                de = dirp;
4983
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4984
                    goto efault;
4985
                tde = target_dirp;
4986
                while (len > 0) {
4987
                    reclen = de->d_reclen;
4988
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4989
                    tde->d_reclen = tswap16(treclen);
4990
                    tde->d_ino = tswapl(de->d_ino);
4991
                    tde->d_off = tswapl(de->d_off);
4992
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4993
                    if (tnamelen > 256)
4994
                        tnamelen = 256;
4995
                    /* XXX: may not be correct */
4996
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
4997
                    de = (struct linux_dirent *)((char *)de + reclen);
4998
                    len -= reclen;
4999
                    tde = (struct target_dirent *)((char *)tde + treclen);
5000
                    count1 += treclen;
5001
                }
5002
                ret = count1;
5003
                unlock_user(target_dirp, arg2, ret);
5004
            }
5005
            free(dirp);
5006
        }
5007
#else
5008
        {
5009
            struct linux_dirent *dirp;
5010
            abi_long count = arg3;
5011

    
5012
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5013
                goto efault;
5014
            ret = get_errno(sys_getdents(arg1, dirp, count));
5015
            if (!is_error(ret)) {
5016
                struct linux_dirent *de;
5017
                int len = ret;
5018
                int reclen;
5019
                de = dirp;
5020
                while (len > 0) {
5021
                    reclen = de->d_reclen;
5022
                    if (reclen > len)
5023
                        break;
5024
                    de->d_reclen = tswap16(reclen);
5025
                    tswapls(&de->d_ino);
5026
                    tswapls(&de->d_off);
5027
                    de = (struct linux_dirent *)((char *)de + reclen);
5028
                    len -= reclen;
5029
                }
5030
            }
5031
            unlock_user(dirp, arg2, ret);
5032
        }
5033
#endif
5034
        break;
5035
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5036
    case TARGET_NR_getdents64:
5037
        {
5038
            struct linux_dirent64 *dirp;
5039
            abi_long count = arg3;
5040
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5041
                goto efault;
5042
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5043
            if (!is_error(ret)) {
5044
                struct linux_dirent64 *de;
5045
                int len = ret;
5046
                int reclen;
5047
                de = dirp;
5048
                while (len > 0) {
5049
                    reclen = de->d_reclen;
5050
                    if (reclen > len)
5051
                        break;
5052
                    de->d_reclen = tswap16(reclen);
5053
                    tswap64s((uint64_t *)&de->d_ino);
5054
                    tswap64s((uint64_t *)&de->d_off);
5055
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5056
                    len -= reclen;
5057
                }
5058
            }
5059
            unlock_user(dirp, arg2, ret);
5060
        }
5061
        break;
5062
#endif /* TARGET_NR_getdents64 */
5063
#ifdef TARGET_NR__newselect
5064
    case TARGET_NR__newselect:
5065
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5066
        break;
5067
#endif
5068
#ifdef TARGET_NR_poll
5069
    case TARGET_NR_poll:
5070
        {
5071
            struct target_pollfd *target_pfd;
5072
            unsigned int nfds = arg2;
5073
            int timeout = arg3;
5074
            struct pollfd *pfd;
5075
            unsigned int i;
5076

    
5077
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5078
            if (!target_pfd)
5079
                goto efault;
5080
            pfd = alloca(sizeof(struct pollfd) * nfds);
5081
            for(i = 0; i < nfds; i++) {
5082
                pfd[i].fd = tswap32(target_pfd[i].fd);
5083
                pfd[i].events = tswap16(target_pfd[i].events);
5084
            }
5085
            ret = get_errno(poll(pfd, nfds, timeout));
5086
            if (!is_error(ret)) {
5087
                for(i = 0; i < nfds; i++) {
5088
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5089
                }
5090
                ret += nfds * (sizeof(struct target_pollfd)
5091
                               - sizeof(struct pollfd));
5092
            }
5093
            unlock_user(target_pfd, arg1, ret);
5094
        }
5095
        break;
5096
#endif
5097
    case TARGET_NR_flock:
5098
        /* NOTE: the flock constant seems to be the same for every
5099
           Linux platform */
5100
        ret = get_errno(flock(arg1, arg2));
5101
        break;
5102
    case TARGET_NR_readv:
5103
        {
5104
            int count = arg3;
5105
            struct iovec *vec;
5106

    
5107
            vec = alloca(count * sizeof(struct iovec));
5108
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5109
                goto efault;
5110
            ret = get_errno(readv(arg1, vec, count));
5111
            unlock_iovec(vec, arg2, count, 1);
5112
        }
5113
        break;
5114
    case TARGET_NR_writev:
5115
        {
5116
            int count = arg3;
5117
            struct iovec *vec;
5118

    
5119
            vec = alloca(count * sizeof(struct iovec));
5120
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5121
                goto efault;
5122
            ret = get_errno(writev(arg1, vec, count));
5123
            unlock_iovec(vec, arg2, count, 0);
5124
        }
5125
        break;
5126
    case TARGET_NR_getsid:
5127
        ret = get_errno(getsid(arg1));
5128
        break;
5129
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5130
    case TARGET_NR_fdatasync:
5131
        ret = get_errno(fdatasync(arg1));
5132
        break;
5133
#endif
5134
    case TARGET_NR__sysctl:
5135
        /* We don't implement this, but ENOTDIR is always a safe
5136
           return value. */
5137
        ret = -TARGET_ENOTDIR;
5138
        break;
5139
    case TARGET_NR_sched_setparam:
5140
        {
5141
            struct sched_param *target_schp;
5142
            struct sched_param schp;
5143

    
5144
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5145
                goto efault;
5146
            schp.sched_priority = tswap32(target_schp->sched_priority);
5147
            unlock_user_struct(target_schp, arg2, 0);
5148
            ret = get_errno(sched_setparam(arg1, &schp));
5149
        }
5150
        break;
5151
    case TARGET_NR_sched_getparam:
5152
        {
5153
            struct sched_param *target_schp;
5154
            struct sched_param schp;
5155
            ret = get_errno(sched_getparam(arg1, &schp));
5156
            if (!is_error(ret)) {
5157
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5158
                    goto efault;
5159
                target_schp->sched_priority = tswap32(schp.sched_priority);
5160
                unlock_user_struct(target_schp, arg2, 1);
5161
            }
5162
        }
5163
        break;
5164
    case TARGET_NR_sched_setscheduler:
5165
        {
5166
            struct sched_param *target_schp;
5167
            struct sched_param schp;
5168
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5169
                goto efault;
5170
            schp.sched_priority = tswap32(target_schp->sched_priority);
5171
            unlock_user_struct(target_schp, arg3, 0);
5172
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5173
        }
5174
        break;
5175
    case TARGET_NR_sched_getscheduler:
5176
        ret = get_errno(sched_getscheduler(arg1));
5177
        break;
5178
    case TARGET_NR_sched_yield:
5179
        ret = get_errno(sched_yield());
5180
        break;
5181
    case TARGET_NR_sched_get_priority_max:
5182
        ret = get_errno(sched_get_priority_max(arg1));
5183
        break;
5184
    case TARGET_NR_sched_get_priority_min:
5185
        ret = get_errno(sched_get_priority_min(arg1));
5186
        break;
5187
    case TARGET_NR_sched_rr_get_interval:
5188
        {
5189
            struct timespec ts;
5190
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
5191
            if (!is_error(ret)) {
5192
                host_to_target_timespec(arg2, &ts);
5193
            }
5194
        }
5195
        break;
5196
    case TARGET_NR_nanosleep:
5197
        {
5198
            struct timespec req, rem;
5199
            target_to_host_timespec(&req, arg1);
5200
            ret = get_errno(nanosleep(&req, &rem));
5201
            if (is_error(ret) && arg2) {
5202
                host_to_target_timespec(arg2, &rem);
5203
            }
5204
        }
5205
        break;
5206
#ifdef TARGET_NR_query_module
5207
    case TARGET_NR_query_module:
5208
        goto unimplemented;
5209
#endif
5210
#ifdef TARGET_NR_nfsservctl
5211
    case TARGET_NR_nfsservctl:
5212
        goto unimplemented;
5213
#endif
5214
    case TARGET_NR_prctl:
5215
        switch (arg1)
5216
            {
5217
            case PR_GET_PDEATHSIG:
5218
                {
5219
                    int deathsig;
5220
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5221
                    if (!is_error(ret) && arg2
5222
                        && put_user_ual(deathsig, arg2))
5223
                        goto efault;
5224
                }
5225
                break;
5226
            default:
5227
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5228
                break;
5229
            }
5230
        break;
5231
#ifdef TARGET_NR_arch_prctl
5232
    case TARGET_NR_arch_prctl:
5233
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
5234
        ret = do_arch_prctl(cpu_env, arg1, arg2);
5235
        break;
5236
#else
5237
        goto unimplemented;
5238
#endif
5239
#endif
5240
#ifdef TARGET_NR_pread
5241
    case TARGET_NR_pread:
5242
#ifdef TARGET_ARM
5243
        if (((CPUARMState *)cpu_env)->eabi)
5244
            arg4 = arg5;
5245
#endif
5246
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5247
            goto efault;
5248
        ret = get_errno(pread(arg1, p, arg3, arg4));
5249
        unlock_user(p, arg2, ret);
5250
        break;
5251
    case TARGET_NR_pwrite:
5252
#ifdef TARGET_ARM
5253
        if (((CPUARMState *)cpu_env)->eabi)
5254
            arg4 = arg5;
5255
#endif
5256
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5257
            goto efault;
5258
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
5259
        unlock_user(p, arg2, 0);
5260
        break;
5261
#endif
5262
#ifdef TARGET_NR_pread64
5263
    case TARGET_NR_pread64:
5264
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5265
            goto efault;
5266
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5267
        unlock_user(p, arg2, ret);
5268
        break;
5269
    case TARGET_NR_pwrite64:
5270
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5271
            goto efault;
5272
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5273
        unlock_user(p, arg2, 0);
5274
        break;
5275
#endif
5276
    case TARGET_NR_getcwd:
5277
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5278
            goto efault;
5279
        ret = get_errno(sys_getcwd1(p, arg2));
5280
        unlock_user(p, arg1, ret);
5281
        break;
5282
    case TARGET_NR_capget:
5283
        goto unimplemented;
5284
    case TARGET_NR_capset:
5285
        goto unimplemented;
5286
    case TARGET_NR_sigaltstack:
5287
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5288
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5289
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5290
        break;
5291
#else
5292
        goto unimplemented;
5293
#endif
5294
    case TARGET_NR_sendfile:
5295
        goto unimplemented;
5296
#ifdef TARGET_NR_getpmsg
5297
    case TARGET_NR_getpmsg:
5298
        goto unimplemented;
5299
#endif
5300
#ifdef TARGET_NR_putpmsg
5301
    case TARGET_NR_putpmsg:
5302
        goto unimplemented;
5303
#endif
5304
#ifdef TARGET_NR_vfork
5305
    case TARGET_NR_vfork:
5306
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5307
                        0, 0, 0, 0));
5308
        break;
5309
#endif
5310
#ifdef TARGET_NR_ugetrlimit
5311
    case TARGET_NR_ugetrlimit:
5312
    {
5313
        struct rlimit rlim;
5314
        ret = get_errno(getrlimit(arg1, &rlim));
5315
        if (!is_error(ret)) {
5316
            struct target_rlimit *target_rlim;
5317
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5318
                goto efault;
5319
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5320
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
5321
            unlock_user_struct(target_rlim, arg2, 1);
5322
        }
5323
        break;
5324
    }
5325
#endif
5326
#ifdef TARGET_NR_truncate64
5327
    case TARGET_NR_truncate64:
5328
        if (!(p = lock_user_string(arg1)))
5329
            goto efault;
5330
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5331
        unlock_user(p, arg1, 0);
5332
        break;
5333
#endif
5334
#ifdef TARGET_NR_ftruncate64
5335
    case TARGET_NR_ftruncate64:
5336
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5337
        break;
5338
#endif
5339
#ifdef TARGET_NR_stat64
5340
    case TARGET_NR_stat64:
5341
        if (!(p = lock_user_string(arg1)))
5342
            goto efault;
5343
        ret = get_errno(stat(path(p), &st));
5344
        unlock_user(p, arg1, 0);
5345
        if (!is_error(ret))
5346
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5347
        break;
5348
#endif
5349
#ifdef TARGET_NR_lstat64
5350
    case TARGET_NR_lstat64:
5351
        if (!(p = lock_user_string(arg1)))
5352
            goto efault;
5353
        ret = get_errno(lstat(path(p), &st));
5354
        unlock_user(p, arg1, 0);
5355
        if (!is_error(ret))
5356
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5357
        break;
5358
#endif
5359
#ifdef TARGET_NR_fstat64
5360
    case TARGET_NR_fstat64:
5361
        ret = get_errno(fstat(arg1, &st));
5362
        if (!is_error(ret))
5363
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5364
        break;
5365
#endif
5366
#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
5367
    case TARGET_NR_fstatat64:
5368
        if (!(p = lock_user_string(arg2)))
5369
            goto efault;
5370
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5371
        if (!is_error(ret))
5372
            ret = host_to_target_stat64(cpu_env, arg3, &st);
5373
        break;
5374
#endif
5375
#ifdef USE_UID16
5376
    case TARGET_NR_lchown:
5377
        if (!(p = lock_user_string(arg1)))
5378
            goto efault;
5379
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5380
        unlock_user(p, arg1, 0);
5381
        break;
5382
    case TARGET_NR_getuid:
5383
        ret = get_errno(high2lowuid(getuid()));
5384
        break;
5385
    case TARGET_NR_getgid:
5386
        ret = get_errno(high2lowgid(getgid()));
5387
        break;
5388
    case TARGET_NR_geteuid:
5389
        ret = get_errno(high2lowuid(geteuid()));
5390
        break;
5391
    case TARGET_NR_getegid:
5392
        ret = get_errno(high2lowgid(getegid()));
5393
        break;
5394
    case TARGET_NR_setreuid:
5395
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5396
        break;
5397
    case TARGET_NR_setregid:
5398
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5399
        break;
5400
    case TARGET_NR_getgroups:
5401
        {
5402
            int gidsetsize = arg1;
5403
            uint16_t *target_grouplist;
5404
            gid_t *grouplist;
5405
            int i;
5406

    
5407
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5408
            ret = get_errno(getgroups(gidsetsize, grouplist));
5409
            if (gidsetsize == 0)
5410
                break;
5411
            if (!is_error(ret)) {
5412
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5413
                if (!target_grouplist)
5414
                    goto efault;
5415
                for(i = 0;i < ret; i++)
5416
                    target_grouplist[i] = tswap16(grouplist[i]);
5417
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5418
            }
5419
        }
5420
        break;
5421
    case TARGET_NR_setgroups:
5422
        {
5423
            int gidsetsize = arg1;
5424
            uint16_t *target_grouplist;
5425
            gid_t *grouplist;
5426
            int i;
5427

    
5428
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5429
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5430
            if (!target_grouplist) {
5431
                ret = -TARGET_EFAULT;
5432
                goto fail;
5433
            }
5434
            for(i = 0;i < gidsetsize; i++)
5435
                grouplist[i] = tswap16(target_grouplist[i]);
5436
            unlock_user(target_grouplist, arg2, 0);
5437
            ret = get_errno(setgroups(gidsetsize, grouplist));
5438
        }
5439
        break;
5440
    case TARGET_NR_fchown:
5441
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5442
        break;
5443
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5444
    case TARGET_NR_fchownat:
5445
        if (!(p = lock_user_string(arg2))) 
5446
            goto efault;
5447
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5448
        unlock_user(p, arg2, 0);
5449
        break;
5450
#endif
5451
#ifdef TARGET_NR_setresuid
5452
    case TARGET_NR_setresuid:
5453
        ret = get_errno(setresuid(low2highuid(arg1),
5454
                                  low2highuid(arg2),
5455
                                  low2highuid(arg3)));
5456
        break;
5457
#endif
5458
#ifdef TARGET_NR_getresuid
5459
    case TARGET_NR_getresuid:
5460
        {
5461
            uid_t ruid, euid, suid;
5462
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5463
            if (!is_error(ret)) {
5464
                if (put_user_u16(high2lowuid(ruid), arg1)
5465
                    || put_user_u16(high2lowuid(euid), arg2)
5466
                    || put_user_u16(high2lowuid(suid), arg3))
5467
                    goto efault;
5468
            }
5469
        }
5470
        break;
5471
#endif
5472
#ifdef TARGET_NR_getresgid
5473
    case TARGET_NR_setresgid:
5474
        ret = get_errno(setresgid(low2highgid(arg1),
5475
                                  low2highgid(arg2),
5476
                                  low2highgid(arg3)));
5477
        break;
5478
#endif
5479
#ifdef TARGET_NR_getresgid
5480
    case TARGET_NR_getresgid:
5481
        {
5482
            gid_t rgid, egid, sgid;
5483
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5484
            if (!is_error(ret)) {
5485
                if (put_user_u16(high2lowgid(rgid), arg1)
5486
                    || put_user_u16(high2lowgid(egid), arg2)
5487
                    || put_user_u16(high2lowgid(sgid), arg3))
5488
                    goto efault;
5489
            }
5490
        }
5491
        break;
5492
#endif
5493
    case TARGET_NR_chown:
5494
        if (!(p = lock_user_string(arg1)))
5495
            goto efault;
5496
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5497
        unlock_user(p, arg1, 0);
5498
        break;
5499
    case TARGET_NR_setuid:
5500
        ret = get_errno(setuid(low2highuid(arg1)));
5501
        break;
5502
    case TARGET_NR_setgid:
5503
        ret = get_errno(setgid(low2highgid(arg1)));
5504
        break;
5505
    case TARGET_NR_setfsuid:
5506
        ret = get_errno(setfsuid(arg1));
5507
        break;
5508
    case TARGET_NR_setfsgid:
5509
        ret = get_errno(setfsgid(arg1));
5510
        break;
5511
#endif /* USE_UID16 */
5512

    
5513
#ifdef TARGET_NR_lchown32
5514
    case TARGET_NR_lchown32:
5515
        if (!(p = lock_user_string(arg1)))
5516
            goto efault;
5517
        ret = get_errno(lchown(p, arg2, arg3));
5518
        unlock_user(p, arg1, 0);
5519
        break;
5520
#endif
5521
#ifdef TARGET_NR_getuid32
5522
    case TARGET_NR_getuid32:
5523
        ret = get_errno(getuid());
5524
        break;
5525
#endif
5526
#ifdef TARGET_NR_getgid32
5527
    case TARGET_NR_getgid32:
5528
        ret = get_errno(getgid());
5529
        break;
5530
#endif
5531
#ifdef TARGET_NR_geteuid32
5532
    case TARGET_NR_geteuid32:
5533
        ret = get_errno(geteuid());
5534
        break;
5535
#endif
5536
#ifdef TARGET_NR_getegid32
5537
    case TARGET_NR_getegid32:
5538
        ret = get_errno(getegid());
5539
        break;
5540
#endif
5541
#ifdef TARGET_NR_setreuid32
5542
    case TARGET_NR_setreuid32:
5543
        ret = get_errno(setreuid(arg1, arg2));
5544
        break;
5545
#endif
5546
#ifdef TARGET_NR_setregid32
5547
    case TARGET_NR_setregid32:
5548
        ret = get_errno(setregid(arg1, arg2));
5549
        break;
5550
#endif
5551
#ifdef TARGET_NR_getgroups32
5552
    case TARGET_NR_getgroups32:
5553
        {
5554
            int gidsetsize = arg1;
5555
            uint32_t *target_grouplist;
5556
            gid_t *grouplist;
5557
            int i;
5558

    
5559
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5560
            ret = get_errno(getgroups(gidsetsize, grouplist));
5561
            if (gidsetsize == 0)
5562
                break;
5563
            if (!is_error(ret)) {
5564
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5565
                if (!target_grouplist) {
5566
                    ret = -TARGET_EFAULT;
5567
                    goto fail;
5568
                }
5569
                for(i = 0;i < ret; i++)
5570
                    target_grouplist[i] = tswap32(grouplist[i]);
5571
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
5572
            }
5573
        }
5574
        break;
5575
#endif
5576
#ifdef TARGET_NR_setgroups32
5577
    case TARGET_NR_setgroups32:
5578
        {
5579
            int gidsetsize = arg1;
5580
            uint32_t *target_grouplist;
5581
            gid_t *grouplist;
5582
            int i;
5583

    
5584
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5585
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5586
            if (!target_grouplist) {
5587
                ret = -TARGET_EFAULT;
5588
                goto fail;
5589
            }
5590
            for(i = 0;i < gidsetsize; i++)
5591
                grouplist[i] = tswap32(target_grouplist[i]);
5592
            unlock_user(target_grouplist, arg2, 0);
5593
            ret = get_errno(setgroups(gidsetsize, grouplist));
5594
        }
5595
        break;
5596
#endif
5597
#ifdef TARGET_NR_fchown32
5598
    case TARGET_NR_fchown32:
5599
        ret = get_errno(fchown(arg1, arg2, arg3));
5600
        break;
5601
#endif
5602
#ifdef TARGET_NR_setresuid32
5603
    case TARGET_NR_setresuid32:
5604
        ret = get_errno(setresuid(arg1, arg2, arg3));
5605
        break;
5606
#endif
5607
#ifdef TARGET_NR_getresuid32
5608
    case TARGET_NR_getresuid32:
5609
        {
5610
            uid_t ruid, euid, suid;
5611
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5612
            if (!is_error(ret)) {
5613
                if (put_user_u32(ruid, arg1)
5614
                    || put_user_u32(euid, arg2)
5615
                    || put_user_u32(suid, arg3))
5616
                    goto efault;
5617
            }
5618
        }
5619
        break;
5620
#endif
5621
#ifdef TARGET_NR_setresgid32
5622
    case TARGET_NR_setresgid32:
5623
        ret = get_errno(setresgid(arg1, arg2, arg3));
5624
        break;
5625
#endif
5626
#ifdef TARGET_NR_getresgid32
5627
    case TARGET_NR_getresgid32:
5628
        {
5629
            gid_t rgid, egid, sgid;
5630
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5631
            if (!is_error(ret)) {
5632
                if (put_user_u32(rgid, arg1)
5633
                    || put_user_u32(egid, arg2)
5634
                    || put_user_u32(sgid, arg3))
5635
                    goto efault;
5636
            }
5637
        }
5638
        break;
5639
#endif
5640
#ifdef TARGET_NR_chown32
5641
    case TARGET_NR_chown32:
5642
        if (!(p = lock_user_string(arg1)))
5643
            goto efault;
5644
        ret = get_errno(chown(p, arg2, arg3));
5645
        unlock_user(p, arg1, 0);
5646
        break;
5647
#endif
5648
#ifdef TARGET_NR_setuid32
5649
    case TARGET_NR_setuid32:
5650
        ret = get_errno(setuid(arg1));
5651
        break;
5652
#endif
5653
#ifdef TARGET_NR_setgid32
5654
    case TARGET_NR_setgid32:
5655
        ret = get_errno(setgid(arg1));
5656
        break;
5657
#endif
5658
#ifdef TARGET_NR_setfsuid32
5659
    case TARGET_NR_setfsuid32:
5660
        ret = get_errno(setfsuid(arg1));
5661
        break;
5662
#endif
5663
#ifdef TARGET_NR_setfsgid32
5664
    case TARGET_NR_setfsgid32:
5665
        ret = get_errno(setfsgid(arg1));
5666
        break;
5667
#endif
5668

    
5669
    case TARGET_NR_pivot_root:
5670
        goto unimplemented;
5671
#ifdef TARGET_NR_mincore
5672
    case TARGET_NR_mincore:
5673
        {
5674
            void *a;
5675
            ret = -TARGET_EFAULT;
5676
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5677
                goto efault;
5678
            if (!(p = lock_user_string(arg3)))
5679
                goto mincore_fail;
5680
            ret = get_errno(mincore(a, arg2, p));
5681
            unlock_user(p, arg3, ret);
5682
            mincore_fail:
5683
            unlock_user(a, arg1, 0);
5684
        }
5685
        break;
5686
#endif
5687
#ifdef TARGET_NR_arm_fadvise64_64
5688
    case TARGET_NR_arm_fadvise64_64:
5689
        {
5690
                /*
5691
                 * arm_fadvise64_64 looks like fadvise64_64 but
5692
                 * with different argument order
5693
                 */
5694
                abi_long temp;
5695
                temp = arg3;
5696
                arg3 = arg4;
5697
                arg4 = temp;
5698
        }
5699
#endif
5700
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5701
#ifdef TARGET_NR_fadvise64_64
5702
    case TARGET_NR_fadvise64_64:
5703
#endif
5704
        /* This is a hint, so ignoring and returning success is ok.  */
5705
        ret = get_errno(0);
5706
        break;
5707
#endif
5708
#ifdef TARGET_NR_madvise
5709
    case TARGET_NR_madvise:
5710
        /* A straight passthrough may not be safe because qemu sometimes
5711
           turns private flie-backed mappings into anonymous mappings.
5712
           This will break MADV_DONTNEED.
5713
           This is a hint, so ignoring and returning success is ok.  */
5714
        ret = get_errno(0);
5715
        break;
5716
#endif
5717
#if TARGET_ABI_BITS == 32
5718
    case TARGET_NR_fcntl64:
5719
    {
5720
        int cmd;
5721
        struct flock64 fl;
5722
        struct target_flock64 *target_fl;
5723
#ifdef TARGET_ARM
5724
        struct target_eabi_flock64 *target_efl;
5725
#endif
5726

    
5727
        switch(arg2){
5728
        case TARGET_F_GETLK64:
5729
            cmd = F_GETLK64;
5730
            break;
5731
        case TARGET_F_SETLK64:
5732
            cmd = F_SETLK64;
5733
            break;
5734
        case TARGET_F_SETLKW64:
5735
            cmd = F_SETLK64;
5736
            break;
5737
        default:
5738
            cmd = arg2;
5739
            break;
5740
        }
5741

    
5742
        switch(arg2) {
5743
        case TARGET_F_GETLK64:
5744
#ifdef TARGET_ARM
5745
            if (((CPUARMState *)cpu_env)->eabi) {
5746
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5747
                    goto efault;
5748
                fl.l_type = tswap16(target_efl->l_type);
5749
                fl.l_whence = tswap16(target_efl->l_whence);
5750
                fl.l_start = tswap64(target_efl->l_start);
5751
                fl.l_len = tswap64(target_efl->l_len);
5752
                fl.l_pid = tswapl(target_efl->l_pid);
5753
                unlock_user_struct(target_efl, arg3, 0);
5754
            } else
5755
#endif
5756
            {
5757
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5758
                    goto efault;
5759
                fl.l_type = tswap16(target_fl->l_type);
5760
                fl.l_whence = tswap16(target_fl->l_whence);
5761
                fl.l_start = tswap64(target_fl->l_start);
5762
                fl.l_len = tswap64(target_fl->l_len);
5763
                fl.l_pid = tswapl(target_fl->l_pid);
5764
                unlock_user_struct(target_fl, arg3, 0);
5765
            }
5766
            ret = get_errno(fcntl(arg1, cmd, &fl));
5767
            if (ret == 0) {
5768
#ifdef TARGET_ARM
5769
                if (((CPUARMState *)cpu_env)->eabi) {
5770
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
5771
                        goto efault;
5772
                    target_efl->l_type = tswap16(fl.l_type);
5773
                    target_efl->l_whence = tswap16(fl.l_whence);
5774
                    target_efl->l_start = tswap64(fl.l_start);
5775
                    target_efl->l_len = tswap64(fl.l_len);
5776
                    target_efl->l_pid = tswapl(fl.l_pid);
5777
                    unlock_user_struct(target_efl, arg3, 1);
5778
                } else
5779
#endif
5780
                {
5781
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
5782
                        goto efault;
5783
                    target_fl->l_type = tswap16(fl.l_type);
5784
                    target_fl->l_whence = tswap16(fl.l_whence);
5785
                    target_fl->l_start = tswap64(fl.l_start);
5786
                    target_fl->l_len = tswap64(fl.l_len);
5787
                    target_fl->l_pid = tswapl(fl.l_pid);
5788
                    unlock_user_struct(target_fl, arg3, 1);
5789
                }
5790
            }
5791
            break;
5792

    
5793
        case TARGET_F_SETLK64:
5794
        case TARGET_F_SETLKW64:
5795
#ifdef TARGET_ARM
5796
            if (((CPUARMState *)cpu_env)->eabi) {
5797
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5798
                    goto efault;
5799
                fl.l_type = tswap16(target_efl->l_type);
5800
                fl.l_whence = tswap16(target_efl->l_whence);
5801
                fl.l_start = tswap64(target_efl->l_start);
5802
                fl.l_len = tswap64(target_efl->l_len);
5803
                fl.l_pid = tswapl(target_efl->l_pid);
5804
                unlock_user_struct(target_efl, arg3, 0);
5805
            } else
5806
#endif
5807
            {
5808
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5809
                    goto efault;
5810
                fl.l_type = tswap16(target_fl->l_type);
5811
                fl.l_whence = tswap16(target_fl->l_whence);
5812
                fl.l_start = tswap64(target_fl->l_start);
5813
                fl.l_len = tswap64(target_fl->l_len);
5814
                fl.l_pid = tswapl(target_fl->l_pid);
5815
                unlock_user_struct(target_fl, arg3, 0);
5816
            }
5817
            ret = get_errno(fcntl(arg1, cmd, &fl));
5818
            break;
5819
        default:
5820
            ret = do_fcntl(arg1, cmd, arg3);
5821
            break;
5822
        }
5823
        break;
5824
    }
5825
#endif
5826
#ifdef TARGET_NR_cacheflush
5827
    case TARGET_NR_cacheflush:
5828
        /* self-modifying code is handled automatically, so nothing needed */
5829
        ret = 0;
5830
        break;
5831
#endif
5832
#ifdef TARGET_NR_security
5833
    case TARGET_NR_security:
5834
        goto unimplemented;
5835
#endif
5836
#ifdef TARGET_NR_getpagesize
5837
    case TARGET_NR_getpagesize:
5838
        ret = TARGET_PAGE_SIZE;
5839
        break;
5840
#endif
5841
    case TARGET_NR_gettid:
5842
        ret = get_errno(gettid());
5843
        break;
5844
#ifdef TARGET_NR_readahead
5845
    case TARGET_NR_readahead:
5846
#if TARGET_ABI_BITS == 32
5847
#ifdef TARGET_ARM
5848
        if (((CPUARMState *)cpu_env)->eabi)
5849
        {
5850
            arg2 = arg3;
5851
            arg3 = arg4;
5852
            arg4 = arg5;
5853
        }
5854
#endif
5855
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
5856
#else
5857
        ret = get_errno(readahead(arg1, arg2, arg3));
5858
#endif
5859
        break;
5860
#endif
5861
#ifdef TARGET_NR_setxattr
5862
    case TARGET_NR_setxattr:
5863
    case TARGET_NR_lsetxattr:
5864
    case TARGET_NR_fsetxattr:
5865
    case TARGET_NR_getxattr:
5866
    case TARGET_NR_lgetxattr:
5867
    case TARGET_NR_fgetxattr:
5868
    case TARGET_NR_listxattr:
5869
    case TARGET_NR_llistxattr:
5870
    case TARGET_NR_flistxattr:
5871
    case TARGET_NR_removexattr:
5872
    case TARGET_NR_lremovexattr:
5873
    case TARGET_NR_fremovexattr:
5874
        goto unimplemented_nowarn;
5875
#endif
5876
#ifdef TARGET_NR_set_thread_area
5877
    case TARGET_NR_set_thread_area:
5878
#if defined(TARGET_MIPS)
5879
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5880
      ret = 0;
5881
      break;
5882
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
5883
      ret = do_set_thread_area(cpu_env, arg1);
5884
      break;
5885
#else
5886
      goto unimplemented_nowarn;
5887
#endif
5888
#endif
5889
#ifdef TARGET_NR_get_thread_area
5890
    case TARGET_NR_get_thread_area:
5891
#if defined(TARGET_I386) && defined(TARGET_ABI32)
5892
        ret = do_get_thread_area(cpu_env, arg1);
5893
#else
5894
        goto unimplemented_nowarn;
5895
#endif
5896
#endif
5897
#ifdef TARGET_NR_getdomainname
5898
    case TARGET_NR_getdomainname:
5899
        goto unimplemented_nowarn;
5900
#endif
5901

    
5902
#ifdef TARGET_NR_clock_gettime
5903
    case TARGET_NR_clock_gettime:
5904
    {
5905
        struct timespec ts;
5906
        ret = get_errno(clock_gettime(arg1, &ts));
5907
        if (!is_error(ret)) {
5908
            host_to_target_timespec(arg2, &ts);
5909
        }
5910
        break;
5911
    }
5912
#endif
5913
#ifdef TARGET_NR_clock_getres
5914
    case TARGET_NR_clock_getres:
5915
    {
5916
        struct timespec ts;
5917
        ret = get_errno(clock_getres(arg1, &ts));
5918
        if (!is_error(ret)) {
5919
            host_to_target_timespec(arg2, &ts);
5920
        }
5921
        break;
5922
    }
5923
#endif
5924
#ifdef TARGET_NR_clock_nanosleep
5925
    case TARGET_NR_clock_nanosleep:
5926
    {
5927
        struct timespec ts;
5928
        target_to_host_timespec(&ts, arg3);
5929
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5930
        if (arg4)
5931
            host_to_target_timespec(arg4, &ts);
5932
        break;
5933
    }
5934
#endif
5935

    
5936
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5937
    case TARGET_NR_set_tid_address:
5938
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
5939
        break;
5940
#endif
5941

    
5942
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5943
    case TARGET_NR_tkill:
5944
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5945
        break;
5946
#endif
5947

    
5948
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5949
    case TARGET_NR_tgkill:
5950
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5951
                        target_to_host_signal(arg3)));
5952
        break;
5953
#endif
5954

    
5955
#ifdef TARGET_NR_set_robust_list
5956
    case TARGET_NR_set_robust_list:
5957
        goto unimplemented_nowarn;
5958
#endif
5959

    
5960
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5961
    case TARGET_NR_utimensat:
5962
        {
5963
            struct timespec ts[2];
5964
            target_to_host_timespec(ts, arg3);
5965
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5966
            if (!arg2)
5967
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5968
            else {
5969
                if (!(p = lock_user_string(arg2))) {
5970
                    ret = -TARGET_EFAULT;
5971
                    goto fail;
5972
                }
5973
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
5974
                unlock_user(p, arg2, 0);
5975
            }
5976
        }
5977
        break;
5978
#endif
5979
#if defined(USE_NPTL)
5980
    case TARGET_NR_futex:
5981
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
5982
        break;
5983
#endif
5984
#ifdef TARGET_NR_inotify_init
5985
    case TARGET_NR_inotify_init:
5986
        ret = get_errno(sys_inotify_init());
5987
        break;
5988
#endif
5989
#ifdef TARGET_NR_inotify_add_watch
5990
    case TARGET_NR_inotify_add_watch:
5991
        p = lock_user_string(arg2);
5992
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
5993
        unlock_user(p, arg2, 0);
5994
        break;
5995
#endif
5996
#ifdef TARGET_NR_inotify_rm_watch
5997
    case TARGET_NR_inotify_rm_watch:
5998
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
5999
        break;
6000
#endif
6001

    
6002
    default:
6003
    unimplemented:
6004
        gemu_log("qemu: Unsupported syscall: %d\n", num);
6005
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6006
    unimplemented_nowarn:
6007
#endif
6008
        ret = -TARGET_ENOSYS;
6009
        break;
6010
    }
6011
fail:
6012
#ifdef DEBUG
6013
    gemu_log(" = %ld\n", ret);
6014
#endif
6015
    if(do_strace)
6016
        print_syscall_ret(num, ret);
6017
    return ret;
6018
efault:
6019
    ret = -TARGET_EFAULT;
6020
    goto fail;
6021
}