Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 4583f589

History | View | Annotate | Download (180.2 kB)

1
/*
2
 *  Linux syscalls
3
 *
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 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) && defined(USE_UID16)
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
#if TARGET_ABI_BITS == 32
204
_syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
205
#endif
206
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
207
_syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
208
#endif
209
_syscall2(int, sys_getpriority, int, which, int, who);
210
#if !defined (__x86_64__)
211
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
212
          loff_t *, res, uint, wh);
213
#endif
214
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
215
_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
216
          int,newdirfd,const char *,newpath,int,flags)
217
#endif
218
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
219
_syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
220
#endif
221
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
222
_syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
223
          mode_t,mode,dev_t,dev)
224
#endif
225
#if defined(TARGET_NR_openat) && defined(__NR_openat)
226
_syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
227
#endif
228
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
229
_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
230
          char *,buf,size_t,bufsize)
231
#endif
232
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
233
_syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
234
          int,newdirfd,const char *,newpath)
235
#endif
236
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
237
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
238
_syscall3(int,sys_symlinkat,const char *,oldpath,
239
          int,newdirfd,const char *,newpath)
240
#endif
241
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
242
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
243
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
244
#endif
245
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
246
_syscall2(int,sys_tkill,int,tid,int,sig)
247
#endif
248
#ifdef __NR_exit_group
249
_syscall1(int,exit_group,int,error_code)
250
#endif
251
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
252
_syscall1(int,set_tid_address,int *,tidptr)
253
#endif
254
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
255
_syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
256
#endif
257
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
258
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
259
          const struct timespec *,tsp,int,flags)
260
#endif
261
#if defined(USE_NPTL)
262
#if defined(TARGET_NR_futex) && defined(__NR_futex)
263
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
264
          const struct timespec *,timeout,int *,uaddr2,int,val3)
265
#endif
266
#endif
267

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

    
278
#define ERRNO_TABLE_SIZE 1200
279

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

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

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

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

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

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

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

    
429
static abi_ulong target_brk;
430
static abi_ulong target_original_brk;
431

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

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

    
444
    if (!new_brk)
445
        return target_brk;
446
    if (new_brk < target_original_brk)
447
        return target_brk;
448

    
449
    brk_page = HOST_PAGE_ALIGN(target_brk);
450

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

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

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

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

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

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

    
496
    unlock_user(target_fds, target_fds_addr, 0);
497

    
498
    return 0;
499
}
500

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

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

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

    
526
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
527

    
528
    return 0;
529
}
530

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

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

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

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

    
573
    return 0;
574
}
575

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

    
581
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
582
        return -TARGET_EFAULT;
583

    
584
    __get_user(tv->tv_sec, &target_tv->tv_sec);
585
    __get_user(tv->tv_usec, &target_tv->tv_usec);
586

    
587
    unlock_user_struct(target_tv, target_tv_addr, 0);
588

    
589
    return 0;
590
}
591

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

    
597
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
598
        return -TARGET_EFAULT;
599

    
600
    __put_user(tv->tv_sec, &target_tv->tv_sec);
601
    __put_user(tv->tv_usec, &target_tv->tv_usec);
602

    
603
    unlock_user_struct(target_tv, target_tv_addr, 1);
604

    
605
    return 0;
606
}
607

    
608

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

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

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

    
649
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
650

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

    
659
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
660
            return -TARGET_EFAULT;
661
    }
662

    
663
    return ret;
664
}
665

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

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

    
679
    return 0;
680
}
681

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

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

    
695
    return 0;
696
}
697

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

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

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

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

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

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

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

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

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

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

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

    
777
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
778

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1090
    return 0;
1091
}
1092

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

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

    
1129
    target_to_host_sockaddr(addr, target_addr, addrlen);
1130
    return get_errno(bind(sockfd, addr, addrlen));
1131
}
1132

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

    
1139
    target_to_host_sockaddr(addr, target_addr, addrlen);
1140
    return get_errno(connect(sockfd, addr, addrlen));
1141
}
1142

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

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

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

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

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

    
1202
    if (get_user_u32(addrlen, target_addrlen_addr))
1203
        return -TARGET_EFAULT;
1204

    
1205
    addr = alloca(addrlen);
1206

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

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

    
1224
    if (get_user_u32(addrlen, target_addrlen_addr))
1225
        return -TARGET_EFAULT;
1226

    
1227
    addr = alloca(addrlen);
1228

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

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

    
1246
    if (get_user_u32(addrlen, target_addrlen_addr))
1247
        return -TARGET_EFAULT;
1248

    
1249
    addr = alloca(addrlen);
1250

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1594
#ifdef TARGET_NR_ipc
1595
#define N_SHM_REGIONS        32
1596

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1823
    return ret;
1824
}
1825

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

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

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

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

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

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

    
1901
struct target_msgbuf {
1902
        abi_ulong mtype;
1903
        char        mtext[1];
1904
};
1905

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

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

    
1922
    return ret;
1923
}
1924

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

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

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

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

    
1968
    version = call >> 16;
1969
    call &= 0xffff;
1970

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

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

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

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

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

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

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

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

    
2010
                      struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
2011
                      struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
2012

    
2013
                      ret = do_msgrcv(first, (long)msgp, second, 0, third);
2014

    
2015
                }
2016
                break;
2017

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

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

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

    
2090
/* kernel structure types definitions */
2091
#define IFNAMSIZ        16
2092

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

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

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

    
2115
#define IOC_R 0x0001
2116
#define IOC_W 0x0002
2117
#define IOC_RW (IOC_R | IOC_W)
2118

    
2119
#define MAX_STRUCT_SIZE 4096
2120

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2418
#if defined(TARGET_I386)
2419

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2597
    if (contents == 3) {
2598
        if (seg_not_present == 0)
2599
            return -TARGET_EINVAL;
2600
    }
2601

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

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

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

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

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

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

    
2722
#endif /* defined(TARGET_I386) */
2723

    
2724
#if defined(USE_NPTL)
2725

    
2726
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2727

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

    
2740
static void *clone_func(void *arg)
2741
{
2742
    new_thread_info *info = arg;
2743
    CPUState *env;
2744

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

    
2770
static int clone_func(void *arg)
2771
{
2772
    CPUState *env = arg;
2773
    cpu_loop(env);
2774
    /* never exits */
2775
    return 0;
2776
}
2777
#endif
2778

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

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

    
2811
        /* TODO: Implement CLONE_CHILD_CLEARTID.  */
2812
        if (nptl_flags & CLONE_SETTLS)
2813
            cpu_set_tls (new_env, newtls);
2814

    
2815
        /* Grab a mutex so that thread setup appears atomic.  */
2816
        pthread_mutex_lock(&clone_lock);
2817

    
2818
        memset(&info, 0, sizeof(info));
2819
        pthread_mutex_init(&info.mutex, NULL);
2820
        pthread_mutex_lock(&info.mutex);
2821
        pthread_cond_init(&info.cond, NULL);
2822
        info.env = new_env;
2823
        if (nptl_flags & CLONE_CHILD_SETTID)
2824
            info.child_tidptr = child_tidptr;
2825
        if (nptl_flags & CLONE_PARENT_SETTID)
2826
            info.parent_tidptr = parent_tidptr;
2827

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

    
2835
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
2836

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

    
2899
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2900
{
2901
    struct flock fl;
2902
    struct target_flock *target_fl;
2903
    struct flock64 fl64;
2904
    struct target_flock64 *target_fl64;
2905
    abi_long ret;
2906

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

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

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

    
2977
    case F_GETFL:
2978
        ret = get_errno(fcntl(fd, cmd, arg));
2979
        if (ret >= 0) {
2980
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
2981
        }
2982
        break;
2983

    
2984
    case F_SETFL:
2985
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
2986
        break;
2987

    
2988
    default:
2989
        ret = get_errno(fcntl(fd, cmd, arg));
2990
        break;
2991
    }
2992
    return ret;
2993
}
2994

    
2995
#ifdef USE_UID16
2996

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

    
3005
static inline int high2lowgid(int gid)
3006
{
3007
    if (gid > 65535)
3008
        return 65534;
3009
    else
3010
        return gid;
3011
}
3012

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

    
3021
static inline int low2highgid(int gid)
3022
{
3023
    if ((int16_t)gid == -1)
3024
        return -1;
3025
    else
3026
        return gid;
3027
}
3028

    
3029
#endif /* USE_UID16 */
3030

    
3031
void syscall_init(void)
3032
{
3033
    IOCTLEntry *ie;
3034
    const argtype *arg_type;
3035
    int size;
3036
    int i;
3037

    
3038
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3039
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3040
#include "syscall_types.h"
3041
#undef STRUCT
3042
#undef STRUCT_SPECIAL
3043

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

    
3063
        /* Build target_to_host_errno_table[] table from
3064
         * host_to_target_errno_table[]. */
3065
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3066
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3067

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

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

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

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

    
3129
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3130
                                               abi_ulong target_addr)
3131
{
3132
    struct target_timespec *target_ts;
3133

    
3134
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3135
        return -TARGET_EFAULT;
3136
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3137
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3138
    unlock_user_struct(target_ts, target_addr, 0);
3139
    return 0;
3140
}
3141

    
3142
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3143
                                               struct timespec *host_ts)
3144
{
3145
    struct target_timespec *target_ts;
3146

    
3147
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3148
        return -TARGET_EFAULT;
3149
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3150
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3151
    unlock_user_struct(target_ts, target_addr, 1);
3152
    return 0;
3153
}
3154

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

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

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

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

    
3237
#ifdef DEBUG
3238
    gemu_log("syscall %d", num);
3239
#endif
3240
    if(do_strace)
3241
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3242

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

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

    
3400
            argp = alloca((argc + 1) * sizeof(void *));
3401
            envp = alloca((envc + 1) * sizeof(void *));
3402

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

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

    
3425
            if (!(p = lock_user_string(arg1)))
3426
                goto execve_efault;
3427
            ret = get_errno(execve(p, argp, envp));
3428
            unlock_user(p, arg1, 0);
3429

    
3430
            goto execve_end;
3431

    
3432
        execve_efault:
3433
            ret = -TARGET_EFAULT;
3434

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

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

    
3844
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3845

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

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

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

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

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

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

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

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

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

    
4502
    case TARGET_NR_syslog:
4503
        if (!(p = lock_user_string(arg2)))
4504
            goto efault;
4505
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4506
        unlock_user(p, arg2, 0);
4507
        break;
4508

    
4509
    case TARGET_NR_setitimer:
4510
        {
4511
            struct itimerval value, ovalue, *pvalue;
4512

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

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

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

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

    
4774
            dirp = malloc(count);
4775
            if (!dirp) {
4776
                ret = -TARGET_ENOMEM;
4777
                goto fail;
4778
            }
4779

    
4780
            ret = get_errno(sys_getdents(arg1, dirp, count));
4781
            if (!is_error(ret)) {
4782
                struct dirent *de;
4783
                struct target_dirent *tde;
4784
                int len = ret;
4785
                int reclen, treclen;
4786
                int count1, tnamelen;
4787

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5530
        switch(arg2){
5531
        case TARGET_F_GETLK64:
5532
            cmd = F_GETLK64;
5533
            break;
5534
        case TARGET_F_SETLK64:
5535
            cmd = F_SETLK64;
5536
            break;
5537
        case TARGET_F_SETLKW64:
5538
            cmd = F_SETLK64;
5539
            break;
5540
        default:
5541
            cmd = arg2;
5542
            break;
5543
        }
5544

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

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

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

    
5726
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
5727
    case TARGET_NR_set_tid_address:
5728
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
5729
        break;
5730
#endif
5731

    
5732
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
5733
    case TARGET_NR_tkill:
5734
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
5735
        break;
5736
#endif
5737

    
5738
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
5739
    case TARGET_NR_tgkill:
5740
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
5741
                        target_to_host_signal(arg3)));
5742
        break;
5743
#endif
5744

    
5745
#ifdef TARGET_NR_set_robust_list
5746
    case TARGET_NR_set_robust_list:
5747
        goto unimplemented_nowarn;
5748
#endif
5749

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

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