Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ b5dc7732

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

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

    
85
//#define DEBUG
86

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

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

    
97

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

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

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

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

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

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

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

    
143

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

    
151

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

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

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

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

    
271
#define ERRNO_TABLE_SIZE 1200
272

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

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

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

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

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

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

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

    
422
static abi_ulong target_brk;
423
static abi_ulong target_original_brk;
424

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

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

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

    
442
    brk_page = HOST_PAGE_ALIGN(target_brk);
443

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

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

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

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

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

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

    
489
    unlock_user(target_fds, target_fds_addr, 0);
490

    
491
    return 0;
492
}
493

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

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

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

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

    
521
    return 0;
522
}
523

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

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

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

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

    
566
    return 0;
567
}
568

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

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

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

    
580
    unlock_user_struct(target_tv, target_tv_addr, 0);
581

    
582
    return 0;
583
}
584

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

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

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

    
596
    unlock_user_struct(target_tv, target_tv_addr, 1);
597

    
598
    return 0;
599
}
600

    
601

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

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

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

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

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

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

    
656
    return ret;
657
}
658

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

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

    
672
    return 0;
673
}
674

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

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

    
688
    return 0;
689
}
690

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1083
    return 0;
1084
}
1085

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

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

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

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

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

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

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

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

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

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

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

    
1198
    addr = alloca(addrlen);
1199

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

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

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

    
1220
    addr = alloca(addrlen);
1221

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

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

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

    
1242
    addr = alloca(addrlen);
1243

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1587
#ifdef TARGET_NR_ipc
1588
#define N_SHM_REGIONS        32
1589

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1816
    return ret;
1817
}
1818

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

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

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

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

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

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

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

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

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

    
1915
    return ret;
1916
}
1917

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2008
                }
2009
                break;
2010

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

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

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

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

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

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

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

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

    
2112
#define MAX_STRUCT_SIZE 4096
2113

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2411
#if defined(TARGET_I386)
2412

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2715
#if defined(USE_NPTL)
2716

    
2717
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2718

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2986
#ifdef USE_UID16
2987

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

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

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

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

    
3020
#endif /* USE_UID16 */
3021

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3421
            goto execve_end;
3422

    
3423
        execve_efault:
3424
            ret = -TARGET_EFAULT;
3425

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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