Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 6556a833

History | View | Annotate | Download (184.5 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
#ifdef TARGET_NR_ipc
1615
#define N_SHM_REGIONS        32
1616

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1843
    return ret;
1844
}
1845

    
1846
struct target_msqid_ds
1847
{
1848
  struct target_ipc_perm msg_perm;
1849
  abi_ulong msg_stime;
1850
  abi_ulong __unused1;
1851
  abi_ulong msg_rtime;
1852
  abi_ulong __unused2;
1853
  abi_ulong msg_ctime;
1854
  abi_ulong __unused3;
1855
  abi_ulong __msg_cbytes;
1856
  abi_ulong msg_qnum;
1857
  abi_ulong msg_qbytes;
1858
  abi_ulong msg_lspid;
1859
  abi_ulong msg_lrpid;
1860
  abi_ulong __unused4;
1861
  abi_ulong __unused5;
1862
};
1863

    
1864
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1865
                                               abi_ulong target_addr)
1866
{
1867
    struct target_msqid_ds *target_md;
1868

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

    
1884
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1885
                                               struct msqid_ds *host_md)
1886
{
1887
    struct target_msqid_ds *target_md;
1888

    
1889
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1890
        return -TARGET_EFAULT;
1891
    host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
1892
    target_md->msg_stime = tswapl(host_md->msg_stime);
1893
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
1894
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
1895
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1896
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
1897
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1898
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
1899
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1900
    unlock_user_struct(target_md, target_addr, 1);
1901
    return 0;
1902
}
1903

    
1904
static inline abi_long do_msgctl(int first, int second, abi_long ptr)
1905
{
1906
    struct msqid_ds dsarg;
1907
    int cmd = second&0xff;
1908
    abi_long ret = 0;
1909
    switch( cmd ) {
1910
    case IPC_STAT:
1911
    case IPC_SET:
1912
        target_to_host_msqid_ds(&dsarg,ptr);
1913
        ret = get_errno(msgctl(first, cmd, &dsarg));
1914
        host_to_target_msqid_ds(ptr,&dsarg);
1915
    default:
1916
        ret = get_errno(msgctl(first, cmd, &dsarg));
1917
    }
1918
    return ret;
1919
}
1920

    
1921
struct target_msgbuf {
1922
        abi_ulong mtype;
1923
        char        mtext[1];
1924
};
1925

    
1926
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1927
                                 unsigned int msgsz, int msgflg)
1928
{
1929
    struct target_msgbuf *target_mb;
1930
    struct msgbuf *host_mb;
1931
    abi_long ret = 0;
1932

    
1933
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1934
        return -TARGET_EFAULT;
1935
    host_mb = malloc(msgsz+sizeof(long));
1936
    host_mb->mtype = tswapl(target_mb->mtype);
1937
    memcpy(host_mb->mtext,target_mb->mtext,msgsz);
1938
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1939
    free(host_mb);
1940
    unlock_user_struct(target_mb, msgp, 0);
1941

    
1942
    return ret;
1943
}
1944

    
1945
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1946
                                 unsigned int msgsz, int msgtype,
1947
                                 int msgflg)
1948
{
1949
    struct target_msgbuf *target_mb;
1950
    char *target_mtext;
1951
    struct msgbuf *host_mb;
1952
    abi_long ret = 0;
1953

    
1954
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
1955
        return -TARGET_EFAULT;
1956
    host_mb = malloc(msgsz+sizeof(long));
1957
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
1958
    if (ret > 0) {
1959
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
1960
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
1961
        if (!target_mtext) {
1962
            ret = -TARGET_EFAULT;
1963
            goto end;
1964
        }
1965
            memcpy(target_mb->mtext, host_mb->mtext, ret);
1966
        unlock_user(target_mtext, target_mtext_addr, ret);
1967
    }
1968
    target_mb->mtype = tswapl(host_mb->mtype);
1969
    free(host_mb);
1970

    
1971
end:
1972
    if (target_mb)
1973
        unlock_user_struct(target_mb, msgp, 1);
1974
    return ret;
1975
}
1976

    
1977
/* ??? This only works with linear mappings.  */
1978
/* do_ipc() must return target values and target errnos. */
1979
static abi_long do_ipc(unsigned int call, int first,
1980
                       int second, int third,
1981
                       abi_long ptr, abi_long fifth)
1982
{
1983
    int version;
1984
    abi_long ret = 0;
1985
    struct shmid_ds shm_info;
1986
    int i;
1987

    
1988
    version = call >> 16;
1989
    call &= 0xffff;
1990

    
1991
    switch (call) {
1992
    case IPCOP_semop:
1993
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
1994
        break;
1995

    
1996
    case IPCOP_semget:
1997
        ret = get_errno(semget(first, second, third));
1998
        break;
1999

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

    
2004
    case IPCOP_semtimedop:
2005
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2006
        ret = -TARGET_ENOSYS;
2007
        break;
2008

    
2009
        case IPCOP_msgget:
2010
                ret = get_errno(msgget(first, second));
2011
                break;
2012

    
2013
        case IPCOP_msgsnd:
2014
                ret = do_msgsnd(first, ptr, second, third);
2015
                break;
2016

    
2017
        case IPCOP_msgctl:
2018
                ret = do_msgctl(first, second, ptr);
2019
                break;
2020

    
2021
        case IPCOP_msgrcv:
2022
                {
2023
                      /* XXX: this code is not correct */
2024
                      struct ipc_kludge
2025
                      {
2026
                              void *__unbounded msgp;
2027
                              long int msgtyp;
2028
                      };
2029

    
2030
                      struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
2031
                      struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
2032

    
2033
                      ret = do_msgrcv(first, (long)msgp, second, 0, third);
2034

    
2035
                }
2036
                break;
2037

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

    
2083
    case IPCOP_shmget:
2084
        /* IPC_* flag values are the same on all linux platforms */
2085
        ret = get_errno(shmget(first, second, third));
2086
        break;
2087

    
2088
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2089
    case IPCOP_shmctl:
2090
        switch(second) {
2091
        case IPC_RMID:
2092
        case SHM_LOCK:
2093
        case SHM_UNLOCK:
2094
            ret = get_errno(shmctl(first, second, NULL));
2095
            break;
2096
        default:
2097
            goto unimplemented;
2098
        }
2099
        break;
2100
    default:
2101
    unimplemented:
2102
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2103
        ret = -TARGET_ENOSYS;
2104
        break;
2105
    }
2106
    return ret;
2107
}
2108
#endif
2109

    
2110
/* kernel structure types definitions */
2111
#define IFNAMSIZ        16
2112

    
2113
#define STRUCT(name, list...) STRUCT_ ## name,
2114
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2115
enum {
2116
#include "syscall_types.h"
2117
};
2118
#undef STRUCT
2119
#undef STRUCT_SPECIAL
2120

    
2121
#define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2122
#define STRUCT_SPECIAL(name)
2123
#include "syscall_types.h"
2124
#undef STRUCT
2125
#undef STRUCT_SPECIAL
2126

    
2127
typedef struct IOCTLEntry {
2128
    unsigned int target_cmd;
2129
    unsigned int host_cmd;
2130
    const char *name;
2131
    int access;
2132
    const argtype arg_type[5];
2133
} IOCTLEntry;
2134

    
2135
#define IOC_R 0x0001
2136
#define IOC_W 0x0002
2137
#define IOC_RW (IOC_R | IOC_W)
2138

    
2139
#define MAX_STRUCT_SIZE 4096
2140

    
2141
static IOCTLEntry ioctl_entries[] = {
2142
#define IOCTL(cmd, access, types...) \
2143
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2144
#include "ioctls.h"
2145
    { 0, 0, },
2146
};
2147

    
2148
/* ??? Implement proper locking for ioctls.  */
2149
/* do_ioctl() Must return target values and target errnos. */
2150
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2151
{
2152
    const IOCTLEntry *ie;
2153
    const argtype *arg_type;
2154
    abi_long ret;
2155
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2156
    int target_size;
2157
    void *argptr;
2158

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

    
2232
static const bitmask_transtbl iflag_tbl[] = {
2233
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2234
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2235
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2236
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2237
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2238
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2239
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2240
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2241
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2242
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2243
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2244
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2245
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2246
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2247
        { 0, 0, 0, 0 }
2248
};
2249

    
2250
static const bitmask_transtbl oflag_tbl[] = {
2251
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2252
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2253
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2254
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2255
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2256
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2257
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2258
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2259
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2260
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2261
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2262
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2263
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2264
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2265
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2266
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2267
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2268
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2269
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2270
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2271
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2272
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2273
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2274
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2275
        { 0, 0, 0, 0 }
2276
};
2277

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

    
2313
static const bitmask_transtbl lflag_tbl[] = {
2314
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2315
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2316
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2317
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2318
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2319
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2320
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2321
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2322
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2323
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2324
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2325
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2326
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2327
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2328
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2329
        { 0, 0, 0, 0 }
2330
};
2331

    
2332
static void target_to_host_termios (void *dst, const void *src)
2333
{
2334
    struct host_termios *host = dst;
2335
    const struct target_termios *target = src;
2336

    
2337
    host->c_iflag =
2338
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2339
    host->c_oflag =
2340
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2341
    host->c_cflag =
2342
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2343
    host->c_lflag =
2344
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2345
    host->c_line = target->c_line;
2346

    
2347
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2348
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2349
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2350
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2351
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2352
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2353
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2354
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2355
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2356
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2357
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2358
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2359
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2360
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2361
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2362
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2363
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2364
}
2365

    
2366
static void host_to_target_termios (void *dst, const void *src)
2367
{
2368
    struct target_termios *target = dst;
2369
    const struct host_termios *host = src;
2370

    
2371
    target->c_iflag =
2372
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2373
    target->c_oflag =
2374
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2375
    target->c_cflag =
2376
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2377
    target->c_lflag =
2378
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2379
    target->c_line = host->c_line;
2380

    
2381
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2382
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2383
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2384
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2385
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2386
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2387
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2388
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2389
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2390
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2391
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2392
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2393
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2394
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2395
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2396
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2397
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2398
}
2399

    
2400
static const StructEntry struct_termios_def = {
2401
    .convert = { host_to_target_termios, target_to_host_termios },
2402
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2403
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2404
};
2405

    
2406
static bitmask_transtbl mmap_flags_tbl[] = {
2407
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2408
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2409
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2410
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2411
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2412
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2413
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2414
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2415
        { 0, 0, 0, 0 }
2416
};
2417

    
2418
static bitmask_transtbl fcntl_flags_tbl[] = {
2419
        { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
2420
        { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
2421
        { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
2422
        { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
2423
        { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
2424
        { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
2425
        { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
2426
        { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
2427
        { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
2428
        { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
2429
        { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2430
        { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
2431
        { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2432
#if defined(O_DIRECT)
2433
        { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
2434
#endif
2435
        { 0, 0, 0, 0 }
2436
};
2437

    
2438
#if defined(TARGET_I386)
2439

    
2440
/* NOTE: there is really one LDT for all the threads */
2441
uint8_t *ldt_table;
2442

    
2443
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2444
{
2445
    int size;
2446
    void *p;
2447

    
2448
    if (!ldt_table)
2449
        return 0;
2450
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2451
    if (size > bytecount)
2452
        size = bytecount;
2453
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
2454
    if (!p)
2455
        return -TARGET_EFAULT;
2456
    /* ??? Should this by byteswapped?  */
2457
    memcpy(p, ldt_table, size);
2458
    unlock_user(p, ptr, size);
2459
    return size;
2460
}
2461

    
2462
/* XXX: add locking support */
2463
static abi_long write_ldt(CPUX86State *env,
2464
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
2465
{
2466
    struct target_modify_ldt_ldt_s ldt_info;
2467
    struct target_modify_ldt_ldt_s *target_ldt_info;
2468
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2469
    int seg_not_present, useable, lm;
2470
    uint32_t *lp, entry_1, entry_2;
2471

    
2472
    if (bytecount != sizeof(ldt_info))
2473
        return -TARGET_EINVAL;
2474
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2475
        return -TARGET_EFAULT;
2476
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2477
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2478
    ldt_info.limit = tswap32(target_ldt_info->limit);
2479
    ldt_info.flags = tswap32(target_ldt_info->flags);
2480
    unlock_user_struct(target_ldt_info, ptr, 0);
2481

    
2482
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2483
        return -TARGET_EINVAL;
2484
    seg_32bit = ldt_info.flags & 1;
2485
    contents = (ldt_info.flags >> 1) & 3;
2486
    read_exec_only = (ldt_info.flags >> 3) & 1;
2487
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2488
    seg_not_present = (ldt_info.flags >> 5) & 1;
2489
    useable = (ldt_info.flags >> 6) & 1;
2490
#ifdef TARGET_ABI32
2491
    lm = 0;
2492
#else
2493
    lm = (ldt_info.flags >> 7) & 1;
2494
#endif
2495
    if (contents == 3) {
2496
        if (oldmode)
2497
            return -TARGET_EINVAL;
2498
        if (seg_not_present == 0)
2499
            return -TARGET_EINVAL;
2500
    }
2501
    /* allocate the LDT */
2502
    if (!ldt_table) {
2503
        ldt_table = malloc(TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2504
        if (!ldt_table)
2505
            return -TARGET_ENOMEM;
2506
        memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2507
        env->ldt.base = h2g((unsigned long)ldt_table);
2508
        env->ldt.limit = 0xffff;
2509
    }
2510

    
2511
    /* NOTE: same code as Linux kernel */
2512
    /* Allow LDTs to be cleared by the user. */
2513
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2514
        if (oldmode ||
2515
            (contents == 0                &&
2516
             read_exec_only == 1        &&
2517
             seg_32bit == 0                &&
2518
             limit_in_pages == 0        &&
2519
             seg_not_present == 1        &&
2520
             useable == 0 )) {
2521
            entry_1 = 0;
2522
            entry_2 = 0;
2523
            goto install;
2524
        }
2525
    }
2526

    
2527
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2528
        (ldt_info.limit & 0x0ffff);
2529
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2530
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2531
        (ldt_info.limit & 0xf0000) |
2532
        ((read_exec_only ^ 1) << 9) |
2533
        (contents << 10) |
2534
        ((seg_not_present ^ 1) << 15) |
2535
        (seg_32bit << 22) |
2536
        (limit_in_pages << 23) |
2537
        (lm << 21) |
2538
        0x7000;
2539
    if (!oldmode)
2540
        entry_2 |= (useable << 20);
2541

    
2542
    /* Install the new entry ...  */
2543
install:
2544
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2545
    lp[0] = tswap32(entry_1);
2546
    lp[1] = tswap32(entry_2);
2547
    return 0;
2548
}
2549

    
2550
/* specific and weird i386 syscalls */
2551
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2552
                              unsigned long bytecount)
2553
{
2554
    abi_long ret;
2555

    
2556
    switch (func) {
2557
    case 0:
2558
        ret = read_ldt(ptr, bytecount);
2559
        break;
2560
    case 1:
2561
        ret = write_ldt(env, ptr, bytecount, 1);
2562
        break;
2563
    case 0x11:
2564
        ret = write_ldt(env, ptr, bytecount, 0);
2565
        break;
2566
    default:
2567
        ret = -TARGET_ENOSYS;
2568
        break;
2569
    }
2570
    return ret;
2571
}
2572

    
2573
#if defined(TARGET_I386) && defined(TARGET_ABI32)
2574
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2575
{
2576
    uint64_t *gdt_table = g2h(env->gdt.base);
2577
    struct target_modify_ldt_ldt_s ldt_info;
2578
    struct target_modify_ldt_ldt_s *target_ldt_info;
2579
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2580
    int seg_not_present, useable, lm;
2581
    uint32_t *lp, entry_1, entry_2;
2582
    int i;
2583

    
2584
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2585
    if (!target_ldt_info)
2586
        return -TARGET_EFAULT;
2587
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2588
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2589
    ldt_info.limit = tswap32(target_ldt_info->limit);
2590
    ldt_info.flags = tswap32(target_ldt_info->flags);
2591
    if (ldt_info.entry_number == -1) {
2592
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2593
            if (gdt_table[i] == 0) {
2594
                ldt_info.entry_number = i;
2595
                target_ldt_info->entry_number = tswap32(i);
2596
                break;
2597
            }
2598
        }
2599
    }
2600
    unlock_user_struct(target_ldt_info, ptr, 1);
2601

    
2602
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
2603
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2604
           return -TARGET_EINVAL;
2605
    seg_32bit = ldt_info.flags & 1;
2606
    contents = (ldt_info.flags >> 1) & 3;
2607
    read_exec_only = (ldt_info.flags >> 3) & 1;
2608
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2609
    seg_not_present = (ldt_info.flags >> 5) & 1;
2610
    useable = (ldt_info.flags >> 6) & 1;
2611
#ifdef TARGET_ABI32
2612
    lm = 0;
2613
#else
2614
    lm = (ldt_info.flags >> 7) & 1;
2615
#endif
2616

    
2617
    if (contents == 3) {
2618
        if (seg_not_present == 0)
2619
            return -TARGET_EINVAL;
2620
    }
2621

    
2622
    /* NOTE: same code as Linux kernel */
2623
    /* Allow LDTs to be cleared by the user. */
2624
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2625
        if ((contents == 0             &&
2626
             read_exec_only == 1       &&
2627
             seg_32bit == 0            &&
2628
             limit_in_pages == 0       &&
2629
             seg_not_present == 1      &&
2630
             useable == 0 )) {
2631
            entry_1 = 0;
2632
            entry_2 = 0;
2633
            goto install;
2634
        }
2635
    }
2636

    
2637
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2638
        (ldt_info.limit & 0x0ffff);
2639
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2640
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2641
        (ldt_info.limit & 0xf0000) |
2642
        ((read_exec_only ^ 1) << 9) |
2643
        (contents << 10) |
2644
        ((seg_not_present ^ 1) << 15) |
2645
        (seg_32bit << 22) |
2646
        (limit_in_pages << 23) |
2647
        (useable << 20) |
2648
        (lm << 21) |
2649
        0x7000;
2650

    
2651
    /* Install the new entry ...  */
2652
install:
2653
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2654
    lp[0] = tswap32(entry_1);
2655
    lp[1] = tswap32(entry_2);
2656
    return 0;
2657
}
2658

    
2659
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2660
{
2661
    struct target_modify_ldt_ldt_s *target_ldt_info;
2662
    uint64_t *gdt_table = g2h(env->gdt.base);
2663
    uint32_t base_addr, limit, flags;
2664
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2665
    int seg_not_present, useable, lm;
2666
    uint32_t *lp, entry_1, entry_2;
2667

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

    
2707
#ifndef TARGET_ABI32
2708
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2709
{
2710
    abi_long ret;
2711
    abi_ulong val;
2712
    int idx;
2713
    
2714
    switch(code) {
2715
    case TARGET_ARCH_SET_GS:
2716
    case TARGET_ARCH_SET_FS:
2717
        if (code == TARGET_ARCH_SET_GS)
2718
            idx = R_GS;
2719
        else
2720
            idx = R_FS;
2721
        cpu_x86_load_seg(env, idx, 0);
2722
        env->segs[idx].base = addr;
2723
        break;
2724
    case TARGET_ARCH_GET_GS:
2725
    case TARGET_ARCH_GET_FS:
2726
        if (code == TARGET_ARCH_GET_GS)
2727
            idx = R_GS;
2728
        else
2729
            idx = R_FS;
2730
        val = env->segs[idx].base;
2731
        if (put_user(val, addr, abi_ulong))
2732
            return -TARGET_EFAULT;
2733
        break;
2734
    default:
2735
        ret = -TARGET_EINVAL;
2736
        break;
2737
    }
2738
    return 0;
2739
}
2740
#endif
2741

    
2742
#endif /* defined(TARGET_I386) */
2743

    
2744
#if defined(USE_NPTL)
2745

    
2746
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2747

    
2748
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2749
typedef struct {
2750
    CPUState *env;
2751
    pthread_mutex_t mutex;
2752
    pthread_cond_t cond;
2753
    pthread_t thread;
2754
    uint32_t tid;
2755
    abi_ulong child_tidptr;
2756
    abi_ulong parent_tidptr;
2757
    sigset_t sigmask;
2758
} new_thread_info;
2759

    
2760
static void *clone_func(void *arg)
2761
{
2762
    new_thread_info *info = arg;
2763
    CPUState *env;
2764

    
2765
    env = info->env;
2766
    thread_env = env;
2767
    info->tid = gettid();
2768
    if (info->child_tidptr)
2769
        put_user_u32(info->tid, info->child_tidptr);
2770
    if (info->parent_tidptr)
2771
        put_user_u32(info->tid, info->parent_tidptr);
2772
    /* Enable signals.  */
2773
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2774
    /* Signal to the parent that we're ready.  */
2775
    pthread_mutex_lock(&info->mutex);
2776
    pthread_cond_broadcast(&info->cond);
2777
    pthread_mutex_unlock(&info->mutex);
2778
    /* Wait until the parent has finshed initializing the tls state.  */
2779
    pthread_mutex_lock(&clone_lock);
2780
    pthread_mutex_unlock(&clone_lock);
2781
    cpu_loop(env);
2782
    /* never exits */
2783
    return NULL;
2784
}
2785
#else
2786
/* this stack is the equivalent of the kernel stack associated with a
2787
   thread/process */
2788
#define NEW_STACK_SIZE 8192
2789

    
2790
static int clone_func(void *arg)
2791
{
2792
    CPUState *env = arg;
2793
    cpu_loop(env);
2794
    /* never exits */
2795
    return 0;
2796
}
2797
#endif
2798

    
2799
/* do_fork() Must return host values and target errnos (unlike most
2800
   do_*() functions). */
2801
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2802
                   abi_ulong parent_tidptr, target_ulong newtls,
2803
                   abi_ulong child_tidptr)
2804
{
2805
    int ret;
2806
    TaskState *ts;
2807
    uint8_t *new_stack;
2808
    CPUState *new_env;
2809
#if defined(USE_NPTL)
2810
    unsigned int nptl_flags;
2811
    sigset_t sigmask;
2812
#endif
2813

    
2814
    /* Emulate vfork() with fork() */
2815
    if (flags & CLONE_VFORK)
2816
        flags &= ~(CLONE_VFORK | CLONE_VM);
2817

    
2818
    if (flags & CLONE_VM) {
2819
#if defined(USE_NPTL)
2820
        new_thread_info info;
2821
        pthread_attr_t attr;
2822
#endif
2823
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2824
        init_task_state(ts);
2825
        new_stack = ts->stack;
2826
        /* we create a new CPU instance. */
2827
        new_env = cpu_copy(env);
2828
        /* Init regs that differ from the parent.  */
2829
        cpu_clone_regs(new_env, newsp);
2830
        new_env->opaque = ts;
2831
#if defined(USE_NPTL)
2832
        nptl_flags = flags;
2833
        flags &= ~CLONE_NPTL_FLAGS2;
2834

    
2835
        /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2836
        if (nptl_flags & CLONE_SETTLS)
2837
            cpu_set_tls (new_env, newtls);
2838

    
2839
        /* Grab a mutex so that thread setup appears atomic.  */
2840
        pthread_mutex_lock(&clone_lock);
2841

    
2842
        memset(&info, 0, sizeof(info));
2843
        pthread_mutex_init(&info.mutex, NULL);
2844
        pthread_mutex_lock(&info.mutex);
2845
        pthread_cond_init(&info.cond, NULL);
2846
        info.env = new_env;
2847
        if (nptl_flags & CLONE_CHILD_SETTID)
2848
            info.child_tidptr = child_tidptr;
2849
        if (nptl_flags & CLONE_PARENT_SETTID)
2850
            info.parent_tidptr = parent_tidptr;
2851

    
2852
        ret = pthread_attr_init(&attr);
2853
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2854
        /* It is not safe to deliver signals until the child has finished
2855
           initializing, so temporarily block all signals.  */
2856
        sigfillset(&sigmask);
2857
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2858

    
2859
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
2860

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

    
2923
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2924
{
2925
    struct flock fl;
2926
    struct target_flock *target_fl;
2927
    struct flock64 fl64;
2928
    struct target_flock64 *target_fl64;
2929
    abi_long ret;
2930

    
2931
    switch(cmd) {
2932
    case TARGET_F_GETLK:
2933
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2934
            return -TARGET_EFAULT;
2935
        fl.l_type = tswap16(target_fl->l_type);
2936
        fl.l_whence = tswap16(target_fl->l_whence);
2937
        fl.l_start = tswapl(target_fl->l_start);
2938
        fl.l_len = tswapl(target_fl->l_len);
2939
        fl.l_pid = tswapl(target_fl->l_pid);
2940
        unlock_user_struct(target_fl, arg, 0);
2941
        ret = get_errno(fcntl(fd, cmd, &fl));
2942
        if (ret == 0) {
2943
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
2944
                return -TARGET_EFAULT;
2945
            target_fl->l_type = tswap16(fl.l_type);
2946
            target_fl->l_whence = tswap16(fl.l_whence);
2947
            target_fl->l_start = tswapl(fl.l_start);
2948
            target_fl->l_len = tswapl(fl.l_len);
2949
            target_fl->l_pid = tswapl(fl.l_pid);
2950
            unlock_user_struct(target_fl, arg, 1);
2951
        }
2952
        break;
2953

    
2954
    case TARGET_F_SETLK:
2955
    case TARGET_F_SETLKW:
2956
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2957
            return -TARGET_EFAULT;
2958
        fl.l_type = tswap16(target_fl->l_type);
2959
        fl.l_whence = tswap16(target_fl->l_whence);
2960
        fl.l_start = tswapl(target_fl->l_start);
2961
        fl.l_len = tswapl(target_fl->l_len);
2962
        fl.l_pid = tswapl(target_fl->l_pid);
2963
        unlock_user_struct(target_fl, arg, 0);
2964
        ret = get_errno(fcntl(fd, cmd, &fl));
2965
        break;
2966

    
2967
    case TARGET_F_GETLK64:
2968
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2969
            return -TARGET_EFAULT;
2970
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2971
        fl64.l_whence = tswap16(target_fl64->l_whence);
2972
        fl64.l_start = tswapl(target_fl64->l_start);
2973
        fl64.l_len = tswapl(target_fl64->l_len);
2974
        fl64.l_pid = tswap16(target_fl64->l_pid);
2975
        unlock_user_struct(target_fl64, arg, 0);
2976
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2977
        if (ret == 0) {
2978
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
2979
                return -TARGET_EFAULT;
2980
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
2981
            target_fl64->l_whence = tswap16(fl64.l_whence);
2982
            target_fl64->l_start = tswapl(fl64.l_start);
2983
            target_fl64->l_len = tswapl(fl64.l_len);
2984
            target_fl64->l_pid = tswapl(fl64.l_pid);
2985
            unlock_user_struct(target_fl64, arg, 1);
2986
        }
2987
        break;
2988
    case TARGET_F_SETLK64:
2989
    case TARGET_F_SETLKW64:
2990
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2991
            return -TARGET_EFAULT;
2992
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2993
        fl64.l_whence = tswap16(target_fl64->l_whence);
2994
        fl64.l_start = tswapl(target_fl64->l_start);
2995
        fl64.l_len = tswapl(target_fl64->l_len);
2996
        fl64.l_pid = tswap16(target_fl64->l_pid);
2997
        unlock_user_struct(target_fl64, arg, 0);
2998
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2999
        break;
3000

    
3001
    case F_GETFL:
3002
        ret = get_errno(fcntl(fd, cmd, arg));
3003
        if (ret >= 0) {
3004
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3005
        }
3006
        break;
3007

    
3008
    case F_SETFL:
3009
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3010
        break;
3011

    
3012
    default:
3013
        ret = get_errno(fcntl(fd, cmd, arg));
3014
        break;
3015
    }
3016
    return ret;
3017
}
3018

    
3019
#ifdef USE_UID16
3020

    
3021
static inline int high2lowuid(int uid)
3022
{
3023
    if (uid > 65535)
3024
        return 65534;
3025
    else
3026
        return uid;
3027
}
3028

    
3029
static inline int high2lowgid(int gid)
3030
{
3031
    if (gid > 65535)
3032
        return 65534;
3033
    else
3034
        return gid;
3035
}
3036

    
3037
static inline int low2highuid(int uid)
3038
{
3039
    if ((int16_t)uid == -1)
3040
        return -1;
3041
    else
3042
        return uid;
3043
}
3044

    
3045
static inline int low2highgid(int gid)
3046
{
3047
    if ((int16_t)gid == -1)
3048
        return -1;
3049
    else
3050
        return gid;
3051
}
3052

    
3053
#endif /* USE_UID16 */
3054

    
3055
void syscall_init(void)
3056
{
3057
    IOCTLEntry *ie;
3058
    const argtype *arg_type;
3059
    int size;
3060
    int i;
3061

    
3062
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3063
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3064
#include "syscall_types.h"
3065
#undef STRUCT
3066
#undef STRUCT_SPECIAL
3067

    
3068
    /* we patch the ioctl size if necessary. We rely on the fact that
3069
       no ioctl has all the bits at '1' in the size field */
3070
    ie = ioctl_entries;
3071
    while (ie->target_cmd != 0) {
3072
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3073
            TARGET_IOC_SIZEMASK) {
3074
            arg_type = ie->arg_type;
3075
            if (arg_type[0] != TYPE_PTR) {
3076
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3077
                        ie->target_cmd);
3078
                exit(1);
3079
            }
3080
            arg_type++;
3081
            size = thunk_type_size(arg_type, 0);
3082
            ie->target_cmd = (ie->target_cmd &
3083
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3084
                (size << TARGET_IOC_SIZESHIFT);
3085
        }
3086

    
3087
        /* Build target_to_host_errno_table[] table from
3088
         * host_to_target_errno_table[]. */
3089
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3090
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3091

    
3092
        /* automatic consistency check if same arch */
3093
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3094
    (defined(__x86_64__) && defined(TARGET_X86_64))
3095
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3096
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3097
                    ie->name, ie->target_cmd, ie->host_cmd);
3098
        }
3099
#endif
3100
        ie++;
3101
    }
3102
}
3103

    
3104
#if TARGET_ABI_BITS == 32
3105
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3106
{
3107
#ifdef TARGET_WORDS_BIGENDIAN
3108
    return ((uint64_t)word0 << 32) | word1;
3109
#else
3110
    return ((uint64_t)word1 << 32) | word0;
3111
#endif
3112
}
3113
#else /* TARGET_ABI_BITS == 32 */
3114
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3115
{
3116
    return word0;
3117
}
3118
#endif /* TARGET_ABI_BITS != 32 */
3119

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

    
3137
#ifdef TARGET_NR_ftruncate64
3138
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3139
                                          abi_long arg2,
3140
                                          abi_long arg3,
3141
                                          abi_long arg4)
3142
{
3143
#ifdef TARGET_ARM
3144
    if (((CPUARMState *)cpu_env)->eabi)
3145
      {
3146
        arg2 = arg3;
3147
        arg3 = arg4;
3148
      }
3149
#endif
3150
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3151
}
3152
#endif
3153

    
3154
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3155
                                               abi_ulong target_addr)
3156
{
3157
    struct target_timespec *target_ts;
3158

    
3159
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3160
        return -TARGET_EFAULT;
3161
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3162
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3163
    unlock_user_struct(target_ts, target_addr, 0);
3164
    return 0;
3165
}
3166

    
3167
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3168
                                               struct timespec *host_ts)
3169
{
3170
    struct target_timespec *target_ts;
3171

    
3172
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3173
        return -TARGET_EFAULT;
3174
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3175
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3176
    unlock_user_struct(target_ts, target_addr, 1);
3177
    return 0;
3178
}
3179

    
3180
#ifdef TARGET_NR_stat64
3181
static inline abi_long host_to_target_stat64(void *cpu_env,
3182
                                             abi_ulong target_addr,
3183
                                             struct stat *host_st)
3184
{
3185
#ifdef TARGET_ARM
3186
    if (((CPUARMState *)cpu_env)->eabi) {
3187
        struct target_eabi_stat64 *target_st;
3188

    
3189
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3190
            return -TARGET_EFAULT;
3191
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3192
        __put_user(host_st->st_dev, &target_st->st_dev);
3193
        __put_user(host_st->st_ino, &target_st->st_ino);
3194
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3195
        __put_user(host_st->st_ino, &target_st->__st_ino);
3196
#endif
3197
        __put_user(host_st->st_mode, &target_st->st_mode);
3198
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3199
        __put_user(host_st->st_uid, &target_st->st_uid);
3200
        __put_user(host_st->st_gid, &target_st->st_gid);
3201
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3202
        __put_user(host_st->st_size, &target_st->st_size);
3203
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3204
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3205
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3206
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3207
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3208
        unlock_user_struct(target_st, target_addr, 1);
3209
    } else
3210
#endif
3211
    {
3212
        struct target_stat64 *target_st;
3213

    
3214
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3215
            return -TARGET_EFAULT;
3216
        memset(target_st, 0, sizeof(struct target_stat64));
3217
        __put_user(host_st->st_dev, &target_st->st_dev);
3218
        __put_user(host_st->st_ino, &target_st->st_ino);
3219
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3220
        __put_user(host_st->st_ino, &target_st->__st_ino);
3221
#endif
3222
        __put_user(host_st->st_mode, &target_st->st_mode);
3223
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3224
        __put_user(host_st->st_uid, &target_st->st_uid);
3225
        __put_user(host_st->st_gid, &target_st->st_gid);
3226
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3227
        /* XXX: better use of kernel struct */
3228
        __put_user(host_st->st_size, &target_st->st_size);
3229
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3230
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3231
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3232
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3233
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3234
        unlock_user_struct(target_st, target_addr, 1);
3235
    }
3236

    
3237
    return 0;
3238
}
3239
#endif
3240

    
3241
#if defined(USE_NPTL)
3242
/* ??? Using host futex calls even when target atomic operations
3243
   are not really atomic probably breaks things.  However implementing
3244
   futexes locally would make futexes shared between multiple processes
3245
   tricky.  However they're probably useless because guest atomic
3246
   operations won't work either.  */
3247
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3248
                    target_ulong uaddr2, int val3)
3249
{
3250
    struct timespec ts, *pts;
3251

    
3252
    /* ??? We assume FUTEX_* constants are the same on both host
3253
       and target.  */
3254
    switch (op) {
3255
    case FUTEX_WAIT:
3256
        if (timeout) {
3257
            pts = &ts;
3258
            target_to_host_timespec(pts, timeout);
3259
        } else {
3260
            pts = NULL;
3261
        }
3262
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3263
                         pts, NULL, 0));
3264
    case FUTEX_WAKE:
3265
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3266
    case FUTEX_FD:
3267
        return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3268
    case FUTEX_REQUEUE:
3269
        return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3270
                         NULL, g2h(uaddr2), 0));
3271
    case FUTEX_CMP_REQUEUE:
3272
        return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3273
                         NULL, g2h(uaddr2), tswap32(val3)));
3274
    default:
3275
        return -TARGET_ENOSYS;
3276
    }
3277
}
3278
#endif
3279

    
3280
int get_osversion(void)
3281
{
3282
    static int osversion;
3283
    struct new_utsname buf;
3284
    const char *s;
3285
    int i, n, tmp;
3286
    if (osversion)
3287
        return osversion;
3288
    if (qemu_uname_release && *qemu_uname_release) {
3289
        s = qemu_uname_release;
3290
    } else {
3291
        if (sys_uname(&buf))
3292
            return 0;
3293
        s = buf.release;
3294
    }
3295
    tmp = 0;
3296
    for (i = 0; i < 3; i++) {
3297
        n = 0;
3298
        while (*s >= '0' && *s <= '9') {
3299
            n *= 10;
3300
            n += *s - '0';
3301
            s++;
3302
        }
3303
        tmp = (tmp << 8) + n;
3304
        if (*s == '.')
3305
            s++;
3306
    }
3307
    osversion = tmp;
3308
    return osversion;
3309
}
3310

    
3311
/* do_syscall() should always have a single exit point at the end so
3312
   that actions, such as logging of syscall results, can be performed.
3313
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3314
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3315
                    abi_long arg2, abi_long arg3, abi_long arg4,
3316
                    abi_long arg5, abi_long arg6)
3317
{
3318
    abi_long ret;
3319
    struct stat st;
3320
    struct statfs stfs;
3321
    void *p;
3322

    
3323
#ifdef DEBUG
3324
    gemu_log("syscall %d", num);
3325
#endif
3326
    if(do_strace)
3327
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3328

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

    
3467
            argc = 0;
3468
            guest_argp = arg2;
3469
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3470
                if (get_user_ual(addr, gp))
3471
                    goto efault;
3472
                if (!addr)
3473
                    break;
3474
                argc++;
3475
            }
3476
            envc = 0;
3477
            guest_envp = arg3;
3478
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3479
                if (get_user_ual(addr, gp))
3480
                    goto efault;
3481
                if (!addr)
3482
                    break;
3483
                envc++;
3484
            }
3485

    
3486
            argp = alloca((argc + 1) * sizeof(void *));
3487
            envp = alloca((envc + 1) * sizeof(void *));
3488

    
3489
            for (gp = guest_argp, q = argp; gp;
3490
                  gp += sizeof(abi_ulong), q++) {
3491
                if (get_user_ual(addr, gp))
3492
                    goto execve_efault;
3493
                if (!addr)
3494
                    break;
3495
                if (!(*q = lock_user_string(addr)))
3496
                    goto execve_efault;
3497
            }
3498
            *q = NULL;
3499

    
3500
            for (gp = guest_envp, q = envp; gp;
3501
                  gp += sizeof(abi_ulong), q++) {
3502
                if (get_user_ual(addr, gp))
3503
                    goto execve_efault;
3504
                if (!addr)
3505
                    break;
3506
                if (!(*q = lock_user_string(addr)))
3507
                    goto execve_efault;
3508
            }
3509
            *q = NULL;
3510

    
3511
            if (!(p = lock_user_string(arg1)))
3512
                goto execve_efault;
3513
            ret = get_errno(execve(p, argp, envp));
3514
            unlock_user(p, arg1, 0);
3515

    
3516
            goto execve_end;
3517

    
3518
        execve_efault:
3519
            ret = -TARGET_EFAULT;
3520

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

    
3938
            if (arg2) {
3939
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3940
                    goto efault;
3941
                act._sa_handler = old_act->_sa_handler;
3942
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3943
                act.sa_flags = old_act->sa_flags;
3944
                unlock_user_struct(old_act, arg2, 0);
3945
                pact = &act;
3946
            } else {
3947
                pact = NULL;
3948
            }
3949

    
3950
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3951

    
3952
            if (!is_error(ret) && arg3) {
3953
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3954
                    goto efault;
3955
                old_act->_sa_handler = oact._sa_handler;
3956
                old_act->sa_flags = oact.sa_flags;
3957
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
3958
                old_act->sa_mask.sig[1] = 0;
3959
                old_act->sa_mask.sig[2] = 0;
3960
                old_act->sa_mask.sig[3] = 0;
3961
                unlock_user_struct(old_act, arg3, 1);
3962
            }
3963
#endif
3964
        }
3965
        break;
3966
#endif
3967
    case TARGET_NR_rt_sigaction:
3968
        {
3969
            struct target_sigaction *act;
3970
            struct target_sigaction *oact;
3971

    
3972
            if (arg2) {
3973
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
3974
                    goto efault;
3975
            } else
3976
                act = NULL;
3977
            if (arg3) {
3978
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
3979
                    ret = -TARGET_EFAULT;
3980
                    goto rt_sigaction_fail;
3981
                }
3982
            } else
3983
                oact = NULL;
3984
            ret = get_errno(do_sigaction(arg1, act, oact));
3985
        rt_sigaction_fail:
3986
            if (act)
3987
                unlock_user_struct(act, arg2, 0);
3988
            if (oact)
3989
                unlock_user_struct(oact, arg3, 1);
3990
        }
3991
        break;
3992
#ifdef TARGET_NR_sgetmask /* not on alpha */
3993
    case TARGET_NR_sgetmask:
3994
        {
3995
            sigset_t cur_set;
3996
            abi_ulong target_set;
3997
            sigprocmask(0, NULL, &cur_set);
3998
            host_to_target_old_sigset(&target_set, &cur_set);
3999
            ret = target_set;
4000
        }
4001
        break;
4002
#endif
4003
#ifdef TARGET_NR_ssetmask /* not on alpha */
4004
    case TARGET_NR_ssetmask:
4005
        {
4006
            sigset_t set, oset, cur_set;
4007
            abi_ulong target_set = arg1;
4008
            sigprocmask(0, NULL, &cur_set);
4009
            target_to_host_old_sigset(&set, &target_set);
4010
            sigorset(&set, &set, &cur_set);
4011
            sigprocmask(SIG_SETMASK, &set, &oset);
4012
            host_to_target_old_sigset(&target_set, &oset);
4013
            ret = target_set;
4014
        }
4015
        break;
4016
#endif
4017
#ifdef TARGET_NR_sigprocmask
4018
    case TARGET_NR_sigprocmask:
4019
        {
4020
            int how = arg1;
4021
            sigset_t set, oldset, *set_ptr;
4022

    
4023
            if (arg2) {
4024
                switch(how) {
4025
                case TARGET_SIG_BLOCK:
4026
                    how = SIG_BLOCK;
4027
                    break;
4028
                case TARGET_SIG_UNBLOCK:
4029
                    how = SIG_UNBLOCK;
4030
                    break;
4031
                case TARGET_SIG_SETMASK:
4032
                    how = SIG_SETMASK;
4033
                    break;
4034
                default:
4035
                    ret = -TARGET_EINVAL;
4036
                    goto fail;
4037
                }
4038
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4039
                    goto efault;
4040
                target_to_host_old_sigset(&set, p);
4041
                unlock_user(p, arg2, 0);
4042
                set_ptr = &set;
4043
            } else {
4044
                how = 0;
4045
                set_ptr = NULL;
4046
            }
4047
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4048
            if (!is_error(ret) && arg3) {
4049
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4050
                    goto efault;
4051
                host_to_target_old_sigset(p, &oldset);
4052
                unlock_user(p, arg3, sizeof(target_sigset_t));
4053
            }
4054
        }
4055
        break;
4056
#endif
4057
    case TARGET_NR_rt_sigprocmask:
4058
        {
4059
            int how = arg1;
4060
            sigset_t set, oldset, *set_ptr;
4061

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

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

    
4215
            ret = get_errno(getrlimit(resource, &rlim));
4216
            if (!is_error(ret)) {
4217
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4218
                    goto efault;
4219
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4220
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4221
                unlock_user_struct(target_rlim, arg2, 1);
4222
            }
4223
        }
4224
        break;
4225
    case TARGET_NR_getrusage:
4226
        {
4227
            struct rusage rusage;
4228
            ret = get_errno(getrusage(arg1, &rusage));
4229
            if (!is_error(ret)) {
4230
                host_to_target_rusage(arg2, &rusage);
4231
            }
4232
        }
4233
        break;
4234
    case TARGET_NR_gettimeofday:
4235
        {
4236
            struct timeval tv;
4237
            ret = get_errno(gettimeofday(&tv, NULL));
4238
            if (!is_error(ret)) {
4239
                if (copy_to_user_timeval(arg1, &tv))
4240
                    goto efault;
4241
            }
4242
        }
4243
        break;
4244
    case TARGET_NR_settimeofday:
4245
        {
4246
            struct timeval tv;
4247
            if (copy_from_user_timeval(&tv, arg1))
4248
                goto efault;
4249
            ret = get_errno(settimeofday(&tv, NULL));
4250
        }
4251
        break;
4252
#ifdef TARGET_NR_select
4253
    case TARGET_NR_select:
4254
        {
4255
            struct target_sel_arg_struct *sel;
4256
            abi_ulong inp, outp, exp, tvp;
4257
            long nsel;
4258

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

    
4466
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4467
                goto efault;
4468
            __put_user(stfs.f_type, &target_stfs->f_type);
4469
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4470
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4471
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4472
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4473
            __put_user(stfs.f_files, &target_stfs->f_files);
4474
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4475
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4476
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4477
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4478
            unlock_user_struct(target_stfs, arg2, 1);
4479
        }
4480
        break;
4481
    case TARGET_NR_fstatfs:
4482
        ret = get_errno(fstatfs(arg1, &stfs));
4483
        goto convert_statfs;
4484
#ifdef TARGET_NR_statfs64
4485
    case TARGET_NR_statfs64:
4486
        if (!(p = lock_user_string(arg1)))
4487
            goto efault;
4488
        ret = get_errno(statfs(path(p), &stfs));
4489
        unlock_user(p, arg1, 0);
4490
    convert_statfs64:
4491
        if (!is_error(ret)) {
4492
            struct target_statfs64 *target_stfs;
4493

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

    
4608
    case TARGET_NR_syslog:
4609
        if (!(p = lock_user_string(arg2)))
4610
            goto efault;
4611
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4612
        unlock_user(p, arg2, 0);
4613
        break;
4614

    
4615
    case TARGET_NR_setitimer:
4616
        {
4617
            struct itimerval value, ovalue, *pvalue;
4618

    
4619
            if (arg2) {
4620
                pvalue = &value;
4621
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4622
                    || copy_from_user_timeval(&pvalue->it_value,
4623
                                              arg2 + sizeof(struct target_timeval)))
4624
                    goto efault;
4625
            } else {
4626
                pvalue = NULL;
4627
            }
4628
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4629
            if (!is_error(ret) && arg3) {
4630
                if (copy_to_user_timeval(arg3,
4631
                                         &ovalue.it_interval)
4632
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4633
                                            &ovalue.it_value))
4634
                    goto efault;
4635
            }
4636
        }
4637
        break;
4638
    case TARGET_NR_getitimer:
4639
        {
4640
            struct itimerval value;
4641

    
4642
            ret = get_errno(getitimer(arg1, &value));
4643
            if (!is_error(ret) && arg2) {
4644
                if (copy_to_user_timeval(arg2,
4645
                                         &value.it_interval)
4646
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4647
                                            &value.it_value))
4648
                    goto efault;
4649
            }
4650
        }
4651
        break;
4652
    case TARGET_NR_stat:
4653
        if (!(p = lock_user_string(arg1)))
4654
            goto efault;
4655
        ret = get_errno(stat(path(p), &st));
4656
        unlock_user(p, arg1, 0);
4657
        goto do_stat;
4658
    case TARGET_NR_lstat:
4659
        if (!(p = lock_user_string(arg1)))
4660
            goto efault;
4661
        ret = get_errno(lstat(path(p), &st));
4662
        unlock_user(p, arg1, 0);
4663
        goto do_stat;
4664
    case TARGET_NR_fstat:
4665
        {
4666
            ret = get_errno(fstat(arg1, &st));
4667
        do_stat:
4668
            if (!is_error(ret)) {
4669
                struct target_stat *target_st;
4670

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

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

    
4884
            dirp = malloc(count);
4885
            if (!dirp) {
4886
                ret = -TARGET_ENOMEM;
4887
                goto fail;
4888
            }
4889

    
4890
            ret = get_errno(sys_getdents(arg1, dirp, count));
4891
            if (!is_error(ret)) {
4892
                struct linux_dirent *de;
4893
                struct target_dirent *tde;
4894
                int len = ret;
4895
                int reclen, treclen;
4896
                int count1, tnamelen;
4897

    
4898
                count1 = 0;
4899
                de = dirp;
4900
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4901
                    goto efault;
4902
                tde = target_dirp;
4903
                while (len > 0) {
4904
                    reclen = de->d_reclen;
4905
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4906
                    tde->d_reclen = tswap16(treclen);
4907
                    tde->d_ino = tswapl(de->d_ino);
4908
                    tde->d_off = tswapl(de->d_off);
4909
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4910
                    if (tnamelen > 256)
4911
                        tnamelen = 256;
4912
                    /* XXX: may not be correct */
4913
                    strncpy(tde->d_name, de->d_name, tnamelen);
4914
                    de = (struct linux_dirent *)((char *)de + reclen);
4915
                    len -= reclen;
4916
                    tde = (struct target_dirent *)((char *)tde + treclen);
4917
                    count1 += treclen;
4918
                }
4919
                ret = count1;
4920
                unlock_user(target_dirp, arg2, ret);
4921
            }
4922
            free(dirp);
4923
        }
4924
#else
4925
        {
4926
            struct linux_dirent *dirp;
4927
            abi_long count = arg3;
4928

    
4929
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4930
                goto efault;
4931
            ret = get_errno(sys_getdents(arg1, dirp, count));
4932
            if (!is_error(ret)) {
4933
                struct linux_dirent *de;
4934
                int len = ret;
4935
                int reclen;
4936
                de = dirp;
4937
                while (len > 0) {
4938
                    reclen = de->d_reclen;
4939
                    if (reclen > len)
4940
                        break;
4941
                    de->d_reclen = tswap16(reclen);
4942
                    tswapls(&de->d_ino);
4943
                    tswapls(&de->d_off);
4944
                    de = (struct linux_dirent *)((char *)de + reclen);
4945
                    len -= reclen;
4946
                }
4947
            }
4948
            unlock_user(dirp, arg2, ret);
4949
        }
4950
#endif
4951
        break;
4952
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
4953
    case TARGET_NR_getdents64:
4954
        {
4955
            struct linux_dirent64 *dirp;
4956
            abi_long count = arg3;
4957
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4958
                goto efault;
4959
            ret = get_errno(sys_getdents64(arg1, dirp, count));
4960
            if (!is_error(ret)) {
4961
                struct linux_dirent64 *de;
4962
                int len = ret;
4963
                int reclen;
4964
                de = dirp;
4965
                while (len > 0) {
4966
                    reclen = de->d_reclen;
4967
                    if (reclen > len)
4968
                        break;
4969
                    de->d_reclen = tswap16(reclen);
4970
                    tswap64s((uint64_t *)&de->d_ino);
4971
                    tswap64s((uint64_t *)&de->d_off);
4972
                    de = (struct linux_dirent64 *)((char *)de + reclen);
4973
                    len -= reclen;
4974
                }
4975
            }
4976
            unlock_user(dirp, arg2, ret);
4977
        }
4978
        break;
4979
#endif /* TARGET_NR_getdents64 */
4980
#ifdef TARGET_NR__newselect
4981
    case TARGET_NR__newselect:
4982
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
4983
        break;
4984
#endif
4985
#ifdef TARGET_NR_poll
4986
    case TARGET_NR_poll:
4987
        {
4988
            struct target_pollfd *target_pfd;
4989
            unsigned int nfds = arg2;
4990
            int timeout = arg3;
4991
            struct pollfd *pfd;
4992
            unsigned int i;
4993

    
4994
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
4995
            if (!target_pfd)
4996
                goto efault;
4997
            pfd = alloca(sizeof(struct pollfd) * nfds);
4998
            for(i = 0; i < nfds; i++) {
4999
                pfd[i].fd = tswap32(target_pfd[i].fd);
5000
                pfd[i].events = tswap16(target_pfd[i].events);
5001
            }
5002
            ret = get_errno(poll(pfd, nfds, timeout));
5003
            if (!is_error(ret)) {
5004
                for(i = 0; i < nfds; i++) {
5005
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5006
                }
5007
                ret += nfds * (sizeof(struct target_pollfd)
5008
                               - sizeof(struct pollfd));
5009
            }
5010
            unlock_user(target_pfd, arg1, ret);
5011
        }
5012
        break;
5013
#endif
5014
    case TARGET_NR_flock:
5015
        /* NOTE: the flock constant seems to be the same for every
5016
           Linux platform */
5017
        ret = get_errno(flock(arg1, arg2));
5018
        break;
5019
    case TARGET_NR_readv:
5020
        {
5021
            int count = arg3;
5022
            struct iovec *vec;
5023

    
5024
            vec = alloca(count * sizeof(struct iovec));
5025
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5026
                goto efault;
5027
            ret = get_errno(readv(arg1, vec, count));
5028
            unlock_iovec(vec, arg2, count, 1);
5029
        }
5030
        break;
5031
    case TARGET_NR_writev:
5032
        {
5033
            int count = arg3;
5034
            struct iovec *vec;
5035

    
5036
            vec = alloca(count * sizeof(struct iovec));
5037
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5038
                goto efault;
5039
            ret = get_errno(writev(arg1, vec, count));
5040
            unlock_iovec(vec, arg2, count, 0);
5041
        }
5042
        break;
5043
    case TARGET_NR_getsid:
5044
        ret = get_errno(getsid(arg1));
5045
        break;
5046
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5047
    case TARGET_NR_fdatasync:
5048
        ret = get_errno(fdatasync(arg1));
5049
        break;
5050
#endif
5051
    case TARGET_NR__sysctl:
5052
        /* We don't implement this, but ENOTDIR is always a safe
5053
           return value. */
5054
        ret = -TARGET_ENOTDIR;
5055
        break;
5056
    case TARGET_NR_sched_setparam:
5057
        {
5058
            struct sched_param *target_schp;
5059
            struct sched_param schp;
5060

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

    
5324
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5325
            ret = get_errno(getgroups(gidsetsize, grouplist));
5326
            if (gidsetsize == 0)
5327
                break;
5328
            if (!is_error(ret)) {
5329
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5330
                if (!target_grouplist)
5331
                    goto efault;
5332
                for(i = 0;i < ret; i++)
5333
                    target_grouplist[i] = tswap16(grouplist[i]);
5334
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5335
            }
5336
        }
5337
        break;
5338
    case TARGET_NR_setgroups:
5339
        {
5340
            int gidsetsize = arg1;
5341
            uint16_t *target_grouplist;
5342
            gid_t *grouplist;
5343
            int i;
5344

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

    
5430
#ifdef TARGET_NR_lchown32
5431
    case TARGET_NR_lchown32:
5432
        if (!(p = lock_user_string(arg1)))
5433
            goto efault;
5434
        ret = get_errno(lchown(p, arg2, arg3));
5435
        unlock_user(p, arg1, 0);
5436
        break;
5437
#endif
5438
#ifdef TARGET_NR_getuid32
5439
    case TARGET_NR_getuid32:
5440
        ret = get_errno(getuid());
5441
        break;
5442
#endif
5443
#ifdef TARGET_NR_getgid32
5444
    case TARGET_NR_getgid32:
5445
        ret = get_errno(getgid());
5446
        break;
5447
#endif
5448
#ifdef TARGET_NR_geteuid32
5449
    case TARGET_NR_geteuid32:
5450
        ret = get_errno(geteuid());
5451
        break;
5452
#endif
5453
#ifdef TARGET_NR_getegid32
5454
    case TARGET_NR_getegid32:
5455
        ret = get_errno(getegid());
5456
        break;
5457
#endif
5458
#ifdef TARGET_NR_setreuid32
5459
    case TARGET_NR_setreuid32:
5460
        ret = get_errno(setreuid(arg1, arg2));
5461
        break;
5462
#endif
5463
#ifdef TARGET_NR_setregid32
5464
    case TARGET_NR_setregid32:
5465
        ret = get_errno(setregid(arg1, arg2));
5466
        break;
5467
#endif
5468
#ifdef TARGET_NR_getgroups32
5469
    case TARGET_NR_getgroups32:
5470
        {
5471
            int gidsetsize = arg1;
5472
            uint32_t *target_grouplist;
5473
            gid_t *grouplist;
5474
            int i;
5475

    
5476
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5477
            ret = get_errno(getgroups(gidsetsize, grouplist));
5478
            if (gidsetsize == 0)
5479
                break;
5480
            if (!is_error(ret)) {
5481
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5482
                if (!target_grouplist) {
5483
                    ret = -TARGET_EFAULT;
5484
                    goto fail;
5485
                }
5486
                for(i = 0;i < ret; i++)
5487
                    target_grouplist[i] = tswap32(grouplist[i]);
5488
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
5489
            }
5490
        }
5491
        break;
5492
#endif
5493
#ifdef TARGET_NR_setgroups32
5494
    case TARGET_NR_setgroups32:
5495
        {
5496
            int gidsetsize = arg1;
5497
            uint32_t *target_grouplist;
5498
            gid_t *grouplist;
5499
            int i;
5500

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

    
5586
    case TARGET_NR_pivot_root:
5587
        goto unimplemented;
5588
#ifdef TARGET_NR_mincore
5589
    case TARGET_NR_mincore:
5590
        {
5591
            void *a;
5592
            ret = -TARGET_EFAULT;
5593
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5594
                goto efault;
5595
            if (!(p = lock_user_string(arg3)))
5596
                goto mincore_fail;
5597
            ret = get_errno(mincore(a, arg2, p));
5598
            unlock_user(p, arg3, ret);
5599
            mincore_fail:
5600
            unlock_user(a, arg1, 0);
5601
        }
5602
        break;
5603
#endif
5604
#ifdef TARGET_NR_arm_fadvise64_64
5605
    case TARGET_NR_arm_fadvise64_64:
5606
        {
5607
                /*
5608
                 * arm_fadvise64_64 looks like fadvise64_64 but
5609
                 * with different argument order
5610
                 */
5611
                abi_long temp;
5612
                temp = arg3;
5613
                arg3 = arg4;
5614
                arg4 = temp;
5615
        }
5616
#endif
5617
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5618
#ifdef TARGET_NR_fadvise64_64
5619
    case TARGET_NR_fadvise64_64:
5620
#endif
5621
        /* This is a hint, so ignoring and returning success is ok.  */
5622
        ret = get_errno(0);
5623
        break;
5624
#endif
5625
#ifdef TARGET_NR_madvise
5626
    case TARGET_NR_madvise:
5627
        /* A straight passthrough may not be safe because qemu sometimes
5628
           turns private flie-backed mappings into anonymous mappings.
5629
           This will break MADV_DONTNEED.
5630
           This is a hint, so ignoring and returning success is ok.  */
5631
        ret = get_errno(0);
5632
        break;
5633
#endif
5634
#if TARGET_ABI_BITS == 32
5635
    case TARGET_NR_fcntl64:
5636
    {
5637
        int cmd;
5638
        struct flock64 fl;
5639
        struct target_flock64 *target_fl;
5640
#ifdef TARGET_ARM
5641
        struct target_eabi_flock64 *target_efl;
5642
#endif
5643

    
5644
        switch(arg2){
5645
        case TARGET_F_GETLK64:
5646
            cmd = F_GETLK64;
5647
            break;
5648
        case TARGET_F_SETLK64:
5649
            cmd = F_SETLK64;
5650
            break;
5651
        case TARGET_F_SETLKW64:
5652
            cmd = F_SETLK64;
5653
            break;
5654
        default:
5655
            cmd = arg2;
5656
            break;
5657
        }
5658

    
5659
        switch(arg2) {
5660
        case TARGET_F_GETLK64:
5661
#ifdef TARGET_ARM
5662
            if (((CPUARMState *)cpu_env)->eabi) {
5663
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5664
                    goto efault;
5665
                fl.l_type = tswap16(target_efl->l_type);
5666
                fl.l_whence = tswap16(target_efl->l_whence);
5667
                fl.l_start = tswap64(target_efl->l_start);
5668
                fl.l_len = tswap64(target_efl->l_len);
5669
                fl.l_pid = tswapl(target_efl->l_pid);
5670
                unlock_user_struct(target_efl, arg3, 0);
5671
            } else
5672
#endif
5673
            {
5674
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5675
                    goto efault;
5676
                fl.l_type = tswap16(target_fl->l_type);
5677
                fl.l_whence = tswap16(target_fl->l_whence);
5678
                fl.l_start = tswap64(target_fl->l_start);
5679
                fl.l_len = tswap64(target_fl->l_len);
5680
                fl.l_pid = tswapl(target_fl->l_pid);
5681
                unlock_user_struct(target_fl, arg3, 0);
5682
            }
5683
            ret = get_errno(fcntl(arg1, cmd, &fl));
5684
            if (ret == 0) {
5685
#ifdef TARGET_ARM
5686
                if (((CPUARMState *)cpu_env)->eabi) {
5687
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
5688
                        goto efault;
5689
                    target_efl->l_type = tswap16(fl.l_type);
5690
                    target_efl->l_whence = tswap16(fl.l_whence);
5691
                    target_efl->l_start = tswap64(fl.l_start);
5692
                    target_efl->l_len = tswap64(fl.l_len);
5693
                    target_efl->l_pid = tswapl(fl.l_pid);
5694
                    unlock_user_struct(target_efl, arg3, 1);
5695
                } else
5696
#endif
5697
                {
5698
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
5699
                        goto efault;
5700
                    target_fl->l_type = tswap16(fl.l_type);
5701
                    target_fl->l_whence = tswap16(fl.l_whence);
5702
                    target_fl->l_start = tswap64(fl.l_start);
5703
                    target_fl->l_len = tswap64(fl.l_len);
5704
                    target_fl->l_pid = tswapl(fl.l_pid);
5705
                    unlock_user_struct(target_fl, arg3, 1);
5706
                }
5707
            }
5708
            break;
5709

    
5710
        case TARGET_F_SETLK64:
5711
        case TARGET_F_SETLKW64:
5712
#ifdef TARGET_ARM
5713
            if (((CPUARMState *)cpu_env)->eabi) {
5714
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5715
                    goto efault;
5716
                fl.l_type = tswap16(target_efl->l_type);
5717
                fl.l_whence = tswap16(target_efl->l_whence);
5718
                fl.l_start = tswap64(target_efl->l_start);
5719
                fl.l_len = tswap64(target_efl->l_len);
5720
                fl.l_pid = tswapl(target_efl->l_pid);
5721
                unlock_user_struct(target_efl, arg3, 0);
5722
            } else
5723
#endif
5724
            {
5725
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5726
                    goto efault;
5727
                fl.l_type = tswap16(target_fl->l_type);
5728
                fl.l_whence = tswap16(target_fl->l_whence);
5729
                fl.l_start = tswap64(target_fl->l_start);
5730
                fl.l_len = tswap64(target_fl->l_len);
5731
                fl.l_pid = tswapl(target_fl->l_pid);
5732
                unlock_user_struct(target_fl, arg3, 0);
5733
            }
5734
            ret = get_errno(fcntl(arg1, cmd, &fl));
5735
            break;
5736
        default:
5737
            ret = do_fcntl(arg1, cmd, arg3);
5738
            break;
5739
        }
5740
        break;
5741
    }
5742
#endif
5743
#ifdef TARGET_NR_cacheflush
5744
    case TARGET_NR_cacheflush:
5745
        /* self-modifying code is handled automatically, so nothing needed */
5746
        ret = 0;
5747
        break;
5748
#endif
5749
#ifdef TARGET_NR_security
5750
    case TARGET_NR_security:
5751
        goto unimplemented;
5752
#endif
5753
#ifdef TARGET_NR_getpagesize
5754
    case TARGET_NR_getpagesize:
5755
        ret = TARGET_PAGE_SIZE;
5756
        break;
5757
#endif
5758
    case TARGET_NR_gettid:
5759
        ret = get_errno(gettid());
5760
        break;
5761
#ifdef TARGET_NR_readahead
5762
    case TARGET_NR_readahead:
5763
#if TARGET_ABI_BITS == 32
5764
#ifdef TARGET_ARM
5765
        if (((CPUARMState *)cpu_env)->eabi)
5766
        {
5767
            arg2 = arg3;
5768
            arg3 = arg4;
5769
            arg4 = arg5;
5770
        }
5771
#endif
5772
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
5773
#else
5774
        ret = get_errno(readahead(arg1, arg2, arg3));
5775
#endif
5776
        break;
5777
#endif
5778
#ifdef TARGET_NR_setxattr
5779
    case TARGET_NR_setxattr:
5780
    case TARGET_NR_lsetxattr:
5781
    case TARGET_NR_fsetxattr:
5782
    case TARGET_NR_getxattr:
5783
    case TARGET_NR_lgetxattr:
5784
    case TARGET_NR_fgetxattr:
5785
    case TARGET_NR_listxattr:
5786
    case TARGET_NR_llistxattr:
5787
    case TARGET_NR_flistxattr:
5788
    case TARGET_NR_removexattr:
5789
    case TARGET_NR_lremovexattr:
5790
    case TARGET_NR_fremovexattr:
5791
        goto unimplemented_nowarn;
5792
#endif
5793
#ifdef TARGET_NR_set_thread_area
5794
    case TARGET_NR_set_thread_area:
5795
#if defined(TARGET_MIPS)
5796
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5797
      ret = 0;
5798
      break;
5799
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
5800
      ret = do_set_thread_area(cpu_env, arg1);
5801
      break;
5802
#else
5803
      goto unimplemented_nowarn;
5804
#endif
5805
#endif
5806
#ifdef TARGET_NR_get_thread_area
5807
    case TARGET_NR_get_thread_area:
5808
#if defined(TARGET_I386) && defined(TARGET_ABI32)
5809
        ret = do_get_thread_area(cpu_env, arg1);
5810
#else
5811
        goto unimplemented_nowarn;
5812
#endif
5813
#endif
5814
#ifdef TARGET_NR_getdomainname
5815
    case TARGET_NR_getdomainname:
5816
        goto unimplemented_nowarn;
5817
#endif
5818

    
5819
#ifdef TARGET_NR_clock_gettime
5820
    case TARGET_NR_clock_gettime:
5821
    {
5822
        struct timespec ts;
5823
        ret = get_errno(clock_gettime(arg1, &ts));
5824
        if (!is_error(ret)) {
5825
            host_to_target_timespec(arg2, &ts);
5826
        }
5827
        break;
5828
    }
5829
#endif
5830
#ifdef TARGET_NR_clock_getres
5831
    case TARGET_NR_clock_getres:
5832
    {
5833
        struct timespec ts;
5834
        ret = get_errno(clock_getres(arg1, &ts));
5835
        if (!is_error(ret)) {
5836
            host_to_target_timespec(arg2, &ts);
5837
        }
5838
        break;
5839
    }
5840
#endif
5841
#ifdef TARGET_NR_clock_nanosleep
5842
    case TARGET_NR_clock_nanosleep:
5843
    {
5844
        struct timespec ts;
5845
        target_to_host_timespec(&ts, arg3);
5846
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5847
        if (arg4)
5848
            host_to_target_timespec(arg4, &ts);
5849
        break;
5850
    }
5851
#endif
5852

    
5853
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5854
    case TARGET_NR_set_tid_address:
5855
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
5856
        break;
5857
#endif
5858

    
5859
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5860
    case TARGET_NR_tkill:
5861
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5862
        break;
5863
#endif
5864

    
5865
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5866
    case TARGET_NR_tgkill:
5867
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5868
                        target_to_host_signal(arg3)));
5869
        break;
5870
#endif
5871

    
5872
#ifdef TARGET_NR_set_robust_list
5873
    case TARGET_NR_set_robust_list:
5874
        goto unimplemented_nowarn;
5875
#endif
5876

    
5877
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5878
    case TARGET_NR_utimensat:
5879
        {
5880
            struct timespec ts[2];
5881
            target_to_host_timespec(ts, arg3);
5882
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5883
            if (!arg2)
5884
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5885
            else {
5886
                if (!(p = lock_user_string(arg2))) {
5887
                    ret = -TARGET_EFAULT;
5888
                    goto fail;
5889
                }
5890
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
5891
                unlock_user(p, arg2, 0);
5892
            }
5893
        }
5894
        break;
5895
#endif
5896
#if defined(USE_NPTL)
5897
    case TARGET_NR_futex:
5898
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
5899
        break;
5900
#endif
5901
#ifdef TARGET_NR_inotify_init
5902
    case TARGET_NR_inotify_init:
5903
        ret = get_errno(sys_inotify_init());
5904
        break;
5905
#endif
5906
#ifdef TARGET_NR_inotify_add_watch
5907
    case TARGET_NR_inotify_add_watch:
5908
        p = lock_user_string(arg2);
5909
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
5910
        unlock_user(p, arg2, 0);
5911
        break;
5912
#endif
5913
#ifdef TARGET_NR_inotify_rm_watch
5914
    case TARGET_NR_inotify_rm_watch:
5915
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
5916
        break;
5917
#endif
5918

    
5919
    default:
5920
    unimplemented:
5921
        gemu_log("qemu: Unsupported syscall: %d\n", num);
5922
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
5923
    unimplemented_nowarn:
5924
#endif
5925
        ret = -TARGET_ENOSYS;
5926
        break;
5927
    }
5928
fail:
5929
#ifdef DEBUG
5930
    gemu_log(" = %ld\n", ret);
5931
#endif
5932
    if(do_strace)
5933
        print_syscall_ret(num, ret);
5934
    return ret;
5935
efault:
5936
    ret = -TARGET_EFAULT;
5937
    goto fail;
5938
}