Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 6a24a778

History | View | Annotate | Download (180.9 kB)

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

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

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

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

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

    
87
//#define DEBUG
88

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

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

    
99

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

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

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

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

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

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

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

    
145

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

    
154

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

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

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

    
274
extern int personality(int);
275
extern int flock(int, int);
276
extern int setfsuid(int);
277
extern int setfsgid(int);
278
extern int setgroups(int, gid_t *);
279

    
280
#define ERRNO_TABLE_SIZE 1200
281

    
282
/* target_to_host_errno_table[] is initialized from
283
 * host_to_target_errno_table[] in syscall_init(). */
284
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
285
};
286

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

    
399
static inline int host_to_target_errno(int err)
400
{
401
    if(host_to_target_errno_table[err])
402
        return host_to_target_errno_table[err];
403
    return err;
404
}
405

    
406
static inline int target_to_host_errno(int err)
407
{
408
    if (target_to_host_errno_table[err])
409
        return target_to_host_errno_table[err];
410
    return err;
411
}
412

    
413
static inline abi_long get_errno(abi_long ret)
414
{
415
    if (ret == -1)
416
        return -host_to_target_errno(errno);
417
    else
418
        return ret;
419
}
420

    
421
static inline int is_error(abi_long ret)
422
{
423
    return (abi_ulong)ret >= (abi_ulong)(-4096);
424
}
425

    
426
char *target_strerror(int err)
427
{
428
    return strerror(target_to_host_errno(err));
429
}
430

    
431
static abi_ulong target_brk;
432
static abi_ulong target_original_brk;
433

    
434
void target_set_brk(abi_ulong new_brk)
435
{
436
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
437
}
438

    
439
/* do_brk() must return target values and target errnos. */
440
abi_long do_brk(abi_ulong new_brk)
441
{
442
    abi_ulong brk_page;
443
    abi_long mapped_addr;
444
    int        new_alloc_size;
445

    
446
    if (!new_brk)
447
        return target_brk;
448
    if (new_brk < target_original_brk)
449
        return target_brk;
450

    
451
    brk_page = HOST_PAGE_ALIGN(target_brk);
452

    
453
    /* If the new brk is less than this, set it and we're done... */
454
    if (new_brk < brk_page) {
455
        target_brk = new_brk;
456
            return target_brk;
457
    }
458

    
459
    /* We need to allocate more memory after the brk... */
460
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
461
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
462
                                        PROT_READ|PROT_WRITE,
463
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
464

    
465
    if (!is_error(mapped_addr))
466
        target_brk = new_brk;
467
    
468
    return target_brk;
469
}
470

    
471
static inline abi_long copy_from_user_fdset(fd_set *fds,
472
                                            abi_ulong target_fds_addr,
473
                                            int n)
474
{
475
    int i, nw, j, k;
476
    abi_ulong b, *target_fds;
477

    
478
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
479
    if (!(target_fds = lock_user(VERIFY_READ,
480
                                 target_fds_addr,
481
                                 sizeof(abi_ulong) * nw,
482
                                 1)))
483
        return -TARGET_EFAULT;
484

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

    
498
    unlock_user(target_fds, target_fds_addr, 0);
499

    
500
    return 0;
501
}
502

    
503
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
504
                                          const fd_set *fds,
505
                                          int n)
506
{
507
    int i, nw, j, k;
508
    abi_long v;
509
    abi_ulong *target_fds;
510

    
511
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
512
    if (!(target_fds = lock_user(VERIFY_WRITE,
513
                                 target_fds_addr,
514
                                 sizeof(abi_ulong) * nw,
515
                                 0)))
516
        return -TARGET_EFAULT;
517

    
518
    k = 0;
519
    for (i = 0; i < nw; i++) {
520
        v = 0;
521
        for (j = 0; j < TARGET_ABI_BITS; j++) {
522
            v |= ((FD_ISSET(k, fds) != 0) << j);
523
            k++;
524
        }
525
        __put_user(v, &target_fds[i]);
526
    }
527

    
528
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
529

    
530
    return 0;
531
}
532

    
533
#if defined(__alpha__)
534
#define HOST_HZ 1024
535
#else
536
#define HOST_HZ 100
537
#endif
538

    
539
static inline abi_long host_to_target_clock_t(long ticks)
540
{
541
#if HOST_HZ == TARGET_HZ
542
    return ticks;
543
#else
544
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
545
#endif
546
}
547

    
548
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
549
                                             const struct rusage *rusage)
550
{
551
    struct target_rusage *target_rusage;
552

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

    
575
    return 0;
576
}
577

    
578
static inline abi_long copy_from_user_timeval(struct timeval *tv,
579
                                              abi_ulong target_tv_addr)
580
{
581
    struct target_timeval *target_tv;
582

    
583
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
584
        return -TARGET_EFAULT;
585

    
586
    __get_user(tv->tv_sec, &target_tv->tv_sec);
587
    __get_user(tv->tv_usec, &target_tv->tv_usec);
588

    
589
    unlock_user_struct(target_tv, target_tv_addr, 0);
590

    
591
    return 0;
592
}
593

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

    
599
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
600
        return -TARGET_EFAULT;
601

    
602
    __put_user(tv->tv_sec, &target_tv->tv_sec);
603
    __put_user(tv->tv_usec, &target_tv->tv_usec);
604

    
605
    unlock_user_struct(target_tv, target_tv_addr, 1);
606

    
607
    return 0;
608
}
609

    
610

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

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

    
643
    if (target_tv_addr) {
644
        if (copy_from_user_timeval(&tv, target_tv_addr))
645
            return -TARGET_EFAULT;
646
        tv_ptr = &tv;
647
    } else {
648
        tv_ptr = NULL;
649
    }
650

    
651
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
652

    
653
    if (!is_error(ret)) {
654
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
655
            return -TARGET_EFAULT;
656
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
657
            return -TARGET_EFAULT;
658
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
659
            return -TARGET_EFAULT;
660

    
661
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
662
            return -TARGET_EFAULT;
663
    }
664

    
665
    return ret;
666
}
667

    
668
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
669
                                               abi_ulong target_addr,
670
                                               socklen_t len)
671
{
672
    struct target_sockaddr *target_saddr;
673

    
674
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
675
    if (!target_saddr)
676
        return -TARGET_EFAULT;
677
    memcpy(addr, target_saddr, len);
678
    addr->sa_family = tswap16(target_saddr->sa_family);
679
    unlock_user(target_saddr, target_addr, 0);
680

    
681
    return 0;
682
}
683

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

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

    
697
    return 0;
698
}
699

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

    
718
    while (cmsg && target_cmsg) {
719
        void *data = CMSG_DATA(cmsg);
720
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
721

    
722
        int len = tswapl(target_cmsg->cmsg_len)
723
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
724

    
725
        space += CMSG_SPACE(len);
726
        if (space > msgh->msg_controllen) {
727
            space -= CMSG_SPACE(len);
728
            gemu_log("Host cmsg overflow\n");
729
            break;
730
        }
731

    
732
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
733
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
734
        cmsg->cmsg_len = CMSG_LEN(len);
735

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

    
744
            for (i = 0; i < numfds; i++)
745
                fd[i] = tswap32(target_fd[i]);
746
        }
747

    
748
        cmsg = CMSG_NXTHDR(msgh, cmsg);
749
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
750
    }
751
    unlock_user(target_cmsg, target_cmsg_addr, 0);
752
 the_end:
753
    msgh->msg_controllen = space;
754
    return 0;
755
}
756

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

    
767
    msg_controllen = tswapl(target_msgh->msg_controllen);
768
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
769
        goto the_end;
770
    target_cmsg_addr = tswapl(target_msgh->msg_control);
771
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
772
    if (!target_cmsg)
773
        return -TARGET_EFAULT;
774

    
775
    while (cmsg && target_cmsg) {
776
        void *data = CMSG_DATA(cmsg);
777
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
778

    
779
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
780

    
781
        space += TARGET_CMSG_SPACE(len);
782
        if (space > msg_controllen) {
783
            space -= TARGET_CMSG_SPACE(len);
784
            gemu_log("Target cmsg overflow\n");
785
            break;
786
        }
787

    
788
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
789
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
790
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
791

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

    
800
            for (i = 0; i < numfds; i++)
801
                target_fd[i] = tswap32(fd[i]);
802
        }
803

    
804
        cmsg = CMSG_NXTHDR(msgh, cmsg);
805
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
806
    }
807
    unlock_user(target_cmsg, target_cmsg_addr, space);
808
 the_end:
809
    target_msgh->msg_controllen = tswapl(space);
810
    return 0;
811
}
812

    
813
/* do_setsockopt() Must return target values and target errnos. */
814
static abi_long do_setsockopt(int sockfd, int level, int optname,
815
                              abi_ulong optval_addr, socklen_t optlen)
816
{
817
    abi_long ret;
818
    int val;
819

    
820
    switch(level) {
821
    case SOL_TCP:
822
        /* TCP options all take an 'int' value.  */
823
        if (optlen < sizeof(uint32_t))
824
            return -TARGET_EINVAL;
825

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

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

    
939
/* do_getsockopt() Must return target values and target errnos. */
940
static abi_long do_getsockopt(int sockfd, int level, int optname,
941
                              abi_ulong optval_addr, abi_ulong optlen)
942
{
943
    abi_long ret;
944
    int len, lv, val;
945

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

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

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

    
1076
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1077
                             int count, int copy)
1078
{
1079
    struct target_iovec *target_vec;
1080
    abi_ulong base;
1081
    int i;
1082

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

    
1092
    return 0;
1093
}
1094

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

    
1125
/* do_bind() Must return target values and target errnos. */
1126
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1127
                        socklen_t addrlen)
1128
{
1129
    void *addr = alloca(addrlen);
1130

    
1131
    target_to_host_sockaddr(addr, target_addr, addrlen);
1132
    return get_errno(bind(sockfd, addr, addrlen));
1133
}
1134

    
1135
/* do_connect() Must return target values and target errnos. */
1136
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1137
                           socklen_t addrlen)
1138
{
1139
    void *addr = alloca(addrlen);
1140

    
1141
    target_to_host_sockaddr(addr, target_addr, addrlen);
1142
    return get_errno(connect(sockfd, addr, addrlen));
1143
}
1144

    
1145
/* do_sendrecvmsg() Must return target values and target errnos. */
1146
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1147
                               int flags, int send)
1148
{
1149
    abi_long ret;
1150
    struct target_msghdr *msgp;
1151
    struct msghdr msg;
1152
    int count;
1153
    struct iovec *vec;
1154
    abi_ulong target_vec;
1155

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

    
1175
    count = tswapl(msgp->msg_iovlen);
1176
    vec = alloca(count * sizeof(struct iovec));
1177
    target_vec = tswapl(msgp->msg_iov);
1178
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1179
    msg.msg_iovlen = count;
1180
    msg.msg_iov = vec;
1181

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

    
1196
/* do_accept() Must return target values and target errnos. */
1197
static abi_long do_accept(int fd, abi_ulong target_addr,
1198
                          abi_ulong target_addrlen_addr)
1199
{
1200
    socklen_t addrlen;
1201
    void *addr;
1202
    abi_long ret;
1203

    
1204
    if (get_user_u32(addrlen, target_addrlen_addr))
1205
        return -TARGET_EFAULT;
1206

    
1207
    addr = alloca(addrlen);
1208

    
1209
    ret = get_errno(accept(fd, addr, &addrlen));
1210
    if (!is_error(ret)) {
1211
        host_to_target_sockaddr(target_addr, addr, addrlen);
1212
        if (put_user_u32(addrlen, target_addrlen_addr))
1213
            ret = -TARGET_EFAULT;
1214
    }
1215
    return ret;
1216
}
1217

    
1218
/* do_getpeername() Must return target values and target errnos. */
1219
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1220
                               abi_ulong target_addrlen_addr)
1221
{
1222
    socklen_t addrlen;
1223
    void *addr;
1224
    abi_long ret;
1225

    
1226
    if (get_user_u32(addrlen, target_addrlen_addr))
1227
        return -TARGET_EFAULT;
1228

    
1229
    addr = alloca(addrlen);
1230

    
1231
    ret = get_errno(getpeername(fd, addr, &addrlen));
1232
    if (!is_error(ret)) {
1233
        host_to_target_sockaddr(target_addr, addr, addrlen);
1234
        if (put_user_u32(addrlen, target_addrlen_addr))
1235
            ret = -TARGET_EFAULT;
1236
    }
1237
    return ret;
1238
}
1239

    
1240
/* do_getsockname() Must return target values and target errnos. */
1241
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1242
                               abi_ulong target_addrlen_addr)
1243
{
1244
    socklen_t addrlen;
1245
    void *addr;
1246
    abi_long ret;
1247

    
1248
    if (get_user_u32(addrlen, target_addrlen_addr))
1249
        return -TARGET_EFAULT;
1250

    
1251
    addr = alloca(addrlen);
1252

    
1253
    ret = get_errno(getsockname(fd, addr, &addrlen));
1254
    if (!is_error(ret)) {
1255
        host_to_target_sockaddr(target_addr, addr, addrlen);
1256
        if (put_user_u32(addrlen, target_addrlen_addr))
1257
            ret = -TARGET_EFAULT;
1258
    }
1259
    return ret;
1260
}
1261

    
1262
/* do_socketpair() Must return target values and target errnos. */
1263
static abi_long do_socketpair(int domain, int type, int protocol,
1264
                              abi_ulong target_tab_addr)
1265
{
1266
    int tab[2];
1267
    abi_long ret;
1268

    
1269
    ret = get_errno(socketpair(domain, type, protocol, tab));
1270
    if (!is_error(ret)) {
1271
        if (put_user_s32(tab[0], target_tab_addr)
1272
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1273
            ret = -TARGET_EFAULT;
1274
    }
1275
    return ret;
1276
}
1277

    
1278
/* do_sendto() Must return target values and target errnos. */
1279
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1280
                          abi_ulong target_addr, socklen_t addrlen)
1281
{
1282
    void *addr;
1283
    void *host_msg;
1284
    abi_long ret;
1285

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

    
1300
/* do_recvfrom() Must return target values and target errnos. */
1301
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1302
                            abi_ulong target_addr,
1303
                            abi_ulong target_addrlen)
1304
{
1305
    socklen_t addrlen;
1306
    void *addr;
1307
    void *host_msg;
1308
    abi_long ret;
1309

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

    
1340
#ifdef TARGET_NR_socketcall
1341
/* do_socketcall() Must return target values and target errnos. */
1342
static abi_long do_socketcall(int num, abi_ulong vptr)
1343
{
1344
    abi_long ret;
1345
    const int n = sizeof(abi_ulong);
1346

    
1347
    switch(num) {
1348
    case SOCKOP_socket:
1349
        {
1350
            int domain, type, protocol;
1351

    
1352
            if (get_user_s32(domain, vptr)
1353
                || get_user_s32(type, vptr + n)
1354
                || get_user_s32(protocol, vptr + 2 * n))
1355
                return -TARGET_EFAULT;
1356

    
1357
            ret = do_socket(domain, type, protocol);
1358
        }
1359
        break;
1360
    case SOCKOP_bind:
1361
        {
1362
            int sockfd;
1363
            abi_ulong target_addr;
1364
            socklen_t addrlen;
1365

    
1366
            if (get_user_s32(sockfd, vptr)
1367
                || get_user_ual(target_addr, vptr + n)
1368
                || get_user_u32(addrlen, vptr + 2 * n))
1369
                return -TARGET_EFAULT;
1370

    
1371
            ret = do_bind(sockfd, target_addr, addrlen);
1372
        }
1373
        break;
1374
    case SOCKOP_connect:
1375
        {
1376
            int sockfd;
1377
            abi_ulong target_addr;
1378
            socklen_t addrlen;
1379

    
1380
            if (get_user_s32(sockfd, vptr)
1381
                || get_user_ual(target_addr, vptr + n)
1382
                || get_user_u32(addrlen, vptr + 2 * n))
1383
                return -TARGET_EFAULT;
1384

    
1385
            ret = do_connect(sockfd, target_addr, addrlen);
1386
        }
1387
        break;
1388
    case SOCKOP_listen:
1389
        {
1390
            int sockfd, backlog;
1391

    
1392
            if (get_user_s32(sockfd, vptr)
1393
                || get_user_s32(backlog, vptr + n))
1394
                return -TARGET_EFAULT;
1395

    
1396
            ret = get_errno(listen(sockfd, backlog));
1397
        }
1398
        break;
1399
    case SOCKOP_accept:
1400
        {
1401
            int sockfd;
1402
            abi_ulong target_addr, target_addrlen;
1403

    
1404
            if (get_user_s32(sockfd, vptr)
1405
                || get_user_ual(target_addr, vptr + n)
1406
                || get_user_u32(target_addrlen, vptr + 2 * n))
1407
                return -TARGET_EFAULT;
1408

    
1409
            ret = do_accept(sockfd, target_addr, target_addrlen);
1410
        }
1411
        break;
1412
    case SOCKOP_getsockname:
1413
        {
1414
            int sockfd;
1415
            abi_ulong target_addr, target_addrlen;
1416

    
1417
            if (get_user_s32(sockfd, vptr)
1418
                || get_user_ual(target_addr, vptr + n)
1419
                || get_user_u32(target_addrlen, vptr + 2 * n))
1420
                return -TARGET_EFAULT;
1421

    
1422
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1423
        }
1424
        break;
1425
    case SOCKOP_getpeername:
1426
        {
1427
            int sockfd;
1428
            abi_ulong target_addr, target_addrlen;
1429

    
1430
            if (get_user_s32(sockfd, vptr)
1431
                || get_user_ual(target_addr, vptr + n)
1432
                || get_user_u32(target_addrlen, vptr + 2 * n))
1433
                return -TARGET_EFAULT;
1434

    
1435
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1436
        }
1437
        break;
1438
    case SOCKOP_socketpair:
1439
        {
1440
            int domain, type, protocol;
1441
            abi_ulong tab;
1442

    
1443
            if (get_user_s32(domain, vptr)
1444
                || get_user_s32(type, vptr + n)
1445
                || get_user_s32(protocol, vptr + 2 * n)
1446
                || get_user_ual(tab, vptr + 3 * n))
1447
                return -TARGET_EFAULT;
1448

    
1449
            ret = do_socketpair(domain, type, protocol, tab);
1450
        }
1451
        break;
1452
    case SOCKOP_send:
1453
        {
1454
            int sockfd;
1455
            abi_ulong msg;
1456
            size_t len;
1457
            int flags;
1458

    
1459
            if (get_user_s32(sockfd, vptr)
1460
                || get_user_ual(msg, vptr + n)
1461
                || get_user_ual(len, vptr + 2 * n)
1462
                || get_user_s32(flags, vptr + 3 * n))
1463
                return -TARGET_EFAULT;
1464

    
1465
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1466
        }
1467
        break;
1468
    case SOCKOP_recv:
1469
        {
1470
            int sockfd;
1471
            abi_ulong msg;
1472
            size_t len;
1473
            int flags;
1474

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

    
1481
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1482
        }
1483
        break;
1484
    case SOCKOP_sendto:
1485
        {
1486
            int sockfd;
1487
            abi_ulong msg;
1488
            size_t len;
1489
            int flags;
1490
            abi_ulong addr;
1491
            socklen_t addrlen;
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
                || get_user_ual(addr, vptr + 4 * n)
1498
                || get_user_u32(addrlen, vptr + 5 * n))
1499
                return -TARGET_EFAULT;
1500

    
1501
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1502
        }
1503
        break;
1504
    case SOCKOP_recvfrom:
1505
        {
1506
            int sockfd;
1507
            abi_ulong msg;
1508
            size_t len;
1509
            int flags;
1510
            abi_ulong addr;
1511
            socklen_t addrlen;
1512

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

    
1521
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1522
        }
1523
        break;
1524
    case SOCKOP_shutdown:
1525
        {
1526
            int sockfd, how;
1527

    
1528
            if (get_user_s32(sockfd, vptr)
1529
                || get_user_s32(how, vptr + n))
1530
                return -TARGET_EFAULT;
1531

    
1532
            ret = get_errno(shutdown(sockfd, how));
1533
        }
1534
        break;
1535
    case SOCKOP_sendmsg:
1536
    case SOCKOP_recvmsg:
1537
        {
1538
            int fd;
1539
            abi_ulong target_msg;
1540
            int flags;
1541

    
1542
            if (get_user_s32(fd, vptr)
1543
                || get_user_ual(target_msg, vptr + n)
1544
                || get_user_s32(flags, vptr + 2 * n))
1545
                return -TARGET_EFAULT;
1546

    
1547
            ret = do_sendrecvmsg(fd, target_msg, flags,
1548
                                 (num == SOCKOP_sendmsg));
1549
        }
1550
        break;
1551
    case SOCKOP_setsockopt:
1552
        {
1553
            int sockfd;
1554
            int level;
1555
            int optname;
1556
            abi_ulong optval;
1557
            socklen_t optlen;
1558

    
1559
            if (get_user_s32(sockfd, vptr)
1560
                || get_user_s32(level, vptr + n)
1561
                || get_user_s32(optname, vptr + 2 * n)
1562
                || get_user_ual(optval, vptr + 3 * n)
1563
                || get_user_u32(optlen, vptr + 4 * n))
1564
                return -TARGET_EFAULT;
1565

    
1566
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1567
        }
1568
        break;
1569
    case SOCKOP_getsockopt:
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_getsockopt(sockfd, level, optname, optval, optlen);
1585
        }
1586
        break;
1587
    default:
1588
        gemu_log("Unsupported socketcall: %d\n", num);
1589
        ret = -TARGET_ENOSYS;
1590
        break;
1591
    }
1592
    return ret;
1593
}
1594
#endif
1595

    
1596
#ifdef TARGET_NR_ipc
1597
#define N_SHM_REGIONS        32
1598

    
1599
static struct shm_region {
1600
    abi_ulong        start;
1601
    abi_ulong        size;
1602
} shm_regions[N_SHM_REGIONS];
1603

    
1604
struct target_ipc_perm
1605
{
1606
    abi_long __key;
1607
    abi_ulong uid;
1608
    abi_ulong gid;
1609
    abi_ulong cuid;
1610
    abi_ulong cgid;
1611
    unsigned short int mode;
1612
    unsigned short int __pad1;
1613
    unsigned short int __seq;
1614
    unsigned short int __pad2;
1615
    abi_ulong __unused1;
1616
    abi_ulong __unused2;
1617
};
1618

    
1619
struct target_semid_ds
1620
{
1621
  struct target_ipc_perm sem_perm;
1622
  abi_ulong sem_otime;
1623
  abi_ulong __unused1;
1624
  abi_ulong sem_ctime;
1625
  abi_ulong __unused2;
1626
  abi_ulong sem_nsems;
1627
  abi_ulong __unused3;
1628
  abi_ulong __unused4;
1629
};
1630

    
1631
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1632
                                               abi_ulong target_addr)
1633
{
1634
    struct target_ipc_perm *target_ip;
1635
    struct target_semid_ds *target_sd;
1636

    
1637
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1638
        return -TARGET_EFAULT;
1639
    target_ip=&(target_sd->sem_perm);
1640
    host_ip->__key = tswapl(target_ip->__key);
1641
    host_ip->uid = tswapl(target_ip->uid);
1642
    host_ip->gid = tswapl(target_ip->gid);
1643
    host_ip->cuid = tswapl(target_ip->cuid);
1644
    host_ip->cgid = tswapl(target_ip->cgid);
1645
    host_ip->mode = tswapl(target_ip->mode);
1646
    unlock_user_struct(target_sd, target_addr, 0);
1647
    return 0;
1648
}
1649

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

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

    
1669
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1670
                                               abi_ulong target_addr)
1671
{
1672
    struct target_semid_ds *target_sd;
1673

    
1674
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1675
        return -TARGET_EFAULT;
1676
    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1677
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1678
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
1679
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1680
    unlock_user_struct(target_sd, target_addr, 0);
1681
    return 0;
1682
}
1683

    
1684
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1685
                                               struct semid_ds *host_sd)
1686
{
1687
    struct target_semid_ds *target_sd;
1688

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

    
1699
union semun {
1700
        int val;
1701
        struct semid_ds *buf;
1702
        unsigned short *array;
1703
};
1704

    
1705
union target_semun {
1706
        int val;
1707
        abi_long buf;
1708
        unsigned short int *array;
1709
};
1710

    
1711
static inline abi_long target_to_host_semun(int cmd,
1712
                                            union semun *host_su,
1713
                                            abi_ulong target_addr,
1714
                                            struct semid_ds *ds)
1715
{
1716
    union target_semun *target_su;
1717

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

    
1747
static inline abi_long host_to_target_semun(int cmd,
1748
                                            abi_ulong target_addr,
1749
                                            union semun *host_su,
1750
                                            struct semid_ds *ds)
1751
{
1752
    union target_semun *target_su;
1753

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

    
1782
static inline abi_long do_semctl(int first, int second, int third,
1783
                                 abi_long ptr)
1784
{
1785
    union semun arg;
1786
    struct semid_ds dsarg;
1787
    int cmd = third&0xff;
1788
    abi_long ret = 0;
1789

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

    
1825
    return ret;
1826
}
1827

    
1828
struct target_msqid_ds
1829
{
1830
  struct target_ipc_perm msg_perm;
1831
  abi_ulong msg_stime;
1832
  abi_ulong __unused1;
1833
  abi_ulong msg_rtime;
1834
  abi_ulong __unused2;
1835
  abi_ulong msg_ctime;
1836
  abi_ulong __unused3;
1837
  abi_ulong __msg_cbytes;
1838
  abi_ulong msg_qnum;
1839
  abi_ulong msg_qbytes;
1840
  abi_ulong msg_lspid;
1841
  abi_ulong msg_lrpid;
1842
  abi_ulong __unused4;
1843
  abi_ulong __unused5;
1844
};
1845

    
1846
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1847
                                               abi_ulong target_addr)
1848
{
1849
    struct target_msqid_ds *target_md;
1850

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

    
1866
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1867
                                               struct msqid_ds *host_md)
1868
{
1869
    struct target_msqid_ds *target_md;
1870

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

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

    
1903
struct target_msgbuf {
1904
        abi_ulong mtype;
1905
        char        mtext[1];
1906
};
1907

    
1908
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1909
                                 unsigned int msgsz, int msgflg)
1910
{
1911
    struct target_msgbuf *target_mb;
1912
    struct msgbuf *host_mb;
1913
    abi_long ret = 0;
1914

    
1915
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1916
        return -TARGET_EFAULT;
1917
    host_mb = malloc(msgsz+sizeof(long));
1918
    host_mb->mtype = tswapl(target_mb->mtype);
1919
    memcpy(host_mb->mtext,target_mb->mtext,msgsz);
1920
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1921
    free(host_mb);
1922
    unlock_user_struct(target_mb, msgp, 0);
1923

    
1924
    return ret;
1925
}
1926

    
1927
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1928
                                 unsigned int msgsz, int msgtype,
1929
                                 int msgflg)
1930
{
1931
    struct target_msgbuf *target_mb;
1932
    char *target_mtext;
1933
    struct msgbuf *host_mb;
1934
    abi_long ret = 0;
1935

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

    
1953
end:
1954
    if (target_mb)
1955
        unlock_user_struct(target_mb, msgp, 1);
1956
    return ret;
1957
}
1958

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

    
1970
    version = call >> 16;
1971
    call &= 0xffff;
1972

    
1973
    switch (call) {
1974
    case IPCOP_semop:
1975
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
1976
        break;
1977

    
1978
    case IPCOP_semget:
1979
        ret = get_errno(semget(first, second, third));
1980
        break;
1981

    
1982
    case IPCOP_semctl:
1983
        ret = do_semctl(first, second, third, ptr);
1984
        break;
1985

    
1986
    case IPCOP_semtimedop:
1987
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
1988
        ret = -TARGET_ENOSYS;
1989
        break;
1990

    
1991
        case IPCOP_msgget:
1992
                ret = get_errno(msgget(first, second));
1993
                break;
1994

    
1995
        case IPCOP_msgsnd:
1996
                ret = do_msgsnd(first, ptr, second, third);
1997
                break;
1998

    
1999
        case IPCOP_msgctl:
2000
                ret = do_msgctl(first, second, ptr);
2001
                break;
2002

    
2003
        case IPCOP_msgrcv:
2004
                {
2005
                      /* XXX: this code is not correct */
2006
                      struct ipc_kludge
2007
                      {
2008
                              void *__unbounded msgp;
2009
                              long int msgtyp;
2010
                      };
2011

    
2012
                      struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
2013
                      struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
2014

    
2015
                      ret = do_msgrcv(first, (long)msgp, second, 0, third);
2016

    
2017
                }
2018
                break;
2019

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

    
2065
    case IPCOP_shmget:
2066
        /* IPC_* flag values are the same on all linux platforms */
2067
        ret = get_errno(shmget(first, second, third));
2068
        break;
2069

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

    
2092
/* kernel structure types definitions */
2093
#define IFNAMSIZ        16
2094

    
2095
#define STRUCT(name, list...) STRUCT_ ## name,
2096
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2097
enum {
2098
#include "syscall_types.h"
2099
};
2100
#undef STRUCT
2101
#undef STRUCT_SPECIAL
2102

    
2103
#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2104
#define STRUCT_SPECIAL(name)
2105
#include "syscall_types.h"
2106
#undef STRUCT
2107
#undef STRUCT_SPECIAL
2108

    
2109
typedef struct IOCTLEntry {
2110
    unsigned int target_cmd;
2111
    unsigned int host_cmd;
2112
    const char *name;
2113
    int access;
2114
    const argtype arg_type[5];
2115
} IOCTLEntry;
2116

    
2117
#define IOC_R 0x0001
2118
#define IOC_W 0x0002
2119
#define IOC_RW (IOC_R | IOC_W)
2120

    
2121
#define MAX_STRUCT_SIZE 4096
2122

    
2123
IOCTLEntry ioctl_entries[] = {
2124
#define IOCTL(cmd, access, types...) \
2125
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2126
#include "ioctls.h"
2127
    { 0, 0, },
2128
};
2129

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

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

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

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

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

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

    
2314
static void target_to_host_termios (void *dst, const void *src)
2315
{
2316
    struct host_termios *host = dst;
2317
    const struct target_termios *target = src;
2318

    
2319
    host->c_iflag =
2320
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2321
    host->c_oflag =
2322
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2323
    host->c_cflag =
2324
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2325
    host->c_lflag =
2326
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2327
    host->c_line = target->c_line;
2328

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

    
2348
static void host_to_target_termios (void *dst, const void *src)
2349
{
2350
    struct target_termios *target = dst;
2351
    const struct host_termios *host = src;
2352

    
2353
    target->c_iflag =
2354
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2355
    target->c_oflag =
2356
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2357
    target->c_cflag =
2358
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2359
    target->c_lflag =
2360
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2361
    target->c_line = host->c_line;
2362

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

    
2382
StructEntry struct_termios_def = {
2383
    .convert = { host_to_target_termios, target_to_host_termios },
2384
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2385
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2386
};
2387

    
2388
static bitmask_transtbl mmap_flags_tbl[] = {
2389
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2390
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2391
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2392
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2393
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2394
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2395
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2396
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2397
        { 0, 0, 0, 0 }
2398
};
2399

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

    
2420
#if defined(TARGET_I386)
2421

    
2422
/* NOTE: there is really one LDT for all the threads */
2423
uint8_t *ldt_table;
2424

    
2425
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2426
{
2427
    int size;
2428
    void *p;
2429

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

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

    
2454
    if (bytecount != sizeof(ldt_info))
2455
        return -TARGET_EINVAL;
2456
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2457
        return -TARGET_EFAULT;
2458
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2459
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2460
    ldt_info.limit = tswap32(target_ldt_info->limit);
2461
    ldt_info.flags = tswap32(target_ldt_info->flags);
2462
    unlock_user_struct(target_ldt_info, ptr, 0);
2463

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

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

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

    
2524
    /* Install the new entry ...  */
2525
install:
2526
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2527
    lp[0] = tswap32(entry_1);
2528
    lp[1] = tswap32(entry_2);
2529
    return 0;
2530
}
2531

    
2532
/* specific and weird i386 syscalls */
2533
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2534
                              unsigned long bytecount)
2535
{
2536
    abi_long ret;
2537

    
2538
    switch (func) {
2539
    case 0:
2540
        ret = read_ldt(ptr, bytecount);
2541
        break;
2542
    case 1:
2543
        ret = write_ldt(env, ptr, bytecount, 1);
2544
        break;
2545
    case 0x11:
2546
        ret = write_ldt(env, ptr, bytecount, 0);
2547
        break;
2548
    default:
2549
        ret = -TARGET_ENOSYS;
2550
        break;
2551
    }
2552
    return ret;
2553
}
2554

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

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

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

    
2599
    if (contents == 3) {
2600
        if (seg_not_present == 0)
2601
            return -TARGET_EINVAL;
2602
    }
2603

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

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

    
2633
    /* Install the new entry ...  */
2634
install:
2635
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2636
    lp[0] = tswap32(entry_1);
2637
    lp[1] = tswap32(entry_2);
2638
    return 0;
2639
}
2640

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

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

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

    
2724
#endif /* defined(TARGET_I386) */
2725

    
2726
#if defined(USE_NPTL)
2727

    
2728
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2729

    
2730
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2731
typedef struct {
2732
    CPUState *env;
2733
    pthread_mutex_t mutex;
2734
    pthread_cond_t cond;
2735
    pthread_t thread;
2736
    uint32_t tid;
2737
    abi_ulong child_tidptr;
2738
    abi_ulong parent_tidptr;
2739
    sigset_t sigmask;
2740
} new_thread_info;
2741

    
2742
static void *clone_func(void *arg)
2743
{
2744
    new_thread_info *info = arg;
2745
    CPUState *env;
2746

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

    
2772
static int clone_func(void *arg)
2773
{
2774
    CPUState *env = arg;
2775
    cpu_loop(env);
2776
    /* never exits */
2777
    return 0;
2778
}
2779
#endif
2780

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

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

    
2813
        /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2814
        if (nptl_flags & CLONE_SETTLS)
2815
            cpu_set_tls (new_env, newtls);
2816

    
2817
        /* Grab a mutex so that thread setup appears atomic.  */
2818
        pthread_mutex_lock(&clone_lock);
2819

    
2820
        memset(&info, 0, sizeof(info));
2821
        pthread_mutex_init(&info.mutex, NULL);
2822
        pthread_mutex_lock(&info.mutex);
2823
        pthread_cond_init(&info.cond, NULL);
2824
        info.env = new_env;
2825
        if (nptl_flags & CLONE_CHILD_SETTID)
2826
            info.child_tidptr = child_tidptr;
2827
        if (nptl_flags & CLONE_PARENT_SETTID)
2828
            info.parent_tidptr = parent_tidptr;
2829

    
2830
        ret = pthread_attr_init(&attr);
2831
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2832
        /* It is not safe to deliver signals until the child has finished
2833
           initializing, so temporarily block all signals.  */
2834
        sigfillset(&sigmask);
2835
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2836

    
2837
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
2838

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

    
2901
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2902
{
2903
    struct flock fl;
2904
    struct target_flock *target_fl;
2905
    struct flock64 fl64;
2906
    struct target_flock64 *target_fl64;
2907
    abi_long ret;
2908

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

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

    
2945
    case TARGET_F_GETLK64:
2946
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2947
            return -TARGET_EFAULT;
2948
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2949
        fl64.l_whence = tswap16(target_fl64->l_whence);
2950
        fl64.l_start = tswapl(target_fl64->l_start);
2951
        fl64.l_len = tswapl(target_fl64->l_len);
2952
        fl64.l_pid = tswap16(target_fl64->l_pid);
2953
        unlock_user_struct(target_fl64, arg, 0);
2954
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2955
        if (ret == 0) {
2956
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
2957
                return -TARGET_EFAULT;
2958
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
2959
            target_fl64->l_whence = tswap16(fl64.l_whence);
2960
            target_fl64->l_start = tswapl(fl64.l_start);
2961
            target_fl64->l_len = tswapl(fl64.l_len);
2962
            target_fl64->l_pid = tswapl(fl64.l_pid);
2963
            unlock_user_struct(target_fl64, arg, 1);
2964
        }
2965
        break;
2966
    case TARGET_F_SETLK64:
2967
    case TARGET_F_SETLKW64:
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
        break;
2978

    
2979
    case F_GETFL:
2980
        ret = get_errno(fcntl(fd, cmd, arg));
2981
        if (ret >= 0) {
2982
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
2983
        }
2984
        break;
2985

    
2986
    case F_SETFL:
2987
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
2988
        break;
2989

    
2990
    default:
2991
        ret = get_errno(fcntl(fd, cmd, arg));
2992
        break;
2993
    }
2994
    return ret;
2995
}
2996

    
2997
#ifdef USE_UID16
2998

    
2999
static inline int high2lowuid(int uid)
3000
{
3001
    if (uid > 65535)
3002
        return 65534;
3003
    else
3004
        return uid;
3005
}
3006

    
3007
static inline int high2lowgid(int gid)
3008
{
3009
    if (gid > 65535)
3010
        return 65534;
3011
    else
3012
        return gid;
3013
}
3014

    
3015
static inline int low2highuid(int uid)
3016
{
3017
    if ((int16_t)uid == -1)
3018
        return -1;
3019
    else
3020
        return uid;
3021
}
3022

    
3023
static inline int low2highgid(int gid)
3024
{
3025
    if ((int16_t)gid == -1)
3026
        return -1;
3027
    else
3028
        return gid;
3029
}
3030

    
3031
#endif /* USE_UID16 */
3032

    
3033
void syscall_init(void)
3034
{
3035
    IOCTLEntry *ie;
3036
    const argtype *arg_type;
3037
    int size;
3038
    int i;
3039

    
3040
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3041
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3042
#include "syscall_types.h"
3043
#undef STRUCT
3044
#undef STRUCT_SPECIAL
3045

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

    
3065
        /* Build target_to_host_errno_table[] table from
3066
         * host_to_target_errno_table[]. */
3067
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3068
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3069

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

    
3081
#if TARGET_ABI_BITS == 32
3082
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3083
{
3084
#ifdef TARGET_WORDS_BIGENDIAN
3085
    return ((uint64_t)word0 << 32) | word1;
3086
#else
3087
    return ((uint64_t)word1 << 32) | word0;
3088
#endif
3089
}
3090
#else /* TARGET_ABI_BITS == 32 */
3091
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3092
{
3093
    return word0;
3094
}
3095
#endif /* TARGET_ABI_BITS != 32 */
3096

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

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

    
3131
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3132
                                               abi_ulong target_addr)
3133
{
3134
    struct target_timespec *target_ts;
3135

    
3136
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3137
        return -TARGET_EFAULT;
3138
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3139
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3140
    unlock_user_struct(target_ts, target_addr, 0);
3141
    return 0;
3142
}
3143

    
3144
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3145
                                               struct timespec *host_ts)
3146
{
3147
    struct target_timespec *target_ts;
3148

    
3149
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3150
        return -TARGET_EFAULT;
3151
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3152
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3153
    unlock_user_struct(target_ts, target_addr, 1);
3154
    return 0;
3155
}
3156

    
3157
#ifdef TARGET_NR_stat64
3158
static inline abi_long host_to_target_stat64(void *cpu_env,
3159
                                             abi_ulong target_addr,
3160
                                             struct stat *host_st)
3161
{
3162
#ifdef TARGET_ARM
3163
    if (((CPUARMState *)cpu_env)->eabi) {
3164
        struct target_eabi_stat64 *target_st;
3165

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

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

    
3214
    return 0;
3215
}
3216
#endif
3217

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

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

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

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

    
3300
#ifdef DEBUG
3301
    gemu_log("syscall %d", num);
3302
#endif
3303
    if(do_strace)
3304
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3305

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

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

    
3463
            argp = alloca((argc + 1) * sizeof(void *));
3464
            envp = alloca((envc + 1) * sizeof(void *));
3465

    
3466
            for (gp = guest_argp, q = argp; gp;
3467
                  gp += sizeof(abi_ulong), q++) {
3468
                if (get_user_ual(addr, gp))
3469
                    goto execve_efault;
3470
                if (!addr)
3471
                    break;
3472
                if (!(*q = lock_user_string(addr)))
3473
                    goto execve_efault;
3474
            }
3475
            *q = NULL;
3476

    
3477
            for (gp = guest_envp, q = envp; gp;
3478
                  gp += sizeof(abi_ulong), q++) {
3479
                if (get_user_ual(addr, gp))
3480
                    goto execve_efault;
3481
                if (!addr)
3482
                    break;
3483
                if (!(*q = lock_user_string(addr)))
3484
                    goto execve_efault;
3485
            }
3486
            *q = NULL;
3487

    
3488
            if (!(p = lock_user_string(arg1)))
3489
                goto execve_efault;
3490
            ret = get_errno(execve(p, argp, envp));
3491
            unlock_user(p, arg1, 0);
3492

    
3493
            goto execve_end;
3494

    
3495
        execve_efault:
3496
            ret = -TARGET_EFAULT;
3497

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

    
3895
            if (arg2) {
3896
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3897
                    goto efault;
3898
                act._sa_handler = old_act->_sa_handler;
3899
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3900
                act.sa_flags = old_act->sa_flags;
3901
                unlock_user_struct(old_act, arg2, 0);
3902
                pact = &act;
3903
            } else {
3904
                pact = NULL;
3905
            }
3906

    
3907
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3908

    
3909
            if (!is_error(ret) && arg3) {
3910
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3911
                    goto efault;
3912
                old_act->_sa_handler = oact._sa_handler;
3913
                old_act->sa_flags = oact.sa_flags;
3914
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
3915
                old_act->sa_mask.sig[1] = 0;
3916
                old_act->sa_mask.sig[2] = 0;
3917
                old_act->sa_mask.sig[3] = 0;
3918
                unlock_user_struct(old_act, arg3, 1);
3919
            }
3920
#endif
3921
        }
3922
        break;
3923
#endif
3924
    case TARGET_NR_rt_sigaction:
3925
        {
3926
            struct target_sigaction *act;
3927
            struct target_sigaction *oact;
3928

    
3929
            if (arg2) {
3930
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
3931
                    goto efault;
3932
            } else
3933
                act = NULL;
3934
            if (arg3) {
3935
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
3936
                    ret = -TARGET_EFAULT;
3937
                    goto rt_sigaction_fail;
3938
                }
3939
            } else
3940
                oact = NULL;
3941
            ret = get_errno(do_sigaction(arg1, act, oact));
3942
        rt_sigaction_fail:
3943
            if (act)
3944
                unlock_user_struct(act, arg2, 0);
3945
            if (oact)
3946
                unlock_user_struct(oact, arg3, 1);
3947
        }
3948
        break;
3949
#ifdef TARGET_NR_sgetmask /* not on alpha */
3950
    case TARGET_NR_sgetmask:
3951
        {
3952
            sigset_t cur_set;
3953
            abi_ulong target_set;
3954
            sigprocmask(0, NULL, &cur_set);
3955
            host_to_target_old_sigset(&target_set, &cur_set);
3956
            ret = target_set;
3957
        }
3958
        break;
3959
#endif
3960
#ifdef TARGET_NR_ssetmask /* not on alpha */
3961
    case TARGET_NR_ssetmask:
3962
        {
3963
            sigset_t set, oset, cur_set;
3964
            abi_ulong target_set = arg1;
3965
            sigprocmask(0, NULL, &cur_set);
3966
            target_to_host_old_sigset(&set, &target_set);
3967
            sigorset(&set, &set, &cur_set);
3968
            sigprocmask(SIG_SETMASK, &set, &oset);
3969
            host_to_target_old_sigset(&target_set, &oset);
3970
            ret = target_set;
3971
        }
3972
        break;
3973
#endif
3974
#ifdef TARGET_NR_sigprocmask
3975
    case TARGET_NR_sigprocmask:
3976
        {
3977
            int how = arg1;
3978
            sigset_t set, oldset, *set_ptr;
3979

    
3980
            if (arg2) {
3981
                switch(how) {
3982
                case TARGET_SIG_BLOCK:
3983
                    how = SIG_BLOCK;
3984
                    break;
3985
                case TARGET_SIG_UNBLOCK:
3986
                    how = SIG_UNBLOCK;
3987
                    break;
3988
                case TARGET_SIG_SETMASK:
3989
                    how = SIG_SETMASK;
3990
                    break;
3991
                default:
3992
                    ret = -TARGET_EINVAL;
3993
                    goto fail;
3994
                }
3995
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3996
                    goto efault;
3997
                target_to_host_old_sigset(&set, p);
3998
                unlock_user(p, arg2, 0);
3999
                set_ptr = &set;
4000
            } else {
4001
                how = 0;
4002
                set_ptr = NULL;
4003
            }
4004
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4005
            if (!is_error(ret) && arg3) {
4006
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4007
                    goto efault;
4008
                host_to_target_old_sigset(p, &oldset);
4009
                unlock_user(p, arg3, sizeof(target_sigset_t));
4010
            }
4011
        }
4012
        break;
4013
#endif
4014
    case TARGET_NR_rt_sigprocmask:
4015
        {
4016
            int how = arg1;
4017
            sigset_t set, oldset, *set_ptr;
4018

    
4019
            if (arg2) {
4020
                switch(how) {
4021
                case TARGET_SIG_BLOCK:
4022
                    how = SIG_BLOCK;
4023
                    break;
4024
                case TARGET_SIG_UNBLOCK:
4025
                    how = SIG_UNBLOCK;
4026
                    break;
4027
                case TARGET_SIG_SETMASK:
4028
                    how = SIG_SETMASK;
4029
                    break;
4030
                default:
4031
                    ret = -TARGET_EINVAL;
4032
                    goto fail;
4033
                }
4034
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4035
                    goto efault;
4036
                target_to_host_sigset(&set, p);
4037
                unlock_user(p, arg2, 0);
4038
                set_ptr = &set;
4039
            } else {
4040
                how = 0;
4041
                set_ptr = NULL;
4042
            }
4043
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4044
            if (!is_error(ret) && arg3) {
4045
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4046
                    goto efault;
4047
                host_to_target_sigset(p, &oldset);
4048
                unlock_user(p, arg3, sizeof(target_sigset_t));
4049
            }
4050
        }
4051
        break;
4052
#ifdef TARGET_NR_sigpending
4053
    case TARGET_NR_sigpending:
4054
        {
4055
            sigset_t set;
4056
            ret = get_errno(sigpending(&set));
4057
            if (!is_error(ret)) {
4058
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4059
                    goto efault;
4060
                host_to_target_old_sigset(p, &set);
4061
                unlock_user(p, arg1, sizeof(target_sigset_t));
4062
            }
4063
        }
4064
        break;
4065
#endif
4066
    case TARGET_NR_rt_sigpending:
4067
        {
4068
            sigset_t set;
4069
            ret = get_errno(sigpending(&set));
4070
            if (!is_error(ret)) {
4071
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4072
                    goto efault;
4073
                host_to_target_sigset(p, &set);
4074
                unlock_user(p, arg1, sizeof(target_sigset_t));
4075
            }
4076
        }
4077
        break;
4078
#ifdef TARGET_NR_sigsuspend
4079
    case TARGET_NR_sigsuspend:
4080
        {
4081
            sigset_t set;
4082
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4083
                goto efault;
4084
            target_to_host_old_sigset(&set, p);
4085
            unlock_user(p, arg1, 0);
4086
            ret = get_errno(sigsuspend(&set));
4087
        }
4088
        break;
4089
#endif
4090
    case TARGET_NR_rt_sigsuspend:
4091
        {
4092
            sigset_t set;
4093
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4094
                goto efault;
4095
            target_to_host_sigset(&set, p);
4096
            unlock_user(p, arg1, 0);
4097
            ret = get_errno(sigsuspend(&set));
4098
        }
4099
        break;
4100
    case TARGET_NR_rt_sigtimedwait:
4101
        {
4102
            sigset_t set;
4103
            struct timespec uts, *puts;
4104
            siginfo_t uinfo;
4105

    
4106
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4107
                goto efault;
4108
            target_to_host_sigset(&set, p);
4109
            unlock_user(p, arg1, 0);
4110
            if (arg3) {
4111
                puts = &uts;
4112
                target_to_host_timespec(puts, arg3);
4113
            } else {
4114
                puts = NULL;
4115
            }
4116
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4117
            if (!is_error(ret) && arg2) {
4118
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4119
                    goto efault;
4120
                host_to_target_siginfo(p, &uinfo);
4121
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4122
            }
4123
        }
4124
        break;
4125
    case TARGET_NR_rt_sigqueueinfo:
4126
        {
4127
            siginfo_t uinfo;
4128
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4129
                goto efault;
4130
            target_to_host_siginfo(&uinfo, p);
4131
            unlock_user(p, arg1, 0);
4132
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4133
        }
4134
        break;
4135
#ifdef TARGET_NR_sigreturn
4136
    case TARGET_NR_sigreturn:
4137
        /* NOTE: ret is eax, so not transcoding must be done */
4138
        ret = do_sigreturn(cpu_env);
4139
        break;
4140
#endif
4141
    case TARGET_NR_rt_sigreturn:
4142
        /* NOTE: ret is eax, so not transcoding must be done */
4143
        ret = do_rt_sigreturn(cpu_env);
4144
        break;
4145
    case TARGET_NR_sethostname:
4146
        if (!(p = lock_user_string(arg1)))
4147
            goto efault;
4148
        ret = get_errno(sethostname(p, arg2));
4149
        unlock_user(p, arg1, 0);
4150
        break;
4151
    case TARGET_NR_setrlimit:
4152
        {
4153
            /* XXX: convert resource ? */
4154
            int resource = arg1;
4155
            struct target_rlimit *target_rlim;
4156
            struct rlimit rlim;
4157
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4158
                goto efault;
4159
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4160
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4161
            unlock_user_struct(target_rlim, arg2, 0);
4162
            ret = get_errno(setrlimit(resource, &rlim));
4163
        }
4164
        break;
4165
    case TARGET_NR_getrlimit:
4166
        {
4167
            /* XXX: convert resource ? */
4168
            int resource = arg1;
4169
            struct target_rlimit *target_rlim;
4170
            struct rlimit rlim;
4171

    
4172
            ret = get_errno(getrlimit(resource, &rlim));
4173
            if (!is_error(ret)) {
4174
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4175
                    goto efault;
4176
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4177
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4178
                unlock_user_struct(target_rlim, arg2, 1);
4179
            }
4180
        }
4181
        break;
4182
    case TARGET_NR_getrusage:
4183
        {
4184
            struct rusage rusage;
4185
            ret = get_errno(getrusage(arg1, &rusage));
4186
            if (!is_error(ret)) {
4187
                host_to_target_rusage(arg2, &rusage);
4188
            }
4189
        }
4190
        break;
4191
    case TARGET_NR_gettimeofday:
4192
        {
4193
            struct timeval tv;
4194
            ret = get_errno(gettimeofday(&tv, NULL));
4195
            if (!is_error(ret)) {
4196
                if (copy_to_user_timeval(arg1, &tv))
4197
                    goto efault;
4198
            }
4199
        }
4200
        break;
4201
    case TARGET_NR_settimeofday:
4202
        {
4203
            struct timeval tv;
4204
            if (copy_from_user_timeval(&tv, arg1))
4205
                goto efault;
4206
            ret = get_errno(settimeofday(&tv, NULL));
4207
        }
4208
        break;
4209
#ifdef TARGET_NR_select
4210
    case TARGET_NR_select:
4211
        {
4212
            struct target_sel_arg_struct *sel;
4213
            abi_ulong inp, outp, exp, tvp;
4214
            long nsel;
4215

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

    
4423
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4424
                goto efault;
4425
            __put_user(stfs.f_type, &target_stfs->f_type);
4426
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4427
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4428
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4429
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4430
            __put_user(stfs.f_files, &target_stfs->f_files);
4431
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4432
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4433
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4434
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4435
            unlock_user_struct(target_stfs, arg2, 1);
4436
        }
4437
        break;
4438
    case TARGET_NR_fstatfs:
4439
        ret = get_errno(fstatfs(arg1, &stfs));
4440
        goto convert_statfs;
4441
#ifdef TARGET_NR_statfs64
4442
    case TARGET_NR_statfs64:
4443
        if (!(p = lock_user_string(arg1)))
4444
            goto efault;
4445
        ret = get_errno(statfs(path(p), &stfs));
4446
        unlock_user(p, arg1, 0);
4447
    convert_statfs64:
4448
        if (!is_error(ret)) {
4449
            struct target_statfs64 *target_stfs;
4450

    
4451
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4452
                goto efault;
4453
            __put_user(stfs.f_type, &target_stfs->f_type);
4454
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4455
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4456
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4457
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4458
            __put_user(stfs.f_files, &target_stfs->f_files);
4459
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4460
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4461
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4462
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4463
            unlock_user_struct(target_stfs, arg3, 1);
4464
        }
4465
        break;
4466
    case TARGET_NR_fstatfs64:
4467
        ret = get_errno(fstatfs(arg1, &stfs));
4468
        goto convert_statfs64;
4469
#endif
4470
#ifdef TARGET_NR_ioperm
4471
    case TARGET_NR_ioperm:
4472
        goto unimplemented;
4473
#endif
4474
#ifdef TARGET_NR_socketcall
4475
    case TARGET_NR_socketcall:
4476
        ret = do_socketcall(arg1, arg2);
4477
        break;
4478
#endif
4479
#ifdef TARGET_NR_accept
4480
    case TARGET_NR_accept:
4481
        ret = do_accept(arg1, arg2, arg3);
4482
        break;
4483
#endif
4484
#ifdef TARGET_NR_bind
4485
    case TARGET_NR_bind:
4486
        ret = do_bind(arg1, arg2, arg3);
4487
        break;
4488
#endif
4489
#ifdef TARGET_NR_connect
4490
    case TARGET_NR_connect:
4491
        ret = do_connect(arg1, arg2, arg3);
4492
        break;
4493
#endif
4494
#ifdef TARGET_NR_getpeername
4495
    case TARGET_NR_getpeername:
4496
        ret = do_getpeername(arg1, arg2, arg3);
4497
        break;
4498
#endif
4499
#ifdef TARGET_NR_getsockname
4500
    case TARGET_NR_getsockname:
4501
        ret = do_getsockname(arg1, arg2, arg3);
4502
        break;
4503
#endif
4504
#ifdef TARGET_NR_getsockopt
4505
    case TARGET_NR_getsockopt:
4506
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4507
        break;
4508
#endif
4509
#ifdef TARGET_NR_listen
4510
    case TARGET_NR_listen:
4511
        ret = get_errno(listen(arg1, arg2));
4512
        break;
4513
#endif
4514
#ifdef TARGET_NR_recv
4515
    case TARGET_NR_recv:
4516
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4517
        break;
4518
#endif
4519
#ifdef TARGET_NR_recvfrom
4520
    case TARGET_NR_recvfrom:
4521
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4522
        break;
4523
#endif
4524
#ifdef TARGET_NR_recvmsg
4525
    case TARGET_NR_recvmsg:
4526
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4527
        break;
4528
#endif
4529
#ifdef TARGET_NR_send
4530
    case TARGET_NR_send:
4531
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4532
        break;
4533
#endif
4534
#ifdef TARGET_NR_sendmsg
4535
    case TARGET_NR_sendmsg:
4536
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4537
        break;
4538
#endif
4539
#ifdef TARGET_NR_sendto
4540
    case TARGET_NR_sendto:
4541
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4542
        break;
4543
#endif
4544
#ifdef TARGET_NR_shutdown
4545
    case TARGET_NR_shutdown:
4546
        ret = get_errno(shutdown(arg1, arg2));
4547
        break;
4548
#endif
4549
#ifdef TARGET_NR_socket
4550
    case TARGET_NR_socket:
4551
        ret = do_socket(arg1, arg2, arg3);
4552
        break;
4553
#endif
4554
#ifdef TARGET_NR_socketpair
4555
    case TARGET_NR_socketpair:
4556
        ret = do_socketpair(arg1, arg2, arg3, arg4);
4557
        break;
4558
#endif
4559
#ifdef TARGET_NR_setsockopt
4560
    case TARGET_NR_setsockopt:
4561
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4562
        break;
4563
#endif
4564

    
4565
    case TARGET_NR_syslog:
4566
        if (!(p = lock_user_string(arg2)))
4567
            goto efault;
4568
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4569
        unlock_user(p, arg2, 0);
4570
        break;
4571

    
4572
    case TARGET_NR_setitimer:
4573
        {
4574
            struct itimerval value, ovalue, *pvalue;
4575

    
4576
            if (arg2) {
4577
                pvalue = &value;
4578
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4579
                    || copy_from_user_timeval(&pvalue->it_value,
4580
                                              arg2 + sizeof(struct target_timeval)))
4581
                    goto efault;
4582
            } else {
4583
                pvalue = NULL;
4584
            }
4585
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4586
            if (!is_error(ret) && arg3) {
4587
                if (copy_to_user_timeval(arg3,
4588
                                         &ovalue.it_interval)
4589
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4590
                                            &ovalue.it_value))
4591
                    goto efault;
4592
            }
4593
        }
4594
        break;
4595
    case TARGET_NR_getitimer:
4596
        {
4597
            struct itimerval value;
4598

    
4599
            ret = get_errno(getitimer(arg1, &value));
4600
            if (!is_error(ret) && arg2) {
4601
                if (copy_to_user_timeval(arg2,
4602
                                         &value.it_interval)
4603
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4604
                                            &value.it_value))
4605
                    goto efault;
4606
            }
4607
        }
4608
        break;
4609
    case TARGET_NR_stat:
4610
        if (!(p = lock_user_string(arg1)))
4611
            goto efault;
4612
        ret = get_errno(stat(path(p), &st));
4613
        unlock_user(p, arg1, 0);
4614
        goto do_stat;
4615
    case TARGET_NR_lstat:
4616
        if (!(p = lock_user_string(arg1)))
4617
            goto efault;
4618
        ret = get_errno(lstat(path(p), &st));
4619
        unlock_user(p, arg1, 0);
4620
        goto do_stat;
4621
    case TARGET_NR_fstat:
4622
        {
4623
            ret = get_errno(fstat(arg1, &st));
4624
        do_stat:
4625
            if (!is_error(ret)) {
4626
                struct target_stat *target_st;
4627

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

    
4756
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4757
                goto efault;
4758
            ret = get_errno(sys_uname(buf));
4759
            if (!is_error(ret)) {
4760
                /* Overrite the native machine name with whatever is being
4761
                   emulated. */
4762
                strcpy (buf->machine, UNAME_MACHINE);
4763
                /* Allow the user to override the reported release.  */
4764
                if (qemu_uname_release && *qemu_uname_release)
4765
                  strcpy (buf->release, qemu_uname_release);
4766
            }
4767
            unlock_user_struct(buf, arg1, 1);
4768
        }
4769
        break;
4770
#ifdef TARGET_I386
4771
    case TARGET_NR_modify_ldt:
4772
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4773
        break;
4774
#if !defined(TARGET_X86_64)
4775
    case TARGET_NR_vm86old:
4776
        goto unimplemented;
4777
    case TARGET_NR_vm86:
4778
        ret = do_vm86(cpu_env, arg1, arg2);
4779
        break;
4780
#endif
4781
#endif
4782
    case TARGET_NR_adjtimex:
4783
        goto unimplemented;
4784
#ifdef TARGET_NR_create_module
4785
    case TARGET_NR_create_module:
4786
#endif
4787
    case TARGET_NR_init_module:
4788
    case TARGET_NR_delete_module:
4789
#ifdef TARGET_NR_get_kernel_syms
4790
    case TARGET_NR_get_kernel_syms:
4791
#endif
4792
        goto unimplemented;
4793
    case TARGET_NR_quotactl:
4794
        goto unimplemented;
4795
    case TARGET_NR_getpgid:
4796
        ret = get_errno(getpgid(arg1));
4797
        break;
4798
    case TARGET_NR_fchdir:
4799
        ret = get_errno(fchdir(arg1));
4800
        break;
4801
#ifdef TARGET_NR_bdflush /* not on x86_64 */
4802
    case TARGET_NR_bdflush:
4803
        goto unimplemented;
4804
#endif
4805
#ifdef TARGET_NR_sysfs
4806
    case TARGET_NR_sysfs:
4807
        goto unimplemented;
4808
#endif
4809
    case TARGET_NR_personality:
4810
        ret = get_errno(personality(arg1));
4811
        break;
4812
#ifdef TARGET_NR_afs_syscall
4813
    case TARGET_NR_afs_syscall:
4814
        goto unimplemented;
4815
#endif
4816
#ifdef TARGET_NR__llseek /* Not on alpha */
4817
    case TARGET_NR__llseek:
4818
        {
4819
#if defined (__x86_64__)
4820
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4821
            if (put_user_s64(ret, arg4))
4822
                goto efault;
4823
#else
4824
            int64_t res;
4825
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4826
            if (put_user_s64(res, arg4))
4827
                goto efault;
4828
#endif
4829
        }
4830
        break;
4831
#endif
4832
    case TARGET_NR_getdents:
4833
#if TARGET_ABI_BITS != 32
4834
        goto unimplemented;
4835
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4836
        {
4837
            struct target_dirent *target_dirp;
4838
            struct dirent *dirp;
4839
            abi_long count = arg3;
4840

    
4841
            dirp = malloc(count);
4842
            if (!dirp) {
4843
                ret = -TARGET_ENOMEM;
4844
                goto fail;
4845
            }
4846

    
4847
            ret = get_errno(sys_getdents(arg1, dirp, count));
4848
            if (!is_error(ret)) {
4849
                struct dirent *de;
4850
                struct target_dirent *tde;
4851
                int len = ret;
4852
                int reclen, treclen;
4853
                int count1, tnamelen;
4854

    
4855
                count1 = 0;
4856
                de = dirp;
4857
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4858
                    goto efault;
4859
                tde = target_dirp;
4860
                while (len > 0) {
4861
                    reclen = de->d_reclen;
4862
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4863
                    tde->d_reclen = tswap16(treclen);
4864
                    tde->d_ino = tswapl(de->d_ino);
4865
                    tde->d_off = tswapl(de->d_off);
4866
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4867
                    if (tnamelen > 256)
4868
                        tnamelen = 256;
4869
                    /* XXX: may not be correct */
4870
                    strncpy(tde->d_name, de->d_name, tnamelen);
4871
                    de = (struct dirent *)((char *)de + reclen);
4872
                    len -= reclen;
4873
                    tde = (struct target_dirent *)((char *)tde + treclen);
4874
                    count1 += treclen;
4875
                }
4876
                ret = count1;
4877
                unlock_user(target_dirp, arg2, ret);
4878
            }
4879
            free(dirp);
4880
        }
4881
#else
4882
        {
4883
            struct dirent *dirp;
4884
            abi_long count = arg3;
4885

    
4886
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4887
                goto efault;
4888
            ret = get_errno(sys_getdents(arg1, dirp, count));
4889
            if (!is_error(ret)) {
4890
                struct dirent *de;
4891
                int len = ret;
4892
                int reclen;
4893
                de = dirp;
4894
                while (len > 0) {
4895
                    reclen = de->d_reclen;
4896
                    if (reclen > len)
4897
                        break;
4898
                    de->d_reclen = tswap16(reclen);
4899
                    tswapls(&de->d_ino);
4900
                    tswapls(&de->d_off);
4901
                    de = (struct dirent *)((char *)de + reclen);
4902
                    len -= reclen;
4903
                }
4904
            }
4905
            unlock_user(dirp, arg2, ret);
4906
        }
4907
#endif
4908
        break;
4909
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
4910
    case TARGET_NR_getdents64:
4911
        {
4912
            struct dirent64 *dirp;
4913
            abi_long count = arg3;
4914
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4915
                goto efault;
4916
            ret = get_errno(sys_getdents64(arg1, dirp, count));
4917
            if (!is_error(ret)) {
4918
                struct dirent64 *de;
4919
                int len = ret;
4920
                int reclen;
4921
                de = dirp;
4922
                while (len > 0) {
4923
                    reclen = de->d_reclen;
4924
                    if (reclen > len)
4925
                        break;
4926
                    de->d_reclen = tswap16(reclen);
4927
                    tswap64s((uint64_t *)&de->d_ino);
4928
                    tswap64s((uint64_t *)&de->d_off);
4929
                    de = (struct dirent64 *)((char *)de + reclen);
4930
                    len -= reclen;
4931
                }
4932
            }
4933
            unlock_user(dirp, arg2, ret);
4934
        }
4935
        break;
4936
#endif /* TARGET_NR_getdents64 */
4937
#ifdef TARGET_NR__newselect
4938
    case TARGET_NR__newselect:
4939
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
4940
        break;
4941
#endif
4942
#ifdef TARGET_NR_poll
4943
    case TARGET_NR_poll:
4944
        {
4945
            struct target_pollfd *target_pfd;
4946
            unsigned int nfds = arg2;
4947
            int timeout = arg3;
4948
            struct pollfd *pfd;
4949
            unsigned int i;
4950

    
4951
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
4952
            if (!target_pfd)
4953
                goto efault;
4954
            pfd = alloca(sizeof(struct pollfd) * nfds);
4955
            for(i = 0; i < nfds; i++) {
4956
                pfd[i].fd = tswap32(target_pfd[i].fd);
4957
                pfd[i].events = tswap16(target_pfd[i].events);
4958
            }
4959
            ret = get_errno(poll(pfd, nfds, timeout));
4960
            if (!is_error(ret)) {
4961
                for(i = 0; i < nfds; i++) {
4962
                    target_pfd[i].revents = tswap16(pfd[i].revents);
4963
                }
4964
                ret += nfds * (sizeof(struct target_pollfd)
4965
                               - sizeof(struct pollfd));
4966
            }
4967
            unlock_user(target_pfd, arg1, ret);
4968
        }
4969
        break;
4970
#endif
4971
    case TARGET_NR_flock:
4972
        /* NOTE: the flock constant seems to be the same for every
4973
           Linux platform */
4974
        ret = get_errno(flock(arg1, arg2));
4975
        break;
4976
    case TARGET_NR_readv:
4977
        {
4978
            int count = arg3;
4979
            struct iovec *vec;
4980

    
4981
            vec = alloca(count * sizeof(struct iovec));
4982
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
4983
                goto efault;
4984
            ret = get_errno(readv(arg1, vec, count));
4985
            unlock_iovec(vec, arg2, count, 1);
4986
        }
4987
        break;
4988
    case TARGET_NR_writev:
4989
        {
4990
            int count = arg3;
<