Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 8fcd3692

History | View | Annotate | Download (180.1 kB)

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

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

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

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

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

    
86
//#define DEBUG
87

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

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

    
98

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

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

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

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

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

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

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

    
144

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

    
153

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

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

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

    
266
extern int personality(int);
267
extern int flock(int, int);
268
extern int setfsuid(int);
269
extern int setfsgid(int);
270
extern int setresuid(uid_t, uid_t, uid_t);
271
extern int getresuid(uid_t *, uid_t *, uid_t *);
272
extern int setresgid(gid_t, gid_t, gid_t);
273
extern int getresgid(gid_t *, gid_t *, gid_t *);
274
extern int setgroups(int, gid_t *);
275

    
276
#define ERRNO_TABLE_SIZE 1200
277

    
278
/* target_to_host_errno_table[] is initialized from
279
 * host_to_target_errno_table[] in syscall_init(). */
280
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
281
};
282

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

    
395
static inline int host_to_target_errno(int err)
396
{
397
    if(host_to_target_errno_table[err])
398
        return host_to_target_errno_table[err];
399
    return err;
400
}
401

    
402
static inline int target_to_host_errno(int err)
403
{
404
    if (target_to_host_errno_table[err])
405
        return target_to_host_errno_table[err];
406
    return err;
407
}
408

    
409
static inline abi_long get_errno(abi_long ret)
410
{
411
    if (ret == -1)
412
        return -host_to_target_errno(errno);
413
    else
414
        return ret;
415
}
416

    
417
static inline int is_error(abi_long ret)
418
{
419
    return (abi_ulong)ret >= (abi_ulong)(-4096);
420
}
421

    
422
char *target_strerror(int err)
423
{
424
    return strerror(target_to_host_errno(err));
425
}
426

    
427
static abi_ulong target_brk;
428
static abi_ulong target_original_brk;
429

    
430
void target_set_brk(abi_ulong new_brk)
431
{
432
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
433
}
434

    
435
/* do_brk() must return target values and target errnos. */
436
abi_long do_brk(abi_ulong new_brk)
437
{
438
    abi_ulong brk_page;
439
    abi_long mapped_addr;
440
    int        new_alloc_size;
441

    
442
    if (!new_brk)
443
        return target_brk;
444
    if (new_brk < target_original_brk)
445
        return target_brk;
446

    
447
    brk_page = HOST_PAGE_ALIGN(target_brk);
448

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

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

    
461
    if (!is_error(mapped_addr))
462
        target_brk = new_brk;
463
    
464
    return target_brk;
465
}
466

    
467
static inline abi_long copy_from_user_fdset(fd_set *fds,
468
                                            abi_ulong target_fds_addr,
469
                                            int n)
470
{
471
    int i, nw, j, k;
472
    abi_ulong b, *target_fds;
473

    
474
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
475
    if (!(target_fds = lock_user(VERIFY_READ,
476
                                 target_fds_addr,
477
                                 sizeof(abi_ulong) * nw,
478
                                 1)))
479
        return -TARGET_EFAULT;
480

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

    
494
    unlock_user(target_fds, target_fds_addr, 0);
495

    
496
    return 0;
497
}
498

    
499
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
500
                                          const fd_set *fds,
501
                                          int n)
502
{
503
    int i, nw, j, k;
504
    abi_long v;
505
    abi_ulong *target_fds;
506

    
507
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
508
    if (!(target_fds = lock_user(VERIFY_WRITE,
509
                                 target_fds_addr,
510
                                 sizeof(abi_ulong) * nw,
511
                                 0)))
512
        return -TARGET_EFAULT;
513

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

    
524
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
525

    
526
    return 0;
527
}
528

    
529
#if defined(__alpha__)
530
#define HOST_HZ 1024
531
#else
532
#define HOST_HZ 100
533
#endif
534

    
535
static inline abi_long host_to_target_clock_t(long ticks)
536
{
537
#if HOST_HZ == TARGET_HZ
538
    return ticks;
539
#else
540
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
541
#endif
542
}
543

    
544
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
545
                                             const struct rusage *rusage)
546
{
547
    struct target_rusage *target_rusage;
548

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

    
571
    return 0;
572
}
573

    
574
static inline abi_long copy_from_user_timeval(struct timeval *tv,
575
                                              abi_ulong target_tv_addr)
576
{
577
    struct target_timeval *target_tv;
578

    
579
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
580
        return -TARGET_EFAULT;
581

    
582
    __get_user(tv->tv_sec, &target_tv->tv_sec);
583
    __get_user(tv->tv_usec, &target_tv->tv_usec);
584

    
585
    unlock_user_struct(target_tv, target_tv_addr, 0);
586

    
587
    return 0;
588
}
589

    
590
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
591
                                            const struct timeval *tv)
592
{
593
    struct target_timeval *target_tv;
594

    
595
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
596
        return -TARGET_EFAULT;
597

    
598
    __put_user(tv->tv_sec, &target_tv->tv_sec);
599
    __put_user(tv->tv_usec, &target_tv->tv_usec);
600

    
601
    unlock_user_struct(target_tv, target_tv_addr, 1);
602

    
603
    return 0;
604
}
605

    
606

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

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

    
639
    if (target_tv_addr) {
640
        if (copy_from_user_timeval(&tv, target_tv_addr))
641
            return -TARGET_EFAULT;
642
        tv_ptr = &tv;
643
    } else {
644
        tv_ptr = NULL;
645
    }
646

    
647
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
648

    
649
    if (!is_error(ret)) {
650
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
651
            return -TARGET_EFAULT;
652
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
653
            return -TARGET_EFAULT;
654
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
655
            return -TARGET_EFAULT;
656

    
657
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
658
            return -TARGET_EFAULT;
659
    }
660

    
661
    return ret;
662
}
663

    
664
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
665
                                               abi_ulong target_addr,
666
                                               socklen_t len)
667
{
668
    struct target_sockaddr *target_saddr;
669

    
670
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
671
    if (!target_saddr)
672
        return -TARGET_EFAULT;
673
    memcpy(addr, target_saddr, len);
674
    addr->sa_family = tswap16(target_saddr->sa_family);
675
    unlock_user(target_saddr, target_addr, 0);
676

    
677
    return 0;
678
}
679

    
680
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
681
                                               struct sockaddr *addr,
682
                                               socklen_t len)
683
{
684
    struct target_sockaddr *target_saddr;
685

    
686
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
687
    if (!target_saddr)
688
        return -TARGET_EFAULT;
689
    memcpy(target_saddr, addr, len);
690
    target_saddr->sa_family = tswap16(addr->sa_family);
691
    unlock_user(target_saddr, target_addr, len);
692

    
693
    return 0;
694
}
695

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

    
714
    while (cmsg && target_cmsg) {
715
        void *data = CMSG_DATA(cmsg);
716
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
717

    
718
        int len = tswapl(target_cmsg->cmsg_len)
719
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
720

    
721
        space += CMSG_SPACE(len);
722
        if (space > msgh->msg_controllen) {
723
            space -= CMSG_SPACE(len);
724
            gemu_log("Host cmsg overflow\n");
725
            break;
726
        }
727

    
728
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
729
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
730
        cmsg->cmsg_len = CMSG_LEN(len);
731

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

    
740
            for (i = 0; i < numfds; i++)
741
                fd[i] = tswap32(target_fd[i]);
742
        }
743

    
744
        cmsg = CMSG_NXTHDR(msgh, cmsg);
745
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
746
    }
747
    unlock_user(target_cmsg, target_cmsg_addr, 0);
748
 the_end:
749
    msgh->msg_controllen = space;
750
    return 0;
751
}
752

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

    
763
    msg_controllen = tswapl(target_msgh->msg_controllen);
764
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
765
        goto the_end;
766
    target_cmsg_addr = tswapl(target_msgh->msg_control);
767
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
768
    if (!target_cmsg)
769
        return -TARGET_EFAULT;
770

    
771
    while (cmsg && target_cmsg) {
772
        void *data = CMSG_DATA(cmsg);
773
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
774

    
775
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
776

    
777
        space += TARGET_CMSG_SPACE(len);
778
        if (space > msg_controllen) {
779
            space -= TARGET_CMSG_SPACE(len);
780
            gemu_log("Target cmsg overflow\n");
781
            break;
782
        }
783

    
784
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
785
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
786
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
787

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

    
796
            for (i = 0; i < numfds; i++)
797
                target_fd[i] = tswap32(fd[i]);
798
        }
799

    
800
        cmsg = CMSG_NXTHDR(msgh, cmsg);
801
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
802
    }
803
    unlock_user(target_cmsg, target_cmsg_addr, space);
804
 the_end:
805
    target_msgh->msg_controllen = tswapl(space);
806
    return 0;
807
}
808

    
809
/* do_setsockopt() Must return target values and target errnos. */
810
static abi_long do_setsockopt(int sockfd, int level, int optname,
811
                              abi_ulong optval_addr, socklen_t optlen)
812
{
813
    abi_long ret;
814
    int val;
815

    
816
    switch(level) {
817
    case SOL_TCP:
818
        /* TCP options all take an 'int' value.  */
819
        if (optlen < sizeof(uint32_t))
820
            return -TARGET_EINVAL;
821

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

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

    
935
/* do_getsockopt() Must return target values and target errnos. */
936
static abi_long do_getsockopt(int sockfd, int level, int optname,
937
                              abi_ulong optval_addr, abi_ulong optlen)
938
{
939
    abi_long ret;
940
    int len, lv, val;
941

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

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

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

    
1072
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1073
                             int count, int copy)
1074
{
1075
    struct target_iovec *target_vec;
1076
    abi_ulong base;
1077
    int i;
1078

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

    
1088
    return 0;
1089
}
1090

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

    
1121
/* do_bind() Must return target values and target errnos. */
1122
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1123
                        socklen_t addrlen)
1124
{
1125
    void *addr = alloca(addrlen);
1126

    
1127
    target_to_host_sockaddr(addr, target_addr, addrlen);
1128
    return get_errno(bind(sockfd, addr, addrlen));
1129
}
1130

    
1131
/* do_connect() Must return target values and target errnos. */
1132
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1133
                           socklen_t addrlen)
1134
{
1135
    void *addr = alloca(addrlen);
1136

    
1137
    target_to_host_sockaddr(addr, target_addr, addrlen);
1138
    return get_errno(connect(sockfd, addr, addrlen));
1139
}
1140

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

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

    
1171
    count = tswapl(msgp->msg_iovlen);
1172
    vec = alloca(count * sizeof(struct iovec));
1173
    target_vec = tswapl(msgp->msg_iov);
1174
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1175
    msg.msg_iovlen = count;
1176
    msg.msg_iov = vec;
1177

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

    
1192
/* do_accept() Must return target values and target errnos. */
1193
static abi_long do_accept(int fd, abi_ulong target_addr,
1194
                          abi_ulong target_addrlen_addr)
1195
{
1196
    socklen_t addrlen;
1197
    void *addr;
1198
    abi_long ret;
1199

    
1200
    if (get_user_u32(addrlen, target_addrlen_addr))
1201
        return -TARGET_EFAULT;
1202

    
1203
    addr = alloca(addrlen);
1204

    
1205
    ret = get_errno(accept(fd, addr, &addrlen));
1206
    if (!is_error(ret)) {
1207
        host_to_target_sockaddr(target_addr, addr, addrlen);
1208
        if (put_user_u32(addrlen, target_addrlen_addr))
1209
            ret = -TARGET_EFAULT;
1210
    }
1211
    return ret;
1212
}
1213

    
1214
/* do_getpeername() Must return target values and target errnos. */
1215
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1216
                               abi_ulong target_addrlen_addr)
1217
{
1218
    socklen_t addrlen;
1219
    void *addr;
1220
    abi_long ret;
1221

    
1222
    if (get_user_u32(addrlen, target_addrlen_addr))
1223
        return -TARGET_EFAULT;
1224

    
1225
    addr = alloca(addrlen);
1226

    
1227
    ret = get_errno(getpeername(fd, addr, &addrlen));
1228
    if (!is_error(ret)) {
1229
        host_to_target_sockaddr(target_addr, addr, addrlen);
1230
        if (put_user_u32(addrlen, target_addrlen_addr))
1231
            ret = -TARGET_EFAULT;
1232
    }
1233
    return ret;
1234
}
1235

    
1236
/* do_getsockname() Must return target values and target errnos. */
1237
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1238
                               abi_ulong target_addrlen_addr)
1239
{
1240
    socklen_t addrlen;
1241
    void *addr;
1242
    abi_long ret;
1243

    
1244
    if (get_user_u32(addrlen, target_addrlen_addr))
1245
        return -TARGET_EFAULT;
1246

    
1247
    addr = alloca(addrlen);
1248

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

    
1258
/* do_socketpair() Must return target values and target errnos. */
1259
static abi_long do_socketpair(int domain, int type, int protocol,
1260
                              abi_ulong target_tab_addr)
1261
{
1262
    int tab[2];
1263
    abi_long ret;
1264

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

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

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

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

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

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

    
1343
    switch(num) {
1344
    case SOCKOP_socket:
1345
        {
1346
            int domain, type, protocol;
1347

    
1348
            if (get_user_s32(domain, vptr)
1349
                || get_user_s32(type, vptr + n)
1350
                || get_user_s32(protocol, vptr + 2 * n))
1351
                return -TARGET_EFAULT;
1352

    
1353
            ret = do_socket(domain, type, protocol);
1354
        }
1355
        break;
1356
    case SOCKOP_bind:
1357
        {
1358
            int sockfd;
1359
            abi_ulong target_addr;
1360
            socklen_t addrlen;
1361

    
1362
            if (get_user_s32(sockfd, vptr)
1363
                || get_user_ual(target_addr, vptr + n)
1364
                || get_user_u32(addrlen, vptr + 2 * n))
1365
                return -TARGET_EFAULT;
1366

    
1367
            ret = do_bind(sockfd, target_addr, addrlen);
1368
        }
1369
        break;
1370
    case SOCKOP_connect:
1371
        {
1372
            int sockfd;
1373
            abi_ulong target_addr;
1374
            socklen_t addrlen;
1375

    
1376
            if (get_user_s32(sockfd, vptr)
1377
                || get_user_ual(target_addr, vptr + n)
1378
                || get_user_u32(addrlen, vptr + 2 * n))
1379
                return -TARGET_EFAULT;
1380

    
1381
            ret = do_connect(sockfd, target_addr, addrlen);
1382
        }
1383
        break;
1384
    case SOCKOP_listen:
1385
        {
1386
            int sockfd, backlog;
1387

    
1388
            if (get_user_s32(sockfd, vptr)
1389
                || get_user_s32(backlog, vptr + n))
1390
                return -TARGET_EFAULT;
1391

    
1392
            ret = get_errno(listen(sockfd, backlog));
1393
        }
1394
        break;
1395
    case SOCKOP_accept:
1396
        {
1397
            int sockfd;
1398
            abi_ulong target_addr, target_addrlen;
1399

    
1400
            if (get_user_s32(sockfd, vptr)
1401
                || get_user_ual(target_addr, vptr + n)
1402
                || get_user_u32(target_addrlen, vptr + 2 * n))
1403
                return -TARGET_EFAULT;
1404

    
1405
            ret = do_accept(sockfd, target_addr, target_addrlen);
1406
        }
1407
        break;
1408
    case SOCKOP_getsockname:
1409
        {
1410
            int sockfd;
1411
            abi_ulong target_addr, target_addrlen;
1412

    
1413
            if (get_user_s32(sockfd, vptr)
1414
                || get_user_ual(target_addr, vptr + n)
1415
                || get_user_u32(target_addrlen, vptr + 2 * n))
1416
                return -TARGET_EFAULT;
1417

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

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

    
1431
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1432
        }
1433
        break;
1434
    case SOCKOP_socketpair:
1435
        {
1436
            int domain, type, protocol;
1437
            abi_ulong tab;
1438

    
1439
            if (get_user_s32(domain, vptr)
1440
                || get_user_s32(type, vptr + n)
1441
                || get_user_s32(protocol, vptr + 2 * n)
1442
                || get_user_ual(tab, vptr + 3 * n))
1443
                return -TARGET_EFAULT;
1444

    
1445
            ret = do_socketpair(domain, type, protocol, tab);
1446
        }
1447
        break;
1448
    case SOCKOP_send:
1449
        {
1450
            int sockfd;
1451
            abi_ulong msg;
1452
            size_t len;
1453
            int flags;
1454

    
1455
            if (get_user_s32(sockfd, vptr)
1456
                || get_user_ual(msg, vptr + n)
1457
                || get_user_ual(len, vptr + 2 * n)
1458
                || get_user_s32(flags, vptr + 3 * n))
1459
                return -TARGET_EFAULT;
1460

    
1461
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1462
        }
1463
        break;
1464
    case SOCKOP_recv:
1465
        {
1466
            int sockfd;
1467
            abi_ulong msg;
1468
            size_t len;
1469
            int flags;
1470

    
1471
            if (get_user_s32(sockfd, vptr)
1472
                || get_user_ual(msg, vptr + n)
1473
                || get_user_ual(len, vptr + 2 * n)
1474
                || get_user_s32(flags, vptr + 3 * n))
1475
                return -TARGET_EFAULT;
1476

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

    
1489
            if (get_user_s32(sockfd, vptr)
1490
                || get_user_ual(msg, vptr + n)
1491
                || get_user_ual(len, vptr + 2 * n)
1492
                || get_user_s32(flags, vptr + 3 * n)
1493
                || get_user_ual(addr, vptr + 4 * n)
1494
                || get_user_u32(addrlen, vptr + 5 * n))
1495
                return -TARGET_EFAULT;
1496

    
1497
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1498
        }
1499
        break;
1500
    case SOCKOP_recvfrom:
1501
        {
1502
            int sockfd;
1503
            abi_ulong msg;
1504
            size_t len;
1505
            int flags;
1506
            abi_ulong addr;
1507
            socklen_t addrlen;
1508

    
1509
            if (get_user_s32(sockfd, vptr)
1510
                || get_user_ual(msg, vptr + n)
1511
                || get_user_ual(len, vptr + 2 * n)
1512
                || get_user_s32(flags, vptr + 3 * n)
1513
                || get_user_ual(addr, vptr + 4 * n)
1514
                || get_user_u32(addrlen, vptr + 5 * n))
1515
                return -TARGET_EFAULT;
1516

    
1517
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1518
        }
1519
        break;
1520
    case SOCKOP_shutdown:
1521
        {
1522
            int sockfd, how;
1523

    
1524
            if (get_user_s32(sockfd, vptr)
1525
                || get_user_s32(how, vptr + n))
1526
                return -TARGET_EFAULT;
1527

    
1528
            ret = get_errno(shutdown(sockfd, how));
1529
        }
1530
        break;
1531
    case SOCKOP_sendmsg:
1532
    case SOCKOP_recvmsg:
1533
        {
1534
            int fd;
1535
            abi_ulong target_msg;
1536
            int flags;
1537

    
1538
            if (get_user_s32(fd, vptr)
1539
                || get_user_ual(target_msg, vptr + n)
1540
                || get_user_s32(flags, vptr + 2 * n))
1541
                return -TARGET_EFAULT;
1542

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

    
1555
            if (get_user_s32(sockfd, vptr)
1556
                || get_user_s32(level, vptr + n)
1557
                || get_user_s32(optname, vptr + 2 * n)
1558
                || get_user_ual(optval, vptr + 3 * n)
1559
                || get_user_u32(optlen, vptr + 4 * n))
1560
                return -TARGET_EFAULT;
1561

    
1562
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1563
        }
1564
        break;
1565
    case SOCKOP_getsockopt:
1566
        {
1567
            int sockfd;
1568
            int level;
1569
            int optname;
1570
            abi_ulong optval;
1571
            socklen_t optlen;
1572

    
1573
            if (get_user_s32(sockfd, vptr)
1574
                || get_user_s32(level, vptr + n)
1575
                || get_user_s32(optname, vptr + 2 * n)
1576
                || get_user_ual(optval, vptr + 3 * n)
1577
                || get_user_u32(optlen, vptr + 4 * n))
1578
                return -TARGET_EFAULT;
1579

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

    
1592
#ifdef TARGET_NR_ipc
1593
#define N_SHM_REGIONS        32
1594

    
1595
static struct shm_region {
1596
    abi_ulong        start;
1597
    abi_ulong        size;
1598
} shm_regions[N_SHM_REGIONS];
1599

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

    
1615
struct target_semid_ds
1616
{
1617
  struct target_ipc_perm sem_perm;
1618
  abi_ulong sem_otime;
1619
  abi_ulong __unused1;
1620
  abi_ulong sem_ctime;
1621
  abi_ulong __unused2;
1622
  abi_ulong sem_nsems;
1623
  abi_ulong __unused3;
1624
  abi_ulong __unused4;
1625
};
1626

    
1627
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1628
                                               abi_ulong target_addr)
1629
{
1630
    struct target_ipc_perm *target_ip;
1631
    struct target_semid_ds *target_sd;
1632

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

    
1646
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1647
                                               struct ipc_perm *host_ip)
1648
{
1649
    struct target_ipc_perm *target_ip;
1650
    struct target_semid_ds *target_sd;
1651

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

    
1665
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1666
                                               abi_ulong target_addr)
1667
{
1668
    struct target_semid_ds *target_sd;
1669

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

    
1680
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1681
                                               struct semid_ds *host_sd)
1682
{
1683
    struct target_semid_ds *target_sd;
1684

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

    
1695
union semun {
1696
        int val;
1697
        struct semid_ds *buf;
1698
        unsigned short *array;
1699
};
1700

    
1701
union target_semun {
1702
        int val;
1703
        abi_long buf;
1704
        unsigned short int *array;
1705
};
1706

    
1707
static inline abi_long target_to_host_semun(int cmd,
1708
                                            union semun *host_su,
1709
                                            abi_ulong target_addr,
1710
                                            struct semid_ds *ds)
1711
{
1712
    union target_semun *target_su;
1713

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

    
1743
static inline abi_long host_to_target_semun(int cmd,
1744
                                            abi_ulong target_addr,
1745
                                            union semun *host_su,
1746
                                            struct semid_ds *ds)
1747
{
1748
    union target_semun *target_su;
1749

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

    
1778
static inline abi_long do_semctl(int first, int second, int third,
1779
                                 abi_long ptr)
1780
{
1781
    union semun arg;
1782
    struct semid_ds dsarg;
1783
    int cmd = third&0xff;
1784
    abi_long ret = 0;
1785

    
1786
    switch( cmd ) {
1787
        case GETVAL:
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 SETVAL:
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 GETALL:
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 SETALL:
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_STAT:
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
        case IPC_SET:
1813
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1814
            ret = get_errno(semctl(first, second, cmd, arg));
1815
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1816
            break;
1817
    default:
1818
            ret = get_errno(semctl(first, second, cmd, arg));
1819
    }
1820

    
1821
    return ret;
1822
}
1823

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

    
1842
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1843
                                               abi_ulong target_addr)
1844
{
1845
    struct target_msqid_ds *target_md;
1846

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

    
1862
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1863
                                               struct msqid_ds *host_md)
1864
{
1865
    struct target_msqid_ds *target_md;
1866

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

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

    
1899
struct target_msgbuf {
1900
        abi_ulong mtype;
1901
        char        mtext[1];
1902
};
1903

    
1904
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1905
                                 unsigned int msgsz, int msgflg)
1906
{
1907
    struct target_msgbuf *target_mb;
1908
    struct msgbuf *host_mb;
1909
    abi_long ret = 0;
1910

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

    
1920
    return ret;
1921
}
1922

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

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

    
1949
end:
1950
    if (target_mb)
1951
        unlock_user_struct(target_mb, msgp, 1);
1952
    return ret;
1953
}
1954

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

    
1966
    version = call >> 16;
1967
    call &= 0xffff;
1968

    
1969
    switch (call) {
1970
    case IPCOP_semop:
1971
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
1972
        break;
1973

    
1974
    case IPCOP_semget:
1975
        ret = get_errno(semget(first, second, third));
1976
        break;
1977

    
1978
    case IPCOP_semctl:
1979
        ret = do_semctl(first, second, third, ptr);
1980
        break;
1981

    
1982
    case IPCOP_semtimedop:
1983
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
1984
        ret = -TARGET_ENOSYS;
1985
        break;
1986

    
1987
        case IPCOP_msgget:
1988
                ret = get_errno(msgget(first, second));
1989
                break;
1990

    
1991
        case IPCOP_msgsnd:
1992
                ret = do_msgsnd(first, ptr, second, third);
1993
                break;
1994

    
1995
        case IPCOP_msgctl:
1996
                ret = do_msgctl(first, second, ptr);
1997
                break;
1998

    
1999
        case IPCOP_msgrcv:
2000
                {
2001
                      /* XXX: this code is not correct */
2002
                      struct ipc_kludge
2003
                      {
2004
                              void *__unbounded msgp;
2005
                              long int msgtyp;
2006
                      };
2007

    
2008
                      struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
2009
                      struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
2010

    
2011
                      ret = do_msgrcv(first, (long)msgp, second, 0, third);
2012

    
2013
                }
2014
                break;
2015

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

    
2061
    case IPCOP_shmget:
2062
        /* IPC_* flag values are the same on all linux platforms */
2063
        ret = get_errno(shmget(first, second, third));
2064
        break;
2065

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

    
2088
/* kernel structure types definitions */
2089
#define IFNAMSIZ        16
2090

    
2091
#define STRUCT(name, list...) STRUCT_ ## name,
2092
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2093
enum {
2094
#include "syscall_types.h"
2095
};
2096
#undef STRUCT
2097
#undef STRUCT_SPECIAL
2098

    
2099
#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2100
#define STRUCT_SPECIAL(name)
2101
#include "syscall_types.h"
2102
#undef STRUCT
2103
#undef STRUCT_SPECIAL
2104

    
2105
typedef struct IOCTLEntry {
2106
    unsigned int target_cmd;
2107
    unsigned int host_cmd;
2108
    const char *name;
2109
    int access;
2110
    const argtype arg_type[5];
2111
} IOCTLEntry;
2112

    
2113
#define IOC_R 0x0001
2114
#define IOC_W 0x0002
2115
#define IOC_RW (IOC_R | IOC_W)
2116

    
2117
#define MAX_STRUCT_SIZE 4096
2118

    
2119
IOCTLEntry ioctl_entries[] = {
2120
#define IOCTL(cmd, access, types...) \
2121
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2122
#include "ioctls.h"
2123
    { 0, 0, },
2124
};
2125

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

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

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

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

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

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

    
2310
static void target_to_host_termios (void *dst, const void *src)
2311
{
2312
    struct host_termios *host = dst;
2313
    const struct target_termios *target = src;
2314

    
2315
    host->c_iflag =
2316
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2317
    host->c_oflag =
2318
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2319
    host->c_cflag =
2320
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2321
    host->c_lflag =
2322
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2323
    host->c_line = target->c_line;
2324

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

    
2344
static void host_to_target_termios (void *dst, const void *src)
2345
{
2346
    struct target_termios *target = dst;
2347
    const struct host_termios *host = src;
2348

    
2349
    target->c_iflag =
2350
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2351
    target->c_oflag =
2352
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2353
    target->c_cflag =
2354
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2355
    target->c_lflag =
2356
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2357
    target->c_line = host->c_line;
2358

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

    
2378
StructEntry struct_termios_def = {
2379
    .convert = { host_to_target_termios, target_to_host_termios },
2380
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2381
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2382
};
2383

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

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

    
2416
#if defined(TARGET_I386)
2417

    
2418
/* NOTE: there is really one LDT for all the threads */
2419
uint8_t *ldt_table;
2420

    
2421
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2422
{
2423
    int size;
2424
    void *p;
2425

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

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

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

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

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

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

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

    
2528
/* specific and weird i386 syscalls */
2529
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2530
                              unsigned long bytecount)
2531
{
2532
    abi_long ret;
2533

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

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

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

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

    
2594
    if (contents == 3) {
2595
        if (seg_not_present == 0)
2596
            return -TARGET_EINVAL;
2597
    }
2598

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

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

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

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

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

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

    
2718
#endif /* defined(TARGET_I386) */
2719

    
2720
#if defined(USE_NPTL)
2721

    
2722
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2723

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

    
2736
static void *clone_func(void *arg)
2737
{
2738
    new_thread_info *info = arg;
2739
    CPUState *env;
2740

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

    
2766
static int clone_func(void *arg)
2767
{
2768
    CPUState *env = arg;
2769
    cpu_loop(env);
2770
    /* never exits */
2771
    return 0;
2772
}
2773
#endif
2774

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

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

    
2807
        /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2808
        if (nptl_flags & CLONE_SETTLS)
2809
            cpu_set_tls (new_env, newtls);
2810

    
2811
        /* Grab a mutex so that thread setup appears atomic.  */
2812
        pthread_mutex_lock(&clone_lock);
2813

    
2814
        memset(&info, 0, sizeof(info));
2815
        pthread_mutex_init(&info.mutex, NULL);
2816
        pthread_mutex_lock(&info.mutex);
2817
        pthread_cond_init(&info.cond, NULL);
2818
        info.env = new_env;
2819
        if (nptl_flags & CLONE_CHILD_SETTID)
2820
            info.child_tidptr = child_tidptr;
2821
        if (nptl_flags & CLONE_PARENT_SETTID)
2822
            info.parent_tidptr = parent_tidptr;
2823

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

    
2831
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
2832

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

    
2895
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2896
{
2897
    struct flock fl;
2898
    struct target_flock *target_fl;
2899
    struct flock64 fl64;
2900
    struct target_flock64 *target_fl64;
2901
    abi_long ret;
2902

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

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

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

    
2973
    case F_GETFL:
2974
        ret = get_errno(fcntl(fd, cmd, arg));
2975
        if (ret >= 0) {
2976
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
2977
        }
2978
        break;
2979

    
2980
    case F_SETFL:
2981
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
2982
        break;
2983

    
2984
    default:
2985
        ret = get_errno(fcntl(fd, cmd, arg));
2986
        break;
2987
    }
2988
    return ret;
2989
}
2990

    
2991
#ifdef USE_UID16
2992

    
2993
static inline int high2lowuid(int uid)
2994
{
2995
    if (uid > 65535)
2996
        return 65534;
2997
    else
2998
        return uid;
2999
}
3000

    
3001
static inline int high2lowgid(int gid)
3002
{
3003
    if (gid > 65535)
3004
        return 65534;
3005
    else
3006
        return gid;
3007
}
3008

    
3009
static inline int low2highuid(int uid)
3010
{
3011
    if ((int16_t)uid == -1)
3012
        return -1;
3013
    else
3014
        return uid;
3015
}
3016

    
3017
static inline int low2highgid(int gid)
3018
{
3019
    if ((int16_t)gid == -1)
3020
        return -1;
3021
    else
3022
        return gid;
3023
}
3024

    
3025
#endif /* USE_UID16 */
3026

    
3027
void syscall_init(void)
3028
{
3029
    IOCTLEntry *ie;
3030
    const argtype *arg_type;
3031
    int size;
3032
    int i;
3033

    
3034
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3035
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3036
#include "syscall_types.h"
3037
#undef STRUCT
3038
#undef STRUCT_SPECIAL
3039

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

    
3059
        /* Build target_to_host_errno_table[] table from
3060
         * host_to_target_errno_table[]. */
3061
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3062
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3063

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

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

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

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

    
3125
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3126
                                               abi_ulong target_addr)
3127
{
3128
    struct target_timespec *target_ts;
3129

    
3130
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3131
        return -TARGET_EFAULT;
3132
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3133
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3134
    unlock_user_struct(target_ts, target_addr, 0);
3135
    return 0;
3136
}
3137

    
3138
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3139
                                               struct timespec *host_ts)
3140
{
3141
    struct target_timespec *target_ts;
3142

    
3143
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3144
        return -TARGET_EFAULT;
3145
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3146
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3147
    unlock_user_struct(target_ts, target_addr, 1);
3148
    return 0;
3149
}
3150

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

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

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

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

    
3233
#ifdef DEBUG
3234
    gemu_log("syscall %d", num);
3235
#endif
3236
    if(do_strace)
3237
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3238

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

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

    
3396
            argp = alloca((argc + 1) * sizeof(void *));
3397
            envp = alloca((envc + 1) * sizeof(void *));
3398

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

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

    
3421
            if (!(p = lock_user_string(arg1)))
3422
                goto execve_efault;
3423
            ret = get_errno(execve(p, argp, envp));
3424
            unlock_user(p, arg1, 0);
3425

    
3426
            goto execve_end;
3427

    
3428
        execve_efault:
3429
            ret = -TARGET_EFAULT;
3430

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

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

    
3840
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3841

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

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

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

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

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

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

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

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

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

    
4498
    case TARGET_NR_syslog:
4499
        if (!(p = lock_user_string(arg2)))
4500
            goto efault;
4501
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4502
        unlock_user(p, arg2, 0);
4503
        break;
4504

    
4505
    case TARGET_NR_setitimer:
4506
        {
4507
            struct itimerval value, ovalue, *pvalue;
4508

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

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

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

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

    
4770
            dirp = malloc(count);
4771
            if (!dirp) {
4772
                ret = -TARGET_ENOMEM;
4773
                goto fail;
4774
            }
4775

    
4776
            ret = get_errno(sys_getdents(arg1, dirp, count));
4777
            if (!is_error(ret)) {
4778
                struct dirent *de;
4779
                struct target_dirent *tde;
4780
                int len = ret;
4781
                int reclen, treclen;
4782
                int count1, tnamelen;
4783

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5526
        switch(arg2){
5527
        case TARGET_F_GETLK64:
5528
            cmd = F_GETLK64;
5529
            break;
5530
        case TARGET_F_SETLK64:
5531
            cmd = F_SETLK64;
5532
            break;
5533
        case TARGET_F_SETLKW64:
5534
            cmd = F_SETLK64;
5535
            break;
5536
        default:
5537
            cmd = arg2;
5538
            break;
5539
        }
5540

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

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

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

    
5722
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5723
    case TARGET_NR_set_tid_address:
5724
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
5725
        break;
5726
#endif
5727

    
5728
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5729
    case TARGET_NR_tkill:
5730
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5731
        break;
5732
#endif
5733

    
5734
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5735
    case TARGET_NR_tgkill:
5736
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5737
                        target_to_host_signal(arg3)));
5738
        break;
5739
#endif
5740

    
5741
#ifdef TARGET_NR_set_robust_list
5742
    case TARGET_NR_set_robust_list:
5743
        goto unimplemented_nowarn;
5744
#endif
5745

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

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