Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ f0cbb613

History | View | Annotate | Download (175.8 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_waitid
3173
    case TARGET_NR_waitid:
3174
        {
3175
            siginfo_t info;
3176
            info.si_pid = 0;
3177
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
3178
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
3179
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3180
                    goto efault;
3181
                host_to_target_siginfo(p, &info);
3182
                unlock_user(p, arg3, sizeof(target_siginfo_t));
3183
            }
3184
        }
3185
        break;
3186
#endif
3187
#ifdef TARGET_NR_creat /* not on alpha */
3188
    case TARGET_NR_creat:
3189
        if (!(p = lock_user_string(arg1)))
3190
            goto efault;
3191
        ret = get_errno(creat(p, arg2));
3192
        unlock_user(p, arg1, 0);
3193
        break;
3194
#endif
3195
    case TARGET_NR_link:
3196
        {
3197
            void * p2;
3198
            p = lock_user_string(arg1);
3199
            p2 = lock_user_string(arg2);
3200
            if (!p || !p2)
3201
                ret = -TARGET_EFAULT;
3202
            else
3203
                ret = get_errno(link(p, p2));
3204
            unlock_user(p2, arg2, 0);
3205
            unlock_user(p, arg1, 0);
3206
        }
3207
        break;
3208
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3209
    case TARGET_NR_linkat:
3210
        {
3211
            void * p2 = NULL;
3212
            if (!arg2 || !arg4)
3213
                goto efault;
3214
            p  = lock_user_string(arg2);
3215
            p2 = lock_user_string(arg4);
3216
            if (!p || !p2)
3217
                ret = -TARGET_EFAULT;
3218
            else
3219
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3220
            unlock_user(p, arg2, 0);
3221
            unlock_user(p2, arg4, 0);
3222
        }
3223
        break;
3224
#endif
3225
    case TARGET_NR_unlink:
3226
        if (!(p = lock_user_string(arg1)))
3227
            goto efault;
3228
        ret = get_errno(unlink(p));
3229
        unlock_user(p, arg1, 0);
3230
        break;
3231
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3232
    case TARGET_NR_unlinkat:
3233
        if (!(p = lock_user_string(arg2)))
3234
            goto efault;
3235
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
3236
        unlock_user(p, arg2, 0);
3237
        break;
3238
#endif
3239
    case TARGET_NR_execve:
3240
        {
3241
            char **argp, **envp;
3242
            int argc, envc;
3243
            abi_ulong gp;
3244
            abi_ulong guest_argp;
3245
            abi_ulong guest_envp;
3246
            abi_ulong addr;
3247
            char **q;
3248

    
3249
            argc = 0;
3250
            guest_argp = arg2;
3251
            for (gp = guest_argp; ; gp += sizeof(abi_ulong)) {
3252
                if (get_user_ual(addr, gp))
3253
                    goto efault;
3254
                if (!addr)
3255
                    break;
3256
                argc++;
3257
            }
3258
            envc = 0;
3259
            guest_envp = arg3;
3260
            for (gp = guest_envp; ; gp += sizeof(abi_ulong)) {
3261
                if (get_user_ual(addr, gp))
3262
                    goto efault;
3263
                if (!addr)
3264
                    break;
3265
                envc++;
3266
            }
3267

    
3268
            argp = alloca((argc + 1) * sizeof(void *));
3269
            envp = alloca((envc + 1) * sizeof(void *));
3270

    
3271
            for (gp = guest_argp, q = argp; ;
3272
                  gp += sizeof(abi_ulong), q++) {
3273
                if (get_user_ual(addr, gp))
3274
                    goto execve_efault;
3275
                if (!addr)
3276
                    break;
3277
                if (!(*q = lock_user_string(addr)))
3278
                    goto execve_efault;
3279
            }
3280
            *q = NULL;
3281

    
3282
            for (gp = guest_envp, q = envp; ;
3283
                  gp += sizeof(abi_ulong), q++) {
3284
                if (get_user_ual(addr, gp))
3285
                    goto execve_efault;
3286
                if (!addr)
3287
                    break;
3288
                if (!(*q = lock_user_string(addr)))
3289
                    goto execve_efault;
3290
            }
3291
            *q = NULL;
3292

    
3293
            if (!(p = lock_user_string(arg1)))
3294
                goto execve_efault;
3295
            ret = get_errno(execve(p, argp, envp));
3296
            unlock_user(p, arg1, 0);
3297

    
3298
            goto execve_end;
3299

    
3300
        execve_efault:
3301
            ret = -TARGET_EFAULT;
3302

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

    
3700
            if (arg2) {
3701
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
3702
                    goto efault;
3703
                act._sa_handler = old_act->_sa_handler;
3704
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
3705
                act.sa_flags = old_act->sa_flags;
3706
                unlock_user_struct(old_act, arg2, 0);
3707
                pact = &act;
3708
            } else {
3709
                pact = NULL;
3710
            }
3711

    
3712
            ret = get_errno(do_sigaction(arg1, pact, &oact));
3713

    
3714
            if (!is_error(ret) && arg3) {
3715
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
3716
                    goto efault;
3717
                old_act->_sa_handler = oact._sa_handler;
3718
                old_act->sa_flags = oact.sa_flags;
3719
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
3720
                old_act->sa_mask.sig[1] = 0;
3721
                old_act->sa_mask.sig[2] = 0;
3722
                old_act->sa_mask.sig[3] = 0;
3723
                unlock_user_struct(old_act, arg3, 1);
3724
            }
3725
#endif
3726
        }
3727
        break;
3728
#endif
3729
    case TARGET_NR_rt_sigaction:
3730
        {
3731
            struct target_sigaction *act;
3732
            struct target_sigaction *oact;
3733

    
3734
            if (arg2) {
3735
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
3736
                    goto efault;
3737
            } else
3738
                act = NULL;
3739
            if (arg3) {
3740
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
3741
                    ret = -TARGET_EFAULT;
3742
                    goto rt_sigaction_fail;
3743
                }
3744
            } else
3745
                oact = NULL;
3746
            ret = get_errno(do_sigaction(arg1, act, oact));
3747
        rt_sigaction_fail:
3748
            if (act)
3749
                unlock_user_struct(act, arg2, 0);
3750
            if (oact)
3751
                unlock_user_struct(oact, arg3, 1);
3752
        }
3753
        break;
3754
#ifdef TARGET_NR_sgetmask /* not on alpha */
3755
    case TARGET_NR_sgetmask:
3756
        {
3757
            sigset_t cur_set;
3758
            abi_ulong target_set;
3759
            sigprocmask(0, NULL, &cur_set);
3760
            host_to_target_old_sigset(&target_set, &cur_set);
3761
            ret = target_set;
3762
        }
3763
        break;
3764
#endif
3765
#ifdef TARGET_NR_ssetmask /* not on alpha */
3766
    case TARGET_NR_ssetmask:
3767
        {
3768
            sigset_t set, oset, cur_set;
3769
            abi_ulong target_set = arg1;
3770
            sigprocmask(0, NULL, &cur_set);
3771
            target_to_host_old_sigset(&set, &target_set);
3772
            sigorset(&set, &set, &cur_set);
3773
            sigprocmask(SIG_SETMASK, &set, &oset);
3774
            host_to_target_old_sigset(&target_set, &oset);
3775
            ret = target_set;
3776
        }
3777
        break;
3778
#endif
3779
#ifdef TARGET_NR_sigprocmask
3780
    case TARGET_NR_sigprocmask:
3781
        {
3782
            int how = arg1;
3783
            sigset_t set, oldset, *set_ptr;
3784

    
3785
            if (arg2) {
3786
                switch(how) {
3787
                case TARGET_SIG_BLOCK:
3788
                    how = SIG_BLOCK;
3789
                    break;
3790
                case TARGET_SIG_UNBLOCK:
3791
                    how = SIG_UNBLOCK;
3792
                    break;
3793
                case TARGET_SIG_SETMASK:
3794
                    how = SIG_SETMASK;
3795
                    break;
3796
                default:
3797
                    ret = -TARGET_EINVAL;
3798
                    goto fail;
3799
                }
3800
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
3801
                    goto efault;
3802
                target_to_host_old_sigset(&set, p);
3803
                unlock_user(p, arg2, 0);
3804
                set_ptr = &set;
3805
            } else {
3806
                how = 0;
3807
                set_ptr = NULL;
3808
            }
3809
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
3810
            if (!is_error(ret) && arg3) {
3811
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
3812
                    goto efault;
3813
                host_to_target_old_sigset(p, &oldset);
3814
                unlock_user(p, arg3, sizeof(target_sigset_t));
3815
            }
3816
        }
3817
        break;
3818
#endif
3819
    case TARGET_NR_rt_sigprocmask:
3820
        {
3821
            int how = arg1;
3822
            sigset_t set, oldset, *set_ptr;
3823

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

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

    
3977
            ret = get_errno(getrlimit(resource, &rlim));
3978
            if (!is_error(ret)) {
3979
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
3980
                    goto efault;
3981
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
3982
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
3983
                unlock_user_struct(target_rlim, arg2, 1);
3984
            }
3985
        }
3986
        break;
3987
    case TARGET_NR_getrusage:
3988
        {
3989
            struct rusage rusage;
3990
            ret = get_errno(getrusage(arg1, &rusage));
3991
            if (!is_error(ret)) {
3992
                host_to_target_rusage(arg2, &rusage);
3993
            }
3994
        }
3995
        break;
3996
    case TARGET_NR_gettimeofday:
3997
        {
3998
            struct timeval tv;
3999
            ret = get_errno(gettimeofday(&tv, NULL));
4000
            if (!is_error(ret)) {
4001
                if (copy_to_user_timeval(arg1, &tv))
4002
                    goto efault;
4003
            }
4004
        }
4005
        break;
4006
    case TARGET_NR_settimeofday:
4007
        {
4008
            struct timeval tv;
4009
            if (copy_from_user_timeval(&tv, arg1))
4010
                goto efault;
4011
            ret = get_errno(settimeofday(&tv, NULL));
4012
        }
4013
        break;
4014
#ifdef TARGET_NR_select
4015
    case TARGET_NR_select:
4016
        {
4017
            struct target_sel_arg_struct *sel;
4018
            abi_ulong inp, outp, exp, tvp;
4019
            long nsel;
4020

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

    
4228
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4229
                goto efault;
4230
            __put_user(stfs.f_type, &target_stfs->f_type);
4231
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4232
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4233
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4234
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4235
            __put_user(stfs.f_files, &target_stfs->f_files);
4236
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4237
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4238
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4239
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4240
            unlock_user_struct(target_stfs, arg2, 1);
4241
        }
4242
        break;
4243
    case TARGET_NR_fstatfs:
4244
        ret = get_errno(fstatfs(arg1, &stfs));
4245
        goto convert_statfs;
4246
#ifdef TARGET_NR_statfs64
4247
    case TARGET_NR_statfs64:
4248
        if (!(p = lock_user_string(arg1)))
4249
            goto efault;
4250
        ret = get_errno(statfs(path(p), &stfs));
4251
        unlock_user(p, arg1, 0);
4252
    convert_statfs64:
4253
        if (!is_error(ret)) {
4254
            struct target_statfs64 *target_stfs;
4255

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

    
4370
    case TARGET_NR_syslog:
4371
        if (!(p = lock_user_string(arg2)))
4372
            goto efault;
4373
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4374
        unlock_user(p, arg2, 0);
4375
        break;
4376

    
4377
    case TARGET_NR_setitimer:
4378
        {
4379
            struct itimerval value, ovalue, *pvalue;
4380

    
4381
            if (arg2) {
4382
                pvalue = &value;
4383
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4384
                    || copy_from_user_timeval(&pvalue->it_value,
4385
                                              arg2 + sizeof(struct target_timeval)))
4386
                    goto efault;
4387
            } else {
4388
                pvalue = NULL;
4389
            }
4390
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4391
            if (!is_error(ret) && arg3) {
4392
                if (copy_to_user_timeval(arg3,
4393
                                         &ovalue.it_interval)
4394
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4395
                                            &ovalue.it_value))
4396
                    goto efault;
4397
            }
4398
        }
4399
        break;
4400
    case TARGET_NR_getitimer:
4401
        {
4402
            struct itimerval value;
4403

    
4404
            ret = get_errno(getitimer(arg1, &value));
4405
            if (!is_error(ret) && arg2) {
4406
                if (copy_to_user_timeval(arg2,
4407
                                         &value.it_interval)
4408
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4409
                                            &value.it_value))
4410
                    goto efault;
4411
            }
4412
        }
4413
        break;
4414
    case TARGET_NR_stat:
4415
        if (!(p = lock_user_string(arg1)))
4416
            goto efault;
4417
        ret = get_errno(stat(path(p), &st));
4418
        unlock_user(p, arg1, 0);
4419
        goto do_stat;
4420
    case TARGET_NR_lstat:
4421
        if (!(p = lock_user_string(arg1)))
4422
            goto efault;
4423
        ret = get_errno(lstat(path(p), &st));
4424
        unlock_user(p, arg1, 0);
4425
        goto do_stat;
4426
    case TARGET_NR_fstat:
4427
        {
4428
            ret = get_errno(fstat(arg1, &st));
4429
        do_stat:
4430
            if (!is_error(ret)) {
4431
                struct target_stat *target_st;
4432

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

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

    
4642
            dirp = malloc(count);
4643
            if (!dirp) {
4644
                ret = -TARGET_ENOMEM;
4645
                goto fail;
4646
            }
4647

    
4648
            ret = get_errno(sys_getdents(arg1, dirp, count));
4649
            if (!is_error(ret)) {
4650
                struct dirent *de;
4651
                struct target_dirent *tde;
4652
                int len = ret;
4653
                int reclen, treclen;
4654
                int count1, tnamelen;
4655

    
4656
                count1 = 0;
4657
                de = dirp;
4658
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4659
                    goto efault;
4660
                tde = target_dirp;
4661
                while (len > 0) {
4662
                    reclen = de->d_reclen;
4663
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
4664
                    tde->d_reclen = tswap16(treclen);
4665
                    tde->d_ino = tswapl(de->d_ino);
4666
                    tde->d_off = tswapl(de->d_off);
4667
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
4668
                    if (tnamelen > 256)
4669
                        tnamelen = 256;
4670
                    /* XXX: may not be correct */
4671
                    strncpy(tde->d_name, de->d_name, tnamelen);
4672
                    de = (struct dirent *)((char *)de + reclen);
4673
                    len -= reclen;
4674
                    tde = (struct target_dirent *)((char *)tde + treclen);
4675
                    count1 += treclen;
4676
                }
4677
                ret = count1;
4678
                unlock_user(target_dirp, arg2, ret);
4679
            }
4680
            free(dirp);
4681
        }
4682
#else
4683
        {
4684
            struct dirent *dirp;
4685
            abi_long count = arg3;
4686

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

    
4752
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
4753
            if (!target_pfd)
4754
                goto efault;
4755
            pfd = alloca(sizeof(struct pollfd) * nfds);
4756
            for(i = 0; i < nfds; i++) {
4757
                pfd[i].fd = tswap32(target_pfd[i].fd);
4758
                pfd[i].events = tswap16(target_pfd[i].events);
4759
            }
4760
            ret = get_errno(poll(pfd, nfds, timeout));
4761
            if (!is_error(ret)) {
4762
                for(i = 0; i < nfds; i++) {
4763
                    target_pfd[i].revents = tswap16(pfd[i].revents);
4764
                }
4765
                ret += nfds * (sizeof(struct target_pollfd)
4766
                               - sizeof(struct pollfd));
4767
            }
4768
            unlock_user(target_pfd, arg1, ret);
4769
        }
4770
        break;
4771
#endif
4772
    case TARGET_NR_flock:
4773
        /* NOTE: the flock constant seems to be the same for every
4774
           Linux platform */
4775
        ret = get_errno(flock(arg1, arg2));
4776
        break;
4777
    case TARGET_NR_readv:
4778
        {
4779
            int count = arg3;
4780
            struct iovec *vec;
4781

    
4782
            vec = alloca(count * sizeof(struct iovec));
4783
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
4784
                goto efault;
4785
            ret = get_errno(readv(arg1, vec, count));
4786
            unlock_iovec(vec, arg2, count, 1);
4787
        }
4788
        break;
4789
    case TARGET_NR_writev:
4790
        {
4791
            int count = arg3;
4792
            struct iovec *vec;
4793

    
4794
            vec = alloca(count * sizeof(struct iovec));
4795
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
4796
                goto efault;
4797
            ret = get_errno(writev(arg1, vec, count));
4798
            unlock_iovec(vec, arg2, count, 0);
4799
        }
4800
        break;
4801
    case TARGET_NR_getsid:
4802
        ret = get_errno(getsid(arg1));
4803
        break;
4804
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
4805
    case TARGET_NR_fdatasync:
4806
        ret = get_errno(fdatasync(arg1));
4807
        break;
4808
#endif
4809
    case TARGET_NR__sysctl:
4810
        /* We don't implement this, but ENOTDIR is always a safe
4811
           return value. */
4812
        ret = -TARGET_ENOTDIR;
4813
        break;
4814
    case TARGET_NR_sched_setparam:
4815
        {
4816
            struct sched_param *target_schp;
4817
            struct sched_param schp;
4818

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