Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 526ccb7a

History | View | Annotate | Download (179.9 kB)

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

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

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

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

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

    
86
//#define DEBUG
87

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

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

    
98

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

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

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

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

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

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

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

    
144

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

    
152

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

    
176
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
177
#define __NR__llseek __NR_lseek
178
#endif
179

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

    
262
extern int personality(int);
263
extern int flock(int, int);
264
extern int setfsuid(int);
265
extern int setfsgid(int);
266
extern int setresuid(uid_t, uid_t, uid_t);
267
extern int getresuid(uid_t *, uid_t *, uid_t *);
268
extern int setresgid(gid_t, gid_t, gid_t);
269
extern int getresgid(gid_t *, gid_t *, gid_t *);
270
extern int setgroups(int, gid_t *);
271

    
272
#define ERRNO_TABLE_SIZE 1200
273

    
274
/* target_to_host_errno_table[] is initialized from
275
 * host_to_target_errno_table[] in syscall_init(). */
276
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
277
};
278

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

    
391
static inline int host_to_target_errno(int err)
392
{
393
    if(host_to_target_errno_table[err])
394
        return host_to_target_errno_table[err];
395
    return err;
396
}
397

    
398
static inline int target_to_host_errno(int err)
399
{
400
    if (target_to_host_errno_table[err])
401
        return target_to_host_errno_table[err];
402
    return err;
403
}
404

    
405
static inline abi_long get_errno(abi_long ret)
406
{
407
    if (ret == -1)
408
        return -host_to_target_errno(errno);
409
    else
410
        return ret;
411
}
412

    
413
static inline int is_error(abi_long ret)
414
{
415
    return (abi_ulong)ret >= (abi_ulong)(-4096);
416
}
417

    
418
char *target_strerror(int err)
419
{
420
    return strerror(target_to_host_errno(err));
421
}
422

    
423
static abi_ulong target_brk;
424
static abi_ulong target_original_brk;
425

    
426
void target_set_brk(abi_ulong new_brk)
427
{
428
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
429
}
430

    
431
/* do_brk() must return target values and target errnos. */
432
abi_long do_brk(abi_ulong new_brk)
433
{
434
    abi_ulong brk_page;
435
    abi_long mapped_addr;
436
    int        new_alloc_size;
437

    
438
    if (!new_brk)
439
        return target_brk;
440
    if (new_brk < target_original_brk)
441
        return target_brk;
442

    
443
    brk_page = HOST_PAGE_ALIGN(target_brk);
444

    
445
    /* If the new brk is less than this, set it and we're done... */
446
    if (new_brk < brk_page) {
447
        target_brk = new_brk;
448
            return target_brk;
449
    }
450

    
451
    /* We need to allocate more memory after the brk... */
452
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
453
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
454
                                        PROT_READ|PROT_WRITE,
455
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
456

    
457
    if (!is_error(mapped_addr))
458
        target_brk = new_brk;
459
    
460
    return target_brk;
461
}
462

    
463
static inline abi_long copy_from_user_fdset(fd_set *fds,
464
                                            abi_ulong target_fds_addr,
465
                                            int n)
466
{
467
    int i, nw, j, k;
468
    abi_ulong b, *target_fds;
469

    
470
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
471
    if (!(target_fds = lock_user(VERIFY_READ,
472
                                 target_fds_addr,
473
                                 sizeof(abi_ulong) * nw,
474
                                 1)))
475
        return -TARGET_EFAULT;
476

    
477
    FD_ZERO(fds);
478
    k = 0;
479
    for (i = 0; i < nw; i++) {
480
        /* grab the abi_ulong */
481
        __get_user(b, &target_fds[i]);
482
        for (j = 0; j < TARGET_ABI_BITS; j++) {
483
            /* check the bit inside the abi_ulong */
484
            if ((b >> j) & 1)
485
                FD_SET(k, fds);
486
            k++;
487
        }
488
    }
489

    
490
    unlock_user(target_fds, target_fds_addr, 0);
491

    
492
    return 0;
493
}
494

    
495
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
496
                                          const fd_set *fds,
497
                                          int n)
498
{
499
    int i, nw, j, k;
500
    abi_long v;
501
    abi_ulong *target_fds;
502

    
503
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
504
    if (!(target_fds = lock_user(VERIFY_WRITE,
505
                                 target_fds_addr,
506
                                 sizeof(abi_ulong) * nw,
507
                                 0)))
508
        return -TARGET_EFAULT;
509

    
510
    k = 0;
511
    for (i = 0; i < nw; i++) {
512
        v = 0;
513
        for (j = 0; j < TARGET_ABI_BITS; j++) {
514
            v |= ((FD_ISSET(k, fds) != 0) << j);
515
            k++;
516
        }
517
        __put_user(v, &target_fds[i]);
518
    }
519

    
520
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
521

    
522
    return 0;
523
}
524

    
525
#if defined(__alpha__)
526
#define HOST_HZ 1024
527
#else
528
#define HOST_HZ 100
529
#endif
530

    
531
static inline abi_long host_to_target_clock_t(long ticks)
532
{
533
#if HOST_HZ == TARGET_HZ
534
    return ticks;
535
#else
536
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
537
#endif
538
}
539

    
540
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
541
                                             const struct rusage *rusage)
542
{
543
    struct target_rusage *target_rusage;
544

    
545
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
546
        return -TARGET_EFAULT;
547
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
548
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
549
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
550
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
551
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
552
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
553
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
554
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
555
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
556
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
557
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
558
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
559
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
560
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
561
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
562
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
563
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
564
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
565
    unlock_user_struct(target_rusage, target_addr, 1);
566

    
567
    return 0;
568
}
569

    
570
static inline abi_long copy_from_user_timeval(struct timeval *tv,
571
                                              abi_ulong target_tv_addr)
572
{
573
    struct target_timeval *target_tv;
574

    
575
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
576
        return -TARGET_EFAULT;
577

    
578
    __get_user(tv->tv_sec, &target_tv->tv_sec);
579
    __get_user(tv->tv_usec, &target_tv->tv_usec);
580

    
581
    unlock_user_struct(target_tv, target_tv_addr, 0);
582

    
583
    return 0;
584
}
585

    
586
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
587
                                            const struct timeval *tv)
588
{
589
    struct target_timeval *target_tv;
590

    
591
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
592
        return -TARGET_EFAULT;
593

    
594
    __put_user(tv->tv_sec, &target_tv->tv_sec);
595
    __put_user(tv->tv_usec, &target_tv->tv_usec);
596

    
597
    unlock_user_struct(target_tv, target_tv_addr, 1);
598

    
599
    return 0;
600
}
601

    
602

    
603
/* do_select() must return target values and target errnos. */
604
static abi_long do_select(int n,
605
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
606
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
607
{
608
    fd_set rfds, wfds, efds;
609
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
610
    struct timeval tv, *tv_ptr;
611
    abi_long ret;
612

    
613
    if (rfd_addr) {
614
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
615
            return -TARGET_EFAULT;
616
        rfds_ptr = &rfds;
617
    } else {
618
        rfds_ptr = NULL;
619
    }
620
    if (wfd_addr) {
621
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
622
            return -TARGET_EFAULT;
623
        wfds_ptr = &wfds;
624
    } else {
625
        wfds_ptr = NULL;
626
    }
627
    if (efd_addr) {
628
        if (copy_from_user_fdset(&efds, efd_addr, n))
629
            return -TARGET_EFAULT;
630
        efds_ptr = &efds;
631
    } else {
632
        efds_ptr = NULL;
633
    }
634

    
635
    if (target_tv_addr) {
636
        if (copy_from_user_timeval(&tv, target_tv_addr))
637
            return -TARGET_EFAULT;
638
        tv_ptr = &tv;
639
    } else {
640
        tv_ptr = NULL;
641
    }
642

    
643
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
644

    
645
    if (!is_error(ret)) {
646
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
647
            return -TARGET_EFAULT;
648
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
649
            return -TARGET_EFAULT;
650
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
651
            return -TARGET_EFAULT;
652

    
653
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
654
            return -TARGET_EFAULT;
655
    }
656

    
657
    return ret;
658
}
659

    
660
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
661
                                               abi_ulong target_addr,
662
                                               socklen_t len)
663
{
664
    struct target_sockaddr *target_saddr;
665

    
666
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
667
    if (!target_saddr)
668
        return -TARGET_EFAULT;
669
    memcpy(addr, target_saddr, len);
670
    addr->sa_family = tswap16(target_saddr->sa_family);
671
    unlock_user(target_saddr, target_addr, 0);
672

    
673
    return 0;
674
}
675

    
676
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
677
                                               struct sockaddr *addr,
678
                                               socklen_t len)
679
{
680
    struct target_sockaddr *target_saddr;
681

    
682
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
683
    if (!target_saddr)
684
        return -TARGET_EFAULT;
685
    memcpy(target_saddr, addr, len);
686
    target_saddr->sa_family = tswap16(addr->sa_family);
687
    unlock_user(target_saddr, target_addr, len);
688

    
689
    return 0;
690
}
691

    
692
/* ??? Should this also swap msgh->name?  */
693
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
694
                                           struct target_msghdr *target_msgh)
695
{
696
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
697
    abi_long msg_controllen;
698
    abi_ulong target_cmsg_addr;
699
    struct target_cmsghdr *target_cmsg;
700
    socklen_t space = 0;
701
    
702
    msg_controllen = tswapl(target_msgh->msg_controllen);
703
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
704
        goto the_end;
705
    target_cmsg_addr = tswapl(target_msgh->msg_control);
706
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
707
    if (!target_cmsg)
708
        return -TARGET_EFAULT;
709

    
710
    while (cmsg && target_cmsg) {
711
        void *data = CMSG_DATA(cmsg);
712
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
713

    
714
        int len = tswapl(target_cmsg->cmsg_len)
715
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
716

    
717
        space += CMSG_SPACE(len);
718
        if (space > msgh->msg_controllen) {
719
            space -= CMSG_SPACE(len);
720
            gemu_log("Host cmsg overflow\n");
721
            break;
722
        }
723

    
724
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
725
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
726
        cmsg->cmsg_len = CMSG_LEN(len);
727

    
728
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
729
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
730
            memcpy(data, target_data, len);
731
        } else {
732
            int *fd = (int *)data;
733
            int *target_fd = (int *)target_data;
734
            int i, numfds = len / sizeof(int);
735

    
736
            for (i = 0; i < numfds; i++)
737
                fd[i] = tswap32(target_fd[i]);
738
        }
739

    
740
        cmsg = CMSG_NXTHDR(msgh, cmsg);
741
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
742
    }
743
    unlock_user(target_cmsg, target_cmsg_addr, 0);
744
 the_end:
745
    msgh->msg_controllen = space;
746
    return 0;
747
}
748

    
749
/* ??? Should this also swap msgh->name?  */
750
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
751
                                           struct msghdr *msgh)
752
{
753
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
754
    abi_long msg_controllen;
755
    abi_ulong target_cmsg_addr;
756
    struct target_cmsghdr *target_cmsg;
757
    socklen_t space = 0;
758

    
759
    msg_controllen = tswapl(target_msgh->msg_controllen);
760
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
761
        goto the_end;
762
    target_cmsg_addr = tswapl(target_msgh->msg_control);
763
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
764
    if (!target_cmsg)
765
        return -TARGET_EFAULT;
766

    
767
    while (cmsg && target_cmsg) {
768
        void *data = CMSG_DATA(cmsg);
769
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
770

    
771
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
772

    
773
        space += TARGET_CMSG_SPACE(len);
774
        if (space > msg_controllen) {
775
            space -= TARGET_CMSG_SPACE(len);
776
            gemu_log("Target cmsg overflow\n");
777
            break;
778
        }
779

    
780
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
781
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
782
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
783

    
784
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
785
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
786
            memcpy(target_data, data, len);
787
        } else {
788
            int *fd = (int *)data;
789
            int *target_fd = (int *)target_data;
790
            int i, numfds = len / sizeof(int);
791

    
792
            for (i = 0; i < numfds; i++)
793
                target_fd[i] = tswap32(fd[i]);
794
        }
795

    
796
        cmsg = CMSG_NXTHDR(msgh, cmsg);
797
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
798
    }
799
    unlock_user(target_cmsg, target_cmsg_addr, space);
800
 the_end:
801
    target_msgh->msg_controllen = tswapl(space);
802
    return 0;
803
}
804

    
805
/* do_setsockopt() Must return target values and target errnos. */
806
static abi_long do_setsockopt(int sockfd, int level, int optname,
807
                              abi_ulong optval_addr, socklen_t optlen)
808
{
809
    abi_long ret;
810
    int val;
811

    
812
    switch(level) {
813
    case SOL_TCP:
814
        /* TCP options all take an 'int' value.  */
815
        if (optlen < sizeof(uint32_t))
816
            return -TARGET_EINVAL;
817

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

    
919
        if (get_user_u32(val, optval_addr))
920
            return -TARGET_EFAULT;
921
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
922
        break;
923
    default:
924
    unimplemented:
925
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
926
        ret = -TARGET_ENOPROTOOPT;
927
    }
928
    return ret;
929
}
930

    
931
/* do_getsockopt() Must return target values and target errnos. */
932
static abi_long do_getsockopt(int sockfd, int level, int optname,
933
                              abi_ulong optval_addr, abi_ulong optlen)
934
{
935
    abi_long ret;
936
    int len, lv, val;
937

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

    
1030
/* FIXME
1031
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1032
 * other lock functions have a return code of 0 for failure.
1033
 */
1034
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1035
                           int count, int copy)
1036
{
1037
    struct target_iovec *target_vec;
1038
    abi_ulong base;
1039
    int i, j;
1040

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

    
1068
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1069
                             int count, int copy)
1070
{
1071
    struct target_iovec *target_vec;
1072
    abi_ulong base;
1073
    int i;
1074

    
1075
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1076
    if (!target_vec)
1077
        return -TARGET_EFAULT;
1078
    for(i = 0;i < count; i++) {
1079
        base = tswapl(target_vec[i].iov_base);
1080
        unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1081
    }
1082
    unlock_user (target_vec, target_addr, 0);
1083

    
1084
    return 0;
1085
}
1086

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

    
1117
/* do_bind() Must return target values and target errnos. */
1118
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1119
                        socklen_t addrlen)
1120
{
1121
    void *addr = alloca(addrlen);
1122

    
1123
    target_to_host_sockaddr(addr, target_addr, addrlen);
1124
    return get_errno(bind(sockfd, addr, addrlen));
1125
}
1126

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

    
1133
    target_to_host_sockaddr(addr, target_addr, addrlen);
1134
    return get_errno(connect(sockfd, addr, addrlen));
1135
}
1136

    
1137
/* do_sendrecvmsg() Must return target values and target errnos. */
1138
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1139
                               int flags, int send)
1140
{
1141
    abi_long ret;
1142
    struct target_msghdr *msgp;
1143
    struct msghdr msg;
1144
    int count;
1145
    struct iovec *vec;
1146
    abi_ulong target_vec;
1147

    
1148
    /* FIXME */
1149
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1150
                          msgp,
1151
                          target_msg,
1152
                          send ? 1 : 0))
1153
        return -TARGET_EFAULT;
1154
    if (msgp->msg_name) {
1155
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1156
        msg.msg_name = alloca(msg.msg_namelen);
1157
        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1158
                                msg.msg_namelen);
1159
    } else {
1160
        msg.msg_name = NULL;
1161
        msg.msg_namelen = 0;
1162
    }
1163
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1164
    msg.msg_control = alloca(msg.msg_controllen);
1165
    msg.msg_flags = tswap32(msgp->msg_flags);
1166

    
1167
    count = tswapl(msgp->msg_iovlen);
1168
    vec = alloca(count * sizeof(struct iovec));
1169
    target_vec = tswapl(msgp->msg_iov);
1170
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1171
    msg.msg_iovlen = count;
1172
    msg.msg_iov = vec;
1173

    
1174
    if (send) {
1175
        ret = target_to_host_cmsg(&msg, msgp);
1176
        if (ret == 0)
1177
            ret = get_errno(sendmsg(fd, &msg, flags));
1178
    } else {
1179
        ret = get_errno(recvmsg(fd, &msg, flags));
1180
        if (!is_error(ret))
1181
            ret = host_to_target_cmsg(msgp, &msg);
1182
    }
1183
    unlock_iovec(vec, target_vec, count, !send);
1184
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1185
    return ret;
1186
}
1187

    
1188
/* do_accept() Must return target values and target errnos. */
1189
static abi_long do_accept(int fd, abi_ulong target_addr,
1190
                          abi_ulong target_addrlen_addr)
1191
{
1192
    socklen_t addrlen;
1193
    void *addr;
1194
    abi_long ret;
1195

    
1196
    if (get_user_u32(addrlen, target_addrlen_addr))
1197
        return -TARGET_EFAULT;
1198

    
1199
    addr = alloca(addrlen);
1200

    
1201
    ret = get_errno(accept(fd, addr, &addrlen));
1202
    if (!is_error(ret)) {
1203
        host_to_target_sockaddr(target_addr, addr, addrlen);
1204
        if (put_user_u32(addrlen, target_addrlen_addr))
1205
            ret = -TARGET_EFAULT;
1206
    }
1207
    return ret;
1208
}
1209

    
1210
/* do_getpeername() Must return target values and target errnos. */
1211
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1212
                               abi_ulong target_addrlen_addr)
1213
{
1214
    socklen_t addrlen;
1215
    void *addr;
1216
    abi_long ret;
1217

    
1218
    if (get_user_u32(addrlen, target_addrlen_addr))
1219
        return -TARGET_EFAULT;
1220

    
1221
    addr = alloca(addrlen);
1222

    
1223
    ret = get_errno(getpeername(fd, addr, &addrlen));
1224
    if (!is_error(ret)) {
1225
        host_to_target_sockaddr(target_addr, addr, addrlen);
1226
        if (put_user_u32(addrlen, target_addrlen_addr))
1227
            ret = -TARGET_EFAULT;
1228
    }
1229
    return ret;
1230
}
1231

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

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

    
1243
    addr = alloca(addrlen);
1244

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

    
1254
/* do_socketpair() Must return target values and target errnos. */
1255
static abi_long do_socketpair(int domain, int type, int protocol,
1256
                              abi_ulong target_tab_addr)
1257
{
1258
    int tab[2];
1259
    abi_long ret;
1260

    
1261
    ret = get_errno(socketpair(domain, type, protocol, tab));
1262
    if (!is_error(ret)) {
1263
        if (put_user_s32(tab[0], target_tab_addr)
1264
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1265
            ret = -TARGET_EFAULT;
1266
    }
1267
    return ret;
1268
}
1269

    
1270
/* do_sendto() Must return target values and target errnos. */
1271
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1272
                          abi_ulong target_addr, socklen_t addrlen)
1273
{
1274
    void *addr;
1275
    void *host_msg;
1276
    abi_long ret;
1277

    
1278
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1279
    if (!host_msg)
1280
        return -TARGET_EFAULT;
1281
    if (target_addr) {
1282
        addr = alloca(addrlen);
1283
        target_to_host_sockaddr(addr, target_addr, addrlen);
1284
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1285
    } else {
1286
        ret = get_errno(send(fd, host_msg, len, flags));
1287
    }
1288
    unlock_user(host_msg, msg, 0);
1289
    return ret;
1290
}
1291

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

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

    
1332
#ifdef TARGET_NR_socketcall
1333
/* do_socketcall() Must return target values and target errnos. */
1334
static abi_long do_socketcall(int num, abi_ulong vptr)
1335
{
1336
    abi_long ret;
1337
    const int n = sizeof(abi_ulong);
1338

    
1339
    switch(num) {
1340
    case SOCKOP_socket:
1341
        {
1342
            int domain, type, protocol;
1343

    
1344
            if (get_user_s32(domain, vptr)
1345
                || get_user_s32(type, vptr + n)
1346
                || get_user_s32(protocol, vptr + 2 * n))
1347
                return -TARGET_EFAULT;
1348

    
1349
            ret = do_socket(domain, type, protocol);
1350
        }
1351
        break;
1352
    case SOCKOP_bind:
1353
        {
1354
            int sockfd;
1355
            abi_ulong target_addr;
1356
            socklen_t addrlen;
1357

    
1358
            if (get_user_s32(sockfd, vptr)
1359
                || get_user_ual(target_addr, vptr + n)
1360
                || get_user_u32(addrlen, vptr + 2 * n))
1361
                return -TARGET_EFAULT;
1362

    
1363
            ret = do_bind(sockfd, target_addr, addrlen);
1364
        }
1365
        break;
1366
    case SOCKOP_connect:
1367
        {
1368
            int sockfd;
1369
            abi_ulong target_addr;
1370
            socklen_t addrlen;
1371

    
1372
            if (get_user_s32(sockfd, vptr)
1373
                || get_user_ual(target_addr, vptr + n)
1374
                || get_user_u32(addrlen, vptr + 2 * n))
1375
                return -TARGET_EFAULT;
1376

    
1377
            ret = do_connect(sockfd, target_addr, addrlen);
1378
        }
1379
        break;
1380
    case SOCKOP_listen:
1381
        {
1382
            int sockfd, backlog;
1383

    
1384
            if (get_user_s32(sockfd, vptr)
1385
                || get_user_s32(backlog, vptr + n))
1386
                return -TARGET_EFAULT;
1387

    
1388
            ret = get_errno(listen(sockfd, backlog));
1389
        }
1390
        break;
1391
    case SOCKOP_accept:
1392
        {
1393
            int sockfd;
1394
            abi_ulong target_addr, target_addrlen;
1395

    
1396
            if (get_user_s32(sockfd, vptr)
1397
                || get_user_ual(target_addr, vptr + n)
1398
                || get_user_u32(target_addrlen, vptr + 2 * n))
1399
                return -TARGET_EFAULT;
1400

    
1401
            ret = do_accept(sockfd, target_addr, target_addrlen);
1402
        }
1403
        break;
1404
    case SOCKOP_getsockname:
1405
        {
1406
            int sockfd;
1407
            abi_ulong target_addr, target_addrlen;
1408

    
1409
            if (get_user_s32(sockfd, vptr)
1410
                || get_user_ual(target_addr, vptr + n)
1411
                || get_user_u32(target_addrlen, vptr + 2 * n))
1412
                return -TARGET_EFAULT;
1413

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

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

    
1427
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1428
        }
1429
        break;
1430
    case SOCKOP_socketpair:
1431
        {
1432
            int domain, type, protocol;
1433
            abi_ulong tab;
1434

    
1435
            if (get_user_s32(domain, vptr)
1436
                || get_user_s32(type, vptr + n)
1437
                || get_user_s32(protocol, vptr + 2 * n)
1438
                || get_user_ual(tab, vptr + 3 * n))
1439
                return -TARGET_EFAULT;
1440

    
1441
            ret = do_socketpair(domain, type, protocol, tab);
1442
        }
1443
        break;
1444
    case SOCKOP_send:
1445
        {
1446
            int sockfd;
1447
            abi_ulong msg;
1448
            size_t len;
1449
            int flags;
1450

    
1451
            if (get_user_s32(sockfd, vptr)
1452
                || get_user_ual(msg, vptr + n)
1453
                || get_user_ual(len, vptr + 2 * n)
1454
                || get_user_s32(flags, vptr + 3 * n))
1455
                return -TARGET_EFAULT;
1456

    
1457
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1458
        }
1459
        break;
1460
    case SOCKOP_recv:
1461
        {
1462
            int sockfd;
1463
            abi_ulong msg;
1464
            size_t len;
1465
            int flags;
1466

    
1467
            if (get_user_s32(sockfd, vptr)
1468
                || get_user_ual(msg, vptr + n)
1469
                || get_user_ual(len, vptr + 2 * n)
1470
                || get_user_s32(flags, vptr + 3 * n))
1471
                return -TARGET_EFAULT;
1472

    
1473
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1474
        }
1475
        break;
1476
    case SOCKOP_sendto:
1477
        {
1478
            int sockfd;
1479
            abi_ulong msg;
1480
            size_t len;
1481
            int flags;
1482
            abi_ulong addr;
1483
            socklen_t addrlen;
1484

    
1485
            if (get_user_s32(sockfd, vptr)
1486
                || get_user_ual(msg, vptr + n)
1487
                || get_user_ual(len, vptr + 2 * n)
1488
                || get_user_s32(flags, vptr + 3 * n)
1489
                || get_user_ual(addr, vptr + 4 * n)
1490
                || get_user_u32(addrlen, vptr + 5 * n))
1491
                return -TARGET_EFAULT;
1492

    
1493
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1494
        }
1495
        break;
1496
    case SOCKOP_recvfrom:
1497
        {
1498
            int sockfd;
1499
            abi_ulong msg;
1500
            size_t len;
1501
            int flags;
1502
            abi_ulong addr;
1503
            socklen_t addrlen;
1504

    
1505
            if (get_user_s32(sockfd, vptr)
1506
                || get_user_ual(msg, vptr + n)
1507
                || get_user_ual(len, vptr + 2 * n)
1508
                || get_user_s32(flags, vptr + 3 * n)
1509
                || get_user_ual(addr, vptr + 4 * n)
1510
                || get_user_u32(addrlen, vptr + 5 * n))
1511
                return -TARGET_EFAULT;
1512

    
1513
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1514
        }
1515
        break;
1516
    case SOCKOP_shutdown:
1517
        {
1518
            int sockfd, how;
1519

    
1520
            if (get_user_s32(sockfd, vptr)
1521
                || get_user_s32(how, vptr + n))
1522
                return -TARGET_EFAULT;
1523

    
1524
            ret = get_errno(shutdown(sockfd, how));
1525
        }
1526
        break;
1527
    case SOCKOP_sendmsg:
1528
    case SOCKOP_recvmsg:
1529
        {
1530
            int fd;
1531
            abi_ulong target_msg;
1532
            int flags;
1533

    
1534
            if (get_user_s32(fd, vptr)
1535
                || get_user_ual(target_msg, vptr + n)
1536
                || get_user_s32(flags, vptr + 2 * n))
1537
                return -TARGET_EFAULT;
1538

    
1539
            ret = do_sendrecvmsg(fd, target_msg, flags,
1540
                                 (num == SOCKOP_sendmsg));
1541
        }
1542
        break;
1543
    case SOCKOP_setsockopt:
1544
        {
1545
            int sockfd;
1546
            int level;
1547
            int optname;
1548
            abi_ulong optval;
1549
            socklen_t optlen;
1550

    
1551
            if (get_user_s32(sockfd, vptr)
1552
                || get_user_s32(level, vptr + n)
1553
                || get_user_s32(optname, vptr + 2 * n)
1554
                || get_user_ual(optval, vptr + 3 * n)
1555
                || get_user_u32(optlen, vptr + 4 * n))
1556
                return -TARGET_EFAULT;
1557

    
1558
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1559
        }
1560
        break;
1561
    case SOCKOP_getsockopt:
1562
        {
1563
            int sockfd;
1564
            int level;
1565
            int optname;
1566
            abi_ulong optval;
1567
            socklen_t optlen;
1568

    
1569
            if (get_user_s32(sockfd, vptr)
1570
                || get_user_s32(level, vptr + n)
1571
                || get_user_s32(optname, vptr + 2 * n)
1572
                || get_user_ual(optval, vptr + 3 * n)
1573
                || get_user_u32(optlen, vptr + 4 * n))
1574
                return -TARGET_EFAULT;
1575

    
1576
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1577
        }
1578
        break;
1579
    default:
1580
        gemu_log("Unsupported socketcall: %d\n", num);
1581
        ret = -TARGET_ENOSYS;
1582
        break;
1583
    }
1584
    return ret;
1585
}
1586
#endif
1587

    
1588
#ifdef TARGET_NR_ipc
1589
#define N_SHM_REGIONS        32
1590

    
1591
static struct shm_region {
1592
    abi_ulong        start;
1593
    abi_ulong        size;
1594
} shm_regions[N_SHM_REGIONS];
1595

    
1596
struct target_ipc_perm
1597
{
1598
    abi_long __key;
1599
    abi_ulong uid;
1600
    abi_ulong gid;
1601
    abi_ulong cuid;
1602
    abi_ulong cgid;
1603
    unsigned short int mode;
1604
    unsigned short int __pad1;
1605
    unsigned short int __seq;
1606
    unsigned short int __pad2;
1607
    abi_ulong __unused1;
1608
    abi_ulong __unused2;
1609
};
1610

    
1611
struct target_semid_ds
1612
{
1613
  struct target_ipc_perm sem_perm;
1614
  abi_ulong sem_otime;
1615
  abi_ulong __unused1;
1616
  abi_ulong sem_ctime;
1617
  abi_ulong __unused2;
1618
  abi_ulong sem_nsems;
1619
  abi_ulong __unused3;
1620
  abi_ulong __unused4;
1621
};
1622

    
1623
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1624
                                               abi_ulong target_addr)
1625
{
1626
    struct target_ipc_perm *target_ip;
1627
    struct target_semid_ds *target_sd;
1628

    
1629
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1630
        return -TARGET_EFAULT;
1631
    target_ip=&(target_sd->sem_perm);
1632
    host_ip->__key = tswapl(target_ip->__key);
1633
    host_ip->uid = tswapl(target_ip->uid);
1634
    host_ip->gid = tswapl(target_ip->gid);
1635
    host_ip->cuid = tswapl(target_ip->cuid);
1636
    host_ip->cgid = tswapl(target_ip->cgid);
1637
    host_ip->mode = tswapl(target_ip->mode);
1638
    unlock_user_struct(target_sd, target_addr, 0);
1639
    return 0;
1640
}
1641

    
1642
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1643
                                               struct ipc_perm *host_ip)
1644
{
1645
    struct target_ipc_perm *target_ip;
1646
    struct target_semid_ds *target_sd;
1647

    
1648
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1649
        return -TARGET_EFAULT;
1650
    target_ip = &(target_sd->sem_perm);
1651
    target_ip->__key = tswapl(host_ip->__key);
1652
    target_ip->uid = tswapl(host_ip->uid);
1653
    target_ip->gid = tswapl(host_ip->gid);
1654
    target_ip->cuid = tswapl(host_ip->cuid);
1655
    target_ip->cgid = tswapl(host_ip->cgid);
1656
    target_ip->mode = tswapl(host_ip->mode);
1657
    unlock_user_struct(target_sd, target_addr, 1);
1658
    return 0;
1659
}
1660

    
1661
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1662
                                               abi_ulong target_addr)
1663
{
1664
    struct target_semid_ds *target_sd;
1665

    
1666
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1667
        return -TARGET_EFAULT;
1668
    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1669
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1670
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
1671
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1672
    unlock_user_struct(target_sd, target_addr, 0);
1673
    return 0;
1674
}
1675

    
1676
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1677
                                               struct semid_ds *host_sd)
1678
{
1679
    struct target_semid_ds *target_sd;
1680

    
1681
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1682
        return -TARGET_EFAULT;
1683
    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1684
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1685
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
1686
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1687
    unlock_user_struct(target_sd, target_addr, 1);
1688
    return 0;
1689
}
1690

    
1691
union semun {
1692
        int val;
1693
        struct semid_ds *buf;
1694
        unsigned short *array;
1695
};
1696

    
1697
union target_semun {
1698
        int val;
1699
        abi_long buf;
1700
        unsigned short int *array;
1701
};
1702

    
1703
static inline abi_long target_to_host_semun(int cmd,
1704
                                            union semun *host_su,
1705
                                            abi_ulong target_addr,
1706
                                            struct semid_ds *ds)
1707
{
1708
    union target_semun *target_su;
1709

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

    
1739
static inline abi_long host_to_target_semun(int cmd,
1740
                                            abi_ulong target_addr,
1741
                                            union semun *host_su,
1742
                                            struct semid_ds *ds)
1743
{
1744
    union target_semun *target_su;
1745

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

    
1774
static inline abi_long do_semctl(int first, int second, int third,
1775
                                 abi_long ptr)
1776
{
1777
    union semun arg;
1778
    struct semid_ds dsarg;
1779
    int cmd = third&0xff;
1780
    abi_long ret = 0;
1781

    
1782
    switch( cmd ) {
1783
        case GETVAL:
1784
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1785
            ret = get_errno(semctl(first, second, cmd, arg));
1786
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1787
            break;
1788
        case SETVAL:
1789
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1790
            ret = get_errno(semctl(first, second, cmd, arg));
1791
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1792
            break;
1793
        case GETALL:
1794
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1795
            ret = get_errno(semctl(first, second, cmd, arg));
1796
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1797
            break;
1798
        case SETALL:
1799
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1800
            ret = get_errno(semctl(first, second, cmd, arg));
1801
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1802
            break;
1803
        case IPC_STAT:
1804
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1805
            ret = get_errno(semctl(first, second, cmd, arg));
1806
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1807
            break;
1808
        case IPC_SET:
1809
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1810
            ret = get_errno(semctl(first, second, cmd, arg));
1811
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1812
            break;
1813
    default:
1814
            ret = get_errno(semctl(first, second, cmd, arg));
1815
    }
1816

    
1817
    return ret;
1818
}
1819

    
1820
struct target_msqid_ds
1821
{
1822
  struct target_ipc_perm msg_perm;
1823
  abi_ulong msg_stime;
1824
  abi_ulong __unused1;
1825
  abi_ulong msg_rtime;
1826
  abi_ulong __unused2;
1827
  abi_ulong msg_ctime;
1828
  abi_ulong __unused3;
1829
  abi_ulong __msg_cbytes;
1830
  abi_ulong msg_qnum;
1831
  abi_ulong msg_qbytes;
1832
  abi_ulong msg_lspid;
1833
  abi_ulong msg_lrpid;
1834
  abi_ulong __unused4;
1835
  abi_ulong __unused5;
1836
};
1837

    
1838
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1839
                                               abi_ulong target_addr)
1840
{
1841
    struct target_msqid_ds *target_md;
1842

    
1843
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1844
        return -TARGET_EFAULT;
1845
    target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
1846
    host_md->msg_stime = tswapl(target_md->msg_stime);
1847
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
1848
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
1849
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1850
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
1851
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1852
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
1853
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1854
    unlock_user_struct(target_md, target_addr, 0);
1855
    return 0;
1856
}
1857

    
1858
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1859
                                               struct msqid_ds *host_md)
1860
{
1861
    struct target_msqid_ds *target_md;
1862

    
1863
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1864
        return -TARGET_EFAULT;
1865
    host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
1866
    target_md->msg_stime = tswapl(host_md->msg_stime);
1867
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
1868
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
1869
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1870
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
1871
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1872
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
1873
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1874
    unlock_user_struct(target_md, target_addr, 1);
1875
    return 0;
1876
}
1877

    
1878
static inline abi_long do_msgctl(int first, int second, abi_long ptr)
1879
{
1880
    struct msqid_ds dsarg;
1881
    int cmd = second&0xff;
1882
    abi_long ret = 0;
1883
    switch( cmd ) {
1884
    case IPC_STAT:
1885
    case IPC_SET:
1886
        target_to_host_msqid_ds(&dsarg,ptr);
1887
        ret = get_errno(msgctl(first, cmd, &dsarg));
1888
        host_to_target_msqid_ds(ptr,&dsarg);
1889
    default:
1890
        ret = get_errno(msgctl(first, cmd, &dsarg));
1891
    }
1892
    return ret;
1893
}
1894

    
1895
struct target_msgbuf {
1896
        abi_ulong mtype;
1897
        char        mtext[1];
1898
};
1899

    
1900
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1901
                                 unsigned int msgsz, int msgflg)
1902
{
1903
    struct target_msgbuf *target_mb;
1904
    struct msgbuf *host_mb;
1905
    abi_long ret = 0;
1906

    
1907
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1908
        return -TARGET_EFAULT;
1909
    host_mb = malloc(msgsz+sizeof(long));
1910
    host_mb->mtype = tswapl(target_mb->mtype);
1911
    memcpy(host_mb->mtext,target_mb->mtext,msgsz);
1912
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1913
    free(host_mb);
1914
    unlock_user_struct(target_mb, msgp, 0);
1915

    
1916
    return ret;
1917
}
1918

    
1919
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1920
                                 unsigned int msgsz, int msgtype,
1921
                                 int msgflg)
1922
{
1923
    struct target_msgbuf *target_mb;
1924
    char *target_mtext;
1925
    struct msgbuf *host_mb;
1926
    abi_long ret = 0;
1927

    
1928
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
1929
        return -TARGET_EFAULT;
1930
    host_mb = malloc(msgsz+sizeof(long));
1931
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
1932
    if (ret > 0) {
1933
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
1934
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
1935
        if (!target_mtext) {
1936
            ret = -TARGET_EFAULT;
1937
            goto end;
1938
        }
1939
            memcpy(target_mb->mtext, host_mb->mtext, ret);
1940
        unlock_user(target_mtext, target_mtext_addr, ret);
1941
    }
1942
    target_mb->mtype = tswapl(host_mb->mtype);
1943
    free(host_mb);
1944

    
1945
end:
1946
    if (target_mb)
1947
        unlock_user_struct(target_mb, msgp, 1);
1948
    return ret;
1949
}
1950

    
1951
/* ??? This only works with linear mappings.  */
1952
/* do_ipc() must return target values and target errnos. */
1953
static abi_long do_ipc(unsigned int call, int first,
1954
                       int second, int third,
1955
                       abi_long ptr, abi_long fifth)
1956
{
1957
    int version;
1958
    abi_long ret = 0;
1959
    struct shmid_ds shm_info;
1960
    int i;
1961

    
1962
    version = call >> 16;
1963
    call &= 0xffff;
1964

    
1965
    switch (call) {
1966
    case IPCOP_semop:
1967
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
1968
        break;
1969

    
1970
    case IPCOP_semget:
1971
        ret = get_errno(semget(first, second, third));
1972
        break;
1973

    
1974
    case IPCOP_semctl:
1975
        ret = do_semctl(first, second, third, ptr);
1976
        break;
1977

    
1978
    case IPCOP_semtimedop:
1979
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
1980
        ret = -TARGET_ENOSYS;
1981
        break;
1982

    
1983
        case IPCOP_msgget:
1984
                ret = get_errno(msgget(first, second));
1985
                break;
1986

    
1987
        case IPCOP_msgsnd:
1988
                ret = do_msgsnd(first, ptr, second, third);
1989
                break;
1990

    
1991
        case IPCOP_msgctl:
1992
                ret = do_msgctl(first, second, ptr);
1993
                break;
1994

    
1995
        case IPCOP_msgrcv:
1996
                {
1997
                      /* XXX: this code is not correct */
1998
                      struct ipc_kludge
1999
                      {
2000
                              void *__unbounded msgp;
2001
                              long int msgtyp;
2002
                      };
2003

    
2004
                      struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
2005
                      struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
2006

    
2007
                      ret = do_msgrcv(first, (long)msgp, second, 0, third);
2008

    
2009
                }
2010
                break;
2011

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

    
2057
    case IPCOP_shmget:
2058
        /* IPC_* flag values are the same on all linux platforms */
2059
        ret = get_errno(shmget(first, second, third));
2060
        break;
2061

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

    
2084
/* kernel structure types definitions */
2085
#define IFNAMSIZ        16
2086

    
2087
#define STRUCT(name, list...) STRUCT_ ## name,
2088
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2089
enum {
2090
#include "syscall_types.h"
2091
};
2092
#undef STRUCT
2093
#undef STRUCT_SPECIAL
2094

    
2095
#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2096
#define STRUCT_SPECIAL(name)
2097
#include "syscall_types.h"
2098
#undef STRUCT
2099
#undef STRUCT_SPECIAL
2100

    
2101
typedef struct IOCTLEntry {
2102
    unsigned int target_cmd;
2103
    unsigned int host_cmd;
2104
    const char *name;
2105
    int access;
2106
    const argtype arg_type[5];
2107
} IOCTLEntry;
2108

    
2109
#define IOC_R 0x0001
2110
#define IOC_W 0x0002
2111
#define IOC_RW (IOC_R | IOC_W)
2112

    
2113
#define MAX_STRUCT_SIZE 4096
2114

    
2115
IOCTLEntry ioctl_entries[] = {
2116
#define IOCTL(cmd, access, types...) \
2117
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2118
#include "ioctls.h"
2119
    { 0, 0, },
2120
};
2121

    
2122
/* ??? Implement proper locking for ioctls.  */
2123
/* do_ioctl() Must return target values and target errnos. */
2124
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2125
{
2126
    const IOCTLEntry *ie;
2127
    const argtype *arg_type;
2128
    abi_long ret;
2129
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2130
    int target_size;
2131
    void *argptr;
2132

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

    
2206
bitmask_transtbl iflag_tbl[] = {
2207
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2208
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2209
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2210
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2211
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2212
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2213
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2214
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2215
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2216
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2217
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2218
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2219
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2220
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2221
        { 0, 0, 0, 0 }
2222
};
2223

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

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

    
2287
bitmask_transtbl lflag_tbl[] = {
2288
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2289
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2290
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2291
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2292
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2293
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2294
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2295
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2296
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2297
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2298
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2299
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2300
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2301
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2302
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2303
        { 0, 0, 0, 0 }
2304
};
2305

    
2306
static void target_to_host_termios (void *dst, const void *src)
2307
{
2308
    struct host_termios *host = dst;
2309
    const struct target_termios *target = src;
2310

    
2311
    host->c_iflag =
2312
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2313
    host->c_oflag =
2314
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2315
    host->c_cflag =
2316
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2317
    host->c_lflag =
2318
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2319
    host->c_line = target->c_line;
2320

    
2321
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2322
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2323
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2324
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2325
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2326
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2327
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2328
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2329
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2330
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2331
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2332
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2333
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2334
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2335
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2336
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2337
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2338
}
2339

    
2340
static void host_to_target_termios (void *dst, const void *src)
2341
{
2342
    struct target_termios *target = dst;
2343
    const struct host_termios *host = src;
2344

    
2345
    target->c_iflag =
2346
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2347
    target->c_oflag =
2348
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2349
    target->c_cflag =
2350
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2351
    target->c_lflag =
2352
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2353
    target->c_line = host->c_line;
2354

    
2355
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2356
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2357
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2358
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2359
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2360
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2361
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2362
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2363
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2364
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2365
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2366
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2367
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2368
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2369
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2370
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2371
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2372
}
2373

    
2374
StructEntry struct_termios_def = {
2375
    .convert = { host_to_target_termios, target_to_host_termios },
2376
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2377
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2378
};
2379

    
2380
static bitmask_transtbl mmap_flags_tbl[] = {
2381
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2382
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2383
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2384
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2385
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2386
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2387
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2388
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2389
        { 0, 0, 0, 0 }
2390
};
2391

    
2392
static bitmask_transtbl fcntl_flags_tbl[] = {
2393
        { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
2394
        { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
2395
        { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
2396
        { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
2397
        { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
2398
        { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
2399
        { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
2400
        { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
2401
        { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
2402
        { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
2403
        { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2404
        { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
2405
        { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2406
#if defined(O_DIRECT)
2407
        { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
2408
#endif
2409
        { 0, 0, 0, 0 }
2410
};
2411

    
2412
#if defined(TARGET_I386)
2413

    
2414
/* NOTE: there is really one LDT for all the threads */
2415
uint8_t *ldt_table;
2416

    
2417
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2418
{
2419
    int size;
2420
    void *p;
2421

    
2422
    if (!ldt_table)
2423
        return 0;
2424
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2425
    if (size > bytecount)
2426
        size = bytecount;
2427
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
2428
    if (!p)
2429
        return -TARGET_EFAULT;
2430
    /* ??? Should this by byteswapped?  */
2431
    memcpy(p, ldt_table, size);
2432
    unlock_user(p, ptr, size);
2433
    return size;
2434
}
2435

    
2436
/* XXX: add locking support */
2437
static abi_long write_ldt(CPUX86State *env,
2438
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
2439
{
2440
    struct target_modify_ldt_ldt_s ldt_info;
2441
    struct target_modify_ldt_ldt_s *target_ldt_info;
2442
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2443
    int seg_not_present, useable, lm;
2444
    uint32_t *lp, entry_1, entry_2;
2445

    
2446
    if (bytecount != sizeof(ldt_info))
2447
        return -TARGET_EINVAL;
2448
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2449
        return -TARGET_EFAULT;
2450
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2451
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2452
    ldt_info.limit = tswap32(target_ldt_info->limit);
2453
    ldt_info.flags = tswap32(target_ldt_info->flags);
2454
    unlock_user_struct(target_ldt_info, ptr, 0);
2455

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

    
2485
    /* NOTE: same code as Linux kernel */
2486
    /* Allow LDTs to be cleared by the user. */
2487
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2488
        if (oldmode ||
2489
            (contents == 0                &&
2490
             read_exec_only == 1        &&
2491
             seg_32bit == 0                &&
2492
             limit_in_pages == 0        &&
2493
             seg_not_present == 1        &&
2494
             useable == 0 )) {
2495
            entry_1 = 0;
2496
            entry_2 = 0;
2497
            goto install;
2498
        }
2499
    }
2500

    
2501
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2502
        (ldt_info.limit & 0x0ffff);
2503
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2504
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2505
        (ldt_info.limit & 0xf0000) |
2506
        ((read_exec_only ^ 1) << 9) |
2507
        (contents << 10) |
2508
        ((seg_not_present ^ 1) << 15) |
2509
        (seg_32bit << 22) |
2510
        (limit_in_pages << 23) |
2511
        (lm << 21) |
2512
        0x7000;
2513
    if (!oldmode)
2514
        entry_2 |= (useable << 20);
2515

    
2516
    /* Install the new entry ...  */
2517
install:
2518
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2519
    lp[0] = tswap32(entry_1);
2520
    lp[1] = tswap32(entry_2);
2521
    return 0;
2522
}
2523

    
2524
/* specific and weird i386 syscalls */
2525
abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr, 
2526
                       unsigned long bytecount)
2527
{
2528
    abi_long ret;
2529

    
2530
    switch (func) {
2531
    case 0:
2532
        ret = read_ldt(ptr, bytecount);
2533
        break;
2534
    case 1:
2535
        ret = write_ldt(env, ptr, bytecount, 1);
2536
        break;
2537
    case 0x11:
2538
        ret = write_ldt(env, ptr, bytecount, 0);
2539
        break;
2540
    default:
2541
        ret = -TARGET_ENOSYS;
2542
        break;
2543
    }
2544
    return ret;
2545
}
2546

    
2547
abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2548
{
2549
    uint64_t *gdt_table = g2h(env->gdt.base);
2550
    struct target_modify_ldt_ldt_s ldt_info;
2551
    struct target_modify_ldt_ldt_s *target_ldt_info;
2552
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2553
    int seg_not_present, useable, lm;
2554
    uint32_t *lp, entry_1, entry_2;
2555
    int i;
2556

    
2557
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2558
    if (!target_ldt_info)
2559
        return -TARGET_EFAULT;
2560
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2561
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2562
    ldt_info.limit = tswap32(target_ldt_info->limit);
2563
    ldt_info.flags = tswap32(target_ldt_info->flags);
2564
    if (ldt_info.entry_number == -1) {
2565
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2566
            if (gdt_table[i] == 0) {
2567
                ldt_info.entry_number = i;
2568
                target_ldt_info->entry_number = tswap32(i);
2569
                break;
2570
            }
2571
        }
2572
    }
2573
    unlock_user_struct(target_ldt_info, ptr, 1);
2574

    
2575
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
2576
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2577
           return -TARGET_EINVAL;
2578
    seg_32bit = ldt_info.flags & 1;
2579
    contents = (ldt_info.flags >> 1) & 3;
2580
    read_exec_only = (ldt_info.flags >> 3) & 1;
2581
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2582
    seg_not_present = (ldt_info.flags >> 5) & 1;
2583
    useable = (ldt_info.flags >> 6) & 1;
2584
#ifdef TARGET_ABI32
2585
    lm = 0;
2586
#else
2587
    lm = (ldt_info.flags >> 7) & 1;
2588
#endif
2589

    
2590
    if (contents == 3) {
2591
        if (seg_not_present == 0)
2592
            return -TARGET_EINVAL;
2593
    }
2594

    
2595
    /* NOTE: same code as Linux kernel */
2596
    /* Allow LDTs to be cleared by the user. */
2597
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2598
        if ((contents == 0             &&
2599
             read_exec_only == 1       &&
2600
             seg_32bit == 0            &&
2601
             limit_in_pages == 0       &&
2602
             seg_not_present == 1      &&
2603
             useable == 0 )) {
2604
            entry_1 = 0;
2605
            entry_2 = 0;
2606
            goto install;
2607
        }
2608
    }
2609

    
2610
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2611
        (ldt_info.limit & 0x0ffff);
2612
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2613
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2614
        (ldt_info.limit & 0xf0000) |
2615
        ((read_exec_only ^ 1) << 9) |
2616
        (contents << 10) |
2617
        ((seg_not_present ^ 1) << 15) |
2618
        (seg_32bit << 22) |
2619
        (limit_in_pages << 23) |
2620
        (useable << 20) |
2621
        (lm << 21) |
2622
        0x7000;
2623

    
2624
    /* Install the new entry ...  */
2625
install:
2626
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2627
    lp[0] = tswap32(entry_1);
2628
    lp[1] = tswap32(entry_2);
2629
    return 0;
2630
}
2631

    
2632
abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2633
{
2634
    struct target_modify_ldt_ldt_s *target_ldt_info;
2635
    uint64_t *gdt_table = g2h(env->gdt.base);
2636
    uint32_t base_addr, limit, flags;
2637
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2638
    int seg_not_present, useable, lm;
2639
    uint32_t *lp, entry_1, entry_2;
2640

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

    
2679
#ifndef TARGET_ABI32
2680
abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2681
{
2682
    abi_long ret;
2683
    abi_ulong val;
2684
    int idx;
2685
    
2686
    switch(code) {
2687
    case TARGET_ARCH_SET_GS:
2688
    case TARGET_ARCH_SET_FS:
2689
        if (code == TARGET_ARCH_SET_GS)
2690
            idx = R_GS;
2691
        else
2692
            idx = R_FS;
2693
        cpu_x86_load_seg(env, idx, 0);
2694
        env->segs[idx].base = addr;
2695
        break;
2696
    case TARGET_ARCH_GET_GS:
2697
    case TARGET_ARCH_GET_FS:
2698
        if (code == TARGET_ARCH_GET_GS)
2699
            idx = R_GS;
2700
        else
2701
            idx = R_FS;
2702
        val = env->segs[idx].base;
2703
        if (put_user(val, addr, abi_ulong))
2704
            return -TARGET_EFAULT;
2705
        break;
2706
    default:
2707
        ret = -TARGET_EINVAL;
2708
        break;
2709
    }
2710
    return 0;
2711
}
2712
#endif
2713

    
2714
#endif /* defined(TARGET_I386) */
2715

    
2716
#if defined(USE_NPTL)
2717

    
2718
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2719

    
2720
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2721
typedef struct {
2722
    CPUState *env;
2723
    pthread_mutex_t mutex;
2724
    pthread_cond_t cond;
2725
    pthread_t thread;
2726
    uint32_t tid;
2727
    abi_ulong child_tidptr;
2728
    abi_ulong parent_tidptr;
2729
    sigset_t sigmask;
2730
} new_thread_info;
2731

    
2732
static void *clone_func(void *arg)
2733
{
2734
    new_thread_info *info = arg;
2735
    CPUState *env;
2736

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

    
2762
static int clone_func(void *arg)
2763
{
2764
    CPUState *env = arg;
2765
    cpu_loop(env);
2766
    /* never exits */
2767
    return 0;
2768
}
2769
#endif
2770

    
2771
/* do_fork() Must return host values and target errnos (unlike most
2772
   do_*() functions). */
2773
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2774
                   abi_ulong parent_tidptr, target_ulong newtls,
2775
                   abi_ulong child_tidptr)
2776
{
2777
    int ret;
2778
    TaskState *ts;
2779
    uint8_t *new_stack;
2780
    CPUState *new_env;
2781
#if defined(USE_NPTL)
2782
    unsigned int nptl_flags;
2783
    sigset_t sigmask;
2784
#endif
2785

    
2786
    if (flags & CLONE_VM) {
2787
#if defined(USE_NPTL)
2788
        new_thread_info info;
2789
        pthread_attr_t attr;
2790
#endif
2791
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2792
        init_task_state(ts);
2793
        new_stack = ts->stack;
2794
        /* we create a new CPU instance. */
2795
        new_env = cpu_copy(env);
2796
        /* Init regs that differ from the parent.  */
2797
        cpu_clone_regs(new_env, newsp);
2798
        new_env->opaque = ts;
2799
#if defined(USE_NPTL)
2800
        nptl_flags = flags;
2801
        flags &= ~CLONE_NPTL_FLAGS2;
2802

    
2803
        /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2804
        if (nptl_flags & CLONE_SETTLS)
2805
            cpu_set_tls (new_env, newtls);
2806

    
2807
        /* Grab a mutex so that thread setup appears atomic.  */
2808
        pthread_mutex_lock(&clone_lock);
2809

    
2810
        memset(&info, 0, sizeof(info));
2811
        pthread_mutex_init(&info.mutex, NULL);
2812
        pthread_mutex_lock(&info.mutex);
2813
        pthread_cond_init(&info.cond, NULL);
2814
        info.env = new_env;
2815
        if (nptl_flags & CLONE_CHILD_SETTID)
2816
            info.child_tidptr = child_tidptr;
2817
        if (nptl_flags & CLONE_PARENT_SETTID)
2818
            info.parent_tidptr = parent_tidptr;
2819

    
2820
        ret = pthread_attr_init(&attr);
2821
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
2822
        /* It is not safe to deliver signals until the child has finished
2823
           initializing, so temporarily block all signals.  */
2824
        sigfillset(&sigmask);
2825
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
2826

    
2827
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
2828

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

    
2891
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2892
{
2893
    struct flock fl;
2894
    struct target_flock *target_fl;
2895
    struct flock64 fl64;
2896
    struct target_flock64 *target_fl64;
2897
    abi_long ret;
2898

    
2899
    switch(cmd) {
2900
    case TARGET_F_GETLK:
2901
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2902
            return -TARGET_EFAULT;
2903
        fl.l_type = tswap16(target_fl->l_type);
2904
        fl.l_whence = tswap16(target_fl->l_whence);
2905
        fl.l_start = tswapl(target_fl->l_start);
2906
        fl.l_len = tswapl(target_fl->l_len);
2907
        fl.l_pid = tswapl(target_fl->l_pid);
2908
        unlock_user_struct(target_fl, arg, 0);
2909
        ret = get_errno(fcntl(fd, cmd, &fl));
2910
        if (ret == 0) {
2911
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
2912
                return -TARGET_EFAULT;
2913
            target_fl->l_type = tswap16(fl.l_type);
2914
            target_fl->l_whence = tswap16(fl.l_whence);
2915
            target_fl->l_start = tswapl(fl.l_start);
2916
            target_fl->l_len = tswapl(fl.l_len);
2917
            target_fl->l_pid = tswapl(fl.l_pid);
2918
            unlock_user_struct(target_fl, arg, 1);
2919
        }
2920
        break;
2921

    
2922
    case TARGET_F_SETLK:
2923
    case TARGET_F_SETLKW:
2924
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2925
            return -TARGET_EFAULT;
2926
        fl.l_type = tswap16(target_fl->l_type);
2927
        fl.l_whence = tswap16(target_fl->l_whence);
2928
        fl.l_start = tswapl(target_fl->l_start);
2929
        fl.l_len = tswapl(target_fl->l_len);
2930
        fl.l_pid = tswapl(target_fl->l_pid);
2931
        unlock_user_struct(target_fl, arg, 0);
2932
        ret = get_errno(fcntl(fd, cmd, &fl));
2933
        break;
2934

    
2935
    case TARGET_F_GETLK64:
2936
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2937
            return -TARGET_EFAULT;
2938
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2939
        fl64.l_whence = tswap16(target_fl64->l_whence);
2940
        fl64.l_start = tswapl(target_fl64->l_start);
2941
        fl64.l_len = tswapl(target_fl64->l_len);
2942
        fl64.l_pid = tswap16(target_fl64->l_pid);
2943
        unlock_user_struct(target_fl64, arg, 0);
2944
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2945
        if (ret == 0) {
2946
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
2947
                return -TARGET_EFAULT;
2948
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
2949
            target_fl64->l_whence = tswap16(fl64.l_whence);
2950
            target_fl64->l_start = tswapl(fl64.l_start);
2951
            target_fl64->l_len = tswapl(fl64.l_len);
2952
            target_fl64->l_pid = tswapl(fl64.l_pid);
2953
            unlock_user_struct(target_fl64, arg, 1);
2954
        }
2955
        break;
2956
    case TARGET_F_SETLK64:
2957
    case TARGET_F_SETLKW64:
2958
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2959
            return -TARGET_EFAULT;
2960
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2961
        fl64.l_whence = tswap16(target_fl64->l_whence);
2962
        fl64.l_start = tswapl(target_fl64->l_start);
2963
        fl64.l_len = tswapl(target_fl64->l_len);
2964
        fl64.l_pid = tswap16(target_fl64->l_pid);
2965
        unlock_user_struct(target_fl64, arg, 0);
2966
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2967
        break;
2968

    
2969
    case F_GETFL:
2970
        ret = get_errno(fcntl(fd, cmd, arg));
2971
        if (ret >= 0) {
2972
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
2973
        }
2974
        break;
2975

    
2976
    case F_SETFL:
2977
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
2978
        break;
2979

    
2980
    default:
2981
        ret = get_errno(fcntl(fd, cmd, arg));
2982
        break;
2983
    }
2984
    return ret;
2985
}
2986

    
2987
#ifdef USE_UID16
2988

    
2989
static inline int high2lowuid(int uid)
2990
{
2991
    if (uid > 65535)
2992
        return 65534;
2993
    else
2994
        return uid;
2995
}
2996

    
2997
static inline int high2lowgid(int gid)
2998
{
2999
    if (gid > 65535)
3000
        return 65534;
3001
    else
3002
        return gid;
3003
}
3004

    
3005
static inline int low2highuid(int uid)
3006
{
3007
    if ((int16_t)uid == -1)
3008
        return -1;
3009
    else
3010
        return uid;
3011
}
3012

    
3013
static inline int low2highgid(int gid)
3014
{
3015
    if ((int16_t)gid == -1)
3016
        return -1;
3017
    else
3018
        return gid;
3019
}
3020

    
3021
#endif /* USE_UID16 */
3022

    
3023
void syscall_init(void)
3024
{
3025
    IOCTLEntry *ie;
3026
    const argtype *arg_type;
3027
    int size;
3028
    int i;
3029

    
3030
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3031
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3032
#include "syscall_types.h"
3033
#undef STRUCT
3034
#undef STRUCT_SPECIAL
3035

    
3036
    /* we patch the ioctl size if necessary. We rely on the fact that
3037
       no ioctl has all the bits at '1' in the size field */
3038
    ie = ioctl_entries;
3039
    while (ie->target_cmd != 0) {
3040
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3041
            TARGET_IOC_SIZEMASK) {
3042
            arg_type = ie->arg_type;
3043
            if (arg_type[0] != TYPE_PTR) {
3044
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3045
                        ie->target_cmd);
3046
                exit(1);
3047
            }
3048
            arg_type++;
3049
            size = thunk_type_size(arg_type, 0);
3050
            ie->target_cmd = (ie->target_cmd &
3051
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3052
                (size << TARGET_IOC_SIZESHIFT);
3053
        }
3054

    
3055
        /* Build target_to_host_errno_table[] table from
3056
         * host_to_target_errno_table[]. */
3057
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3058
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3059

    
3060
        /* automatic consistency check if same arch */
3061
#if defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)
3062
        if (ie->target_cmd != ie->host_cmd) {
3063
            fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",
3064
                    ie->target_cmd, ie->host_cmd);
3065
        }
3066
#endif
3067
        ie++;
3068
    }
3069
}
3070

    
3071
#if TARGET_ABI_BITS == 32
3072
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3073
{
3074
#ifdef TARGET_WORDS_BIGENDIAN
3075
    return ((uint64_t)word0 << 32) | word1;
3076
#else
3077
    return ((uint64_t)word1 << 32) | word0;
3078
#endif
3079
}
3080
#else /* TARGET_ABI_BITS == 32 */
3081
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3082
{
3083
    return word0;
3084
}
3085
#endif /* TARGET_ABI_BITS != 32 */
3086

    
3087
#ifdef TARGET_NR_truncate64
3088
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3089
                                         abi_long arg2,
3090
                                         abi_long arg3,
3091
                                         abi_long arg4)
3092
{
3093
#ifdef TARGET_ARM
3094
    if (((CPUARMState *)cpu_env)->eabi)
3095
      {
3096
        arg2 = arg3;
3097
        arg3 = arg4;
3098
      }
3099
#endif
3100
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3101
}
3102
#endif
3103

    
3104
#ifdef TARGET_NR_ftruncate64
3105
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3106
                                          abi_long arg2,
3107
                                          abi_long arg3,
3108
                                          abi_long arg4)
3109
{
3110
#ifdef TARGET_ARM
3111
    if (((CPUARMState *)cpu_env)->eabi)
3112
      {
3113
        arg2 = arg3;
3114
        arg3 = arg4;
3115
      }
3116
#endif
3117
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3118
}
3119
#endif
3120

    
3121
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3122
                                               abi_ulong target_addr)
3123
{
3124
    struct target_timespec *target_ts;
3125

    
3126
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3127
        return -TARGET_EFAULT;
3128
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3129
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3130
    unlock_user_struct(target_ts, target_addr, 0);
3131
    return 0;
3132
}
3133

    
3134
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3135
                                               struct timespec *host_ts)
3136
{
3137
    struct target_timespec *target_ts;
3138

    
3139
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3140
        return -TARGET_EFAULT;
3141
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3142
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3143
    unlock_user_struct(target_ts, target_addr, 1);
3144
    return 0;
3145
}
3146

    
3147
#if defined(USE_NPTL)
3148
/* ??? Using host futex calls even when target atomic operations
3149
   are not really atomic probably breaks things.  However implementing
3150
   futexes locally would make futexes shared between multiple processes
3151
   tricky.  However they're probably useless because guest atomic
3152
   operations won't work either.  */
3153
int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3154
             target_ulong uaddr2, int val3)
3155
{
3156
    struct timespec ts, *pts;
3157

    
3158
    /* ??? We assume FUTEX_* constants are the same on both host
3159
       and target.  */
3160
    switch (op) {
3161
    case FUTEX_WAIT:
3162
        if (timeout) {
3163
            pts = &ts;
3164
            target_to_host_timespec(pts, timeout);
3165
        } else {
3166
            pts = NULL;
3167
        }
3168
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3169
                         pts, NULL, 0));
3170
    case FUTEX_WAKE:
3171
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3172
    case FUTEX_FD:
3173
        return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3174
    case FUTEX_REQUEUE:
3175
        return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3176
                         NULL, g2h(uaddr2), 0));
3177
    case FUTEX_CMP_REQUEUE:
3178
        return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3179
                         NULL, g2h(uaddr2), tswap32(val3)));
3180
    default:
3181
        return -TARGET_ENOSYS;
3182
    }
3183
}
3184
#endif
3185

    
3186
int get_osversion(void)
3187
{
3188
    static int osversion;
3189
    struct new_utsname buf;
3190
    const char *s;
3191
    int i, n, tmp;
3192
    if (osversion)
3193
        return osversion;
3194
    if (qemu_uname_release && *qemu_uname_release) {
3195
        s = qemu_uname_release;
3196
    } else {
3197
        if (sys_uname(&buf))
3198
            return 0;
3199
        s = buf.release;
3200
    }
3201
    tmp = 0;
3202
    for (i = 0; i < 3; i++) {
3203
        n = 0;
3204
        while (*s >= '0' && *s <= '9') {
3205
            n *= 10;
3206
            n += *s - '0';
3207
            s++;
3208
        }
3209
        tmp = (tmp << 8) + n;
3210
        if (*s == '.')
3211
            s++;
3212
    }
3213
    osversion = tmp;
3214
    return osversion;
3215
}
3216

    
3217
/* do_syscall() should always have a single exit point at the end so
3218
   that actions, such as logging of syscall results, can be performed.
3219
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3220
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3221
                    abi_long arg2, abi_long arg3, abi_long arg4,
3222
                    abi_long arg5, abi_long arg6)
3223
{
3224
    abi_long ret;
3225
    struct stat st;
3226
    struct statfs stfs;
3227
    void *p;
3228

    
3229
#ifdef DEBUG
3230
    gemu_log("syscall %d", num);
3231
#endif
3232
    if(do_strace)
3233
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3234

    
3235
    switch(num) {
3236
    case TARGET_NR_exit:
3237
#ifdef HAVE_GPROF
3238
        _mcleanup();
3239
#endif
3240
        gdb_exit(cpu_env, arg1);
3241
        /* XXX: should free thread stack and CPU env */
3242
        _exit(arg1);
3243
        ret = 0; /* avoid warning */
3244
        break;
3245
    case TARGET_NR_read:
3246
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3247
            goto efault;
3248
        ret = get_errno(read(arg1, p, arg3));
3249
        unlock_user(p, arg2, ret);
3250
        break;
3251
    case TARGET_NR_write:
3252
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3253
            goto efault;
3254
        ret = get_errno(write(arg1, p, arg3));
3255
        unlock_user(p, arg2, 0);
3256
        break;
3257
    case TARGET_NR_open:
3258
        if (!(p = lock_user_string(arg1)))
3259
            goto efault;
3260
        ret = get_errno(open(path(p),
3261
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
3262
                             arg3));
3263
        unlock_user(p, arg1, 0);
3264
        break;
3265
#if defined(TARGET_NR_openat) && defined(__NR_openat)
3266
    case TARGET_NR_openat:
3267
        if (!(p = lock_user_string(arg2)))
3268
            goto efault;
3269
        ret = get_errno(sys_openat(arg1,
3270
                                   path(p),
3271
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
3272
                                   arg4));
3273
        unlock_user(p, arg2, 0);
3274
        break;
3275
#endif
3276
    case TARGET_NR_close:
3277
        ret = get_errno(close(arg1));
3278
        break;
3279
    case TARGET_NR_brk:
3280
        ret = do_brk(arg1);
3281
        break;
3282
    case TARGET_NR_fork:
3283
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3284
        break;
3285
#ifdef TARGET_NR_waitpid
3286
    case TARGET_NR_waitpid:
3287
        {
3288
            int status;
3289
            ret = get_errno(waitpid(arg1, &status, arg3));
3290
            if (!is_error(ret) && arg2
3291
                && put_user_s32(status, arg2))
3292
                goto efault;
3293
        }
3294
        break;
3295
#endif
3296
#ifdef TARGET_NR_waitid
3297
    case TARGET_NR_waitid:
3298
        {
3299
            siginfo_t info;
3300
            info.si_pid = 0;
3301
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
3302
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
3303
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3304
                    goto efault;
3305
                host_to_target_siginfo(p, &info);
3306
                unlock_user(p, arg3, sizeof(target_siginfo_t));
3307
            }
3308
        }
3309
        break;
3310
#endif
3311
#ifdef TARGET_NR_creat /* not on alpha */
3312
    case TARGET_NR_creat:
3313
        if (!(p = lock_user_string(arg1)))
3314
            goto efault;
3315
        ret = get_errno(creat(p, arg2));
3316
        unlock_user(p, arg1, 0);
3317
        break;
3318
#endif
3319
    case TARGET_NR_link:
3320
        {
3321
            void * p2;
3322
            p = lock_user_string(arg1);
3323
            p2 = lock_user_string(arg2);
3324
            if (!p || !p2)
3325
                ret = -TARGET_EFAULT;
3326
            else
3327
                ret = get_errno(link(p, p2));
3328
            unlock_user(p2, arg2, 0);
3329
            unlock_user(p, arg1, 0);
3330
        }
3331
        break;
3332
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3333
    case TARGET_NR_linkat:
3334
        {
3335
            void * p2 = NULL;
3336
            if (!arg2 || !arg4)
3337
                goto efault;
3338
            p  = lock_user_string(arg2);
3339
            p2 = lock_user_string(arg4);
3340
            if (!p || !p2)
3341
                ret = -TARGET_EFAULT;
3342
            else
3343
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3344
            unlock_user(p, arg2, 0);
3345
            unlock_user(p2, arg4, 0);
3346
        }
3347
        break;
3348
#endif
3349
    case TARGET_NR_unlink:
3350
        if (!(p = lock_user_string(arg1)))
3351
            goto efault;
3352
        ret = get_errno(unlink(p));
3353
        unlock_user(p, arg1, 0);
3354
        break;
3355
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3356
    case TARGET_NR_unlinkat:
3357
        if (!(p = lock_user_string(arg2)))
3358
            goto efault;
3359
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
3360
        unlock_user(p, arg2, 0);
3361
        break;
3362
#endif
3363
    case TARGET_NR_execve:
3364
        {
3365
            char **argp, **envp;
3366
            int argc, envc;
3367
            abi_ulong gp;
3368
            abi_ulong guest_argp;
3369
            abi_ulong guest_envp;
3370
            abi_ulong addr;
3371
            char **q;
3372

    
3373
            argc = 0;
3374
            guest_argp = arg2;
3375
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3376
                if (get_user_ual(addr, gp))
3377
                    goto efault;
3378
                if (!addr)
3379
                    break;
3380
                argc++;
3381
            }
3382
            envc = 0;
3383
            guest_envp = arg3;
3384
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3385
                if (get_user_ual(addr, gp))
3386
                    goto efault;
3387
                if (!addr)
3388
                    break;
3389
                envc++;
3390
            }
3391

    
3392
            argp = alloca((argc + 1) * sizeof(void *));
3393
            envp = alloca((envc + 1) * sizeof(void *));
3394

    
3395
            for (gp = guest_argp, q = argp; gp;
3396
                  gp += sizeof(abi_ulong), q++) {
3397
                if (get_user_ual(addr, gp))
3398
                    goto execve_efault;
3399
                if (!addr)
3400
                    break;
3401
                if (!(*q = lock_user_string(addr)))
3402
                    goto execve_efault;
3403
            }
3404
            *q = NULL;
3405

    
3406
            for (gp = guest_envp, q = envp; gp;
3407
                  gp += sizeof(abi_ulong), q++) {
3408
                if (get_user_ual(addr, gp))
3409
                    goto execve_efault;
3410
                if (!addr)
3411
                    break;
3412
                if (!(*q = lock_user_string(addr)))
3413
                    goto execve_efault;
3414
            }
3415
            *q = NULL;
3416

    
3417
            if (!(p = lock_user_string(arg1)))
3418
                goto execve_efault;
3419
            ret = get_errno(execve(p, argp, envp));
3420
            unlock_user(p, arg1, 0);
3421

    
3422
            goto execve_end;
3423

    
3424
        execve_efault:
3425
            ret = -TARGET_EFAULT;
3426

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

    
3824
            if (arg2) {
3825
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3826
                    goto efault;
3827
                act._sa_handler = old_act->_sa_handler;
3828
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3829
                act.sa_flags = old_act->sa_flags;
3830
                unlock_user_struct(old_act, arg2, 0);
3831
                pact = &act;
3832
            } else {
3833
                pact = NULL;
3834
            }
3835

    
3836
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3837

    
3838
            if (!is_error(ret) && arg3) {
3839
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3840
                    goto efault;
3841
                old_act->_sa_handler = oact._sa_handler;
3842
                old_act->sa_flags = oact.sa_flags;
3843
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
3844
                old_act->sa_mask.sig[1] = 0;
3845
                old_act->sa_mask.sig[2] = 0;
3846
                old_act->sa_mask.sig[3] = 0;
3847
                unlock_user_struct(old_act, arg3, 1);
3848
            }
3849
#endif
3850
        }
3851
        break;
3852
#endif
3853
    case TARGET_NR_rt_sigaction:
3854
        {
3855
            struct target_sigaction *act;
3856
            struct target_sigaction *oact;
3857

    
3858
            if (arg2) {
3859
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
3860
                    goto efault;
3861
            } else
3862
                act = NULL;
3863
            if (arg3) {
3864
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
3865
                    ret = -TARGET_EFAULT;
3866
                    goto rt_sigaction_fail;
3867
                }
3868
            } else
3869
                oact = NULL;
3870
            ret = get_errno(do_sigaction(arg1, act, oact));
3871
        rt_sigaction_fail:
3872
            if (act)
3873
                unlock_user_struct(act, arg2, 0);
3874
            if (oact)
3875
                unlock_user_struct(oact, arg3, 1);
3876
        }
3877
        break;
3878
#ifdef TARGET_NR_sgetmask /* not on alpha */
3879
    case TARGET_NR_sgetmask:
3880
        {
3881
            sigset_t cur_set;
3882
            abi_ulong target_set;
3883
            sigprocmask(0, NULL, &cur_set);
3884
            host_to_target_old_sigset(&target_set, &cur_set);
3885
            ret = target_set;
3886
        }
3887
        break;
3888
#endif
3889
#ifdef TARGET_NR_ssetmask /* not on alpha */
3890
    case TARGET_NR_ssetmask:
3891
        {
3892
            sigset_t set, oset, cur_set;
3893
            abi_ulong target_set = arg1;
3894
            sigprocmask(0, NULL, &cur_set);
3895
            target_to_host_old_sigset(&set, &target_set);
3896
            sigorset(&set, &set, &cur_set);
3897
            sigprocmask(SIG_SETMASK, &set, &oset);
3898
            host_to_target_old_sigset(&target_set, &oset);
3899
            ret = target_set;
3900
        }
3901
        break;
3902
#endif
3903
#ifdef TARGET_NR_sigprocmask
3904
    case TARGET_NR_sigprocmask:
3905
        {
3906
            int how = arg1;
3907
            sigset_t set, oldset, *set_ptr;
3908

    
3909
            if (arg2) {
3910
                switch(how) {
3911
                case TARGET_SIG_BLOCK:
3912
                    how = SIG_BLOCK;
3913
                    break;
3914
                case TARGET_SIG_UNBLOCK:
3915
                    how = SIG_UNBLOCK;
3916
                    break;
3917
                case TARGET_SIG_SETMASK:
3918
                    how = SIG_SETMASK;
3919
                    break;
3920
                default:
3921
                    ret = -TARGET_EINVAL;
3922
                    goto fail;
3923
                }
3924
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3925
                    goto efault;
3926
                target_to_host_old_sigset(&set, p);
3927
                unlock_user(p, arg2, 0);
3928
                set_ptr = &set;
3929
            } else {
3930
                how = 0;
3931
                set_ptr = NULL;
3932
            }
3933
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
3934
            if (!is_error(ret) && arg3) {
3935
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
3936
                    goto efault;
3937
                host_to_target_old_sigset(p, &oldset);
3938
                unlock_user(p, arg3, sizeof(target_sigset_t));
3939
            }
3940
        }
3941
        break;
3942
#endif
3943
    case TARGET_NR_rt_sigprocmask:
3944
        {
3945
            int how = arg1;
3946
            sigset_t set, oldset, *set_ptr;
3947

    
3948
            if (arg2) {
3949
                switch(how) {
3950
                case TARGET_SIG_BLOCK:
3951
                    how = SIG_BLOCK;
3952
                    break;
3953
                case TARGET_SIG_UNBLOCK:
3954
                    how = SIG_UNBLOCK;
3955
                    break;
3956
                case TARGET_SIG_SETMASK:
3957
                    how = SIG_SETMASK;
3958
                    break;
3959
                default:
3960
                    ret = -TARGET_EINVAL;
3961
                    goto fail;
3962
                }
3963
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3964
                    goto efault;
3965
                target_to_host_sigset(&set, p);
3966
                unlock_user(p, arg2, 0);
3967
                set_ptr = &set;
3968
            } else {
3969
                how = 0;
3970
                set_ptr = NULL;
3971
            }
3972
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
3973
            if (!is_error(ret) && arg3) {
3974
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
3975
                    goto efault;
3976
                host_to_target_sigset(p, &oldset);
3977
                unlock_user(p, arg3, sizeof(target_sigset_t));
3978
            }
3979
        }
3980
        break;
3981
#ifdef TARGET_NR_sigpending
3982
    case TARGET_NR_sigpending:
3983
        {
3984
            sigset_t set;
3985
            ret = get_errno(sigpending(&set));
3986
            if (!is_error(ret)) {
3987
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
3988
                    goto efault;
3989
                host_to_target_old_sigset(p, &set);
3990
                unlock_user(p, arg1, sizeof(target_sigset_t));
3991
            }
3992
        }
3993
        break;
3994
#endif
3995
    case TARGET_NR_rt_sigpending:
3996
        {
3997
            sigset_t set;
3998
            ret = get_errno(sigpending(&set));
3999
            if (!is_error(ret)) {
4000
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4001
                    goto efault;
4002
                host_to_target_sigset(p, &set);
4003
                unlock_user(p, arg1, sizeof(target_sigset_t));
4004
            }
4005
        }
4006
        break;
4007
#ifdef TARGET_NR_sigsuspend
4008
    case TARGET_NR_sigsuspend:
4009
        {
4010
            sigset_t set;
4011
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4012
                goto efault;
4013
            target_to_host_old_sigset(&set, p);
4014
            unlock_user(p, arg1, 0);
4015
            ret = get_errno(sigsuspend(&set));
4016
        }
4017
        break;
4018
#endif
4019
    case TARGET_NR_rt_sigsuspend:
4020
        {
4021
            sigset_t set;
4022
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4023
                goto efault;
4024
            target_to_host_sigset(&set, p);
4025
            unlock_user(p, arg1, 0);
4026
            ret = get_errno(sigsuspend(&set));
4027
        }
4028
        break;
4029
    case TARGET_NR_rt_sigtimedwait:
4030
        {
4031
            sigset_t set;
4032
            struct timespec uts, *puts;
4033
            siginfo_t uinfo;
4034

    
4035
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4036
                goto efault;
4037
            target_to_host_sigset(&set, p);
4038
            unlock_user(p, arg1, 0);
4039
            if (arg3) {
4040
                puts = &uts;
4041
                target_to_host_timespec(puts, arg3);
4042
            } else {
4043
                puts = NULL;
4044
            }
4045
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4046
            if (!is_error(ret) && arg2) {
4047
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4048
                    goto efault;
4049
                host_to_target_siginfo(p, &uinfo);
4050
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4051
            }
4052
        }
4053
        break;
4054
    case TARGET_NR_rt_sigqueueinfo:
4055
        {
4056
            siginfo_t uinfo;
4057
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4058
                goto efault;
4059
            target_to_host_siginfo(&uinfo, p);
4060
            unlock_user(p, arg1, 0);
4061
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4062
        }
4063
        break;
4064
#ifdef TARGET_NR_sigreturn
4065
    case TARGET_NR_sigreturn:
4066
        /* NOTE: ret is eax, so not transcoding must be done */
4067
        ret = do_sigreturn(cpu_env);
4068
        break;
4069
#endif
4070
    case TARGET_NR_rt_sigreturn:
4071
        /* NOTE: ret is eax, so not transcoding must be done */
4072
        ret = do_rt_sigreturn(cpu_env);
4073
        break;
4074
    case TARGET_NR_sethostname:
4075
        if (!(p = lock_user_string(arg1)))
4076
            goto efault;
4077
        ret = get_errno(sethostname(p, arg2));
4078
        unlock_user(p, arg1, 0);
4079
        break;
4080
    case TARGET_NR_setrlimit:
4081
        {
4082
            /* XXX: convert resource ? */
4083
            int resource = arg1;
4084
            struct target_rlimit *target_rlim;
4085
            struct rlimit rlim;
4086
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4087
                goto efault;
4088
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4089
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4090
            unlock_user_struct(target_rlim, arg2, 0);
4091
            ret = get_errno(setrlimit(resource, &rlim));
4092
        }
4093
        break;
4094
    case TARGET_NR_getrlimit:
4095
        {
4096
            /* XXX: convert resource ? */
4097
            int resource = arg1;
4098
            struct target_rlimit *target_rlim;
4099
            struct rlimit rlim;
4100

    
4101
            ret = get_errno(getrlimit(resource, &rlim));
4102
            if (!is_error(ret)) {
4103
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4104
                    goto efault;
4105
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4106
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4107
                unlock_user_struct(target_rlim, arg2, 1);
4108
            }
4109
        }
4110
        break;
4111
    case TARGET_NR_getrusage:
4112
        {
4113
            struct rusage rusage;
4114
            ret = get_errno(getrusage(arg1, &rusage));
4115
            if (!is_error(ret)) {
4116
                host_to_target_rusage(arg2, &rusage);
4117
            }
4118
        }
4119
        break;
4120
    case TARGET_NR_gettimeofday:
4121
        {
4122
            struct timeval tv;
4123
            ret = get_errno(gettimeofday(&tv, NULL));
4124
            if (!is_error(ret)) {
4125
                if (copy_to_user_timeval(arg1, &tv))
4126
                    goto efault;
4127
            }
4128
        }
4129
        break;
4130
    case TARGET_NR_settimeofday:
4131
        {
4132
            struct timeval tv;
4133
            if (copy_from_user_timeval(&tv, arg1))
4134
                goto efault;
4135
            ret = get_errno(settimeofday(&tv, NULL));
4136
        }
4137
        break;
4138
#ifdef TARGET_NR_select
4139
    case TARGET_NR_select:
4140
        {
4141
            struct target_sel_arg_struct *sel;
4142
            abi_ulong inp, outp, exp, tvp;
4143
            long nsel;
4144

    
4145
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4146
                goto efault;
4147
            nsel = tswapl(sel->n);
4148
            inp = tswapl(sel->inp);
4149
            outp = tswapl(sel->outp);
4150
            exp = tswapl(sel->exp);
4151
            tvp = tswapl(sel->tvp);
4152
            unlock_user_struct(sel, arg1, 0);
4153
            ret = do_select(nsel, inp, outp, exp, tvp);
4154
        }
4155
        break;
4156
#endif
4157
    case TARGET_NR_symlink:
4158
        {
4159
            void *p2;
4160
            p = lock_user_string(arg1);
4161
            p2 = lock_user_string(arg2);
4162
            if (!p || !p2)
4163
                ret = -TARGET_EFAULT;
4164
            else
4165
                ret = get_errno(symlink(p, p2));
4166
            unlock_user(p2, arg2, 0);
4167
            unlock_user(p, arg1, 0);
4168
        }
4169
        break;
4170
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4171
    case TARGET_NR_symlinkat:
4172
        {
4173
            void *p2;
4174
            p  = lock_user_string(arg1);
4175
            p2 = lock_user_string(arg3);
4176
            if (!p || !p2)
4177
                ret = -TARGET_EFAULT;
4178
            else
4179
                ret = get_errno(sys_symlinkat(p, arg2, p2));
4180
            unlock_user(p2, arg3, 0);
4181
            unlock_user(p, arg1, 0);
4182
        }
4183
        break;
4184
#endif
4185
#ifdef TARGET_NR_oldlstat
4186
    case TARGET_NR_oldlstat:
4187
        goto unimplemented;
4188
#endif
4189
    case TARGET_NR_readlink:
4190
        {
4191
            void *p2;
4192
            p = lock_user_string(arg1);
4193
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4194
            if (!p || !p2)
4195
                ret = -TARGET_EFAULT;
4196
            else
4197
                ret = get_errno(readlink(path(p), p2, arg3));
4198
            unlock_user(p2, arg2, ret);
4199
            unlock_user(p, arg1, 0);
4200
        }
4201
        break;
4202
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4203
    case TARGET_NR_readlinkat:
4204
        {
4205
            void *p2;
4206
            p  = lock_user_string(arg2);
4207
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4208
            if (!p || !p2)
4209
                ret = -TARGET_EFAULT;
4210
            else
4211
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4212
            unlock_user(p2, arg3, ret);
4213
            unlock_user(p, arg2, 0);
4214
        }
4215
        break;
4216
#endif
4217
#ifdef TARGET_NR_uselib
4218
    case TARGET_NR_uselib:
4219
        goto unimplemented;
4220
#endif
4221
#ifdef TARGET_NR_swapon
4222
    case TARGET_NR_swapon:
4223
        if (!(p = lock_user_string(arg1)))
4224
            goto efault;
4225
        ret = get_errno(swapon(p, arg2));
4226
        unlock_user(p, arg1, 0);
4227
        break;
4228
#endif
4229
    case TARGET_NR_reboot:
4230
        goto unimplemented;
4231
#ifdef TARGET_NR_readdir
4232
    case TARGET_NR_readdir:
4233
        goto unimplemented;
4234
#endif
4235
#ifdef TARGET_NR_mmap
4236
    case TARGET_NR_mmap:
4237
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4238
        {
4239
            abi_ulong *v;
4240
            abi_ulong v1, v2, v3, v4, v5, v6;
4241
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4242
                goto efault;
4243
            v1 = tswapl(v[0]);
4244
            v2 = tswapl(v[1]);
4245
            v3 = tswapl(v[2]);
4246
            v4 = tswapl(v[3]);
4247
            v5 = tswapl(v[4]);
4248
            v6 = tswapl(v[5]);
4249
            unlock_user(v, arg1, 0);
4250
            ret = get_errno(target_mmap(v1, v2, v3,
4251
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
4252
                                        v5, v6));
4253
        }
4254
#else
4255
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4256
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4257
                                    arg5,
4258
                                    arg6));
4259
#endif
4260
        break;
4261
#endif
4262
#ifdef TARGET_NR_mmap2
4263
    case TARGET_NR_mmap2:
4264
#ifndef MMAP_SHIFT
4265
#define MMAP_SHIFT 12
4266
#endif
4267
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4268
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4269
                                    arg5,
4270
                                    arg6 << MMAP_SHIFT));
4271
        break;
4272
#endif
4273
    case TARGET_NR_munmap:
4274
        ret = get_errno(target_munmap(arg1, arg2));
4275
        break;
4276
    case TARGET_NR_mprotect:
4277
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
4278
        break;
4279
#ifdef TARGET_NR_mremap
4280
    case TARGET_NR_mremap:
4281
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4282
        break;
4283
#endif
4284
        /* ??? msync/mlock/munlock are broken for softmmu.  */
4285
#ifdef TARGET_NR_msync
4286
    case TARGET_NR_msync:
4287
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
4288
        break;
4289
#endif
4290
#ifdef TARGET_NR_mlock
4291
    case TARGET_NR_mlock:
4292
        ret = get_errno(mlock(g2h(arg1), arg2));
4293
        break;
4294
#endif
4295
#ifdef TARGET_NR_munlock
4296
    case TARGET_NR_munlock:
4297
        ret = get_errno(munlock(g2h(arg1), arg2));
4298
        break;
4299
#endif
4300
#ifdef TARGET_NR_mlockall
4301
    case TARGET_NR_mlockall:
4302
        ret = get_errno(mlockall(arg1));
4303
        break;
4304
#endif
4305
#ifdef TARGET_NR_munlockall
4306
    case TARGET_NR_munlockall:
4307
        ret = get_errno(munlockall());
4308
        break;
4309
#endif
4310
    case TARGET_NR_truncate:
4311
        if (!(p = lock_user_string(arg1)))
4312
            goto efault;
4313
        ret = get_errno(truncate(p, arg2));
4314
        unlock_user(p, arg1, 0);
4315
        break;
4316
    case TARGET_NR_ftruncate:
4317
        ret = get_errno(ftruncate(arg1, arg2));
4318
        break;
4319
    case TARGET_NR_fchmod:
4320
        ret = get_errno(fchmod(arg1, arg2));
4321
        break;
4322
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4323
    case TARGET_NR_fchmodat:
4324
        if (!(p = lock_user_string(arg2)))
4325
            goto efault;
4326
        ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4327
        unlock_user(p, arg2, 0);
4328
        break;
4329
#endif
4330
    case TARGET_NR_getpriority:
4331
        /* libc does special remapping of the return value of
4332
         * sys_getpriority() so it's just easiest to call
4333
         * sys_getpriority() directly rather than through libc. */
4334
        ret = sys_getpriority(arg1, arg2);
4335
        break;
4336
    case TARGET_NR_setpriority:
4337
        ret = get_errno(setpriority(arg1, arg2, arg3));
4338
        break;
4339
#ifdef TARGET_NR_profil
4340
    case TARGET_NR_profil:
4341
        goto unimplemented;
4342
#endif
4343
    case TARGET_NR_statfs:
4344
        if (!(p = lock_user_string(arg1)))
4345
            goto efault;
4346
        ret = get_errno(statfs(path(p), &stfs));
4347
        unlock_user(p, arg1, 0);
4348
    convert_statfs:
4349
        if (!is_error(ret)) {
4350
            struct target_statfs *target_stfs;
4351

    
4352
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4353
                goto efault;
4354
            __put_user(stfs.f_type, &target_stfs->f_type);
4355
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4356
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4357
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4358
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4359
            __put_user(stfs.f_files, &target_stfs->f_files);
4360
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4361
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4362
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4363
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4364
            unlock_user_struct(target_stfs, arg2, 1);
4365
        }
4366
        break;
4367
    case TARGET_NR_fstatfs:
4368
        ret = get_errno(fstatfs(arg1, &stfs));
4369
        goto convert_statfs;
4370
#ifdef TARGET_NR_statfs64
4371
    case TARGET_NR_statfs64:
4372
        if (!(p = lock_user_string(arg1)))
4373
            goto efault;
4374
        ret = get_errno(statfs(path(p), &stfs));
4375
        unlock_user(p, arg1, 0);
4376
    convert_statfs64:
4377
        if (!is_error(ret)) {
4378
            struct target_statfs64 *target_stfs;
4379

    
4380
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4381
                goto efault;
4382
            __put_user(stfs.f_type, &target_stfs->f_type);
4383
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4384
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4385
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4386
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4387
            __put_user(stfs.f_files, &target_stfs->f_files);
4388
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4389
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4390
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4391
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4392
            unlock_user_struct(target_stfs, arg3, 1);
4393
        }
4394
        break;
4395
    case TARGET_NR_fstatfs64:
4396
        ret = get_errno(fstatfs(arg1, &stfs));
4397
        goto convert_statfs64;
4398
#endif
4399
#ifdef TARGET_NR_ioperm
4400
    case TARGET_NR_ioperm:
4401
        goto unimplemented;
4402
#endif
4403
#ifdef TARGET_NR_socketcall
4404
    case TARGET_NR_socketcall:
4405
        ret = do_socketcall(arg1, arg2);
4406
        break;
4407
#endif
4408
#ifdef TARGET_NR_accept
4409
    case TARGET_NR_accept:
4410
        ret = do_accept(arg1, arg2, arg3);
4411
        break;
4412
#endif
4413
#ifdef TARGET_NR_bind
4414
    case TARGET_NR_bind:
4415
        ret = do_bind(arg1, arg2, arg3);
4416
        break;
4417
#endif
4418
#ifdef TARGET_NR_connect
4419
    case TARGET_NR_connect:
4420
        ret = do_connect(arg1, arg2, arg3);
4421
        break;
4422
#endif
4423
#ifdef TARGET_NR_getpeername
4424
    case TARGET_NR_getpeername:
4425
        ret = do_getpeername(arg1, arg2, arg3);
4426
        break;
4427
#endif
4428
#ifdef TARGET_NR_getsockname
4429
    case TARGET_NR_getsockname:
4430
        ret = do_getsockname(arg1, arg2, arg3);
4431
        break;
4432
#endif
4433
#ifdef TARGET_NR_getsockopt
4434
    case TARGET_NR_getsockopt:
4435
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4436
        break;
4437
#endif
4438
#ifdef TARGET_NR_listen
4439
    case TARGET_NR_listen:
4440
        ret = get_errno(listen(arg1, arg2));
4441
        break;
4442
#endif
4443
#ifdef TARGET_NR_recv
4444
    case TARGET_NR_recv:
4445
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4446
        break;
4447
#endif
4448
#ifdef TARGET_NR_recvfrom
4449
    case TARGET_NR_recvfrom:
4450
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4451
        break;
4452
#endif
4453
#ifdef TARGET_NR_recvmsg
4454
    case TARGET_NR_recvmsg:
4455
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4456
        break;
4457
#endif
4458
#ifdef TARGET_NR_send
4459
    case TARGET_NR_send:
4460
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4461
        break;
4462
#endif
4463
#ifdef TARGET_NR_sendmsg
4464
    case TARGET_NR_sendmsg:
4465
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4466
        break;
4467
#endif
4468
#ifdef TARGET_NR_sendto
4469
    case TARGET_NR_sendto:
4470
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4471
        break;
4472
#endif
4473
#ifdef TARGET_NR_shutdown
4474
    case TARGET_NR_shutdown:
4475
        ret = get_errno(shutdown(arg1, arg2));
4476
        break;
4477
#endif
4478
#ifdef TARGET_NR_socket
4479
    case TARGET_NR_socket:
4480
        ret = do_socket(arg1, arg2, arg3);
4481
        break;
4482
#endif
4483
#ifdef TARGET_NR_socketpair
4484
    case TARGET_NR_socketpair:
4485
        ret = do_socketpair(arg1, arg2, arg3, arg4);
4486
        break;
4487
#endif
4488
#ifdef TARGET_NR_setsockopt
4489
    case TARGET_NR_setsockopt:
4490
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4491
        break;
4492
#endif
4493

    
4494
    case TARGET_NR_syslog:
4495
        if (!(p = lock_user_string(arg2)))
4496
            goto efault;
4497
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4498
        unlock_user(p, arg2, 0);
4499
        break;
4500

    
4501
    case TARGET_NR_setitimer:
4502
        {
4503
            struct itimerval value, ovalue, *pvalue;
4504

    
4505
            if (arg2) {
4506
                pvalue = &value;
4507
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4508
                    || copy_from_user_timeval(&pvalue->it_value,
4509
                                              arg2 + sizeof(struct target_timeval)))
4510
                    goto efault;
4511
            } else {
4512
                pvalue = NULL;
4513
            }
4514
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4515
            if (!is_error(ret) && arg3) {
4516
                if (copy_to_user_timeval(arg3,
4517
                                         &ovalue.it_interval)
4518
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4519
                                            &ovalue.it_value))
4520
                    goto efault;
4521
            }
4522
        }
4523
        break;
4524
    case TARGET_NR_getitimer:
4525
        {
4526
            struct itimerval value;
4527

    
4528
            ret = get_errno(getitimer(arg1, &value));
4529
            if (!is_error(ret) && arg2) {
4530
                if (copy_to_user_timeval(arg2,
4531
                                         &value.it_interval)
4532
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4533
                                            &value.it_value))
4534
                    goto efault;
4535
            }
4536
        }
4537
        break;
4538
    case TARGET_NR_stat:
4539
        if (!(p = lock_user_string(arg1)))
4540
            goto efault;
4541
        ret = get_errno(stat(path(p), &st));
4542
        unlock_user(p, arg1, 0);
4543
        goto do_stat;
4544
    case TARGET_NR_lstat:
4545
        if (!(p = lock_user_string(arg1)))
4546
            goto efault;
4547
        ret = get_errno(lstat(path(p), &st));
4548
        unlock_user(p, arg1, 0);
4549
        goto do_stat;
4550
    case TARGET_NR_fstat:
4551
        {
4552
            ret = get_errno(fstat(arg1, &st));
4553
        do_stat:
4554
            if (!is_error(ret)) {
4555
                struct target_stat *target_st;
4556

    
4557
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4558
                    goto efault;
4559
                __put_user(st.st_dev, &target_st->st_dev);
4560
                __put_user(st.st_ino, &target_st->st_ino);
4561
                __put_user(st.st_mode, &target_st->st_mode);
4562
                __put_user(st.st_uid, &target_st->st_uid);
4563
                __put_user(st.st_gid, &target_st->st_gid);
4564
                __put_user(st.st_nlink, &target_st->st_nlink);
4565
                __put_user(st.st_rdev, &target_st->st_rdev);
4566
                __put_user(st.st_size, &target_st->st_size);
4567
                __put_user(st.st_blksize, &target_st->st_blksize);
4568
                __put_user(st.st_blocks, &target_st->st_blocks);
4569
                __put_user(st.st_atime, &target_st->target_st_atime);
4570
                __put_user(st.st_mtime, &target_st->target_st_mtime);
4571
                __put_user(st.st_ctime, &target_st->target_st_ctime);
4572
                unlock_user_struct(target_st, arg2, 1);
4573
            }
4574
        }
4575
        break;
4576
#ifdef TARGET_NR_olduname
4577
    case TARGET_NR_olduname:
4578
        goto unimplemented;
4579
#endif
4580
#ifdef TARGET_NR_iopl
4581
    case TARGET_NR_iopl:
4582
        goto unimplemented;
4583
#endif
4584
    case TARGET_NR_vhangup:
4585
        ret = get_errno(vhangup());
4586
        break;
4587
#ifdef TARGET_NR_idle
4588
    case TARGET_NR_idle:
4589
        goto unimplemented;
4590
#endif
4591
#ifdef TARGET_NR_syscall
4592
    case TARGET_NR_syscall:
4593
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4594
            break;
4595
#endif
4596
    case TARGET_NR_wait4:
4597
        {
4598
            int status;
4599
            abi_long status_ptr = arg2;
4600
            struct rusage rusage, *rusage_ptr;
4601
            abi_ulong target_rusage = arg4;
4602
            if (target_rusage)
4603
                rusage_ptr = &rusage;
4604
            else
4605
                rusage_ptr = NULL;
4606
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4607
            if (!is_error(ret)) {
4608
                if (status_ptr) {
4609
                    if (put_user_s32(status, status_ptr))
4610
                        goto efault;
4611
                }
4612
                if (target_rusage)
4613
                    host_to_target_rusage(target_rusage, &rusage);
4614
            }
4615
        }
4616
        break;
4617
#ifdef TARGET_NR_swapoff
4618
    case TARGET_NR_swapoff:
4619
        if (!(p = lock_user_string(arg1)))
4620
            goto efault;
4621
        ret = get_errno(swapoff(p));
4622
        unlock_user(p, arg1, 0);
4623
        break;
4624
#endif
4625
    case TARGET_NR_sysinfo:
4626
        {
4627
            struct target_sysinfo *target_value;
4628
            struct sysinfo value;
4629
            ret = get_errno(sysinfo(&value));
4630
            if (!is_error(ret) && arg1)
4631
            {
4632
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4633
                    goto efault;
4634
                __put_user(value.uptime, &target_value->uptime);
4635
                __put_user(value.loads[0], &target_value->loads[0]);
4636
                __put_user(value.loads[1], &target_value->loads[1]);
4637
                __put_user(value.loads[2], &target_value->loads[2]);
4638
                __put_user(value.totalram, &target_value->totalram);
4639
                __put_user(value.freeram, &target_value->freeram);
4640
                __put_user(value.sharedram, &target_value->sharedram);
4641
                __put_user(value.bufferram, &target_value->bufferram);
4642
                __put_user(value.totalswap, &target_value->totalswap);
4643
                __put_user(value.freeswap, &target_value->freeswap);
4644
                __put_user(value.procs, &target_value->procs);
4645
                __put_user(value.totalhigh, &target_value->totalhigh);
4646
                __put_user(value.freehigh, &target_value->freehigh);
4647
                __put_user(value.mem_unit, &target_value->mem_unit);
4648
                unlock_user_struct(target_value, arg1, 1);
4649
            }
4650
        }
4651
        break;
4652
#ifdef TARGET_NR_ipc
4653
    case TARGET_NR_ipc:
4654
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4655
        break;
4656
#endif
4657
    case TARGET_NR_fsync:
4658
        ret = get_errno(fsync(arg1));
4659
        break;
4660
    case TARGET_NR_clone:
4661
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
4662
        break;
4663
#ifdef __NR_exit_group
4664
        /* new thread calls */
4665
    case TARGET_NR_exit_group:
4666
        gdb_exit(cpu_env, arg1);
4667
        ret = get_errno(exit_group(arg1));
4668
        break;
4669
#endif
4670
    case TARGET_NR_setdomainname:
4671
        if (!(p = lock_user_string(arg1)))
4672
            goto efault;
4673
        ret = get_errno(setdomainname(p, arg2));
4674
        unlock_user(p, arg1, 0);
4675
        break;
4676
    case TARGET_NR_uname:
4677
        /* no need to transcode because we use the linux syscall */
4678
        {
4679
            struct new_utsname * buf;
4680

    
4681
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4682
                goto efault;
4683
            ret = get_errno(sys_uname(buf));
4684
            if (!is_error(ret)) {
4685
                /* Overrite the native machine name with whatever is being
4686
                   emulated. */
4687
                strcpy (buf->machine, UNAME_MACHINE);
4688
                /* Allow the user to override the reported release.  */
4689
                if (qemu_uname_release && *qemu_uname_release)
4690
                  strcpy (buf->release, qemu_uname_release);
4691
            }
4692
            unlock_user_struct(buf, arg1, 1);
4693
        }
4694
        break;
4695
#ifdef TARGET_I386
4696
    case TARGET_NR_modify_ldt:
4697
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4698
        break;
4699
#if !defined(TARGET_X86_64)
4700
    case TARGET_NR_vm86old:
4701
        goto unimplemented;
4702
    case TARGET_NR_vm86:
4703
        ret = do_vm86(cpu_env, arg1, arg2);
4704
        break;
4705
#endif
4706
#endif
4707
    case TARGET_NR_adjtimex:
4708
        goto unimplemented;
4709
#ifdef TARGET_NR_create_module
4710
    case TARGET_NR_create_module:
4711
#endif
4712
    case TARGET_NR_init_module:
4713
    case TARGET_NR_delete_module:
4714
#ifdef TARGET_NR_get_kernel_syms
4715
    case TARGET_NR_get_kernel_syms:
4716
#endif
4717
        goto unimplemented;
4718
    case TARGET_NR_quotactl:
4719
        goto unimplemented;
4720
    case TARGET_NR_getpgid:
4721
        ret = get_errno(getpgid(arg1));
4722
        break;
4723
    case TARGET_NR_fchdir:
4724
        ret = get_errno(fchdir(arg1));
4725
        break;
4726
#ifdef TARGET_NR_bdflush /* not on x86_64 */
4727
    case TARGET_NR_bdflush:
4728
        goto unimplemented;
4729
#endif
4730
#ifdef TARGET_NR_sysfs
4731
    case TARGET_NR_sysfs:
4732
        goto unimplemented;
4733
#endif
4734
    case TARGET_NR_personality:
4735
        ret = get_errno(personality(arg1));
4736
        break;
4737
#ifdef TARGET_NR_afs_syscall
4738
    case TARGET_NR_afs_syscall:
4739
        goto unimplemented;
4740
#endif
4741
#ifdef TARGET_NR__llseek /* Not on alpha */
4742
    case TARGET_NR__llseek:
4743
        {
4744
#if defined (__x86_64__)
4745
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4746
            if (put_user_s64(ret, arg4))
4747
                goto efault;
4748
#else
4749
            int64_t res;
4750
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4751
            if (put_user_s64(res, arg4))
4752
                goto efault;
4753
#endif
4754
        }
4755
        break;
4756
#endif
4757
    case TARGET_NR_getdents:
4758
#if TARGET_ABI_BITS != 32
4759
        goto unimplemented;
4760
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4761
        {
4762
            struct target_dirent *target_dirp;
4763
            struct dirent *dirp;
4764
            abi_long count = arg3;
4765

    
4766
            dirp = malloc(count);
4767
            if (!dirp) {
4768
                ret = -TARGET_ENOMEM;
4769
                goto fail;
4770
            }
4771

    
4772
            ret = get_errno(sys_getdents(arg1, dirp, count));
4773
            if (!is_error(ret)) {
4774
                struct dirent *de;
4775
                struct target_dirent *tde;
4776
                int len = ret;
4777
                int reclen, treclen;
4778
                int count1, tnamelen;
4779

    
4780
                count1 = 0;
4781
                de = dirp;
4782
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4783
                    goto efault;
4784
                tde = target_dirp;
4785
                while (len > 0) {
4786
                    reclen = de->d_reclen;
4787
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4788
                    tde->d_reclen = tswap16(treclen);
4789
                    tde->d_ino = tswapl(de->d_ino);
4790
                    tde->d_off = tswapl(de->d_off);
4791
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4792
                    if (tnamelen > 256)
4793
                        tnamelen = 256;
4794
                    /* XXX: may not be correct */
4795
                    strncpy(tde->d_name, de->d_name, tnamelen);
4796
                    de = (struct dirent *)((char *)de + reclen);
4797
                    len -= reclen;
4798
                    tde = (struct target_dirent *)((char *)tde + treclen);
4799
                    count1 += treclen;
4800
                }
4801
                ret = count1;
4802
                unlock_user(target_dirp, arg2, ret);
4803
            }
4804
            free(dirp);
4805
        }
4806
#else
4807
        {
4808
            struct dirent *dirp;
4809
            abi_long count = arg3;
4810

    
4811
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4812
                goto efault;
4813
            ret = get_errno(sys_getdents(arg1, dirp, count));
4814
            if (!is_error(ret)) {
4815
                struct dirent *de;
4816
                int len = ret;
4817
                int reclen;
4818
                de = dirp;
4819
                while (len > 0) {
4820
                    reclen = de->d_reclen;
4821
                    if (reclen > len)
4822
                        break;
4823
                    de->d_reclen = tswap16(reclen);
4824
                    tswapls(&de->d_ino);
4825
                    tswapls(&de->d_off);
4826
                    de = (struct dirent *)((char *)de + reclen);
4827
                    len -= reclen;
4828
                }
4829
            }
4830
            unlock_user(dirp, arg2, ret);
4831
        }
4832
#endif
4833
        break;
4834
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
4835
    case TARGET_NR_getdents64:
4836
        {
4837
            struct dirent64 *dirp;
4838
            abi_long count = arg3;
4839
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4840
                goto efault;
4841
            ret = get_errno(sys_getdents64(arg1, dirp, count));
4842
            if (!is_error(ret)) {
4843
                struct dirent64 *de;
4844
                int len = ret;
4845
                int reclen;
4846
                de = dirp;
4847
                while (len > 0) {
4848
                    reclen = de->d_reclen;
4849
                    if (reclen > len)
4850
                        break;
4851
                    de->d_reclen = tswap16(reclen);
4852
                    tswap64s((uint64_t *)&de->d_ino);
4853
                    tswap64s((uint64_t *)&de->d_off);
4854
                    de = (struct dirent64 *)((char *)de + reclen);
4855
                    len -= reclen;
4856
                }
4857
            }
4858
            unlock_user(dirp, arg2, ret);
4859
        }
4860
        break;
4861
#endif /* TARGET_NR_getdents64 */
4862
#ifdef TARGET_NR__newselect
4863
    case TARGET_NR__newselect:
4864
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
4865
        break;
4866
#endif
4867
#ifdef TARGET_NR_poll
4868
    case TARGET_NR_poll:
4869
        {
4870
            struct target_pollfd *target_pfd;
4871
            unsigned int nfds = arg2;
4872
            int timeout = arg3;
4873
            struct pollfd *pfd;
4874
            unsigned int i;
4875

    
4876
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
4877
            if (!target_pfd)
4878
                goto efault;
4879
            pfd = alloca(sizeof(struct pollfd) * nfds);
4880
            for(i = 0; i < nfds; i++) {
4881
                pfd[i].fd = tswap32(target_pfd[i].fd);
4882
                pfd[i].events = tswap16(target_pfd[i].events);
4883
            }
4884
            ret = get_errno(poll(pfd, nfds, timeout));
4885
            if (!is_error(ret)) {
4886
                for(i = 0; i < nfds; i++) {
4887
                    target_pfd[i].revents = tswap16(pfd[i].revents);
4888
                }
4889
                ret += nfds * (sizeof(struct target_pollfd)
4890
                               - sizeof(struct pollfd));
4891
            }
4892
            unlock_user(target_pfd, arg1, ret);
4893
        }
4894
        break;
4895
#endif
4896
    case TARGET_NR_flock:
4897
        /* NOTE: the flock constant seems to be the same for every
4898
           Linux platform */
4899
        ret = get_errno(flock(arg1, arg2));
4900
        break;
4901
    case TARGET_NR_readv:
4902
        {
4903
            int count = arg3;
4904
            struct iovec *vec;
4905

    
4906
            vec = alloca(count * sizeof(struct iovec));
4907
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
4908
                goto efault;
4909
            ret = get_errno(readv(arg1, vec, count));
4910
            unlock_iovec(vec, arg2, count, 1);
4911
        }
4912
        break;
4913
    case TARGET_NR_writev:
4914
        {
4915
            int count = arg3;
4916
            struct iovec *vec;
4917

    
4918
            vec = alloca(count * sizeof(struct iovec));
4919
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
4920
                goto efault;
4921
            ret = get_errno(writev(arg1, vec, count));
4922
            unlock_iovec(vec, arg2, count, 0);
4923
        }
4924
        break;
4925
    case TARGET_NR_getsid:
4926
        ret = get_errno(getsid(arg1));
4927
        break;
4928
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
4929
    case TARGET_NR_fdatasync:
4930
        ret = get_errno(fdatasync(arg1));
4931
        break;
4932
#endif
4933
    case TARGET_NR__sysctl:
4934
        /* We don't implement this, but ENOTDIR is always a safe
4935
           return value. */
4936
        ret = -TARGET_ENOTDIR;
4937
        break;
4938
    case TARGET_NR_sched_setparam:
4939
        {
4940
            struct sched_param *target_schp;
4941
            struct sched_param schp;
4942

    
4943
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
4944
                goto efault;
4945
            schp.sched_priority = tswap32(target_schp->sched_priority);
4946
            unlock_user_struct(target_schp, arg2, 0);
4947
            ret = get_errno(sched_setparam(arg1, &schp));
4948
        }
4949
        break;
4950
    case TARGET_NR_sched_getparam:
4951
        {
4952
            struct sched_param *target_schp;
4953
            struct sched_param schp;
4954
            ret = get_errno(sched_getparam(arg1, &schp));
4955
            if (!is_error(ret)) {
4956
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
4957
                    goto efault;
4958
                target_schp->sched_priority = tswap32(schp.sched_priority);
4959
                unlock_user_struct(target_schp, arg2, 1);
4960
            }
4961
        }
4962
        break;
4963
    case TARGET_NR_sched_setscheduler:
4964
        {
4965
            struct sched_param *target_schp;
4966
            struct sched_param schp;
4967
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
4968
                goto efault;
4969
            schp.sched_priority = tswap32(target_schp->sched_priority);
4970
            unlock_user_struct(target_schp, arg3, 0);
4971
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
4972
        }
4973
        break;
4974
    case TARGET_NR_sched_getscheduler:
4975
        ret = get_errno(sched_getscheduler(arg1));
4976
        break;
4977
    case TARGET_NR_sched_yield:
4978
        ret = get_errno(sched_yield());
4979
        break;
4980
    case TARGET_NR_sched_get_priority_max:
4981
        ret = get_errno(sched_get_priority_max(arg1));
4982
        break;
4983
    case TARGET_NR_sched_get_priority_min:
4984
        ret = get_errno(sched_get_priority_min(arg1));
4985
        break;
4986
    case TARGET_NR_sched_rr_get_interval:
4987
        {
4988
            struct timespec ts;
4989
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
4990
            if (!is_error(ret)) {
4991
                host_to_target_timespec(arg2, &ts);
4992
            }
4993
        }
4994
        break;
4995
    case TARGET_NR_nanosleep:
4996
        {
4997
            struct timespec req, rem;
4998
            target_to_host_timespec(&req, arg1);
4999
            ret = get_errno(nanosleep(&req, &rem));
5000
            if (is_error(ret) && arg2) {
5001
                host_to_target_timespec(arg2, &rem);
5002
            }
5003
        }
5004
        break;
5005
#ifdef TARGET_NR_query_module
5006
    case TARGET_NR_query_module:
5007
        goto unimplemented;
5008
#endif
5009
#ifdef TARGET_NR_nfsservctl
5010
    case TARGET_NR_nfsservctl:
5011
        goto unimplemented;
5012
#endif
5013
    case TARGET_NR_prctl:
5014
        switch (arg1)
5015
            {
5016
            case PR_GET_PDEATHSIG:
5017
                {
5018
                    int deathsig;
5019
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5020
                    if (!is_error(ret) && arg2
5021
                        && put_user_ual(deathsig, arg2))
5022
                        goto efault;
5023
                }
5024
                break;
5025
            default:
5026
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5027
                break;
5028
            }
5029
        break;
5030
#ifdef TARGET_NR_arch_prctl
5031
    case TARGET_NR_arch_prctl:
5032
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
5033
        ret = do_arch_prctl(cpu_env, arg1, arg2);
5034
        break;
5035
#else
5036
        goto unimplemented;
5037
#endif
5038
#endif
5039
#ifdef TARGET_NR_pread
5040
    case TARGET_NR_pread:
5041
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5042
            goto efault;
5043
        ret = get_errno(pread(arg1, p, arg3, arg4));
5044
        unlock_user(p, arg2, ret);
5045
        break;
5046
    case TARGET_NR_pwrite:
5047
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5048
            goto efault;
5049
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
5050
        unlock_user(p, arg2, 0);
5051
        break;
5052
#endif
5053
#ifdef TARGET_NR_pread64
5054
    case TARGET_NR_pread64:
5055
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5056
            goto efault;
5057
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5058
        unlock_user(p, arg2, ret);
5059
        break;
5060
    case TARGET_NR_pwrite64:
5061
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5062
            goto efault;
5063
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5064
        unlock_user(p, arg2, 0);
5065
        break;
5066
#endif
5067
    case TARGET_NR_getcwd:
5068
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5069
            goto efault;
5070
        ret = get_errno(sys_getcwd1(p, arg2));
5071
        unlock_user(p, arg1, ret);
5072
        break;
5073
    case TARGET_NR_capget:
5074
        goto unimplemented;
5075
    case TARGET_NR_capset:
5076
        goto unimplemented;
5077
    case TARGET_NR_sigaltstack:
5078
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5079
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5080
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5081
        break;
5082
#else
5083
        goto unimplemented;
5084
#endif
5085
    case TARGET_NR_sendfile:
5086
        goto unimplemented;
5087
#ifdef TARGET_NR_getpmsg
5088
    case TARGET_NR_getpmsg:
5089
        goto unimplemented;
5090
#endif
5091
#ifdef TARGET_NR_putpmsg
5092
    case TARGET_NR_putpmsg:
5093
        goto unimplemented;
5094
#endif
5095
#ifdef TARGET_NR_vfork
5096
    case TARGET_NR_vfork:
5097
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5098
                        0, 0, 0, 0));
5099
        break;
5100
#endif
5101
#ifdef TARGET_NR_ugetrlimit
5102
    case TARGET_NR_ugetrlimit:
5103
    {
5104
        struct rlimit rlim;
5105
        ret = get_errno(getrlimit(arg1, &rlim));
5106
        if (!is_error(ret)) {
5107
            struct target_rlimit *target_rlim;
5108
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5109
                goto efault;
5110
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5111
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
5112
            unlock_user_struct(target_rlim, arg2, 1);
5113
        }
5114
        break;
5115
    }
5116
#endif
5117
#ifdef TARGET_NR_truncate64
5118
    case TARGET_NR_truncate64:
5119
        if (!(p = lock_user_string(arg1)))
5120
            goto efault;
5121
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5122
        unlock_user(p, arg1, 0);
5123
        break;
5124
#endif
5125
#ifdef TARGET_NR_ftruncate64
5126
    case TARGET_NR_ftruncate64:
5127
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5128
        break;
5129
#endif
5130
#ifdef TARGET_NR_stat64
5131
    case TARGET_NR_stat64:
5132
        if (!(p = lock_user_string(arg1)))
5133
            goto efault;
5134
        ret = get_errno(stat(path(p), &st));
5135
        unlock_user(p, arg1, 0);
5136
        goto do_stat64;
5137
#endif
5138
#ifdef TARGET_NR_lstat64
5139
    case TARGET_NR_lstat64:
5140
        if (!(p = lock_user_string(arg1)))
5141
            goto efault;
5142
        ret = get_errno(lstat(path(p), &st));
5143
        unlock_user(p, arg1, 0);
5144
        goto do_stat64;
5145
#endif
5146
#ifdef TARGET_NR_fstat64
5147
    case TARGET_NR_fstat64:
5148
        {
5149
            ret = get_errno(fstat(arg1, &st));
5150
        do_stat64:
5151
            if (!is_error(ret)) {
5152
#ifdef TARGET_ARM
5153
                if (((CPUARMState *)cpu_env)->eabi) {
5154
                    struct target_eabi_stat64 *target_st;
5155

    
5156
                    if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5157
                        goto efault;
5158
                    memset(target_st, 0, sizeof(struct target_eabi_stat64));
5159
                    __put_user(st.st_dev, &target_st->st_dev);
5160
                    __put_user(st.st_ino, &target_st->st_ino);
5161
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5162
                    __put_user(st.st_ino, &target_st->__st_ino);
5163
#endif
5164
                    __put_user(st.st_mode, &target_st->st_mode);
5165
                    __put_user(st.st_nlink, &target_st->st_nlink);
5166
                    __put_user(st.st_uid, &target_st->st_uid);
5167
                    __put_user(st.st_gid, &target_st->st_gid);
5168
                    __put_user(st.st_rdev, &target_st->st_rdev);
5169
                    __put_user(st.st_size, &target_st->st_size);
5170
                    __put_user(st.st_blksize, &target_st->st_blksize);
5171
                    __put_user(st.st_blocks, &target_st->st_blocks);
5172
                    __put_user(st.st_atime, &target_st->target_st_atime);
5173
                    __put_user(st.st_mtime, &target_st->target_st_mtime);
5174
                    __put_user(st.st_ctime, &target_st->target_st_ctime);
5175
                    unlock_user_struct(target_st, arg2, 1);
5176
                } else
5177
#endif
5178
                {
5179
                    struct target_stat64 *target_st;
5180

    
5181
                    if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5182
                        goto efault;
5183
                    memset(target_st, 0, sizeof(struct target_stat64));
5184
                    __put_user(st.st_dev, &target_st->st_dev);
5185
                    __put_user(st.st_ino, &target_st->st_ino);
5186
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5187
                    __put_user(st.st_ino, &target_st->__st_ino);
5188
#endif
5189
                    __put_user(st.st_mode, &target_st->st_mode);
5190
                    __put_user(st.st_nlink, &target_st->st_nlink);
5191
                    __put_user(st.st_uid, &target_st->st_uid);
5192
                    __put_user(st.st_gid, &target_st->st_gid);
5193
                    __put_user(st.st_rdev, &target_st->st_rdev);
5194
                    /* XXX: better use of kernel struct */
5195
                    __put_user(st.st_size, &target_st->st_size);
5196
                    __put_user(st.st_blksize, &target_st->st_blksize);
5197
                    __put_user(st.st_blocks, &target_st->st_blocks);
5198
                    __put_user(st.st_atime, &target_st->target_st_atime);
5199
                    __put_user(st.st_mtime, &target_st->target_st_mtime);
5200
                    __put_user(st.st_ctime, &target_st->target_st_ctime);
5201
                    unlock_user_struct(target_st, arg2, 1);
5202
                }
5203
            }
5204
        }
5205
        break;
5206
#endif
5207
#ifdef USE_UID16
5208
    case TARGET_NR_lchown:
5209
        if (!(p = lock_user_string(arg1)))
5210
            goto efault;
5211
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5212
        unlock_user(p, arg1, 0);
5213
        break;
5214
    case TARGET_NR_getuid:
5215
        ret = get_errno(high2lowuid(getuid()));
5216
        break;
5217
    case TARGET_NR_getgid:
5218
        ret = get_errno(high2lowgid(getgid()));
5219
        break;
5220
    case TARGET_NR_geteuid:
5221
        ret = get_errno(high2lowuid(geteuid()));
5222
        break;
5223
    case TARGET_NR_getegid:
5224
        ret = get_errno(high2lowgid(getegid()));
5225
        break;
5226
    case TARGET_NR_setreuid:
5227
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5228
        break;
5229
    case TARGET_NR_setregid:
5230
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5231
        break;
5232
    case TARGET_NR_getgroups:
5233
        {
5234
            int gidsetsize = arg1;
5235
            uint16_t *target_grouplist;
5236
            gid_t *grouplist;
5237
            int i;
5238

    
5239
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5240
            ret = get_errno(getgroups(gidsetsize, grouplist));
5241
            if (!is_error(ret)) {
5242
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5243
                if (!target_grouplist)
5244
                    goto efault;
5245
                for(i = 0;i < gidsetsize; i++)
5246
                    target_grouplist[i] = tswap16(grouplist[i]);
5247
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5248
            }
5249
        }
5250
        break;
5251
    case TARGET_NR_setgroups:
5252
        {
5253
            int gidsetsize = arg1;
5254
            uint16_t *target_grouplist;
5255
            gid_t *grouplist;
5256
            int i;
5257

    
5258
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5259
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5260
            if (!target_grouplist) {
5261
                ret = -TARGET_EFAULT;
5262
                goto fail;
5263
            }
5264
            for(i = 0;i < gidsetsize; i++)
5265
                grouplist[i] = tswap16(target_grouplist[i]);
5266
            unlock_user(target_grouplist, arg2, 0);
5267
            ret = get_errno(setgroups(gidsetsize, grouplist));
5268
        }
5269
        break;
5270
    case TARGET_NR_fchown:
5271
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5272
        break;
5273
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5274
    case TARGET_NR_fchownat:
5275
        if (!(p = lock_user_string(arg2))) 
5276
            goto efault;
5277
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5278
        unlock_user(p, arg2, 0);
5279
        break;
5280
#endif
5281
#ifdef TARGET_NR_setresuid
5282
    case TARGET_NR_setresuid:
5283
        ret = get_errno(setresuid(low2highuid(arg1),
5284
                                  low2highuid(arg2),
5285
                                  low2highuid(arg3)));
5286
        break;
5287
#endif
5288
#ifdef TARGET_NR_getresuid
5289
    case TARGET_NR_getresuid:
5290
        {
5291
            uid_t ruid, euid, suid;
5292
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5293
            if (!is_error(ret)) {
5294
                if (put_user_u16(high2lowuid(ruid), arg1)
5295
                    || put_user_u16(high2lowuid(euid), arg2)
5296
                    || put_user_u16(high2lowuid(suid), arg3))
5297
                    goto efault;
5298
            }
5299
        }
5300
        break;
5301
#endif
5302
#ifdef TARGET_NR_getresgid
5303
    case TARGET_NR_setresgid:
5304
        ret = get_errno(setresgid(low2highgid(arg1),
5305
                                  low2highgid(arg2),
5306
                                  low2highgid(arg3)));
5307
        break;
5308
#endif
5309
#ifdef TARGET_NR_getresgid
5310
    case TARGET_NR_getresgid:
5311
        {
5312
            gid_t rgid, egid, sgid;
5313
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5314
            if (!is_error(ret)) {
5315
                if (put_user_u16(high2lowgid(rgid), arg1)
5316
                    || put_user_u16(high2lowgid(egid), arg2)
5317
                    || put_user_u16(high2lowgid(sgid), arg3))
5318
                    goto efault;
5319
            }
5320
        }
5321
        break;
5322
#endif
5323
    case TARGET_NR_chown:
5324
        if (!(p = lock_user_string(arg1)))
5325
            goto efault;
5326
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5327
        unlock_user(p, arg1, 0);
5328
        break;
5329
    case TARGET_NR_setuid:
5330
        ret = get_errno(setuid(low2highuid(arg1)));
5331
        break;
5332
    case TARGET_NR_setgid:
5333
        ret = get_errno(setgid(low2highgid(arg1)));
5334
        break;
5335
    case TARGET_NR_setfsuid:
5336
        ret = get_errno(setfsuid(arg1));
5337
        break;
5338
    case TARGET_NR_setfsgid:
5339
        ret = get_errno(setfsgid(arg1));
5340
        break;
5341
#endif /* USE_UID16 */
5342

    
5343
#ifdef TARGET_NR_lchown32
5344
    case TARGET_NR_lchown32:
5345
        if (!(p = lock_user_string(arg1)))
5346
            goto efault;
5347
        ret = get_errno(lchown(p, arg2, arg3));
5348
        unlock_user(p, arg1, 0);
5349
        break;
5350
#endif
5351
#ifdef TARGET_NR_getuid32
5352
    case TARGET_NR_getuid32:
5353
        ret = get_errno(getuid());
5354
        break;
5355
#endif
5356
#ifdef TARGET_NR_getgid32
5357
    case TARGET_NR_getgid32:
5358
        ret = get_errno(getgid());
5359
        break;
5360
#endif
5361
#ifdef TARGET_NR_geteuid32
5362
    case TARGET_NR_geteuid32:
5363
        ret = get_errno(geteuid());
5364
        break;
5365
#endif
5366
#ifdef TARGET_NR_getegid32
5367
    case TARGET_NR_getegid32:
5368
        ret = get_errno(getegid());
5369
        break;
5370
#endif
5371
#ifdef TARGET_NR_setreuid32
5372
    case TARGET_NR_setreuid32:
5373
        ret = get_errno(setreuid(arg1, arg2));
5374
        break;
5375
#endif
5376
#ifdef TARGET_NR_setregid32
5377
    case TARGET_NR_setregid32:
5378
        ret = get_errno(setregid(arg1, arg2));
5379
        break;
5380
#endif
5381
#ifdef TARGET_NR_getgroups32
5382
    case TARGET_NR_getgroups32:
5383
        {
5384
            int gidsetsize = arg1;
5385
            uint32_t *target_grouplist;
5386
            gid_t *grouplist;
5387
            int i;
5388

    
5389
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5390
            ret = get_errno(getgroups(gidsetsize, grouplist));
5391
            if (!is_error(ret)) {
5392
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5393
                if (!target_grouplist) {
5394
                    ret = -TARGET_EFAULT;
5395
                    goto fail;
5396
                }
5397
                for(i = 0;i < gidsetsize; i++)
5398
                    target_grouplist[i] = tswap32(grouplist[i]);
5399
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
5400
            }
5401
        }
5402
        break;
5403
#endif
5404
#ifdef TARGET_NR_setgroups32
5405
    case TARGET_NR_setgroups32:
5406
        {
5407
            int gidsetsize = arg1;
5408
            uint32_t *target_grouplist;
5409
            gid_t *grouplist;
5410
            int i;
5411

    
5412
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5413
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5414
            if (!target_grouplist) {
5415
                ret = -TARGET_EFAULT;
5416
                goto fail;
5417
            }
5418
            for(i = 0;i < gidsetsize; i++)
5419
                grouplist[i] = tswap32(target_grouplist[i]);
5420
            unlock_user(target_grouplist, arg2, 0);
5421
            ret = get_errno(setgroups(gidsetsize, grouplist));
5422
        }
5423
        break;
5424
#endif
5425
#ifdef TARGET_NR_fchown32
5426
    case TARGET_NR_fchown32:
5427
        ret = get_errno(fchown(arg1, arg2, arg3));
5428
        break;
5429
#endif
5430
#ifdef TARGET_NR_setresuid32
5431
    case TARGET_NR_setresuid32:
5432
        ret = get_errno(setresuid(arg1, arg2, arg3));
5433
        break;
5434
#endif
5435
#ifdef TARGET_NR_getresuid32
5436
    case TARGET_NR_getresuid32:
5437
        {
5438
            uid_t ruid, euid, suid;
5439
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5440
            if (!is_error(ret)) {
5441
                if (put_user_u32(ruid, arg1)
5442
                    || put_user_u32(euid, arg2)
5443
                    || put_user_u32(suid, arg3))
5444
                    goto efault;
5445
            }
5446
        }
5447
        break;
5448
#endif
5449
#ifdef TARGET_NR_setresgid32
5450
    case TARGET_NR_setresgid32:
5451
        ret = get_errno(setresgid(arg1, arg2, arg3));
5452
        break;
5453
#endif
5454
#ifdef TARGET_NR_getresgid32
5455
    case TARGET_NR_getresgid32:
5456
        {
5457
            gid_t rgid, egid, sgid;
5458
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5459
            if (!is_error(ret)) {
5460
                if (put_user_u32(rgid, arg1)
5461
                    || put_user_u32(egid, arg2)
5462
                    || put_user_u32(sgid, arg3))
5463
                    goto efault;
5464
            }
5465
        }
5466
        break;
5467
#endif
5468
#ifdef TARGET_NR_chown32
5469
    case TARGET_NR_chown32:
5470
        if (!(p = lock_user_string(arg1)))
5471
            goto efault;
5472
        ret = get_errno(chown(p, arg2, arg3));
5473
        unlock_user(p, arg1, 0);
5474
        break;
5475
#endif
5476
#ifdef TARGET_NR_setuid32
5477
    case TARGET_NR_setuid32:
5478
        ret = get_errno(setuid(arg1));
5479
        break;
5480
#endif
5481
#ifdef TARGET_NR_setgid32
5482
    case TARGET_NR_setgid32:
5483
        ret = get_errno(setgid(arg1));
5484
        break;
5485
#endif
5486
#ifdef TARGET_NR_setfsuid32
5487
    case TARGET_NR_setfsuid32:
5488
        ret = get_errno(setfsuid(arg1));
5489
        break;
5490
#endif
5491
#ifdef TARGET_NR_setfsgid32
5492
    case TARGET_NR_setfsgid32:
5493
        ret = get_errno(setfsgid(arg1));
5494
        break;
5495
#endif
5496

    
5497
    case TARGET_NR_pivot_root:
5498
        goto unimplemented;
5499
#ifdef TARGET_NR_mincore
5500
    case TARGET_NR_mincore:
5501
        goto unimplemented;
5502
#endif
5503
#ifdef TARGET_NR_madvise
5504
    case TARGET_NR_madvise:
5505
        /* A straight passthrough may not be safe because qemu sometimes
5506
           turns private flie-backed mappings into anonymous mappings.
5507
           This will break MADV_DONTNEED.
5508
           This is a hint, so ignoring and returning success is ok.  */
5509
        ret = get_errno(0);
5510
        break;
5511
#endif
5512
#if TARGET_ABI_BITS == 32
5513
    case TARGET_NR_fcntl64:
5514
    {
5515
        int cmd;
5516
        struct flock64 fl;
5517
        struct target_flock64 *target_fl;
5518
#ifdef TARGET_ARM
5519
        struct target_eabi_flock64 *target_efl;
5520
#endif
5521

    
5522
        switch(arg2){
5523
        case TARGET_F_GETLK64:
5524
            cmd = F_GETLK64;
5525
            break;
5526
        case TARGET_F_SETLK64:
5527
            cmd = F_SETLK64;
5528
            break;
5529
        case TARGET_F_SETLKW64:
5530
            cmd = F_SETLK64;
5531
            break;
5532
        default:
5533
            cmd = arg2;
5534
            break;
5535
        }
5536

    
5537
        switch(arg2) {
5538
        case TARGET_F_GETLK64:
5539
#ifdef TARGET_ARM
5540
            if (((CPUARMState *)cpu_env)->eabi) {
5541
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5542
                    goto efault;
5543
                fl.l_type = tswap16(target_efl->l_type);
5544
                fl.l_whence = tswap16(target_efl->l_whence);
5545
                fl.l_start = tswap64(target_efl->l_start);
5546
                fl.l_len = tswap64(target_efl->l_len);
5547
                fl.l_pid = tswapl(target_efl->l_pid);
5548
                unlock_user_struct(target_efl, arg3, 0);
5549
            } else
5550
#endif
5551
            {
5552
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5553
                    goto efault;
5554
                fl.l_type = tswap16(target_fl->l_type);
5555
                fl.l_whence = tswap16(target_fl->l_whence);
5556
                fl.l_start = tswap64(target_fl->l_start);
5557
                fl.l_len = tswap64(target_fl->l_len);
5558
                fl.l_pid = tswapl(target_fl->l_pid);
5559
                unlock_user_struct(target_fl, arg3, 0);
5560
            }
5561
            ret = get_errno(fcntl(arg1, cmd, &fl));
5562
            if (ret == 0) {
5563
#ifdef TARGET_ARM
5564
                if (((CPUARMState *)cpu_env)->eabi) {
5565
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
5566
                        goto efault;
5567
                    target_efl->l_type = tswap16(fl.l_type);
5568
                    target_efl->l_whence = tswap16(fl.l_whence);
5569
                    target_efl->l_start = tswap64(fl.l_start);
5570
                    target_efl->l_len = tswap64(fl.l_len);
5571
                    target_efl->l_pid = tswapl(fl.l_pid);
5572
                    unlock_user_struct(target_efl, arg3, 1);
5573
                } else
5574
#endif
5575
                {
5576
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
5577
                        goto efault;
5578
                    target_fl->l_type = tswap16(fl.l_type);
5579
                    target_fl->l_whence = tswap16(fl.l_whence);
5580
                    target_fl->l_start = tswap64(fl.l_start);
5581
                    target_fl->l_len = tswap64(fl.l_len);
5582
                    target_fl->l_pid = tswapl(fl.l_pid);
5583
                    unlock_user_struct(target_fl, arg3, 1);
5584
                }
5585
            }
5586
            break;
5587

    
5588
        case TARGET_F_SETLK64:
5589
        case TARGET_F_SETLKW64:
5590
#ifdef TARGET_ARM
5591
            if (((CPUARMState *)cpu_env)->eabi) {
5592
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5593
                    goto efault;
5594
                fl.l_type = tswap16(target_efl->l_type);
5595
                fl.l_whence = tswap16(target_efl->l_whence);
5596
                fl.l_start = tswap64(target_efl->l_start);
5597
                fl.l_len = tswap64(target_efl->l_len);
5598
                fl.l_pid = tswapl(target_efl->l_pid);
5599
                unlock_user_struct(target_efl, arg3, 0);
5600
            } else
5601
#endif
5602
            {
5603
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5604
                    goto efault;
5605
                fl.l_type = tswap16(target_fl->l_type);
5606
                fl.l_whence = tswap16(target_fl->l_whence);
5607
                fl.l_start = tswap64(target_fl->l_start);
5608
                fl.l_len = tswap64(target_fl->l_len);
5609
                fl.l_pid = tswapl(target_fl->l_pid);
5610
                unlock_user_struct(target_fl, arg3, 0);
5611
            }
5612
            ret = get_errno(fcntl(arg1, cmd, &fl));
5613
            break;
5614
        default:
5615
            ret = do_fcntl(arg1, cmd, arg3);
5616
            break;
5617
        }
5618
        break;
5619
    }
5620
#endif
5621
#ifdef TARGET_NR_cacheflush
5622
    case TARGET_NR_cacheflush:
5623
        /* self-modifying code is handled automatically, so nothing needed */
5624
        ret = 0;
5625
        break;
5626
#endif
5627
#ifdef TARGET_NR_security
5628
    case TARGET_NR_security:
5629
        goto unimplemented;
5630
#endif
5631
#ifdef TARGET_NR_getpagesize
5632
    case TARGET_NR_getpagesize:
5633
        ret = TARGET_PAGE_SIZE;
5634
        break;
5635
#endif
5636
    case TARGET_NR_gettid:
5637
        ret = get_errno(gettid());
5638
        break;
5639
#ifdef TARGET_NR_readahead
5640
    case TARGET_NR_readahead:
5641
        goto unimplemented;
5642
#endif
5643
#ifdef TARGET_NR_setxattr
5644
    case TARGET_NR_setxattr:
5645
    case TARGET_NR_lsetxattr:
5646
    case TARGET_NR_fsetxattr:
5647
    case TARGET_NR_getxattr:
5648
    case TARGET_NR_lgetxattr:
5649
    case TARGET_NR_fgetxattr:
5650
    case TARGET_NR_listxattr:
5651
    case TARGET_NR_llistxattr:
5652
    case TARGET_NR_flistxattr:
5653
    case TARGET_NR_removexattr:
5654
    case TARGET_NR_lremovexattr:
5655
    case TARGET_NR_fremovexattr:
5656
        goto unimplemented_nowarn;
5657
#endif
5658
#ifdef TARGET_NR_set_thread_area
5659
    case TARGET_NR_set_thread_area:
5660
#if defined(TARGET_MIPS)
5661
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
5662
      ret = 0;
5663
      break;
5664
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
5665
      ret = do_set_thread_area(cpu_env, arg1);
5666
      break;
5667
#else
5668
      goto unimplemented_nowarn;
5669
#endif
5670
#endif
5671
#ifdef TARGET_NR_get_thread_area
5672
    case TARGET_NR_get_thread_area:
5673
#if defined(TARGET_I386) && defined(TARGET_ABI32)
5674
        ret = do_get_thread_area(cpu_env, arg1);
5675
#else
5676
        goto unimplemented_nowarn;
5677
#endif
5678
#endif
5679
#ifdef TARGET_NR_getdomainname
5680
    case TARGET_NR_getdomainname:
5681
        goto unimplemented_nowarn;
5682
#endif
5683

    
5684
#ifdef TARGET_NR_clock_gettime
5685
    case TARGET_NR_clock_gettime:
5686
    {
5687
        struct timespec ts;
5688
        ret = get_errno(clock_gettime(arg1, &ts));
5689
        if (!is_error(ret)) {
5690
            host_to_target_timespec(arg2, &ts);
5691
        }
5692
        break;
5693
    }
5694
#endif
5695
#ifdef TARGET_NR_clock_getres
5696
    case TARGET_NR_clock_getres:
5697
    {
5698
        struct timespec ts;
5699
        ret = get_errno(clock_getres(arg1, &ts));
5700
        if (!is_error(ret)) {
5701
            host_to_target_timespec(arg2, &ts);
5702
        }
5703
        break;
5704
    }
5705
#endif
5706
#ifdef TARGET_NR_clock_nanosleep
5707
    case TARGET_NR_clock_nanosleep:
5708
    {
5709
        struct timespec ts;
5710
        target_to_host_timespec(&ts, arg3);
5711
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
5712
        if (arg4)
5713
            host_to_target_timespec(arg4, &ts);
5714
        break;
5715
    }
5716
#endif
5717

    
5718
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5719
    case TARGET_NR_set_tid_address:
5720
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
5721
        break;
5722
#endif
5723

    
5724
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5725
    case TARGET_NR_tkill:
5726
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5727
        break;
5728
#endif
5729

    
5730
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5731
    case TARGET_NR_tgkill:
5732
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5733
                        target_to_host_signal(arg3)));
5734
        break;
5735
#endif
5736

    
5737
#ifdef TARGET_NR_set_robust_list
5738
    case TARGET_NR_set_robust_list:
5739
        goto unimplemented_nowarn;
5740
#endif
5741

    
5742
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
5743
    case TARGET_NR_utimensat:
5744
        {
5745
            struct timespec ts[2];
5746
            target_to_host_timespec(ts, arg3);
5747
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
5748
            if (!arg2)
5749
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
5750
            else {
5751
                if (!(p = lock_user_string(arg2))) {
5752
                    ret = -TARGET_EFAULT;
5753
                    goto fail;
5754
                }
5755
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
5756
                unlock_user(p, arg2, 0);
5757
            }
5758
        }
5759
        break;
5760
#endif
5761
#if defined(USE_NPTL)
5762
    case TARGET_NR_futex:
5763
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
5764
        break;
5765
#endif
5766

    
5767
    default:
5768
    unimplemented:
5769
        gemu_log("qemu: Unsupported syscall: %d\n", num);
5770
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
5771
    unimplemented_nowarn:
5772
#endif
5773
        ret = -TARGET_ENOSYS;
5774
        break;
5775
    }
5776
fail:
5777
#ifdef DEBUG
5778
    gemu_log(" = %ld\n", ret);
5779
#endif
5780
    if(do_strace)
5781
        print_syscall_ret(num, ret);
5782
    return ret;
5783
efault:
5784
    ret = -TARGET_EFAULT;
5785
    goto fail;
5786
}