Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 530e7615

History | View | Annotate | Download (187.6 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
/* do_bind() Must return target values and target errnos. */
1144
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1145
                        socklen_t addrlen)
1146
{
1147
    void *addr = alloca(addrlen);
1148

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

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

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

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

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

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

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

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

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

    
1229
    addr = alloca(addrlen);
1230

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

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

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

    
1251
    addr = alloca(addrlen);
1252

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

    
1262
/* do_getsockname() Must return target values and target errnos. */
1263
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1264
                               abi_ulong target_addrlen_addr)
1265
{
1266
    socklen_t addrlen;
1267
    void *addr;
1268
    abi_long ret;
1269

    
1270
    if (get_user_u32(addrlen, target_addrlen_addr))
1271
        return -TARGET_EFAULT;
1272

    
1273
    addr = alloca(addrlen);
1274

    
1275
    ret = get_errno(getsockname(fd, addr, &addrlen));
1276
    if (!is_error(ret)) {
1277
        host_to_target_sockaddr(target_addr, addr, addrlen);
1278
        if (put_user_u32(addrlen, target_addrlen_addr))
1279
            ret = -TARGET_EFAULT;
1280
    }
1281
    return ret;
1282
}
1283

    
1284
/* do_socketpair() Must return target values and target errnos. */
1285
static abi_long do_socketpair(int domain, int type, int protocol,
1286
                              abi_ulong target_tab_addr)
1287
{
1288
    int tab[2];
1289
    abi_long ret;
1290

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

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

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

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

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

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

    
1369
    switch(num) {
1370
    case SOCKOP_socket:
1371
        {
1372
            int domain, type, protocol;
1373

    
1374
            if (get_user_s32(domain, vptr)
1375
                || get_user_s32(type, vptr + n)
1376
                || get_user_s32(protocol, vptr + 2 * n))
1377
                return -TARGET_EFAULT;
1378

    
1379
            ret = do_socket(domain, type, protocol);
1380
        }
1381
        break;
1382
    case SOCKOP_bind:
1383
        {
1384
            int sockfd;
1385
            abi_ulong target_addr;
1386
            socklen_t addrlen;
1387

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

    
1393
            ret = do_bind(sockfd, target_addr, addrlen);
1394
        }
1395
        break;
1396
    case SOCKOP_connect:
1397
        {
1398
            int sockfd;
1399
            abi_ulong target_addr;
1400
            socklen_t addrlen;
1401

    
1402
            if (get_user_s32(sockfd, vptr)
1403
                || get_user_ual(target_addr, vptr + n)
1404
                || get_user_u32(addrlen, vptr + 2 * n))
1405
                return -TARGET_EFAULT;
1406

    
1407
            ret = do_connect(sockfd, target_addr, addrlen);
1408
        }
1409
        break;
1410
    case SOCKOP_listen:
1411
        {
1412
            int sockfd, backlog;
1413

    
1414
            if (get_user_s32(sockfd, vptr)
1415
                || get_user_s32(backlog, vptr + n))
1416
                return -TARGET_EFAULT;
1417

    
1418
            ret = get_errno(listen(sockfd, backlog));
1419
        }
1420
        break;
1421
    case SOCKOP_accept:
1422
        {
1423
            int sockfd;
1424
            abi_ulong target_addr, target_addrlen;
1425

    
1426
            if (get_user_s32(sockfd, vptr)
1427
                || get_user_ual(target_addr, vptr + n)
1428
                || get_user_u32(target_addrlen, vptr + 2 * n))
1429
                return -TARGET_EFAULT;
1430

    
1431
            ret = do_accept(sockfd, target_addr, target_addrlen);
1432
        }
1433
        break;
1434
    case SOCKOP_getsockname:
1435
        {
1436
            int sockfd;
1437
            abi_ulong target_addr, target_addrlen;
1438

    
1439
            if (get_user_s32(sockfd, vptr)
1440
                || get_user_ual(target_addr, vptr + n)
1441
                || get_user_u32(target_addrlen, vptr + 2 * n))
1442
                return -TARGET_EFAULT;
1443

    
1444
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1445
        }
1446
        break;
1447
    case SOCKOP_getpeername:
1448
        {
1449
            int sockfd;
1450
            abi_ulong target_addr, target_addrlen;
1451

    
1452
            if (get_user_s32(sockfd, vptr)
1453
                || get_user_ual(target_addr, vptr + n)
1454
                || get_user_u32(target_addrlen, vptr + 2 * n))
1455
                return -TARGET_EFAULT;
1456

    
1457
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1458
        }
1459
        break;
1460
    case SOCKOP_socketpair:
1461
        {
1462
            int domain, type, protocol;
1463
            abi_ulong tab;
1464

    
1465
            if (get_user_s32(domain, vptr)
1466
                || get_user_s32(type, vptr + n)
1467
                || get_user_s32(protocol, vptr + 2 * n)
1468
                || get_user_ual(tab, vptr + 3 * n))
1469
                return -TARGET_EFAULT;
1470

    
1471
            ret = do_socketpair(domain, type, protocol, tab);
1472
        }
1473
        break;
1474
    case SOCKOP_send:
1475
        {
1476
            int sockfd;
1477
            abi_ulong msg;
1478
            size_t len;
1479
            int flags;
1480

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

    
1487
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1488
        }
1489
        break;
1490
    case SOCKOP_recv:
1491
        {
1492
            int sockfd;
1493
            abi_ulong msg;
1494
            size_t len;
1495
            int flags;
1496

    
1497
            if (get_user_s32(sockfd, vptr)
1498
                || get_user_ual(msg, vptr + n)
1499
                || get_user_ual(len, vptr + 2 * n)
1500
                || get_user_s32(flags, vptr + 3 * n))
1501
                return -TARGET_EFAULT;
1502

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

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

    
1523
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1524
        }
1525
        break;
1526
    case SOCKOP_recvfrom:
1527
        {
1528
            int sockfd;
1529
            abi_ulong msg;
1530
            size_t len;
1531
            int flags;
1532
            abi_ulong addr;
1533
            socklen_t addrlen;
1534

    
1535
            if (get_user_s32(sockfd, vptr)
1536
                || get_user_ual(msg, vptr + n)
1537
                || get_user_ual(len, vptr + 2 * n)
1538
                || get_user_s32(flags, vptr + 3 * n)
1539
                || get_user_ual(addr, vptr + 4 * n)
1540
                || get_user_u32(addrlen, vptr + 5 * n))
1541
                return -TARGET_EFAULT;
1542

    
1543
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1544
        }
1545
        break;
1546
    case SOCKOP_shutdown:
1547
        {
1548
            int sockfd, how;
1549

    
1550
            if (get_user_s32(sockfd, vptr)
1551
                || get_user_s32(how, vptr + n))
1552
                return -TARGET_EFAULT;
1553

    
1554
            ret = get_errno(shutdown(sockfd, how));
1555
        }
1556
        break;
1557
    case SOCKOP_sendmsg:
1558
    case SOCKOP_recvmsg:
1559
        {
1560
            int fd;
1561
            abi_ulong target_msg;
1562
            int flags;
1563

    
1564
            if (get_user_s32(fd, vptr)
1565
                || get_user_ual(target_msg, vptr + n)
1566
                || get_user_s32(flags, vptr + 2 * n))
1567
                return -TARGET_EFAULT;
1568

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

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

    
1588
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1589
        }
1590
        break;
1591
    case SOCKOP_getsockopt:
1592
        {
1593
            int sockfd;
1594
            int level;
1595
            int optname;
1596
            abi_ulong optval;
1597
            socklen_t optlen;
1598

    
1599
            if (get_user_s32(sockfd, vptr)
1600
                || get_user_s32(level, vptr + n)
1601
                || get_user_s32(optname, vptr + 2 * n)
1602
                || get_user_ual(optval, vptr + 3 * n)
1603
                || get_user_u32(optlen, vptr + 4 * n))
1604
                return -TARGET_EFAULT;
1605

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

    
1618
#ifdef TARGET_NR_ipc
1619
#define N_SHM_REGIONS        32
1620

    
1621
static struct shm_region {
1622
    abi_ulong        start;
1623
    abi_ulong        size;
1624
} shm_regions[N_SHM_REGIONS];
1625
#endif
1626

    
1627
struct target_ipc_perm
1628
{
1629
    abi_long __key;
1630
    abi_ulong uid;
1631
    abi_ulong gid;
1632
    abi_ulong cuid;
1633
    abi_ulong cgid;
1634
    unsigned short int mode;
1635
    unsigned short int __pad1;
1636
    unsigned short int __seq;
1637
    unsigned short int __pad2;
1638
    abi_ulong __unused1;
1639
    abi_ulong __unused2;
1640
};
1641

    
1642
struct target_semid_ds
1643
{
1644
  struct target_ipc_perm sem_perm;
1645
  abi_ulong sem_otime;
1646
  abi_ulong __unused1;
1647
  abi_ulong sem_ctime;
1648
  abi_ulong __unused2;
1649
  abi_ulong sem_nsems;
1650
  abi_ulong __unused3;
1651
  abi_ulong __unused4;
1652
};
1653

    
1654
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1655
                                               abi_ulong target_addr)
1656
{
1657
    struct target_ipc_perm *target_ip;
1658
    struct target_semid_ds *target_sd;
1659

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

    
1673
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1674
                                               struct ipc_perm *host_ip)
1675
{
1676
    struct target_ipc_perm *target_ip;
1677
    struct target_semid_ds *target_sd;
1678

    
1679
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1680
        return -TARGET_EFAULT;
1681
    target_ip = &(target_sd->sem_perm);
1682
    target_ip->__key = tswapl(host_ip->__key);
1683
    target_ip->uid = tswapl(host_ip->uid);
1684
    target_ip->gid = tswapl(host_ip->gid);
1685
    target_ip->cuid = tswapl(host_ip->cuid);
1686
    target_ip->cgid = tswapl(host_ip->cgid);
1687
    target_ip->mode = tswapl(host_ip->mode);
1688
    unlock_user_struct(target_sd, target_addr, 1);
1689
    return 0;
1690
}
1691

    
1692
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1693
                                               abi_ulong target_addr)
1694
{
1695
    struct target_semid_ds *target_sd;
1696

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

    
1707
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1708
                                               struct semid_ds *host_sd)
1709
{
1710
    struct target_semid_ds *target_sd;
1711

    
1712
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1713
        return -TARGET_EFAULT;
1714
    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1715
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1716
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
1717
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1718
    unlock_user_struct(target_sd, target_addr, 1);
1719
    return 0;
1720
}
1721

    
1722
union semun {
1723
        int val;
1724
        struct semid_ds *buf;
1725
        unsigned short *array;
1726
};
1727

    
1728
union target_semun {
1729
        int val;
1730
        abi_long buf;
1731
        unsigned short int *array;
1732
};
1733

    
1734
static inline abi_long target_to_host_semun(int cmd,
1735
                                            union semun *host_su,
1736
                                            abi_ulong target_addr,
1737
                                            struct semid_ds *ds)
1738
{
1739
    union target_semun *target_su;
1740

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

    
1770
static inline abi_long host_to_target_semun(int cmd,
1771
                                            abi_ulong target_addr,
1772
                                            union semun *host_su,
1773
                                            struct semid_ds *ds)
1774
{
1775
    union target_semun *target_su;
1776

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

    
1805
static inline abi_long do_semctl(int first, int second, int third,
1806
                                 abi_long ptr)
1807
{
1808
    union semun arg;
1809
    struct semid_ds dsarg;
1810
    int cmd = third&0xff;
1811
    abi_long ret = 0;
1812

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

    
1848
    return ret;
1849
}
1850

    
1851
struct target_msqid_ds
1852
{
1853
    struct target_ipc_perm msg_perm;
1854
    abi_ulong msg_stime;
1855
#if TARGET_ABI_BITS == 32
1856
    abi_ulong __unused1;
1857
#endif
1858
    abi_ulong msg_rtime;
1859
#if TARGET_ABI_BITS == 32
1860
    abi_ulong __unused2;
1861
#endif
1862
    abi_ulong msg_ctime;
1863
#if TARGET_ABI_BITS == 32
1864
    abi_ulong __unused3;
1865
#endif
1866
    abi_ulong __msg_cbytes;
1867
    abi_ulong msg_qnum;
1868
    abi_ulong msg_qbytes;
1869
    abi_ulong msg_lspid;
1870
    abi_ulong msg_lrpid;
1871
    abi_ulong __unused4;
1872
    abi_ulong __unused5;
1873
};
1874

    
1875
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1876
                                               abi_ulong target_addr)
1877
{
1878
    struct target_msqid_ds *target_md;
1879

    
1880
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1881
        return -TARGET_EFAULT;
1882
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
1883
        return -TARGET_EFAULT;
1884
    host_md->msg_stime = tswapl(target_md->msg_stime);
1885
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
1886
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
1887
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1888
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
1889
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1890
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
1891
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1892
    unlock_user_struct(target_md, target_addr, 0);
1893
    return 0;
1894
}
1895

    
1896
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1897
                                               struct msqid_ds *host_md)
1898
{
1899
    struct target_msqid_ds *target_md;
1900

    
1901
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1902
        return -TARGET_EFAULT;
1903
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
1904
        return -TARGET_EFAULT;
1905
    target_md->msg_stime = tswapl(host_md->msg_stime);
1906
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
1907
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
1908
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1909
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
1910
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1911
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
1912
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1913
    unlock_user_struct(target_md, target_addr, 1);
1914
    return 0;
1915
}
1916

    
1917
struct target_msginfo {
1918
    int msgpool;
1919
    int msgmap;
1920
    int msgmax;
1921
    int msgmnb;
1922
    int msgmni;
1923
    int msgssz;
1924
    int msgtql;
1925
    unsigned short int msgseg;
1926
};
1927

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

    
1946
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1947
{
1948
    struct msqid_ds dsarg;
1949
    struct msginfo msginfo;
1950
    abi_long ret = -TARGET_EINVAL;
1951

    
1952
    cmd &= 0xff;
1953

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

    
1975
    return ret;
1976
}
1977

    
1978
struct target_msgbuf {
1979
    abi_long mtype;
1980
    char        mtext[1];
1981
};
1982

    
1983
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1984
                                 unsigned int msgsz, int msgflg)
1985
{
1986
    struct target_msgbuf *target_mb;
1987
    struct msgbuf *host_mb;
1988
    abi_long ret = 0;
1989

    
1990
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1991
        return -TARGET_EFAULT;
1992
    host_mb = malloc(msgsz+sizeof(long));
1993
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
1994
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
1995
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1996
    free(host_mb);
1997
    unlock_user_struct(target_mb, msgp, 0);
1998

    
1999
    return ret;
2000
}
2001

    
2002
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2003
                                 unsigned int msgsz, abi_long msgtyp,
2004
                                 int msgflg)
2005
{
2006
    struct target_msgbuf *target_mb;
2007
    char *target_mtext;
2008
    struct msgbuf *host_mb;
2009
    abi_long ret = 0;
2010

    
2011
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2012
        return -TARGET_EFAULT;
2013

    
2014
    host_mb = malloc(msgsz+sizeof(long));
2015
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2016

    
2017
    if (ret > 0) {
2018
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2019
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2020
        if (!target_mtext) {
2021
            ret = -TARGET_EFAULT;
2022
            goto end;
2023
        }
2024
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2025
        unlock_user(target_mtext, target_mtext_addr, ret);
2026
    }
2027

    
2028
    target_mb->mtype = tswapl(host_mb->mtype);
2029
    free(host_mb);
2030

    
2031
end:
2032
    if (target_mb)
2033
        unlock_user_struct(target_mb, msgp, 1);
2034
    return ret;
2035
}
2036

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

    
2049
    version = call >> 16;
2050
    call &= 0xffff;
2051

    
2052
    switch (call) {
2053
    case IPCOP_semop:
2054
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
2055
        break;
2056

    
2057
    case IPCOP_semget:
2058
        ret = get_errno(semget(first, second, third));
2059
        break;
2060

    
2061
    case IPCOP_semctl:
2062
        ret = do_semctl(first, second, third, ptr);
2063
        break;
2064

    
2065
    case IPCOP_semtimedop:
2066
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2067
        ret = -TARGET_ENOSYS;
2068
        break;
2069

    
2070
    case IPCOP_msgget:
2071
        ret = get_errno(msgget(first, second));
2072
        break;
2073

    
2074
    case IPCOP_msgsnd:
2075
        ret = do_msgsnd(first, ptr, second, third);
2076
        break;
2077

    
2078
    case IPCOP_msgctl:
2079
        ret = do_msgctl(first, second, ptr);
2080
        break;
2081

    
2082
    case IPCOP_msgrcv:
2083
        switch (version) {
2084
        case 0:
2085
            {
2086
                struct target_ipc_kludge {
2087
                    abi_long msgp;
2088
                    abi_long msgtyp;
2089
                } *tmp;
2090

    
2091
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2092
                    ret = -TARGET_EFAULT;
2093
                    break;
2094
                }
2095

    
2096
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2097

    
2098
                unlock_user_struct(tmp, ptr, 0);
2099
                break;
2100
            }
2101
        default:
2102
            ret = do_msgrcv(first, ptr, second, fifth, third);
2103
        }
2104
        break;
2105

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

    
2151
    case IPCOP_shmget:
2152
        /* IPC_* flag values are the same on all linux platforms */
2153
        ret = get_errno(shmget(first, second, third));
2154
        break;
2155

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

    
2178
/* kernel structure types definitions */
2179
#define IFNAMSIZ        16
2180

    
2181
#define STRUCT(name, list...) STRUCT_ ## name,
2182
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2183
enum {
2184
#include "syscall_types.h"
2185
};
2186
#undef STRUCT
2187
#undef STRUCT_SPECIAL
2188

    
2189
#define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2190
#define STRUCT_SPECIAL(name)
2191
#include "syscall_types.h"
2192
#undef STRUCT
2193
#undef STRUCT_SPECIAL
2194

    
2195
typedef struct IOCTLEntry {
2196
    unsigned int target_cmd;
2197
    unsigned int host_cmd;
2198
    const char *name;
2199
    int access;
2200
    const argtype arg_type[5];
2201
} IOCTLEntry;
2202

    
2203
#define IOC_R 0x0001
2204
#define IOC_W 0x0002
2205
#define IOC_RW (IOC_R | IOC_W)
2206

    
2207
#define MAX_STRUCT_SIZE 4096
2208

    
2209
static IOCTLEntry ioctl_entries[] = {
2210
#define IOCTL(cmd, access, types...) \
2211
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2212
#include "ioctls.h"
2213
    { 0, 0, },
2214
};
2215

    
2216
/* ??? Implement proper locking for ioctls.  */
2217
/* do_ioctl() Must return target values and target errnos. */
2218
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2219
{
2220
    const IOCTLEntry *ie;
2221
    const argtype *arg_type;
2222
    abi_long ret;
2223
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2224
    int target_size;
2225
    void *argptr;
2226

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

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

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

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

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

    
2400
static void target_to_host_termios (void *dst, const void *src)
2401
{
2402
    struct host_termios *host = dst;
2403
    const struct target_termios *target = src;
2404

    
2405
    host->c_iflag =
2406
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2407
    host->c_oflag =
2408
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2409
    host->c_cflag =
2410
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2411
    host->c_lflag =
2412
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2413
    host->c_line = target->c_line;
2414

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

    
2434
static void host_to_target_termios (void *dst, const void *src)
2435
{
2436
    struct target_termios *target = dst;
2437
    const struct host_termios *host = src;
2438

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

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

    
2468
static const StructEntry struct_termios_def = {
2469
    .convert = { host_to_target_termios, target_to_host_termios },
2470
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2471
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2472
};
2473

    
2474
static bitmask_transtbl mmap_flags_tbl[] = {
2475
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2476
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2477
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2478
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2479
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2480
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2481
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2482
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2483
        { 0, 0, 0, 0 }
2484
};
2485

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

    
2506
#if defined(TARGET_I386)
2507

    
2508
/* NOTE: there is really one LDT for all the threads */
2509
static uint8_t *ldt_table;
2510

    
2511
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2512
{
2513
    int size;
2514
    void *p;
2515

    
2516
    if (!ldt_table)
2517
        return 0;
2518
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2519
    if (size > bytecount)
2520
        size = bytecount;
2521
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
2522
    if (!p)
2523
        return -TARGET_EFAULT;
2524
    /* ??? Should this by byteswapped?  */
2525
    memcpy(p, ldt_table, size);
2526
    unlock_user(p, ptr, size);
2527
    return size;
2528
}
2529

    
2530
/* XXX: add locking support */
2531
static abi_long write_ldt(CPUX86State *env,
2532
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
2533
{
2534
    struct target_modify_ldt_ldt_s ldt_info;
2535
    struct target_modify_ldt_ldt_s *target_ldt_info;
2536
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2537
    int seg_not_present, useable, lm;
2538
    uint32_t *lp, entry_1, entry_2;
2539

    
2540
    if (bytecount != sizeof(ldt_info))
2541
        return -TARGET_EINVAL;
2542
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2543
        return -TARGET_EFAULT;
2544
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2545
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2546
    ldt_info.limit = tswap32(target_ldt_info->limit);
2547
    ldt_info.flags = tswap32(target_ldt_info->flags);
2548
    unlock_user_struct(target_ldt_info, ptr, 0);
2549

    
2550
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2551
        return -TARGET_EINVAL;
2552
    seg_32bit = ldt_info.flags & 1;
2553
    contents = (ldt_info.flags >> 1) & 3;
2554
    read_exec_only = (ldt_info.flags >> 3) & 1;
2555
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2556
    seg_not_present = (ldt_info.flags >> 5) & 1;
2557
    useable = (ldt_info.flags >> 6) & 1;
2558
#ifdef TARGET_ABI32
2559
    lm = 0;
2560
#else
2561
    lm = (ldt_info.flags >> 7) & 1;
2562
#endif
2563
    if (contents == 3) {
2564
        if (oldmode)
2565
            return -TARGET_EINVAL;
2566
        if (seg_not_present == 0)
2567
            return -TARGET_EINVAL;
2568
    }
2569
    /* allocate the LDT */
2570
    if (!ldt_table) {
2571
        env->ldt.base = target_mmap(0,
2572
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
2573
                                    PROT_READ|PROT_WRITE,
2574
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2575
        if (env->ldt.base == -1)
2576
            return -TARGET_ENOMEM;
2577
        memset(g2h(env->ldt.base), 0,
2578
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2579
        env->ldt.limit = 0xffff;
2580
        ldt_table = g2h(env->ldt.base);
2581
    }
2582

    
2583
    /* NOTE: same code as Linux kernel */
2584
    /* Allow LDTs to be cleared by the user. */
2585
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2586
        if (oldmode ||
2587
            (contents == 0                &&
2588
             read_exec_only == 1        &&
2589
             seg_32bit == 0                &&
2590
             limit_in_pages == 0        &&
2591
             seg_not_present == 1        &&
2592
             useable == 0 )) {
2593
            entry_1 = 0;
2594
            entry_2 = 0;
2595
            goto install;
2596
        }
2597
    }
2598

    
2599
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2600
        (ldt_info.limit & 0x0ffff);
2601
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2602
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2603
        (ldt_info.limit & 0xf0000) |
2604
        ((read_exec_only ^ 1) << 9) |
2605
        (contents << 10) |
2606
        ((seg_not_present ^ 1) << 15) |
2607
        (seg_32bit << 22) |
2608
        (limit_in_pages << 23) |
2609
        (lm << 21) |
2610
        0x7000;
2611
    if (!oldmode)
2612
        entry_2 |= (useable << 20);
2613

    
2614
    /* Install the new entry ...  */
2615
install:
2616
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2617
    lp[0] = tswap32(entry_1);
2618
    lp[1] = tswap32(entry_2);
2619
    return 0;
2620
}
2621

    
2622
/* specific and weird i386 syscalls */
2623
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2624
                              unsigned long bytecount)
2625
{
2626
    abi_long ret;
2627

    
2628
    switch (func) {
2629
    case 0:
2630
        ret = read_ldt(ptr, bytecount);
2631
        break;
2632
    case 1:
2633
        ret = write_ldt(env, ptr, bytecount, 1);
2634
        break;
2635
    case 0x11:
2636
        ret = write_ldt(env, ptr, bytecount, 0);
2637
        break;
2638
    default:
2639
        ret = -TARGET_ENOSYS;
2640
        break;
2641
    }
2642
    return ret;
2643
}
2644

    
2645
#if defined(TARGET_I386) && defined(TARGET_ABI32)
2646
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2647
{
2648
    uint64_t *gdt_table = g2h(env->gdt.base);
2649
    struct target_modify_ldt_ldt_s ldt_info;
2650
    struct target_modify_ldt_ldt_s *target_ldt_info;
2651
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2652
    int seg_not_present, useable, lm;
2653
    uint32_t *lp, entry_1, entry_2;
2654
    int i;
2655

    
2656
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2657
    if (!target_ldt_info)
2658
        return -TARGET_EFAULT;
2659
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2660
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2661
    ldt_info.limit = tswap32(target_ldt_info->limit);
2662
    ldt_info.flags = tswap32(target_ldt_info->flags);
2663
    if (ldt_info.entry_number == -1) {
2664
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2665
            if (gdt_table[i] == 0) {
2666
                ldt_info.entry_number = i;
2667
                target_ldt_info->entry_number = tswap32(i);
2668
                break;
2669
            }
2670
        }
2671
    }
2672
    unlock_user_struct(target_ldt_info, ptr, 1);
2673

    
2674
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
2675
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2676
           return -TARGET_EINVAL;
2677
    seg_32bit = ldt_info.flags & 1;
2678
    contents = (ldt_info.flags >> 1) & 3;
2679
    read_exec_only = (ldt_info.flags >> 3) & 1;
2680
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2681
    seg_not_present = (ldt_info.flags >> 5) & 1;
2682
    useable = (ldt_info.flags >> 6) & 1;
2683
#ifdef TARGET_ABI32
2684
    lm = 0;
2685
#else
2686
    lm = (ldt_info.flags >> 7) & 1;
2687
#endif
2688

    
2689
    if (contents == 3) {
2690
        if (seg_not_present == 0)
2691
            return -TARGET_EINVAL;
2692
    }
2693

    
2694
    /* NOTE: same code as Linux kernel */
2695
    /* Allow LDTs to be cleared by the user. */
2696
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2697
        if ((contents == 0             &&
2698
             read_exec_only == 1       &&
2699
             seg_32bit == 0            &&
2700
             limit_in_pages == 0       &&
2701
             seg_not_present == 1      &&
2702
             useable == 0 )) {
2703
            entry_1 = 0;
2704
            entry_2 = 0;
2705
            goto install;
2706
        }
2707
    }
2708

    
2709
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2710
        (ldt_info.limit & 0x0ffff);
2711
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2712
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2713
        (ldt_info.limit & 0xf0000) |
2714
        ((read_exec_only ^ 1) << 9) |
2715
        (contents << 10) |
2716
        ((seg_not_present ^ 1) << 15) |
2717
        (seg_32bit << 22) |
2718
        (limit_in_pages << 23) |
2719
        (useable << 20) |
2720
        (lm << 21) |
2721
        0x7000;
2722

    
2723
    /* Install the new entry ...  */
2724
install:
2725
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2726
    lp[0] = tswap32(entry_1);
2727
    lp[1] = tswap32(entry_2);
2728
    return 0;
2729
}
2730

    
2731
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2732
{
2733
    struct target_modify_ldt_ldt_s *target_ldt_info;
2734
    uint64_t *gdt_table = g2h(env->gdt.base);
2735
    uint32_t base_addr, limit, flags;
2736
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2737
    int seg_not_present, useable, lm;
2738
    uint32_t *lp, entry_1, entry_2;
2739

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

    
2779
#ifndef TARGET_ABI32
2780
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2781
{
2782
    abi_long ret;
2783
    abi_ulong val;
2784
    int idx;
2785
    
2786
    switch(code) {
2787
    case TARGET_ARCH_SET_GS:
2788
    case TARGET_ARCH_SET_FS:
2789
        if (code == TARGET_ARCH_SET_GS)
2790
            idx = R_GS;
2791
        else
2792
            idx = R_FS;
2793
        cpu_x86_load_seg(env, idx, 0);
2794
        env->segs[idx].base = addr;
2795
        break;
2796
    case TARGET_ARCH_GET_GS:
2797
    case TARGET_ARCH_GET_FS:
2798
        if (code == TARGET_ARCH_GET_GS)
2799
            idx = R_GS;
2800
        else
2801
            idx = R_FS;
2802
        val = env->segs[idx].base;
2803
        if (put_user(val, addr, abi_ulong))
2804
            return -TARGET_EFAULT;
2805
        break;
2806
    default:
2807
        ret = -TARGET_EINVAL;
2808
        break;
2809
    }
2810
    return 0;
2811
}
2812
#endif
2813

    
2814
#endif /* defined(TARGET_I386) */
2815

    
2816
#if defined(USE_NPTL)
2817

    
2818
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2819

    
2820
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2821
typedef struct {
2822
    CPUState *env;
2823
    pthread_mutex_t mutex;
2824
    pthread_cond_t cond;
2825
    pthread_t thread;
2826
    uint32_t tid;
2827
    abi_ulong child_tidptr;
2828
    abi_ulong parent_tidptr;
2829
    sigset_t sigmask;
2830
} new_thread_info;
2831

    
2832
static void *clone_func(void *arg)
2833
{
2834
    new_thread_info *info = arg;
2835
    CPUState *env;
2836

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

    
2862
static int clone_func(void *arg)
2863
{
2864
    CPUState *env = arg;
2865
    cpu_loop(env);
2866
    /* never exits */
2867
    return 0;
2868
}
2869
#endif
2870

    
2871
/* do_fork() Must return host values and target errnos (unlike most
2872
   do_*() functions). */
2873
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2874
                   abi_ulong parent_tidptr, target_ulong newtls,
2875
                   abi_ulong child_tidptr)
2876
{
2877
    int ret;
2878
    TaskState *ts;
2879
    uint8_t *new_stack;
2880
    CPUState *new_env;
2881
#if defined(USE_NPTL)
2882
    unsigned int nptl_flags;
2883
    sigset_t sigmask;
2884
#endif
2885

    
2886
    /* Emulate vfork() with fork() */
2887
    if (flags & CLONE_VFORK)
2888
        flags &= ~(CLONE_VFORK | CLONE_VM);
2889

    
2890
    if (flags & CLONE_VM) {
2891
#if defined(USE_NPTL)
2892
        new_thread_info info;
2893
        pthread_attr_t attr;
2894
#endif
2895
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2896
        init_task_state(ts);
2897
        new_stack = ts->stack;
2898
        /* we create a new CPU instance. */
2899
        new_env = cpu_copy(env);
2900
        /* Init regs that differ from the parent.  */
2901
        cpu_clone_regs(new_env, newsp);
2902
        new_env->opaque = ts;
2903
#if defined(USE_NPTL)
2904
        nptl_flags = flags;
2905
        flags &= ~CLONE_NPTL_FLAGS2;
2906

    
2907
        /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2908
        if (nptl_flags & CLONE_SETTLS)
2909
            cpu_set_tls (new_env, newtls);
2910

    
2911
        /* Grab a mutex so that thread setup appears atomic.  */
2912
        pthread_mutex_lock(&clone_lock);
2913

    
2914
        memset(&info, 0, sizeof(info));
2915
        pthread_mutex_init(&info.mutex, NULL);
2916
        pthread_mutex_lock(&info.mutex);
2917
        pthread_cond_init(&info.cond, NULL);
2918
        info.env = new_env;
2919
        if (nptl_flags & CLONE_CHILD_SETTID)
2920
            info.child_tidptr = child_tidptr;
2921
        if (nptl_flags & CLONE_PARENT_SETTID)
2922
            info.parent_tidptr = parent_tidptr;
2923

    
2924
        ret = pthread_attr_init(&attr);
2925
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2926
        /* It is not safe to deliver signals until the child has finished
2927
           initializing, so temporarily block all signals.  */
2928
        sigfillset(&sigmask);
2929
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2930

    
2931
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
2932

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

    
2991
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2992
{
2993
    struct flock fl;
2994
    struct target_flock *target_fl;
2995
    struct flock64 fl64;
2996
    struct target_flock64 *target_fl64;
2997
    abi_long ret;
2998

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

    
3022
    case TARGET_F_SETLK:
3023
    case TARGET_F_SETLKW:
3024
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3025
            return -TARGET_EFAULT;
3026
        fl.l_type = tswap16(target_fl->l_type);
3027
        fl.l_whence = tswap16(target_fl->l_whence);
3028
        fl.l_start = tswapl(target_fl->l_start);
3029
        fl.l_len = tswapl(target_fl->l_len);
3030
        fl.l_pid = tswapl(target_fl->l_pid);
3031
        unlock_user_struct(target_fl, arg, 0);
3032
        ret = get_errno(fcntl(fd, cmd, &fl));
3033
        break;
3034

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

    
3069
    case F_GETFL:
3070
        ret = get_errno(fcntl(fd, cmd, arg));
3071
        if (ret >= 0) {
3072
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3073
        }
3074
        break;
3075

    
3076
    case F_SETFL:
3077
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3078
        break;
3079

    
3080
    default:
3081
        ret = get_errno(fcntl(fd, cmd, arg));
3082
        break;
3083
    }
3084
    return ret;
3085
}
3086

    
3087
#ifdef USE_UID16
3088

    
3089
static inline int high2lowuid(int uid)
3090
{
3091
    if (uid > 65535)
3092
        return 65534;
3093
    else
3094
        return uid;
3095
}
3096

    
3097
static inline int high2lowgid(int gid)
3098
{
3099
    if (gid > 65535)
3100
        return 65534;
3101
    else
3102
        return gid;
3103
}
3104

    
3105
static inline int low2highuid(int uid)
3106
{
3107
    if ((int16_t)uid == -1)
3108
        return -1;
3109
    else
3110
        return uid;
3111
}
3112

    
3113
static inline int low2highgid(int gid)
3114
{
3115
    if ((int16_t)gid == -1)
3116
        return -1;
3117
    else
3118
        return gid;
3119
}
3120

    
3121
#endif /* USE_UID16 */
3122

    
3123
void syscall_init(void)
3124
{
3125
    IOCTLEntry *ie;
3126
    const argtype *arg_type;
3127
    int size;
3128
    int i;
3129

    
3130
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3131
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3132
#include "syscall_types.h"
3133
#undef STRUCT
3134
#undef STRUCT_SPECIAL
3135

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

    
3155
        /* Build target_to_host_errno_table[] table from
3156
         * host_to_target_errno_table[]. */
3157
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3158
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3159

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

    
3172
#if TARGET_ABI_BITS == 32
3173
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3174
{
3175
#ifdef TARGET_WORDS_BIGENDIAN
3176
    return ((uint64_t)word0 << 32) | word1;
3177
#else
3178
    return ((uint64_t)word1 << 32) | word0;
3179
#endif
3180
}
3181
#else /* TARGET_ABI_BITS == 32 */
3182
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3183
{
3184
    return word0;
3185
}
3186
#endif /* TARGET_ABI_BITS != 32 */
3187

    
3188
#ifdef TARGET_NR_truncate64
3189
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3190
                                         abi_long arg2,
3191
                                         abi_long arg3,
3192
                                         abi_long arg4)
3193
{
3194
#ifdef TARGET_ARM
3195
    if (((CPUARMState *)cpu_env)->eabi)
3196
      {
3197
        arg2 = arg3;
3198
        arg3 = arg4;
3199
      }
3200
#endif
3201
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3202
}
3203
#endif
3204

    
3205
#ifdef TARGET_NR_ftruncate64
3206
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3207
                                          abi_long arg2,
3208
                                          abi_long arg3,
3209
                                          abi_long arg4)
3210
{
3211
#ifdef TARGET_ARM
3212
    if (((CPUARMState *)cpu_env)->eabi)
3213
      {
3214
        arg2 = arg3;
3215
        arg3 = arg4;
3216
      }
3217
#endif
3218
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3219
}
3220
#endif
3221

    
3222
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3223
                                               abi_ulong target_addr)
3224
{
3225
    struct target_timespec *target_ts;
3226

    
3227
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3228
        return -TARGET_EFAULT;
3229
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3230
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3231
    unlock_user_struct(target_ts, target_addr, 0);
3232
    return 0;
3233
}
3234

    
3235
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3236
                                               struct timespec *host_ts)
3237
{
3238
    struct target_timespec *target_ts;
3239

    
3240
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3241
        return -TARGET_EFAULT;
3242
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3243
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3244
    unlock_user_struct(target_ts, target_addr, 1);
3245
    return 0;
3246
}
3247

    
3248
#ifdef TARGET_NR_stat64
3249
static inline abi_long host_to_target_stat64(void *cpu_env,
3250
                                             abi_ulong target_addr,
3251
                                             struct stat *host_st)
3252
{
3253
#ifdef TARGET_ARM
3254
    if (((CPUARMState *)cpu_env)->eabi) {
3255
        struct target_eabi_stat64 *target_st;
3256

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

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

    
3305
    return 0;
3306
}
3307
#endif
3308

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

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

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

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

    
3391
#ifdef DEBUG
3392
    gemu_log("syscall %d", num);
3393
#endif
3394
    if(do_strace)
3395
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3396

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

    
3535
            argc = 0;
3536
            guest_argp = arg2;
3537
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3538
                if (get_user_ual(addr, gp))
3539
                    goto efault;
3540
                if (!addr)
3541
                    break;
3542
                argc++;
3543
            }
3544
            envc = 0;
3545
            guest_envp = arg3;
3546
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3547
                if (get_user_ual(addr, gp))
3548
                    goto efault;
3549
                if (!addr)
3550
                    break;
3551
                envc++;
3552
            }
3553

    
3554
            argp = alloca((argc + 1) * sizeof(void *));
3555
            envp = alloca((envc + 1) * sizeof(void *));
3556

    
3557
            for (gp = guest_argp, q = argp; gp;
3558
                  gp += sizeof(abi_ulong), q++) {
3559
                if (get_user_ual(addr, gp))
3560
                    goto execve_efault;
3561
                if (!addr)
3562
                    break;
3563
                if (!(*q = lock_user_string(addr)))
3564
                    goto execve_efault;
3565
            }
3566
            *q = NULL;
3567

    
3568
            for (gp = guest_envp, q = envp; gp;
3569
                  gp += sizeof(abi_ulong), q++) {
3570
                if (get_user_ual(addr, gp))
3571
                    goto execve_efault;
3572
                if (!addr)
3573
                    break;
3574
                if (!(*q = lock_user_string(addr)))
3575
                    goto execve_efault;
3576
            }
3577
            *q = NULL;
3578

    
3579
            if (!(p = lock_user_string(arg1)))
3580
                goto execve_efault;
3581
            ret = get_errno(execve(p, argp, envp));
3582
            unlock_user(p, arg1, 0);
3583

    
3584
            goto execve_end;
3585

    
3586
        execve_efault:
3587
            ret = -TARGET_EFAULT;
3588

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

    
4006
            if (arg2) {
4007
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4008
                    goto efault;
4009
                act._sa_handler = old_act->_sa_handler;
4010
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4011
                act.sa_flags = old_act->sa_flags;
4012
                unlock_user_struct(old_act, arg2, 0);
4013
                pact = &act;
4014
            } else {
4015
                pact = NULL;
4016
            }
4017

    
4018
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4019

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

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

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

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

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

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

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

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

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

    
4676
    case TARGET_NR_syslog:
4677
        if (!(p = lock_user_string(arg2)))
4678
            goto efault;
4679
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4680
        unlock_user(p, arg2, 0);
4681
        break;
4682

    
4683
    case TARGET_NR_setitimer:
4684
        {
4685
            struct itimerval value, ovalue, *pvalue;
4686

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

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

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

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

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

    
4976
            dirp = malloc(count);
4977
            if (!dirp) {
4978
                ret = -TARGET_ENOMEM;
4979
                goto fail;
4980
            }
4981

    
4982
            ret = get_errno(sys_getdents(arg1, dirp, count));
4983
            if (!is_error(ret)) {
4984
                struct linux_dirent *de;
4985
                struct target_dirent *tde;
4986
                int len = ret;
4987
                int reclen, treclen;
4988
                int count1, tnamelen;
4989

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

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

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

    
5116
            vec = alloca(count * sizeof(struct iovec));
5117
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5118
                goto efault;
5119
            ret = get_errno(readv(arg1, vec, count));
5120
            unlock_iovec(vec, arg2, count, 1);
5121
        }
5122
        break;
5123
    case TARGET_NR_writev:
5124
        {
5125
            int count = arg3;
5126
            struct iovec *vec;
5127

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

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

    
5416
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5417
            ret = get_errno(getgroups(gidsetsize, grouplist));
5418
            if (gidsetsize == 0)
5419
                break;
5420
            if (!is_error(ret)) {
5421
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5422
                if (!target_grouplist)
5423
                    goto efault;
5424
                for(i = 0;i < ret; i++)
5425
                    target_grouplist[i] = tswap16(grouplist[i]);
5426
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5427
            }
5428
        }
5429
        break;
5430
    case TARGET_NR_setgroups:
5431
        {
5432
            int gidsetsize = arg1;
5433
            uint16_t *target_grouplist;
5434
            gid_t *grouplist;
5435
            int i;
5436

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

    
5522
#ifdef TARGET_NR_lchown32
5523
    case TARGET_NR_lchown32:
5524
        if (!(p = lock_user_string(arg1)))
5525
            goto efault;
5526
        ret = get_errno(lchown(p, arg2, arg3));
5527
        unlock_user(p, arg1, 0);
5528
        break;
5529
#endif
5530
#ifdef TARGET_NR_getuid32
5531
    case TARGET_NR_getuid32:
5532
        ret = get_errno(getuid());
5533
        break;
5534
#endif
5535

    
5536
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
5537
   /* Alpha specific */
5538
    case TARGET_NR_getxuid:
5539
         {
5540
            uid_t euid;
5541
            euid=geteuid();
5542
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
5543
         }
5544
        ret = get_errno(getuid());
5545
        break;
5546
#endif
5547
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
5548
   /* Alpha specific */
5549
    case TARGET_NR_getxgid:
5550
         {
5551
            uid_t egid;
5552
            egid=getegid();
5553
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
5554
         }
5555
        ret = get_errno(getgid());
5556
        break;
5557
#endif
5558

    
5559
#ifdef TARGET_NR_getgid32
5560
    case TARGET_NR_getgid32:
5561
        ret = get_errno(getgid());
5562
        break;
5563
#endif
5564
#ifdef TARGET_NR_geteuid32
5565
    case TARGET_NR_geteuid32:
5566
        ret = get_errno(geteuid());
5567
        break;
5568
#endif
5569
#ifdef TARGET_NR_getegid32
5570
    case TARGET_NR_getegid32:
5571
        ret = get_errno(getegid());
5572
        break;
5573
#endif
5574
#ifdef TARGET_NR_setreuid32
5575
    case TARGET_NR_setreuid32:
5576
        ret = get_errno(setreuid(arg1, arg2));
5577
        break;
5578
#endif
5579
#ifdef TARGET_NR_setregid32
5580
    case TARGET_NR_setregid32:
5581
        ret = get_errno(setregid(arg1, arg2));
5582
        break;
5583
#endif
5584
#ifdef TARGET_NR_getgroups32
5585
    case TARGET_NR_getgroups32:
5586
        {
5587
            int gidsetsize = arg1;
5588
            uint32_t *target_grouplist;
5589
            gid_t *grouplist;
5590
            int i;
5591

    
5592
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5593
            ret = get_errno(getgroups(gidsetsize, grouplist));
5594
            if (gidsetsize == 0)
5595
                break;
5596
            if (!is_error(ret)) {
5597
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5598
                if (!target_grouplist) {
5599
                    ret = -TARGET_EFAULT;
5600
                    goto fail;
5601
                }
5602
                for(i = 0;i < ret; i++)
5603
                    target_grouplist[i] = tswap32(grouplist[i]);
5604
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
5605
            }
5606
        }
5607
        break;
5608
#endif
5609
#ifdef TARGET_NR_setgroups32
5610
    case TARGET_NR_setgroups32:
5611
        {
5612
            int gidsetsize = arg1;
5613
            uint32_t *target_grouplist;
5614
            gid_t *grouplist;
5615
            int i;
5616

    
5617
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5618
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5619
            if (!target_grouplist) {
5620
                ret = -TARGET_EFAULT;
5621
                goto fail;
5622
            }
5623
            for(i = 0;i < gidsetsize; i++)
5624
                grouplist[i] = tswap32(target_grouplist[i]);
5625
            unlock_user(target_grouplist, arg2, 0);
5626
            ret = get_errno(setgroups(gidsetsize, grouplist));
5627
        }
5628
        break;
5629
#endif
5630
#ifdef TARGET_NR_fchown32
5631
    case TARGET_NR_fchown32:
5632
        ret = get_errno(fchown(arg1, arg2, arg3));
5633
        break;
5634
#endif
5635
#ifdef TARGET_NR_setresuid32
5636
    case TARGET_NR_setresuid32:
5637
        ret = get_errno(setresuid(arg1, arg2, arg3));
5638
        break;
5639
#endif
5640
#ifdef TARGET_NR_getresuid32
5641
    case TARGET_NR_getresuid32:
5642
        {
5643
            uid_t ruid, euid, suid;
5644
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5645
            if (!is_error(ret)) {
5646
                if (put_user_u32(ruid, arg1)
5647
                    || put_user_u32(euid, arg2)
5648
                    || put_user_u32(suid, arg3))
5649
                    goto efault;
5650
            }
5651
        }
5652
        break;
5653
#endif
5654
#ifdef TARGET_NR_setresgid32
5655
    case TARGET_NR_setresgid32:
5656
        ret = get_errno(setresgid(arg1, arg2, arg3));
5657
        break;
5658
#endif
5659
#ifdef TARGET_NR_getresgid32
5660
    case TARGET_NR_getresgid32:
5661
        {
5662
            gid_t rgid, egid, sgid;
5663
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5664
            if (!is_error(ret)) {
5665
                if (put_user_u32(rgid, arg1)
5666
                    || put_user_u32(egid, arg2)
5667
                    || put_user_u32(sgid, arg3))
5668
                    goto efault;
5669
            }
5670
        }
5671
        break;
5672
#endif
5673
#ifdef TARGET_NR_chown32
5674
    case TARGET_NR_chown32:
5675
        if (!(p = lock_user_string(arg1)))
5676
            goto efault;
5677
        ret = get_errno(chown(p, arg2, arg3));
5678
        unlock_user(p, arg1, 0);
5679
        break;
5680
#endif
5681
#ifdef TARGET_NR_setuid32
5682
    case TARGET_NR_setuid32:
5683
        ret = get_errno(setuid(arg1));
5684
        break;
5685
#endif
5686
#ifdef TARGET_NR_setgid32
5687
    case TARGET_NR_setgid32:
5688
        ret = get_errno(setgid(arg1));
5689
        break;
5690
#endif
5691
#ifdef TARGET_NR_setfsuid32
5692
    case TARGET_NR_setfsuid32:
5693
        ret = get_errno(setfsuid(arg1));
5694
        break;
5695
#endif
5696
#ifdef TARGET_NR_setfsgid32
5697
    case TARGET_NR_setfsgid32:
5698
        ret = get_errno(setfsgid(arg1));
5699
        break;
5700
#endif
5701

    
5702
    case TARGET_NR_pivot_root:
5703
        goto unimplemented;
5704
#ifdef TARGET_NR_mincore
5705
    case TARGET_NR_mincore:
5706
        {
5707
            void *a;
5708
            ret = -TARGET_EFAULT;
5709
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5710
                goto efault;
5711
            if (!(p = lock_user_string(arg3)))
5712
                goto mincore_fail;
5713
            ret = get_errno(mincore(a, arg2, p));
5714
            unlock_user(p, arg3, ret);
5715
            mincore_fail:
5716
            unlock_user(a, arg1, 0);
5717
        }
5718
        break;
5719
#endif
5720
#ifdef TARGET_NR_arm_fadvise64_64
5721
    case TARGET_NR_arm_fadvise64_64:
5722
        {
5723
                /*
5724
                 * arm_fadvise64_64 looks like fadvise64_64 but
5725
                 * with different argument order
5726
                 */
5727
                abi_long temp;
5728
                temp = arg3;
5729
                arg3 = arg4;
5730
                arg4 = temp;
5731
        }
5732
#endif
5733
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5734
#ifdef TARGET_NR_fadvise64_64
5735
    case TARGET_NR_fadvise64_64:
5736
#endif
5737
        /* This is a hint, so ignoring and returning success is ok.  */
5738
        ret = get_errno(0);
5739
        break;
5740
#endif
5741
#ifdef TARGET_NR_madvise
5742
    case TARGET_NR_madvise:
5743
        /* A straight passthrough may not be safe because qemu sometimes
5744
           turns private flie-backed mappings into anonymous mappings.
5745
           This will break MADV_DONTNEED.
5746
           This is a hint, so ignoring and returning success is ok.  */
5747
        ret = get_errno(0);
5748
        break;
5749
#endif
5750
#if TARGET_ABI_BITS == 32
5751
    case TARGET_NR_fcntl64:
5752
    {
5753
        int cmd;
5754
        struct flock64 fl;
5755
        struct target_flock64 *target_fl;
5756
#ifdef TARGET_ARM
5757
        struct target_eabi_flock64 *target_efl;
5758
#endif
5759

    
5760
        switch(arg2){
5761
        case TARGET_F_GETLK64:
5762
            cmd = F_GETLK64;
5763
            break;
5764
        case TARGET_F_SETLK64:
5765
            cmd = F_SETLK64;
5766
            break;
5767
        case TARGET_F_SETLKW64:
5768
            cmd = F_SETLK64;
5769
            break;
5770
        default:
5771
            cmd = arg2;
5772
            break;
5773
        }
5774

    
5775
        switch(arg2) {
5776
        case TARGET_F_GETLK64:
5777
#ifdef TARGET_ARM
5778
            if (((CPUARMState *)cpu_env)->eabi) {
5779
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5780
                    goto efault;
5781
                fl.l_type = tswap16(target_efl->l_type);
5782
                fl.l_whence = tswap16(target_efl->l_whence);
5783
                fl.l_start = tswap64(target_efl->l_start);
5784
                fl.l_len = tswap64(target_efl->l_len);
5785
                fl.l_pid = tswapl(target_efl->l_pid);
5786
                unlock_user_struct(target_efl, arg3, 0);
5787
            } else
5788
#endif
5789
            {
5790
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5791
                    goto efault;
5792
                fl.l_type = tswap16(target_fl->l_type);
5793
                fl.l_whence = tswap16(target_fl->l_whence);
5794
                fl.l_start = tswap64(target_fl->l_start);
5795
                fl.l_len = tswap64(target_fl->l_len);
5796
                fl.l_pid = tswapl(target_fl->l_pid);
5797
                unlock_user_struct(target_fl, arg3, 0);
5798
            }
5799
            ret = get_errno(fcntl(arg1, cmd, &fl));
5800
            if (ret == 0) {
5801
#ifdef TARGET_ARM
5802
                if (((CPUARMState *)cpu_env)->eabi) {
5803
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
5804
                        goto efault;
5805
                    target_efl->l_type = tswap16(fl.l_type);
5806
                    target_efl->l_whence = tswap16(fl.l_whence);
5807
                    target_efl->l_start = tswap64(fl.l_start);
5808
                    target_efl->l_len = tswap64(fl.l_len);
5809
                    target_efl->l_pid = tswapl(fl.l_pid);
5810
                    unlock_user_struct(target_efl, arg3, 1);
5811
                } else
5812
#endif
5813
                {
5814
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
5815
                        goto efault;
5816
                    target_fl->l_type = tswap16(fl.l_type);
5817
                    target_fl->l_whence = tswap16(fl.l_whence);
5818
                    target_fl->l_start = tswap64(fl.l_start);
5819
                    target_fl->l_len = tswap64(fl.l_len);
5820
                    target_fl->l_pid = tswapl(fl.l_pid);
5821
                    unlock_user_struct(target_fl, arg3, 1);
5822
                }
5823
            }
5824
            break;
5825

    
5826
        case TARGET_F_SETLK64:
5827
        case TARGET_F_SETLKW64:
5828
#ifdef TARGET_ARM
5829
            if (((CPUARMState *)cpu_env)->eabi) {
5830
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5831
                    goto efault;
5832
                fl.l_type = tswap16(target_efl->l_type);
5833
                fl.l_whence = tswap16(target_efl->l_whence);
5834
                fl.l_start = tswap64(target_efl->l_start);
5835
                fl.l_len = tswap64(target_efl->l_len);
5836
                fl.l_pid = tswapl(target_efl->l_pid);
5837
                unlock_user_struct(target_efl, arg3, 0);
5838
            } else
5839
#endif
5840
            {
5841
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5842
                    goto efault;
5843
                fl.l_type = tswap16(target_fl->l_type);
5844
                fl.l_whence = tswap16(target_fl->l_whence);
5845
                fl.l_start = tswap64(target_fl->l_start);
5846
                fl.l_len = tswap64(target_fl->l_len);
5847
                fl.l_pid = tswapl(target_fl->l_pid);
5848
                unlock_user_struct(target_fl, arg3, 0);
5849
            }
5850
            ret = get_errno(fcntl(arg1, cmd, &fl));
5851
            break;
5852
        default:
5853
            ret = do_fcntl(arg1, cmd, arg3);
5854
            break;
5855
        }
5856
        break;
5857
    }
5858
#endif
5859
#ifdef TARGET_NR_cacheflush
5860
    case TARGET_NR_cacheflush:
5861
        /* self-modifying code is handled automatically, so nothing needed */
5862
        ret = 0;
5863
        break;
5864
#endif
5865
#ifdef TARGET_NR_security
5866
    case TARGET_NR_security:
5867
        goto unimplemented;
5868
#endif
5869
#ifdef TARGET_NR_getpagesize
5870
    case TARGET_NR_getpagesize:
5871
        ret = TARGET_PAGE_SIZE;
5872
        break;
5873
#endif
5874
    case TARGET_NR_gettid:
5875
        ret = get_errno(gettid());
5876
        break;
5877
#ifdef TARGET_NR_readahead
5878
    case TARGET_NR_readahead:
5879
#if TARGET_ABI_BITS == 32
5880
#ifdef TARGET_ARM
5881
        if (((CPUARMState *)cpu_env)->eabi)
5882
        {
5883
            arg2 = arg3;
5884
            arg3 = arg4;
5885
            arg4 = arg5;
5886
        }
5887
#endif
5888
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
5889
#else
5890
        ret = get_errno(readahead(arg1, arg2, arg3));
5891
#endif
5892
        break;
5893
#endif
5894
#ifdef TARGET_NR_setxattr
5895
    case TARGET_NR_setxattr:
5896
    case TARGET_NR_lsetxattr:
5897
    case TARGET_NR_fsetxattr:
5898
    case TARGET_NR_getxattr:
5899
    case TARGET_NR_lgetxattr:
5900
    case TARGET_NR_fgetxattr:
5901
    case TARGET_NR_listxattr:
5902
    case TARGET_NR_llistxattr:
5903
    case TARGET_NR_flistxattr:
5904
    case TARGET_NR_removexattr:
5905
    case TARGET_NR_lremovexattr:
5906
    case TARGET_NR_fremovexattr:
5907
        goto unimplemented_nowarn;
5908
#endif
5909
#ifdef TARGET_NR_set_thread_area
5910
    case TARGET_NR_set_thread_area:
5911
#if defined(TARGET_MIPS)
5912
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5913
      ret = 0;
5914
      break;
5915
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
5916
      ret = do_set_thread_area(cpu_env, arg1);
5917
      break;
5918
#else
5919
      goto unimplemented_nowarn;
5920
#endif
5921
#endif
5922
#ifdef TARGET_NR_get_thread_area
5923
    case TARGET_NR_get_thread_area:
5924
#if defined(TARGET_I386) && defined(TARGET_ABI32)
5925
        ret = do_get_thread_area(cpu_env, arg1);
5926
#else
5927
        goto unimplemented_nowarn;
5928
#endif
5929
#endif
5930
#ifdef TARGET_NR_getdomainname
5931
    case TARGET_NR_getdomainname:
5932
        goto unimplemented_nowarn;
5933
#endif
5934

    
5935
#ifdef TARGET_NR_clock_gettime
5936
    case TARGET_NR_clock_gettime:
5937
    {
5938
        struct timespec ts;
5939
        ret = get_errno(clock_gettime(arg1, &ts));
5940
        if (!is_error(ret)) {
5941
            host_to_target_timespec(arg2, &ts);
5942
        }
5943
        break;
5944
    }
5945
#endif
5946
#ifdef TARGET_NR_clock_getres
5947
    case TARGET_NR_clock_getres:
5948
    {
5949
        struct timespec ts;
5950
        ret = get_errno(clock_getres(arg1, &ts));
5951
        if (!is_error(ret)) {
5952
            host_to_target_timespec(arg2, &ts);
5953
        }
5954
        break;
5955
    }
5956
#endif
5957
#ifdef TARGET_NR_clock_nanosleep
5958
    case TARGET_NR_clock_nanosleep:
5959
    {
5960
        struct timespec ts;
5961
        target_to_host_timespec(&ts, arg3);
5962
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5963
        if (arg4)
5964
            host_to_target_timespec(arg4, &ts);
5965
        break;
5966
    }
5967
#endif
5968

    
5969
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5970
    case TARGET_NR_set_tid_address:
5971
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
5972
        break;
5973
#endif
5974

    
5975
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5976
    case TARGET_NR_tkill:
5977
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5978
        break;
5979
#endif
5980

    
5981
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5982
    case TARGET_NR_tgkill:
5983
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5984
                        target_to_host_signal(arg3)));
5985
        break;
5986
#endif
5987

    
5988
#ifdef TARGET_NR_set_robust_list
5989
    case TARGET_NR_set_robust_list:
5990
        goto unimplemented_nowarn;
5991
#endif
5992

    
5993
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5994
    case TARGET_NR_utimensat:
5995
        {
5996
            struct timespec ts[2];
5997
            target_to_host_timespec(ts, arg3);
5998
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5999
            if (!arg2)
6000
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
6001
            else {
6002
                if (!(p = lock_user_string(arg2))) {
6003
                    ret = -TARGET_EFAULT;
6004
                    goto fail;
6005
                }
6006
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
6007
                unlock_user(p, arg2, 0);
6008
            }
6009
        }
6010
        break;
6011
#endif
6012
#if defined(USE_NPTL)
6013
    case TARGET_NR_futex:
6014
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6015
        break;
6016
#endif
6017
#ifdef TARGET_NR_inotify_init
6018
    case TARGET_NR_inotify_init:
6019
        ret = get_errno(sys_inotify_init());
6020
        break;
6021
#endif
6022
#ifdef TARGET_NR_inotify_add_watch
6023
    case TARGET_NR_inotify_add_watch:
6024
        p = lock_user_string(arg2);
6025
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6026
        unlock_user(p, arg2, 0);
6027
        break;
6028
#endif
6029
#ifdef TARGET_NR_inotify_rm_watch
6030
    case TARGET_NR_inotify_rm_watch:
6031
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6032
        break;
6033
#endif
6034

    
6035
    default:
6036
    unimplemented:
6037
        gemu_log("qemu: Unsupported syscall: %d\n", num);
6038
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6039
    unimplemented_nowarn:
6040
#endif
6041
        ret = -TARGET_ENOSYS;
6042
        break;
6043
    }
6044
fail:
6045
#ifdef DEBUG
6046
    gemu_log(" = %ld\n", ret);
6047
#endif
6048
    if(do_strace)
6049
        print_syscall_ret(num, ret);
6050
    return ret;
6051
efault:
6052
    ret = -TARGET_EFAULT;
6053
    goto fail;
6054
}