Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 4cb05961

History | View | Annotate | Download (175.3 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 <sys/types.h>
31
#include <sys/ipc.h>
32
#include <sys/msg.h>
33
#include <sys/wait.h>
34
#include <sys/time.h>
35
#include <sys/stat.h>
36
#include <sys/mount.h>
37
#include <sys/prctl.h>
38
#include <sys/resource.h>
39
#include <sys/mman.h>
40
#include <sys/swap.h>
41
#include <signal.h>
42
#include <sched.h>
43
#include <sys/socket.h>
44
#include <sys/uio.h>
45
#include <sys/poll.h>
46
#include <sys/times.h>
47
#include <sys/shm.h>
48
#include <sys/sem.h>
49
#include <sys/statfs.h>
50
#include <utime.h>
51
#include <sys/sysinfo.h>
52
//#include <sys/user.h>
53
#include <netinet/ip.h>
54
#include <netinet/tcp.h>
55
#if defined(USE_NPTL)
56
#include <sys/futex.h>
57
#endif
58

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

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

    
76
#include "qemu.h"
77

    
78
//#define DEBUG
79

    
80
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
81
    || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
82
/* 16 bit uid wrappers emulation */
83
#define USE_UID16
84
#endif
85

    
86
//#include <linux/msdos_fs.h>
87
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct dirent [2])
88
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct dirent [2])
89

    
90

    
91
#undef _syscall0
92
#undef _syscall1
93
#undef _syscall2
94
#undef _syscall3
95
#undef _syscall4
96
#undef _syscall5
97
#undef _syscall6
98

    
99
#define _syscall0(type,name)                \
100
type name (void)                        \
101
{                                        \
102
        return syscall(__NR_##name);        \
103
}
104

    
105
#define _syscall1(type,name,type1,arg1)                \
106
type name (type1 arg1)                                \
107
{                                                \
108
        return syscall(__NR_##name, arg1);        \
109
}
110

    
111
#define _syscall2(type,name,type1,arg1,type2,arg2)        \
112
type name (type1 arg1,type2 arg2)                        \
113
{                                                        \
114
        return syscall(__NR_##name, arg1, arg2);        \
115
}
116

    
117
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)        \
118
type name (type1 arg1,type2 arg2,type3 arg3)                        \
119
{                                                                \
120
        return syscall(__NR_##name, arg1, arg2, arg3);                \
121
}
122

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

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

    
136

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

    
144

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

    
168
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
169
#define __NR__llseek __NR_lseek
170
#endif
171

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

    
254
extern int personality(int);
255
extern int flock(int, int);
256
extern int setfsuid(int);
257
extern int setfsgid(int);
258
extern int setresuid(uid_t, uid_t, uid_t);
259
extern int getresuid(uid_t *, uid_t *, uid_t *);
260
extern int setresgid(gid_t, gid_t, gid_t);
261
extern int getresgid(gid_t *, gid_t *, gid_t *);
262
extern int setgroups(int, gid_t *);
263

    
264
#define ERRNO_TABLE_SIZE 1200
265

    
266
/* target_to_host_errno_table[] is initialized from
267
 * host_to_target_errno_table[] in syscall_init(). */
268
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
269
};
270

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

    
383
static inline int host_to_target_errno(int err)
384
{
385
    if(host_to_target_errno_table[err])
386
        return host_to_target_errno_table[err];
387
    return err;
388
}
389

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

    
397
static inline abi_long get_errno(abi_long ret)
398
{
399
    if (ret == -1)
400
        return -host_to_target_errno(errno);
401
    else
402
        return ret;
403
}
404

    
405
static inline int is_error(abi_long ret)
406
{
407
    return (abi_ulong)ret >= (abi_ulong)(-4096);
408
}
409

    
410
char *target_strerror(int err)
411
{
412
    return strerror(target_to_host_errno(err));
413
}
414

    
415
static abi_ulong target_brk;
416
static abi_ulong target_original_brk;
417

    
418
void target_set_brk(abi_ulong new_brk)
419
{
420
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
421
}
422

    
423
/* do_brk() must return target values and target errnos. */
424
abi_long do_brk(abi_ulong new_brk)
425
{
426
    abi_ulong brk_page;
427
    abi_long mapped_addr;
428
    int        new_alloc_size;
429

    
430
    if (!new_brk)
431
        return target_brk;
432
    if (new_brk < target_original_brk)
433
        return target_brk;
434

    
435
    brk_page = HOST_PAGE_ALIGN(target_brk);
436

    
437
    /* If the new brk is less than this, set it and we're done... */
438
    if (new_brk < brk_page) {
439
        target_brk = new_brk;
440
            return target_brk;
441
    }
442

    
443
    /* We need to allocate more memory after the brk... */
444
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
445
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
446
                                        PROT_READ|PROT_WRITE,
447
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
448

    
449
    if (!is_error(mapped_addr))
450
        target_brk = new_brk;
451
    
452
    return target_brk;
453
}
454

    
455
static inline abi_long copy_from_user_fdset(fd_set *fds,
456
                                            abi_ulong target_fds_addr,
457
                                            int n)
458
{
459
    int i, nw, j, k;
460
    abi_ulong b, *target_fds;
461

    
462
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
463
    if (!(target_fds = lock_user(VERIFY_READ,
464
                                 target_fds_addr,
465
                                 sizeof(abi_ulong) * nw,
466
                                 1)))
467
        return -TARGET_EFAULT;
468

    
469
    FD_ZERO(fds);
470
    k = 0;
471
    for (i = 0; i < nw; i++) {
472
        /* grab the abi_ulong */
473
        __get_user(b, &target_fds[i]);
474
        for (j = 0; j < TARGET_ABI_BITS; j++) {
475
            /* check the bit inside the abi_ulong */
476
            if ((b >> j) & 1)
477
                FD_SET(k, fds);
478
            k++;
479
        }
480
    }
481

    
482
    unlock_user(target_fds, target_fds_addr, 0);
483

    
484
    return 0;
485
}
486

    
487
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
488
                                          const fd_set *fds,
489
                                          int n)
490
{
491
    int i, nw, j, k;
492
    abi_long v;
493
    abi_ulong *target_fds;
494

    
495
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
496
    if (!(target_fds = lock_user(VERIFY_WRITE,
497
                                 target_fds_addr,
498
                                 sizeof(abi_ulong) * nw,
499
                                 0)))
500
        return -TARGET_EFAULT;
501

    
502
    k = 0;
503
    for (i = 0; i < nw; i++) {
504
        v = 0;
505
        for (j = 0; j < TARGET_ABI_BITS; j++) {
506
            v |= ((FD_ISSET(k, fds) != 0) << j);
507
            k++;
508
        }
509
        __put_user(v, &target_fds[i]);
510
    }
511

    
512
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
513

    
514
    return 0;
515
}
516

    
517
#if defined(__alpha__)
518
#define HOST_HZ 1024
519
#else
520
#define HOST_HZ 100
521
#endif
522

    
523
static inline abi_long host_to_target_clock_t(long ticks)
524
{
525
#if HOST_HZ == TARGET_HZ
526
    return ticks;
527
#else
528
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
529
#endif
530
}
531

    
532
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
533
                                             const struct rusage *rusage)
534
{
535
    struct target_rusage *target_rusage;
536

    
537
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
538
        return -TARGET_EFAULT;
539
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
540
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
541
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
542
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
543
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
544
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
545
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
546
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
547
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
548
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
549
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
550
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
551
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
552
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
553
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
554
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
555
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
556
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
557
    unlock_user_struct(target_rusage, target_addr, 1);
558

    
559
    return 0;
560
}
561

    
562
static inline abi_long copy_from_user_timeval(struct timeval *tv,
563
                                              abi_ulong target_tv_addr)
564
{
565
    struct target_timeval *target_tv;
566

    
567
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
568
        return -TARGET_EFAULT;
569

    
570
    __get_user(tv->tv_sec, &target_tv->tv_sec);
571
    __get_user(tv->tv_usec, &target_tv->tv_usec);
572

    
573
    unlock_user_struct(target_tv, target_tv_addr, 0);
574

    
575
    return 0;
576
}
577

    
578
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
579
                                            const struct timeval *tv)
580
{
581
    struct target_timeval *target_tv;
582

    
583
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
584
        return -TARGET_EFAULT;
585

    
586
    __put_user(tv->tv_sec, &target_tv->tv_sec);
587
    __put_user(tv->tv_usec, &target_tv->tv_usec);
588

    
589
    unlock_user_struct(target_tv, target_tv_addr, 1);
590

    
591
    return 0;
592
}
593

    
594

    
595
/* do_select() must return target values and target errnos. */
596
static abi_long do_select(int n,
597
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
598
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
599
{
600
    fd_set rfds, wfds, efds;
601
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
602
    struct timeval tv, *tv_ptr;
603
    abi_long ret;
604

    
605
    if (rfd_addr) {
606
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
607
            return -TARGET_EFAULT;
608
        rfds_ptr = &rfds;
609
    } else {
610
        rfds_ptr = NULL;
611
    }
612
    if (wfd_addr) {
613
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
614
            return -TARGET_EFAULT;
615
        wfds_ptr = &wfds;
616
    } else {
617
        wfds_ptr = NULL;
618
    }
619
    if (efd_addr) {
620
        if (copy_from_user_fdset(&efds, efd_addr, n))
621
            return -TARGET_EFAULT;
622
        efds_ptr = &efds;
623
    } else {
624
        efds_ptr = NULL;
625
    }
626

    
627
    if (target_tv_addr) {
628
        if (copy_from_user_timeval(&tv, target_tv_addr))
629
            return -TARGET_EFAULT;
630
        tv_ptr = &tv;
631
    } else {
632
        tv_ptr = NULL;
633
    }
634

    
635
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
636

    
637
    if (!is_error(ret)) {
638
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
639
            return -TARGET_EFAULT;
640
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
641
            return -TARGET_EFAULT;
642
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
643
            return -TARGET_EFAULT;
644

    
645
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
646
            return -TARGET_EFAULT;
647
    }
648

    
649
    return ret;
650
}
651

    
652
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
653
                                               abi_ulong target_addr,
654
                                               socklen_t len)
655
{
656
    struct target_sockaddr *target_saddr;
657

    
658
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
659
    if (!target_saddr)
660
        return -TARGET_EFAULT;
661
    memcpy(addr, target_saddr, len);
662
    addr->sa_family = tswap16(target_saddr->sa_family);
663
    unlock_user(target_saddr, target_addr, 0);
664

    
665
    return 0;
666
}
667

    
668
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
669
                                               struct sockaddr *addr,
670
                                               socklen_t len)
671
{
672
    struct target_sockaddr *target_saddr;
673

    
674
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
675
    if (!target_saddr)
676
        return -TARGET_EFAULT;
677
    memcpy(target_saddr, addr, len);
678
    target_saddr->sa_family = tswap16(addr->sa_family);
679
    unlock_user(target_saddr, target_addr, len);
680

    
681
    return 0;
682
}
683

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

    
702
    while (cmsg && target_cmsg) {
703
        void *data = CMSG_DATA(cmsg);
704
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
705

    
706
        int len = tswapl(target_cmsg->cmsg_len)
707
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
708

    
709
        space += CMSG_SPACE(len);
710
        if (space > msgh->msg_controllen) {
711
            space -= CMSG_SPACE(len);
712
            gemu_log("Host cmsg overflow\n");
713
            break;
714
        }
715

    
716
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
717
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
718
        cmsg->cmsg_len = CMSG_LEN(len);
719

    
720
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
721
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
722
            memcpy(data, target_data, len);
723
        } else {
724
            int *fd = (int *)data;
725
            int *target_fd = (int *)target_data;
726
            int i, numfds = len / sizeof(int);
727

    
728
            for (i = 0; i < numfds; i++)
729
                fd[i] = tswap32(target_fd[i]);
730
        }
731

    
732
        cmsg = CMSG_NXTHDR(msgh, cmsg);
733
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
734
    }
735
    unlock_user(target_cmsg, target_cmsg_addr, 0);
736
 the_end:
737
    msgh->msg_controllen = space;
738
    return 0;
739
}
740

    
741
/* ??? Should this also swap msgh->name?  */
742
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
743
                                           struct msghdr *msgh)
744
{
745
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
746
    abi_long msg_controllen;
747
    abi_ulong target_cmsg_addr;
748
    struct target_cmsghdr *target_cmsg;
749
    socklen_t space = 0;
750

    
751
    msg_controllen = tswapl(target_msgh->msg_controllen);
752
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
753
        goto the_end;
754
    target_cmsg_addr = tswapl(target_msgh->msg_control);
755
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
756
    if (!target_cmsg)
757
        return -TARGET_EFAULT;
758

    
759
    while (cmsg && target_cmsg) {
760
        void *data = CMSG_DATA(cmsg);
761
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
762

    
763
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
764

    
765
        space += TARGET_CMSG_SPACE(len);
766
        if (space > msg_controllen) {
767
            space -= TARGET_CMSG_SPACE(len);
768
            gemu_log("Target cmsg overflow\n");
769
            break;
770
        }
771

    
772
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
773
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
774
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
775

    
776
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
777
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
778
            memcpy(target_data, data, len);
779
        } else {
780
            int *fd = (int *)data;
781
            int *target_fd = (int *)target_data;
782
            int i, numfds = len / sizeof(int);
783

    
784
            for (i = 0; i < numfds; i++)
785
                target_fd[i] = tswap32(fd[i]);
786
        }
787

    
788
        cmsg = CMSG_NXTHDR(msgh, cmsg);
789
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
790
    }
791
    unlock_user(target_cmsg, target_cmsg_addr, space);
792
 the_end:
793
    target_msgh->msg_controllen = tswapl(space);
794
    return 0;
795
}
796

    
797
/* do_setsockopt() Must return target values and target errnos. */
798
static abi_long do_setsockopt(int sockfd, int level, int optname,
799
                              abi_ulong optval_addr, socklen_t optlen)
800
{
801
    abi_long ret;
802
    int val;
803

    
804
    switch(level) {
805
    case SOL_TCP:
806
        /* TCP options all take an 'int' value.  */
807
        if (optlen < sizeof(uint32_t))
808
            return -TARGET_EINVAL;
809

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

    
911
        if (get_user_u32(val, optval_addr))
912
            return -TARGET_EFAULT;
913
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
914
        break;
915
    default:
916
    unimplemented:
917
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
918
        ret = -TARGET_ENOPROTOOPT;
919
    }
920
    return ret;
921
}
922

    
923
/* do_getsockopt() Must return target values and target errnos. */
924
static abi_long do_getsockopt(int sockfd, int level, int optname,
925
                              abi_ulong optval_addr, abi_ulong optlen)
926
{
927
    abi_long ret;
928
    int len, lv, val;
929

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

    
1022
/* FIXME
1023
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1024
 * other lock functions have a return code of 0 for failure.
1025
 */
1026
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1027
                           int count, int copy)
1028
{
1029
    struct target_iovec *target_vec;
1030
    abi_ulong base;
1031
    int i, j;
1032

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

    
1060
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1061
                             int count, int copy)
1062
{
1063
    struct target_iovec *target_vec;
1064
    abi_ulong base;
1065
    int i;
1066

    
1067
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1068
    if (!target_vec)
1069
        return -TARGET_EFAULT;
1070
    for(i = 0;i < count; i++) {
1071
        base = tswapl(target_vec[i].iov_base);
1072
        unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1073
    }
1074
    unlock_user (target_vec, target_addr, 0);
1075

    
1076
    return 0;
1077
}
1078

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

    
1109
/* do_bind() Must return target values and target errnos. */
1110
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1111
                        socklen_t addrlen)
1112
{
1113
    void *addr = alloca(addrlen);
1114

    
1115
    target_to_host_sockaddr(addr, target_addr, addrlen);
1116
    return get_errno(bind(sockfd, addr, addrlen));
1117
}
1118

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

    
1125
    target_to_host_sockaddr(addr, target_addr, addrlen);
1126
    return get_errno(connect(sockfd, addr, addrlen));
1127
}
1128

    
1129
/* do_sendrecvmsg() Must return target values and target errnos. */
1130
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1131
                               int flags, int send)
1132
{
1133
    abi_long ret;
1134
    struct target_msghdr *msgp;
1135
    struct msghdr msg;
1136
    int count;
1137
    struct iovec *vec;
1138
    abi_ulong target_vec;
1139

    
1140
    /* FIXME */
1141
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1142
                          msgp,
1143
                          target_msg,
1144
                          send ? 1 : 0))
1145
        return -TARGET_EFAULT;
1146
    if (msgp->msg_name) {
1147
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1148
        msg.msg_name = alloca(msg.msg_namelen);
1149
        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1150
                                msg.msg_namelen);
1151
    } else {
1152
        msg.msg_name = NULL;
1153
        msg.msg_namelen = 0;
1154
    }
1155
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1156
    msg.msg_control = alloca(msg.msg_controllen);
1157
    msg.msg_flags = tswap32(msgp->msg_flags);
1158

    
1159
    count = tswapl(msgp->msg_iovlen);
1160
    vec = alloca(count * sizeof(struct iovec));
1161
    target_vec = tswapl(msgp->msg_iov);
1162
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1163
    msg.msg_iovlen = count;
1164
    msg.msg_iov = vec;
1165

    
1166
    if (send) {
1167
        ret = target_to_host_cmsg(&msg, msgp);
1168
        if (ret == 0)
1169
            ret = get_errno(sendmsg(fd, &msg, flags));
1170
    } else {
1171
        ret = get_errno(recvmsg(fd, &msg, flags));
1172
        if (!is_error(ret))
1173
            ret = host_to_target_cmsg(msgp, &msg);
1174
    }
1175
    unlock_iovec(vec, target_vec, count, !send);
1176
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1177
    return ret;
1178
}
1179

    
1180
/* do_accept() Must return target values and target errnos. */
1181
static abi_long do_accept(int fd, abi_ulong target_addr,
1182
                          abi_ulong target_addrlen_addr)
1183
{
1184
    socklen_t addrlen;
1185
    void *addr;
1186
    abi_long ret;
1187

    
1188
    if (get_user_u32(addrlen, target_addrlen_addr))
1189
        return -TARGET_EFAULT;
1190

    
1191
    addr = alloca(addrlen);
1192

    
1193
    ret = get_errno(accept(fd, addr, &addrlen));
1194
    if (!is_error(ret)) {
1195
        host_to_target_sockaddr(target_addr, addr, addrlen);
1196
        if (put_user_u32(addrlen, target_addrlen_addr))
1197
            ret = -TARGET_EFAULT;
1198
    }
1199
    return ret;
1200
}
1201

    
1202
/* do_getpeername() Must return target values and target errnos. */
1203
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1204
                               abi_ulong target_addrlen_addr)
1205
{
1206
    socklen_t addrlen;
1207
    void *addr;
1208
    abi_long ret;
1209

    
1210
    if (get_user_u32(addrlen, target_addrlen_addr))
1211
        return -TARGET_EFAULT;
1212

    
1213
    addr = alloca(addrlen);
1214

    
1215
    ret = get_errno(getpeername(fd, addr, &addrlen));
1216
    if (!is_error(ret)) {
1217
        host_to_target_sockaddr(target_addr, addr, addrlen);
1218
        if (put_user_u32(addrlen, target_addrlen_addr))
1219
            ret = -TARGET_EFAULT;
1220
    }
1221
    return ret;
1222
}
1223

    
1224
/* do_getsockname() Must return target values and target errnos. */
1225
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1226
                               abi_ulong target_addrlen_addr)
1227
{
1228
    socklen_t addrlen;
1229
    void *addr;
1230
    abi_long ret;
1231

    
1232
    if (get_user_u32(addrlen, target_addrlen_addr))
1233
        return -TARGET_EFAULT;
1234

    
1235
    addr = alloca(addrlen);
1236

    
1237
    ret = get_errno(getsockname(fd, addr, &addrlen));
1238
    if (!is_error(ret)) {
1239
        host_to_target_sockaddr(target_addr, addr, addrlen);
1240
        if (put_user_u32(addrlen, target_addrlen_addr))
1241
            ret = -TARGET_EFAULT;
1242
    }
1243
    return ret;
1244
}
1245

    
1246
/* do_socketpair() Must return target values and target errnos. */
1247
static abi_long do_socketpair(int domain, int type, int protocol,
1248
                              abi_ulong target_tab_addr)
1249
{
1250
    int tab[2];
1251
    abi_long ret;
1252

    
1253
    ret = get_errno(socketpair(domain, type, protocol, tab));
1254
    if (!is_error(ret)) {
1255
        if (put_user_s32(tab[0], target_tab_addr)
1256
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1257
            ret = -TARGET_EFAULT;
1258
    }
1259
    return ret;
1260
}
1261

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

    
1270
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1271
    if (!host_msg)
1272
        return -TARGET_EFAULT;
1273
    if (target_addr) {
1274
        addr = alloca(addrlen);
1275
        target_to_host_sockaddr(addr, target_addr, addrlen);
1276
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1277
    } else {
1278
        ret = get_errno(send(fd, host_msg, len, flags));
1279
    }
1280
    unlock_user(host_msg, msg, 0);
1281
    return ret;
1282
}
1283

    
1284
/* do_recvfrom() Must return target values and target errnos. */
1285
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1286
                            abi_ulong target_addr,
1287
                            abi_ulong target_addrlen)
1288
{
1289
    socklen_t addrlen;
1290
    void *addr;
1291
    void *host_msg;
1292
    abi_long ret;
1293

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

    
1324
#ifdef TARGET_NR_socketcall
1325
/* do_socketcall() Must return target values and target errnos. */
1326
static abi_long do_socketcall(int num, abi_ulong vptr)
1327
{
1328
    abi_long ret;
1329
    const int n = sizeof(abi_ulong);
1330

    
1331
    switch(num) {
1332
    case SOCKOP_socket:
1333
        {
1334
            int domain, type, protocol;
1335

    
1336
            if (get_user_s32(domain, vptr)
1337
                || get_user_s32(type, vptr + n)
1338
                || get_user_s32(protocol, vptr + 2 * n))
1339
                return -TARGET_EFAULT;
1340

    
1341
            ret = do_socket(domain, type, protocol);
1342
        }
1343
        break;
1344
    case SOCKOP_bind:
1345
        {
1346
            int sockfd;
1347
            abi_ulong target_addr;
1348
            socklen_t addrlen;
1349

    
1350
            if (get_user_s32(sockfd, vptr)
1351
                || get_user_ual(target_addr, vptr + n)
1352
                || get_user_u32(addrlen, vptr + 2 * n))
1353
                return -TARGET_EFAULT;
1354

    
1355
            ret = do_bind(sockfd, target_addr, addrlen);
1356
        }
1357
        break;
1358
    case SOCKOP_connect:
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_connect(sockfd, target_addr, addrlen);
1370
        }
1371
        break;
1372
    case SOCKOP_listen:
1373
        {
1374
            int sockfd, backlog;
1375

    
1376
            if (get_user_s32(sockfd, vptr)
1377
                || get_user_s32(backlog, vptr + n))
1378
                return -TARGET_EFAULT;
1379

    
1380
            ret = get_errno(listen(sockfd, backlog));
1381
        }
1382
        break;
1383
    case SOCKOP_accept:
1384
        {
1385
            int sockfd;
1386
            abi_ulong target_addr, target_addrlen;
1387

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

    
1393
            ret = do_accept(sockfd, target_addr, target_addrlen);
1394
        }
1395
        break;
1396
    case SOCKOP_getsockname:
1397
        {
1398
            int sockfd;
1399
            abi_ulong target_addr, target_addrlen;
1400

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

    
1406
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1407
        }
1408
        break;
1409
    case SOCKOP_getpeername:
1410
        {
1411
            int sockfd;
1412
            abi_ulong target_addr, target_addrlen;
1413

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

    
1419
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1420
        }
1421
        break;
1422
    case SOCKOP_socketpair:
1423
        {
1424
            int domain, type, protocol;
1425
            abi_ulong tab;
1426

    
1427
            if (get_user_s32(domain, vptr)
1428
                || get_user_s32(type, vptr + n)
1429
                || get_user_s32(protocol, vptr + 2 * n)
1430
                || get_user_ual(tab, vptr + 3 * n))
1431
                return -TARGET_EFAULT;
1432

    
1433
            ret = do_socketpair(domain, type, protocol, tab);
1434
        }
1435
        break;
1436
    case SOCKOP_send:
1437
        {
1438
            int sockfd;
1439
            abi_ulong msg;
1440
            size_t len;
1441
            int flags;
1442

    
1443
            if (get_user_s32(sockfd, vptr)
1444
                || get_user_ual(msg, vptr + n)
1445
                || get_user_ual(len, vptr + 2 * n)
1446
                || get_user_s32(flags, vptr + 3 * n))
1447
                return -TARGET_EFAULT;
1448

    
1449
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1450
        }
1451
        break;
1452
    case SOCKOP_recv:
1453
        {
1454
            int sockfd;
1455
            abi_ulong msg;
1456
            size_t len;
1457
            int flags;
1458

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

    
1465
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1466
        }
1467
        break;
1468
    case SOCKOP_sendto:
1469
        {
1470
            int sockfd;
1471
            abi_ulong msg;
1472
            size_t len;
1473
            int flags;
1474
            abi_ulong addr;
1475
            socklen_t addrlen;
1476

    
1477
            if (get_user_s32(sockfd, vptr)
1478
                || get_user_ual(msg, vptr + n)
1479
                || get_user_ual(len, vptr + 2 * n)
1480
                || get_user_s32(flags, vptr + 3 * n)
1481
                || get_user_ual(addr, vptr + 4 * n)
1482
                || get_user_u32(addrlen, vptr + 5 * n))
1483
                return -TARGET_EFAULT;
1484

    
1485
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1486
        }
1487
        break;
1488
    case SOCKOP_recvfrom:
1489
        {
1490
            int sockfd;
1491
            abi_ulong msg;
1492
            size_t len;
1493
            int flags;
1494
            abi_ulong addr;
1495
            socklen_t addrlen;
1496

    
1497
            if (get_user_s32(sockfd, vptr)
1498
                || get_user_ual(msg, vptr + n)
1499
                || get_user_ual(len, vptr + 2 * n)
1500
                || get_user_s32(flags, vptr + 3 * n)
1501
                || get_user_ual(addr, vptr + 4 * n)
1502
                || get_user_u32(addrlen, vptr + 5 * n))
1503
                return -TARGET_EFAULT;
1504

    
1505
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1506
        }
1507
        break;
1508
    case SOCKOP_shutdown:
1509
        {
1510
            int sockfd, how;
1511

    
1512
            if (get_user_s32(sockfd, vptr)
1513
                || get_user_s32(how, vptr + n))
1514
                return -TARGET_EFAULT;
1515

    
1516
            ret = get_errno(shutdown(sockfd, how));
1517
        }
1518
        break;
1519
    case SOCKOP_sendmsg:
1520
    case SOCKOP_recvmsg:
1521
        {
1522
            int fd;
1523
            abi_ulong target_msg;
1524
            int flags;
1525

    
1526
            if (get_user_s32(fd, vptr)
1527
                || get_user_ual(target_msg, vptr + n)
1528
                || get_user_s32(flags, vptr + 2 * n))
1529
                return -TARGET_EFAULT;
1530

    
1531
            ret = do_sendrecvmsg(fd, target_msg, flags,
1532
                                 (num == SOCKOP_sendmsg));
1533
        }
1534
        break;
1535
    case SOCKOP_setsockopt:
1536
        {
1537
            int sockfd;
1538
            int level;
1539
            int optname;
1540
            abi_ulong optval;
1541
            socklen_t optlen;
1542

    
1543
            if (get_user_s32(sockfd, vptr)
1544
                || get_user_s32(level, vptr + n)
1545
                || get_user_s32(optname, vptr + 2 * n)
1546
                || get_user_ual(optval, vptr + 3 * n)
1547
                || get_user_u32(optlen, vptr + 4 * n))
1548
                return -TARGET_EFAULT;
1549

    
1550
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1551
        }
1552
        break;
1553
    case SOCKOP_getsockopt:
1554
        {
1555
            int sockfd;
1556
            int level;
1557
            int optname;
1558
            abi_ulong optval;
1559
            socklen_t optlen;
1560

    
1561
            if (get_user_s32(sockfd, vptr)
1562
                || get_user_s32(level, vptr + n)
1563
                || get_user_s32(optname, vptr + 2 * n)
1564
                || get_user_ual(optval, vptr + 3 * n)
1565
                || get_user_u32(optlen, vptr + 4 * n))
1566
                return -TARGET_EFAULT;
1567

    
1568
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1569
        }
1570
        break;
1571
    default:
1572
        gemu_log("Unsupported socketcall: %d\n", num);
1573
        ret = -TARGET_ENOSYS;
1574
        break;
1575
    }
1576
    return ret;
1577
}
1578
#endif
1579

    
1580
#ifdef TARGET_NR_ipc
1581
#define N_SHM_REGIONS        32
1582

    
1583
static struct shm_region {
1584
    abi_ulong        start;
1585
    abi_ulong        size;
1586
} shm_regions[N_SHM_REGIONS];
1587

    
1588
struct target_ipc_perm
1589
{
1590
    abi_long __key;
1591
    abi_ulong uid;
1592
    abi_ulong gid;
1593
    abi_ulong cuid;
1594
    abi_ulong cgid;
1595
    unsigned short int mode;
1596
    unsigned short int __pad1;
1597
    unsigned short int __seq;
1598
    unsigned short int __pad2;
1599
    abi_ulong __unused1;
1600
    abi_ulong __unused2;
1601
};
1602

    
1603
struct target_semid_ds
1604
{
1605
  struct target_ipc_perm sem_perm;
1606
  abi_ulong sem_otime;
1607
  abi_ulong __unused1;
1608
  abi_ulong sem_ctime;
1609
  abi_ulong __unused2;
1610
  abi_ulong sem_nsems;
1611
  abi_ulong __unused3;
1612
  abi_ulong __unused4;
1613
};
1614

    
1615
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1616
                                               abi_ulong target_addr)
1617
{
1618
    struct target_ipc_perm *target_ip;
1619
    struct target_semid_ds *target_sd;
1620

    
1621
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1622
        return -TARGET_EFAULT;
1623
    target_ip=&(target_sd->sem_perm);
1624
    host_ip->__key = tswapl(target_ip->__key);
1625
    host_ip->uid = tswapl(target_ip->uid);
1626
    host_ip->gid = tswapl(target_ip->gid);
1627
    host_ip->cuid = tswapl(target_ip->cuid);
1628
    host_ip->cgid = tswapl(target_ip->cgid);
1629
    host_ip->mode = tswapl(target_ip->mode);
1630
    unlock_user_struct(target_sd, target_addr, 0);
1631
    return 0;
1632
}
1633

    
1634
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1635
                                               struct ipc_perm *host_ip)
1636
{
1637
    struct target_ipc_perm *target_ip;
1638
    struct target_semid_ds *target_sd;
1639

    
1640
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1641
        return -TARGET_EFAULT;
1642
    target_ip = &(target_sd->sem_perm);
1643
    target_ip->__key = tswapl(host_ip->__key);
1644
    target_ip->uid = tswapl(host_ip->uid);
1645
    target_ip->gid = tswapl(host_ip->gid);
1646
    target_ip->cuid = tswapl(host_ip->cuid);
1647
    target_ip->cgid = tswapl(host_ip->cgid);
1648
    target_ip->mode = tswapl(host_ip->mode);
1649
    unlock_user_struct(target_sd, target_addr, 1);
1650
    return 0;
1651
}
1652

    
1653
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1654
                                               abi_ulong target_addr)
1655
{
1656
    struct target_semid_ds *target_sd;
1657

    
1658
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1659
        return -TARGET_EFAULT;
1660
    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1661
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1662
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
1663
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1664
    unlock_user_struct(target_sd, target_addr, 0);
1665
    return 0;
1666
}
1667

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

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

    
1683
union semun {
1684
        int val;
1685
        struct semid_ds *buf;
1686
        unsigned short *array;
1687
};
1688

    
1689
union target_semun {
1690
        int val;
1691
        abi_long buf;
1692
        unsigned short int *array;
1693
};
1694

    
1695
static inline abi_long target_to_host_semun(int cmd,
1696
                                            union semun *host_su,
1697
                                            abi_ulong target_addr,
1698
                                            struct semid_ds *ds)
1699
{
1700
    union target_semun *target_su;
1701

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

    
1731
static inline abi_long host_to_target_semun(int cmd,
1732
                                            abi_ulong target_addr,
1733
                                            union semun *host_su,
1734
                                            struct semid_ds *ds)
1735
{
1736
    union target_semun *target_su;
1737

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

    
1766
static inline abi_long do_semctl(int first, int second, int third,
1767
                                 abi_long ptr)
1768
{
1769
    union semun arg;
1770
    struct semid_ds dsarg;
1771
    int cmd = third&0xff;
1772
    abi_long ret = 0;
1773

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

    
1809
    return ret;
1810
}
1811

    
1812
struct target_msqid_ds
1813
{
1814
  struct target_ipc_perm msg_perm;
1815
  abi_ulong msg_stime;
1816
  abi_ulong __unused1;
1817
  abi_ulong msg_rtime;
1818
  abi_ulong __unused2;
1819
  abi_ulong msg_ctime;
1820
  abi_ulong __unused3;
1821
  abi_ulong __msg_cbytes;
1822
  abi_ulong msg_qnum;
1823
  abi_ulong msg_qbytes;
1824
  abi_ulong msg_lspid;
1825
  abi_ulong msg_lrpid;
1826
  abi_ulong __unused4;
1827
  abi_ulong __unused5;
1828
};
1829

    
1830
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1831
                                               abi_ulong target_addr)
1832
{
1833
    struct target_msqid_ds *target_md;
1834

    
1835
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1836
        return -TARGET_EFAULT;
1837
    target_to_host_ipc_perm(&(host_md->msg_perm),target_addr);
1838
    host_md->msg_stime = tswapl(target_md->msg_stime);
1839
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
1840
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
1841
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1842
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
1843
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1844
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
1845
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1846
    unlock_user_struct(target_md, target_addr, 0);
1847
    return 0;
1848
}
1849

    
1850
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1851
                                               struct msqid_ds *host_md)
1852
{
1853
    struct target_msqid_ds *target_md;
1854

    
1855
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1856
        return -TARGET_EFAULT;
1857
    host_to_target_ipc_perm(target_addr,&(host_md->msg_perm));
1858
    target_md->msg_stime = tswapl(host_md->msg_stime);
1859
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
1860
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
1861
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
1862
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
1863
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
1864
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
1865
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
1866
    unlock_user_struct(target_md, target_addr, 1);
1867
    return 0;
1868
}
1869

    
1870
static inline abi_long do_msgctl(int first, int second, abi_long ptr)
1871
{
1872
    struct msqid_ds dsarg;
1873
    int cmd = second&0xff;
1874
    abi_long ret = 0;
1875
    switch( cmd ) {
1876
    case IPC_STAT:
1877
    case IPC_SET:
1878
        target_to_host_msqid_ds(&dsarg,ptr);
1879
        ret = get_errno(msgctl(first, cmd, &dsarg));
1880
        host_to_target_msqid_ds(ptr,&dsarg);
1881
    default:
1882
        ret = get_errno(msgctl(first, cmd, &dsarg));
1883
    }
1884
    return ret;
1885
}
1886

    
1887
struct target_msgbuf {
1888
        abi_ulong mtype;
1889
        char        mtext[1];
1890
};
1891

    
1892
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
1893
                                 unsigned int msgsz, int msgflg)
1894
{
1895
    struct target_msgbuf *target_mb;
1896
    struct msgbuf *host_mb;
1897
    abi_long ret = 0;
1898

    
1899
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
1900
        return -TARGET_EFAULT;
1901
    host_mb = malloc(msgsz+sizeof(long));
1902
    host_mb->mtype = tswapl(target_mb->mtype);
1903
    memcpy(host_mb->mtext,target_mb->mtext,msgsz);
1904
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
1905
    free(host_mb);
1906
    unlock_user_struct(target_mb, msgp, 0);
1907

    
1908
    return ret;
1909
}
1910

    
1911
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
1912
                                 unsigned int msgsz, int msgtype,
1913
                                 int msgflg)
1914
{
1915
    struct target_msgbuf *target_mb;
1916
    char *target_mtext;
1917
    struct msgbuf *host_mb;
1918
    abi_long ret = 0;
1919

    
1920
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
1921
        return -TARGET_EFAULT;
1922
    host_mb = malloc(msgsz+sizeof(long));
1923
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg));
1924
    if (ret > 0) {
1925
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
1926
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
1927
        if (!target_mtext) {
1928
            ret = -TARGET_EFAULT;
1929
            goto end;
1930
        }
1931
            memcpy(target_mb->mtext, host_mb->mtext, ret);
1932
        unlock_user(target_mtext, target_mtext_addr, ret);
1933
    }
1934
    target_mb->mtype = tswapl(host_mb->mtype);
1935
    free(host_mb);
1936

    
1937
end:
1938
    if (target_mb)
1939
        unlock_user_struct(target_mb, msgp, 1);
1940
    return ret;
1941
}
1942

    
1943
/* ??? This only works with linear mappings.  */
1944
/* do_ipc() must return target values and target errnos. */
1945
static abi_long do_ipc(unsigned int call, int first,
1946
                       int second, int third,
1947
                       abi_long ptr, abi_long fifth)
1948
{
1949
    int version;
1950
    abi_long ret = 0;
1951
    struct shmid_ds shm_info;
1952
    int i;
1953

    
1954
    version = call >> 16;
1955
    call &= 0xffff;
1956

    
1957
    switch (call) {
1958
    case IPCOP_semop:
1959
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
1960
        break;
1961

    
1962
    case IPCOP_semget:
1963
        ret = get_errno(semget(first, second, third));
1964
        break;
1965

    
1966
    case IPCOP_semctl:
1967
        ret = do_semctl(first, second, third, ptr);
1968
        break;
1969

    
1970
    case IPCOP_semtimedop:
1971
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
1972
        ret = -TARGET_ENOSYS;
1973
        break;
1974

    
1975
        case IPCOP_msgget:
1976
                ret = get_errno(msgget(first, second));
1977
                break;
1978

    
1979
        case IPCOP_msgsnd:
1980
                ret = do_msgsnd(first, ptr, second, third);
1981
                break;
1982

    
1983
        case IPCOP_msgctl:
1984
                ret = do_msgctl(first, second, ptr);
1985
                break;
1986

    
1987
        case IPCOP_msgrcv:
1988
                {
1989
                      /* XXX: this code is not correct */
1990
                      struct ipc_kludge
1991
                      {
1992
                              void *__unbounded msgp;
1993
                              long int msgtyp;
1994
                      };
1995

    
1996
                      struct ipc_kludge *foo = (struct ipc_kludge *)g2h(ptr);
1997
                      struct msgbuf *msgp = (struct msgbuf *) foo->msgp;
1998

    
1999
                      ret = do_msgrcv(first, (long)msgp, second, 0, third);
2000

    
2001
                }
2002
                break;
2003

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

    
2049
    case IPCOP_shmget:
2050
        /* IPC_* flag values are the same on all linux platforms */
2051
        ret = get_errno(shmget(first, second, third));
2052
        break;
2053

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

    
2076
/* kernel structure types definitions */
2077
#define IFNAMSIZ        16
2078

    
2079
#define STRUCT(name, list...) STRUCT_ ## name,
2080
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2081
enum {
2082
#include "syscall_types.h"
2083
};
2084
#undef STRUCT
2085
#undef STRUCT_SPECIAL
2086

    
2087
#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2088
#define STRUCT_SPECIAL(name)
2089
#include "syscall_types.h"
2090
#undef STRUCT
2091
#undef STRUCT_SPECIAL
2092

    
2093
typedef struct IOCTLEntry {
2094
    unsigned int target_cmd;
2095
    unsigned int host_cmd;
2096
    const char *name;
2097
    int access;
2098
    const argtype arg_type[5];
2099
} IOCTLEntry;
2100

    
2101
#define IOC_R 0x0001
2102
#define IOC_W 0x0002
2103
#define IOC_RW (IOC_R | IOC_W)
2104

    
2105
#define MAX_STRUCT_SIZE 4096
2106

    
2107
IOCTLEntry ioctl_entries[] = {
2108
#define IOCTL(cmd, access, types...) \
2109
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2110
#include "ioctls.h"
2111
    { 0, 0, },
2112
};
2113

    
2114
/* ??? Implement proper locking for ioctls.  */
2115
/* do_ioctl() Must return target values and target errnos. */
2116
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2117
{
2118
    const IOCTLEntry *ie;
2119
    const argtype *arg_type;
2120
    abi_long ret;
2121
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2122
    int target_size;
2123
    void *argptr;
2124

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

    
2198
bitmask_transtbl iflag_tbl[] = {
2199
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2200
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2201
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2202
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2203
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2204
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2205
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2206
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2207
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2208
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2209
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2210
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2211
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2212
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2213
        { 0, 0, 0, 0 }
2214
};
2215

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

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

    
2279
bitmask_transtbl lflag_tbl[] = {
2280
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2281
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2282
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2283
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2284
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2285
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2286
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2287
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2288
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2289
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2290
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2291
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2292
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2293
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2294
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2295
        { 0, 0, 0, 0 }
2296
};
2297

    
2298
static void target_to_host_termios (void *dst, const void *src)
2299
{
2300
    struct host_termios *host = dst;
2301
    const struct target_termios *target = src;
2302

    
2303
    host->c_iflag =
2304
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2305
    host->c_oflag =
2306
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2307
    host->c_cflag =
2308
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2309
    host->c_lflag =
2310
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2311
    host->c_line = target->c_line;
2312

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

    
2332
static void host_to_target_termios (void *dst, const void *src)
2333
{
2334
    struct target_termios *target = dst;
2335
    const struct host_termios *host = src;
2336

    
2337
    target->c_iflag =
2338
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2339
    target->c_oflag =
2340
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2341
    target->c_cflag =
2342
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2343
    target->c_lflag =
2344
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2345
    target->c_line = host->c_line;
2346

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

    
2366
StructEntry struct_termios_def = {
2367
    .convert = { host_to_target_termios, target_to_host_termios },
2368
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2369
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2370
};
2371

    
2372
static bitmask_transtbl mmap_flags_tbl[] = {
2373
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2374
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2375
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2376
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2377
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2378
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2379
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2380
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2381
        { 0, 0, 0, 0 }
2382
};
2383

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

    
2404
#if defined(TARGET_I386)
2405

    
2406
/* NOTE: there is really one LDT for all the threads */
2407
uint8_t *ldt_table;
2408

    
2409
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2410
{
2411
    int size;
2412
    void *p;
2413

    
2414
    if (!ldt_table)
2415
        return 0;
2416
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2417
    if (size > bytecount)
2418
        size = bytecount;
2419
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
2420
    if (!p)
2421
        return -TARGET_EFAULT;
2422
    /* ??? Should this by byteswapped?  */
2423
    memcpy(p, ldt_table, size);
2424
    unlock_user(p, ptr, size);
2425
    return size;
2426
}
2427

    
2428
/* XXX: add locking support */
2429
static abi_long write_ldt(CPUX86State *env,
2430
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
2431
{
2432
    struct target_modify_ldt_ldt_s ldt_info;
2433
    struct target_modify_ldt_ldt_s *target_ldt_info;
2434
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2435
    int seg_not_present, useable, lm;
2436
    uint32_t *lp, entry_1, entry_2;
2437

    
2438
    if (bytecount != sizeof(ldt_info))
2439
        return -TARGET_EINVAL;
2440
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2441
        return -TARGET_EFAULT;
2442
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2443
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2444
    ldt_info.limit = tswap32(target_ldt_info->limit);
2445
    ldt_info.flags = tswap32(target_ldt_info->flags);
2446
    unlock_user_struct(target_ldt_info, ptr, 0);
2447

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

    
2477
    /* NOTE: same code as Linux kernel */
2478
    /* Allow LDTs to be cleared by the user. */
2479
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2480
        if (oldmode ||
2481
            (contents == 0                &&
2482
             read_exec_only == 1        &&
2483
             seg_32bit == 0                &&
2484
             limit_in_pages == 0        &&
2485
             seg_not_present == 1        &&
2486
             useable == 0 )) {
2487
            entry_1 = 0;
2488
            entry_2 = 0;
2489
            goto install;
2490
        }
2491
    }
2492

    
2493
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2494
        (ldt_info.limit & 0x0ffff);
2495
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2496
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2497
        (ldt_info.limit & 0xf0000) |
2498
        ((read_exec_only ^ 1) << 9) |
2499
        (contents << 10) |
2500
        ((seg_not_present ^ 1) << 15) |
2501
        (seg_32bit << 22) |
2502
        (limit_in_pages << 23) |
2503
        (lm << 21) |
2504
        0x7000;
2505
    if (!oldmode)
2506
        entry_2 |= (useable << 20);
2507

    
2508
    /* Install the new entry ...  */
2509
install:
2510
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2511
    lp[0] = tswap32(entry_1);
2512
    lp[1] = tswap32(entry_2);
2513
    return 0;
2514
}
2515

    
2516
/* specific and weird i386 syscalls */
2517
abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr, 
2518
                       unsigned long bytecount)
2519
{
2520
    abi_long ret;
2521

    
2522
    switch (func) {
2523
    case 0:
2524
        ret = read_ldt(ptr, bytecount);
2525
        break;
2526
    case 1:
2527
        ret = write_ldt(env, ptr, bytecount, 1);
2528
        break;
2529
    case 0x11:
2530
        ret = write_ldt(env, ptr, bytecount, 0);
2531
        break;
2532
    default:
2533
        ret = -TARGET_ENOSYS;
2534
        break;
2535
    }
2536
    return ret;
2537
}
2538

    
2539
abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2540
{
2541
    uint64_t *gdt_table = g2h(env->gdt.base);
2542
    struct target_modify_ldt_ldt_s ldt_info;
2543
    struct target_modify_ldt_ldt_s *target_ldt_info;
2544
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2545
    int seg_not_present, useable, lm;
2546
    uint32_t *lp, entry_1, entry_2;
2547
    int i;
2548

    
2549
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2550
    if (!target_ldt_info)
2551
        return -TARGET_EFAULT;
2552
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2553
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2554
    ldt_info.limit = tswap32(target_ldt_info->limit);
2555
    ldt_info.flags = tswap32(target_ldt_info->flags);
2556
    if (ldt_info.entry_number == -1) {
2557
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2558
            if (gdt_table[i] == 0) {
2559
                ldt_info.entry_number = i;
2560
                target_ldt_info->entry_number = tswap32(i);
2561
                break;
2562
            }
2563
        }
2564
    }
2565
    unlock_user_struct(target_ldt_info, ptr, 1);
2566

    
2567
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
2568
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2569
           return -TARGET_EINVAL;
2570
    seg_32bit = ldt_info.flags & 1;
2571
    contents = (ldt_info.flags >> 1) & 3;
2572
    read_exec_only = (ldt_info.flags >> 3) & 1;
2573
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2574
    seg_not_present = (ldt_info.flags >> 5) & 1;
2575
    useable = (ldt_info.flags >> 6) & 1;
2576
#ifdef TARGET_ABI32
2577
    lm = 0;
2578
#else
2579
    lm = (ldt_info.flags >> 7) & 1;
2580
#endif
2581

    
2582
    if (contents == 3) {
2583
        if (seg_not_present == 0)
2584
            return -TARGET_EINVAL;
2585
    }
2586

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

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

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

    
2624
abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2625
{
2626
    struct target_modify_ldt_ldt_s *target_ldt_info;
2627
    uint64_t *gdt_table = g2h(env->gdt.base);
2628
    uint32_t base_addr, limit, flags;
2629
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2630
    int seg_not_present, useable, lm;
2631
    uint32_t *lp, entry_1, entry_2;
2632

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

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

    
2706
#endif /* defined(TARGET_I386) */
2707

    
2708
/* this stack is the equivalent of the kernel stack associated with a
2709
   thread/process */
2710
#define NEW_STACK_SIZE 8192
2711

    
2712
static int clone_func(void *arg)
2713
{
2714
    CPUState *env = arg;
2715
    cpu_loop(env);
2716
    /* never exits */
2717
    return 0;
2718
}
2719

    
2720
/* do_fork() Must return host values and target errnos (unlike most
2721
   do_*() functions). */
2722
int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp)
2723
{
2724
    int ret;
2725
    TaskState *ts;
2726
    uint8_t *new_stack;
2727
    CPUState *new_env;
2728

    
2729
    if (flags & CLONE_VM) {
2730
#if defined(USE_NPTL)
2731
        /* qemu is not threadsafe.  Bail out immediately if application
2732
           tries to create a thread.  */
2733
        if (!(flags & CLONE_VFORK)) {
2734
            gemu_log ("clone(CLONE_VM) not supported\n");
2735
            return -EINVAL;
2736
        }
2737
#endif
2738
        ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
2739
        memset(ts, 0, sizeof(TaskState));
2740
        new_stack = ts->stack;
2741
        ts->used = 1;
2742
        /* add in task state list */
2743
        ts->next = first_task_state;
2744
        first_task_state = ts;
2745
        /* we create a new CPU instance. */
2746
        new_env = cpu_copy(env);
2747
        /* Init regs that differ from the parent.  */
2748
        cpu_clone_regs(new_env, newsp);
2749
        new_env->opaque = ts;
2750
#ifdef __ia64__
2751
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2752
#else
2753
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
2754
#endif
2755
    } else {
2756
        /* if no CLONE_VM, we consider it is a fork */
2757
        if ((flags & ~CSIGNAL) != 0)
2758
            return -EINVAL;
2759
        ret = fork();
2760
        if (ret == 0) {
2761
            cpu_clone_regs(env, newsp);
2762
        }
2763
    }
2764
    return ret;
2765
}
2766

    
2767
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
2768
{
2769
    struct flock fl;
2770
    struct target_flock *target_fl;
2771
    struct flock64 fl64;
2772
    struct target_flock64 *target_fl64;
2773
    abi_long ret;
2774

    
2775
    switch(cmd) {
2776
    case TARGET_F_GETLK:
2777
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2778
            return -TARGET_EFAULT;
2779
        fl.l_type = tswap16(target_fl->l_type);
2780
        fl.l_whence = tswap16(target_fl->l_whence);
2781
        fl.l_start = tswapl(target_fl->l_start);
2782
        fl.l_len = tswapl(target_fl->l_len);
2783
        fl.l_pid = tswapl(target_fl->l_pid);
2784
        unlock_user_struct(target_fl, arg, 0);
2785
        ret = get_errno(fcntl(fd, cmd, &fl));
2786
        if (ret == 0) {
2787
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
2788
                return -TARGET_EFAULT;
2789
            target_fl->l_type = tswap16(fl.l_type);
2790
            target_fl->l_whence = tswap16(fl.l_whence);
2791
            target_fl->l_start = tswapl(fl.l_start);
2792
            target_fl->l_len = tswapl(fl.l_len);
2793
            target_fl->l_pid = tswapl(fl.l_pid);
2794
            unlock_user_struct(target_fl, arg, 1);
2795
        }
2796
        break;
2797

    
2798
    case TARGET_F_SETLK:
2799
    case TARGET_F_SETLKW:
2800
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
2801
            return -TARGET_EFAULT;
2802
        fl.l_type = tswap16(target_fl->l_type);
2803
        fl.l_whence = tswap16(target_fl->l_whence);
2804
        fl.l_start = tswapl(target_fl->l_start);
2805
        fl.l_len = tswapl(target_fl->l_len);
2806
        fl.l_pid = tswapl(target_fl->l_pid);
2807
        unlock_user_struct(target_fl, arg, 0);
2808
        ret = get_errno(fcntl(fd, cmd, &fl));
2809
        break;
2810

    
2811
    case TARGET_F_GETLK64:
2812
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2813
            return -TARGET_EFAULT;
2814
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2815
        fl64.l_whence = tswap16(target_fl64->l_whence);
2816
        fl64.l_start = tswapl(target_fl64->l_start);
2817
        fl64.l_len = tswapl(target_fl64->l_len);
2818
        fl64.l_pid = tswap16(target_fl64->l_pid);
2819
        unlock_user_struct(target_fl64, arg, 0);
2820
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2821
        if (ret == 0) {
2822
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
2823
                return -TARGET_EFAULT;
2824
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
2825
            target_fl64->l_whence = tswap16(fl64.l_whence);
2826
            target_fl64->l_start = tswapl(fl64.l_start);
2827
            target_fl64->l_len = tswapl(fl64.l_len);
2828
            target_fl64->l_pid = tswapl(fl64.l_pid);
2829
            unlock_user_struct(target_fl64, arg, 1);
2830
        }
2831
        break;
2832
    case TARGET_F_SETLK64:
2833
    case TARGET_F_SETLKW64:
2834
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
2835
            return -TARGET_EFAULT;
2836
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
2837
        fl64.l_whence = tswap16(target_fl64->l_whence);
2838
        fl64.l_start = tswapl(target_fl64->l_start);
2839
        fl64.l_len = tswapl(target_fl64->l_len);
2840
        fl64.l_pid = tswap16(target_fl64->l_pid);
2841
        unlock_user_struct(target_fl64, arg, 0);
2842
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
2843
        break;
2844

    
2845
    case F_GETFL:
2846
        ret = get_errno(fcntl(fd, cmd, arg));
2847
        if (ret >= 0) {
2848
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
2849
        }
2850
        break;
2851

    
2852
    case F_SETFL:
2853
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
2854
        break;
2855

    
2856
    default:
2857
        ret = get_errno(fcntl(fd, cmd, arg));
2858
        break;
2859
    }
2860
    return ret;
2861
}
2862

    
2863
#ifdef USE_UID16
2864

    
2865
static inline int high2lowuid(int uid)
2866
{
2867
    if (uid > 65535)
2868
        return 65534;
2869
    else
2870
        return uid;
2871
}
2872

    
2873
static inline int high2lowgid(int gid)
2874
{
2875
    if (gid > 65535)
2876
        return 65534;
2877
    else
2878
        return gid;
2879
}
2880

    
2881
static inline int low2highuid(int uid)
2882
{
2883
    if ((int16_t)uid == -1)
2884
        return -1;
2885
    else
2886
        return uid;
2887
}
2888

    
2889
static inline int low2highgid(int gid)
2890
{
2891
    if ((int16_t)gid == -1)
2892
        return -1;
2893
    else
2894
        return gid;
2895
}
2896

    
2897
#endif /* USE_UID16 */
2898

    
2899
void syscall_init(void)
2900
{
2901
    IOCTLEntry *ie;
2902
    const argtype *arg_type;
2903
    int size;
2904
    int i;
2905

    
2906
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
2907
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
2908
#include "syscall_types.h"
2909
#undef STRUCT
2910
#undef STRUCT_SPECIAL
2911

    
2912
    /* we patch the ioctl size if necessary. We rely on the fact that
2913
       no ioctl has all the bits at '1' in the size field */
2914
    ie = ioctl_entries;
2915
    while (ie->target_cmd != 0) {
2916
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
2917
            TARGET_IOC_SIZEMASK) {
2918
            arg_type = ie->arg_type;
2919
            if (arg_type[0] != TYPE_PTR) {
2920
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
2921
                        ie->target_cmd);
2922
                exit(1);
2923
            }
2924
            arg_type++;
2925
            size = thunk_type_size(arg_type, 0);
2926
            ie->target_cmd = (ie->target_cmd &
2927
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
2928
                (size << TARGET_IOC_SIZESHIFT);
2929
        }
2930

    
2931
        /* Build target_to_host_errno_table[] table from
2932
         * host_to_target_errno_table[]. */
2933
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
2934
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
2935

    
2936
        /* automatic consistency check if same arch */
2937
#if defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)
2938
        if (ie->target_cmd != ie->host_cmd) {
2939
            fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",
2940
                    ie->target_cmd, ie->host_cmd);
2941
        }
2942
#endif
2943
        ie++;
2944
    }
2945
}
2946

    
2947
#if TARGET_ABI_BITS == 32
2948
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
2949
{
2950
#ifdef TARGET_WORDS_BIG_ENDIAN
2951
    return ((uint64_t)word0 << 32) | word1;
2952
#else
2953
    return ((uint64_t)word1 << 32) | word0;
2954
#endif
2955
}
2956
#else /* TARGET_ABI_BITS == 32 */
2957
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
2958
{
2959
    return word0;
2960
}
2961
#endif /* TARGET_ABI_BITS != 32 */
2962

    
2963
#ifdef TARGET_NR_truncate64
2964
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
2965
                                         abi_long arg2,
2966
                                         abi_long arg3,
2967
                                         abi_long arg4)
2968
{
2969
#ifdef TARGET_ARM
2970
    if (((CPUARMState *)cpu_env)->eabi)
2971
      {
2972
        arg2 = arg3;
2973
        arg3 = arg4;
2974
      }
2975
#endif
2976
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
2977
}
2978
#endif
2979

    
2980
#ifdef TARGET_NR_ftruncate64
2981
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
2982
                                          abi_long arg2,
2983
                                          abi_long arg3,
2984
                                          abi_long arg4)
2985
{
2986
#ifdef TARGET_ARM
2987
    if (((CPUARMState *)cpu_env)->eabi)
2988
      {
2989
        arg2 = arg3;
2990
        arg3 = arg4;
2991
      }
2992
#endif
2993
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
2994
}
2995
#endif
2996

    
2997
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
2998
                                               abi_ulong target_addr)
2999
{
3000
    struct target_timespec *target_ts;
3001

    
3002
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3003
        return -TARGET_EFAULT;
3004
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3005
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3006
    unlock_user_struct(target_ts, target_addr, 0);
3007
    return 0;
3008
}
3009

    
3010
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3011
                                               struct timespec *host_ts)
3012
{
3013
    struct target_timespec *target_ts;
3014

    
3015
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3016
        return -TARGET_EFAULT;
3017
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3018
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3019
    unlock_user_struct(target_ts, target_addr, 1);
3020
    return 0;
3021
}
3022

    
3023
#if defined(USE_NPTL)
3024
/* ??? Using host futex calls even when target atomic operations
3025
   are not really atomic probably breaks things.  However implementing
3026
   futexes locally would make futexes shared between multiple processes
3027
   tricky.  However they're probably useless because guest atomic
3028
   operations won't work either.  */
3029
int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3030
             target_ulong uaddr2, int val3)
3031
{
3032
    struct timespec ts, *pts;
3033

    
3034
    /* ??? We assume FUTEX_* constants are the same on both host
3035
       and target.  */
3036
    switch (op) {
3037
    case FUTEX_WAIT:
3038
        if (timeout) {
3039
            pts = &ts;
3040
            target_to_host_timespec(pts, timeout);
3041
        } else {
3042
            pts = NULL;
3043
        }
3044
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3045
                         pts, NULL, 0));
3046
    case FUTEX_WAKE:
3047
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3048
    case FUTEX_FD:
3049
        return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3050
    case FUTEX_REQUEUE:
3051
        return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3052
                         NULL, g2h(uaddr2), 0));
3053
    case FUTEX_CMP_REQUEUE:
3054
        return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3055
                         NULL, g2h(uaddr2), tswap32(val3)));
3056
    default:
3057
        return -TARGET_ENOSYS;
3058
    }
3059
}
3060
#endif
3061

    
3062
int get_osversion(void)
3063
{
3064
    static int osversion;
3065
    struct new_utsname buf;
3066
    const char *s;
3067
    int i, n, tmp;
3068
    if (osversion)
3069
        return osversion;
3070
    if (qemu_uname_release && *qemu_uname_release) {
3071
        s = qemu_uname_release;
3072
    } else {
3073
        if (sys_uname(&buf))
3074
            return 0;
3075
        s = buf.release;
3076
    }
3077
    tmp = 0;
3078
    for (i = 0; i < 3; i++) {
3079
        n = 0;
3080
        while (*s >= '0' && *s <= '9') {
3081
            n *= 10;
3082
            n += *s - '0';
3083
            s++;
3084
        }
3085
        tmp = (tmp << 8) + n;
3086
        if (*s == '.')
3087
            s++;
3088
    }
3089
    osversion = tmp;
3090
    return osversion;
3091
}
3092

    
3093
/* do_syscall() should always have a single exit point at the end so
3094
   that actions, such as logging of syscall results, can be performed.
3095
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3096
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3097
                    abi_long arg2, abi_long arg3, abi_long arg4,
3098
                    abi_long arg5, abi_long arg6)
3099
{
3100
    abi_long ret;
3101
    struct stat st;
3102
    struct statfs stfs;
3103
    void *p;
3104

    
3105
#ifdef DEBUG
3106
    gemu_log("syscall %d", num);
3107
#endif
3108
    if(do_strace)
3109
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3110

    
3111
    switch(num) {
3112
    case TARGET_NR_exit:
3113
#ifdef HAVE_GPROF
3114
        _mcleanup();
3115
#endif
3116
        gdb_exit(cpu_env, arg1);
3117
        /* XXX: should free thread stack and CPU env */
3118
        _exit(arg1);
3119
        ret = 0; /* avoid warning */
3120
        break;
3121
    case TARGET_NR_read:
3122
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3123
            goto efault;
3124
        ret = get_errno(read(arg1, p, arg3));
3125
        unlock_user(p, arg2, ret);
3126
        break;
3127
    case TARGET_NR_write:
3128
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3129
            goto efault;
3130
        ret = get_errno(write(arg1, p, arg3));
3131
        unlock_user(p, arg2, 0);
3132
        break;
3133
    case TARGET_NR_open:
3134
        if (!(p = lock_user_string(arg1)))
3135
            goto efault;
3136
        ret = get_errno(open(path(p),
3137
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
3138
                             arg3));
3139
        unlock_user(p, arg1, 0);
3140
        break;
3141
#if defined(TARGET_NR_openat) && defined(__NR_openat)
3142
    case TARGET_NR_openat:
3143
        if (!(p = lock_user_string(arg2)))
3144
            goto efault;
3145
        ret = get_errno(sys_openat(arg1,
3146
                                   path(p),
3147
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
3148
                                   arg4));
3149
        unlock_user(p, arg2, 0);
3150
        break;
3151
#endif
3152
    case TARGET_NR_close:
3153
        ret = get_errno(close(arg1));
3154
        break;
3155
    case TARGET_NR_brk:
3156
        ret = do_brk(arg1);
3157
        break;
3158
    case TARGET_NR_fork:
3159
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
3160
        break;
3161
#ifdef TARGET_NR_waitpid
3162
    case TARGET_NR_waitpid:
3163
        {
3164
            int status;
3165
            ret = get_errno(waitpid(arg1, &status, arg3));
3166
            if (!is_error(ret) && arg2
3167
                && put_user_s32(status, arg2))
3168
                goto efault;
3169
        }
3170
        break;
3171
#endif
3172
#ifdef TARGET_NR_creat /* not on alpha */
3173
    case TARGET_NR_creat:
3174
        if (!(p = lock_user_string(arg1)))
3175
            goto efault;
3176
        ret = get_errno(creat(p, arg2));
3177
        unlock_user(p, arg1, 0);
3178
        break;
3179
#endif
3180
    case TARGET_NR_link:
3181
        {
3182
            void * p2;
3183
            p = lock_user_string(arg1);
3184
            p2 = lock_user_string(arg2);
3185
            if (!p || !p2)
3186
                ret = -TARGET_EFAULT;
3187
            else
3188
                ret = get_errno(link(p, p2));
3189
            unlock_user(p2, arg2, 0);
3190
            unlock_user(p, arg1, 0);
3191
        }
3192
        break;
3193
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3194
    case TARGET_NR_linkat:
3195
        {
3196
            void * p2 = NULL;
3197
            if (!arg2 || !arg4)
3198
                goto efault;
3199
            p  = lock_user_string(arg2);
3200
            p2 = lock_user_string(arg4);
3201
            if (!p || !p2)
3202
                ret = -TARGET_EFAULT;
3203
            else
3204
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3205
            unlock_user(p, arg2, 0);
3206
            unlock_user(p2, arg4, 0);
3207
        }
3208
        break;
3209
#endif
3210
    case TARGET_NR_unlink:
3211
        if (!(p = lock_user_string(arg1)))
3212
            goto efault;
3213
        ret = get_errno(unlink(p));
3214
        unlock_user(p, arg1, 0);
3215
        break;
3216
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3217
    case TARGET_NR_unlinkat:
3218
        if (!(p = lock_user_string(arg2)))
3219
            goto efault;
3220
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
3221
        unlock_user(p, arg2, 0);
3222
        break;
3223
#endif
3224
    case TARGET_NR_execve:
3225
        {
3226
            char **argp, **envp;
3227
            int argc, envc;
3228
            abi_ulong gp;
3229
            abi_ulong guest_argp;
3230
            abi_ulong guest_envp;
3231
            abi_ulong addr;
3232
            char **q;
3233

    
3234
            argc = 0;
3235
            guest_argp = arg2;
3236
            for (gp = guest_argp; ; gp += sizeof(abi_ulong)) {
3237
                if (get_user_ual(addr, gp))
3238
                    goto efault;
3239
                if (!addr)
3240
                    break;
3241
                argc++;
3242
            }
3243
            envc = 0;
3244
            guest_envp = arg3;
3245
            for (gp = guest_envp; ; gp += sizeof(abi_ulong)) {
3246
                if (get_user_ual(addr, gp))
3247
                    goto efault;
3248
                if (!addr)
3249
                    break;
3250
                envc++;
3251
            }
3252

    
3253
            argp = alloca((argc + 1) * sizeof(void *));
3254
            envp = alloca((envc + 1) * sizeof(void *));
3255

    
3256
            for (gp = guest_argp, q = argp; ;
3257
                  gp += sizeof(abi_ulong), q++) {
3258
                if (get_user_ual(addr, gp))
3259
                    goto execve_efault;
3260
                if (!addr)
3261
                    break;
3262
                if (!(*q = lock_user_string(addr)))
3263
                    goto execve_efault;
3264
            }
3265
            *q = NULL;
3266

    
3267
            for (gp = guest_envp, q = envp; ;
3268
                  gp += sizeof(abi_ulong), q++) {
3269
                if (get_user_ual(addr, gp))
3270
                    goto execve_efault;
3271
                if (!addr)
3272
                    break;
3273
                if (!(*q = lock_user_string(addr)))
3274
                    goto execve_efault;
3275
            }
3276
            *q = NULL;
3277

    
3278
            if (!(p = lock_user_string(arg1)))
3279
                goto execve_efault;
3280
            ret = get_errno(execve(p, argp, envp));
3281
            unlock_user(p, arg1, 0);
3282

    
3283
            goto execve_end;
3284

    
3285
        execve_efault:
3286
            ret = -TARGET_EFAULT;
3287

    
3288
        execve_end:
3289
            for (gp = guest_argp, q = argp; *q;
3290
                  gp += sizeof(abi_ulong), q++) {
3291
                if (get_user_ual(addr, gp)
3292
                    || !addr)
3293
                    break;
3294
                unlock_user(*q, addr, 0);
3295
            }
3296
            for (gp = guest_envp, q = envp; *q;
3297
                  gp += sizeof(abi_ulong), q++) {
3298
                if (get_user_ual(addr, gp)
3299
                    || !addr)
3300
                    break;
3301
                unlock_user(*q, addr, 0);
3302
            }
3303
        }
3304
        break;
3305
    case TARGET_NR_chdir:
3306
        if (!(p = lock_user_string(arg1)))
3307
            goto efault;
3308
        ret = get_errno(chdir(p));
3309
        unlock_user(p, arg1, 0);
3310
        break;
3311
#ifdef TARGET_NR_time
3312
    case TARGET_NR_time:
3313
        {
3314
            time_t host_time;
3315
            ret = get_errno(time(&host_time));
3316
            if (!is_error(ret)
3317
                && arg1
3318
                && put_user_sal(host_time, arg1))
3319
                goto efault;
3320
        }
3321
        break;
3322
#endif
3323
    case TARGET_NR_mknod:
3324
        if (!(p = lock_user_string(arg1)))
3325
            goto efault;
3326
        ret = get_errno(mknod(p, arg2, arg3));
3327
        unlock_user(p, arg1, 0);
3328
        break;
3329
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3330
    case TARGET_NR_mknodat:
3331
        if (!(p = lock_user_string(arg2)))
3332
            goto efault;
3333
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3334
        unlock_user(p, arg2, 0);
3335
        break;
3336
#endif
3337
    case TARGET_NR_chmod:
3338
        if (!(p = lock_user_string(arg1)))
3339
            goto efault;
3340
        ret = get_errno(chmod(p, arg2));
3341
        unlock_user(p, arg1, 0);
3342
        break;
3343
#ifdef TARGET_NR_break
3344
    case TARGET_NR_break:
3345
        goto unimplemented;
3346
#endif
3347
#ifdef TARGET_NR_oldstat
3348
    case TARGET_NR_oldstat:
3349
        goto unimplemented;
3350
#endif
3351
    case TARGET_NR_lseek:
3352
        ret = get_errno(lseek(arg1, arg2, arg3));
3353
        break;
3354
#ifdef TARGET_NR_getxpid
3355
    case TARGET_NR_getxpid:
3356
#else
3357
    case TARGET_NR_getpid:
3358
#endif
3359
        ret = get_errno(getpid());
3360
        break;
3361
    case TARGET_NR_mount:
3362
                {
3363
                        /* need to look at the data field */
3364
                        void *p2, *p3;
3365
                        p = lock_user_string(arg1);
3366
                        p2 = lock_user_string(arg2);
3367
                        p3 = lock_user_string(arg3);
3368
                        if (!p || !p2 || !p3)
3369
                            ret = -TARGET_EFAULT;
3370
                        else
3371
                            /* FIXME - arg5 should be locked, but it isn't clear how to
3372
                             * do that since it's not guaranteed to be a NULL-terminated
3373
                             * string.
3374
                             */
3375
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3376
                        unlock_user(p, arg1, 0);
3377
                        unlock_user(p2, arg2, 0);
3378
                        unlock_user(p3, arg3, 0);
3379
                        break;
3380
                }
3381
#ifdef TARGET_NR_umount
3382
    case TARGET_NR_umount:
3383
        if (!(p = lock_user_string(arg1)))
3384
            goto efault;
3385
        ret = get_errno(umount(p));
3386
        unlock_user(p, arg1, 0);
3387
        break;
3388
#endif
3389
#ifdef TARGET_NR_stime /* not on alpha */
3390
    case TARGET_NR_stime:
3391
        {
3392
            time_t host_time;
3393
            if (get_user_sal(host_time, arg1))
3394
                goto efault;
3395
            ret = get_errno(stime(&host_time));
3396
        }
3397
        break;
3398
#endif
3399
    case TARGET_NR_ptrace:
3400
        goto unimplemented;
3401
#ifdef TARGET_NR_alarm /* not on alpha */
3402
    case TARGET_NR_alarm:
3403
        ret = alarm(arg1);
3404
        break;
3405
#endif
3406
#ifdef TARGET_NR_oldfstat
3407
    case TARGET_NR_oldfstat:
3408
        goto unimplemented;
3409
#endif
3410
#ifdef TARGET_NR_pause /* not on alpha */
3411
    case TARGET_NR_pause:
3412
        ret = get_errno(pause());
3413
        break;
3414
#endif
3415
#ifdef TARGET_NR_utime
3416
    case TARGET_NR_utime:
3417
        {
3418
            struct utimbuf tbuf, *host_tbuf;
3419
            struct target_utimbuf *target_tbuf;
3420
            if (arg2) {
3421
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3422
                    goto efault;
3423
                tbuf.actime = tswapl(target_tbuf->actime);
3424
                tbuf.modtime = tswapl(target_tbuf->modtime);
3425
                unlock_user_struct(target_tbuf, arg2, 0);
3426
                host_tbuf = &tbuf;
3427
            } else {
3428
                host_tbuf = NULL;
3429
            }
3430
            if (!(p = lock_user_string(arg1)))
3431
                goto efault;
3432
            ret = get_errno(utime(p, host_tbuf));
3433
            unlock_user(p, arg1, 0);
3434
        }
3435
        break;
3436
#endif
3437
    case TARGET_NR_utimes:
3438
        {
3439
            struct timeval *tvp, tv[2];
3440
            if (arg2) {
3441
                if (copy_from_user_timeval(&tv[0], arg2)
3442
                    || copy_from_user_timeval(&tv[1],
3443
                                              arg2 + sizeof(struct target_timeval)))
3444
                    goto efault;
3445
                tvp = tv;
3446
            } else {
3447
                tvp = NULL;
3448
            }
3449
            if (!(p = lock_user_string(arg1)))
3450
                goto efault;
3451
            ret = get_errno(utimes(p, tvp));
3452
            unlock_user(p, arg1, 0);
3453
        }
3454
        break;
3455
#ifdef TARGET_NR_stty
3456
    case TARGET_NR_stty:
3457
        goto unimplemented;
3458
#endif
3459
#ifdef TARGET_NR_gtty
3460
    case TARGET_NR_gtty:
3461
        goto unimplemented;
3462
#endif
3463
    case TARGET_NR_access:
3464
        if (!(p = lock_user_string(arg1)))
3465
            goto efault;
3466
        ret = get_errno(access(p, arg2));
3467
        unlock_user(p, arg1, 0);
3468
        break;
3469
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3470
    case TARGET_NR_faccessat:
3471
        if (!(p = lock_user_string(arg2)))
3472
            goto efault;
3473
        ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3474
        unlock_user(p, arg2, 0);
3475
        break;
3476
#endif
3477
#ifdef TARGET_NR_nice /* not on alpha */
3478
    case TARGET_NR_nice:
3479
        ret = get_errno(nice(arg1));
3480
        break;
3481
#endif
3482
#ifdef TARGET_NR_ftime
3483
    case TARGET_NR_ftime:
3484
        goto unimplemented;
3485
#endif
3486
    case TARGET_NR_sync:
3487
        sync();
3488
        ret = 0;
3489
        break;
3490
    case TARGET_NR_kill:
3491
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3492
        break;
3493
    case TARGET_NR_rename:
3494
        {
3495
            void *p2;
3496
            p = lock_user_string(arg1);
3497
            p2 = lock_user_string(arg2);
3498
            if (!p || !p2)
3499
                ret = -TARGET_EFAULT;
3500
            else
3501
                ret = get_errno(rename(p, p2));
3502
            unlock_user(p2, arg2, 0);
3503
            unlock_user(p, arg1, 0);
3504
        }
3505
        break;
3506
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3507
    case TARGET_NR_renameat:
3508
        {
3509
            void *p2;
3510
            p  = lock_user_string(arg2);
3511
            p2 = lock_user_string(arg4);
3512
            if (!p || !p2)
3513
                ret = -TARGET_EFAULT;
3514
            else
3515
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3516
            unlock_user(p2, arg4, 0);
3517
            unlock_user(p, arg2, 0);
3518
        }
3519
        break;
3520
#endif
3521
    case TARGET_NR_mkdir:
3522
        if (!(p = lock_user_string(arg1)))
3523
            goto efault;
3524
        ret = get_errno(mkdir(p, arg2));
3525
        unlock_user(p, arg1, 0);
3526
        break;
3527
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3528
    case TARGET_NR_mkdirat:
3529
        if (!(p = lock_user_string(arg2)))
3530
            goto efault;
3531
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
3532
        unlock_user(p, arg2, 0);
3533
        break;
3534
#endif
3535
    case TARGET_NR_rmdir:
3536
        if (!(p = lock_user_string(arg1)))
3537
            goto efault;
3538
        ret = get_errno(rmdir(p));
3539
        unlock_user(p, arg1, 0);
3540
        break;
3541
    case TARGET_NR_dup:
3542
        ret = get_errno(dup(arg1));
3543
        break;
3544
    case TARGET_NR_pipe:
3545
        {
3546
            int host_pipe[2];
3547
            ret = get_errno(pipe(host_pipe));
3548
            if (!is_error(ret)) {
3549
#if defined(TARGET_MIPS)
3550
                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
3551
                env->gpr[env->current_tc][3] = host_pipe[1];
3552
                ret = host_pipe[0];
3553
#elif defined(TARGET_SH4)
3554
                ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
3555
                ret = host_pipe[0];
3556
#else
3557
                if (put_user_s32(host_pipe[0], arg1)
3558
                    || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
3559
                    goto efault;
3560
#endif
3561
            }
3562
        }
3563
        break;
3564
    case TARGET_NR_times:
3565
        {
3566
            struct target_tms *tmsp;
3567
            struct tms tms;
3568
            ret = get_errno(times(&tms));
3569
            if (arg1) {
3570
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
3571
                if (!tmsp)
3572
                    goto efault;
3573
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
3574
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
3575
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
3576
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
3577
            }
3578
            if (!is_error(ret))
3579
                ret = host_to_target_clock_t(ret);
3580
        }
3581
        break;
3582
#ifdef TARGET_NR_prof
3583
    case TARGET_NR_prof:
3584
        goto unimplemented;
3585
#endif
3586
#ifdef TARGET_NR_signal
3587
    case TARGET_NR_signal:
3588
        goto unimplemented;
3589
#endif
3590
    case TARGET_NR_acct:
3591
        if (!(p = lock_user_string(arg1)))
3592
            goto efault;
3593
        ret = get_errno(acct(path(p)));
3594
        unlock_user(p, arg1, 0);
3595
        break;
3596
#ifdef TARGET_NR_umount2 /* not on alpha */
3597
    case TARGET_NR_umount2:
3598
        if (!(p = lock_user_string(arg1)))
3599
            goto efault;
3600
        ret = get_errno(umount2(p, arg2));
3601
        unlock_user(p, arg1, 0);
3602
        break;
3603
#endif
3604
#ifdef TARGET_NR_lock
3605
    case TARGET_NR_lock:
3606
        goto unimplemented;
3607
#endif
3608
    case TARGET_NR_ioctl:
3609
        ret = do_ioctl(arg1, arg2, arg3);
3610
        break;
3611
    case TARGET_NR_fcntl:
3612
        ret = do_fcntl(arg1, arg2, arg3);
3613
        break;
3614
#ifdef TARGET_NR_mpx
3615
    case TARGET_NR_mpx:
3616
        goto unimplemented;
3617
#endif
3618
    case TARGET_NR_setpgid:
3619
        ret = get_errno(setpgid(arg1, arg2));
3620
        break;
3621
#ifdef TARGET_NR_ulimit
3622
    case TARGET_NR_ulimit:
3623
        goto unimplemented;
3624
#endif
3625
#ifdef TARGET_NR_oldolduname
3626
    case TARGET_NR_oldolduname:
3627
        goto unimplemented;
3628
#endif
3629
    case TARGET_NR_umask:
3630
        ret = get_errno(umask(arg1));
3631
        break;
3632
    case TARGET_NR_chroot:
3633
        if (!(p = lock_user_string(arg1)))
3634
            goto efault;
3635
        ret = get_errno(chroot(p));
3636
        unlock_user(p, arg1, 0);
3637
        break;
3638
    case TARGET_NR_ustat:
3639
        goto unimplemented;
3640
    case TARGET_NR_dup2:
3641
        ret = get_errno(dup2(arg1, arg2));
3642
        break;
3643
#ifdef TARGET_NR_getppid /* not on alpha */
3644
    case TARGET_NR_getppid:
3645
        ret = get_errno(getppid());
3646
        break;
3647
#endif
3648
    case TARGET_NR_getpgrp:
3649
        ret = get_errno(getpgrp());
3650
        break;
3651
    case TARGET_NR_setsid:
3652
        ret = get_errno(setsid());
3653
        break;
3654
#ifdef TARGET_NR_sigaction
3655
    case TARGET_NR_sigaction:
3656
        {
3657
#if !defined(TARGET_MIPS)
3658
            struct target_old_sigaction *old_act;
3659
            struct target_sigaction act, oact, *pact;
3660
            if (arg2) {
3661
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3662
                    goto efault;
3663
                act._sa_handler = old_act->_sa_handler;
3664
                target_siginitset(&act.sa_mask, old_act->sa_mask);
3665
                act.sa_flags = old_act->sa_flags;
3666
                act.sa_restorer = old_act->sa_restorer;
3667
                unlock_user_struct(old_act, arg2, 0);
3668
                pact = &act;
3669
            } else {
3670
                pact = NULL;
3671
            }
3672
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3673
            if (!is_error(ret) && arg3) {
3674
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3675
                    goto efault;
3676
                old_act->_sa_handler = oact._sa_handler;
3677
                old_act->sa_mask = oact.sa_mask.sig[0];
3678
                old_act->sa_flags = oact.sa_flags;
3679
                old_act->sa_restorer = oact.sa_restorer;
3680
                unlock_user_struct(old_act, arg3, 1);
3681
            }
3682
#else
3683
            struct target_sigaction act, oact, *pact, *old_act;
3684

    
3685
            if (arg2) {
3686
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3687
                    goto efault;
3688
                act._sa_handler = old_act->_sa_handler;
3689
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3690
                act.sa_flags = old_act->sa_flags;
3691
                unlock_user_struct(old_act, arg2, 0);
3692
                pact = &act;
3693
            } else {
3694
                pact = NULL;
3695
            }
3696

    
3697
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3698

    
3699
            if (!is_error(ret) && arg3) {
3700
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3701
                    goto efault;
3702
                old_act->_sa_handler = oact._sa_handler;
3703
                old_act->sa_flags = oact.sa_flags;
3704
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
3705
                old_act->sa_mask.sig[1] = 0;
3706
                old_act->sa_mask.sig[2] = 0;
3707
                old_act->sa_mask.sig[3] = 0;
3708
                unlock_user_struct(old_act, arg3, 1);
3709
            }
3710
#endif
3711
        }
3712
        break;
3713
#endif
3714
    case TARGET_NR_rt_sigaction:
3715
        {
3716
            struct target_sigaction *act;
3717
            struct target_sigaction *oact;
3718

    
3719
            if (arg2) {
3720
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
3721
                    goto efault;
3722
            } else
3723
                act = NULL;
3724
            if (arg3) {
3725
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
3726
                    ret = -TARGET_EFAULT;
3727
                    goto rt_sigaction_fail;
3728
                }
3729
            } else
3730
                oact = NULL;
3731
            ret = get_errno(do_sigaction(arg1, act, oact));
3732
        rt_sigaction_fail:
3733
            if (act)
3734
                unlock_user_struct(act, arg2, 0);
3735
            if (oact)
3736
                unlock_user_struct(oact, arg3, 1);
3737
        }
3738
        break;
3739
#ifdef TARGET_NR_sgetmask /* not on alpha */
3740
    case TARGET_NR_sgetmask:
3741
        {
3742
            sigset_t cur_set;
3743
            abi_ulong target_set;
3744
            sigprocmask(0, NULL, &cur_set);
3745
            host_to_target_old_sigset(&target_set, &cur_set);
3746
            ret = target_set;
3747
        }
3748
        break;
3749
#endif
3750
#ifdef TARGET_NR_ssetmask /* not on alpha */
3751
    case TARGET_NR_ssetmask:
3752
        {
3753
            sigset_t set, oset, cur_set;
3754
            abi_ulong target_set = arg1;
3755
            sigprocmask(0, NULL, &cur_set);
3756
            target_to_host_old_sigset(&set, &target_set);
3757
            sigorset(&set, &set, &cur_set);
3758
            sigprocmask(SIG_SETMASK, &set, &oset);
3759
            host_to_target_old_sigset(&target_set, &oset);
3760
            ret = target_set;
3761
        }
3762
        break;
3763
#endif
3764
#ifdef TARGET_NR_sigprocmask
3765
    case TARGET_NR_sigprocmask:
3766
        {
3767
            int how = arg1;
3768
            sigset_t set, oldset, *set_ptr;
3769

    
3770
            if (arg2) {
3771
                switch(how) {
3772
                case TARGET_SIG_BLOCK:
3773
                    how = SIG_BLOCK;
3774
                    break;
3775
                case TARGET_SIG_UNBLOCK:
3776
                    how = SIG_UNBLOCK;
3777
                    break;
3778
                case TARGET_SIG_SETMASK:
3779
                    how = SIG_SETMASK;
3780
                    break;
3781
                default:
3782
                    ret = -TARGET_EINVAL;
3783
                    goto fail;
3784
                }
3785
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3786
                    goto efault;
3787
                target_to_host_old_sigset(&set, p);
3788
                unlock_user(p, arg2, 0);
3789
                set_ptr = &set;
3790
            } else {
3791
                how = 0;
3792
                set_ptr = NULL;
3793
            }
3794
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
3795
            if (!is_error(ret) && arg3) {
3796
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
3797
                    goto efault;
3798
                host_to_target_old_sigset(p, &oldset);
3799
                unlock_user(p, arg3, sizeof(target_sigset_t));
3800
            }
3801
        }
3802
        break;
3803
#endif
3804
    case TARGET_NR_rt_sigprocmask:
3805
        {
3806
            int how = arg1;
3807
            sigset_t set, oldset, *set_ptr;
3808

    
3809
            if (arg2) {
3810
                switch(how) {
3811
                case TARGET_SIG_BLOCK:
3812
                    how = SIG_BLOCK;
3813
                    break;
3814
                case TARGET_SIG_UNBLOCK:
3815
                    how = SIG_UNBLOCK;
3816
                    break;
3817
                case TARGET_SIG_SETMASK:
3818
                    how = SIG_SETMASK;
3819
                    break;
3820
                default:
3821
                    ret = -TARGET_EINVAL;
3822
                    goto fail;
3823
                }
3824
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3825
                    goto efault;
3826
                target_to_host_sigset(&set, p);
3827
                unlock_user(p, arg2, 0);
3828
                set_ptr = &set;
3829
            } else {
3830
                how = 0;
3831
                set_ptr = NULL;
3832
            }
3833
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
3834
            if (!is_error(ret) && arg3) {
3835
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
3836
                    goto efault;
3837
                host_to_target_sigset(p, &oldset);
3838
                unlock_user(p, arg3, sizeof(target_sigset_t));
3839
            }
3840
        }
3841
        break;
3842
#ifdef TARGET_NR_sigpending
3843
    case TARGET_NR_sigpending:
3844
        {
3845
            sigset_t set;
3846
            ret = get_errno(sigpending(&set));
3847
            if (!is_error(ret)) {
3848
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
3849
                    goto efault;
3850
                host_to_target_old_sigset(p, &set);
3851
                unlock_user(p, arg1, sizeof(target_sigset_t));
3852
            }
3853
        }
3854
        break;
3855
#endif
3856
    case TARGET_NR_rt_sigpending:
3857
        {
3858
            sigset_t set;
3859
            ret = get_errno(sigpending(&set));
3860
            if (!is_error(ret)) {
3861
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
3862
                    goto efault;
3863
                host_to_target_sigset(p, &set);
3864
                unlock_user(p, arg1, sizeof(target_sigset_t));
3865
            }
3866
        }
3867
        break;
3868
#ifdef TARGET_NR_sigsuspend
3869
    case TARGET_NR_sigsuspend:
3870
        {
3871
            sigset_t set;
3872
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
3873
                goto efault;
3874
            target_to_host_old_sigset(&set, p);
3875
            unlock_user(p, arg1, 0);
3876
            ret = get_errno(sigsuspend(&set));
3877
        }
3878
        break;
3879
#endif
3880
    case TARGET_NR_rt_sigsuspend:
3881
        {
3882
            sigset_t set;
3883
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
3884
                goto efault;
3885
            target_to_host_sigset(&set, p);
3886
            unlock_user(p, arg1, 0);
3887
            ret = get_errno(sigsuspend(&set));
3888
        }
3889
        break;
3890
    case TARGET_NR_rt_sigtimedwait:
3891
        {
3892
            sigset_t set;
3893
            struct timespec uts, *puts;
3894
            siginfo_t uinfo;
3895

    
3896
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
3897
                goto efault;
3898
            target_to_host_sigset(&set, p);
3899
            unlock_user(p, arg1, 0);
3900
            if (arg3) {
3901
                puts = &uts;
3902
                target_to_host_timespec(puts, arg3);
3903
            } else {
3904
                puts = NULL;
3905
            }
3906
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
3907
            if (!is_error(ret) && arg2) {
3908
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_sigset_t), 0)))
3909
                    goto efault;
3910
                host_to_target_siginfo(p, &uinfo);
3911
                unlock_user(p, arg2, sizeof(target_sigset_t));
3912
            }
3913
        }
3914
        break;
3915
    case TARGET_NR_rt_sigqueueinfo:
3916
        {
3917
            siginfo_t uinfo;
3918
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
3919
                goto efault;
3920
            target_to_host_siginfo(&uinfo, p);
3921
            unlock_user(p, arg1, 0);
3922
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
3923
        }
3924
        break;
3925
#ifdef TARGET_NR_sigreturn
3926
    case TARGET_NR_sigreturn:
3927
        /* NOTE: ret is eax, so not transcoding must be done */
3928
        ret = do_sigreturn(cpu_env);
3929
        break;
3930
#endif
3931
    case TARGET_NR_rt_sigreturn:
3932
        /* NOTE: ret is eax, so not transcoding must be done */
3933
        ret = do_rt_sigreturn(cpu_env);
3934
        break;
3935
    case TARGET_NR_sethostname:
3936
        if (!(p = lock_user_string(arg1)))
3937
            goto efault;
3938
        ret = get_errno(sethostname(p, arg2));
3939
        unlock_user(p, arg1, 0);
3940
        break;
3941
    case TARGET_NR_setrlimit:
3942
        {
3943
            /* XXX: convert resource ? */
3944
            int resource = arg1;
3945
            struct target_rlimit *target_rlim;
3946
            struct rlimit rlim;
3947
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
3948
                goto efault;
3949
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
3950
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
3951
            unlock_user_struct(target_rlim, arg2, 0);
3952
            ret = get_errno(setrlimit(resource, &rlim));
3953
        }
3954
        break;
3955
    case TARGET_NR_getrlimit:
3956
        {
3957
            /* XXX: convert resource ? */
3958
            int resource = arg1;
3959
            struct target_rlimit *target_rlim;
3960
            struct rlimit rlim;
3961

    
3962
            ret = get_errno(getrlimit(resource, &rlim));
3963
            if (!is_error(ret)) {
3964
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
3965
                    goto efault;
3966
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
3967
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
3968
                unlock_user_struct(target_rlim, arg2, 1);
3969
            }
3970
        }
3971
        break;
3972
    case TARGET_NR_getrusage:
3973
        {
3974
            struct rusage rusage;
3975
            ret = get_errno(getrusage(arg1, &rusage));
3976
            if (!is_error(ret)) {
3977
                host_to_target_rusage(arg2, &rusage);
3978
            }
3979
        }
3980
        break;
3981
    case TARGET_NR_gettimeofday:
3982
        {
3983
            struct timeval tv;
3984
            ret = get_errno(gettimeofday(&tv, NULL));
3985
            if (!is_error(ret)) {
3986
                if (copy_to_user_timeval(arg1, &tv))
3987
                    goto efault;
3988
            }
3989
        }
3990
        break;
3991
    case TARGET_NR_settimeofday:
3992
        {
3993
            struct timeval tv;
3994
            if (copy_from_user_timeval(&tv, arg1))
3995
                goto efault;
3996
            ret = get_errno(settimeofday(&tv, NULL));
3997
        }
3998
        break;
3999
#ifdef TARGET_NR_select
4000
    case TARGET_NR_select:
4001
        {
4002
            struct target_sel_arg_struct *sel;
4003
            abi_ulong inp, outp, exp, tvp;
4004
            long nsel;
4005

    
4006
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4007
                goto efault;
4008
            nsel = tswapl(sel->n);
4009
            inp = tswapl(sel->inp);
4010
            outp = tswapl(sel->outp);
4011
            exp = tswapl(sel->exp);
4012
            tvp = tswapl(sel->tvp);
4013
            unlock_user_struct(sel, arg1, 0);
4014
            ret = do_select(nsel, inp, outp, exp, tvp);
4015
        }
4016
        break;
4017
#endif
4018
    case TARGET_NR_symlink:
4019
        {
4020
            void *p2;
4021
            p = lock_user_string(arg1);
4022
            p2 = lock_user_string(arg2);
4023
            if (!p || !p2)
4024
                ret = -TARGET_EFAULT;
4025
            else
4026
                ret = get_errno(symlink(p, p2));
4027
            unlock_user(p2, arg2, 0);
4028
            unlock_user(p, arg1, 0);
4029
        }
4030
        break;
4031
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4032
    case TARGET_NR_symlinkat:
4033
        {
4034
            void *p2;
4035
            p  = lock_user_string(arg1);
4036
            p2 = lock_user_string(arg3);
4037
            if (!p || !p2)
4038
                ret = -TARGET_EFAULT;
4039
            else
4040
                ret = get_errno(sys_symlinkat(p, arg2, p2));
4041
            unlock_user(p2, arg3, 0);
4042
            unlock_user(p, arg1, 0);
4043
        }
4044
        break;
4045
#endif
4046
#ifdef TARGET_NR_oldlstat
4047
    case TARGET_NR_oldlstat:
4048
        goto unimplemented;
4049
#endif
4050
    case TARGET_NR_readlink:
4051
        {
4052
            void *p2;
4053
            p = lock_user_string(arg1);
4054
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4055
            if (!p || !p2)
4056
                ret = -TARGET_EFAULT;
4057
            else
4058
                ret = get_errno(readlink(path(p), p2, arg3));
4059
            unlock_user(p2, arg2, ret);
4060
            unlock_user(p, arg1, 0);
4061
        }
4062
        break;
4063
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4064
    case TARGET_NR_readlinkat:
4065
        {
4066
            void *p2;
4067
            p  = lock_user_string(arg2);
4068
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4069
            if (!p || !p2)
4070
                ret = -TARGET_EFAULT;
4071
            else
4072
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4073
            unlock_user(p2, arg3, ret);
4074
            unlock_user(p, arg2, 0);
4075
        }
4076
        break;
4077
#endif
4078
#ifdef TARGET_NR_uselib
4079
    case TARGET_NR_uselib:
4080
        goto unimplemented;
4081
#endif
4082
#ifdef TARGET_NR_swapon
4083
    case TARGET_NR_swapon:
4084
        if (!(p = lock_user_string(arg1)))
4085
            goto efault;
4086
        ret = get_errno(swapon(p, arg2));
4087
        unlock_user(p, arg1, 0);
4088
        break;
4089
#endif
4090
    case TARGET_NR_reboot:
4091
        goto unimplemented;
4092
#ifdef TARGET_NR_readdir
4093
    case TARGET_NR_readdir:
4094
        goto unimplemented;
4095
#endif
4096
#ifdef TARGET_NR_mmap
4097
    case TARGET_NR_mmap:
4098
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4099
        {
4100
            abi_ulong *v;
4101
            abi_ulong v1, v2, v3, v4, v5, v6;
4102
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4103
                goto efault;
4104
            v1 = tswapl(v[0]);
4105
            v2 = tswapl(v[1]);
4106
            v3 = tswapl(v[2]);
4107
            v4 = tswapl(v[3]);
4108
            v5 = tswapl(v[4]);
4109
            v6 = tswapl(v[5]);
4110
            unlock_user(v, arg1, 0);
4111
            ret = get_errno(target_mmap(v1, v2, v3,
4112
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
4113
                                        v5, v6));
4114
        }
4115
#else
4116
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4117
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4118
                                    arg5,
4119
                                    arg6));
4120
#endif
4121
        break;
4122
#endif
4123
#ifdef TARGET_NR_mmap2
4124
    case TARGET_NR_mmap2:
4125
#ifndef MMAP_SHIFT
4126
#define MMAP_SHIFT 12
4127
#endif
4128
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4129
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4130
                                    arg5,
4131
                                    arg6 << MMAP_SHIFT));
4132
        break;
4133
#endif
4134
    case TARGET_NR_munmap:
4135
        ret = get_errno(target_munmap(arg1, arg2));
4136
        break;
4137
    case TARGET_NR_mprotect:
4138
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
4139
        break;
4140
#ifdef TARGET_NR_mremap
4141
    case TARGET_NR_mremap:
4142
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4143
        break;
4144
#endif
4145
        /* ??? msync/mlock/munlock are broken for softmmu.  */
4146
#ifdef TARGET_NR_msync
4147
    case TARGET_NR_msync:
4148
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
4149
        break;
4150
#endif
4151
#ifdef TARGET_NR_mlock
4152
    case TARGET_NR_mlock:
4153
        ret = get_errno(mlock(g2h(arg1), arg2));
4154
        break;
4155
#endif
4156
#ifdef TARGET_NR_munlock
4157
    case TARGET_NR_munlock:
4158
        ret = get_errno(munlock(g2h(arg1), arg2));
4159
        break;
4160
#endif
4161
#ifdef TARGET_NR_mlockall
4162
    case TARGET_NR_mlockall:
4163
        ret = get_errno(mlockall(arg1));
4164
        break;
4165
#endif
4166
#ifdef TARGET_NR_munlockall
4167
    case TARGET_NR_munlockall:
4168
        ret = get_errno(munlockall());
4169
        break;
4170
#endif
4171
    case TARGET_NR_truncate:
4172
        if (!(p = lock_user_string(arg1)))
4173
            goto efault;
4174
        ret = get_errno(truncate(p, arg2));
4175
        unlock_user(p, arg1, 0);
4176
        break;
4177
    case TARGET_NR_ftruncate:
4178
        ret = get_errno(ftruncate(arg1, arg2));
4179
        break;
4180
    case TARGET_NR_fchmod:
4181
        ret = get_errno(fchmod(arg1, arg2));
4182
        break;
4183
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4184
    case TARGET_NR_fchmodat:
4185
        if (!(p = lock_user_string(arg2)))
4186
            goto efault;
4187
        ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4188
        unlock_user(p, arg2, 0);
4189
        break;
4190
#endif
4191
    case TARGET_NR_getpriority:
4192
        /* libc does special remapping of the return value of
4193
         * sys_getpriority() so it's just easiest to call
4194
         * sys_getpriority() directly rather than through libc. */
4195
        ret = sys_getpriority(arg1, arg2);
4196
        break;
4197
    case TARGET_NR_setpriority:
4198
        ret = get_errno(setpriority(arg1, arg2, arg3));
4199
        break;
4200
#ifdef TARGET_NR_profil
4201
    case TARGET_NR_profil:
4202
        goto unimplemented;
4203
#endif
4204
    case TARGET_NR_statfs:
4205
        if (!(p = lock_user_string(arg1)))
4206
            goto efault;
4207
        ret = get_errno(statfs(path(p), &stfs));
4208
        unlock_user(p, arg1, 0);
4209
    convert_statfs:
4210
        if (!is_error(ret)) {
4211
            struct target_statfs *target_stfs;
4212

    
4213
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4214
                goto efault;
4215
            __put_user(stfs.f_type, &target_stfs->f_type);
4216
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4217
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4218
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4219
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4220
            __put_user(stfs.f_files, &target_stfs->f_files);
4221
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4222
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4223
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4224
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4225
            unlock_user_struct(target_stfs, arg2, 1);
4226
        }
4227
        break;
4228
    case TARGET_NR_fstatfs:
4229
        ret = get_errno(fstatfs(arg1, &stfs));
4230
        goto convert_statfs;
4231
#ifdef TARGET_NR_statfs64
4232
    case TARGET_NR_statfs64:
4233
        if (!(p = lock_user_string(arg1)))
4234
            goto efault;
4235
        ret = get_errno(statfs(path(p), &stfs));
4236
        unlock_user(p, arg1, 0);
4237
    convert_statfs64:
4238
        if (!is_error(ret)) {
4239
            struct target_statfs64 *target_stfs;
4240

    
4241
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4242
                goto efault;
4243
            __put_user(stfs.f_type, &target_stfs->f_type);
4244
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4245
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4246
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4247
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4248
            __put_user(stfs.f_files, &target_stfs->f_files);
4249
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4250
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4251
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4252
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4253
            unlock_user_struct(target_stfs, arg3, 1);
4254
        }
4255
        break;
4256
    case TARGET_NR_fstatfs64:
4257
        ret = get_errno(fstatfs(arg1, &stfs));
4258
        goto convert_statfs64;
4259
#endif
4260
#ifdef TARGET_NR_ioperm
4261
    case TARGET_NR_ioperm:
4262
        goto unimplemented;
4263
#endif
4264
#ifdef TARGET_NR_socketcall
4265
    case TARGET_NR_socketcall:
4266
        ret = do_socketcall(arg1, arg2);
4267
        break;
4268
#endif
4269
#ifdef TARGET_NR_accept
4270
    case TARGET_NR_accept:
4271
        ret = do_accept(arg1, arg2, arg3);
4272
        break;
4273
#endif
4274
#ifdef TARGET_NR_bind
4275
    case TARGET_NR_bind:
4276
        ret = do_bind(arg1, arg2, arg3);
4277
        break;
4278
#endif
4279
#ifdef TARGET_NR_connect
4280
    case TARGET_NR_connect:
4281
        ret = do_connect(arg1, arg2, arg3);
4282
        break;
4283
#endif
4284
#ifdef TARGET_NR_getpeername
4285
    case TARGET_NR_getpeername:
4286
        ret = do_getpeername(arg1, arg2, arg3);
4287
        break;
4288
#endif
4289
#ifdef TARGET_NR_getsockname
4290
    case TARGET_NR_getsockname:
4291
        ret = do_getsockname(arg1, arg2, arg3);
4292
        break;
4293
#endif
4294
#ifdef TARGET_NR_getsockopt
4295
    case TARGET_NR_getsockopt:
4296
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4297
        break;
4298
#endif
4299
#ifdef TARGET_NR_listen
4300
    case TARGET_NR_listen:
4301
        ret = get_errno(listen(arg1, arg2));
4302
        break;
4303
#endif
4304
#ifdef TARGET_NR_recv
4305
    case TARGET_NR_recv:
4306
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4307
        break;
4308
#endif
4309
#ifdef TARGET_NR_recvfrom
4310
    case TARGET_NR_recvfrom:
4311
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4312
        break;
4313
#endif
4314
#ifdef TARGET_NR_recvmsg
4315
    case TARGET_NR_recvmsg:
4316
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4317
        break;
4318
#endif
4319
#ifdef TARGET_NR_send
4320
    case TARGET_NR_send:
4321
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4322
        break;
4323
#endif
4324
#ifdef TARGET_NR_sendmsg
4325
    case TARGET_NR_sendmsg:
4326
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4327
        break;
4328
#endif
4329
#ifdef TARGET_NR_sendto
4330
    case TARGET_NR_sendto:
4331
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4332
        break;
4333
#endif
4334
#ifdef TARGET_NR_shutdown
4335
    case TARGET_NR_shutdown:
4336
        ret = get_errno(shutdown(arg1, arg2));
4337
        break;
4338
#endif
4339
#ifdef TARGET_NR_socket
4340
    case TARGET_NR_socket:
4341
        ret = do_socket(arg1, arg2, arg3);
4342
        break;
4343
#endif
4344
#ifdef TARGET_NR_socketpair
4345
    case TARGET_NR_socketpair:
4346
        ret = do_socketpair(arg1, arg2, arg3, arg4);
4347
        break;
4348
#endif
4349
#ifdef TARGET_NR_setsockopt
4350
    case TARGET_NR_setsockopt:
4351
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4352
        break;
4353
#endif
4354

    
4355
    case TARGET_NR_syslog:
4356
        if (!(p = lock_user_string(arg2)))
4357
            goto efault;
4358
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4359
        unlock_user(p, arg2, 0);
4360
        break;
4361

    
4362
    case TARGET_NR_setitimer:
4363
        {
4364
            struct itimerval value, ovalue, *pvalue;
4365

    
4366
            if (arg2) {
4367
                pvalue = &value;
4368
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4369
                    || copy_from_user_timeval(&pvalue->it_value,
4370
                                              arg2 + sizeof(struct target_timeval)))
4371
                    goto efault;
4372
            } else {
4373
                pvalue = NULL;
4374
            }
4375
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4376
            if (!is_error(ret) && arg3) {
4377
                if (copy_to_user_timeval(arg3,
4378
                                         &ovalue.it_interval)
4379
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4380
                                            &ovalue.it_value))
4381
                    goto efault;
4382
            }
4383
        }
4384
        break;
4385
    case TARGET_NR_getitimer:
4386
        {
4387
            struct itimerval value;
4388

    
4389
            ret = get_errno(getitimer(arg1, &value));
4390
            if (!is_error(ret) && arg2) {
4391
                if (copy_to_user_timeval(arg2,
4392
                                         &value.it_interval)
4393
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4394
                                            &value.it_value))
4395
                    goto efault;
4396
            }
4397
        }
4398
        break;
4399
    case TARGET_NR_stat:
4400
        if (!(p = lock_user_string(arg1)))
4401
            goto efault;
4402
        ret = get_errno(stat(path(p), &st));
4403
        unlock_user(p, arg1, 0);
4404
        goto do_stat;
4405
    case TARGET_NR_lstat:
4406
        if (!(p = lock_user_string(arg1)))
4407
            goto efault;
4408
        ret = get_errno(lstat(path(p), &st));
4409
        unlock_user(p, arg1, 0);
4410
        goto do_stat;
4411
    case TARGET_NR_fstat:
4412
        {
4413
            ret = get_errno(fstat(arg1, &st));
4414
        do_stat:
4415
            if (!is_error(ret)) {
4416
                struct target_stat *target_st;
4417

    
4418
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4419
                    goto efault;
4420
                __put_user(st.st_dev, &target_st->st_dev);
4421
                __put_user(st.st_ino, &target_st->st_ino);
4422
                __put_user(st.st_mode, &target_st->st_mode);
4423
                __put_user(st.st_uid, &target_st->st_uid);
4424
                __put_user(st.st_gid, &target_st->st_gid);
4425
                __put_user(st.st_nlink, &target_st->st_nlink);
4426
                __put_user(st.st_rdev, &target_st->st_rdev);
4427
                __put_user(st.st_size, &target_st->st_size);
4428
                __put_user(st.st_blksize, &target_st->st_blksize);
4429
                __put_user(st.st_blocks, &target_st->st_blocks);
4430
                __put_user(st.st_atime, &target_st->target_st_atime);
4431
                __put_user(st.st_mtime, &target_st->target_st_mtime);
4432
                __put_user(st.st_ctime, &target_st->target_st_ctime);
4433
                unlock_user_struct(target_st, arg2, 1);
4434
            }
4435
        }
4436
        break;
4437
#ifdef TARGET_NR_olduname
4438
    case TARGET_NR_olduname:
4439
        goto unimplemented;
4440
#endif
4441
#ifdef TARGET_NR_iopl
4442
    case TARGET_NR_iopl:
4443
        goto unimplemented;
4444
#endif
4445
    case TARGET_NR_vhangup:
4446
        ret = get_errno(vhangup());
4447
        break;
4448
#ifdef TARGET_NR_idle
4449
    case TARGET_NR_idle:
4450
        goto unimplemented;
4451
#endif
4452
#ifdef TARGET_NR_syscall
4453
    case TARGET_NR_syscall:
4454
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4455
            break;
4456
#endif
4457
    case TARGET_NR_wait4:
4458
        {
4459
            int status;
4460
            abi_long status_ptr = arg2;
4461
            struct rusage rusage, *rusage_ptr;
4462
            abi_ulong target_rusage = arg4;
4463
            if (target_rusage)
4464
                rusage_ptr = &rusage;
4465
            else
4466
                rusage_ptr = NULL;
4467
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4468
            if (!is_error(ret)) {
4469
                if (status_ptr) {
4470
                    if (put_user_s32(status, status_ptr))
4471
                        goto efault;
4472
                }
4473
                if (target_rusage)
4474
                    host_to_target_rusage(target_rusage, &rusage);
4475
            }
4476
        }
4477
        break;
4478
#ifdef TARGET_NR_swapoff
4479
    case TARGET_NR_swapoff:
4480
        if (!(p = lock_user_string(arg1)))
4481
            goto efault;
4482
        ret = get_errno(swapoff(p));
4483
        unlock_user(p, arg1, 0);
4484
        break;
4485
#endif
4486
    case TARGET_NR_sysinfo:
4487
        {
4488
            struct target_sysinfo *target_value;
4489
            struct sysinfo value;
4490
            ret = get_errno(sysinfo(&value));
4491
            if (!is_error(ret) && arg1)
4492
            {
4493
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4494
                    goto efault;
4495
                __put_user(value.uptime, &target_value->uptime);
4496
                __put_user(value.loads[0], &target_value->loads[0]);
4497
                __put_user(value.loads[1], &target_value->loads[1]);
4498
                __put_user(value.loads[2], &target_value->loads[2]);
4499
                __put_user(value.totalram, &target_value->totalram);
4500
                __put_user(value.freeram, &target_value->freeram);
4501
                __put_user(value.sharedram, &target_value->sharedram);
4502
                __put_user(value.bufferram, &target_value->bufferram);
4503
                __put_user(value.totalswap, &target_value->totalswap);
4504
                __put_user(value.freeswap, &target_value->freeswap);
4505
                __put_user(value.procs, &target_value->procs);
4506
                __put_user(value.totalhigh, &target_value->totalhigh);
4507
                __put_user(value.freehigh, &target_value->freehigh);
4508
                __put_user(value.mem_unit, &target_value->mem_unit);
4509
                unlock_user_struct(target_value, arg1, 1);
4510
            }
4511
        }
4512
        break;
4513
#ifdef TARGET_NR_ipc
4514
    case TARGET_NR_ipc:
4515
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4516
        break;
4517
#endif
4518
    case TARGET_NR_fsync:
4519
        ret = get_errno(fsync(arg1));
4520
        break;
4521
    case TARGET_NR_clone:
4522
        ret = get_errno(do_fork(cpu_env, arg1, arg2));
4523
        break;
4524
#ifdef __NR_exit_group
4525
        /* new thread calls */
4526
    case TARGET_NR_exit_group:
4527
        gdb_exit(cpu_env, arg1);
4528
        ret = get_errno(exit_group(arg1));
4529
        break;
4530
#endif
4531
    case TARGET_NR_setdomainname:
4532
        if (!(p = lock_user_string(arg1)))
4533
            goto efault;
4534
        ret = get_errno(setdomainname(p, arg2));
4535
        unlock_user(p, arg1, 0);
4536
        break;
4537
    case TARGET_NR_uname:
4538
        /* no need to transcode because we use the linux syscall */
4539
        {
4540
            struct new_utsname * buf;
4541

    
4542
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
4543
                goto efault;
4544
            ret = get_errno(sys_uname(buf));
4545
            if (!is_error(ret)) {
4546
                /* Overrite the native machine name with whatever is being
4547
                   emulated. */
4548
                strcpy (buf->machine, UNAME_MACHINE);
4549
                /* Allow the user to override the reported release.  */
4550
                if (qemu_uname_release && *qemu_uname_release)
4551
                  strcpy (buf->release, qemu_uname_release);
4552
            }
4553
            unlock_user_struct(buf, arg1, 1);
4554
        }
4555
        break;
4556
#ifdef TARGET_I386
4557
    case TARGET_NR_modify_ldt:
4558
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
4559
        break;
4560
#if !defined(TARGET_X86_64)
4561
    case TARGET_NR_vm86old:
4562
        goto unimplemented;
4563
    case TARGET_NR_vm86:
4564
        ret = do_vm86(cpu_env, arg1, arg2);
4565
        break;
4566
#endif
4567
#endif
4568
    case TARGET_NR_adjtimex:
4569
        goto unimplemented;
4570
#ifdef TARGET_NR_create_module
4571
    case TARGET_NR_create_module:
4572
#endif
4573
    case TARGET_NR_init_module:
4574
    case TARGET_NR_delete_module:
4575
#ifdef TARGET_NR_get_kernel_syms
4576
    case TARGET_NR_get_kernel_syms:
4577
#endif
4578
        goto unimplemented;
4579
    case TARGET_NR_quotactl:
4580
        goto unimplemented;
4581
    case TARGET_NR_getpgid:
4582
        ret = get_errno(getpgid(arg1));
4583
        break;
4584
    case TARGET_NR_fchdir:
4585
        ret = get_errno(fchdir(arg1));
4586
        break;
4587
#ifdef TARGET_NR_bdflush /* not on x86_64 */
4588
    case TARGET_NR_bdflush:
4589
        goto unimplemented;
4590
#endif
4591
#ifdef TARGET_NR_sysfs
4592
    case TARGET_NR_sysfs:
4593
        goto unimplemented;
4594
#endif
4595
    case TARGET_NR_personality:
4596
        ret = get_errno(personality(arg1));
4597
        break;
4598
#ifdef TARGET_NR_afs_syscall
4599
    case TARGET_NR_afs_syscall:
4600
        goto unimplemented;
4601
#endif
4602
#ifdef TARGET_NR__llseek /* Not on alpha */
4603
    case TARGET_NR__llseek:
4604
        {
4605
#if defined (__x86_64__)
4606
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
4607
            if (put_user_s64(ret, arg4))
4608
                goto efault;
4609
#else
4610
            int64_t res;
4611
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4612
            if (put_user_s64(res, arg4))
4613
                goto efault;
4614
#endif
4615
        }
4616
        break;
4617
#endif
4618
    case TARGET_NR_getdents:
4619
#if TARGET_ABI_BITS != 32
4620
        goto unimplemented;
4621
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4622
        {
4623
            struct target_dirent *target_dirp;
4624
            struct dirent *dirp;
4625
            abi_long count = arg3;
4626

    
4627
            dirp = malloc(count);
4628
            if (!dirp) {
4629
                ret = -TARGET_ENOMEM;
4630
                goto fail;
4631
            }
4632

    
4633
            ret = get_errno(sys_getdents(arg1, dirp, count));
4634
            if (!is_error(ret)) {
4635
                struct dirent *de;
4636
                struct target_dirent *tde;
4637
                int len = ret;
4638
                int reclen, treclen;
4639
                int count1, tnamelen;
4640

    
4641
                count1 = 0;
4642
                de = dirp;
4643
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4644
                    goto efault;
4645
                tde = target_dirp;
4646
                while (len > 0) {
4647
                    reclen = de->d_reclen;
4648
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4649
                    tde->d_reclen = tswap16(treclen);
4650
                    tde->d_ino = tswapl(de->d_ino);
4651
                    tde->d_off = tswapl(de->d_off);
4652
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4653
                    if (tnamelen > 256)
4654
                        tnamelen = 256;
4655
                    /* XXX: may not be correct */
4656
                    strncpy(tde->d_name, de->d_name, tnamelen);
4657
                    de = (struct dirent *)((char *)de + reclen);
4658
                    len -= reclen;
4659
                    tde = (struct target_dirent *)((char *)tde + treclen);
4660
                    count1 += treclen;
4661
                }
4662
                ret = count1;
4663
                unlock_user(target_dirp, arg2, ret);
4664
            }
4665
            free(dirp);
4666
        }
4667
#else
4668
        {
4669
            struct dirent *dirp;
4670
            abi_long count = arg3;
4671

    
4672
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4673
                goto efault;
4674
            ret = get_errno(sys_getdents(arg1, dirp, count));
4675
            if (!is_error(ret)) {
4676
                struct dirent *de;
4677
                int len = ret;
4678
                int reclen;
4679
                de = dirp;
4680
                while (len > 0) {
4681
                    reclen = de->d_reclen;
4682
                    if (reclen > len)
4683
                        break;
4684
                    de->d_reclen = tswap16(reclen);
4685
                    tswapls(&de->d_ino);
4686
                    tswapls(&de->d_off);
4687
                    de = (struct dirent *)((char *)de + reclen);
4688
                    len -= reclen;
4689
                }
4690
            }
4691
            unlock_user(dirp, arg2, ret);
4692
        }
4693
#endif
4694
        break;
4695
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
4696
    case TARGET_NR_getdents64:
4697
        {
4698
            struct dirent64 *dirp;
4699
            abi_long count = arg3;
4700
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4701
                goto efault;
4702
            ret = get_errno(sys_getdents64(arg1, dirp, count));
4703
            if (!is_error(ret)) {
4704
                struct dirent64 *de;
4705
                int len = ret;
4706
                int reclen;
4707
                de = dirp;
4708
                while (len > 0) {
4709
                    reclen = de->d_reclen;
4710
                    if (reclen > len)
4711
                        break;
4712
                    de->d_reclen = tswap16(reclen);
4713
                    tswap64s((uint64_t *)&de->d_ino);
4714
                    tswap64s((uint64_t *)&de->d_off);
4715
                    de = (struct dirent64 *)((char *)de + reclen);
4716
                    len -= reclen;
4717
                }
4718
            }
4719
            unlock_user(dirp, arg2, ret);
4720
        }
4721
        break;
4722
#endif /* TARGET_NR_getdents64 */
4723
#ifdef TARGET_NR__newselect
4724
    case TARGET_NR__newselect:
4725
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
4726
        break;
4727
#endif
4728
#ifdef TARGET_NR_poll
4729
    case TARGET_NR_poll:
4730
        {
4731
            struct target_pollfd *target_pfd;
4732
            unsigned int nfds = arg2;
4733
            int timeout = arg3;
4734
            struct pollfd *pfd;
4735
            unsigned int i;
4736

    
4737
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
4738
            if (!target_pfd)
4739
                goto efault;
4740
            pfd = alloca(sizeof(struct pollfd) * nfds);
4741
            for(i = 0; i < nfds; i++) {
4742
                pfd[i].fd = tswap32(target_pfd[i].fd);
4743
                pfd[i].events = tswap16(target_pfd[i].events);
4744
            }
4745
            ret = get_errno(poll(pfd, nfds, timeout));
4746
            if (!is_error(ret)) {
4747
                for(i = 0; i < nfds; i++) {
4748
                    target_pfd[i].revents = tswap16(pfd[i].revents);
4749
                }
4750
                ret += nfds * (sizeof(struct target_pollfd)
4751
                               - sizeof(struct pollfd));
4752
            }
4753
            unlock_user(target_pfd, arg1, ret);
4754
        }
4755
        break;
4756
#endif
4757
    case TARGET_NR_flock:
4758
        /* NOTE: the flock constant seems to be the same for every
4759
           Linux platform */
4760
        ret = get_errno(flock(arg1, arg2));
4761
        break;
4762
    case TARGET_NR_readv:
4763
        {
4764
            int count = arg3;
4765
            struct iovec *vec;
4766

    
4767
            vec = alloca(count * sizeof(struct iovec));
4768
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
4769
                goto efault;
4770
            ret = get_errno(readv(arg1, vec, count));
4771
            unlock_iovec(vec, arg2, count, 1);
4772
        }
4773
        break;
4774
    case TARGET_NR_writev:
4775
        {
4776
            int count = arg3;
4777
            struct iovec *vec;
4778

    
4779
            vec = alloca(count * sizeof(struct iovec));
4780
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
4781
                goto efault;
4782
            ret = get_errno(writev(arg1, vec, count));
4783
            unlock_iovec(vec, arg2, count, 0);
4784
        }
4785
        break;
4786
    case TARGET_NR_getsid:
4787
        ret = get_errno(getsid(arg1));
4788
        break;
4789
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
4790
    case TARGET_NR_fdatasync:
4791
        ret = get_errno(fdatasync(arg1));
4792
        break;
4793
#endif
4794
    case TARGET_NR__sysctl:
4795
        /* We don't implement this, but ENOTDIR is always a safe
4796
           return value. */
4797
        ret = -TARGET_ENOTDIR;
4798
        break;
4799
    case TARGET_NR_sched_setparam:
4800
        {
4801
            struct sched_param *target_schp;
4802
            struct sched_param schp;
4803

    
4804
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
4805
                goto efault;
4806
            schp.sched_priority = tswap32(target_schp->sched_priority);
4807
            unlock_user_struct(target_schp, arg2, 0);
4808
            ret = get_errno(sched_setparam(arg1, &schp));
4809
        }
4810
        break;
4811
    case TARGET_NR_sched_getparam:
4812
        {
4813
            struct sched_param *target_schp;
4814
            struct sched_param schp;
4815
            ret = get_errno(sched_getparam(arg1, &schp));
4816
            if (!is_error(ret)) {
4817
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
4818
                    goto efault;
4819
                target_schp->sched_priority = tswap32(schp.sched_priority);
4820
                unlock_user_struct(target_schp, arg2, 1);
4821
            }
4822
        }
4823
        break;
4824
    case TARGET_NR_sched_setscheduler:
4825
        {
4826
            struct sched_param *target_schp;
4827
            struct sched_param schp;
4828
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
4829
                goto efault;
4830
            schp.sched_priority = tswap32(target_schp->sched_priority);
4831
            unlock_user_struct(target_schp, arg3, 0);
4832
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
4833
        }
4834
        break;
4835
    case TARGET_NR_sched_getscheduler:
4836
        ret = get_errno(sched_getscheduler(arg1));
4837
        break;
4838
    case TARGET_NR_sched_yield:
4839
        ret = get_errno(sched_yield());
4840
        break;
4841
    case TARGET_NR_sched_get_priority_max:
4842
        ret = get_errno(sched_get_priority_max(arg1));
4843
        break;
4844
    case TARGET_NR_sched_get_priority_min:
4845
        ret = get_errno(sched_get_priority_min(arg1));
4846
        break;
4847
    case TARGET_NR_sched_rr_get_interval:
4848
        {
4849
            struct timespec ts;
4850
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
4851
            if (!is_error(ret)) {
4852
                host_to_target_timespec(arg2, &ts);
4853
            }
4854
        }
4855
        break;
4856
    case TARGET_NR_nanosleep:
4857
        {
4858
            struct timespec req, rem;
4859
            target_to_host_timespec(&req, arg1);
4860
            ret = get_errno(nanosleep(&req, &rem));
4861
            if (is_error(ret) && arg2) {
4862
                host_to_target_timespec(arg2, &rem);
4863
            }
4864
        }
4865
        break;
4866
#ifdef TARGET_NR_query_module
4867
    case TARGET_NR_query_module:
4868
        goto unimplemented;
4869
#endif
4870
#ifdef TARGET_NR_nfsservctl
4871
    case TARGET_NR_nfsservctl:
4872
        goto unimplemented;
4873
#endif
4874
    case TARGET_NR_prctl:
4875
        switch (arg1)
4876
            {
4877
            case PR_GET_PDEATHSIG:
4878
                {
4879
                    int deathsig;
4880
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
4881
                    if (!is_error(ret) && arg2
4882
                        && put_user_ual(deathsig, arg2))
4883
                        goto efault;
4884
                }
4885
                break;
4886
            default:
4887
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
4888
                break;
4889
            }
4890
        break;
4891
#ifdef TARGET_NR_arch_prctl
4892
    case TARGET_NR_arch_prctl:
4893
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
4894
        ret = do_arch_prctl(cpu_env, arg1, arg2);
4895
        break;
4896
#else
4897
        goto unimplemented;
4898
#endif
4899
#endif
4900
#ifdef TARGET_NR_pread
4901
    case TARGET_NR_pread:
4902
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4903
            goto efault;
4904
        ret = get_errno(pread(arg1, p, arg3, arg4));
4905
        unlock_user(p, arg2, ret);
4906
        break;
4907
    case TARGET_NR_pwrite:
4908
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4909
            goto efault;
4910
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
4911
        unlock_user(p, arg2, 0);
4912
        break;
4913
#endif
4914
#ifdef TARGET_NR_pread64
4915
    case TARGET_NR_pread64:
4916
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4917
            goto efault;
4918
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
4919
        unlock_user(p, arg2, ret);
4920
        break;
4921
    case TARGET_NR_pwrite64:
4922
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4923
            goto efault;
4924
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
4925
        unlock_user(p, arg2, 0);
4926
        break;
4927
#endif
4928
    case TARGET_NR_getcwd:
4929
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
4930
            goto efault;
4931
        ret = get_errno(sys_getcwd1(p, arg2));
4932
        unlock_user(p, arg1, ret);
4933
        break;
4934
    case TARGET_NR_capget:
4935
        goto unimplemented;
4936
    case TARGET_NR_capset:
4937
        goto unimplemented;
4938
    case TARGET_NR_sigaltstack:
4939
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
4940
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
4941
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
4942
        break;
4943
#else
4944
        goto unimplemented;
4945
#endif
4946
    case TARGET_NR_sendfile:
4947
        goto unimplemented;
4948
#ifdef TARGET_NR_getpmsg
4949
    case TARGET_NR_getpmsg:
4950
        goto unimplemented;
4951
#endif
4952
#ifdef TARGET_NR_putpmsg
4953
    case TARGET_NR_putpmsg:
4954
        goto unimplemented;
4955
#endif
4956
#ifdef TARGET_NR_vfork
4957
    case TARGET_NR_vfork:
4958
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
4959
        break;
4960
#endif
4961
#ifdef TARGET_NR_ugetrlimit
4962
    case TARGET_NR_ugetrlimit:
4963
    {
4964
        struct rlimit rlim;
4965
        ret = get_errno(getrlimit(arg1, &rlim));
4966
        if (!is_error(ret)) {
4967
            struct target_rlimit *target_rlim;
4968
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4969
                goto efault;
4970
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
4971
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
4972
            unlock_user_struct(target_rlim, arg2, 1);
4973
        }
4974
        break;
4975
    }
4976
#endif
4977
#ifdef TARGET_NR_truncate64
4978
    case TARGET_NR_truncate64:
4979
        if (!(p = lock_user_string(arg1)))
4980
            goto efault;
4981
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
4982
        unlock_user(p, arg1, 0);
4983
        break;
4984
#endif
4985
#ifdef TARGET_NR_ftruncate64
4986
    case TARGET_NR_ftruncate64:
4987
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
4988
        break;
4989
#endif
4990
#ifdef TARGET_NR_stat64
4991
    case TARGET_NR_stat64:
4992
        if (!(p = lock_user_string(arg1)))
4993
            goto efault;