Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 1eec614b

History | View | Annotate | Download (189.2 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., 51 Franklin Street - Fifth Floor, Boston,
19
 *  MA 02110-1301, USA.
20
 */
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <stdarg.h>
24
#include <string.h>
25
#include <elf.h>
26
#include <endian.h>
27
#include <errno.h>
28
#include <unistd.h>
29
#include <fcntl.h>
30
#include <time.h>
31
#include <limits.h>
32
#include <sys/types.h>
33
#include <sys/ipc.h>
34
#include <sys/msg.h>
35
#include <sys/wait.h>
36
#include <sys/time.h>
37
#include <sys/stat.h>
38
#include <sys/mount.h>
39
#include <sys/prctl.h>
40
#include <sys/resource.h>
41
#include <sys/mman.h>
42
#include <sys/swap.h>
43
#include <signal.h>
44
#include <sched.h>
45
#include <sys/socket.h>
46
#include <sys/uio.h>
47
#include <sys/poll.h>
48
#include <sys/times.h>
49
#include <sys/shm.h>
50
#include <sys/sem.h>
51
#include <sys/statfs.h>
52
#include <utime.h>
53
#include <sys/sysinfo.h>
54
//#include <sys/user.h>
55
#include <netinet/ip.h>
56
#include <netinet/tcp.h>
57
#include <qemu-common.h>
58
#ifdef HAVE_GPROF
59
#include <sys/gmon.h>
60
#endif
61

    
62
#define termios host_termios
63
#define winsize host_winsize
64
#define termio host_termio
65
#define sgttyb host_sgttyb /* same as target */
66
#define tchars host_tchars /* same as target */
67
#define ltchars host_ltchars /* same as target */
68

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

    
79
#include "qemu.h"
80
#include "qemu-common.h"
81

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

    
91
//#define DEBUG
92

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

    
99
//#include <linux/msdos_fs.h>
100
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
101
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
102

    
103

    
104
#undef _syscall0
105
#undef _syscall1
106
#undef _syscall2
107
#undef _syscall3
108
#undef _syscall4
109
#undef _syscall5
110
#undef _syscall6
111

    
112
#define _syscall0(type,name)                \
113
static type name (void)                        \
114
{                                        \
115
        return syscall(__NR_##name);        \
116
}
117

    
118
#define _syscall1(type,name,type1,arg1)                \
119
static type name (type1 arg1)                        \
120
{                                                \
121
        return syscall(__NR_##name, arg1);        \
122
}
123

    
124
#define _syscall2(type,name,type1,arg1,type2,arg2)        \
125
static type name (type1 arg1,type2 arg2)                \
126
{                                                        \
127
        return syscall(__NR_##name, arg1, arg2);        \
128
}
129

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

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

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

    
149

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

    
158

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

    
188
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
189
#define __NR__llseek __NR_lseek
190
#endif
191

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

    
297
extern int personality(int);
298
extern int flock(int, int);
299
extern int setfsuid(int);
300
extern int setfsgid(int);
301
extern int setgroups(int, gid_t *);
302

    
303
#define ERRNO_TABLE_SIZE 1200
304

    
305
/* target_to_host_errno_table[] is initialized from
306
 * host_to_target_errno_table[] in syscall_init(). */
307
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
308
};
309

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

    
422
static inline int host_to_target_errno(int err)
423
{
424
    if(host_to_target_errno_table[err])
425
        return host_to_target_errno_table[err];
426
    return err;
427
}
428

    
429
static inline int target_to_host_errno(int err)
430
{
431
    if (target_to_host_errno_table[err])
432
        return target_to_host_errno_table[err];
433
    return err;
434
}
435

    
436
static inline abi_long get_errno(abi_long ret)
437
{
438
    if (ret == -1)
439
        return -host_to_target_errno(errno);
440
    else
441
        return ret;
442
}
443

    
444
static inline int is_error(abi_long ret)
445
{
446
    return (abi_ulong)ret >= (abi_ulong)(-4096);
447
}
448

    
449
char *target_strerror(int err)
450
{
451
    return strerror(target_to_host_errno(err));
452
}
453

    
454
static abi_ulong target_brk;
455
static abi_ulong target_original_brk;
456

    
457
void target_set_brk(abi_ulong new_brk)
458
{
459
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
460
}
461

    
462
/* do_brk() must return target values and target errnos. */
463
abi_long do_brk(abi_ulong new_brk)
464
{
465
    abi_ulong brk_page;
466
    abi_long mapped_addr;
467
    int        new_alloc_size;
468

    
469
    if (!new_brk)
470
        return target_brk;
471
    if (new_brk < target_original_brk)
472
        return target_brk;
473

    
474
    brk_page = HOST_PAGE_ALIGN(target_brk);
475

    
476
    /* If the new brk is less than this, set it and we're done... */
477
    if (new_brk < brk_page) {
478
        target_brk = new_brk;
479
            return target_brk;
480
    }
481

    
482
    /* We need to allocate more memory after the brk... */
483
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
484
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
485
                                        PROT_READ|PROT_WRITE,
486
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
487

    
488
    if (!is_error(mapped_addr))
489
        target_brk = new_brk;
490
    
491
    return target_brk;
492
}
493

    
494
static inline abi_long copy_from_user_fdset(fd_set *fds,
495
                                            abi_ulong target_fds_addr,
496
                                            int n)
497
{
498
    int i, nw, j, k;
499
    abi_ulong b, *target_fds;
500

    
501
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
502
    if (!(target_fds = lock_user(VERIFY_READ,
503
                                 target_fds_addr,
504
                                 sizeof(abi_ulong) * nw,
505
                                 1)))
506
        return -TARGET_EFAULT;
507

    
508
    FD_ZERO(fds);
509
    k = 0;
510
    for (i = 0; i < nw; i++) {
511
        /* grab the abi_ulong */
512
        __get_user(b, &target_fds[i]);
513
        for (j = 0; j < TARGET_ABI_BITS; j++) {
514
            /* check the bit inside the abi_ulong */
515
            if ((b >> j) & 1)
516
                FD_SET(k, fds);
517
            k++;
518
        }
519
    }
520

    
521
    unlock_user(target_fds, target_fds_addr, 0);
522

    
523
    return 0;
524
}
525

    
526
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
527
                                          const fd_set *fds,
528
                                          int n)
529
{
530
    int i, nw, j, k;
531
    abi_long v;
532
    abi_ulong *target_fds;
533

    
534
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
535
    if (!(target_fds = lock_user(VERIFY_WRITE,
536
                                 target_fds_addr,
537
                                 sizeof(abi_ulong) * nw,
538
                                 0)))
539
        return -TARGET_EFAULT;
540

    
541
    k = 0;
542
    for (i = 0; i < nw; i++) {
543
        v = 0;
544
        for (j = 0; j < TARGET_ABI_BITS; j++) {
545
            v |= ((FD_ISSET(k, fds) != 0) << j);
546
            k++;
547
        }
548
        __put_user(v, &target_fds[i]);
549
    }
550

    
551
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
552

    
553
    return 0;
554
}
555

    
556
#if defined(__alpha__)
557
#define HOST_HZ 1024
558
#else
559
#define HOST_HZ 100
560
#endif
561

    
562
static inline abi_long host_to_target_clock_t(long ticks)
563
{
564
#if HOST_HZ == TARGET_HZ
565
    return ticks;
566
#else
567
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
568
#endif
569
}
570

    
571
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
572
                                             const struct rusage *rusage)
573
{
574
    struct target_rusage *target_rusage;
575

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

    
598
    return 0;
599
}
600

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

    
606
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
607
        return -TARGET_EFAULT;
608

    
609
    __get_user(tv->tv_sec, &target_tv->tv_sec);
610
    __get_user(tv->tv_usec, &target_tv->tv_usec);
611

    
612
    unlock_user_struct(target_tv, target_tv_addr, 0);
613

    
614
    return 0;
615
}
616

    
617
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
618
                                            const struct timeval *tv)
619
{
620
    struct target_timeval *target_tv;
621

    
622
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
623
        return -TARGET_EFAULT;
624

    
625
    __put_user(tv->tv_sec, &target_tv->tv_sec);
626
    __put_user(tv->tv_usec, &target_tv->tv_usec);
627

    
628
    unlock_user_struct(target_tv, target_tv_addr, 1);
629

    
630
    return 0;
631
}
632

    
633

    
634
/* do_select() must return target values and target errnos. */
635
static abi_long do_select(int n,
636
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
637
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
638
{
639
    fd_set rfds, wfds, efds;
640
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
641
    struct timeval tv, *tv_ptr;
642
    abi_long ret;
643

    
644
    if (rfd_addr) {
645
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
646
            return -TARGET_EFAULT;
647
        rfds_ptr = &rfds;
648
    } else {
649
        rfds_ptr = NULL;
650
    }
651
    if (wfd_addr) {
652
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
653
            return -TARGET_EFAULT;
654
        wfds_ptr = &wfds;
655
    } else {
656
        wfds_ptr = NULL;
657
    }
658
    if (efd_addr) {
659
        if (copy_from_user_fdset(&efds, efd_addr, n))
660
            return -TARGET_EFAULT;
661
        efds_ptr = &efds;
662
    } else {
663
        efds_ptr = NULL;
664
    }
665

    
666
    if (target_tv_addr) {
667
        if (copy_from_user_timeval(&tv, target_tv_addr))
668
            return -TARGET_EFAULT;
669
        tv_ptr = &tv;
670
    } else {
671
        tv_ptr = NULL;
672
    }
673

    
674
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
675

    
676
    if (!is_error(ret)) {
677
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
678
            return -TARGET_EFAULT;
679
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
680
            return -TARGET_EFAULT;
681
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
682
            return -TARGET_EFAULT;
683

    
684
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
685
            return -TARGET_EFAULT;
686
    }
687

    
688
    return ret;
689
}
690

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

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

    
704
    return 0;
705
}
706

    
707
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
708
                                               struct sockaddr *addr,
709
                                               socklen_t len)
710
{
711
    struct target_sockaddr *target_saddr;
712

    
713
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
714
    if (!target_saddr)
715
        return -TARGET_EFAULT;
716
    memcpy(target_saddr, addr, len);
717
    target_saddr->sa_family = tswap16(addr->sa_family);
718
    unlock_user(target_saddr, target_addr, len);
719

    
720
    return 0;
721
}
722

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

    
741
    while (cmsg && target_cmsg) {
742
        void *data = CMSG_DATA(cmsg);
743
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
744

    
745
        int len = tswapl(target_cmsg->cmsg_len)
746
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
747

    
748
        space += CMSG_SPACE(len);
749
        if (space > msgh->msg_controllen) {
750
            space -= CMSG_SPACE(len);
751
            gemu_log("Host cmsg overflow\n");
752
            break;
753
        }
754

    
755
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
756
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
757
        cmsg->cmsg_len = CMSG_LEN(len);
758

    
759
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
760
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
761
            memcpy(data, target_data, len);
762
        } else {
763
            int *fd = (int *)data;
764
            int *target_fd = (int *)target_data;
765
            int i, numfds = len / sizeof(int);
766

    
767
            for (i = 0; i < numfds; i++)
768
                fd[i] = tswap32(target_fd[i]);
769
        }
770

    
771
        cmsg = CMSG_NXTHDR(msgh, cmsg);
772
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
773
    }
774
    unlock_user(target_cmsg, target_cmsg_addr, 0);
775
 the_end:
776
    msgh->msg_controllen = space;
777
    return 0;
778
}
779

    
780
/* ??? Should this also swap msgh->name?  */
781
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
782
                                           struct msghdr *msgh)
783
{
784
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
785
    abi_long msg_controllen;
786
    abi_ulong target_cmsg_addr;
787
    struct target_cmsghdr *target_cmsg;
788
    socklen_t space = 0;
789

    
790
    msg_controllen = tswapl(target_msgh->msg_controllen);
791
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
792
        goto the_end;
793
    target_cmsg_addr = tswapl(target_msgh->msg_control);
794
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
795
    if (!target_cmsg)
796
        return -TARGET_EFAULT;
797

    
798
    while (cmsg && target_cmsg) {
799
        void *data = CMSG_DATA(cmsg);
800
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
801

    
802
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
803

    
804
        space += TARGET_CMSG_SPACE(len);
805
        if (space > msg_controllen) {
806
            space -= TARGET_CMSG_SPACE(len);
807
            gemu_log("Target cmsg overflow\n");
808
            break;
809
        }
810

    
811
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
812
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
813
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
814

    
815
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
816
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
817
            memcpy(target_data, data, len);
818
        } else {
819
            int *fd = (int *)data;
820
            int *target_fd = (int *)target_data;
821
            int i, numfds = len / sizeof(int);
822

    
823
            for (i = 0; i < numfds; i++)
824
                target_fd[i] = tswap32(fd[i]);
825
        }
826

    
827
        cmsg = CMSG_NXTHDR(msgh, cmsg);
828
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
829
    }
830
    unlock_user(target_cmsg, target_cmsg_addr, space);
831
 the_end:
832
    target_msgh->msg_controllen = tswapl(space);
833
    return 0;
834
}
835

    
836
/* do_setsockopt() Must return target values and target errnos. */
837
static abi_long do_setsockopt(int sockfd, int level, int optname,
838
                              abi_ulong optval_addr, socklen_t optlen)
839
{
840
    abi_long ret;
841
    int val;
842

    
843
    switch(level) {
844
    case SOL_TCP:
845
        /* TCP options all take an 'int' value.  */
846
        if (optlen < sizeof(uint32_t))
847
            return -TARGET_EINVAL;
848

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

    
950
        if (get_user_u32(val, optval_addr))
951
            return -TARGET_EFAULT;
952
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
953
        break;
954
    default:
955
    unimplemented:
956
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
957
        ret = -TARGET_ENOPROTOOPT;
958
    }
959
    return ret;
960
}
961

    
962
/* do_getsockopt() Must return target values and target errnos. */
963
static abi_long do_getsockopt(int sockfd, int level, int optname,
964
                              abi_ulong optval_addr, abi_ulong optlen)
965
{
966
    abi_long ret;
967
    int len, val;
968
    socklen_t lv;
969

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

    
1062
/* FIXME
1063
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1064
 * other lock functions have a return code of 0 for failure.
1065
 */
1066
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1067
                           int count, int copy)
1068
{
1069
    struct target_iovec *target_vec;
1070
    abi_ulong base;
1071
    int i;
1072

    
1073
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1074
    if (!target_vec)
1075
        return -TARGET_EFAULT;
1076
    for(i = 0;i < count; i++) {
1077
        base = tswapl(target_vec[i].iov_base);
1078
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1079
        if (vec[i].iov_len != 0) {
1080
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1081
            /* Don't check lock_user return value. We must call writev even
1082
               if a element has invalid base address. */
1083
        } else {
1084
            /* zero length pointer is ignored */
1085
            vec[i].iov_base = NULL;
1086
        }
1087
    }
1088
    unlock_user (target_vec, target_addr, 0);
1089
    return 0;
1090
}
1091

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

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

    
1110
    return 0;
1111
}
1112

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

    
1143
/* MAX_SOCK_ADDR from linux/net/socket.c */
1144
#define MAX_SOCK_ADDR        128
1145

    
1146
/* do_bind() Must return target values and target errnos. */
1147
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1148
                        socklen_t addrlen)
1149
{
1150
    void *addr;
1151

    
1152
    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1153
        return -TARGET_EINVAL;
1154

    
1155
    addr = alloca(addrlen);
1156

    
1157
    target_to_host_sockaddr(addr, target_addr, addrlen);
1158
    return get_errno(bind(sockfd, addr, addrlen));
1159
}
1160

    
1161
/* do_connect() Must return target values and target errnos. */
1162
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1163
                           socklen_t addrlen)
1164
{
1165
    void *addr;
1166

    
1167
    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1168
        return -TARGET_EINVAL;
1169

    
1170
    addr = alloca(addrlen);
1171

    
1172
    target_to_host_sockaddr(addr, target_addr, addrlen);
1173
    return get_errno(connect(sockfd, addr, addrlen));
1174
}
1175

    
1176
/* do_sendrecvmsg() Must return target values and target errnos. */
1177
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1178
                               int flags, int send)
1179
{
1180
    abi_long ret, len;
1181
    struct target_msghdr *msgp;
1182
    struct msghdr msg;
1183
    int count;
1184
    struct iovec *vec;
1185
    abi_ulong target_vec;
1186

    
1187
    /* FIXME */
1188
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1189
                          msgp,
1190
                          target_msg,
1191
                          send ? 1 : 0))
1192
        return -TARGET_EFAULT;
1193
    if (msgp->msg_name) {
1194
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1195
        msg.msg_name = alloca(msg.msg_namelen);
1196
        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1197
                                msg.msg_namelen);
1198
    } else {
1199
        msg.msg_name = NULL;
1200
        msg.msg_namelen = 0;
1201
    }
1202
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1203
    msg.msg_control = alloca(msg.msg_controllen);
1204
    msg.msg_flags = tswap32(msgp->msg_flags);
1205

    
1206
    count = tswapl(msgp->msg_iovlen);
1207
    vec = alloca(count * sizeof(struct iovec));
1208
    target_vec = tswapl(msgp->msg_iov);
1209
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1210
    msg.msg_iovlen = count;
1211
    msg.msg_iov = vec;
1212

    
1213
    if (send) {
1214
        ret = target_to_host_cmsg(&msg, msgp);
1215
        if (ret == 0)
1216
            ret = get_errno(sendmsg(fd, &msg, flags));
1217
    } else {
1218
        ret = get_errno(recvmsg(fd, &msg, flags));
1219
        if (!is_error(ret)) {
1220
            len = ret;
1221
            ret = host_to_target_cmsg(msgp, &msg);
1222
            if (!is_error(ret))
1223
                ret = len;
1224
        }
1225
    }
1226
    unlock_iovec(vec, target_vec, count, !send);
1227
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1228
    return ret;
1229
}
1230

    
1231
/* do_accept() Must return target values and target errnos. */
1232
static abi_long do_accept(int fd, abi_ulong target_addr,
1233
                          abi_ulong target_addrlen_addr)
1234
{
1235
    socklen_t addrlen;
1236
    void *addr;
1237
    abi_long ret;
1238

    
1239
    if (get_user_u32(addrlen, target_addrlen_addr))
1240
        return -TARGET_EFAULT;
1241

    
1242
    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1243
        return -TARGET_EINVAL;
1244

    
1245
    addr = alloca(addrlen);
1246

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

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

    
1264
    if (get_user_u32(addrlen, target_addrlen_addr))
1265
        return -TARGET_EFAULT;
1266

    
1267
    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1268
        return -TARGET_EINVAL;
1269

    
1270
    addr = alloca(addrlen);
1271

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

    
1281
/* do_getsockname() Must return target values and target errnos. */
1282
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1283
                               abi_ulong target_addrlen_addr)
1284
{
1285
    socklen_t addrlen;
1286
    void *addr;
1287
    abi_long ret;
1288

    
1289
    if (target_addr == 0)
1290
       return get_errno(accept(fd, NULL, NULL));
1291

    
1292
    if (get_user_u32(addrlen, target_addrlen_addr))
1293
        return -TARGET_EFAULT;
1294

    
1295
    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1296
        return -TARGET_EINVAL;
1297

    
1298
    addr = alloca(addrlen);
1299

    
1300
    ret = get_errno(getsockname(fd, addr, &addrlen));
1301
    if (!is_error(ret)) {
1302
        host_to_target_sockaddr(target_addr, addr, addrlen);
1303
        if (put_user_u32(addrlen, target_addrlen_addr))
1304
            ret = -TARGET_EFAULT;
1305
    }
1306
    return ret;
1307
}
1308

    
1309
/* do_socketpair() Must return target values and target errnos. */
1310
static abi_long do_socketpair(int domain, int type, int protocol,
1311
                              abi_ulong target_tab_addr)
1312
{
1313
    int tab[2];
1314
    abi_long ret;
1315

    
1316
    ret = get_errno(socketpair(domain, type, protocol, tab));
1317
    if (!is_error(ret)) {
1318
        if (put_user_s32(tab[0], target_tab_addr)
1319
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1320
            ret = -TARGET_EFAULT;
1321
    }
1322
    return ret;
1323
}
1324

    
1325
/* do_sendto() Must return target values and target errnos. */
1326
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1327
                          abi_ulong target_addr, socklen_t addrlen)
1328
{
1329
    void *addr;
1330
    void *host_msg;
1331
    abi_long ret;
1332

    
1333
    if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
1334
        return -TARGET_EINVAL;
1335

    
1336
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1337
    if (!host_msg)
1338
        return -TARGET_EFAULT;
1339
    if (target_addr) {
1340
        addr = alloca(addrlen);
1341
        target_to_host_sockaddr(addr, target_addr, addrlen);
1342
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1343
    } else {
1344
        ret = get_errno(send(fd, host_msg, len, flags));
1345
    }
1346
    unlock_user(host_msg, msg, 0);
1347
    return ret;
1348
}
1349

    
1350
/* do_recvfrom() Must return target values and target errnos. */
1351
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1352
                            abi_ulong target_addr,
1353
                            abi_ulong target_addrlen)
1354
{
1355
    socklen_t addrlen;
1356
    void *addr;
1357
    void *host_msg;
1358
    abi_long ret;
1359

    
1360
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1361
    if (!host_msg)
1362
        return -TARGET_EFAULT;
1363
    if (target_addr) {
1364
        if (get_user_u32(addrlen, target_addrlen)) {
1365
            ret = -TARGET_EFAULT;
1366
            goto fail;
1367
        }
1368
        if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) {
1369
            ret = -TARGET_EINVAL;
1370
            goto fail;
1371
        }
1372
        addr = alloca(addrlen);
1373
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1374
    } else {
1375
        addr = NULL; /* To keep compiler quiet.  */
1376
        ret = get_errno(recv(fd, host_msg, len, flags));
1377
    }
1378
    if (!is_error(ret)) {
1379
        if (target_addr) {
1380
            host_to_target_sockaddr(target_addr, addr, addrlen);
1381
            if (put_user_u32(addrlen, target_addrlen)) {
1382
                ret = -TARGET_EFAULT;
1383
                goto fail;
1384
            }
1385
        }
1386
        unlock_user(host_msg, msg, len);
1387
    } else {
1388
fail:
1389
        unlock_user(host_msg, msg, 0);
1390
    }
1391
    return ret;
1392
}
1393

    
1394
#ifdef TARGET_NR_socketcall
1395
/* do_socketcall() Must return target values and target errnos. */
1396
static abi_long do_socketcall(int num, abi_ulong vptr)
1397
{
1398
    abi_long ret;
1399
    const int n = sizeof(abi_ulong);
1400

    
1401
    switch(num) {
1402
    case SOCKOP_socket:
1403
        {
1404
            int domain, type, protocol;
1405

    
1406
            if (get_user_s32(domain, vptr)
1407
                || get_user_s32(type, vptr + n)
1408
                || get_user_s32(protocol, vptr + 2 * n))
1409
                return -TARGET_EFAULT;
1410

    
1411
            ret = do_socket(domain, type, protocol);
1412
        }
1413
        break;
1414
    case SOCKOP_bind:
1415
        {
1416
            int sockfd;
1417
            abi_ulong target_addr;
1418
            socklen_t addrlen;
1419

    
1420
            if (get_user_s32(sockfd, vptr)
1421
                || get_user_ual(target_addr, vptr + n)
1422
                || get_user_u32(addrlen, vptr + 2 * n))
1423
                return -TARGET_EFAULT;
1424

    
1425
            ret = do_bind(sockfd, target_addr, addrlen);
1426
        }
1427
        break;
1428
    case SOCKOP_connect:
1429
        {
1430
            int sockfd;
1431
            abi_ulong target_addr;
1432
            socklen_t addrlen;
1433

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

    
1439
            ret = do_connect(sockfd, target_addr, addrlen);
1440
        }
1441
        break;
1442
    case SOCKOP_listen:
1443
        {
1444
            int sockfd, backlog;
1445

    
1446
            if (get_user_s32(sockfd, vptr)
1447
                || get_user_s32(backlog, vptr + n))
1448
                return -TARGET_EFAULT;
1449

    
1450
            ret = get_errno(listen(sockfd, backlog));
1451
        }
1452
        break;
1453
    case SOCKOP_accept:
1454
        {
1455
            int sockfd;
1456
            abi_ulong target_addr, target_addrlen;
1457

    
1458
            if (get_user_s32(sockfd, vptr)
1459
                || get_user_ual(target_addr, vptr + n)
1460
                || get_user_u32(target_addrlen, vptr + 2 * n))
1461
                return -TARGET_EFAULT;
1462

    
1463
            ret = do_accept(sockfd, target_addr, target_addrlen);
1464
        }
1465
        break;
1466
    case SOCKOP_getsockname:
1467
        {
1468
            int sockfd;
1469
            abi_ulong target_addr, target_addrlen;
1470

    
1471
            if (get_user_s32(sockfd, vptr)
1472
                || get_user_ual(target_addr, vptr + n)
1473
                || get_user_u32(target_addrlen, vptr + 2 * n))
1474
                return -TARGET_EFAULT;
1475

    
1476
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1477
        }
1478
        break;
1479
    case SOCKOP_getpeername:
1480
        {
1481
            int sockfd;
1482
            abi_ulong target_addr, target_addrlen;
1483

    
1484
            if (get_user_s32(sockfd, vptr)
1485
                || get_user_ual(target_addr, vptr + n)
1486
                || get_user_u32(target_addrlen, vptr + 2 * n))
1487
                return -TARGET_EFAULT;
1488

    
1489
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1490
        }
1491
        break;
1492
    case SOCKOP_socketpair:
1493
        {
1494
            int domain, type, protocol;
1495
            abi_ulong tab;
1496

    
1497
            if (get_user_s32(domain, vptr)
1498
                || get_user_s32(type, vptr + n)
1499
                || get_user_s32(protocol, vptr + 2 * n)
1500
                || get_user_ual(tab, vptr + 3 * n))
1501
                return -TARGET_EFAULT;
1502

    
1503
            ret = do_socketpair(domain, type, protocol, tab);
1504
        }
1505
        break;
1506
    case SOCKOP_send:
1507
        {
1508
            int sockfd;
1509
            abi_ulong msg;
1510
            size_t len;
1511
            int flags;
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
                return -TARGET_EFAULT;
1518

    
1519
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1520
        }
1521
        break;
1522
    case SOCKOP_recv:
1523
        {
1524
            int sockfd;
1525
            abi_ulong msg;
1526
            size_t len;
1527
            int flags;
1528

    
1529
            if (get_user_s32(sockfd, vptr)
1530
                || get_user_ual(msg, vptr + n)
1531
                || get_user_ual(len, vptr + 2 * n)
1532
                || get_user_s32(flags, vptr + 3 * n))
1533
                return -TARGET_EFAULT;
1534

    
1535
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1536
        }
1537
        break;
1538
    case SOCKOP_sendto:
1539
        {
1540
            int sockfd;
1541
            abi_ulong msg;
1542
            size_t len;
1543
            int flags;
1544
            abi_ulong addr;
1545
            socklen_t addrlen;
1546

    
1547
            if (get_user_s32(sockfd, vptr)
1548
                || get_user_ual(msg, vptr + n)
1549
                || get_user_ual(len, vptr + 2 * n)
1550
                || get_user_s32(flags, vptr + 3 * n)
1551
                || get_user_ual(addr, vptr + 4 * n)
1552
                || get_user_u32(addrlen, vptr + 5 * n))
1553
                return -TARGET_EFAULT;
1554

    
1555
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1556
        }
1557
        break;
1558
    case SOCKOP_recvfrom:
1559
        {
1560
            int sockfd;
1561
            abi_ulong msg;
1562
            size_t len;
1563
            int flags;
1564
            abi_ulong addr;
1565
            socklen_t addrlen;
1566

    
1567
            if (get_user_s32(sockfd, vptr)
1568
                || get_user_ual(msg, vptr + n)
1569
                || get_user_ual(len, vptr + 2 * n)
1570
                || get_user_s32(flags, vptr + 3 * n)
1571
                || get_user_ual(addr, vptr + 4 * n)
1572
                || get_user_u32(addrlen, vptr + 5 * n))
1573
                return -TARGET_EFAULT;
1574

    
1575
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1576
        }
1577
        break;
1578
    case SOCKOP_shutdown:
1579
        {
1580
            int sockfd, how;
1581

    
1582
            if (get_user_s32(sockfd, vptr)
1583
                || get_user_s32(how, vptr + n))
1584
                return -TARGET_EFAULT;
1585

    
1586
            ret = get_errno(shutdown(sockfd, how));
1587
        }
1588
        break;
1589
    case SOCKOP_sendmsg:
1590
    case SOCKOP_recvmsg:
1591
        {
1592
            int fd;
1593
            abi_ulong target_msg;
1594
            int flags;
1595

    
1596
            if (get_user_s32(fd, vptr)
1597
                || get_user_ual(target_msg, vptr + n)
1598
                || get_user_s32(flags, vptr + 2 * n))
1599
                return -TARGET_EFAULT;
1600

    
1601
            ret = do_sendrecvmsg(fd, target_msg, flags,
1602
                                 (num == SOCKOP_sendmsg));
1603
        }
1604
        break;
1605
    case SOCKOP_setsockopt:
1606
        {
1607
            int sockfd;
1608
            int level;
1609
            int optname;
1610
            abi_ulong optval;
1611
            socklen_t optlen;
1612

    
1613
            if (get_user_s32(sockfd, vptr)
1614
                || get_user_s32(level, vptr + n)
1615
                || get_user_s32(optname, vptr + 2 * n)
1616
                || get_user_ual(optval, vptr + 3 * n)
1617
                || get_user_u32(optlen, vptr + 4 * n))
1618
                return -TARGET_EFAULT;
1619

    
1620
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1621
        }
1622
        break;
1623
    case SOCKOP_getsockopt:
1624
        {
1625
            int sockfd;
1626
            int level;
1627
            int optname;
1628
            abi_ulong optval;
1629
            socklen_t optlen;
1630

    
1631
            if (get_user_s32(sockfd, vptr)
1632
                || get_user_s32(level, vptr + n)
1633
                || get_user_s32(optname, vptr + 2 * n)
1634
                || get_user_ual(optval, vptr + 3 * n)
1635
                || get_user_u32(optlen, vptr + 4 * n))
1636
                return -TARGET_EFAULT;
1637

    
1638
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1639
        }
1640
        break;
1641
    default:
1642
        gemu_log("Unsupported socketcall: %d\n", num);
1643
        ret = -TARGET_ENOSYS;
1644
        break;
1645
    }
1646
    return ret;
1647
}
1648
#endif
1649

    
1650
#ifdef TARGET_NR_ipc
1651
#define N_SHM_REGIONS        32
1652

    
1653
static struct shm_region {
1654
    abi_ulong        start;
1655
    abi_ulong        size;
1656
} shm_regions[N_SHM_REGIONS];
1657
#endif
1658

    
1659
struct target_ipc_perm
1660
{
1661
    abi_long __key;
1662
    abi_ulong uid;
1663
    abi_ulong gid;
1664
    abi_ulong cuid;
1665
    abi_ulong cgid;
1666
    unsigned short int mode;
1667
    unsigned short int __pad1;
1668
    unsigned short int __seq;
1669
    unsigned short int __pad2;
1670
    abi_ulong __unused1;
1671
    abi_ulong __unused2;
1672
};
1673

    
1674
struct target_semid_ds
1675
{
1676
  struct target_ipc_perm sem_perm;
1677
  abi_ulong sem_otime;
1678
  abi_ulong __unused1;
1679
  abi_ulong sem_ctime;
1680
  abi_ulong __unused2;
1681
  abi_ulong sem_nsems;
1682
  abi_ulong __unused3;
1683
  abi_ulong __unused4;
1684
};
1685

    
1686
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1687
                                               abi_ulong target_addr)
1688
{
1689
    struct target_ipc_perm *target_ip;
1690
    struct target_semid_ds *target_sd;
1691

    
1692
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1693
        return -TARGET_EFAULT;
1694
    target_ip=&(target_sd->sem_perm);
1695
    host_ip->__key = tswapl(target_ip->__key);
1696
    host_ip->uid = tswapl(target_ip->uid);
1697
    host_ip->gid = tswapl(target_ip->gid);
1698
    host_ip->cuid = tswapl(target_ip->cuid);
1699
    host_ip->cgid = tswapl(target_ip->cgid);
1700
    host_ip->mode = tswapl(target_ip->mode);
1701
    unlock_user_struct(target_sd, target_addr, 0);
1702
    return 0;
1703
}
1704

    
1705
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1706
                                               struct ipc_perm *host_ip)
1707
{
1708
    struct target_ipc_perm *target_ip;
1709
    struct target_semid_ds *target_sd;
1710

    
1711
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1712
        return -TARGET_EFAULT;
1713
    target_ip = &(target_sd->sem_perm);
1714
    target_ip->__key = tswapl(host_ip->__key);
1715
    target_ip->uid = tswapl(host_ip->uid);
1716
    target_ip->gid = tswapl(host_ip->gid);
1717
    target_ip->cuid = tswapl(host_ip->cuid);
1718
    target_ip->cgid = tswapl(host_ip->cgid);
1719
    target_ip->mode = tswapl(host_ip->mode);
1720
    unlock_user_struct(target_sd, target_addr, 1);
1721
    return 0;
1722
}
1723

    
1724
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1725
                                               abi_ulong target_addr)
1726
{
1727
    struct target_semid_ds *target_sd;
1728

    
1729
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1730
        return -TARGET_EFAULT;
1731
    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1732
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1733
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
1734
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1735
    unlock_user_struct(target_sd, target_addr, 0);
1736
    return 0;
1737
}
1738

    
1739
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1740
                                               struct semid_ds *host_sd)
1741
{
1742
    struct target_semid_ds *target_sd;
1743

    
1744
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1745
        return -TARGET_EFAULT;
1746
    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1747
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1748
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
1749
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1750
    unlock_user_struct(target_sd, target_addr, 1);
1751
    return 0;
1752
}
1753

    
1754
union semun {
1755
        int val;
1756
        struct semid_ds *buf;
1757
        unsigned short *array;
1758
};
1759

    
1760
union target_semun {
1761
        int val;
1762
        abi_long buf;
1763
        unsigned short int *array;
1764
};
1765

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

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

    
1802
static inline abi_long host_to_target_semun(int cmd,
1803
                                            abi_ulong target_addr,
1804
                                            union semun *host_su,
1805
                                            struct semid_ds *ds)
1806
{
1807
    union target_semun *target_su;
1808

    
1809
    switch( cmd ) {
1810
        case IPC_STAT:
1811
        case IPC_SET:
1812
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1813
               return -TARGET_EFAULT;
1814
           host_to_target_semid_ds(target_su->buf,ds);
1815
           unlock_user_struct(target_su, target_addr, 1);
1816
           break;
1817
        case GETVAL:
1818
        case SETVAL:
1819
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1820
               return -TARGET_EFAULT;
1821
           target_su->val = tswapl(host_su->val);
1822
           unlock_user_struct(target_su, target_addr, 1);
1823
           break;
1824
        case GETALL:
1825
        case SETALL:
1826
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1827
               return -TARGET_EFAULT;
1828
           *target_su->array = tswap16(*host_su->array);
1829
           unlock_user_struct(target_su, target_addr, 1);
1830
           break;
1831
        default:
1832
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1833
    }
1834
    return 0;
1835
}
1836

    
1837
static inline abi_long do_semctl(int first, int second, int third,
1838
                                 abi_long ptr)
1839
{
1840
    union semun arg;
1841
    struct semid_ds dsarg;
1842
    int cmd = third&0xff;
1843
    abi_long ret = 0;
1844

    
1845
    switch( cmd ) {
1846
        case GETVAL:
1847
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1848
            ret = get_errno(semctl(first, second, cmd, arg));
1849
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1850
            break;
1851
        case SETVAL:
1852
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1853
            ret = get_errno(semctl(first, second, cmd, arg));
1854
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1855
            break;
1856
        case GETALL:
1857
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1858
            ret = get_errno(semctl(first, second, cmd, arg));
1859
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1860
            break;
1861
        case SETALL:
1862
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1863
            ret = get_errno(semctl(first, second, cmd, arg));
1864
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1865
            break;
1866
        case IPC_STAT:
1867
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1868
            ret = get_errno(semctl(first, second, cmd, arg));
1869
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1870
            break;
1871
        case IPC_SET:
1872
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1873
            ret = get_errno(semctl(first, second, cmd, arg));
1874
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1875
            break;
1876
    default:
1877
            ret = get_errno(semctl(first, second, cmd, arg));
1878
    }
1879

    
1880
    return ret;
1881
}
1882

    
1883
struct target_msqid_ds
1884
{
1885
    struct target_ipc_perm msg_perm;
1886
    abi_ulong msg_stime;
1887
#if TARGET_ABI_BITS == 32
1888
    abi_ulong __unused1;
1889
#endif
1890
    abi_ulong msg_rtime;
1891
#if TARGET_ABI_BITS == 32
1892
    abi_ulong __unused2;
1893
#endif
1894
    abi_ulong msg_ctime;
1895
#if TARGET_ABI_BITS == 32
1896
    abi_ulong __unused3;
1897
#endif
1898
    abi_ulong __msg_cbytes;
1899
    abi_ulong msg_qnum;
1900
    abi_ulong msg_qbytes;
1901
    abi_ulong msg_lspid;
1902
    abi_ulong msg_lrpid;
1903
    abi_ulong __unused4;
1904
    abi_ulong __unused5;
1905
};
1906

    
1907
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1908
                                               abi_ulong target_addr)
1909
{
1910
    struct target_msqid_ds *target_md;
1911

    
1912
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1913
        return -TARGET_EFAULT;
1914
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
1915
        return -TARGET_EFAULT;
1916
    host_md->msg_stime = tswapl(target_md->msg_stime);
1917
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
1918
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
1919
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1920
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
1921
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1922
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
1923
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1924
    unlock_user_struct(target_md, target_addr, 0);
1925
    return 0;
1926
}
1927

    
1928
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1929
                                               struct msqid_ds *host_md)
1930
{
1931
    struct target_msqid_ds *target_md;
1932

    
1933
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1934
        return -TARGET_EFAULT;
1935
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
1936
        return -TARGET_EFAULT;
1937
    target_md->msg_stime = tswapl(host_md->msg_stime);
1938
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
1939
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
1940
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1941
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
1942
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1943
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
1944
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1945
    unlock_user_struct(target_md, target_addr, 1);
1946
    return 0;
1947
}
1948

    
1949
struct target_msginfo {
1950
    int msgpool;
1951
    int msgmap;
1952
    int msgmax;
1953
    int msgmnb;
1954
    int msgmni;
1955
    int msgssz;
1956
    int msgtql;
1957
    unsigned short int msgseg;
1958
};
1959

    
1960
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
1961
                                              struct msginfo *host_msginfo)
1962
{
1963
    struct target_msginfo *target_msginfo;
1964
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
1965
        return -TARGET_EFAULT;
1966
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
1967
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
1968
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
1969
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
1970
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
1971
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
1972
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
1973
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
1974
    unlock_user_struct(target_msginfo, target_addr, 1);
1975
    return 0;
1976
}
1977

    
1978
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1979
{
1980
    struct msqid_ds dsarg;
1981
    struct msginfo msginfo;
1982
    abi_long ret = -TARGET_EINVAL;
1983

    
1984
    cmd &= 0xff;
1985

    
1986
    switch (cmd) {
1987
    case IPC_STAT:
1988
    case IPC_SET:
1989
    case MSG_STAT:
1990
        if (target_to_host_msqid_ds(&dsarg,ptr))
1991
            return -TARGET_EFAULT;
1992
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
1993
        if (host_to_target_msqid_ds(ptr,&dsarg))
1994
            return -TARGET_EFAULT;
1995
        break;
1996
    case IPC_RMID:
1997
        ret = get_errno(msgctl(msgid, cmd, NULL));
1998
        break;
1999
    case IPC_INFO:
2000
    case MSG_INFO:
2001
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2002
        if (host_to_target_msginfo(ptr, &msginfo))
2003
            return -TARGET_EFAULT;
2004
        break;
2005
    }
2006

    
2007
    return ret;
2008
}
2009

    
2010
struct target_msgbuf {
2011
    abi_long mtype;
2012
    char        mtext[1];
2013
};
2014

    
2015
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2016
                                 unsigned int msgsz, int msgflg)
2017
{
2018
    struct target_msgbuf *target_mb;
2019
    struct msgbuf *host_mb;
2020
    abi_long ret = 0;
2021

    
2022
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2023
        return -TARGET_EFAULT;
2024
    host_mb = malloc(msgsz+sizeof(long));
2025
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2026
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2027
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2028
    free(host_mb);
2029
    unlock_user_struct(target_mb, msgp, 0);
2030

    
2031
    return ret;
2032
}
2033

    
2034
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2035
                                 unsigned int msgsz, abi_long msgtyp,
2036
                                 int msgflg)
2037
{
2038
    struct target_msgbuf *target_mb;
2039
    char *target_mtext;
2040
    struct msgbuf *host_mb;
2041
    abi_long ret = 0;
2042

    
2043
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2044
        return -TARGET_EFAULT;
2045

    
2046
    host_mb = malloc(msgsz+sizeof(long));
2047
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2048

    
2049
    if (ret > 0) {
2050
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2051
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2052
        if (!target_mtext) {
2053
            ret = -TARGET_EFAULT;
2054
            goto end;
2055
        }
2056
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2057
        unlock_user(target_mtext, target_mtext_addr, ret);
2058
    }
2059

    
2060
    target_mb->mtype = tswapl(host_mb->mtype);
2061
    free(host_mb);
2062

    
2063
end:
2064
    if (target_mb)
2065
        unlock_user_struct(target_mb, msgp, 1);
2066
    return ret;
2067
}
2068

    
2069
#ifdef TARGET_NR_ipc
2070
/* ??? This only works with linear mappings.  */
2071
/* do_ipc() must return target values and target errnos. */
2072
static abi_long do_ipc(unsigned int call, int first,
2073
                       int second, int third,
2074
                       abi_long ptr, abi_long fifth)
2075
{
2076
    int version;
2077
    abi_long ret = 0;
2078
    struct shmid_ds shm_info;
2079
    int i;
2080

    
2081
    version = call >> 16;
2082
    call &= 0xffff;
2083

    
2084
    switch (call) {
2085
    case IPCOP_semop:
2086
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
2087
        break;
2088

    
2089
    case IPCOP_semget:
2090
        ret = get_errno(semget(first, second, third));
2091
        break;
2092

    
2093
    case IPCOP_semctl:
2094
        ret = do_semctl(first, second, third, ptr);
2095
        break;
2096

    
2097
    case IPCOP_semtimedop:
2098
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2099
        ret = -TARGET_ENOSYS;
2100
        break;
2101

    
2102
    case IPCOP_msgget:
2103
        ret = get_errno(msgget(first, second));
2104
        break;
2105

    
2106
    case IPCOP_msgsnd:
2107
        ret = do_msgsnd(first, ptr, second, third);
2108
        break;
2109

    
2110
    case IPCOP_msgctl:
2111
        ret = do_msgctl(first, second, ptr);
2112
        break;
2113

    
2114
    case IPCOP_msgrcv:
2115
        switch (version) {
2116
        case 0:
2117
            {
2118
                struct target_ipc_kludge {
2119
                    abi_long msgp;
2120
                    abi_long msgtyp;
2121
                } *tmp;
2122

    
2123
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2124
                    ret = -TARGET_EFAULT;
2125
                    break;
2126
                }
2127

    
2128
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2129

    
2130
                unlock_user_struct(tmp, ptr, 0);
2131
                break;
2132
            }
2133
        default:
2134
            ret = do_msgrcv(first, ptr, second, fifth, third);
2135
        }
2136
        break;
2137

    
2138
    case IPCOP_shmat:
2139
        {
2140
            abi_ulong raddr;
2141
            void *host_addr;
2142
            /* SHM_* flags are the same on all linux platforms */
2143
            host_addr = shmat(first, (void *)g2h(ptr), second);
2144
            if (host_addr == (void *)-1) {
2145
                ret = get_errno((long)host_addr);
2146
                break;
2147
            }
2148
            raddr = h2g((unsigned long)host_addr);
2149
            /* find out the length of the shared memory segment */
2150
            
2151
            ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2152
            if (is_error(ret)) {
2153
                /* can't get length, bail out */
2154
                shmdt(host_addr);
2155
                break;
2156
            }
2157
            page_set_flags(raddr, raddr + shm_info.shm_segsz,
2158
                           PAGE_VALID | PAGE_READ |
2159
                           ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2160
            for (i = 0; i < N_SHM_REGIONS; ++i) {
2161
                if (shm_regions[i].start == 0) {
2162
                    shm_regions[i].start = raddr;
2163
                    shm_regions[i].size = shm_info.shm_segsz;
2164
                    break;
2165
                }
2166
            }
2167
            if (put_user_ual(raddr, third))
2168
                return -TARGET_EFAULT;
2169
            ret = 0;
2170
        }
2171
        break;
2172
    case IPCOP_shmdt:
2173
        for (i = 0; i < N_SHM_REGIONS; ++i) {
2174
            if (shm_regions[i].start == ptr) {
2175
                shm_regions[i].start = 0;
2176
                page_set_flags(ptr, shm_regions[i].size, 0);
2177
                break;
2178
            }
2179
        }
2180
        ret = get_errno(shmdt((void *)g2h(ptr)));
2181
        break;
2182

    
2183
    case IPCOP_shmget:
2184
        /* IPC_* flag values are the same on all linux platforms */
2185
        ret = get_errno(shmget(first, second, third));
2186
        break;
2187

    
2188
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2189
    case IPCOP_shmctl:
2190
        switch(second) {
2191
        case IPC_RMID:
2192
        case SHM_LOCK:
2193
        case SHM_UNLOCK:
2194
            ret = get_errno(shmctl(first, second, NULL));
2195
            break;
2196
        default:
2197
            goto unimplemented;
2198
        }
2199
        break;
2200
    default:
2201
    unimplemented:
2202
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2203
        ret = -TARGET_ENOSYS;
2204
        break;
2205
    }
2206
    return ret;
2207
}
2208
#endif
2209

    
2210
/* kernel structure types definitions */
2211
#define IFNAMSIZ        16
2212

    
2213
#define STRUCT(name, list...) STRUCT_ ## name,
2214
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2215
enum {
2216
#include "syscall_types.h"
2217
};
2218
#undef STRUCT
2219
#undef STRUCT_SPECIAL
2220

    
2221
#define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2222
#define STRUCT_SPECIAL(name)
2223
#include "syscall_types.h"
2224
#undef STRUCT
2225
#undef STRUCT_SPECIAL
2226

    
2227
typedef struct IOCTLEntry {
2228
    unsigned int target_cmd;
2229
    unsigned int host_cmd;
2230
    const char *name;
2231
    int access;
2232
    const argtype arg_type[5];
2233
} IOCTLEntry;
2234

    
2235
#define IOC_R 0x0001
2236
#define IOC_W 0x0002
2237
#define IOC_RW (IOC_R | IOC_W)
2238

    
2239
#define MAX_STRUCT_SIZE 4096
2240

    
2241
static IOCTLEntry ioctl_entries[] = {
2242
#define IOCTL(cmd, access, types...) \
2243
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2244
#include "ioctls.h"
2245
    { 0, 0, },
2246
};
2247

    
2248
/* ??? Implement proper locking for ioctls.  */
2249
/* do_ioctl() Must return target values and target errnos. */
2250
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2251
{
2252
    const IOCTLEntry *ie;
2253
    const argtype *arg_type;
2254
    abi_long ret;
2255
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2256
    int target_size;
2257
    void *argptr;
2258

    
2259
    ie = ioctl_entries;
2260
    for(;;) {
2261
        if (ie->target_cmd == 0) {
2262
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2263
            return -TARGET_ENOSYS;
2264
        }
2265
        if (ie->target_cmd == cmd)
2266
            break;
2267
        ie++;
2268
    }
2269
    arg_type = ie->arg_type;
2270
#if defined(DEBUG)
2271
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2272
#endif
2273
    switch(arg_type[0]) {
2274
    case TYPE_NULL:
2275
        /* no argument */
2276
        ret = get_errno(ioctl(fd, ie->host_cmd));
2277
        break;
2278
    case TYPE_PTRVOID:
2279
    case TYPE_INT:
2280
        /* int argment */
2281
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2282
        break;
2283
    case TYPE_PTR:
2284
        arg_type++;
2285
        target_size = thunk_type_size(arg_type, 0);
2286
        switch(ie->access) {
2287
        case IOC_R:
2288
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2289
            if (!is_error(ret)) {
2290
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2291
                if (!argptr)
2292
                    return -TARGET_EFAULT;
2293
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2294
                unlock_user(argptr, arg, target_size);
2295
            }
2296
            break;
2297
        case IOC_W:
2298
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2299
            if (!argptr)
2300
                return -TARGET_EFAULT;
2301
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2302
            unlock_user(argptr, arg, 0);
2303
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2304
            break;
2305
        default:
2306
        case IOC_RW:
2307
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2308
            if (!argptr)
2309
                return -TARGET_EFAULT;
2310
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2311
            unlock_user(argptr, arg, 0);
2312
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2313
            if (!is_error(ret)) {
2314
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2315
                if (!argptr)
2316
                    return -TARGET_EFAULT;
2317
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2318
                unlock_user(argptr, arg, target_size);
2319
            }
2320
            break;
2321
        }
2322
        break;
2323
    default:
2324
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2325
                 (long)cmd, arg_type[0]);
2326
        ret = -TARGET_ENOSYS;
2327
        break;
2328
    }
2329
    return ret;
2330
}
2331

    
2332
static const bitmask_transtbl iflag_tbl[] = {
2333
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2334
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2335
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2336
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2337
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2338
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2339
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2340
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2341
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2342
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2343
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2344
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2345
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2346
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2347
        { 0, 0, 0, 0 }
2348
};
2349

    
2350
static const bitmask_transtbl oflag_tbl[] = {
2351
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2352
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2353
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2354
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2355
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2356
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2357
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2358
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2359
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2360
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2361
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2362
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2363
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2364
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2365
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2366
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2367
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2368
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2369
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2370
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2371
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2372
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2373
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2374
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2375
        { 0, 0, 0, 0 }
2376
};
2377

    
2378
static const bitmask_transtbl cflag_tbl[] = {
2379
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2380
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2381
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2382
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2383
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2384
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2385
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2386
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2387
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2388
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2389
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2390
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2391
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2392
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2393
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2394
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2395
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2396
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2397
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2398
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2399
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2400
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2401
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2402
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2403
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2404
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2405
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2406
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2407
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2408
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2409
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2410
        { 0, 0, 0, 0 }
2411
};
2412

    
2413
static const bitmask_transtbl lflag_tbl[] = {
2414
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2415
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2416
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2417
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2418
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2419
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2420
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2421
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2422
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2423
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2424
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2425
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2426
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2427
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2428
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2429
        { 0, 0, 0, 0 }
2430
};
2431

    
2432
static void target_to_host_termios (void *dst, const void *src)
2433
{
2434
    struct host_termios *host = dst;
2435
    const struct target_termios *target = src;
2436

    
2437
    host->c_iflag =
2438
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2439
    host->c_oflag =
2440
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2441
    host->c_cflag =
2442
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2443
    host->c_lflag =
2444
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2445
    host->c_line = target->c_line;
2446

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

    
2466
static void host_to_target_termios (void *dst, const void *src)
2467
{
2468
    struct target_termios *target = dst;
2469
    const struct host_termios *host = src;
2470

    
2471
    target->c_iflag =
2472
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2473
    target->c_oflag =
2474
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2475
    target->c_cflag =
2476
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2477
    target->c_lflag =
2478
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2479
    target->c_line = host->c_line;
2480

    
2481
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2482
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2483
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2484
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2485
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2486
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2487
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2488
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2489
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2490
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2491
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2492
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2493
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2494
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2495
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2496
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2497
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2498
}
2499

    
2500
static const StructEntry struct_termios_def = {
2501
    .convert = { host_to_target_termios, target_to_host_termios },
2502
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2503
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2504
};
2505

    
2506
static bitmask_transtbl mmap_flags_tbl[] = {
2507
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2508
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2509
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2510
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2511
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2512
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2513
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2514
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2515
        { 0, 0, 0, 0 }
2516
};
2517

    
2518
static bitmask_transtbl fcntl_flags_tbl[] = {
2519
        { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
2520
        { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
2521
        { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
2522
        { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
2523
        { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
2524
        { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
2525
        { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
2526
        { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
2527
        { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
2528
        { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
2529
        { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2530
        { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
2531
        { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2532
#if defined(O_DIRECT)
2533
        { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
2534
#endif
2535
        { 0, 0, 0, 0 }
2536
};
2537

    
2538
#if defined(TARGET_I386)
2539

    
2540
/* NOTE: there is really one LDT for all the threads */
2541
static uint8_t *ldt_table;
2542

    
2543
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2544
{
2545
    int size;
2546
    void *p;
2547

    
2548
    if (!ldt_table)
2549
        return 0;
2550
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2551
    if (size > bytecount)
2552
        size = bytecount;
2553
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
2554
    if (!p)
2555
        return -TARGET_EFAULT;
2556
    /* ??? Should this by byteswapped?  */
2557
    memcpy(p, ldt_table, size);
2558
    unlock_user(p, ptr, size);
2559
    return size;
2560
}
2561

    
2562
/* XXX: add locking support */
2563
static abi_long write_ldt(CPUX86State *env,
2564
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
2565
{
2566
    struct target_modify_ldt_ldt_s ldt_info;
2567
    struct target_modify_ldt_ldt_s *target_ldt_info;
2568
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2569
    int seg_not_present, useable, lm;
2570
    uint32_t *lp, entry_1, entry_2;
2571

    
2572
    if (bytecount != sizeof(ldt_info))
2573
        return -TARGET_EINVAL;
2574
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2575
        return -TARGET_EFAULT;
2576
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2577
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2578
    ldt_info.limit = tswap32(target_ldt_info->limit);
2579
    ldt_info.flags = tswap32(target_ldt_info->flags);
2580
    unlock_user_struct(target_ldt_info, ptr, 0);
2581

    
2582
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2583
        return -TARGET_EINVAL;
2584
    seg_32bit = ldt_info.flags & 1;
2585
    contents = (ldt_info.flags >> 1) & 3;
2586
    read_exec_only = (ldt_info.flags >> 3) & 1;
2587
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2588
    seg_not_present = (ldt_info.flags >> 5) & 1;
2589
    useable = (ldt_info.flags >> 6) & 1;
2590
#ifdef TARGET_ABI32
2591
    lm = 0;
2592
#else
2593
    lm = (ldt_info.flags >> 7) & 1;
2594
#endif
2595
    if (contents == 3) {
2596
        if (oldmode)
2597
            return -TARGET_EINVAL;
2598
        if (seg_not_present == 0)
2599
            return -TARGET_EINVAL;
2600
    }
2601
    /* allocate the LDT */
2602
    if (!ldt_table) {
2603
        env->ldt.base = target_mmap(0,
2604
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
2605
                                    PROT_READ|PROT_WRITE,
2606
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2607
        if (env->ldt.base == -1)
2608
            return -TARGET_ENOMEM;
2609
        memset(g2h(env->ldt.base), 0,
2610
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2611
        env->ldt.limit = 0xffff;
2612
        ldt_table = g2h(env->ldt.base);
2613
    }
2614

    
2615
    /* NOTE: same code as Linux kernel */
2616
    /* Allow LDTs to be cleared by the user. */
2617
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2618
        if (oldmode ||
2619
            (contents == 0                &&
2620
             read_exec_only == 1        &&
2621
             seg_32bit == 0                &&
2622
             limit_in_pages == 0        &&
2623
             seg_not_present == 1        &&
2624
             useable == 0 )) {
2625
            entry_1 = 0;
2626
            entry_2 = 0;
2627
            goto install;
2628
        }
2629
    }
2630

    
2631
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2632
        (ldt_info.limit & 0x0ffff);
2633
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2634
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2635
        (ldt_info.limit & 0xf0000) |
2636
        ((read_exec_only ^ 1) << 9) |
2637
        (contents << 10) |
2638
        ((seg_not_present ^ 1) << 15) |
2639
        (seg_32bit << 22) |
2640
        (limit_in_pages << 23) |
2641
        (lm << 21) |
2642
        0x7000;
2643
    if (!oldmode)
2644
        entry_2 |= (useable << 20);
2645

    
2646
    /* Install the new entry ...  */
2647
install:
2648
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2649
    lp[0] = tswap32(entry_1);
2650
    lp[1] = tswap32(entry_2);
2651
    return 0;
2652
}
2653

    
2654
/* specific and weird i386 syscalls */
2655
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2656
                              unsigned long bytecount)
2657
{
2658
    abi_long ret;
2659

    
2660
    switch (func) {
2661
    case 0:
2662
        ret = read_ldt(ptr, bytecount);
2663
        break;
2664
    case 1:
2665
        ret = write_ldt(env, ptr, bytecount, 1);
2666
        break;
2667
    case 0x11:
2668
        ret = write_ldt(env, ptr, bytecount, 0);
2669
        break;
2670
    default:
2671
        ret = -TARGET_ENOSYS;
2672
        break;
2673
    }
2674
    return ret;
2675
}
2676

    
2677
#if defined(TARGET_I386) && defined(TARGET_ABI32)
2678
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2679
{
2680
    uint64_t *gdt_table = g2h(env->gdt.base);
2681
    struct target_modify_ldt_ldt_s ldt_info;
2682
    struct target_modify_ldt_ldt_s *target_ldt_info;
2683
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2684
    int seg_not_present, useable, lm;
2685
    uint32_t *lp, entry_1, entry_2;
2686
    int i;
2687

    
2688
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2689
    if (!target_ldt_info)
2690
        return -TARGET_EFAULT;
2691
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2692
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2693
    ldt_info.limit = tswap32(target_ldt_info->limit);
2694
    ldt_info.flags = tswap32(target_ldt_info->flags);
2695
    if (ldt_info.entry_number == -1) {
2696
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2697
            if (gdt_table[i] == 0) {
2698
                ldt_info.entry_number = i;
2699
                target_ldt_info->entry_number = tswap32(i);
2700
                break;
2701
            }
2702
        }
2703
    }
2704
    unlock_user_struct(target_ldt_info, ptr, 1);
2705

    
2706
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
2707
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2708
           return -TARGET_EINVAL;
2709
    seg_32bit = ldt_info.flags & 1;
2710
    contents = (ldt_info.flags >> 1) & 3;
2711
    read_exec_only = (ldt_info.flags >> 3) & 1;
2712
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2713
    seg_not_present = (ldt_info.flags >> 5) & 1;
2714
    useable = (ldt_info.flags >> 6) & 1;
2715
#ifdef TARGET_ABI32
2716
    lm = 0;
2717
#else
2718
    lm = (ldt_info.flags >> 7) & 1;
2719
#endif
2720

    
2721
    if (contents == 3) {
2722
        if (seg_not_present == 0)
2723
            return -TARGET_EINVAL;
2724
    }
2725

    
2726
    /* NOTE: same code as Linux kernel */
2727
    /* Allow LDTs to be cleared by the user. */
2728
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2729
        if ((contents == 0             &&
2730
             read_exec_only == 1       &&
2731
             seg_32bit == 0            &&
2732
             limit_in_pages == 0       &&
2733
             seg_not_present == 1      &&
2734
             useable == 0 )) {
2735
            entry_1 = 0;
2736
            entry_2 = 0;
2737
            goto install;
2738
        }
2739
    }
2740

    
2741
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2742
        (ldt_info.limit & 0x0ffff);
2743
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2744
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2745
        (ldt_info.limit & 0xf0000) |
2746
        ((read_exec_only ^ 1) << 9) |
2747
        (contents << 10) |
2748
        ((seg_not_present ^ 1) << 15) |
2749
        (seg_32bit << 22) |
2750
        (limit_in_pages << 23) |
2751
        (useable << 20) |
2752
        (lm << 21) |
2753
        0x7000;
2754

    
2755
    /* Install the new entry ...  */
2756
install:
2757
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2758
    lp[0] = tswap32(entry_1);
2759
    lp[1] = tswap32(entry_2);
2760
    return 0;
2761
}
2762

    
2763
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2764
{
2765
    struct target_modify_ldt_ldt_s *target_ldt_info;
2766
    uint64_t *gdt_table = g2h(env->gdt.base);
2767
    uint32_t base_addr, limit, flags;
2768
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2769
    int seg_not_present, useable, lm;
2770
    uint32_t *lp, entry_1, entry_2;
2771

    
2772
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2773
    if (!target_ldt_info)
2774
        return -TARGET_EFAULT;
2775
    idx = tswap32(target_ldt_info->entry_number);
2776
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2777
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
2778
        unlock_user_struct(target_ldt_info, ptr, 1);
2779
        return -TARGET_EINVAL;
2780
    }
2781
    lp = (uint32_t *)(gdt_table + idx);
2782
    entry_1 = tswap32(lp[0]);
2783
    entry_2 = tswap32(lp[1]);
2784
    
2785
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2786
    contents = (entry_2 >> 10) & 3;
2787
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2788
    seg_32bit = (entry_2 >> 22) & 1;
2789
    limit_in_pages = (entry_2 >> 23) & 1;
2790
    useable = (entry_2 >> 20) & 1;
2791
#ifdef TARGET_ABI32
2792
    lm = 0;
2793
#else
2794
    lm = (entry_2 >> 21) & 1;
2795
#endif
2796
    flags = (seg_32bit << 0) | (contents << 1) |
2797
        (read_exec_only << 3) | (limit_in_pages << 4) |
2798
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
2799
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
2800
    base_addr = (entry_1 >> 16) | 
2801
        (entry_2 & 0xff000000) | 
2802
        ((entry_2 & 0xff) << 16);
2803
    target_ldt_info->base_addr = tswapl(base_addr);
2804
    target_ldt_info->limit = tswap32(limit);
2805
    target_ldt_info->flags = tswap32(flags);
2806
    unlock_user_struct(target_ldt_info, ptr, 1);
2807
    return 0;
2808
}
2809
#endif /* TARGET_I386 && TARGET_ABI32 */
2810

    
2811
#ifndef TARGET_ABI32
2812
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2813
{
2814
    abi_long ret;
2815
    abi_ulong val;
2816
    int idx;
2817
    
2818
    switch(code) {
2819
    case TARGET_ARCH_SET_GS:
2820
    case TARGET_ARCH_SET_FS:
2821
        if (code == TARGET_ARCH_SET_GS)
2822
            idx = R_GS;
2823
        else
2824
            idx = R_FS;
2825
        cpu_x86_load_seg(env, idx, 0);
2826
        env->segs[idx].base = addr;
2827
        break;
2828
    case TARGET_ARCH_GET_GS:
2829
    case TARGET_ARCH_GET_FS:
2830
        if (code == TARGET_ARCH_GET_GS)
2831
            idx = R_GS;
2832
        else
2833
            idx = R_FS;
2834
        val = env->segs[idx].base;
2835
        if (put_user(val, addr, abi_ulong))
2836
            return -TARGET_EFAULT;
2837
        break;
2838
    default:
2839
        ret = -TARGET_EINVAL;
2840
        break;
2841
    }
2842
    return 0;
2843
}
2844
#endif
2845

    
2846
#endif /* defined(TARGET_I386) */
2847

    
2848
#if defined(USE_NPTL)
2849

    
2850
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2851

    
2852
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2853
typedef struct {
2854
    CPUState *env;
2855
    pthread_mutex_t mutex;
2856
    pthread_cond_t cond;
2857
    pthread_t thread;
2858
    uint32_t tid;
2859
    abi_ulong child_tidptr;
2860
    abi_ulong parent_tidptr;
2861
    sigset_t sigmask;
2862
} new_thread_info;
2863

    
2864
static void *clone_func(void *arg)
2865
{
2866
    new_thread_info *info = arg;
2867
    CPUState *env;
2868

    
2869
    env = info->env;
2870
    thread_env = env;
2871
    info->tid = gettid();
2872
    if (info->child_tidptr)
2873
        put_user_u32(info->tid, info->child_tidptr);
2874
    if (info->parent_tidptr)
2875
        put_user_u32(info->tid, info->parent_tidptr);
2876
    /* Enable signals.  */
2877
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2878
    /* Signal to the parent that we're ready.  */
2879
    pthread_mutex_lock(&info->mutex);
2880
    pthread_cond_broadcast(&info->cond);
2881
    pthread_mutex_unlock(&info->mutex);
2882
    /* Wait until the parent has finshed initializing the tls state.  */
2883
    pthread_mutex_lock(&clone_lock);
2884
    pthread_mutex_unlock(&clone_lock);
2885
    cpu_loop(env);
2886
    /* never exits */
2887
    return NULL;
2888
}
2889
#else
2890
/* this stack is the equivalent of the kernel stack associated with a
2891
   thread/process */
2892
#define NEW_STACK_SIZE 8192
2893

    
2894
static int clone_func(void *arg)
2895
{
2896
    CPUState *env = arg;
2897
    cpu_loop(env);
2898
    /* never exits */
2899
    return 0;
2900
}
2901
#endif
2902

    
2903
/* do_fork() Must return host values and target errnos (unlike most
2904
   do_*() functions). */
2905
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2906
                   abi_ulong parent_tidptr, target_ulong newtls,
2907
                   abi_ulong child_tidptr)
2908
{
2909
    int ret;
2910
    TaskState *ts;
2911
    uint8_t *new_stack;
2912
    CPUState *new_env;
2913
#if defined(USE_NPTL)
2914
    unsigned int nptl_flags;
2915
    sigset_t sigmask;
2916
#endif
2917

    
2918
    /* Emulate vfork() with fork() */
2919
    if (flags & CLONE_VFORK)
2920
        flags &= ~(CLONE_VFORK | CLONE_VM);
2921

    
2922
    if (flags & CLONE_VM) {
2923
#if defined(USE_NPTL)
2924
        new_thread_info info;
2925
        pthread_attr_t attr;
2926
#endif
2927
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2928
        init_task_state(ts);
2929
        new_stack = ts->stack;
2930
        /* we create a new CPU instance. */
2931
        new_env = cpu_copy(env);
2932
        /* Init regs that differ from the parent.  */
2933
        cpu_clone_regs(new_env, newsp);
2934
        new_env->opaque = ts;
2935
#if defined(USE_NPTL)
2936
        nptl_flags = flags;
2937
        flags &= ~CLONE_NPTL_FLAGS2;
2938

    
2939
        /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2940
        if (nptl_flags & CLONE_SETTLS)
2941
            cpu_set_tls (new_env, newtls);
2942

    
2943
        /* Grab a mutex so that thread setup appears atomic.  */
2944
        pthread_mutex_lock(&clone_lock);
2945

    
2946
        memset(&info, 0, sizeof(info));
2947
        pthread_mutex_init(&info.mutex, NULL);
2948
        pthread_mutex_lock(&info.mutex);
2949
        pthread_cond_init(&info.cond, NULL);
2950
        info.env = new_env;
2951
        if (nptl_flags & CLONE_CHILD_SETTID)
2952
            info.child_tidptr = child_tidptr;
2953
        if (nptl_flags & CLONE_PARENT_SETTID)
2954
            info.parent_tidptr = parent_tidptr;
2955

    
2956
        ret = pthread_attr_init(&attr);
2957
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2958
        /* It is not safe to deliver signals until the child has finished
2959
           initializing, so temporarily block all signals.  */
2960
        sigfillset(&sigmask);
2961
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2962

    
2963
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
2964

    
2965
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
2966
        pthread_attr_destroy(&attr);
2967
        if (ret == 0) {
2968
            /* Wait for the child to initialize.  */
2969
            pthread_cond_wait(&info.cond, &info.mutex);
2970
            ret = info.tid;
2971
            if (flags & CLONE_PARENT_SETTID)
2972
                put_user_u32(ret, parent_tidptr);
2973
        } else {
2974
            ret = -1;
2975
        }
2976
        pthread_mutex_unlock(&info.mutex);
2977
        pthread_cond_destroy(&info.cond);
2978
        pthread_mutex_destroy(&info.mutex);
2979
        pthread_mutex_unlock(&clone_lock);
2980
#else
2981
        if (flags & CLONE_NPTL_FLAGS2)
2982
            return -EINVAL;
2983
        /* This is probably going to die very quickly, but do it anyway.  */
2984
#ifdef __ia64__
2985
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2986
#else
2987
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2988
#endif
2989
#endif
2990
    } else {
2991
        /* if no CLONE_VM, we consider it is a fork */
2992
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
2993
            return -EINVAL;
2994
        fork_start();
2995
        ret = fork();
2996
        if (ret == 0) {
2997
            /* Child Process.  */
2998
            cpu_clone_regs(env, newsp);
2999
            fork_end(1);
3000
#if defined(USE_NPTL)
3001
            /* There is a race condition here.  The parent process could
3002
               theoretically read the TID in the child process before the child
3003
               tid is set.  This would require using either ptrace
3004
               (not implemented) or having *_tidptr to point at a shared memory
3005
               mapping.  We can't repeat the spinlock hack used above because
3006
               the child process gets its own copy of the lock.  */
3007
            if (flags & CLONE_CHILD_SETTID)
3008
                put_user_u32(gettid(), child_tidptr);
3009
            if (flags & CLONE_PARENT_SETTID)
3010
                put_user_u32(gettid(), parent_tidptr);
3011
            ts = (TaskState *)env->opaque;
3012
            if (flags & CLONE_SETTLS)
3013
                cpu_set_tls (env, newtls);
3014
            /* TODO: Implement CLONE_CHILD_CLEARTID.  */
3015
#endif
3016
        } else {
3017
            fork_end(0);
3018
        }
3019
    }
3020
    return ret;
3021
}
3022

    
3023
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3024
{
3025
    struct flock fl;
3026
    struct target_flock *target_fl;
3027
    struct flock64 fl64;
3028
    struct target_flock64 *target_fl64;
3029
    abi_long ret;
3030

    
3031
    switch(cmd) {
3032
    case TARGET_F_GETLK:
3033
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3034
            return -TARGET_EFAULT;
3035
        fl.l_type = tswap16(target_fl->l_type);
3036
        fl.l_whence = tswap16(target_fl->l_whence);
3037
        fl.l_start = tswapl(target_fl->l_start);
3038
        fl.l_len = tswapl(target_fl->l_len);
3039
        fl.l_pid = tswapl(target_fl->l_pid);
3040
        unlock_user_struct(target_fl, arg, 0);
3041
        ret = get_errno(fcntl(fd, cmd, &fl));
3042
        if (ret == 0) {
3043
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3044
                return -TARGET_EFAULT;
3045
            target_fl->l_type = tswap16(fl.l_type);
3046
            target_fl->l_whence = tswap16(fl.l_whence);
3047
            target_fl->l_start = tswapl(fl.l_start);
3048
            target_fl->l_len = tswapl(fl.l_len);
3049
            target_fl->l_pid = tswapl(fl.l_pid);
3050
            unlock_user_struct(target_fl, arg, 1);
3051
        }
3052
        break;
3053

    
3054
    case TARGET_F_SETLK:
3055
    case TARGET_F_SETLKW:
3056
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3057
            return -TARGET_EFAULT;
3058
        fl.l_type = tswap16(target_fl->l_type);
3059
        fl.l_whence = tswap16(target_fl->l_whence);
3060
        fl.l_start = tswapl(target_fl->l_start);
3061
        fl.l_len = tswapl(target_fl->l_len);
3062
        fl.l_pid = tswapl(target_fl->l_pid);
3063
        unlock_user_struct(target_fl, arg, 0);
3064
        ret = get_errno(fcntl(fd, cmd, &fl));
3065
        break;
3066

    
3067
    case TARGET_F_GETLK64:
3068
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3069
            return -TARGET_EFAULT;
3070
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3071
        fl64.l_whence = tswap16(target_fl64->l_whence);
3072
        fl64.l_start = tswapl(target_fl64->l_start);
3073
        fl64.l_len = tswapl(target_fl64->l_len);
3074
        fl64.l_pid = tswap16(target_fl64->l_pid);
3075
        unlock_user_struct(target_fl64, arg, 0);
3076
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3077
        if (ret == 0) {
3078
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3079
                return -TARGET_EFAULT;
3080
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3081
            target_fl64->l_whence = tswap16(fl64.l_whence);
3082
            target_fl64->l_start = tswapl(fl64.l_start);
3083
            target_fl64->l_len = tswapl(fl64.l_len);
3084
            target_fl64->l_pid = tswapl(fl64.l_pid);
3085
            unlock_user_struct(target_fl64, arg, 1);
3086
        }
3087
        break;
3088
    case TARGET_F_SETLK64:
3089
    case TARGET_F_SETLKW64:
3090
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3091
            return -TARGET_EFAULT;
3092
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3093
        fl64.l_whence = tswap16(target_fl64->l_whence);
3094
        fl64.l_start = tswapl(target_fl64->l_start);
3095
        fl64.l_len = tswapl(target_fl64->l_len);
3096
        fl64.l_pid = tswap16(target_fl64->l_pid);
3097
        unlock_user_struct(target_fl64, arg, 0);
3098
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3099
        break;
3100

    
3101
    case F_GETFL:
3102
        ret = get_errno(fcntl(fd, cmd, arg));
3103
        if (ret >= 0) {
3104
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3105
        }
3106
        break;
3107

    
3108
    case F_SETFL:
3109
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3110
        break;
3111

    
3112
    default:
3113
        ret = get_errno(fcntl(fd, cmd, arg));
3114
        break;
3115
    }
3116
    return ret;
3117
}
3118

    
3119
#ifdef USE_UID16
3120

    
3121
static inline int high2lowuid(int uid)
3122
{
3123
    if (uid > 65535)
3124
        return 65534;
3125
    else
3126
        return uid;
3127
}
3128

    
3129
static inline int high2lowgid(int gid)
3130
{
3131
    if (gid > 65535)
3132
        return 65534;
3133
    else
3134
        return gid;
3135
}
3136

    
3137
static inline int low2highuid(int uid)
3138
{
3139
    if ((int16_t)uid == -1)
3140
        return -1;
3141
    else
3142
        return uid;
3143
}
3144

    
3145
static inline int low2highgid(int gid)
3146
{
3147
    if ((int16_t)gid == -1)
3148
        return -1;
3149
    else
3150
        return gid;
3151
}
3152

    
3153
#endif /* USE_UID16 */
3154

    
3155
void syscall_init(void)
3156
{
3157
    IOCTLEntry *ie;
3158
    const argtype *arg_type;
3159
    int size;
3160
    int i;
3161

    
3162
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3163
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3164
#include "syscall_types.h"
3165
#undef STRUCT
3166
#undef STRUCT_SPECIAL
3167

    
3168
    /* we patch the ioctl size if necessary. We rely on the fact that
3169
       no ioctl has all the bits at '1' in the size field */
3170
    ie = ioctl_entries;
3171
    while (ie->target_cmd != 0) {
3172
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3173
            TARGET_IOC_SIZEMASK) {
3174
            arg_type = ie->arg_type;
3175
            if (arg_type[0] != TYPE_PTR) {
3176
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3177
                        ie->target_cmd);
3178
                exit(1);
3179
            }
3180
            arg_type++;
3181
            size = thunk_type_size(arg_type, 0);
3182
            ie->target_cmd = (ie->target_cmd &
3183
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3184
                (size << TARGET_IOC_SIZESHIFT);
3185
        }
3186

    
3187
        /* Build target_to_host_errno_table[] table from
3188
         * host_to_target_errno_table[]. */
3189
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3190
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3191

    
3192
        /* automatic consistency check if same arch */
3193
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3194
    (defined(__x86_64__) && defined(TARGET_X86_64))
3195
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3196
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3197
                    ie->name, ie->target_cmd, ie->host_cmd);
3198
        }
3199
#endif
3200
        ie++;
3201
    }
3202
}
3203

    
3204
#if TARGET_ABI_BITS == 32
3205
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3206
{
3207
#ifdef TARGET_WORDS_BIGENDIAN
3208
    return ((uint64_t)word0 << 32) | word1;
3209
#else
3210
    return ((uint64_t)word1 << 32) | word0;
3211
#endif
3212
}
3213
#else /* TARGET_ABI_BITS == 32 */
3214
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3215
{
3216
    return word0;
3217
}
3218
#endif /* TARGET_ABI_BITS != 32 */
3219

    
3220
#ifdef TARGET_NR_truncate64
3221
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3222
                                         abi_long arg2,
3223
                                         abi_long arg3,
3224
                                         abi_long arg4)
3225
{
3226
#ifdef TARGET_ARM
3227
    if (((CPUARMState *)cpu_env)->eabi)
3228
      {
3229
        arg2 = arg3;
3230
        arg3 = arg4;
3231
      }
3232
#endif
3233
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3234
}
3235
#endif
3236

    
3237
#ifdef TARGET_NR_ftruncate64
3238
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3239
                                          abi_long arg2,
3240
                                          abi_long arg3,
3241
                                          abi_long arg4)
3242
{
3243
#ifdef TARGET_ARM
3244
    if (((CPUARMState *)cpu_env)->eabi)
3245
      {
3246
        arg2 = arg3;
3247
        arg3 = arg4;
3248
      }
3249
#endif
3250
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3251
}
3252
#endif
3253

    
3254
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3255
                                               abi_ulong target_addr)
3256
{
3257
    struct target_timespec *target_ts;
3258

    
3259
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3260
        return -TARGET_EFAULT;
3261
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3262
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3263
    unlock_user_struct(target_ts, target_addr, 0);
3264
    return 0;
3265
}
3266

    
3267
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3268
                                               struct timespec *host_ts)
3269
{
3270
    struct target_timespec *target_ts;
3271

    
3272
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3273
        return -TARGET_EFAULT;
3274
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3275
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3276
    unlock_user_struct(target_ts, target_addr, 1);
3277
    return 0;
3278
}
3279

    
3280
#ifdef TARGET_NR_stat64
3281
static inline abi_long host_to_target_stat64(void *cpu_env,
3282
                                             abi_ulong target_addr,
3283
                                             struct stat *host_st)
3284
{
3285
#ifdef TARGET_ARM
3286
    if (((CPUARMState *)cpu_env)->eabi) {
3287
        struct target_eabi_stat64 *target_st;
3288

    
3289
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3290
            return -TARGET_EFAULT;
3291
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3292
        __put_user(host_st->st_dev, &target_st->st_dev);
3293
        __put_user(host_st->st_ino, &target_st->st_ino);
3294
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3295
        __put_user(host_st->st_ino, &target_st->__st_ino);
3296
#endif
3297
        __put_user(host_st->st_mode, &target_st->st_mode);
3298
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3299
        __put_user(host_st->st_uid, &target_st->st_uid);
3300
        __put_user(host_st->st_gid, &target_st->st_gid);
3301
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3302
        __put_user(host_st->st_size, &target_st->st_size);
3303
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3304
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3305
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3306
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3307
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3308
        unlock_user_struct(target_st, target_addr, 1);
3309
    } else
3310
#endif
3311
    {
3312
        struct target_stat64 *target_st;
3313

    
3314
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3315
            return -TARGET_EFAULT;
3316
        memset(target_st, 0, sizeof(struct target_stat64));
3317
        __put_user(host_st->st_dev, &target_st->st_dev);
3318
        __put_user(host_st->st_ino, &target_st->st_ino);
3319
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3320
        __put_user(host_st->st_ino, &target_st->__st_ino);
3321
#endif
3322
        __put_user(host_st->st_mode, &target_st->st_mode);
3323
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3324
        __put_user(host_st->st_uid, &target_st->st_uid);
3325
        __put_user(host_st->st_gid, &target_st->st_gid);
3326
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3327
        /* XXX: better use of kernel struct */
3328
        __put_user(host_st->st_size, &target_st->st_size);
3329
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3330
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3331
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3332
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3333
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3334
        unlock_user_struct(target_st, target_addr, 1);
3335
    }
3336

    
3337
    return 0;
3338
}
3339
#endif
3340

    
3341
#if defined(USE_NPTL)
3342
/* ??? Using host futex calls even when target atomic operations
3343
   are not really atomic probably breaks things.  However implementing
3344
   futexes locally would make futexes shared between multiple processes
3345
   tricky.  However they're probably useless because guest atomic
3346
   operations won't work either.  */
3347
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3348
                    target_ulong uaddr2, int val3)
3349
{
3350
    struct timespec ts, *pts;
3351

    
3352
    /* ??? We assume FUTEX_* constants are the same on both host
3353
       and target.  */
3354
    switch (op) {
3355
    case FUTEX_WAIT:
3356
        if (timeout) {
3357
            pts = &ts;
3358
            target_to_host_timespec(pts, timeout);
3359
        } else {
3360
            pts = NULL;
3361
        }
3362
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3363
                         pts, NULL, 0));
3364
    case FUTEX_WAKE:
3365
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3366
    case FUTEX_FD:
3367
        return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3368
    case FUTEX_REQUEUE:
3369
        return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3370
                         NULL, g2h(uaddr2), 0));
3371
    case FUTEX_CMP_REQUEUE:
3372
        return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3373
                         NULL, g2h(uaddr2), tswap32(val3)));
3374
    default:
3375
        return -TARGET_ENOSYS;
3376
    }
3377
}
3378
#endif
3379

    
3380
int get_osversion(void)
3381
{
3382
    static int osversion;
3383
    struct new_utsname buf;
3384
    const char *s;
3385
    int i, n, tmp;
3386
    if (osversion)
3387
        return osversion;
3388
    if (qemu_uname_release && *qemu_uname_release) {
3389
        s = qemu_uname_release;
3390
    } else {
3391
        if (sys_uname(&buf))
3392
            return 0;
3393
        s = buf.release;
3394
    }
3395
    tmp = 0;
3396
    for (i = 0; i < 3; i++) {
3397
        n = 0;
3398
        while (*s >= '0' && *s <= '9') {
3399
            n *= 10;
3400
            n += *s - '0';
3401
            s++;
3402
        }
3403
        tmp = (tmp << 8) + n;
3404
        if (*s == '.')
3405
            s++;
3406
    }
3407
    osversion = tmp;
3408
    return osversion;
3409
}
3410

    
3411
/* do_syscall() should always have a single exit point at the end so
3412
   that actions, such as logging of syscall results, can be performed.
3413
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3414
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3415
                    abi_long arg2, abi_long arg3, abi_long arg4,
3416
                    abi_long arg5, abi_long arg6)
3417
{
3418
    abi_long ret;
3419
    struct stat st;
3420
    struct statfs stfs;
3421
    void *p;
3422

    
3423
#ifdef DEBUG
3424
    gemu_log("syscall %d", num);
3425
#endif
3426
    if(do_strace)
3427
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3428

    
3429
    switch(num) {
3430
    case TARGET_NR_exit:
3431
#ifdef HAVE_GPROF
3432
        _mcleanup();
3433
#endif
3434
        gdb_exit(cpu_env, arg1);
3435
        /* XXX: should free thread stack and CPU env */
3436
        sys_exit(arg1);
3437
        ret = 0; /* avoid warning */
3438
        break;
3439
    case TARGET_NR_read:
3440
        if (arg3 == 0)
3441
            ret = 0;
3442
        else {
3443
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3444
                goto efault;
3445
            ret = get_errno(read(arg1, p, arg3));
3446
            unlock_user(p, arg2, ret);
3447
        }
3448
        break;
3449
    case TARGET_NR_write:
3450
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3451
            goto efault;
3452
        ret = get_errno(write(arg1, p, arg3));
3453
        unlock_user(p, arg2, 0);
3454
        break;
3455
    case TARGET_NR_open:
3456
        if (!(p = lock_user_string(arg1)))
3457
            goto efault;
3458
        ret = get_errno(open(path(p),
3459
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
3460
                             arg3));
3461
        unlock_user(p, arg1, 0);
3462
        break;
3463
#if defined(TARGET_NR_openat) && defined(__NR_openat)
3464
    case TARGET_NR_openat:
3465
        if (!(p = lock_user_string(arg2)))
3466
            goto efault;
3467
        ret = get_errno(sys_openat(arg1,
3468
                                   path(p),
3469
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
3470
                                   arg4));
3471
        unlock_user(p, arg2, 0);
3472
        break;
3473
#endif
3474
    case TARGET_NR_close:
3475
        ret = get_errno(close(arg1));
3476
        break;
3477
    case TARGET_NR_brk:
3478
        ret = do_brk(arg1);
3479
        break;
3480
    case TARGET_NR_fork:
3481
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3482
        break;
3483
#ifdef TARGET_NR_waitpid
3484
    case TARGET_NR_waitpid:
3485
        {
3486
            int status;
3487
            ret = get_errno(waitpid(arg1, &status, arg3));
3488
            if (!is_error(ret) && arg2
3489
                && put_user_s32(status, arg2))
3490
                goto efault;
3491
        }
3492
        break;
3493
#endif
3494
#ifdef TARGET_NR_waitid
3495
    case TARGET_NR_waitid:
3496
        {
3497
            siginfo_t info;
3498
            info.si_pid = 0;
3499
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
3500
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
3501
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3502
                    goto efault;
3503
                host_to_target_siginfo(p, &info);
3504
                unlock_user(p, arg3, sizeof(target_siginfo_t));
3505
            }
3506
        }
3507
        break;
3508
#endif
3509
#ifdef TARGET_NR_creat /* not on alpha */
3510
    case TARGET_NR_creat:
3511
        if (!(p = lock_user_string(arg1)))
3512
            goto efault;
3513
        ret = get_errno(creat(p, arg2));
3514
        unlock_user(p, arg1, 0);
3515
        break;
3516
#endif
3517
    case TARGET_NR_link:
3518
        {
3519
            void * p2;
3520
            p = lock_user_string(arg1);
3521
            p2 = lock_user_string(arg2);
3522
            if (!p || !p2)
3523
                ret = -TARGET_EFAULT;
3524
            else
3525
                ret = get_errno(link(p, p2));
3526
            unlock_user(p2, arg2, 0);
3527
            unlock_user(p, arg1, 0);
3528
        }
3529
        break;
3530
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3531
    case TARGET_NR_linkat:
3532
        {
3533
            void * p2 = NULL;
3534
            if (!arg2 || !arg4)
3535
                goto efault;
3536
            p  = lock_user_string(arg2);
3537
            p2 = lock_user_string(arg4);
3538
            if (!p || !p2)
3539
                ret = -TARGET_EFAULT;
3540
            else
3541
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3542
            unlock_user(p, arg2, 0);
3543
            unlock_user(p2, arg4, 0);
3544
        }
3545
        break;
3546
#endif
3547
    case TARGET_NR_unlink:
3548
        if (!(p = lock_user_string(arg1)))
3549
            goto efault;
3550
        ret = get_errno(unlink(p));
3551
        unlock_user(p, arg1, 0);
3552
        break;
3553
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3554
    case TARGET_NR_unlinkat:
3555
        if (!(p = lock_user_string(arg2)))
3556
            goto efault;
3557
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
3558
        unlock_user(p, arg2, 0);
3559
        break;
3560
#endif
3561
    case TARGET_NR_execve:
3562
        {
3563
            char **argp, **envp;
3564
            int argc, envc;
3565
            abi_ulong gp;
3566
            abi_ulong guest_argp;
3567
            abi_ulong guest_envp;
3568
            abi_ulong addr;
3569
            char **q;
3570

    
3571
            argc = 0;
3572
            guest_argp = arg2;
3573
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3574
                if (get_user_ual(addr, gp))
3575
                    goto efault;
3576
                if (!addr)
3577
                    break;
3578
                argc++;
3579
            }
3580
            envc = 0;
3581
            guest_envp = arg3;
3582
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3583
                if (get_user_ual(addr, gp))
3584
                    goto efault;
3585
                if (!addr)
3586
                    break;
3587
                envc++;
3588
            }
3589

    
3590
            argp = alloca((argc + 1) * sizeof(void *));
3591
            envp = alloca((envc + 1) * sizeof(void *));
3592

    
3593
            for (gp = guest_argp, q = argp; gp;
3594
                  gp += sizeof(abi_ulong), q++) {
3595
                if (get_user_ual(addr, gp))
3596
                    goto execve_efault;
3597
                if (!addr)
3598
                    break;
3599
                if (!(*q = lock_user_string(addr)))
3600
                    goto execve_efault;
3601
            }
3602
            *q = NULL;
3603

    
3604
            for (gp = guest_envp, q = envp; gp;
3605
                  gp += sizeof(abi_ulong), q++) {
3606
                if (get_user_ual(addr, gp))
3607
                    goto execve_efault;
3608
                if (!addr)
3609
                    break;
3610
                if (!(*q = lock_user_string(addr)))
3611
                    goto execve_efault;
3612
            }
3613
            *q = NULL;
3614

    
3615
            if (!(p = lock_user_string(arg1)))
3616
                goto execve_efault;
3617
            ret = get_errno(execve(p, argp, envp));
3618
            unlock_user(p, arg1, 0);
3619

    
3620
            goto execve_end;
3621

    
3622
        execve_efault:
3623
            ret = -TARGET_EFAULT;
3624

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

    
4046
            if (arg2) {
4047
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4048
                    goto efault;
4049
                act._sa_handler = old_act->_sa_handler;
4050
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4051
                act.sa_flags = old_act->sa_flags;
4052
                unlock_user_struct(old_act, arg2, 0);
4053
                pact = &act;
4054
            } else {
4055
                pact = NULL;
4056
            }
4057

    
4058
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4059

    
4060
            if (!is_error(ret) && arg3) {
4061
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4062
                    goto efault;
4063
                old_act->_sa_handler = oact._sa_handler;
4064
                old_act->sa_flags = oact.sa_flags;
4065
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4066
                old_act->sa_mask.sig[1] = 0;
4067
                old_act->sa_mask.sig[2] = 0;
4068
                old_act->sa_mask.sig[3] = 0;
4069
                unlock_user_struct(old_act, arg3, 1);
4070
            }
4071
#endif
4072
        }
4073
        break;
4074
#endif
4075
    case TARGET_NR_rt_sigaction:
4076
        {
4077
            struct target_sigaction *act;
4078
            struct target_sigaction *oact;
4079

    
4080
            if (arg2) {
4081
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4082
                    goto efault;
4083
            } else
4084
                act = NULL;
4085
            if (arg3) {
4086
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4087
                    ret = -TARGET_EFAULT;
4088
                    goto rt_sigaction_fail;
4089
                }
4090
            } else
4091
                oact = NULL;
4092
            ret = get_errno(do_sigaction(arg1, act, oact));
4093
        rt_sigaction_fail:
4094
            if (act)
4095
                unlock_user_struct(act, arg2, 0);
4096
            if (oact)
4097
                unlock_user_struct(oact, arg3, 1);
4098
        }
4099
        break;
4100
#ifdef TARGET_NR_sgetmask /* not on alpha */
4101
    case TARGET_NR_sgetmask:
4102
        {
4103
            sigset_t cur_set;
4104
            abi_ulong target_set;
4105
            sigprocmask(0, NULL, &cur_set);
4106
            host_to_target_old_sigset(&target_set, &cur_set);
4107
            ret = target_set;
4108
        }
4109
        break;
4110
#endif
4111
#ifdef TARGET_NR_ssetmask /* not on alpha */
4112
    case TARGET_NR_ssetmask:
4113
        {
4114
            sigset_t set, oset, cur_set;
4115
            abi_ulong target_set = arg1;
4116
            sigprocmask(0, NULL, &cur_set);
4117
            target_to_host_old_sigset(&set, &target_set);
4118
            sigorset(&set, &set, &cur_set);
4119
            sigprocmask(SIG_SETMASK, &set, &oset);
4120
            host_to_target_old_sigset(&target_set, &oset);
4121
            ret = target_set;
4122
        }
4123
        break;
4124
#endif
4125
#ifdef TARGET_NR_sigprocmask
4126
    case TARGET_NR_sigprocmask:
4127
        {
4128
            int how = arg1;
4129
            sigset_t set, oldset, *set_ptr;
4130

    
4131
            if (arg2) {
4132
                switch(how) {
4133
                case TARGET_SIG_BLOCK:
4134
                    how = SIG_BLOCK;
4135
                    break;
4136
                case TARGET_SIG_UNBLOCK:
4137
                    how = SIG_UNBLOCK;
4138
                    break;
4139
                case TARGET_SIG_SETMASK:
4140
                    how = SIG_SETMASK;
4141
                    break;
4142
                default:
4143
                    ret = -TARGET_EINVAL;
4144
                    goto fail;
4145
                }
4146
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4147
                    goto efault;
4148
                target_to_host_old_sigset(&set, p);
4149
                unlock_user(p, arg2, 0);
4150
                set_ptr = &set;
4151
            } else {
4152
                how = 0;
4153
                set_ptr = NULL;
4154
            }
4155
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4156
            if (!is_error(ret) && arg3) {
4157
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4158
                    goto efault;
4159
                host_to_target_old_sigset(p, &oldset);
4160
                unlock_user(p, arg3, sizeof(target_sigset_t));
4161
            }
4162
        }
4163
        break;
4164
#endif
4165
    case TARGET_NR_rt_sigprocmask:
4166
        {
4167
            int how = arg1;
4168
            sigset_t set, oldset, *set_ptr;
4169

    
4170
            if (arg2) {
4171
                switch(how) {
4172
                case TARGET_SIG_BLOCK:
4173
                    how = SIG_BLOCK;
4174
                    break;
4175
                case TARGET_SIG_UNBLOCK:
4176
                    how = SIG_UNBLOCK;
4177
                    break;
4178
                case TARGET_SIG_SETMASK:
4179
                    how = SIG_SETMASK;
4180
                    break;
4181
                default:
4182
                    ret = -TARGET_EINVAL;
4183
                    goto fail;
4184
                }
4185
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4186
                    goto efault;
4187
                target_to_host_sigset(&set, p);
4188
                unlock_user(p, arg2, 0);
4189
                set_ptr = &set;
4190
            } else {
4191
                how = 0;
4192
                set_ptr = NULL;
4193
            }
4194
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4195
            if (!is_error(ret) && arg3) {
4196
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4197
                    goto efault;
4198
                host_to_target_sigset(p, &oldset);
4199
                unlock_user(p, arg3, sizeof(target_sigset_t));
4200
            }
4201
        }
4202
        break;
4203
#ifdef TARGET_NR_sigpending
4204
    case TARGET_NR_sigpending:
4205
        {
4206
            sigset_t set;
4207
            ret = get_errno(sigpending(&set));
4208
            if (!is_error(ret)) {
4209
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4210
                    goto efault;
4211
                host_to_target_old_sigset(p, &set);
4212
                unlock_user(p, arg1, sizeof(target_sigset_t));
4213
            }
4214
        }
4215
        break;
4216
#endif
4217
    case TARGET_NR_rt_sigpending:
4218
        {
4219
            sigset_t set;
4220
            ret = get_errno(sigpending(&set));
4221
            if (!is_error(ret)) {
4222
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4223
                    goto efault;
4224
                host_to_target_sigset(p, &set);
4225
                unlock_user(p, arg1, sizeof(target_sigset_t));
4226
            }
4227
        }
4228
        break;
4229
#ifdef TARGET_NR_sigsuspend
4230
    case TARGET_NR_sigsuspend:
4231
        {
4232
            sigset_t set;
4233
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4234
                goto efault;
4235
            target_to_host_old_sigset(&set, p);
4236
            unlock_user(p, arg1, 0);
4237
            ret = get_errno(sigsuspend(&set));
4238
        }
4239
        break;
4240
#endif
4241
    case TARGET_NR_rt_sigsuspend:
4242
        {
4243
            sigset_t set;
4244
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4245
                goto efault;
4246
            target_to_host_sigset(&set, p);
4247
            unlock_user(p, arg1, 0);
4248
            ret = get_errno(sigsuspend(&set));
4249
        }
4250
        break;
4251
    case TARGET_NR_rt_sigtimedwait:
4252
        {
4253
            sigset_t set;
4254
            struct timespec uts, *puts;
4255
            siginfo_t uinfo;
4256

    
4257
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4258
                goto efault;
4259
            target_to_host_sigset(&set, p);
4260
            unlock_user(p, arg1, 0);
4261
            if (arg3) {
4262
                puts = &uts;
4263
                target_to_host_timespec(puts, arg3);
4264
            } else {
4265
                puts = NULL;
4266
            }
4267
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4268
            if (!is_error(ret) && arg2) {
4269
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4270
                    goto efault;
4271
                host_to_target_siginfo(p, &uinfo);
4272
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4273
            }
4274
        }
4275
        break;
4276
    case TARGET_NR_rt_sigqueueinfo:
4277
        {
4278
            siginfo_t uinfo;
4279
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4280
                goto efault;
4281
            target_to_host_siginfo(&uinfo, p);
4282
            unlock_user(p, arg1, 0);
4283
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4284
        }
4285
        break;
4286
#ifdef TARGET_NR_sigreturn
4287
    case TARGET_NR_sigreturn:
4288
        /* NOTE: ret is eax, so not transcoding must be done */
4289
        ret = do_sigreturn(cpu_env);
4290
        break;
4291
#endif
4292
    case TARGET_NR_rt_sigreturn:
4293
        /* NOTE: ret is eax, so not transcoding must be done */
4294
        ret = do_rt_sigreturn(cpu_env);
4295
        break;
4296
    case TARGET_NR_sethostname:
4297
        if (!(p = lock_user_string(arg1)))
4298
            goto efault;
4299
        ret = get_errno(sethostname(p, arg2));
4300
        unlock_user(p, arg1, 0);
4301
        break;
4302
    case TARGET_NR_setrlimit:
4303
        {
4304
            /* XXX: convert resource ? */
4305
            int resource = arg1;
4306
            struct target_rlimit *target_rlim;
4307
            struct rlimit rlim;
4308
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4309
                goto efault;
4310
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4311
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4312
            unlock_user_struct(target_rlim, arg2, 0);
4313
            ret = get_errno(setrlimit(resource, &rlim));
4314
        }
4315
        break;
4316
    case TARGET_NR_getrlimit:
4317
        {
4318
            /* XXX: convert resource ? */
4319
            int resource = arg1;
4320
            struct target_rlimit *target_rlim;
4321
            struct rlimit rlim;
4322

    
4323
            ret = get_errno(getrlimit(resource, &rlim));
4324
            if (!is_error(ret)) {
4325
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4326
                    goto efault;
4327
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4328
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4329
                unlock_user_struct(target_rlim, arg2, 1);
4330
            }
4331
        }
4332
        break;
4333
    case TARGET_NR_getrusage:
4334
        {
4335
            struct rusage rusage;
4336
            ret = get_errno(getrusage(arg1, &rusage));
4337
            if (!is_error(ret)) {
4338
                host_to_target_rusage(arg2, &rusage);
4339
            }
4340
        }
4341
        break;
4342
    case TARGET_NR_gettimeofday:
4343
        {
4344
            struct timeval tv;
4345
            ret = get_errno(gettimeofday(&tv, NULL));
4346
            if (!is_error(ret)) {
4347
                if (copy_to_user_timeval(arg1, &tv))
4348
                    goto efault;
4349
            }
4350
        }
4351
        break;
4352
    case TARGET_NR_settimeofday:
4353
        {
4354
            struct timeval tv;
4355
            if (copy_from_user_timeval(&tv, arg1))
4356
                goto efault;
4357
            ret = get_errno(settimeofday(&tv, NULL));
4358
        }
4359
        break;
4360
#ifdef TARGET_NR_select
4361
    case TARGET_NR_select:
4362
        {
4363
            struct target_sel_arg_struct *sel;
4364
            abi_ulong inp, outp, exp, tvp;
4365
            long nsel;
4366

    
4367
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4368
                goto efault;
4369
            nsel = tswapl(sel->n);
4370
            inp = tswapl(sel->inp);
4371
            outp = tswapl(sel->outp);
4372
            exp = tswapl(sel->exp);
4373
            tvp = tswapl(sel->tvp);
4374
            unlock_user_struct(sel, arg1, 0);
4375
            ret = do_select(nsel, inp, outp, exp, tvp);
4376
        }
4377
        break;
4378
#endif
4379
    case TARGET_NR_symlink:
4380
        {
4381
            void *p2;
4382
            p = lock_user_string(arg1);
4383
            p2 = lock_user_string(arg2);
4384
            if (!p || !p2)
4385
                ret = -TARGET_EFAULT;
4386
            else
4387
                ret = get_errno(symlink(p, p2));
4388
            unlock_user(p2, arg2, 0);
4389
            unlock_user(p, arg1, 0);
4390
        }
4391
        break;
4392
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4393
    case TARGET_NR_symlinkat:
4394
        {
4395
            void *p2;
4396
            p  = lock_user_string(arg1);
4397
            p2 = lock_user_string(arg3);
4398
            if (!p || !p2)
4399
                ret = -TARGET_EFAULT;
4400
            else
4401
                ret = get_errno(sys_symlinkat(p, arg2, p2));
4402
            unlock_user(p2, arg3, 0);
4403
            unlock_user(p, arg1, 0);
4404
        }
4405
        break;
4406
#endif
4407
#ifdef TARGET_NR_oldlstat
4408
    case TARGET_NR_oldlstat:
4409
        goto unimplemented;
4410
#endif
4411
    case TARGET_NR_readlink:
4412
        {
4413
            void *p2, *temp;
4414
            p = lock_user_string(arg1);
4415
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4416
            if (!p || !p2)
4417
                ret = -TARGET_EFAULT;
4418
            else {
4419
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
4420
                    char real[PATH_MAX];
4421
                    temp = realpath(exec_path,real);
4422
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
4423
                    snprintf((char *)p2, arg3, "%s", real);
4424
                    }
4425
                else
4426
                    ret = get_errno(readlink(path(p), p2, arg3));
4427
            }
4428
            unlock_user(p2, arg2, ret);
4429
            unlock_user(p, arg1, 0);
4430
        }
4431
        break;
4432
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4433
    case TARGET_NR_readlinkat:
4434
        {
4435
            void *p2;
4436
            p  = lock_user_string(arg2);
4437
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4438
            if (!p || !p2)
4439
                ret = -TARGET_EFAULT;
4440
            else
4441
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4442
            unlock_user(p2, arg3, ret);
4443
            unlock_user(p, arg2, 0);
4444
        }
4445
        break;
4446
#endif
4447
#ifdef TARGET_NR_uselib
4448
    case TARGET_NR_uselib:
4449
        goto unimplemented;
4450
#endif
4451
#ifdef TARGET_NR_swapon
4452
    case TARGET_NR_swapon:
4453
        if (!(p = lock_user_string(arg1)))
4454
            goto efault;
4455
        ret = get_errno(swapon(p, arg2));
4456
        unlock_user(p, arg1, 0);
4457
        break;
4458
#endif
4459
    case TARGET_NR_reboot:
4460
        goto unimplemented;
4461
#ifdef TARGET_NR_readdir
4462
    case TARGET_NR_readdir:
4463
        goto unimplemented;
4464
#endif
4465
#ifdef TARGET_NR_mmap
4466
    case TARGET_NR_mmap:
4467
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4468
        {
4469
            abi_ulong *v;
4470
            abi_ulong v1, v2, v3, v4, v5, v6;
4471
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4472
                goto efault;
4473
            v1 = tswapl(v[0]);
4474
            v2 = tswapl(v[1]);
4475
            v3 = tswapl(v[2]);
4476
            v4 = tswapl(v[3]);
4477
            v5 = tswapl(v[4]);
4478
            v6 = tswapl(v[5]);
4479
            unlock_user(v, arg1, 0);
4480
            ret = get_errno(target_mmap(v1, v2, v3,
4481
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
4482
                                        v5, v6));
4483
        }
4484
#else
4485
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4486
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4487
                                    arg5,
4488
                                    arg6));
4489
#endif
4490
        break;
4491
#endif
4492
#ifdef TARGET_NR_mmap2
4493
    case TARGET_NR_mmap2:
4494
#ifndef MMAP_SHIFT
4495
#define MMAP_SHIFT 12
4496
#endif
4497
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4498
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4499
                                    arg5,
4500
                                    arg6 << MMAP_SHIFT));
4501
        break;
4502
#endif
4503
    case TARGET_NR_munmap:
4504
        ret = get_errno(target_munmap(arg1, arg2));
4505
        break;
4506
    case TARGET_NR_mprotect:
4507
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
4508
        break;
4509
#ifdef TARGET_NR_mremap
4510
    case TARGET_NR_mremap:
4511
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4512
        break;
4513
#endif
4514
        /* ??? msync/mlock/munlock are broken for softmmu.  */
4515
#ifdef TARGET_NR_msync
4516
    case TARGET_NR_msync:
4517
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
4518
        break;
4519
#endif
4520
#ifdef TARGET_NR_mlock
4521
    case TARGET_NR_mlock:
4522
        ret = get_errno(mlock(g2h(arg1), arg2));
4523
        break;
4524
#endif
4525
#ifdef TARGET_NR_munlock
4526
    case TARGET_NR_munlock:
4527
        ret = get_errno(munlock(g2h(arg1), arg2));
4528
        break;
4529
#endif
4530
#ifdef TARGET_NR_mlockall
4531
    case TARGET_NR_mlockall:
4532
        ret = get_errno(mlockall(arg1));
4533
        break;
4534
#endif
4535
#ifdef TARGET_NR_munlockall
4536
    case TARGET_NR_munlockall:
4537
        ret = get_errno(munlockall());
4538
        break;
4539
#endif
4540
    case TARGET_NR_truncate:
4541
        if (!(p = lock_user_string(arg1)))
4542
            goto efault;
4543
        ret = get_errno(truncate(p, arg2));
4544
        unlock_user(p, arg1, 0);
4545
        break;
4546
    case TARGET_NR_ftruncate:
4547
        ret = get_errno(ftruncate(arg1, arg2));
4548
        break;
4549
    case TARGET_NR_fchmod:
4550
        ret = get_errno(fchmod(arg1, arg2));
4551
        break;
4552
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4553
    case TARGET_NR_fchmodat:
4554
        if (!(p = lock_user_string(arg2)))
4555
            goto efault;
4556
        ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4557
        unlock_user(p, arg2, 0);
4558
        break;
4559
#endif
4560
    case TARGET_NR_getpriority:
4561
        /* libc does special remapping of the return value of
4562
         * sys_getpriority() so it's just easiest to call
4563
         * sys_getpriority() directly rather than through libc. */
4564
        ret = sys_getpriority(arg1, arg2);
4565
        break;
4566
    case TARGET_NR_setpriority:
4567
        ret = get_errno(setpriority(arg1, arg2, arg3));
4568
        break;
4569
#ifdef TARGET_NR_profil
4570
    case TARGET_NR_profil:
4571
        goto unimplemented;
4572
#endif
4573
    case TARGET_NR_statfs:
4574
        if (!(p = lock_user_string(arg1)))
4575
            goto efault;
4576
        ret = get_errno(statfs(path(p), &stfs));
4577
        unlock_user(p, arg1, 0);
4578
    convert_statfs:
4579
        if (!is_error(ret)) {
4580
            struct target_statfs *target_stfs;
4581

    
4582
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4583
                goto efault;
4584
            __put_user(stfs.f_type, &target_stfs->f_type);
4585
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4586
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4587
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4588
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4589
            __put_user(stfs.f_files, &target_stfs->f_files);
4590
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4591
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4592
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4593
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4594
            unlock_user_struct(target_stfs, arg2, 1);
4595
        }
4596
        break;
4597
    case TARGET_NR_fstatfs:
4598
        ret = get_errno(fstatfs(arg1, &stfs));
4599
        goto convert_statfs;
4600
#ifdef TARGET_NR_statfs64
4601
    case TARGET_NR_statfs64:
4602
        if (!(p = lock_user_string(arg1)))
4603
            goto efault;
4604
        ret = get_errno(statfs(path(p), &stfs));
4605
        unlock_user(p, arg1, 0);
4606
    convert_statfs64:
4607
        if (!is_error(ret)) {
4608
            struct target_statfs64 *target_stfs;
4609

    
4610
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4611
                goto efault;
4612
            __put_user(stfs.f_type, &target_stfs->f_type);
4613
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4614
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4615
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4616
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4617
            __put_user(stfs.f_files, &target_stfs->f_files);
4618
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4619
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4620
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4621
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4622
            unlock_user_struct(target_stfs, arg3, 1);
4623
        }
4624
        break;
4625
    case TARGET_NR_fstatfs64:
4626
        ret = get_errno(fstatfs(arg1, &stfs));
4627
        goto convert_statfs64;
4628
#endif
4629
#ifdef TARGET_NR_ioperm
4630
    case TARGET_NR_ioperm:
4631
        goto unimplemented;
4632
#endif
4633
#ifdef TARGET_NR_socketcall
4634
    case TARGET_NR_socketcall:
4635
        ret = do_socketcall(arg1, arg2);
4636
        break;
4637
#endif
4638
#ifdef TARGET_NR_accept
4639
    case TARGET_NR_accept:
4640
        ret = do_accept(arg1, arg2, arg3);
4641
        break;
4642
#endif
4643
#ifdef TARGET_NR_bind
4644
    case TARGET_NR_bind:
4645
        ret = do_bind(arg1, arg2, arg3);
4646
        break;
4647
#endif
4648
#ifdef TARGET_NR_connect
4649
    case TARGET_NR_connect:
4650
        ret = do_connect(arg1, arg2, arg3);
4651
        break;
4652
#endif
4653
#ifdef TARGET_NR_getpeername
4654
    case TARGET_NR_getpeername:
4655
        ret = do_getpeername(arg1, arg2, arg3);
4656
        break;
4657
#endif
4658
#ifdef TARGET_NR_getsockname
4659
    case TARGET_NR_getsockname:
4660
        ret = do_getsockname(arg1, arg2, arg3);
4661
        break;
4662
#endif
4663
#ifdef TARGET_NR_getsockopt
4664
    case TARGET_NR_getsockopt:
4665
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4666
        break;
4667
#endif
4668
#ifdef TARGET_NR_listen
4669
    case TARGET_NR_listen:
4670
        ret = get_errno(listen(arg1, arg2));
4671
        break;
4672
#endif
4673
#ifdef TARGET_NR_recv
4674
    case TARGET_NR_recv:
4675
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4676
        break;
4677
#endif
4678
#ifdef TARGET_NR_recvfrom
4679
    case TARGET_NR_recvfrom:
4680
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4681
        break;
4682
#endif
4683
#ifdef TARGET_NR_recvmsg
4684
    case TARGET_NR_recvmsg:
4685
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4686
        break;
4687
#endif
4688
#ifdef TARGET_NR_send
4689
    case TARGET_NR_send:
4690
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4691
        break;
4692
#endif
4693
#ifdef TARGET_NR_sendmsg
4694
    case TARGET_NR_sendmsg:
4695
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4696
        break;
4697
#endif
4698
#ifdef TARGET_NR_sendto
4699
    case TARGET_NR_sendto:
4700
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4701
        break;
4702
#endif
4703
#ifdef TARGET_NR_shutdown
4704
    case TARGET_NR_shutdown:
4705
        ret = get_errno(shutdown(arg1, arg2));
4706
        break;
4707
#endif
4708
#ifdef TARGET_NR_socket
4709
    case TARGET_NR_socket:
4710
        ret = do_socket(arg1, arg2, arg3);
4711
        break;
4712
#endif
4713
#ifdef TARGET_NR_socketpair
4714
    case TARGET_NR_socketpair:
4715
        ret = do_socketpair(arg1, arg2, arg3, arg4);
4716
        break;
4717
#endif
4718
#ifdef TARGET_NR_setsockopt
4719
    case TARGET_NR_setsockopt:
4720
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4721
        break;
4722
#endif
4723

    
4724
    case TARGET_NR_syslog:
4725
        if (!(p = lock_user_string(arg2)))
4726
            goto efault;
4727
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4728
        unlock_user(p, arg2, 0);
4729
        break;
4730

    
4731
    case TARGET_NR_setitimer:
4732
        {
4733
            struct itimerval value, ovalue, *pvalue;
4734

    
4735
            if (arg2) {
4736
                pvalue = &value;
4737
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4738
                    || copy_from_user_timeval(&pvalue->it_value,
4739
                                              arg2 + sizeof(struct target_timeval)))
4740
                    goto efault;
4741
            } else {
4742
                pvalue = NULL;
4743
            }
4744
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4745
            if (!is_error(ret) && arg3) {
4746
                if (copy_to_user_timeval(arg3,
4747
                                         &ovalue.it_interval)
4748
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4749
                                            &ovalue.it_value))
4750
                    goto efault;
4751
            }
4752
        }
4753
        break;
4754
    case TARGET_NR_getitimer:
4755
        {
4756
            struct itimerval value;
4757

    
4758
            ret = get_errno(getitimer(arg1, &value));
4759
            if (!is_error(ret) && arg2) {
4760
                if (copy_to_user_timeval(arg2,
4761
                                         &value.it_interval)
4762
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4763
                                            &value.it_value))
4764
                    goto efault;
4765
            }
4766
        }
4767
        break;
4768
    case TARGET_NR_stat:
4769
        if (!(p = lock_user_string(arg1)))
4770
            goto efault;
4771
        ret = get_errno(stat(path(p), &st));
4772
        unlock_user(p, arg1, 0);
4773
        goto do_stat;
4774
    case TARGET_NR_lstat:
4775
        if (!(p = lock_user_string(arg1)))
4776
            goto efault;
4777
        ret = get_errno(lstat(path(p), &st));
4778
        unlock_user(p, arg1, 0);
4779
        goto do_stat;
4780
    case TARGET_NR_fstat:
4781
        {
4782
            ret = get_errno(fstat(arg1, &st));
4783
        do_stat:
4784
            if (!is_error(ret)) {
4785
                struct target_stat *target_st;
4786

    
4787
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4788
                    goto efault;
4789
                __put_user(st.st_dev, &target_st->st_dev);
4790
                __put_user(st.st_ino, &target_st->st_ino);
4791
                __put_user(st.st_mode, &target_st->st_mode);
4792
                __put_user(st.st_uid, &target_st->st_uid);
4793
                __put_user(st.st_gid, &target_st->st_gid);
4794
                __put_user(st.st_nlink, &target_st->st_nlink);
4795
                __put_user(st.st_rdev, &target_st->st_rdev);
4796
                __put_user(st.st_size, &target_st->st_size);
4797
                __put_user(st.st_blksize, &target_st->st_blksize);
4798
                __put_user(st.st_blocks, &target_st->st_blocks);
4799
                __put_user(st.st_atime, &target_st->target_st_atime);
4800
                __put_user(st.st_mtime, &target_st->target_st_mtime);
4801
                __put_user(st.st_ctime, &target_st->target_st_ctime);
4802
                unlock_user_struct(target_st, arg2, 1);
4803
            }
4804
        }
4805
        break;
4806
#ifdef TARGET_NR_olduname
4807
    case TARGET_NR_olduname:
4808
        goto unimplemented;
4809
#endif
4810
#ifdef TARGET_NR_iopl
4811
    case TARGET_NR_iopl:
4812
        goto unimplemented;
4813
#endif
4814
    case TARGET_NR_vhangup:
4815
        ret = get_errno(vhangup());
4816
        break;
4817
#ifdef TARGET_NR_idle
4818
    case TARGET_NR_idle:
4819
        goto unimplemented;
4820
#endif
4821
#ifdef TARGET_NR_syscall
4822
    case TARGET_NR_syscall:
4823
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4824
            break;
4825
#endif
4826
    case TARGET_NR_wait4:
4827
        {
4828
            int status;
4829
            abi_long status_ptr = arg2;
4830
            struct rusage rusage, *rusage_ptr;
4831
            abi_ulong target_rusage = arg4;
4832
            if (target_rusage)
4833
                rusage_ptr = &rusage;
4834
            else
4835
                rusage_ptr = NULL;
4836
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4837
            if (!is_error(ret)) {
4838
                if (status_ptr) {
4839
                    if (put_user_s32(status, status_ptr))
4840
                        goto efault;
4841
                }
4842
                if (target_rusage)
4843
                    host_to_target_rusage(target_rusage, &rusage);
4844
            }
4845
        }
4846
        break;
4847
#ifdef TARGET_NR_swapoff
4848
    case TARGET_NR_swapoff:
4849
        if (!(p = lock_user_string(arg1)))
4850
            goto efault;
4851
        ret = get_errno(swapoff(p));
4852
        unlock_user(p, arg1, 0);
4853
        break;
4854
#endif
4855
    case TARGET_NR_sysinfo:
4856
        {
4857
            struct target_sysinfo *target_value;
4858
            struct sysinfo value;
4859
            ret = get_errno(sysinfo(&value));
4860
            if (!is_error(ret) && arg1)
4861
            {
4862
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4863
                    goto efault;
4864
                __put_user(value.uptime, &target_value->uptime);
4865
                __put_user(value.loads[0], &target_value->loads[0]);
4866
                __put_user(value.loads[1], &target_value->loads[1]);
4867
                __put_user(value.loads[2], &target_value->loads[2]);
4868
                __put_user(value.totalram, &target_value->totalram);
4869
                __put_user(value.freeram, &target_value->freeram);
4870
                __put_user(value.sharedram, &target_value->sharedram);
4871
                __put_user(value.bufferram, &target_value->bufferram);
4872
                __put_user(value.totalswap, &target_value->totalswap);
4873
                __put_user(value.freeswap, &target_value->freeswap);
4874
                __put_user(value.procs, &target_value->procs);
4875
                __put_user(value.totalhigh, &target_value->totalhigh);
4876
                __put_user(value.freehigh, &target_value->freehigh);
4877
                __put_user(value.mem_unit, &target_value->mem_unit);
4878
                unlock_user_struct(target_value, arg1, 1);
4879
            }
4880
        }
4881
        break;
4882
#ifdef TARGET_NR_ipc
4883
    case TARGET_NR_ipc:
4884
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4885
        break;
4886
#endif
4887

    
4888
#ifdef TARGET_NR_msgctl
4889
    case TARGET_NR_msgctl:
4890
        ret = do_msgctl(arg1, arg2, arg3);
4891
        break;
4892
#endif
4893
#ifdef TARGET_NR_msgget
4894
    case TARGET_NR_msgget:
4895
        ret = get_errno(msgget(arg1, arg2));
4896
        break;
4897
#endif
4898
#ifdef TARGET_NR_msgrcv
4899
    case TARGET_NR_msgrcv:
4900
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
4901
        break;
4902
#endif
4903
#ifdef TARGET_NR_msgsnd
4904
    case TARGET_NR_msgsnd:
4905
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
4906
        break;
4907
#endif
4908
    case TARGET_NR_fsync:
4909
        ret = get_errno(fsync(arg1));
4910
        break;
4911
    case TARGET_NR_clone:
4912
#if defined(TARGET_SH4)
4913
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
4914
#elif defined(TARGET_CRIS)
4915
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
4916
#else
4917
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4918
#endif
4919
        break;
4920
#ifdef __NR_exit_group
4921
        /* new thread calls */
4922
    case TARGET_NR_exit_group:
4923
#ifdef HAVE_GPROF
4924
        _mcleanup();
4925
#endif
4926
        gdb_exit(cpu_env, arg1);
4927
        ret = get_errno(exit_group(arg1));
4928
        break;
4929
#endif
4930
    case TARGET_NR_setdomainname:
4931
        if (!(p = lock_user_string(arg1)))
4932
            goto efault;
4933
        ret = get_errno(setdomainname(p, arg2));
4934
        unlock_user(p, arg1, 0);
4935
        break;
4936
    case TARGET_NR_uname:
4937
        /* no need to transcode because we use the linux syscall */
4938
        {
4939
            struct new_utsname * buf;
4940

    
4941
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4942
                goto efault;
4943
            ret = get_errno(sys_uname(buf));
4944
            if (!is_error(ret)) {
4945
                /* Overrite the native machine name with whatever is being
4946
                   emulated. */
4947
                strcpy (buf->machine, UNAME_MACHINE);
4948
                /* Allow the user to override the reported release.  */
4949
                if (qemu_uname_release && *qemu_uname_release)
4950
                  strcpy (buf->release, qemu_uname_release);
4951
            }
4952
            unlock_user_struct(buf, arg1, 1);
4953
        }
4954
        break;
4955
#ifdef TARGET_I386
4956
    case TARGET_NR_modify_ldt:
4957
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4958
        break;
4959
#if !defined(TARGET_X86_64)
4960
    case TARGET_NR_vm86old:
4961
        goto unimplemented;
4962
    case TARGET_NR_vm86:
4963
        ret = do_vm86(cpu_env, arg1, arg2);
4964
        break;
4965
#endif
4966
#endif
4967
    case TARGET_NR_adjtimex:
4968
        goto unimplemented;
4969
#ifdef TARGET_NR_create_module
4970
    case TARGET_NR_create_module:
4971
#endif
4972
    case TARGET_NR_init_module:
4973
    case TARGET_NR_delete_module:
4974
#ifdef TARGET_NR_get_kernel_syms
4975
    case TARGET_NR_get_kernel_syms:
4976
#endif
4977
        goto unimplemented;
4978
    case TARGET_NR_quotactl:
4979
        goto unimplemented;
4980
    case TARGET_NR_getpgid:
4981
        ret = get_errno(getpgid(arg1));
4982
        break;
4983
    case TARGET_NR_fchdir:
4984
        ret = get_errno(fchdir(arg1));
4985
        break;
4986
#ifdef TARGET_NR_bdflush /* not on x86_64 */
4987
    case TARGET_NR_bdflush:
4988
        goto unimplemented;
4989
#endif
4990
#ifdef TARGET_NR_sysfs
4991
    case TARGET_NR_sysfs:
4992
        goto unimplemented;
4993
#endif
4994
    case TARGET_NR_personality:
4995
        ret = get_errno(personality(arg1));
4996
        break;
4997
#ifdef TARGET_NR_afs_syscall
4998
    case TARGET_NR_afs_syscall:
4999
        goto unimplemented;
5000
#endif
5001
#ifdef TARGET_NR__llseek /* Not on alpha */
5002
    case TARGET_NR__llseek:
5003
        {
5004
#if defined (__x86_64__)
5005
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5006
            if (put_user_s64(ret, arg4))
5007
                goto efault;
5008
#else
5009
            int64_t res;
5010
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5011
            if (put_user_s64(res, arg4))
5012
                goto efault;
5013
#endif
5014
        }
5015
        break;
5016
#endif
5017
    case TARGET_NR_getdents:
5018
#if TARGET_ABI_BITS != 32
5019
        goto unimplemented;
5020
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5021
        {
5022
            struct target_dirent *target_dirp;
5023
            struct linux_dirent *dirp;
5024
            abi_long count = arg3;
5025

    
5026
            dirp = malloc(count);
5027
            if (!dirp) {
5028
                ret = -TARGET_ENOMEM;
5029
                goto fail;
5030
            }
5031

    
5032
            ret = get_errno(sys_getdents(arg1, dirp, count));
5033
            if (!is_error(ret)) {
5034
                struct linux_dirent *de;
5035
                struct target_dirent *tde;
5036
                int len = ret;
5037
                int reclen, treclen;
5038
                int count1, tnamelen;
5039

    
5040
                count1 = 0;
5041
                de = dirp;
5042
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5043
                    goto efault;
5044
                tde = target_dirp;
5045
                while (len > 0) {
5046
                    reclen = de->d_reclen;
5047
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5048
                    tde->d_reclen = tswap16(treclen);
5049
                    tde->d_ino = tswapl(de->d_ino);
5050
                    tde->d_off = tswapl(de->d_off);
5051
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5052
                    if (tnamelen > 256)
5053
                        tnamelen = 256;
5054
                    /* XXX: may not be correct */
5055
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5056
                    de = (struct linux_dirent *)((char *)de + reclen);
5057
                    len -= reclen;
5058
                    tde = (struct target_dirent *)((char *)tde + treclen);
5059
                    count1 += treclen;
5060
                }
5061
                ret = count1;
5062
                unlock_user(target_dirp, arg2, ret);
5063
            }
5064
            free(dirp);
5065
        }
5066
#else
5067
        {
5068
            struct linux_dirent *dirp;
5069
            abi_long count = arg3;
5070

    
5071
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5072
                goto efault;
5073
            ret = get_errno(sys_getdents(arg1, dirp, count));
5074
            if (!is_error(ret)) {
5075
                struct linux_dirent *de;
5076
                int len = ret;
5077
                int reclen;
5078
                de = dirp;
5079
                while (len > 0) {
5080
                    reclen = de->d_reclen;
5081
                    if (reclen > len)
5082
                        break;
5083
                    de->d_reclen = tswap16(reclen);
5084
                    tswapls(&de->d_ino);
5085
                    tswapls(&de->d_off);
5086
                    de = (struct linux_dirent *)((char *)de + reclen);
5087
                    len -= reclen;
5088
                }
5089
            }
5090
            unlock_user(dirp, arg2, ret);
5091
        }
5092
#endif
5093
        break;
5094
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5095
    case TARGET_NR_getdents64:
5096
        {
5097
            struct linux_dirent64 *dirp;
5098
            abi_long count = arg3;
5099
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5100
                goto efault;
5101
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5102
            if (!is_error(ret)) {
5103
                struct linux_dirent64 *de;
5104
                int len = ret;
5105
                int reclen;
5106
                de = dirp;
5107
                while (len > 0) {
5108
                    reclen = de->d_reclen;
5109
                    if (reclen > len)
5110
                        break;
5111
                    de->d_reclen = tswap16(reclen);
5112
                    tswap64s((uint64_t *)&de->d_ino);
5113
                    tswap64s((uint64_t *)&de->d_off);
5114
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5115
                    len -= reclen;
5116
                }
5117
            }
5118
            unlock_user(dirp, arg2, ret);
5119
        }
5120
        break;
5121
#endif /* TARGET_NR_getdents64 */
5122
#ifdef TARGET_NR__newselect
5123
    case TARGET_NR__newselect:
5124
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5125
        break;
5126
#endif
5127
#ifdef TARGET_NR_poll
5128
    case TARGET_NR_poll:
5129
        {
5130
            struct target_pollfd *target_pfd;
5131
            unsigned int nfds = arg2;
5132
            int timeout = arg3;
5133
            struct pollfd *pfd;
5134
            unsigned int i;
5135

    
5136
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5137
            if (!target_pfd)
5138
                goto efault;
5139
            pfd = alloca(sizeof(struct pollfd) * nfds);
5140
            for(i = 0; i < nfds; i++) {
5141
                pfd[i].fd = tswap32(target_pfd[i].fd);
5142
                pfd[i].events = tswap16(target_pfd[i].events);
5143
            }
5144
            ret = get_errno(poll(pfd, nfds, timeout));
5145
            if (!is_error(ret)) {
5146
                for(i = 0; i < nfds; i++) {
5147
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5148
                }
5149
                ret += nfds * (sizeof(struct target_pollfd)
5150
                               - sizeof(struct pollfd));
5151
            }
5152
            unlock_user(target_pfd, arg1, ret);
5153
        }
5154
        break;
5155
#endif
5156
    case TARGET_NR_flock:
5157
        /* NOTE: the flock constant seems to be the same for every
5158
           Linux platform */
5159
        ret = get_errno(flock(arg1, arg2));
5160
        break;
5161
    case TARGET_NR_readv:
5162
        {
5163
            int count = arg3;
5164
            struct iovec *vec;
5165

    
5166
            vec = alloca(count * sizeof(struct iovec));
5167
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5168
                goto efault;
5169
            ret = get_errno(readv(arg1, vec, count));
5170
            unlock_iovec(vec, arg2, count, 1);
5171
        }
5172
        break;
5173
    case TARGET_NR_writev:
5174
        {
5175
            int count = arg3;
5176
            struct iovec *vec;
5177

    
5178
            vec = alloca(count * sizeof(struct iovec));
5179
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5180
                goto efault;
5181
            ret = get_errno(writev(arg1, vec, count));
5182
            unlock_iovec(vec, arg2, count, 0);
5183
        }
5184
        break;
5185
    case TARGET_NR_getsid:
5186
        ret = get_errno(getsid(arg1));
5187
        break;
5188
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5189
    case TARGET_NR_fdatasync:
5190
        ret = get_errno(fdatasync(arg1));
5191
        break;
5192
#endif
5193
    case TARGET_NR__sysctl:
5194
        /* We don't implement this, but ENOTDIR is always a safe
5195
           return value. */
5196
        ret = -TARGET_ENOTDIR;
5197
        break;
5198
    case TARGET_NR_sched_setparam:
5199
        {
5200
            struct sched_param *target_schp;
5201
            struct sched_param schp;
5202

    
5203
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5204
                goto efault;
5205
            schp.sched_priority = tswap32(target_schp->sched_priority);
5206
            unlock_user_struct(target_schp, arg2, 0);
5207
            ret = get_errno(sched_setparam(arg1, &schp));
5208
        }
5209
        break;
5210
    case TARGET_NR_sched_getparam:
5211
        {
5212
            struct sched_param *target_schp;
5213
            struct sched_param schp;
5214
            ret = get_errno(sched_getparam(arg1, &schp));
5215
            if (!is_error(ret)) {
5216
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5217
                    goto efault;
5218
                target_schp->sched_priority = tswap32(schp.sched_priority);
5219
                unlock_user_struct(target_schp, arg2, 1);
5220
            }
5221
        }
5222
        break;
5223
    case TARGET_NR_sched_setscheduler:
5224
        {
5225
            struct sched_param *target_schp;
5226
            struct sched_param schp;
5227
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5228
                goto efault;
5229
            schp.sched_priority = tswap32(target_schp->sched_priority);
5230
            unlock_user_struct(target_schp, arg3, 0);
5231
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5232
        }
5233
        break;
5234
    case TARGET_NR_sched_getscheduler:
5235
        ret = get_errno(sched_getscheduler(arg1));
5236
        break;
5237
    case TARGET_NR_sched_yield:
5238
        ret = get_errno(sched_yield());
5239
        break;
5240
    case TARGET_NR_sched_get_priority_max:
5241
        ret = get_errno(sched_get_priority_max(arg1));
5242
        break;
5243
    case TARGET_NR_sched_get_priority_min:
5244
        ret = get_errno(sched_get_priority_min(arg1));
5245
        break;
5246
    case TARGET_NR_sched_rr_get_interval:
5247
        {
5248
            struct timespec ts;
5249
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
5250
            if (!is_error(ret)) {
5251
                host_to_target_timespec(arg2, &ts);
5252
            }
5253
        }
5254
        break;
5255
    case TARGET_NR_nanosleep:
5256
        {
5257
            struct timespec req, rem;
5258
            target_to_host_timespec(&req, arg1);
5259
            ret = get_errno(nanosleep(&req, &rem));
5260
            if (is_error(ret) && arg2) {
5261
                host_to_target_timespec(arg2, &rem);
5262
            }
5263
        }
5264
        break;
5265
#ifdef TARGET_NR_query_module
5266
    case TARGET_NR_query_module:
5267
        goto unimplemented;
5268
#endif
5269
#ifdef TARGET_NR_nfsservctl
5270
    case TARGET_NR_nfsservctl:
5271
        goto unimplemented;
5272
#endif
5273
    case TARGET_NR_prctl:
5274
        switch (arg1)
5275
            {
5276
            case PR_GET_PDEATHSIG:
5277
                {
5278
                    int deathsig;
5279
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5280
                    if (!is_error(ret) && arg2
5281
                        && put_user_ual(deathsig, arg2))
5282
                        goto efault;
5283
                }
5284
                break;
5285
            default:
5286
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5287
                break;
5288
            }
5289
        break;
5290
#ifdef TARGET_NR_arch_prctl
5291
    case TARGET_NR_arch_prctl:
5292
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
5293
        ret = do_arch_prctl(cpu_env, arg1, arg2);
5294
        break;
5295
#else
5296
        goto unimplemented;
5297
#endif
5298
#endif
5299
#ifdef TARGET_NR_pread
5300
    case TARGET_NR_pread:
5301
#ifdef TARGET_ARM
5302
        if (((CPUARMState *)cpu_env)->eabi)
5303
            arg4 = arg5;
5304
#endif
5305
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5306
            goto efault;
5307
        ret = get_errno(pread(arg1, p, arg3, arg4));
5308
        unlock_user(p, arg2, ret);
5309
        break;
5310
    case TARGET_NR_pwrite:
5311
#ifdef TARGET_ARM
5312
        if (((CPUARMState *)cpu_env)->eabi)
5313
            arg4 = arg5;
5314
#endif
5315
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5316
            goto efault;
5317
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
5318
        unlock_user(p, arg2, 0);
5319
        break;
5320
#endif
5321
#ifdef TARGET_NR_pread64
5322
    case TARGET_NR_pread64:
5323
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5324
            goto efault;
5325
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5326
        unlock_user(p, arg2, ret);
5327
        break;
5328
    case TARGET_NR_pwrite64:
5329
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5330
            goto efault;
5331
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5332
        unlock_user(p, arg2, 0);
5333
        break;
5334
#endif
5335
    case TARGET_NR_getcwd:
5336
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5337
            goto efault;
5338
        ret = get_errno(sys_getcwd1(p, arg2));
5339
        unlock_user(p, arg1, ret);
5340
        break;
5341
    case TARGET_NR_capget:
5342
        goto unimplemented;
5343
    case TARGET_NR_capset:
5344
        goto unimplemented;
5345
    case TARGET_NR_sigaltstack:
5346
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5347
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5348
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5349
        break;
5350
#else
5351
        goto unimplemented;
5352
#endif
5353
    case TARGET_NR_sendfile:
5354
        goto unimplemented;
5355
#ifdef TARGET_NR_getpmsg
5356
    case TARGET_NR_getpmsg:
5357
        goto unimplemented;
5358
#endif
5359
#ifdef TARGET_NR_putpmsg
5360
    case TARGET_NR_putpmsg:
5361
        goto unimplemented;
5362
#endif
5363
#ifdef TARGET_NR_vfork
5364
    case TARGET_NR_vfork:
5365
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5366
                        0, 0, 0, 0));
5367
        break;
5368
#endif
5369
#ifdef TARGET_NR_ugetrlimit
5370
    case TARGET_NR_ugetrlimit:
5371
    {
5372
        struct rlimit rlim;
5373
        ret = get_errno(getrlimit(arg1, &rlim));
5374
        if (!is_error(ret)) {
5375
            struct target_rlimit *target_rlim;
5376
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5377
                goto efault;
5378
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5379
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
5380
            unlock_user_struct(target_rlim, arg2, 1);
5381
        }
5382
        break;
5383
    }
5384
#endif
5385
#ifdef TARGET_NR_truncate64
5386
    case TARGET_NR_truncate64:
5387
        if (!(p = lock_user_string(arg1)))
5388
            goto efault;
5389
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5390
        unlock_user(p, arg1, 0);
5391
        break;
5392
#endif
5393
#ifdef TARGET_NR_ftruncate64
5394
    case TARGET_NR_ftruncate64:
5395
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5396
        break;
5397
#endif
5398
#ifdef TARGET_NR_stat64
5399
    case TARGET_NR_stat64:
5400
        if (!(p = lock_user_string(arg1)))
5401
            goto efault;
5402
        ret = get_errno(stat(path(p), &st));
5403
        unlock_user(p, arg1, 0);
5404
        if (!is_error(ret))
5405
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5406
        break;
5407
#endif
5408
#ifdef TARGET_NR_lstat64
5409
    case TARGET_NR_lstat64:
5410
        if (!(p = lock_user_string(arg1)))
5411
            goto efault;
5412
        ret = get_errno(lstat(path(p), &st));
5413
        unlock_user(p, arg1, 0);
5414
        if (!is_error(ret))
5415
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5416
        break;
5417
#endif
5418
#ifdef TARGET_NR_fstat64
5419
    case TARGET_NR_fstat64:
5420
        ret = get_errno(fstat(arg1, &st));
5421
        if (!is_error(ret))
5422
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5423
        break;
5424
#endif
5425
#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
5426
    case TARGET_NR_fstatat64:
5427
        if (!(p = lock_user_string(arg2)))
5428
            goto efault;
5429
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5430
        if (!is_error(ret))
5431
            ret = host_to_target_stat64(cpu_env, arg3, &st);
5432
        break;
5433
#endif
5434
#ifdef USE_UID16
5435
    case TARGET_NR_lchown:
5436
        if (!(p = lock_user_string(arg1)))
5437
            goto efault;
5438
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5439
        unlock_user(p, arg1, 0);
5440
        break;
5441
    case TARGET_NR_getuid:
5442
        ret = get_errno(high2lowuid(getuid()));
5443
        break;
5444
    case TARGET_NR_getgid:
5445
        ret = get_errno(high2lowgid(getgid()));
5446
        break;
5447
    case TARGET_NR_geteuid:
5448
        ret = get_errno(high2lowuid(geteuid()));
5449
        break;
5450
    case TARGET_NR_getegid:
5451
        ret = get_errno(high2lowgid(getegid()));
5452
        break;
5453
    case TARGET_NR_setreuid:
5454
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5455
        break;
5456
    case TARGET_NR_setregid:
5457
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5458
        break;
5459
    case TARGET_NR_getgroups:
5460
        {
5461
            int gidsetsize = arg1;
5462
            uint16_t *target_grouplist;
5463
            gid_t *grouplist;
5464
            int i;
5465

    
5466
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5467
            ret = get_errno(getgroups(gidsetsize, grouplist));
5468
            if (gidsetsize == 0)
5469
                break;
5470
            if (!is_error(ret)) {
5471
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5472
                if (!target_grouplist)
5473
                    goto efault;
5474
                for(i = 0;i < ret; i++)
5475
                    target_grouplist[i] = tswap16(grouplist[i]);
5476
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5477
            }
5478
        }
5479
        break;
5480
    case TARGET_NR_setgroups:
5481
        {
5482
            int gidsetsize = arg1;
5483
            uint16_t *target_grouplist;
5484
            gid_t *grouplist;
5485
            int i;
5486

    
5487
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5488
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5489
            if (!target_grouplist) {
5490
                ret = -TARGET_EFAULT;
5491
                goto fail;
5492
            }
5493
            for(i = 0;i < gidsetsize; i++)
5494
                grouplist[i] = tswap16(target_grouplist[i]);
5495
            unlock_user(target_grouplist, arg2, 0);
5496
            ret = get_errno(setgroups(gidsetsize, grouplist));
5497
        }
5498
        break;
5499
    case TARGET_NR_fchown:
5500
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5501
        break;
5502
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5503
    case TARGET_NR_fchownat:
5504
        if (!(p = lock_user_string(arg2))) 
5505
            goto efault;
5506
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5507
        unlock_user(p, arg2, 0);
5508
        break;
5509
#endif
5510
#ifdef TARGET_NR_setresuid
5511
    case TARGET_NR_setresuid:
5512
        ret = get_errno(setresuid(low2highuid(arg1),
5513
                                  low2highuid(arg2),
5514
                                  low2highuid(arg3)));
5515
        break;
5516
#endif
5517
#ifdef TARGET_NR_getresuid
5518
    case TARGET_NR_getresuid:
5519
        {
5520
            uid_t ruid, euid, suid;
5521
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5522
            if (!is_error(ret)) {
5523
                if (put_user_u16(high2lowuid(ruid), arg1)
5524
                    || put_user_u16(high2lowuid(euid), arg2)
5525
                    || put_user_u16(high2lowuid(suid), arg3))
5526
                    goto efault;
5527
            }
5528
        }
5529
        break;
5530
#endif
5531
#ifdef TARGET_NR_getresgid
5532
    case TARGET_NR_setresgid:
5533
        ret = get_errno(setresgid(low2highgid(arg1),
5534
                                  low2highgid(arg2),
5535
                                  low2highgid(arg3)));
5536
        break;
5537
#endif
5538
#ifdef TARGET_NR_getresgid
5539
    case TARGET_NR_getresgid:
5540
        {
5541
            gid_t rgid, egid, sgid;
5542
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5543
            if (!is_error(ret)) {
5544
                if (put_user_u16(high2lowgid(rgid), arg1)
5545
                    || put_user_u16(high2lowgid(egid), arg2)
5546
                    || put_user_u16(high2lowgid(sgid), arg3))
5547
                    goto efault;
5548
            }
5549
        }
5550
        break;
5551
#endif
5552
    case TARGET_NR_chown:
5553
        if (!(p = lock_user_string(arg1)))
5554
            goto efault;
5555
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5556
        unlock_user(p, arg1, 0);
5557
        break;
5558
    case TARGET_NR_setuid:
5559
        ret = get_errno(setuid(low2highuid(arg1)));
5560
        break;
5561
    case TARGET_NR_setgid:
5562
        ret = get_errno(setgid(low2highgid(arg1)));
5563
        break;
5564
    case TARGET_NR_setfsuid:
5565
        ret = get_errno(setfsuid(arg1));
5566
        break;
5567
    case TARGET_NR_setfsgid:
5568
        ret = get_errno(setfsgid(arg1));
5569
        break;
5570
#endif /* USE_UID16 */
5571

    
5572
#ifdef TARGET_NR_lchown32
5573
    case TARGET_NR_lchown32:
5574
        if (!(p = lock_user_string(arg1)))
5575
            goto efault;
5576
        ret = get_errno(lchown(p, arg2, arg3));
5577
        unlock_user(p, arg1, 0);
5578
        break;
5579
#endif
5580
#ifdef TARGET_NR_getuid32
5581
    case TARGET_NR_getuid32:
5582
        ret = get_errno(getuid());
5583
        break;
5584
#endif
5585

    
5586
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
5587
   /* Alpha specific */
5588
    case TARGET_NR_getxuid:
5589
         {
5590
            uid_t euid;
5591
            euid=geteuid();
5592
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
5593
         }
5594
        ret = get_errno(getuid());
5595
        break;
5596
#endif
5597
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
5598
   /* Alpha specific */
5599
    case TARGET_NR_getxgid:
5600
         {
5601
            uid_t egid;
5602
            egid=getegid();
5603
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
5604
         }
5605
        ret = get_errno(getgid());
5606
        break;
5607
#endif
5608

    
5609
#ifdef TARGET_NR_getgid32
5610
    case TARGET_NR_getgid32:
5611
        ret = get_errno(getgid());
5612
        break;
5613
#endif
5614
#ifdef TARGET_NR_geteuid32
5615
    case TARGET_NR_geteuid32:
5616
        ret = get_errno(geteuid());
5617
        break;
5618
#endif
5619
#ifdef TARGET_NR_getegid32
5620
    case TARGET_NR_getegid32:
5621
        ret = get_errno(getegid());
5622
        break;
5623
#endif
5624
#ifdef TARGET_NR_setreuid32
5625
    case TARGET_NR_setreuid32:
5626
        ret = get_errno(setreuid(arg1, arg2));
5627
        break;
5628
#endif
5629
#ifdef TARGET_NR_setregid32
5630
    case TARGET_NR_setregid32:
5631
        ret = get_errno(setregid(arg1, arg2));
5632
        break;
5633
#endif
5634
#ifdef TARGET_NR_getgroups32
5635
    case TARGET_NR_getgroups32:
5636
        {
5637
            int gidsetsize = arg1;
5638
            uint32_t *target_grouplist;
5639
            gid_t *grouplist;
5640
            int i;
5641

    
5642
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5643
            ret = get_errno(getgroups(gidsetsize, grouplist));
5644
            if (gidsetsize == 0)
5645
                break;
5646
            if (!is_error(ret)) {
5647
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5648
                if (!target_grouplist) {
5649
                    ret = -TARGET_EFAULT;
5650
                    goto fail;
5651
                }
5652
                for(i = 0;i < ret; i++)
5653
                    target_grouplist[i] = tswap32(grouplist[i]);
5654
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
5655
            }
5656
        }
5657
        break;
5658
#endif
5659
#ifdef TARGET_NR_setgroups32
5660
    case TARGET_NR_setgroups32:
5661
        {
5662
            int gidsetsize = arg1;
5663
            uint32_t *target_grouplist;
5664
            gid_t *grouplist;
5665
            int i;
5666

    
5667
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5668
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5669
            if (!target_grouplist) {
5670
                ret = -TARGET_EFAULT;
5671
                goto fail;
5672
            }
5673
            for(i = 0;i < gidsetsize; i++)
5674
                grouplist[i] = tswap32(target_grouplist[i]);
5675
            unlock_user(target_grouplist, arg2, 0);
5676
            ret = get_errno(setgroups(gidsetsize, grouplist));
5677
        }
5678
        break;
5679
#endif
5680
#ifdef TARGET_NR_fchown32
5681
    case TARGET_NR_fchown32:
5682
        ret = get_errno(fchown(arg1, arg2, arg3));
5683
        break;
5684
#endif
5685
#ifdef TARGET_NR_setresuid32
5686
    case TARGET_NR_setresuid32:
5687
        ret = get_errno(setresuid(arg1, arg2, arg3));
5688
        break;
5689
#endif
5690
#ifdef TARGET_NR_getresuid32
5691
    case TARGET_NR_getresuid32:
5692
        {
5693
            uid_t ruid, euid, suid;
5694
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5695
            if (!is_error(ret)) {
5696
                if (put_user_u32(ruid, arg1)
5697
                    || put_user_u32(euid, arg2)
5698
                    || put_user_u32(suid, arg3))
5699
                    goto efault;
5700
            }
5701
        }
5702
        break;
5703
#endif
5704
#ifdef TARGET_NR_setresgid32
5705
    case TARGET_NR_setresgid32:
5706
        ret = get_errno(setresgid(arg1, arg2, arg3));
5707
        break;
5708
#endif
5709
#ifdef TARGET_NR_getresgid32
5710
    case TARGET_NR_getresgid32:
5711
        {
5712
            gid_t rgid, egid, sgid;
5713
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5714
            if (!is_error(ret)) {
5715
                if (put_user_u32(rgid, arg1)
5716
                    || put_user_u32(egid, arg2)
5717
                    || put_user_u32(sgid, arg3))
5718
                    goto efault;
5719
            }
5720
        }
5721
        break;
5722
#endif
5723
#ifdef TARGET_NR_chown32
5724
    case TARGET_NR_chown32:
5725
        if (!(p = lock_user_string(arg1)))
5726
            goto efault;
5727
        ret = get_errno(chown(p, arg2, arg3));
5728
        unlock_user(p, arg1, 0);
5729
        break;
5730
#endif
5731
#ifdef TARGET_NR_setuid32
5732
    case TARGET_NR_setuid32:
5733
        ret = get_errno(setuid(arg1));
5734
        break;
5735
#endif
5736
#ifdef TARGET_NR_setgid32
5737
    case TARGET_NR_setgid32:
5738
        ret = get_errno(setgid(arg1));
5739
        break;
5740
#endif
5741
#ifdef TARGET_NR_setfsuid32
5742
    case TARGET_NR_setfsuid32:
5743
        ret = get_errno(setfsuid(arg1));
5744
        break;
5745
#endif
5746
#ifdef TARGET_NR_setfsgid32
5747
    case TARGET_NR_setfsgid32:
5748
        ret = get_errno(setfsgid(arg1));
5749
        break;
5750
#endif
5751

    
5752
    case TARGET_NR_pivot_root:
5753
        goto unimplemented;
5754
#ifdef TARGET_NR_mincore
5755
    case TARGET_NR_mincore:
5756
        {
5757
            void *a;
5758
            ret = -TARGET_EFAULT;
5759
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5760
                goto efault;
5761
            if (!(p = lock_user_string(arg3)))
5762
                goto mincore_fail;
5763
            ret = get_errno(mincore(a, arg2, p));
5764
            unlock_user(p, arg3, ret);
5765
            mincore_fail:
5766
            unlock_user(a, arg1, 0);
5767
        }
5768
        break;
5769
#endif
5770
#ifdef TARGET_NR_arm_fadvise64_64
5771
    case TARGET_NR_arm_fadvise64_64:
5772
        {
5773
                /*
5774
                 * arm_fadvise64_64 looks like fadvise64_64 but
5775
                 * with different argument order
5776
                 */
5777
                abi_long temp;
5778
                temp = arg3;
5779
                arg3 = arg4;
5780
                arg4 = temp;
5781
        }
5782
#endif
5783
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5784
#ifdef TARGET_NR_fadvise64_64
5785
    case TARGET_NR_fadvise64_64:
5786
#endif
5787
        /* This is a hint, so ignoring and returning success is ok.  */
5788
        ret = get_errno(0);
5789
        break;
5790
#endif
5791
#ifdef TARGET_NR_madvise
5792
    case TARGET_NR_madvise:
5793
        /* A straight passthrough may not be safe because qemu sometimes
5794
           turns private flie-backed mappings into anonymous mappings.
5795
           This will break MADV_DONTNEED.
5796
           This is a hint, so ignoring and returning success is ok.  */
5797
        ret = get_errno(0);
5798
        break;
5799
#endif
5800
#if TARGET_ABI_BITS == 32
5801
    case TARGET_NR_fcntl64:
5802
    {
5803
        int cmd;
5804
        struct flock64 fl;
5805
        struct target_flock64 *target_fl;
5806
#ifdef TARGET_ARM
5807
        struct target_eabi_flock64 *target_efl;
5808
#endif
5809

    
5810
        switch(arg2){
5811
        case TARGET_F_GETLK64:
5812
            cmd = F_GETLK64;
5813
            break;
5814
        case TARGET_F_SETLK64:
5815
            cmd = F_SETLK64;
5816
            break;
5817
        case TARGET_F_SETLKW64:
5818
            cmd = F_SETLK64;
5819
            break;
5820
        default:
5821
            cmd = arg2;
5822
            break;
5823
        }
5824

    
5825
        switch(arg2) {
5826
        case TARGET_F_GETLK64:
5827
#ifdef TARGET_ARM
5828
            if (((CPUARMState *)cpu_env)->eabi) {
5829
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5830
                    goto efault;
5831
                fl.l_type = tswap16(target_efl->l_type);
5832
                fl.l_whence = tswap16(target_efl->l_whence);
5833
                fl.l_start = tswap64(target_efl->l_start);
5834
                fl.l_len = tswap64(target_efl->l_len);
5835
                fl.l_pid = tswapl(target_efl->l_pid);
5836
                unlock_user_struct(target_efl, arg3, 0);
5837
            } else
5838
#endif
5839
            {
5840
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5841
                    goto efault;
5842
                fl.l_type = tswap16(target_fl->l_type);
5843
                fl.l_whence = tswap16(target_fl->l_whence);
5844
                fl.l_start = tswap64(target_fl->l_start);
5845
                fl.l_len = tswap64(target_fl->l_len);
5846
                fl.l_pid = tswapl(target_fl->l_pid);
5847
                unlock_user_struct(target_fl, arg3, 0);
5848
            }
5849
            ret = get_errno(fcntl(arg1, cmd, &fl));
5850
            if (ret == 0) {
5851
#ifdef TARGET_ARM
5852
                if (((CPUARMState *)cpu_env)->eabi) {
5853
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
5854
                        goto efault;
5855
                    target_efl->l_type = tswap16(fl.l_type);
5856
                    target_efl->l_whence = tswap16(fl.l_whence);
5857
                    target_efl->l_start = tswap64(fl.l_start);
5858
                    target_efl->l_len = tswap64(fl.l_len);
5859
                    target_efl->l_pid = tswapl(fl.l_pid);
5860
                    unlock_user_struct(target_efl, arg3, 1);
5861
                } else
5862
#endif
5863
                {
5864
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
5865
                        goto efault;
5866
                    target_fl->l_type = tswap16(fl.l_type);
5867
                    target_fl->l_whence = tswap16(fl.l_whence);
5868
                    target_fl->l_start = tswap64(fl.l_start);
5869
                    target_fl->l_len = tswap64(fl.l_len);
5870
                    target_fl->l_pid = tswapl(fl.l_pid);
5871
                    unlock_user_struct(target_fl, arg3, 1);
5872
                }
5873
            }
5874
            break;
5875

    
5876
        case TARGET_F_SETLK64:
5877
        case TARGET_F_SETLKW64:
5878
#ifdef TARGET_ARM
5879
            if (((CPUARMState *)cpu_env)->eabi) {
5880
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5881
                    goto efault;
5882
                fl.l_type = tswap16(target_efl->l_type);
5883
                fl.l_whence = tswap16(target_efl->l_whence);
5884
                fl.l_start = tswap64(target_efl->l_start);
5885
                fl.l_len = tswap64(target_efl->l_len);
5886
                fl.l_pid = tswapl(target_efl->l_pid);
5887
                unlock_user_struct(target_efl, arg3, 0);
5888
            } else
5889
#endif
5890
            {
5891
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5892
                    goto efault;
5893
                fl.l_type = tswap16(target_fl->l_type);
5894
                fl.l_whence = tswap16(target_fl->l_whence);
5895
                fl.l_start = tswap64(target_fl->l_start);
5896
                fl.l_len = tswap64(target_fl->l_len);
5897
                fl.l_pid = tswapl(target_fl->l_pid);
5898
                unlock_user_struct(target_fl, arg3, 0);
5899
            }
5900
            ret = get_errno(fcntl(arg1, cmd, &fl));
5901
            break;
5902
        default:
5903
            ret = do_fcntl(arg1, cmd, arg3);
5904
            break;
5905
        }
5906
        break;
5907
    }
5908
#endif
5909
#ifdef TARGET_NR_cacheflush
5910
    case TARGET_NR_cacheflush:
5911
        /* self-modifying code is handled automatically, so nothing needed */
5912
        ret = 0;
5913
        break;
5914
#endif
5915
#ifdef TARGET_NR_security
5916
    case TARGET_NR_security:
5917
        goto unimplemented;
5918
#endif
5919
#ifdef TARGET_NR_getpagesize
5920
    case TARGET_NR_getpagesize:
5921
        ret = TARGET_PAGE_SIZE;
5922
        break;
5923
#endif
5924
    case TARGET_NR_gettid:
5925
        ret = get_errno(gettid());
5926
        break;
5927
#ifdef TARGET_NR_readahead
5928
    case TARGET_NR_readahead:
5929
#if TARGET_ABI_BITS == 32
5930
#ifdef TARGET_ARM
5931
        if (((CPUARMState *)cpu_env)->eabi)
5932
        {
5933
            arg2 = arg3;
5934
            arg3 = arg4;
5935
            arg4 = arg5;
5936
        }
5937
#endif
5938
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
5939
#else
5940
        ret = get_errno(readahead(arg1, arg2, arg3));
5941
#endif
5942
        break;
5943
#endif
5944
#ifdef TARGET_NR_setxattr
5945
    case TARGET_NR_setxattr:
5946
    case TARGET_NR_lsetxattr:
5947
    case TARGET_NR_fsetxattr:
5948
    case TARGET_NR_getxattr:
5949
    case TARGET_NR_lgetxattr:
5950
    case TARGET_NR_fgetxattr:
5951
    case TARGET_NR_listxattr:
5952
    case TARGET_NR_llistxattr:
5953
    case TARGET_NR_flistxattr:
5954
    case TARGET_NR_removexattr:
5955
    case TARGET_NR_lremovexattr:
5956
    case TARGET_NR_fremovexattr:
5957
        goto unimplemented_nowarn;
5958
#endif
5959
#ifdef TARGET_NR_set_thread_area
5960
    case TARGET_NR_set_thread_area:
5961
#if defined(TARGET_MIPS)
5962
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5963
      ret = 0;
5964
      break;
5965
#elif defined(TARGET_CRIS)
5966
      if (arg1 & 0xff)
5967
          ret = -TARGET_EINVAL;
5968
      else {
5969
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
5970
          ret = 0;
5971
      }
5972
      break;
5973
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
5974
      ret = do_set_thread_area(cpu_env, arg1);
5975
      break;
5976
#else
5977
      goto unimplemented_nowarn;
5978
#endif
5979
#endif
5980
#ifdef TARGET_NR_get_thread_area
5981
    case TARGET_NR_get_thread_area:
5982
#if defined(TARGET_I386) && defined(TARGET_ABI32)
5983
        ret = do_get_thread_area(cpu_env, arg1);
5984
#else
5985
        goto unimplemented_nowarn;
5986
#endif
5987
#endif
5988
#ifdef TARGET_NR_getdomainname
5989
    case TARGET_NR_getdomainname:
5990
        goto unimplemented_nowarn;
5991
#endif
5992

    
5993
#ifdef TARGET_NR_clock_gettime
5994
    case TARGET_NR_clock_gettime:
5995
    {
5996
        struct timespec ts;
5997
        ret = get_errno(clock_gettime(arg1, &ts));
5998
        if (!is_error(ret)) {
5999
            host_to_target_timespec(arg2, &ts);
6000
        }
6001
        break;
6002
    }
6003
#endif
6004
#ifdef TARGET_NR_clock_getres
6005
    case TARGET_NR_clock_getres:
6006
    {
6007
        struct timespec ts;
6008
        ret = get_errno(clock_getres(arg1, &ts));
6009
        if (!is_error(ret)) {
6010
            host_to_target_timespec(arg2, &ts);
6011
        }
6012
        break;
6013
    }
6014
#endif
6015
#ifdef TARGET_NR_clock_nanosleep
6016
    case TARGET_NR_clock_nanosleep:
6017
    {
6018
        struct timespec ts;
6019
        target_to_host_timespec(&ts, arg3);
6020
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6021
        if (arg4)
6022
            host_to_target_timespec(arg4, &ts);
6023
        break;
6024
    }
6025
#endif
6026

    
6027
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6028
    case TARGET_NR_set_tid_address:
6029
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
6030
        break;
6031
#endif
6032

    
6033
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6034
    case TARGET_NR_tkill:
6035
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6036
        break;
6037
#endif
6038

    
6039
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6040
    case TARGET_NR_tgkill:
6041
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6042
                        target_to_host_signal(arg3)));
6043
        break;
6044
#endif
6045

    
6046
#ifdef TARGET_NR_set_robust_list
6047
    case TARGET_NR_set_robust_list:
6048
        goto unimplemented_nowarn;
6049
#endif
6050

    
6051
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6052
    case TARGET_NR_utimensat:
6053
        {
6054
            struct timespec ts[2];
6055
            target_to_host_timespec(ts, arg3);
6056
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6057
            if (!arg2)
6058
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
6059
            else {
6060
                if (!(p = lock_user_string(arg2))) {
6061
                    ret = -TARGET_EFAULT;
6062
                    goto fail;
6063
                }
6064
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
6065
                unlock_user(p, arg2, 0);
6066
            }
6067
        }
6068
        break;
6069
#endif
6070
#if defined(USE_NPTL)
6071
    case TARGET_NR_futex:
6072
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6073
        break;
6074
#endif
6075
#ifdef TARGET_NR_inotify_init
6076
    case TARGET_NR_inotify_init:
6077
        ret = get_errno(sys_inotify_init());
6078
        break;
6079
#endif
6080
#ifdef TARGET_NR_inotify_add_watch
6081
    case TARGET_NR_inotify_add_watch:
6082
        p = lock_user_string(arg2);
6083
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6084
        unlock_user(p, arg2, 0);
6085
        break;
6086
#endif
6087
#ifdef TARGET_NR_inotify_rm_watch
6088
    case TARGET_NR_inotify_rm_watch:
6089
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6090
        break;
6091
#endif
6092

    
6093
    default:
6094
    unimplemented:
6095
        gemu_log("qemu: Unsupported syscall: %d\n", num);
6096
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6097
    unimplemented_nowarn:
6098
#endif
6099
        ret = -TARGET_ENOSYS;
6100
        break;
6101
    }
6102
fail:
6103
#ifdef DEBUG
6104
    gemu_log(" = %ld\n", ret);
6105
#endif
6106
    if(do_strace)
6107
        print_syscall_ret(num, ret);
6108
    return ret;
6109
efault:
6110
    ret = -TARGET_EFAULT;
6111
    goto fail;
6112
}