Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ be09ac41

History | View | Annotate | Download (195.3 kB)

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

    
64
#define termios host_termios
65
#define winsize host_winsize
66
#define termio host_termio
67
#define sgttyb host_sgttyb /* same as target */
68
#define tchars host_tchars /* same as target */
69
#define ltchars host_ltchars /* same as target */
70

    
71
#include <linux/termios.h>
72
#include <linux/unistd.h>
73
#include <linux/utsname.h>
74
#include <linux/cdrom.h>
75
#include <linux/hdreg.h>
76
#include <linux/soundcard.h>
77
#include <linux/kd.h>
78
#include <linux/mtio.h>
79
#include "linux_loop.h"
80

    
81
#include "qemu.h"
82
#include "qemu-common.h"
83

    
84
#if defined(USE_NPTL)
85
#include <linux/futex.h>
86
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
87
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
88
#else
89
/* XXX: Hardcode the above values.  */
90
#define CLONE_NPTL_FLAGS2 0
91
#endif
92

    
93
//#define DEBUG
94

    
95
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
96
    || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
97
/* 16 bit uid wrappers emulation */
98
#define USE_UID16
99
#endif
100

    
101
//#include <linux/msdos_fs.h>
102
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
103
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
104

    
105

    
106
#undef _syscall0
107
#undef _syscall1
108
#undef _syscall2
109
#undef _syscall3
110
#undef _syscall4
111
#undef _syscall5
112
#undef _syscall6
113

    
114
#define _syscall0(type,name)                \
115
static type name (void)                        \
116
{                                        \
117
        return syscall(__NR_##name);        \
118
}
119

    
120
#define _syscall1(type,name,type1,arg1)                \
121
static type name (type1 arg1)                        \
122
{                                                \
123
        return syscall(__NR_##name, arg1);        \
124
}
125

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

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

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

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

    
151

    
152
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
153
                  type5,arg5,type6,arg6)                                        \
154
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,        \
155
                  type6 arg6)                                                        \
156
{                                                                                \
157
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
158
}
159

    
160

    
161
#define __NR_sys_uname __NR_uname
162
#define __NR_sys_faccessat __NR_faccessat
163
#define __NR_sys_fchmodat __NR_fchmodat
164
#define __NR_sys_fchownat __NR_fchownat
165
#define __NR_sys_fstatat64 __NR_fstatat64
166
#define __NR_sys_futimesat __NR_futimesat
167
#define __NR_sys_getcwd1 __NR_getcwd
168
#define __NR_sys_getdents __NR_getdents
169
#define __NR_sys_getdents64 __NR_getdents64
170
#define __NR_sys_getpriority __NR_getpriority
171
#define __NR_sys_linkat __NR_linkat
172
#define __NR_sys_mkdirat __NR_mkdirat
173
#define __NR_sys_mknodat __NR_mknodat
174
#define __NR_sys_newfstatat __NR_newfstatat
175
#define __NR_sys_openat __NR_openat
176
#define __NR_sys_readlinkat __NR_readlinkat
177
#define __NR_sys_renameat __NR_renameat
178
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
179
#define __NR_sys_symlinkat __NR_symlinkat
180
#define __NR_sys_syslog __NR_syslog
181
#define __NR_sys_tgkill __NR_tgkill
182
#define __NR_sys_tkill __NR_tkill
183
#define __NR_sys_unlinkat __NR_unlinkat
184
#define __NR_sys_utimensat __NR_utimensat
185
#define __NR_sys_futex __NR_futex
186
#define __NR_sys_inotify_init __NR_inotify_init
187
#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
188
#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
189

    
190
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
191
#define __NR__llseek __NR_lseek
192
#endif
193

    
194
#ifdef __NR_gettid
195
_syscall0(int, gettid)
196
#else
197
/* This is a replacement for the host gettid() and must return a host
198
   errno. */
199
static int gettid(void) {
200
    return -ENOSYS;
201
}
202
#endif
203
_syscall1(int,sys_uname,struct new_utsname *,buf)
204
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
205
_syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
206
#endif
207
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
208
_syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
209
          mode_t,mode,int,flags)
210
#endif
211
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
212
_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
213
          uid_t,owner,gid_t,group,int,flags)
214
#endif
215
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
216
        defined(__NR_fstatat64)
217
_syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
218
          struct stat *,buf,int,flags)
219
#endif
220
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
221
_syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
222
         const struct timeval *,times)
223
#endif
224
_syscall2(int,sys_getcwd1,char *,buf,size_t,size)
225
#if TARGET_ABI_BITS == 32
226
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
227
#endif
228
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
229
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
230
#endif
231
_syscall2(int, sys_getpriority, int, which, int, who);
232
#if !defined (__x86_64__)
233
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
234
          loff_t *, res, uint, wh);
235
#endif
236
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
237
_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
238
          int,newdirfd,const char *,newpath,int,flags)
239
#endif
240
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
241
_syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
242
#endif
243
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
244
_syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
245
          mode_t,mode,dev_t,dev)
246
#endif
247
#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
248
        defined(__NR_newfstatat)
249
_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
250
          struct stat *,buf,int,flags)
251
#endif
252
#if defined(TARGET_NR_openat) && defined(__NR_openat)
253
_syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
254
#endif
255
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
256
_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
257
          char *,buf,size_t,bufsize)
258
#endif
259
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
260
_syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
261
          int,newdirfd,const char *,newpath)
262
#endif
263
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
264
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
265
_syscall3(int,sys_symlinkat,const char *,oldpath,
266
          int,newdirfd,const char *,newpath)
267
#endif
268
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
269
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
270
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
271
#endif
272
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
273
_syscall2(int,sys_tkill,int,tid,int,sig)
274
#endif
275
#ifdef __NR_exit_group
276
_syscall1(int,exit_group,int,error_code)
277
#endif
278
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
279
_syscall1(int,set_tid_address,int *,tidptr)
280
#endif
281
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
282
_syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
283
#endif
284
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
285
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
286
          const struct timespec *,tsp,int,flags)
287
#endif
288
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
289
_syscall0(int,sys_inotify_init)
290
#endif
291
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
292
_syscall3(int,sys_inotify_add_watch,int,fd,const char *,pathname,uint32_t,mask)
293
#endif
294
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
295
_syscall2(int,sys_inotify_rm_watch,int,fd,uint32_t,wd)
296
#endif
297
#if defined(USE_NPTL)
298
#if defined(TARGET_NR_futex) && defined(__NR_futex)
299
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
300
          const struct timespec *,timeout,int *,uaddr2,int,val3)
301
#endif
302
#endif
303

    
304
extern int personality(int);
305
extern int flock(int, int);
306
extern int setfsuid(int);
307
extern int setfsgid(int);
308
extern int setgroups(int, gid_t *);
309

    
310
#define ERRNO_TABLE_SIZE 1200
311

    
312
/* target_to_host_errno_table[] is initialized from
313
 * host_to_target_errno_table[] in syscall_init(). */
314
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
315
};
316

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

    
429
static inline int host_to_target_errno(int err)
430
{
431
    if(host_to_target_errno_table[err])
432
        return host_to_target_errno_table[err];
433
    return err;
434
}
435

    
436
static inline int target_to_host_errno(int err)
437
{
438
    if (target_to_host_errno_table[err])
439
        return target_to_host_errno_table[err];
440
    return err;
441
}
442

    
443
static inline abi_long get_errno(abi_long ret)
444
{
445
    if (ret == -1)
446
        return -host_to_target_errno(errno);
447
    else
448
        return ret;
449
}
450

    
451
static inline int is_error(abi_long ret)
452
{
453
    return (abi_ulong)ret >= (abi_ulong)(-4096);
454
}
455

    
456
char *target_strerror(int err)
457
{
458
    return strerror(target_to_host_errno(err));
459
}
460

    
461
static abi_ulong target_brk;
462
static abi_ulong target_original_brk;
463

    
464
void target_set_brk(abi_ulong new_brk)
465
{
466
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
467
}
468

    
469
/* do_brk() must return target values and target errnos. */
470
abi_long do_brk(abi_ulong new_brk)
471
{
472
    abi_ulong brk_page;
473
    abi_long mapped_addr;
474
    int        new_alloc_size;
475

    
476
    if (!new_brk)
477
        return target_brk;
478
    if (new_brk < target_original_brk)
479
        return target_brk;
480

    
481
    brk_page = HOST_PAGE_ALIGN(target_brk);
482

    
483
    /* If the new brk is less than this, set it and we're done... */
484
    if (new_brk < brk_page) {
485
        target_brk = new_brk;
486
            return target_brk;
487
    }
488

    
489
    /* We need to allocate more memory after the brk... */
490
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
491
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
492
                                        PROT_READ|PROT_WRITE,
493
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
494

    
495
    if (!is_error(mapped_addr))
496
        target_brk = new_brk;
497
    
498
    return target_brk;
499
}
500

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

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

    
515
    FD_ZERO(fds);
516
    k = 0;
517
    for (i = 0; i < nw; i++) {
518
        /* grab the abi_ulong */
519
        __get_user(b, &target_fds[i]);
520
        for (j = 0; j < TARGET_ABI_BITS; j++) {
521
            /* check the bit inside the abi_ulong */
522
            if ((b >> j) & 1)
523
                FD_SET(k, fds);
524
            k++;
525
        }
526
    }
527

    
528
    unlock_user(target_fds, target_fds_addr, 0);
529

    
530
    return 0;
531
}
532

    
533
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
534
                                          const fd_set *fds,
535
                                          int n)
536
{
537
    int i, nw, j, k;
538
    abi_long v;
539
    abi_ulong *target_fds;
540

    
541
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
542
    if (!(target_fds = lock_user(VERIFY_WRITE,
543
                                 target_fds_addr,
544
                                 sizeof(abi_ulong) * nw,
545
                                 0)))
546
        return -TARGET_EFAULT;
547

    
548
    k = 0;
549
    for (i = 0; i < nw; i++) {
550
        v = 0;
551
        for (j = 0; j < TARGET_ABI_BITS; j++) {
552
            v |= ((FD_ISSET(k, fds) != 0) << j);
553
            k++;
554
        }
555
        __put_user(v, &target_fds[i]);
556
    }
557

    
558
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
559

    
560
    return 0;
561
}
562

    
563
#if defined(__alpha__)
564
#define HOST_HZ 1024
565
#else
566
#define HOST_HZ 100
567
#endif
568

    
569
static inline abi_long host_to_target_clock_t(long ticks)
570
{
571
#if HOST_HZ == TARGET_HZ
572
    return ticks;
573
#else
574
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
575
#endif
576
}
577

    
578
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
579
                                             const struct rusage *rusage)
580
{
581
    struct target_rusage *target_rusage;
582

    
583
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
584
        return -TARGET_EFAULT;
585
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
586
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
587
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
588
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
589
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
590
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
591
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
592
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
593
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
594
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
595
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
596
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
597
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
598
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
599
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
600
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
601
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
602
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
603
    unlock_user_struct(target_rusage, target_addr, 1);
604

    
605
    return 0;
606
}
607

    
608
static inline abi_long copy_from_user_timeval(struct timeval *tv,
609
                                              abi_ulong target_tv_addr)
610
{
611
    struct target_timeval *target_tv;
612

    
613
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
614
        return -TARGET_EFAULT;
615

    
616
    __get_user(tv->tv_sec, &target_tv->tv_sec);
617
    __get_user(tv->tv_usec, &target_tv->tv_usec);
618

    
619
    unlock_user_struct(target_tv, target_tv_addr, 0);
620

    
621
    return 0;
622
}
623

    
624
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
625
                                            const struct timeval *tv)
626
{
627
    struct target_timeval *target_tv;
628

    
629
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
630
        return -TARGET_EFAULT;
631

    
632
    __put_user(tv->tv_sec, &target_tv->tv_sec);
633
    __put_user(tv->tv_usec, &target_tv->tv_usec);
634

    
635
    unlock_user_struct(target_tv, target_tv_addr, 1);
636

    
637
    return 0;
638
}
639

    
640
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
641
                                              abi_ulong target_mq_attr_addr)
642
{
643
    struct target_mq_attr *target_mq_attr;
644

    
645
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
646
                          target_mq_attr_addr, 1))
647
        return -TARGET_EFAULT;
648

    
649
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
650
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
651
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
652
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
653

    
654
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
655

    
656
    return 0;
657
}
658

    
659
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
660
                                            const struct mq_attr *attr)
661
{
662
    struct target_mq_attr *target_mq_attr;
663

    
664
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
665
                          target_mq_attr_addr, 0))
666
        return -TARGET_EFAULT;
667

    
668
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
669
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
670
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
671
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
672

    
673
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
674

    
675
    return 0;
676
}
677

    
678
/* do_select() must return target values and target errnos. */
679
static abi_long do_select(int n,
680
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
681
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
682
{
683
    fd_set rfds, wfds, efds;
684
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
685
    struct timeval tv, *tv_ptr;
686
    abi_long ret;
687

    
688
    if (rfd_addr) {
689
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
690
            return -TARGET_EFAULT;
691
        rfds_ptr = &rfds;
692
    } else {
693
        rfds_ptr = NULL;
694
    }
695
    if (wfd_addr) {
696
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
697
            return -TARGET_EFAULT;
698
        wfds_ptr = &wfds;
699
    } else {
700
        wfds_ptr = NULL;
701
    }
702
    if (efd_addr) {
703
        if (copy_from_user_fdset(&efds, efd_addr, n))
704
            return -TARGET_EFAULT;
705
        efds_ptr = &efds;
706
    } else {
707
        efds_ptr = NULL;
708
    }
709

    
710
    if (target_tv_addr) {
711
        if (copy_from_user_timeval(&tv, target_tv_addr))
712
            return -TARGET_EFAULT;
713
        tv_ptr = &tv;
714
    } else {
715
        tv_ptr = NULL;
716
    }
717

    
718
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
719

    
720
    if (!is_error(ret)) {
721
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
722
            return -TARGET_EFAULT;
723
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
724
            return -TARGET_EFAULT;
725
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
726
            return -TARGET_EFAULT;
727

    
728
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
729
            return -TARGET_EFAULT;
730
    }
731

    
732
    return ret;
733
}
734

    
735
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
736
                                               abi_ulong target_addr,
737
                                               socklen_t len)
738
{
739
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
740
    sa_family_t sa_family;
741
    struct target_sockaddr *target_saddr;
742

    
743
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
744
    if (!target_saddr)
745
        return -TARGET_EFAULT;
746

    
747
    sa_family = tswap16(target_saddr->sa_family);
748

    
749
    /* Oops. The caller might send a incomplete sun_path; sun_path
750
     * must be terminated by \0 (see the manual page), but
751
     * unfortunately it is quite common to specify sockaddr_un
752
     * length as "strlen(x->sun_path)" while it should be
753
     * "strlen(...) + 1". We'll fix that here if needed.
754
     * Linux kernel has a similar feature.
755
     */
756

    
757
    if (sa_family == AF_UNIX) {
758
        if (len < unix_maxlen && len > 0) {
759
            char *cp = (char*)target_saddr;
760

    
761
            if ( cp[len-1] && !cp[len] )
762
                len++;
763
        }
764
        if (len > unix_maxlen)
765
            len = unix_maxlen;
766
    }
767

    
768
    memcpy(addr, target_saddr, len);
769
    addr->sa_family = sa_family;
770
    unlock_user(target_saddr, target_addr, 0);
771

    
772
    return 0;
773
}
774

    
775
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
776
                                               struct sockaddr *addr,
777
                                               socklen_t len)
778
{
779
    struct target_sockaddr *target_saddr;
780

    
781
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
782
    if (!target_saddr)
783
        return -TARGET_EFAULT;
784
    memcpy(target_saddr, addr, len);
785
    target_saddr->sa_family = tswap16(addr->sa_family);
786
    unlock_user(target_saddr, target_addr, len);
787

    
788
    return 0;
789
}
790

    
791
/* ??? Should this also swap msgh->name?  */
792
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
793
                                           struct target_msghdr *target_msgh)
794
{
795
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
796
    abi_long msg_controllen;
797
    abi_ulong target_cmsg_addr;
798
    struct target_cmsghdr *target_cmsg;
799
    socklen_t space = 0;
800
    
801
    msg_controllen = tswapl(target_msgh->msg_controllen);
802
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
803
        goto the_end;
804
    target_cmsg_addr = tswapl(target_msgh->msg_control);
805
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
806
    if (!target_cmsg)
807
        return -TARGET_EFAULT;
808

    
809
    while (cmsg && target_cmsg) {
810
        void *data = CMSG_DATA(cmsg);
811
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
812

    
813
        int len = tswapl(target_cmsg->cmsg_len)
814
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
815

    
816
        space += CMSG_SPACE(len);
817
        if (space > msgh->msg_controllen) {
818
            space -= CMSG_SPACE(len);
819
            gemu_log("Host cmsg overflow\n");
820
            break;
821
        }
822

    
823
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
824
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
825
        cmsg->cmsg_len = CMSG_LEN(len);
826

    
827
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
828
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
829
            memcpy(data, target_data, len);
830
        } else {
831
            int *fd = (int *)data;
832
            int *target_fd = (int *)target_data;
833
            int i, numfds = len / sizeof(int);
834

    
835
            for (i = 0; i < numfds; i++)
836
                fd[i] = tswap32(target_fd[i]);
837
        }
838

    
839
        cmsg = CMSG_NXTHDR(msgh, cmsg);
840
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
841
    }
842
    unlock_user(target_cmsg, target_cmsg_addr, 0);
843
 the_end:
844
    msgh->msg_controllen = space;
845
    return 0;
846
}
847

    
848
/* ??? Should this also swap msgh->name?  */
849
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
850
                                           struct msghdr *msgh)
851
{
852
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
853
    abi_long msg_controllen;
854
    abi_ulong target_cmsg_addr;
855
    struct target_cmsghdr *target_cmsg;
856
    socklen_t space = 0;
857

    
858
    msg_controllen = tswapl(target_msgh->msg_controllen);
859
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
860
        goto the_end;
861
    target_cmsg_addr = tswapl(target_msgh->msg_control);
862
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
863
    if (!target_cmsg)
864
        return -TARGET_EFAULT;
865

    
866
    while (cmsg && target_cmsg) {
867
        void *data = CMSG_DATA(cmsg);
868
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
869

    
870
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
871

    
872
        space += TARGET_CMSG_SPACE(len);
873
        if (space > msg_controllen) {
874
            space -= TARGET_CMSG_SPACE(len);
875
            gemu_log("Target cmsg overflow\n");
876
            break;
877
        }
878

    
879
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
880
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
881
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
882

    
883
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
884
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
885
            memcpy(target_data, data, len);
886
        } else {
887
            int *fd = (int *)data;
888
            int *target_fd = (int *)target_data;
889
            int i, numfds = len / sizeof(int);
890

    
891
            for (i = 0; i < numfds; i++)
892
                target_fd[i] = tswap32(fd[i]);
893
        }
894

    
895
        cmsg = CMSG_NXTHDR(msgh, cmsg);
896
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
897
    }
898
    unlock_user(target_cmsg, target_cmsg_addr, space);
899
 the_end:
900
    target_msgh->msg_controllen = tswapl(space);
901
    return 0;
902
}
903

    
904
/* do_setsockopt() Must return target values and target errnos. */
905
static abi_long do_setsockopt(int sockfd, int level, int optname,
906
                              abi_ulong optval_addr, socklen_t optlen)
907
{
908
    abi_long ret;
909
    int val;
910

    
911
    switch(level) {
912
    case SOL_TCP:
913
        /* TCP options all take an 'int' value.  */
914
        if (optlen < sizeof(uint32_t))
915
            return -TARGET_EINVAL;
916

    
917
        if (get_user_u32(val, optval_addr))
918
            return -TARGET_EFAULT;
919
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
920
        break;
921
    case SOL_IP:
922
        switch(optname) {
923
        case IP_TOS:
924
        case IP_TTL:
925
        case IP_HDRINCL:
926
        case IP_ROUTER_ALERT:
927
        case IP_RECVOPTS:
928
        case IP_RETOPTS:
929
        case IP_PKTINFO:
930
        case IP_MTU_DISCOVER:
931
        case IP_RECVERR:
932
        case IP_RECVTOS:
933
#ifdef IP_FREEBIND
934
        case IP_FREEBIND:
935
#endif
936
        case IP_MULTICAST_TTL:
937
        case IP_MULTICAST_LOOP:
938
            val = 0;
939
            if (optlen >= sizeof(uint32_t)) {
940
                if (get_user_u32(val, optval_addr))
941
                    return -TARGET_EFAULT;
942
            } else if (optlen >= 1) {
943
                if (get_user_u8(val, optval_addr))
944
                    return -TARGET_EFAULT;
945
            }
946
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
947
            break;
948
        default:
949
            goto unimplemented;
950
        }
951
        break;
952
    case TARGET_SOL_SOCKET:
953
        switch (optname) {
954
            /* Options with 'int' argument.  */
955
        case TARGET_SO_DEBUG:
956
                optname = SO_DEBUG;
957
                break;
958
        case TARGET_SO_REUSEADDR:
959
                optname = SO_REUSEADDR;
960
                break;
961
        case TARGET_SO_TYPE:
962
                optname = SO_TYPE;
963
                break;
964
        case TARGET_SO_ERROR:
965
                optname = SO_ERROR;
966
                break;
967
        case TARGET_SO_DONTROUTE:
968
                optname = SO_DONTROUTE;
969
                break;
970
        case TARGET_SO_BROADCAST:
971
                optname = SO_BROADCAST;
972
                break;
973
        case TARGET_SO_SNDBUF:
974
                optname = SO_SNDBUF;
975
                break;
976
        case TARGET_SO_RCVBUF:
977
                optname = SO_RCVBUF;
978
                break;
979
        case TARGET_SO_KEEPALIVE:
980
                optname = SO_KEEPALIVE;
981
                break;
982
        case TARGET_SO_OOBINLINE:
983
                optname = SO_OOBINLINE;
984
                break;
985
        case TARGET_SO_NO_CHECK:
986
                optname = SO_NO_CHECK;
987
                break;
988
        case TARGET_SO_PRIORITY:
989
                optname = SO_PRIORITY;
990
                break;
991
#ifdef SO_BSDCOMPAT
992
        case TARGET_SO_BSDCOMPAT:
993
                optname = SO_BSDCOMPAT;
994
                break;
995
#endif
996
        case TARGET_SO_PASSCRED:
997
                optname = SO_PASSCRED;
998
                break;
999
        case TARGET_SO_TIMESTAMP:
1000
                optname = SO_TIMESTAMP;
1001
                break;
1002
        case TARGET_SO_RCVLOWAT:
1003
                optname = SO_RCVLOWAT;
1004
                break;
1005
        case TARGET_SO_RCVTIMEO:
1006
                optname = SO_RCVTIMEO;
1007
                break;
1008
        case TARGET_SO_SNDTIMEO:
1009
                optname = SO_SNDTIMEO;
1010
                break;
1011
            break;
1012
        default:
1013
            goto unimplemented;
1014
        }
1015
        if (optlen < sizeof(uint32_t))
1016
            return -TARGET_EINVAL;
1017

    
1018
        if (get_user_u32(val, optval_addr))
1019
            return -TARGET_EFAULT;
1020
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1021
        break;
1022
    default:
1023
    unimplemented:
1024
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1025
        ret = -TARGET_ENOPROTOOPT;
1026
    }
1027
    return ret;
1028
}
1029

    
1030
/* do_getsockopt() Must return target values and target errnos. */
1031
static abi_long do_getsockopt(int sockfd, int level, int optname,
1032
                              abi_ulong optval_addr, abi_ulong optlen)
1033
{
1034
    abi_long ret;
1035
    int len, val;
1036
    socklen_t lv;
1037

    
1038
    switch(level) {
1039
    case TARGET_SOL_SOCKET:
1040
            level = SOL_SOCKET;
1041
        switch (optname) {
1042
        case TARGET_SO_LINGER:
1043
        case TARGET_SO_RCVTIMEO:
1044
        case TARGET_SO_SNDTIMEO:
1045
        case TARGET_SO_PEERCRED:
1046
        case TARGET_SO_PEERNAME:
1047
            /* These don't just return a single integer */
1048
            goto unimplemented;
1049
        default:
1050
            goto int_case;
1051
        }
1052
        break;
1053
    case SOL_TCP:
1054
        /* TCP options all take an 'int' value.  */
1055
    int_case:
1056
        if (get_user_u32(len, optlen))
1057
            return -TARGET_EFAULT;
1058
        if (len < 0)
1059
            return -TARGET_EINVAL;
1060
        lv = sizeof(int);
1061
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1062
        if (ret < 0)
1063
            return ret;
1064
        val = tswap32(val);
1065
        if (len > lv)
1066
            len = lv;
1067
        if (len == 4) {
1068
            if (put_user_u32(val, optval_addr))
1069
                return -TARGET_EFAULT;
1070
        } else {
1071
            if (put_user_u8(val, optval_addr))
1072
                return -TARGET_EFAULT;
1073
        }
1074
        if (put_user_u32(len, optlen))
1075
            return -TARGET_EFAULT;
1076
        break;
1077
    case SOL_IP:
1078
        switch(optname) {
1079
        case IP_TOS:
1080
        case IP_TTL:
1081
        case IP_HDRINCL:
1082
        case IP_ROUTER_ALERT:
1083
        case IP_RECVOPTS:
1084
        case IP_RETOPTS:
1085
        case IP_PKTINFO:
1086
        case IP_MTU_DISCOVER:
1087
        case IP_RECVERR:
1088
        case IP_RECVTOS:
1089
#ifdef IP_FREEBIND
1090
        case IP_FREEBIND:
1091
#endif
1092
        case IP_MULTICAST_TTL:
1093
        case IP_MULTICAST_LOOP:
1094
            if (get_user_u32(len, optlen))
1095
                return -TARGET_EFAULT;
1096
            if (len < 0)
1097
                return -TARGET_EINVAL;
1098
            lv = sizeof(int);
1099
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1100
            if (ret < 0)
1101
                return ret;
1102
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1103
                len = 1;
1104
                if (put_user_u32(len, optlen)
1105
                    || put_user_u8(val, optval_addr))
1106
                    return -TARGET_EFAULT;
1107
            } else {
1108
                if (len > sizeof(int))
1109
                    len = sizeof(int);
1110
                if (put_user_u32(len, optlen)
1111
                    || put_user_u32(val, optval_addr))
1112
                    return -TARGET_EFAULT;
1113
            }
1114
            break;
1115
        default:
1116
            ret = -TARGET_ENOPROTOOPT;
1117
            break;
1118
        }
1119
        break;
1120
    default:
1121
    unimplemented:
1122
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1123
                 level, optname);
1124
        ret = -TARGET_EOPNOTSUPP;
1125
        break;
1126
    }
1127
    return ret;
1128
}
1129

    
1130
/* FIXME
1131
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1132
 * other lock functions have a return code of 0 for failure.
1133
 */
1134
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1135
                           int count, int copy)
1136
{
1137
    struct target_iovec *target_vec;
1138
    abi_ulong base;
1139
    int i;
1140

    
1141
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1142
    if (!target_vec)
1143
        return -TARGET_EFAULT;
1144
    for(i = 0;i < count; i++) {
1145
        base = tswapl(target_vec[i].iov_base);
1146
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1147
        if (vec[i].iov_len != 0) {
1148
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1149
            /* Don't check lock_user return value. We must call writev even
1150
               if a element has invalid base address. */
1151
        } else {
1152
            /* zero length pointer is ignored */
1153
            vec[i].iov_base = NULL;
1154
        }
1155
    }
1156
    unlock_user (target_vec, target_addr, 0);
1157
    return 0;
1158
}
1159

    
1160
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1161
                             int count, int copy)
1162
{
1163
    struct target_iovec *target_vec;
1164
    abi_ulong base;
1165
    int i;
1166

    
1167
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1168
    if (!target_vec)
1169
        return -TARGET_EFAULT;
1170
    for(i = 0;i < count; i++) {
1171
        if (target_vec[i].iov_base) {
1172
            base = tswapl(target_vec[i].iov_base);
1173
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1174
        }
1175
    }
1176
    unlock_user (target_vec, target_addr, 0);
1177

    
1178
    return 0;
1179
}
1180

    
1181
/* do_socket() Must return target values and target errnos. */
1182
static abi_long do_socket(int domain, int type, int protocol)
1183
{
1184
#if defined(TARGET_MIPS)
1185
    switch(type) {
1186
    case TARGET_SOCK_DGRAM:
1187
        type = SOCK_DGRAM;
1188
        break;
1189
    case TARGET_SOCK_STREAM:
1190
        type = SOCK_STREAM;
1191
        break;
1192
    case TARGET_SOCK_RAW:
1193
        type = SOCK_RAW;
1194
        break;
1195
    case TARGET_SOCK_RDM:
1196
        type = SOCK_RDM;
1197
        break;
1198
    case TARGET_SOCK_SEQPACKET:
1199
        type = SOCK_SEQPACKET;
1200
        break;
1201
    case TARGET_SOCK_PACKET:
1202
        type = SOCK_PACKET;
1203
        break;
1204
    }
1205
#endif
1206
    if (domain == PF_NETLINK)
1207
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1208
    return get_errno(socket(domain, type, protocol));
1209
}
1210

    
1211
/* do_bind() Must return target values and target errnos. */
1212
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1213
                        socklen_t addrlen)
1214
{
1215
    void *addr;
1216

    
1217
    if (addrlen < 0)
1218
        return -TARGET_EINVAL;
1219

    
1220
    addr = alloca(addrlen+1);
1221

    
1222
    target_to_host_sockaddr(addr, target_addr, addrlen);
1223
    return get_errno(bind(sockfd, addr, addrlen));
1224
}
1225

    
1226
/* do_connect() Must return target values and target errnos. */
1227
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1228
                           socklen_t addrlen)
1229
{
1230
    void *addr;
1231

    
1232
    if (addrlen < 0)
1233
        return -TARGET_EINVAL;
1234

    
1235
    addr = alloca(addrlen);
1236

    
1237
    target_to_host_sockaddr(addr, target_addr, addrlen);
1238
    return get_errno(connect(sockfd, addr, addrlen));
1239
}
1240

    
1241
/* do_sendrecvmsg() Must return target values and target errnos. */
1242
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1243
                               int flags, int send)
1244
{
1245
    abi_long ret, len;
1246
    struct target_msghdr *msgp;
1247
    struct msghdr msg;
1248
    int count;
1249
    struct iovec *vec;
1250
    abi_ulong target_vec;
1251

    
1252
    /* FIXME */
1253
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1254
                          msgp,
1255
                          target_msg,
1256
                          send ? 1 : 0))
1257
        return -TARGET_EFAULT;
1258
    if (msgp->msg_name) {
1259
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1260
        msg.msg_name = alloca(msg.msg_namelen);
1261
        target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1262
                                msg.msg_namelen);
1263
    } else {
1264
        msg.msg_name = NULL;
1265
        msg.msg_namelen = 0;
1266
    }
1267
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1268
    msg.msg_control = alloca(msg.msg_controllen);
1269
    msg.msg_flags = tswap32(msgp->msg_flags);
1270

    
1271
    count = tswapl(msgp->msg_iovlen);
1272
    vec = alloca(count * sizeof(struct iovec));
1273
    target_vec = tswapl(msgp->msg_iov);
1274
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1275
    msg.msg_iovlen = count;
1276
    msg.msg_iov = vec;
1277

    
1278
    if (send) {
1279
        ret = target_to_host_cmsg(&msg, msgp);
1280
        if (ret == 0)
1281
            ret = get_errno(sendmsg(fd, &msg, flags));
1282
    } else {
1283
        ret = get_errno(recvmsg(fd, &msg, flags));
1284
        if (!is_error(ret)) {
1285
            len = ret;
1286
            ret = host_to_target_cmsg(msgp, &msg);
1287
            if (!is_error(ret))
1288
                ret = len;
1289
        }
1290
    }
1291
    unlock_iovec(vec, target_vec, count, !send);
1292
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1293
    return ret;
1294
}
1295

    
1296
/* do_accept() Must return target values and target errnos. */
1297
static abi_long do_accept(int fd, abi_ulong target_addr,
1298
                          abi_ulong target_addrlen_addr)
1299
{
1300
    socklen_t addrlen;
1301
    void *addr;
1302
    abi_long ret;
1303

    
1304
    if (get_user_u32(addrlen, target_addrlen_addr))
1305
        return -TARGET_EFAULT;
1306

    
1307
    if (addrlen < 0)
1308
        return -TARGET_EINVAL;
1309

    
1310
    addr = alloca(addrlen);
1311

    
1312
    ret = get_errno(accept(fd, addr, &addrlen));
1313
    if (!is_error(ret)) {
1314
        host_to_target_sockaddr(target_addr, addr, addrlen);
1315
        if (put_user_u32(addrlen, target_addrlen_addr))
1316
            ret = -TARGET_EFAULT;
1317
    }
1318
    return ret;
1319
}
1320

    
1321
/* do_getpeername() Must return target values and target errnos. */
1322
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1323
                               abi_ulong target_addrlen_addr)
1324
{
1325
    socklen_t addrlen;
1326
    void *addr;
1327
    abi_long ret;
1328

    
1329
    if (get_user_u32(addrlen, target_addrlen_addr))
1330
        return -TARGET_EFAULT;
1331

    
1332
    if (addrlen < 0)
1333
        return -TARGET_EINVAL;
1334

    
1335
    addr = alloca(addrlen);
1336

    
1337
    ret = get_errno(getpeername(fd, addr, &addrlen));
1338
    if (!is_error(ret)) {
1339
        host_to_target_sockaddr(target_addr, addr, addrlen);
1340
        if (put_user_u32(addrlen, target_addrlen_addr))
1341
            ret = -TARGET_EFAULT;
1342
    }
1343
    return ret;
1344
}
1345

    
1346
/* do_getsockname() Must return target values and target errnos. */
1347
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1348
                               abi_ulong target_addrlen_addr)
1349
{
1350
    socklen_t addrlen;
1351
    void *addr;
1352
    abi_long ret;
1353

    
1354
    if (target_addr == 0)
1355
       return get_errno(accept(fd, NULL, NULL));
1356

    
1357
    if (get_user_u32(addrlen, target_addrlen_addr))
1358
        return -TARGET_EFAULT;
1359

    
1360
    if (addrlen < 0)
1361
        return -TARGET_EINVAL;
1362

    
1363
    addr = alloca(addrlen);
1364

    
1365
    ret = get_errno(getsockname(fd, addr, &addrlen));
1366
    if (!is_error(ret)) {
1367
        host_to_target_sockaddr(target_addr, addr, addrlen);
1368
        if (put_user_u32(addrlen, target_addrlen_addr))
1369
            ret = -TARGET_EFAULT;
1370
    }
1371
    return ret;
1372
}
1373

    
1374
/* do_socketpair() Must return target values and target errnos. */
1375
static abi_long do_socketpair(int domain, int type, int protocol,
1376
                              abi_ulong target_tab_addr)
1377
{
1378
    int tab[2];
1379
    abi_long ret;
1380

    
1381
    ret = get_errno(socketpair(domain, type, protocol, tab));
1382
    if (!is_error(ret)) {
1383
        if (put_user_s32(tab[0], target_tab_addr)
1384
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1385
            ret = -TARGET_EFAULT;
1386
    }
1387
    return ret;
1388
}
1389

    
1390
/* do_sendto() Must return target values and target errnos. */
1391
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1392
                          abi_ulong target_addr, socklen_t addrlen)
1393
{
1394
    void *addr;
1395
    void *host_msg;
1396
    abi_long ret;
1397

    
1398
    if (addrlen < 0)
1399
        return -TARGET_EINVAL;
1400

    
1401
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1402
    if (!host_msg)
1403
        return -TARGET_EFAULT;
1404
    if (target_addr) {
1405
        addr = alloca(addrlen);
1406
        target_to_host_sockaddr(addr, target_addr, addrlen);
1407
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1408
    } else {
1409
        ret = get_errno(send(fd, host_msg, len, flags));
1410
    }
1411
    unlock_user(host_msg, msg, 0);
1412
    return ret;
1413
}
1414

    
1415
/* do_recvfrom() Must return target values and target errnos. */
1416
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1417
                            abi_ulong target_addr,
1418
                            abi_ulong target_addrlen)
1419
{
1420
    socklen_t addrlen;
1421
    void *addr;
1422
    void *host_msg;
1423
    abi_long ret;
1424

    
1425
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1426
    if (!host_msg)
1427
        return -TARGET_EFAULT;
1428
    if (target_addr) {
1429
        if (get_user_u32(addrlen, target_addrlen)) {
1430
            ret = -TARGET_EFAULT;
1431
            goto fail;
1432
        }
1433
        if (addrlen < 0) {
1434
            ret = -TARGET_EINVAL;
1435
            goto fail;
1436
        }
1437
        addr = alloca(addrlen);
1438
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1439
    } else {
1440
        addr = NULL; /* To keep compiler quiet.  */
1441
        ret = get_errno(recv(fd, host_msg, len, flags));
1442
    }
1443
    if (!is_error(ret)) {
1444
        if (target_addr) {
1445
            host_to_target_sockaddr(target_addr, addr, addrlen);
1446
            if (put_user_u32(addrlen, target_addrlen)) {
1447
                ret = -TARGET_EFAULT;
1448
                goto fail;
1449
            }
1450
        }
1451
        unlock_user(host_msg, msg, len);
1452
    } else {
1453
fail:
1454
        unlock_user(host_msg, msg, 0);
1455
    }
1456
    return ret;
1457
}
1458

    
1459
#ifdef TARGET_NR_socketcall
1460
/* do_socketcall() Must return target values and target errnos. */
1461
static abi_long do_socketcall(int num, abi_ulong vptr)
1462
{
1463
    abi_long ret;
1464
    const int n = sizeof(abi_ulong);
1465

    
1466
    switch(num) {
1467
    case SOCKOP_socket:
1468
        {
1469
            int domain, type, protocol;
1470

    
1471
            if (get_user_s32(domain, vptr)
1472
                || get_user_s32(type, vptr + n)
1473
                || get_user_s32(protocol, vptr + 2 * n))
1474
                return -TARGET_EFAULT;
1475

    
1476
            ret = do_socket(domain, type, protocol);
1477
        }
1478
        break;
1479
    case SOCKOP_bind:
1480
        {
1481
            int sockfd;
1482
            abi_ulong target_addr;
1483
            socklen_t addrlen;
1484

    
1485
            if (get_user_s32(sockfd, vptr)
1486
                || get_user_ual(target_addr, vptr + n)
1487
                || get_user_u32(addrlen, vptr + 2 * n))
1488
                return -TARGET_EFAULT;
1489

    
1490
            ret = do_bind(sockfd, target_addr, addrlen);
1491
        }
1492
        break;
1493
    case SOCKOP_connect:
1494
        {
1495
            int sockfd;
1496
            abi_ulong target_addr;
1497
            socklen_t addrlen;
1498

    
1499
            if (get_user_s32(sockfd, vptr)
1500
                || get_user_ual(target_addr, vptr + n)
1501
                || get_user_u32(addrlen, vptr + 2 * n))
1502
                return -TARGET_EFAULT;
1503

    
1504
            ret = do_connect(sockfd, target_addr, addrlen);
1505
        }
1506
        break;
1507
    case SOCKOP_listen:
1508
        {
1509
            int sockfd, backlog;
1510

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

    
1515
            ret = get_errno(listen(sockfd, backlog));
1516
        }
1517
        break;
1518
    case SOCKOP_accept:
1519
        {
1520
            int sockfd;
1521
            abi_ulong target_addr, target_addrlen;
1522

    
1523
            if (get_user_s32(sockfd, vptr)
1524
                || get_user_ual(target_addr, vptr + n)
1525
                || get_user_u32(target_addrlen, vptr + 2 * n))
1526
                return -TARGET_EFAULT;
1527

    
1528
            ret = do_accept(sockfd, target_addr, target_addrlen);
1529
        }
1530
        break;
1531
    case SOCKOP_getsockname:
1532
        {
1533
            int sockfd;
1534
            abi_ulong target_addr, target_addrlen;
1535

    
1536
            if (get_user_s32(sockfd, vptr)
1537
                || get_user_ual(target_addr, vptr + n)
1538
                || get_user_u32(target_addrlen, vptr + 2 * n))
1539
                return -TARGET_EFAULT;
1540

    
1541
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1542
        }
1543
        break;
1544
    case SOCKOP_getpeername:
1545
        {
1546
            int sockfd;
1547
            abi_ulong target_addr, target_addrlen;
1548

    
1549
            if (get_user_s32(sockfd, vptr)
1550
                || get_user_ual(target_addr, vptr + n)
1551
                || get_user_u32(target_addrlen, vptr + 2 * n))
1552
                return -TARGET_EFAULT;
1553

    
1554
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1555
        }
1556
        break;
1557
    case SOCKOP_socketpair:
1558
        {
1559
            int domain, type, protocol;
1560
            abi_ulong tab;
1561

    
1562
            if (get_user_s32(domain, vptr)
1563
                || get_user_s32(type, vptr + n)
1564
                || get_user_s32(protocol, vptr + 2 * n)
1565
                || get_user_ual(tab, vptr + 3 * n))
1566
                return -TARGET_EFAULT;
1567

    
1568
            ret = do_socketpair(domain, type, protocol, tab);
1569
        }
1570
        break;
1571
    case SOCKOP_send:
1572
        {
1573
            int sockfd;
1574
            abi_ulong msg;
1575
            size_t len;
1576
            int flags;
1577

    
1578
            if (get_user_s32(sockfd, vptr)
1579
                || get_user_ual(msg, vptr + n)
1580
                || get_user_ual(len, vptr + 2 * n)
1581
                || get_user_s32(flags, vptr + 3 * n))
1582
                return -TARGET_EFAULT;
1583

    
1584
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1585
        }
1586
        break;
1587
    case SOCKOP_recv:
1588
        {
1589
            int sockfd;
1590
            abi_ulong msg;
1591
            size_t len;
1592
            int flags;
1593

    
1594
            if (get_user_s32(sockfd, vptr)
1595
                || get_user_ual(msg, vptr + n)
1596
                || get_user_ual(len, vptr + 2 * n)
1597
                || get_user_s32(flags, vptr + 3 * n))
1598
                return -TARGET_EFAULT;
1599

    
1600
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1601
        }
1602
        break;
1603
    case SOCKOP_sendto:
1604
        {
1605
            int sockfd;
1606
            abi_ulong msg;
1607
            size_t len;
1608
            int flags;
1609
            abi_ulong addr;
1610
            socklen_t addrlen;
1611

    
1612
            if (get_user_s32(sockfd, vptr)
1613
                || get_user_ual(msg, vptr + n)
1614
                || get_user_ual(len, vptr + 2 * n)
1615
                || get_user_s32(flags, vptr + 3 * n)
1616
                || get_user_ual(addr, vptr + 4 * n)
1617
                || get_user_u32(addrlen, vptr + 5 * n))
1618
                return -TARGET_EFAULT;
1619

    
1620
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1621
        }
1622
        break;
1623
    case SOCKOP_recvfrom:
1624
        {
1625
            int sockfd;
1626
            abi_ulong msg;
1627
            size_t len;
1628
            int flags;
1629
            abi_ulong addr;
1630
            socklen_t addrlen;
1631

    
1632
            if (get_user_s32(sockfd, vptr)
1633
                || get_user_ual(msg, vptr + n)
1634
                || get_user_ual(len, vptr + 2 * n)
1635
                || get_user_s32(flags, vptr + 3 * n)
1636
                || get_user_ual(addr, vptr + 4 * n)
1637
                || get_user_u32(addrlen, vptr + 5 * n))
1638
                return -TARGET_EFAULT;
1639

    
1640
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1641
        }
1642
        break;
1643
    case SOCKOP_shutdown:
1644
        {
1645
            int sockfd, how;
1646

    
1647
            if (get_user_s32(sockfd, vptr)
1648
                || get_user_s32(how, vptr + n))
1649
                return -TARGET_EFAULT;
1650

    
1651
            ret = get_errno(shutdown(sockfd, how));
1652
        }
1653
        break;
1654
    case SOCKOP_sendmsg:
1655
    case SOCKOP_recvmsg:
1656
        {
1657
            int fd;
1658
            abi_ulong target_msg;
1659
            int flags;
1660

    
1661
            if (get_user_s32(fd, vptr)
1662
                || get_user_ual(target_msg, vptr + n)
1663
                || get_user_s32(flags, vptr + 2 * n))
1664
                return -TARGET_EFAULT;
1665

    
1666
            ret = do_sendrecvmsg(fd, target_msg, flags,
1667
                                 (num == SOCKOP_sendmsg));
1668
        }
1669
        break;
1670
    case SOCKOP_setsockopt:
1671
        {
1672
            int sockfd;
1673
            int level;
1674
            int optname;
1675
            abi_ulong optval;
1676
            socklen_t optlen;
1677

    
1678
            if (get_user_s32(sockfd, vptr)
1679
                || get_user_s32(level, vptr + n)
1680
                || get_user_s32(optname, vptr + 2 * n)
1681
                || get_user_ual(optval, vptr + 3 * n)
1682
                || get_user_u32(optlen, vptr + 4 * n))
1683
                return -TARGET_EFAULT;
1684

    
1685
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1686
        }
1687
        break;
1688
    case SOCKOP_getsockopt:
1689
        {
1690
            int sockfd;
1691
            int level;
1692
            int optname;
1693
            abi_ulong optval;
1694
            socklen_t optlen;
1695

    
1696
            if (get_user_s32(sockfd, vptr)
1697
                || get_user_s32(level, vptr + n)
1698
                || get_user_s32(optname, vptr + 2 * n)
1699
                || get_user_ual(optval, vptr + 3 * n)
1700
                || get_user_u32(optlen, vptr + 4 * n))
1701
                return -TARGET_EFAULT;
1702

    
1703
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
1704
        }
1705
        break;
1706
    default:
1707
        gemu_log("Unsupported socketcall: %d\n", num);
1708
        ret = -TARGET_ENOSYS;
1709
        break;
1710
    }
1711
    return ret;
1712
}
1713
#endif
1714

    
1715
#ifdef TARGET_NR_ipc
1716
#define N_SHM_REGIONS        32
1717

    
1718
static struct shm_region {
1719
    abi_ulong        start;
1720
    abi_ulong        size;
1721
} shm_regions[N_SHM_REGIONS];
1722
#endif
1723

    
1724
struct target_ipc_perm
1725
{
1726
    abi_long __key;
1727
    abi_ulong uid;
1728
    abi_ulong gid;
1729
    abi_ulong cuid;
1730
    abi_ulong cgid;
1731
    unsigned short int mode;
1732
    unsigned short int __pad1;
1733
    unsigned short int __seq;
1734
    unsigned short int __pad2;
1735
    abi_ulong __unused1;
1736
    abi_ulong __unused2;
1737
};
1738

    
1739
struct target_semid_ds
1740
{
1741
  struct target_ipc_perm sem_perm;
1742
  abi_ulong sem_otime;
1743
  abi_ulong __unused1;
1744
  abi_ulong sem_ctime;
1745
  abi_ulong __unused2;
1746
  abi_ulong sem_nsems;
1747
  abi_ulong __unused3;
1748
  abi_ulong __unused4;
1749
};
1750

    
1751
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
1752
                                               abi_ulong target_addr)
1753
{
1754
    struct target_ipc_perm *target_ip;
1755
    struct target_semid_ds *target_sd;
1756

    
1757
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1758
        return -TARGET_EFAULT;
1759
    target_ip=&(target_sd->sem_perm);
1760
    host_ip->__key = tswapl(target_ip->__key);
1761
    host_ip->uid = tswapl(target_ip->uid);
1762
    host_ip->gid = tswapl(target_ip->gid);
1763
    host_ip->cuid = tswapl(target_ip->cuid);
1764
    host_ip->cgid = tswapl(target_ip->cgid);
1765
    host_ip->mode = tswapl(target_ip->mode);
1766
    unlock_user_struct(target_sd, target_addr, 0);
1767
    return 0;
1768
}
1769

    
1770
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
1771
                                               struct ipc_perm *host_ip)
1772
{
1773
    struct target_ipc_perm *target_ip;
1774
    struct target_semid_ds *target_sd;
1775

    
1776
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1777
        return -TARGET_EFAULT;
1778
    target_ip = &(target_sd->sem_perm);
1779
    target_ip->__key = tswapl(host_ip->__key);
1780
    target_ip->uid = tswapl(host_ip->uid);
1781
    target_ip->gid = tswapl(host_ip->gid);
1782
    target_ip->cuid = tswapl(host_ip->cuid);
1783
    target_ip->cgid = tswapl(host_ip->cgid);
1784
    target_ip->mode = tswapl(host_ip->mode);
1785
    unlock_user_struct(target_sd, target_addr, 1);
1786
    return 0;
1787
}
1788

    
1789
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
1790
                                               abi_ulong target_addr)
1791
{
1792
    struct target_semid_ds *target_sd;
1793

    
1794
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
1795
        return -TARGET_EFAULT;
1796
    target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr);
1797
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
1798
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
1799
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
1800
    unlock_user_struct(target_sd, target_addr, 0);
1801
    return 0;
1802
}
1803

    
1804
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
1805
                                               struct semid_ds *host_sd)
1806
{
1807
    struct target_semid_ds *target_sd;
1808

    
1809
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
1810
        return -TARGET_EFAULT;
1811
    host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm));
1812
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
1813
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
1814
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
1815
    unlock_user_struct(target_sd, target_addr, 1);
1816
    return 0;
1817
}
1818

    
1819
union semun {
1820
        int val;
1821
        struct semid_ds *buf;
1822
        unsigned short *array;
1823
};
1824

    
1825
union target_semun {
1826
        int val;
1827
        abi_long buf;
1828
        unsigned short int *array;
1829
};
1830

    
1831
static inline abi_long target_to_host_semun(int cmd,
1832
                                            union semun *host_su,
1833
                                            abi_ulong target_addr,
1834
                                            struct semid_ds *ds)
1835
{
1836
    union target_semun *target_su;
1837

    
1838
    switch( cmd ) {
1839
        case IPC_STAT:
1840
        case IPC_SET:
1841
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1842
               return -TARGET_EFAULT;
1843
           target_to_host_semid_ds(ds,target_su->buf);
1844
           host_su->buf = ds;
1845
           unlock_user_struct(target_su, target_addr, 0);
1846
           break;
1847
        case GETVAL:
1848
        case SETVAL:
1849
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1850
               return -TARGET_EFAULT;
1851
           host_su->val = tswapl(target_su->val);
1852
           unlock_user_struct(target_su, target_addr, 0);
1853
           break;
1854
        case GETALL:
1855
        case SETALL:
1856
           if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1))
1857
               return -TARGET_EFAULT;
1858
           *host_su->array = tswap16(*target_su->array);
1859
           unlock_user_struct(target_su, target_addr, 0);
1860
           break;
1861
        default:
1862
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1863
    }
1864
    return 0;
1865
}
1866

    
1867
static inline abi_long host_to_target_semun(int cmd,
1868
                                            abi_ulong target_addr,
1869
                                            union semun *host_su,
1870
                                            struct semid_ds *ds)
1871
{
1872
    union target_semun *target_su;
1873

    
1874
    switch( cmd ) {
1875
        case IPC_STAT:
1876
        case IPC_SET:
1877
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1878
               return -TARGET_EFAULT;
1879
           host_to_target_semid_ds(target_su->buf,ds);
1880
           unlock_user_struct(target_su, target_addr, 1);
1881
           break;
1882
        case GETVAL:
1883
        case SETVAL:
1884
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1885
               return -TARGET_EFAULT;
1886
           target_su->val = tswapl(host_su->val);
1887
           unlock_user_struct(target_su, target_addr, 1);
1888
           break;
1889
        case GETALL:
1890
        case SETALL:
1891
           if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0))
1892
               return -TARGET_EFAULT;
1893
           *target_su->array = tswap16(*host_su->array);
1894
           unlock_user_struct(target_su, target_addr, 1);
1895
           break;
1896
        default:
1897
           gemu_log("semun operation not fully supported: %d\n", (int)cmd);
1898
    }
1899
    return 0;
1900
}
1901

    
1902
static inline abi_long do_semctl(int first, int second, int third,
1903
                                 abi_long ptr)
1904
{
1905
    union semun arg;
1906
    struct semid_ds dsarg;
1907
    int cmd = third&0xff;
1908
    abi_long ret = 0;
1909

    
1910
    switch( cmd ) {
1911
        case GETVAL:
1912
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1913
            ret = get_errno(semctl(first, second, cmd, arg));
1914
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1915
            break;
1916
        case SETVAL:
1917
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1918
            ret = get_errno(semctl(first, second, cmd, arg));
1919
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1920
            break;
1921
        case GETALL:
1922
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1923
            ret = get_errno(semctl(first, second, cmd, arg));
1924
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1925
            break;
1926
        case SETALL:
1927
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1928
            ret = get_errno(semctl(first, second, cmd, arg));
1929
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1930
            break;
1931
        case IPC_STAT:
1932
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1933
            ret = get_errno(semctl(first, second, cmd, arg));
1934
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1935
            break;
1936
        case IPC_SET:
1937
            target_to_host_semun(cmd,&arg,ptr,&dsarg);
1938
            ret = get_errno(semctl(first, second, cmd, arg));
1939
            host_to_target_semun(cmd,ptr,&arg,&dsarg);
1940
            break;
1941
    default:
1942
            ret = get_errno(semctl(first, second, cmd, arg));
1943
    }
1944

    
1945
    return ret;
1946
}
1947

    
1948
struct target_msqid_ds
1949
{
1950
    struct target_ipc_perm msg_perm;
1951
    abi_ulong msg_stime;
1952
#if TARGET_ABI_BITS == 32
1953
    abi_ulong __unused1;
1954
#endif
1955
    abi_ulong msg_rtime;
1956
#if TARGET_ABI_BITS == 32
1957
    abi_ulong __unused2;
1958
#endif
1959
    abi_ulong msg_ctime;
1960
#if TARGET_ABI_BITS == 32
1961
    abi_ulong __unused3;
1962
#endif
1963
    abi_ulong __msg_cbytes;
1964
    abi_ulong msg_qnum;
1965
    abi_ulong msg_qbytes;
1966
    abi_ulong msg_lspid;
1967
    abi_ulong msg_lrpid;
1968
    abi_ulong __unused4;
1969
    abi_ulong __unused5;
1970
};
1971

    
1972
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
1973
                                               abi_ulong target_addr)
1974
{
1975
    struct target_msqid_ds *target_md;
1976

    
1977
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
1978
        return -TARGET_EFAULT;
1979
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
1980
        return -TARGET_EFAULT;
1981
    host_md->msg_stime = tswapl(target_md->msg_stime);
1982
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
1983
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
1984
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
1985
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
1986
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
1987
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
1988
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
1989
    unlock_user_struct(target_md, target_addr, 0);
1990
    return 0;
1991
}
1992

    
1993
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
1994
                                               struct msqid_ds *host_md)
1995
{
1996
    struct target_msqid_ds *target_md;
1997

    
1998
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
1999
        return -TARGET_EFAULT;
2000
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2001
        return -TARGET_EFAULT;
2002
    target_md->msg_stime = tswapl(host_md->msg_stime);
2003
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2004
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2005
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2006
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2007
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2008
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2009
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2010
    unlock_user_struct(target_md, target_addr, 1);
2011
    return 0;
2012
}
2013

    
2014
struct target_msginfo {
2015
    int msgpool;
2016
    int msgmap;
2017
    int msgmax;
2018
    int msgmnb;
2019
    int msgmni;
2020
    int msgssz;
2021
    int msgtql;
2022
    unsigned short int msgseg;
2023
};
2024

    
2025
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2026
                                              struct msginfo *host_msginfo)
2027
{
2028
    struct target_msginfo *target_msginfo;
2029
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2030
        return -TARGET_EFAULT;
2031
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2032
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2033
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2034
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2035
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2036
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2037
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2038
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2039
    unlock_user_struct(target_msginfo, target_addr, 1);
2040
    return 0;
2041
}
2042

    
2043
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2044
{
2045
    struct msqid_ds dsarg;
2046
    struct msginfo msginfo;
2047
    abi_long ret = -TARGET_EINVAL;
2048

    
2049
    cmd &= 0xff;
2050

    
2051
    switch (cmd) {
2052
    case IPC_STAT:
2053
    case IPC_SET:
2054
    case MSG_STAT:
2055
        if (target_to_host_msqid_ds(&dsarg,ptr))
2056
            return -TARGET_EFAULT;
2057
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2058
        if (host_to_target_msqid_ds(ptr,&dsarg))
2059
            return -TARGET_EFAULT;
2060
        break;
2061
    case IPC_RMID:
2062
        ret = get_errno(msgctl(msgid, cmd, NULL));
2063
        break;
2064
    case IPC_INFO:
2065
    case MSG_INFO:
2066
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2067
        if (host_to_target_msginfo(ptr, &msginfo))
2068
            return -TARGET_EFAULT;
2069
        break;
2070
    }
2071

    
2072
    return ret;
2073
}
2074

    
2075
struct target_msgbuf {
2076
    abi_long mtype;
2077
    char        mtext[1];
2078
};
2079

    
2080
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2081
                                 unsigned int msgsz, int msgflg)
2082
{
2083
    struct target_msgbuf *target_mb;
2084
    struct msgbuf *host_mb;
2085
    abi_long ret = 0;
2086

    
2087
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2088
        return -TARGET_EFAULT;
2089
    host_mb = malloc(msgsz+sizeof(long));
2090
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2091
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2092
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2093
    free(host_mb);
2094
    unlock_user_struct(target_mb, msgp, 0);
2095

    
2096
    return ret;
2097
}
2098

    
2099
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2100
                                 unsigned int msgsz, abi_long msgtyp,
2101
                                 int msgflg)
2102
{
2103
    struct target_msgbuf *target_mb;
2104
    char *target_mtext;
2105
    struct msgbuf *host_mb;
2106
    abi_long ret = 0;
2107

    
2108
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2109
        return -TARGET_EFAULT;
2110

    
2111
    host_mb = malloc(msgsz+sizeof(long));
2112
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2113

    
2114
    if (ret > 0) {
2115
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2116
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2117
        if (!target_mtext) {
2118
            ret = -TARGET_EFAULT;
2119
            goto end;
2120
        }
2121
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2122
        unlock_user(target_mtext, target_mtext_addr, ret);
2123
    }
2124

    
2125
    target_mb->mtype = tswapl(host_mb->mtype);
2126
    free(host_mb);
2127

    
2128
end:
2129
    if (target_mb)
2130
        unlock_user_struct(target_mb, msgp, 1);
2131
    return ret;
2132
}
2133

    
2134
#ifdef TARGET_NR_ipc
2135
/* ??? This only works with linear mappings.  */
2136
/* do_ipc() must return target values and target errnos. */
2137
static abi_long do_ipc(unsigned int call, int first,
2138
                       int second, int third,
2139
                       abi_long ptr, abi_long fifth)
2140
{
2141
    int version;
2142
    abi_long ret = 0;
2143
    struct shmid_ds shm_info;
2144
    int i;
2145

    
2146
    version = call >> 16;
2147
    call &= 0xffff;
2148

    
2149
    switch (call) {
2150
    case IPCOP_semop:
2151
        ret = get_errno(semop(first,(struct sembuf *)g2h(ptr), second));
2152
        break;
2153

    
2154
    case IPCOP_semget:
2155
        ret = get_errno(semget(first, second, third));
2156
        break;
2157

    
2158
    case IPCOP_semctl:
2159
        ret = do_semctl(first, second, third, ptr);
2160
        break;
2161

    
2162
    case IPCOP_semtimedop:
2163
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2164
        ret = -TARGET_ENOSYS;
2165
        break;
2166

    
2167
    case IPCOP_msgget:
2168
        ret = get_errno(msgget(first, second));
2169
        break;
2170

    
2171
    case IPCOP_msgsnd:
2172
        ret = do_msgsnd(first, ptr, second, third);
2173
        break;
2174

    
2175
    case IPCOP_msgctl:
2176
        ret = do_msgctl(first, second, ptr);
2177
        break;
2178

    
2179
    case IPCOP_msgrcv:
2180
        switch (version) {
2181
        case 0:
2182
            {
2183
                struct target_ipc_kludge {
2184
                    abi_long msgp;
2185
                    abi_long msgtyp;
2186
                } *tmp;
2187

    
2188
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2189
                    ret = -TARGET_EFAULT;
2190
                    break;
2191
                }
2192

    
2193
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2194

    
2195
                unlock_user_struct(tmp, ptr, 0);
2196
                break;
2197
            }
2198
        default:
2199
            ret = do_msgrcv(first, ptr, second, fifth, third);
2200
        }
2201
        break;
2202

    
2203
    case IPCOP_shmat:
2204
        {
2205
            abi_ulong raddr;
2206
            void *host_addr;
2207
            /* SHM_* flags are the same on all linux platforms */
2208
            host_addr = shmat(first, (void *)g2h(ptr), second);
2209
            if (host_addr == (void *)-1) {
2210
                ret = get_errno((long)host_addr);
2211
                break;
2212
            }
2213
            raddr = h2g((unsigned long)host_addr);
2214
            /* find out the length of the shared memory segment */
2215
            
2216
            ret = get_errno(shmctl(first, IPC_STAT, &shm_info));
2217
            if (is_error(ret)) {
2218
                /* can't get length, bail out */
2219
                shmdt(host_addr);
2220
                break;
2221
            }
2222
            page_set_flags(raddr, raddr + shm_info.shm_segsz,
2223
                           PAGE_VALID | PAGE_READ |
2224
                           ((second & SHM_RDONLY)? 0: PAGE_WRITE));
2225
            for (i = 0; i < N_SHM_REGIONS; ++i) {
2226
                if (shm_regions[i].start == 0) {
2227
                    shm_regions[i].start = raddr;
2228
                    shm_regions[i].size = shm_info.shm_segsz;
2229
                    break;
2230
                }
2231
            }
2232
            if (put_user_ual(raddr, third))
2233
                return -TARGET_EFAULT;
2234
            ret = 0;
2235
        }
2236
        break;
2237
    case IPCOP_shmdt:
2238
        for (i = 0; i < N_SHM_REGIONS; ++i) {
2239
            if (shm_regions[i].start == ptr) {
2240
                shm_regions[i].start = 0;
2241
                page_set_flags(ptr, shm_regions[i].size, 0);
2242
                break;
2243
            }
2244
        }
2245
        ret = get_errno(shmdt((void *)g2h(ptr)));
2246
        break;
2247

    
2248
    case IPCOP_shmget:
2249
        /* IPC_* flag values are the same on all linux platforms */
2250
        ret = get_errno(shmget(first, second, third));
2251
        break;
2252

    
2253
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2254
    case IPCOP_shmctl:
2255
        switch(second) {
2256
        case IPC_RMID:
2257
        case SHM_LOCK:
2258
        case SHM_UNLOCK:
2259
            ret = get_errno(shmctl(first, second, NULL));
2260
            break;
2261
        default:
2262
            goto unimplemented;
2263
        }
2264
        break;
2265
    default:
2266
    unimplemented:
2267
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2268
        ret = -TARGET_ENOSYS;
2269
        break;
2270
    }
2271
    return ret;
2272
}
2273
#endif
2274

    
2275
/* kernel structure types definitions */
2276
#define IFNAMSIZ        16
2277

    
2278
#define STRUCT(name, list...) STRUCT_ ## name,
2279
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2280
enum {
2281
#include "syscall_types.h"
2282
};
2283
#undef STRUCT
2284
#undef STRUCT_SPECIAL
2285

    
2286
#define STRUCT(name, list...) static const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
2287
#define STRUCT_SPECIAL(name)
2288
#include "syscall_types.h"
2289
#undef STRUCT
2290
#undef STRUCT_SPECIAL
2291

    
2292
typedef struct IOCTLEntry {
2293
    unsigned int target_cmd;
2294
    unsigned int host_cmd;
2295
    const char *name;
2296
    int access;
2297
    const argtype arg_type[5];
2298
} IOCTLEntry;
2299

    
2300
#define IOC_R 0x0001
2301
#define IOC_W 0x0002
2302
#define IOC_RW (IOC_R | IOC_W)
2303

    
2304
#define MAX_STRUCT_SIZE 4096
2305

    
2306
static IOCTLEntry ioctl_entries[] = {
2307
#define IOCTL(cmd, access, types...) \
2308
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
2309
#include "ioctls.h"
2310
    { 0, 0, },
2311
};
2312

    
2313
/* ??? Implement proper locking for ioctls.  */
2314
/* do_ioctl() Must return target values and target errnos. */
2315
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2316
{
2317
    const IOCTLEntry *ie;
2318
    const argtype *arg_type;
2319
    abi_long ret;
2320
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2321
    int target_size;
2322
    void *argptr;
2323

    
2324
    ie = ioctl_entries;
2325
    for(;;) {
2326
        if (ie->target_cmd == 0) {
2327
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2328
            return -TARGET_ENOSYS;
2329
        }
2330
        if (ie->target_cmd == cmd)
2331
            break;
2332
        ie++;
2333
    }
2334
    arg_type = ie->arg_type;
2335
#if defined(DEBUG)
2336
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2337
#endif
2338
    switch(arg_type[0]) {
2339
    case TYPE_NULL:
2340
        /* no argument */
2341
        ret = get_errno(ioctl(fd, ie->host_cmd));
2342
        break;
2343
    case TYPE_PTRVOID:
2344
    case TYPE_INT:
2345
        /* int argment */
2346
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2347
        break;
2348
    case TYPE_PTR:
2349
        arg_type++;
2350
        target_size = thunk_type_size(arg_type, 0);
2351
        switch(ie->access) {
2352
        case IOC_R:
2353
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2354
            if (!is_error(ret)) {
2355
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2356
                if (!argptr)
2357
                    return -TARGET_EFAULT;
2358
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2359
                unlock_user(argptr, arg, target_size);
2360
            }
2361
            break;
2362
        case IOC_W:
2363
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2364
            if (!argptr)
2365
                return -TARGET_EFAULT;
2366
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2367
            unlock_user(argptr, arg, 0);
2368
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2369
            break;
2370
        default:
2371
        case IOC_RW:
2372
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2373
            if (!argptr)
2374
                return -TARGET_EFAULT;
2375
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2376
            unlock_user(argptr, arg, 0);
2377
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2378
            if (!is_error(ret)) {
2379
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2380
                if (!argptr)
2381
                    return -TARGET_EFAULT;
2382
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2383
                unlock_user(argptr, arg, target_size);
2384
            }
2385
            break;
2386
        }
2387
        break;
2388
    default:
2389
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2390
                 (long)cmd, arg_type[0]);
2391
        ret = -TARGET_ENOSYS;
2392
        break;
2393
    }
2394
    return ret;
2395
}
2396

    
2397
static const bitmask_transtbl iflag_tbl[] = {
2398
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2399
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2400
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2401
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2402
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2403
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2404
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2405
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2406
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2407
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2408
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2409
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2410
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2411
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2412
        { 0, 0, 0, 0 }
2413
};
2414

    
2415
static const bitmask_transtbl oflag_tbl[] = {
2416
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2417
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2418
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2419
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2420
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2421
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2422
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2423
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2424
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2425
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2426
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2427
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2428
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2429
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2430
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2431
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2432
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2433
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
2434
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
2435
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
2436
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
2437
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
2438
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
2439
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
2440
        { 0, 0, 0, 0 }
2441
};
2442

    
2443
static const bitmask_transtbl cflag_tbl[] = {
2444
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
2445
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
2446
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
2447
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
2448
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
2449
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
2450
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
2451
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
2452
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
2453
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
2454
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
2455
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
2456
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
2457
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
2458
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
2459
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
2460
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
2461
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
2462
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
2463
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
2464
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
2465
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
2466
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
2467
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
2468
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
2469
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
2470
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
2471
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
2472
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
2473
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
2474
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
2475
        { 0, 0, 0, 0 }
2476
};
2477

    
2478
static const bitmask_transtbl lflag_tbl[] = {
2479
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
2480
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
2481
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
2482
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
2483
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
2484
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
2485
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
2486
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
2487
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
2488
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
2489
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
2490
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
2491
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
2492
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
2493
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
2494
        { 0, 0, 0, 0 }
2495
};
2496

    
2497
static void target_to_host_termios (void *dst, const void *src)
2498
{
2499
    struct host_termios *host = dst;
2500
    const struct target_termios *target = src;
2501

    
2502
    host->c_iflag =
2503
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
2504
    host->c_oflag =
2505
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
2506
    host->c_cflag =
2507
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
2508
    host->c_lflag =
2509
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
2510
    host->c_line = target->c_line;
2511

    
2512
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
2513
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
2514
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
2515
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
2516
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
2517
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
2518
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
2519
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
2520
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
2521
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
2522
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
2523
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
2524
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
2525
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
2526
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
2527
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
2528
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
2529
}
2530

    
2531
static void host_to_target_termios (void *dst, const void *src)
2532
{
2533
    struct target_termios *target = dst;
2534
    const struct host_termios *host = src;
2535

    
2536
    target->c_iflag =
2537
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
2538
    target->c_oflag =
2539
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
2540
    target->c_cflag =
2541
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
2542
    target->c_lflag =
2543
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
2544
    target->c_line = host->c_line;
2545

    
2546
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
2547
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
2548
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
2549
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
2550
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
2551
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
2552
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
2553
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
2554
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
2555
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
2556
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
2557
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
2558
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
2559
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
2560
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
2561
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
2562
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
2563
}
2564

    
2565
static const StructEntry struct_termios_def = {
2566
    .convert = { host_to_target_termios, target_to_host_termios },
2567
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
2568
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
2569
};
2570

    
2571
static bitmask_transtbl mmap_flags_tbl[] = {
2572
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
2573
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
2574
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
2575
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
2576
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
2577
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
2578
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
2579
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
2580
        { 0, 0, 0, 0 }
2581
};
2582

    
2583
static bitmask_transtbl fcntl_flags_tbl[] = {
2584
        { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
2585
        { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
2586
        { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
2587
        { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
2588
        { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
2589
        { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
2590
        { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
2591
        { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
2592
        { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
2593
        { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
2594
        { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
2595
        { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
2596
        { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
2597
#if defined(O_DIRECT)
2598
        { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
2599
#endif
2600
        { 0, 0, 0, 0 }
2601
};
2602

    
2603
#if defined(TARGET_I386)
2604

    
2605
/* NOTE: there is really one LDT for all the threads */
2606
static uint8_t *ldt_table;
2607

    
2608
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
2609
{
2610
    int size;
2611
    void *p;
2612

    
2613
    if (!ldt_table)
2614
        return 0;
2615
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
2616
    if (size > bytecount)
2617
        size = bytecount;
2618
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
2619
    if (!p)
2620
        return -TARGET_EFAULT;
2621
    /* ??? Should this by byteswapped?  */
2622
    memcpy(p, ldt_table, size);
2623
    unlock_user(p, ptr, size);
2624
    return size;
2625
}
2626

    
2627
/* XXX: add locking support */
2628
static abi_long write_ldt(CPUX86State *env,
2629
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
2630
{
2631
    struct target_modify_ldt_ldt_s ldt_info;
2632
    struct target_modify_ldt_ldt_s *target_ldt_info;
2633
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2634
    int seg_not_present, useable, lm;
2635
    uint32_t *lp, entry_1, entry_2;
2636

    
2637
    if (bytecount != sizeof(ldt_info))
2638
        return -TARGET_EINVAL;
2639
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
2640
        return -TARGET_EFAULT;
2641
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2642
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2643
    ldt_info.limit = tswap32(target_ldt_info->limit);
2644
    ldt_info.flags = tswap32(target_ldt_info->flags);
2645
    unlock_user_struct(target_ldt_info, ptr, 0);
2646

    
2647
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
2648
        return -TARGET_EINVAL;
2649
    seg_32bit = ldt_info.flags & 1;
2650
    contents = (ldt_info.flags >> 1) & 3;
2651
    read_exec_only = (ldt_info.flags >> 3) & 1;
2652
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2653
    seg_not_present = (ldt_info.flags >> 5) & 1;
2654
    useable = (ldt_info.flags >> 6) & 1;
2655
#ifdef TARGET_ABI32
2656
    lm = 0;
2657
#else
2658
    lm = (ldt_info.flags >> 7) & 1;
2659
#endif
2660
    if (contents == 3) {
2661
        if (oldmode)
2662
            return -TARGET_EINVAL;
2663
        if (seg_not_present == 0)
2664
            return -TARGET_EINVAL;
2665
    }
2666
    /* allocate the LDT */
2667
    if (!ldt_table) {
2668
        env->ldt.base = target_mmap(0,
2669
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
2670
                                    PROT_READ|PROT_WRITE,
2671
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2672
        if (env->ldt.base == -1)
2673
            return -TARGET_ENOMEM;
2674
        memset(g2h(env->ldt.base), 0,
2675
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
2676
        env->ldt.limit = 0xffff;
2677
        ldt_table = g2h(env->ldt.base);
2678
    }
2679

    
2680
    /* NOTE: same code as Linux kernel */
2681
    /* Allow LDTs to be cleared by the user. */
2682
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2683
        if (oldmode ||
2684
            (contents == 0                &&
2685
             read_exec_only == 1        &&
2686
             seg_32bit == 0                &&
2687
             limit_in_pages == 0        &&
2688
             seg_not_present == 1        &&
2689
             useable == 0 )) {
2690
            entry_1 = 0;
2691
            entry_2 = 0;
2692
            goto install;
2693
        }
2694
    }
2695

    
2696
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2697
        (ldt_info.limit & 0x0ffff);
2698
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2699
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2700
        (ldt_info.limit & 0xf0000) |
2701
        ((read_exec_only ^ 1) << 9) |
2702
        (contents << 10) |
2703
        ((seg_not_present ^ 1) << 15) |
2704
        (seg_32bit << 22) |
2705
        (limit_in_pages << 23) |
2706
        (lm << 21) |
2707
        0x7000;
2708
    if (!oldmode)
2709
        entry_2 |= (useable << 20);
2710

    
2711
    /* Install the new entry ...  */
2712
install:
2713
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
2714
    lp[0] = tswap32(entry_1);
2715
    lp[1] = tswap32(entry_2);
2716
    return 0;
2717
}
2718

    
2719
/* specific and weird i386 syscalls */
2720
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
2721
                              unsigned long bytecount)
2722
{
2723
    abi_long ret;
2724

    
2725
    switch (func) {
2726
    case 0:
2727
        ret = read_ldt(ptr, bytecount);
2728
        break;
2729
    case 1:
2730
        ret = write_ldt(env, ptr, bytecount, 1);
2731
        break;
2732
    case 0x11:
2733
        ret = write_ldt(env, ptr, bytecount, 0);
2734
        break;
2735
    default:
2736
        ret = -TARGET_ENOSYS;
2737
        break;
2738
    }
2739
    return ret;
2740
}
2741

    
2742
#if defined(TARGET_I386) && defined(TARGET_ABI32)
2743
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
2744
{
2745
    uint64_t *gdt_table = g2h(env->gdt.base);
2746
    struct target_modify_ldt_ldt_s ldt_info;
2747
    struct target_modify_ldt_ldt_s *target_ldt_info;
2748
    int seg_32bit, contents, read_exec_only, limit_in_pages;
2749
    int seg_not_present, useable, lm;
2750
    uint32_t *lp, entry_1, entry_2;
2751
    int i;
2752

    
2753
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2754
    if (!target_ldt_info)
2755
        return -TARGET_EFAULT;
2756
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
2757
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
2758
    ldt_info.limit = tswap32(target_ldt_info->limit);
2759
    ldt_info.flags = tswap32(target_ldt_info->flags);
2760
    if (ldt_info.entry_number == -1) {
2761
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
2762
            if (gdt_table[i] == 0) {
2763
                ldt_info.entry_number = i;
2764
                target_ldt_info->entry_number = tswap32(i);
2765
                break;
2766
            }
2767
        }
2768
    }
2769
    unlock_user_struct(target_ldt_info, ptr, 1);
2770

    
2771
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
2772
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
2773
           return -TARGET_EINVAL;
2774
    seg_32bit = ldt_info.flags & 1;
2775
    contents = (ldt_info.flags >> 1) & 3;
2776
    read_exec_only = (ldt_info.flags >> 3) & 1;
2777
    limit_in_pages = (ldt_info.flags >> 4) & 1;
2778
    seg_not_present = (ldt_info.flags >> 5) & 1;
2779
    useable = (ldt_info.flags >> 6) & 1;
2780
#ifdef TARGET_ABI32
2781
    lm = 0;
2782
#else
2783
    lm = (ldt_info.flags >> 7) & 1;
2784
#endif
2785

    
2786
    if (contents == 3) {
2787
        if (seg_not_present == 0)
2788
            return -TARGET_EINVAL;
2789
    }
2790

    
2791
    /* NOTE: same code as Linux kernel */
2792
    /* Allow LDTs to be cleared by the user. */
2793
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
2794
        if ((contents == 0             &&
2795
             read_exec_only == 1       &&
2796
             seg_32bit == 0            &&
2797
             limit_in_pages == 0       &&
2798
             seg_not_present == 1      &&
2799
             useable == 0 )) {
2800
            entry_1 = 0;
2801
            entry_2 = 0;
2802
            goto install;
2803
        }
2804
    }
2805

    
2806
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
2807
        (ldt_info.limit & 0x0ffff);
2808
    entry_2 = (ldt_info.base_addr & 0xff000000) |
2809
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
2810
        (ldt_info.limit & 0xf0000) |
2811
        ((read_exec_only ^ 1) << 9) |
2812
        (contents << 10) |
2813
        ((seg_not_present ^ 1) << 15) |
2814
        (seg_32bit << 22) |
2815
        (limit_in_pages << 23) |
2816
        (useable << 20) |
2817
        (lm << 21) |
2818
        0x7000;
2819

    
2820
    /* Install the new entry ...  */
2821
install:
2822
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
2823
    lp[0] = tswap32(entry_1);
2824
    lp[1] = tswap32(entry_2);
2825
    return 0;
2826
}
2827

    
2828
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
2829
{
2830
    struct target_modify_ldt_ldt_s *target_ldt_info;
2831
    uint64_t *gdt_table = g2h(env->gdt.base);
2832
    uint32_t base_addr, limit, flags;
2833
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
2834
    int seg_not_present, useable, lm;
2835
    uint32_t *lp, entry_1, entry_2;
2836

    
2837
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
2838
    if (!target_ldt_info)
2839
        return -TARGET_EFAULT;
2840
    idx = tswap32(target_ldt_info->entry_number);
2841
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
2842
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
2843
        unlock_user_struct(target_ldt_info, ptr, 1);
2844
        return -TARGET_EINVAL;
2845
    }
2846
    lp = (uint32_t *)(gdt_table + idx);
2847
    entry_1 = tswap32(lp[0]);
2848
    entry_2 = tswap32(lp[1]);
2849
    
2850
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
2851
    contents = (entry_2 >> 10) & 3;
2852
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
2853
    seg_32bit = (entry_2 >> 22) & 1;
2854
    limit_in_pages = (entry_2 >> 23) & 1;
2855
    useable = (entry_2 >> 20) & 1;
2856
#ifdef TARGET_ABI32
2857
    lm = 0;
2858
#else
2859
    lm = (entry_2 >> 21) & 1;
2860
#endif
2861
    flags = (seg_32bit << 0) | (contents << 1) |
2862
        (read_exec_only << 3) | (limit_in_pages << 4) |
2863
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
2864
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
2865
    base_addr = (entry_1 >> 16) | 
2866
        (entry_2 & 0xff000000) | 
2867
        ((entry_2 & 0xff) << 16);
2868
    target_ldt_info->base_addr = tswapl(base_addr);
2869
    target_ldt_info->limit = tswap32(limit);
2870
    target_ldt_info->flags = tswap32(flags);
2871
    unlock_user_struct(target_ldt_info, ptr, 1);
2872
    return 0;
2873
}
2874
#endif /* TARGET_I386 && TARGET_ABI32 */
2875

    
2876
#ifndef TARGET_ABI32
2877
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
2878
{
2879
    abi_long ret;
2880
    abi_ulong val;
2881
    int idx;
2882
    
2883
    switch(code) {
2884
    case TARGET_ARCH_SET_GS:
2885
    case TARGET_ARCH_SET_FS:
2886
        if (code == TARGET_ARCH_SET_GS)
2887
            idx = R_GS;
2888
        else
2889
            idx = R_FS;
2890
        cpu_x86_load_seg(env, idx, 0);
2891
        env->segs[idx].base = addr;
2892
        break;
2893
    case TARGET_ARCH_GET_GS:
2894
    case TARGET_ARCH_GET_FS:
2895
        if (code == TARGET_ARCH_GET_GS)
2896
            idx = R_GS;
2897
        else
2898
            idx = R_FS;
2899
        val = env->segs[idx].base;
2900
        if (put_user(val, addr, abi_ulong))
2901
            return -TARGET_EFAULT;
2902
        break;
2903
    default:
2904
        ret = -TARGET_EINVAL;
2905
        break;
2906
    }
2907
    return 0;
2908
}
2909
#endif
2910

    
2911
#endif /* defined(TARGET_I386) */
2912

    
2913
#if defined(USE_NPTL)
2914

    
2915
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
2916

    
2917
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
2918
typedef struct {
2919
    CPUState *env;
2920
    pthread_mutex_t mutex;
2921
    pthread_cond_t cond;
2922
    pthread_t thread;
2923
    uint32_t tid;
2924
    abi_ulong child_tidptr;
2925
    abi_ulong parent_tidptr;
2926
    sigset_t sigmask;
2927
} new_thread_info;
2928

    
2929
static void *clone_func(void *arg)
2930
{
2931
    new_thread_info *info = arg;
2932
    CPUState *env;
2933

    
2934
    env = info->env;
2935
    thread_env = env;
2936
    info->tid = gettid();
2937
    if (info->child_tidptr)
2938
        put_user_u32(info->tid, info->child_tidptr);
2939
    if (info->parent_tidptr)
2940
        put_user_u32(info->tid, info->parent_tidptr);
2941
    /* Enable signals.  */
2942
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
2943
    /* Signal to the parent that we're ready.  */
2944
    pthread_mutex_lock(&info->mutex);
2945
    pthread_cond_broadcast(&info->cond);
2946
    pthread_mutex_unlock(&info->mutex);
2947
    /* Wait until the parent has finshed initializing the tls state.  */
2948
    pthread_mutex_lock(&clone_lock);
2949
    pthread_mutex_unlock(&clone_lock);
2950
    cpu_loop(env);
2951
    /* never exits */
2952
    return NULL;
2953
}
2954
#else
2955
/* this stack is the equivalent of the kernel stack associated with a
2956
   thread/process */
2957
#define NEW_STACK_SIZE 8192
2958

    
2959
static int clone_func(void *arg)
2960
{
2961
    CPUState *env = arg;
2962
    cpu_loop(env);
2963
    /* never exits */
2964
    return 0;
2965
}
2966
#endif
2967

    
2968
/* do_fork() Must return host values and target errnos (unlike most
2969
   do_*() functions). */
2970
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2971
                   abi_ulong parent_tidptr, target_ulong newtls,
2972
                   abi_ulong child_tidptr)
2973
{
2974
    int ret;
2975
    TaskState *ts;
2976
    uint8_t *new_stack;
2977
    CPUState *new_env;
2978
#if defined(USE_NPTL)
2979
    unsigned int nptl_flags;
2980
    sigset_t sigmask;
2981
#endif
2982

    
2983
    /* Emulate vfork() with fork() */
2984
    if (flags & CLONE_VFORK)
2985
        flags &= ~(CLONE_VFORK | CLONE_VM);
2986

    
2987
    if (flags & CLONE_VM) {
2988
#if defined(USE_NPTL)
2989
        new_thread_info info;
2990
        pthread_attr_t attr;
2991
#endif
2992
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
2993
        init_task_state(ts);
2994
        new_stack = ts->stack;
2995
        /* we create a new CPU instance. */
2996
        new_env = cpu_copy(env);
2997
        /* Init regs that differ from the parent.  */
2998
        cpu_clone_regs(new_env, newsp);
2999
        new_env->opaque = ts;
3000
#if defined(USE_NPTL)
3001
        nptl_flags = flags;
3002
        flags &= ~CLONE_NPTL_FLAGS2;
3003

    
3004
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3005
            ts->child_tidptr = child_tidptr;
3006
        }
3007

    
3008
        if (nptl_flags & CLONE_SETTLS)
3009
            cpu_set_tls (new_env, newtls);
3010

    
3011
        /* Grab a mutex so that thread setup appears atomic.  */
3012
        pthread_mutex_lock(&clone_lock);
3013

    
3014
        memset(&info, 0, sizeof(info));
3015
        pthread_mutex_init(&info.mutex, NULL);
3016
        pthread_mutex_lock(&info.mutex);
3017
        pthread_cond_init(&info.cond, NULL);
3018
        info.env = new_env;
3019
        if (nptl_flags & CLONE_CHILD_SETTID)
3020
            info.child_tidptr = child_tidptr;
3021
        if (nptl_flags & CLONE_PARENT_SETTID)
3022
            info.parent_tidptr = parent_tidptr;
3023

    
3024
        ret = pthread_attr_init(&attr);
3025
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3026
        /* It is not safe to deliver signals until the child has finished
3027
           initializing, so temporarily block all signals.  */
3028
        sigfillset(&sigmask);
3029
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3030

    
3031
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
3032
        /* TODO: Free new CPU state if thread creation failed.  */
3033

    
3034
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3035
        pthread_attr_destroy(&attr);
3036
        if (ret == 0) {
3037
            /* Wait for the child to initialize.  */
3038
            pthread_cond_wait(&info.cond, &info.mutex);
3039
            ret = info.tid;
3040
            if (flags & CLONE_PARENT_SETTID)
3041
                put_user_u32(ret, parent_tidptr);
3042
        } else {
3043
            ret = -1;
3044
        }
3045
        pthread_mutex_unlock(&info.mutex);
3046
        pthread_cond_destroy(&info.cond);
3047
        pthread_mutex_destroy(&info.mutex);
3048
        pthread_mutex_unlock(&clone_lock);
3049
#else
3050
        if (flags & CLONE_NPTL_FLAGS2)
3051
            return -EINVAL;
3052
        /* This is probably going to die very quickly, but do it anyway.  */
3053
#ifdef __ia64__
3054
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3055
#else
3056
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3057
#endif
3058
#endif
3059
    } else {
3060
        /* if no CLONE_VM, we consider it is a fork */
3061
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3062
            return -EINVAL;
3063
        fork_start();
3064
        ret = fork();
3065
        if (ret == 0) {
3066
            /* Child Process.  */
3067
            cpu_clone_regs(env, newsp);
3068
            fork_end(1);
3069
#if defined(USE_NPTL)
3070
            /* There is a race condition here.  The parent process could
3071
               theoretically read the TID in the child process before the child
3072
               tid is set.  This would require using either ptrace
3073
               (not implemented) or having *_tidptr to point at a shared memory
3074
               mapping.  We can't repeat the spinlock hack used above because
3075
               the child process gets its own copy of the lock.  */
3076
            if (flags & CLONE_CHILD_SETTID)
3077
                put_user_u32(gettid(), child_tidptr);
3078
            if (flags & CLONE_PARENT_SETTID)
3079
                put_user_u32(gettid(), parent_tidptr);
3080
            ts = (TaskState *)env->opaque;
3081
            if (flags & CLONE_SETTLS)
3082
                cpu_set_tls (env, newtls);
3083
            if (flags & CLONE_CHILD_CLEARTID)
3084
                ts->child_tidptr = child_tidptr;
3085
#endif
3086
        } else {
3087
            fork_end(0);
3088
        }
3089
    }
3090
    return ret;
3091
}
3092

    
3093
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3094
{
3095
    struct flock fl;
3096
    struct target_flock *target_fl;
3097
    struct flock64 fl64;
3098
    struct target_flock64 *target_fl64;
3099
    abi_long ret;
3100

    
3101
    switch(cmd) {
3102
    case TARGET_F_GETLK:
3103
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3104
            return -TARGET_EFAULT;
3105
        fl.l_type = tswap16(target_fl->l_type);
3106
        fl.l_whence = tswap16(target_fl->l_whence);
3107
        fl.l_start = tswapl(target_fl->l_start);
3108
        fl.l_len = tswapl(target_fl->l_len);
3109
        fl.l_pid = tswapl(target_fl->l_pid);
3110
        unlock_user_struct(target_fl, arg, 0);
3111
        ret = get_errno(fcntl(fd, cmd, &fl));
3112
        if (ret == 0) {
3113
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3114
                return -TARGET_EFAULT;
3115
            target_fl->l_type = tswap16(fl.l_type);
3116
            target_fl->l_whence = tswap16(fl.l_whence);
3117
            target_fl->l_start = tswapl(fl.l_start);
3118
            target_fl->l_len = tswapl(fl.l_len);
3119
            target_fl->l_pid = tswapl(fl.l_pid);
3120
            unlock_user_struct(target_fl, arg, 1);
3121
        }
3122
        break;
3123

    
3124
    case TARGET_F_SETLK:
3125
    case TARGET_F_SETLKW:
3126
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3127
            return -TARGET_EFAULT;
3128
        fl.l_type = tswap16(target_fl->l_type);
3129
        fl.l_whence = tswap16(target_fl->l_whence);
3130
        fl.l_start = tswapl(target_fl->l_start);
3131
        fl.l_len = tswapl(target_fl->l_len);
3132
        fl.l_pid = tswapl(target_fl->l_pid);
3133
        unlock_user_struct(target_fl, arg, 0);
3134
        ret = get_errno(fcntl(fd, cmd, &fl));
3135
        break;
3136

    
3137
    case TARGET_F_GETLK64:
3138
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3139
            return -TARGET_EFAULT;
3140
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3141
        fl64.l_whence = tswap16(target_fl64->l_whence);
3142
        fl64.l_start = tswapl(target_fl64->l_start);
3143
        fl64.l_len = tswapl(target_fl64->l_len);
3144
        fl64.l_pid = tswap16(target_fl64->l_pid);
3145
        unlock_user_struct(target_fl64, arg, 0);
3146
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3147
        if (ret == 0) {
3148
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3149
                return -TARGET_EFAULT;
3150
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3151
            target_fl64->l_whence = tswap16(fl64.l_whence);
3152
            target_fl64->l_start = tswapl(fl64.l_start);
3153
            target_fl64->l_len = tswapl(fl64.l_len);
3154
            target_fl64->l_pid = tswapl(fl64.l_pid);
3155
            unlock_user_struct(target_fl64, arg, 1);
3156
        }
3157
        break;
3158
    case TARGET_F_SETLK64:
3159
    case TARGET_F_SETLKW64:
3160
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3161
            return -TARGET_EFAULT;
3162
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3163
        fl64.l_whence = tswap16(target_fl64->l_whence);
3164
        fl64.l_start = tswapl(target_fl64->l_start);
3165
        fl64.l_len = tswapl(target_fl64->l_len);
3166
        fl64.l_pid = tswap16(target_fl64->l_pid);
3167
        unlock_user_struct(target_fl64, arg, 0);
3168
        ret = get_errno(fcntl(fd, cmd >> 1, &fl64));
3169
        break;
3170

    
3171
    case F_GETFL:
3172
        ret = get_errno(fcntl(fd, cmd, arg));
3173
        if (ret >= 0) {
3174
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3175
        }
3176
        break;
3177

    
3178
    case F_SETFL:
3179
        ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3180
        break;
3181

    
3182
    default:
3183
        ret = get_errno(fcntl(fd, cmd, arg));
3184
        break;
3185
    }
3186
    return ret;
3187
}
3188

    
3189
#ifdef USE_UID16
3190

    
3191
static inline int high2lowuid(int uid)
3192
{
3193
    if (uid > 65535)
3194
        return 65534;
3195
    else
3196
        return uid;
3197
}
3198

    
3199
static inline int high2lowgid(int gid)
3200
{
3201
    if (gid > 65535)
3202
        return 65534;
3203
    else
3204
        return gid;
3205
}
3206

    
3207
static inline int low2highuid(int uid)
3208
{
3209
    if ((int16_t)uid == -1)
3210
        return -1;
3211
    else
3212
        return uid;
3213
}
3214

    
3215
static inline int low2highgid(int gid)
3216
{
3217
    if ((int16_t)gid == -1)
3218
        return -1;
3219
    else
3220
        return gid;
3221
}
3222

    
3223
#endif /* USE_UID16 */
3224

    
3225
void syscall_init(void)
3226
{
3227
    IOCTLEntry *ie;
3228
    const argtype *arg_type;
3229
    int size;
3230
    int i;
3231

    
3232
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3233
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3234
#include "syscall_types.h"
3235
#undef STRUCT
3236
#undef STRUCT_SPECIAL
3237

    
3238
    /* we patch the ioctl size if necessary. We rely on the fact that
3239
       no ioctl has all the bits at '1' in the size field */
3240
    ie = ioctl_entries;
3241
    while (ie->target_cmd != 0) {
3242
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3243
            TARGET_IOC_SIZEMASK) {
3244
            arg_type = ie->arg_type;
3245
            if (arg_type[0] != TYPE_PTR) {
3246
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3247
                        ie->target_cmd);
3248
                exit(1);
3249
            }
3250
            arg_type++;
3251
            size = thunk_type_size(arg_type, 0);
3252
            ie->target_cmd = (ie->target_cmd &
3253
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3254
                (size << TARGET_IOC_SIZESHIFT);
3255
        }
3256

    
3257
        /* Build target_to_host_errno_table[] table from
3258
         * host_to_target_errno_table[]. */
3259
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3260
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3261

    
3262
        /* automatic consistency check if same arch */
3263
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3264
    (defined(__x86_64__) && defined(TARGET_X86_64))
3265
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3266
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3267
                    ie->name, ie->target_cmd, ie->host_cmd);
3268
        }
3269
#endif
3270
        ie++;
3271
    }
3272
}
3273

    
3274
#if TARGET_ABI_BITS == 32
3275
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3276
{
3277
#ifdef TARGET_WORDS_BIGENDIAN
3278
    return ((uint64_t)word0 << 32) | word1;
3279
#else
3280
    return ((uint64_t)word1 << 32) | word0;
3281
#endif
3282
}
3283
#else /* TARGET_ABI_BITS == 32 */
3284
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3285
{
3286
    return word0;
3287
}
3288
#endif /* TARGET_ABI_BITS != 32 */
3289

    
3290
#ifdef TARGET_NR_truncate64
3291
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3292
                                         abi_long arg2,
3293
                                         abi_long arg3,
3294
                                         abi_long arg4)
3295
{
3296
#ifdef TARGET_ARM
3297
    if (((CPUARMState *)cpu_env)->eabi)
3298
      {
3299
        arg2 = arg3;
3300
        arg3 = arg4;
3301
      }
3302
#endif
3303
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3304
}
3305
#endif
3306

    
3307
#ifdef TARGET_NR_ftruncate64
3308
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3309
                                          abi_long arg2,
3310
                                          abi_long arg3,
3311
                                          abi_long arg4)
3312
{
3313
#ifdef TARGET_ARM
3314
    if (((CPUARMState *)cpu_env)->eabi)
3315
      {
3316
        arg2 = arg3;
3317
        arg3 = arg4;
3318
      }
3319
#endif
3320
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3321
}
3322
#endif
3323

    
3324
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3325
                                               abi_ulong target_addr)
3326
{
3327
    struct target_timespec *target_ts;
3328

    
3329
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3330
        return -TARGET_EFAULT;
3331
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3332
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3333
    unlock_user_struct(target_ts, target_addr, 0);
3334
    return 0;
3335
}
3336

    
3337
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3338
                                               struct timespec *host_ts)
3339
{
3340
    struct target_timespec *target_ts;
3341

    
3342
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3343
        return -TARGET_EFAULT;
3344
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3345
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3346
    unlock_user_struct(target_ts, target_addr, 1);
3347
    return 0;
3348
}
3349

    
3350
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3351
static inline abi_long host_to_target_stat64(void *cpu_env,
3352
                                             abi_ulong target_addr,
3353
                                             struct stat *host_st)
3354
{
3355
#ifdef TARGET_ARM
3356
    if (((CPUARMState *)cpu_env)->eabi) {
3357
        struct target_eabi_stat64 *target_st;
3358

    
3359
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3360
            return -TARGET_EFAULT;
3361
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3362
        __put_user(host_st->st_dev, &target_st->st_dev);
3363
        __put_user(host_st->st_ino, &target_st->st_ino);
3364
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3365
        __put_user(host_st->st_ino, &target_st->__st_ino);
3366
#endif
3367
        __put_user(host_st->st_mode, &target_st->st_mode);
3368
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3369
        __put_user(host_st->st_uid, &target_st->st_uid);
3370
        __put_user(host_st->st_gid, &target_st->st_gid);
3371
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3372
        __put_user(host_st->st_size, &target_st->st_size);
3373
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3374
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3375
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3376
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3377
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3378
        unlock_user_struct(target_st, target_addr, 1);
3379
    } else
3380
#endif
3381
    {
3382
#if TARGET_LONG_BITS == 64
3383
        struct target_stat *target_st;
3384
#else
3385
        struct target_stat64 *target_st;
3386
#endif
3387

    
3388
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3389
            return -TARGET_EFAULT;
3390
        memset(target_st, 0, sizeof(*target_st));
3391
        __put_user(host_st->st_dev, &target_st->st_dev);
3392
        __put_user(host_st->st_ino, &target_st->st_ino);
3393
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3394
        __put_user(host_st->st_ino, &target_st->__st_ino);
3395
#endif
3396
        __put_user(host_st->st_mode, &target_st->st_mode);
3397
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3398
        __put_user(host_st->st_uid, &target_st->st_uid);
3399
        __put_user(host_st->st_gid, &target_st->st_gid);
3400
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3401
        /* XXX: better use of kernel struct */
3402
        __put_user(host_st->st_size, &target_st->st_size);
3403
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3404
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3405
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3406
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3407
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3408
        unlock_user_struct(target_st, target_addr, 1);
3409
    }
3410

    
3411
    return 0;
3412
}
3413
#endif
3414

    
3415
#if defined(USE_NPTL)
3416
/* ??? Using host futex calls even when target atomic operations
3417
   are not really atomic probably breaks things.  However implementing
3418
   futexes locally would make futexes shared between multiple processes
3419
   tricky.  However they're probably useless because guest atomic
3420
   operations won't work either.  */
3421
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
3422
                    target_ulong uaddr2, int val3)
3423
{
3424
    struct timespec ts, *pts;
3425

    
3426
    /* ??? We assume FUTEX_* constants are the same on both host
3427
       and target.  */
3428
    switch (op) {
3429
    case FUTEX_WAIT:
3430
        if (timeout) {
3431
            pts = &ts;
3432
            target_to_host_timespec(pts, timeout);
3433
        } else {
3434
            pts = NULL;
3435
        }
3436
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAIT, tswap32(val),
3437
                         pts, NULL, 0));
3438
    case FUTEX_WAKE:
3439
        return get_errno(sys_futex(g2h(uaddr), FUTEX_WAKE, val, NULL, NULL, 0));
3440
    case FUTEX_FD:
3441
        return get_errno(sys_futex(g2h(uaddr), FUTEX_FD, val, NULL, NULL, 0));
3442
    case FUTEX_REQUEUE:
3443
        return get_errno(sys_futex(g2h(uaddr), FUTEX_REQUEUE, val,
3444
                         NULL, g2h(uaddr2), 0));
3445
    case FUTEX_CMP_REQUEUE:
3446
        return get_errno(sys_futex(g2h(uaddr), FUTEX_CMP_REQUEUE, val,
3447
                         NULL, g2h(uaddr2), tswap32(val3)));
3448
    default:
3449
        return -TARGET_ENOSYS;
3450
    }
3451
}
3452
#endif
3453

    
3454
int get_osversion(void)
3455
{
3456
    static int osversion;
3457
    struct new_utsname buf;
3458
    const char *s;
3459
    int i, n, tmp;
3460
    if (osversion)
3461
        return osversion;
3462
    if (qemu_uname_release && *qemu_uname_release) {
3463
        s = qemu_uname_release;
3464
    } else {
3465
        if (sys_uname(&buf))
3466
            return 0;
3467
        s = buf.release;
3468
    }
3469
    tmp = 0;
3470
    for (i = 0; i < 3; i++) {
3471
        n = 0;
3472
        while (*s >= '0' && *s <= '9') {
3473
            n *= 10;
3474
            n += *s - '0';
3475
            s++;
3476
        }
3477
        tmp = (tmp << 8) + n;
3478
        if (*s == '.')
3479
            s++;
3480
    }
3481
    osversion = tmp;
3482
    return osversion;
3483
}
3484

    
3485
/* do_syscall() should always have a single exit point at the end so
3486
   that actions, such as logging of syscall results, can be performed.
3487
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
3488
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
3489
                    abi_long arg2, abi_long arg3, abi_long arg4,
3490
                    abi_long arg5, abi_long arg6)
3491
{
3492
    abi_long ret;
3493
    struct stat st;
3494
    struct statfs stfs;
3495
    void *p;
3496

    
3497
#ifdef DEBUG
3498
    gemu_log("syscall %d", num);
3499
#endif
3500
    if(do_strace)
3501
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
3502

    
3503
    switch(num) {
3504
    case TARGET_NR_exit:
3505
#ifdef USE_NPTL
3506
      /* In old applications this may be used to implement _exit(2).
3507
         However in threaded applictions it is used for thread termination,
3508
         and _exit_group is used for application termination.
3509
         Do thread termination if we have more then one thread.  */
3510
      /* FIXME: This probably breaks if a signal arrives.  We should probably
3511
         be disabling signals.  */
3512
      if (first_cpu->next_cpu) {
3513
          CPUState **lastp;
3514
          CPUState *p;
3515

    
3516
          cpu_list_lock();
3517
          lastp = &first_cpu;
3518
          p = first_cpu;
3519
          while (p && p != (CPUState *)cpu_env) {
3520
              lastp = &p->next_cpu;
3521
              p = p->next_cpu;
3522
          }
3523
          /* If we didn't find the CPU for this thread then something is
3524
             horribly wrong.  */
3525
          if (!p)
3526
              abort();
3527
          /* Remove the CPU from the list.  */
3528
          *lastp = p->next_cpu;
3529
          cpu_list_unlock();
3530
          TaskState *ts = ((CPUState *)cpu_env)->opaque;
3531
          if (ts->child_tidptr) {
3532
              put_user_u32(0, ts->child_tidptr);
3533
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
3534
                        NULL, NULL, 0);
3535
          }
3536
          /* TODO: Free CPU state.  */
3537
          pthread_exit(NULL);
3538
      }
3539
#endif
3540
#ifdef HAVE_GPROF
3541
        _mcleanup();
3542
#endif
3543
        gdb_exit(cpu_env, arg1);
3544
        _exit(arg1);
3545
        ret = 0; /* avoid warning */
3546
        break;
3547
    case TARGET_NR_read:
3548
        if (arg3 == 0)
3549
            ret = 0;
3550
        else {
3551
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
3552
                goto efault;
3553
            ret = get_errno(read(arg1, p, arg3));
3554
            unlock_user(p, arg2, ret);
3555
        }
3556
        break;
3557
    case TARGET_NR_write:
3558
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
3559
            goto efault;
3560
        ret = get_errno(write(arg1, p, arg3));
3561
        unlock_user(p, arg2, 0);
3562
        break;
3563
    case TARGET_NR_open:
3564
        if (!(p = lock_user_string(arg1)))
3565
            goto efault;
3566
        ret = get_errno(open(path(p),
3567
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
3568
                             arg3));
3569
        unlock_user(p, arg1, 0);
3570
        break;
3571
#if defined(TARGET_NR_openat) && defined(__NR_openat)
3572
    case TARGET_NR_openat:
3573
        if (!(p = lock_user_string(arg2)))
3574
            goto efault;
3575
        ret = get_errno(sys_openat(arg1,
3576
                                   path(p),
3577
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
3578
                                   arg4));
3579
        unlock_user(p, arg2, 0);
3580
        break;
3581
#endif
3582
    case TARGET_NR_close:
3583
        ret = get_errno(close(arg1));
3584
        break;
3585
    case TARGET_NR_brk:
3586
        ret = do_brk(arg1);
3587
        break;
3588
    case TARGET_NR_fork:
3589
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
3590
        break;
3591
#ifdef TARGET_NR_waitpid
3592
    case TARGET_NR_waitpid:
3593
        {
3594
            int status;
3595
            ret = get_errno(waitpid(arg1, &status, arg3));
3596
            if (!is_error(ret) && arg2
3597
                && put_user_s32(status, arg2))
3598
                goto efault;
3599
        }
3600
        break;
3601
#endif
3602
#ifdef TARGET_NR_waitid
3603
    case TARGET_NR_waitid:
3604
        {
3605
            siginfo_t info;
3606
            info.si_pid = 0;
3607
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
3608
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
3609
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
3610
                    goto efault;
3611
                host_to_target_siginfo(p, &info);
3612
                unlock_user(p, arg3, sizeof(target_siginfo_t));
3613
            }
3614
        }
3615
        break;
3616
#endif
3617
#ifdef TARGET_NR_creat /* not on alpha */
3618
    case TARGET_NR_creat:
3619
        if (!(p = lock_user_string(arg1)))
3620
            goto efault;
3621
        ret = get_errno(creat(p, arg2));
3622
        unlock_user(p, arg1, 0);
3623
        break;
3624
#endif
3625
    case TARGET_NR_link:
3626
        {
3627
            void * p2;
3628
            p = lock_user_string(arg1);
3629
            p2 = lock_user_string(arg2);
3630
            if (!p || !p2)
3631
                ret = -TARGET_EFAULT;
3632
            else
3633
                ret = get_errno(link(p, p2));
3634
            unlock_user(p2, arg2, 0);
3635
            unlock_user(p, arg1, 0);
3636
        }
3637
        break;
3638
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
3639
    case TARGET_NR_linkat:
3640
        {
3641
            void * p2 = NULL;
3642
            if (!arg2 || !arg4)
3643
                goto efault;
3644
            p  = lock_user_string(arg2);
3645
            p2 = lock_user_string(arg4);
3646
            if (!p || !p2)
3647
                ret = -TARGET_EFAULT;
3648
            else
3649
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
3650
            unlock_user(p, arg2, 0);
3651
            unlock_user(p2, arg4, 0);
3652
        }
3653
        break;
3654
#endif
3655
    case TARGET_NR_unlink:
3656
        if (!(p = lock_user_string(arg1)))
3657
            goto efault;
3658
        ret = get_errno(unlink(p));
3659
        unlock_user(p, arg1, 0);
3660
        break;
3661
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
3662
    case TARGET_NR_unlinkat:
3663
        if (!(p = lock_user_string(arg2)))
3664
            goto efault;
3665
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
3666
        unlock_user(p, arg2, 0);
3667
        break;
3668
#endif
3669
    case TARGET_NR_execve:
3670
        {
3671
            char **argp, **envp;
3672
            int argc, envc;
3673
            abi_ulong gp;
3674
            abi_ulong guest_argp;
3675
            abi_ulong guest_envp;
3676
            abi_ulong addr;
3677
            char **q;
3678

    
3679
            argc = 0;
3680
            guest_argp = arg2;
3681
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
3682
                if (get_user_ual(addr, gp))
3683
                    goto efault;
3684
                if (!addr)
3685
                    break;
3686
                argc++;
3687
            }
3688
            envc = 0;
3689
            guest_envp = arg3;
3690
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
3691
                if (get_user_ual(addr, gp))
3692
                    goto efault;
3693
                if (!addr)
3694
                    break;
3695
                envc++;
3696
            }
3697

    
3698
            argp = alloca((argc + 1) * sizeof(void *));
3699
            envp = alloca((envc + 1) * sizeof(void *));
3700

    
3701
            for (gp = guest_argp, q = argp; gp;
3702
                  gp += sizeof(abi_ulong), q++) {
3703
                if (get_user_ual(addr, gp))
3704
                    goto execve_efault;
3705
                if (!addr)
3706
                    break;
3707
                if (!(*q = lock_user_string(addr)))
3708
                    goto execve_efault;
3709
            }
3710
            *q = NULL;
3711

    
3712
            for (gp = guest_envp, q = envp; gp;
3713
                  gp += sizeof(abi_ulong), q++) {
3714
                if (get_user_ual(addr, gp))
3715
                    goto execve_efault;
3716
                if (!addr)
3717
                    break;
3718
                if (!(*q = lock_user_string(addr)))
3719
                    goto execve_efault;
3720
            }
3721
            *q = NULL;
3722

    
3723
            if (!(p = lock_user_string(arg1)))
3724
                goto execve_efault;
3725
            ret = get_errno(execve(p, argp, envp));
3726
            unlock_user(p, arg1, 0);
3727

    
3728
            goto execve_end;
3729

    
3730
        execve_efault:
3731
            ret = -TARGET_EFAULT;
3732

    
3733
        execve_end:
3734
            for (gp = guest_argp, q = argp; *q;
3735
                  gp += sizeof(abi_ulong), q++) {
3736
                if (get_user_ual(addr, gp)
3737
                    || !addr)
3738
                    break;
3739
                unlock_user(*q, addr, 0);
3740
            }
3741
            for (gp = guest_envp, q = envp; *q;
3742
                  gp += sizeof(abi_ulong), q++) {
3743
                if (get_user_ual(addr, gp)
3744
                    || !addr)
3745
                    break;
3746
                unlock_user(*q, addr, 0);
3747
            }
3748
        }
3749
        break;
3750
    case TARGET_NR_chdir:
3751
        if (!(p = lock_user_string(arg1)))
3752
            goto efault;
3753
        ret = get_errno(chdir(p));
3754
        unlock_user(p, arg1, 0);
3755
        break;
3756
#ifdef TARGET_NR_time
3757
    case TARGET_NR_time:
3758
        {
3759
            time_t host_time;
3760
            ret = get_errno(time(&host_time));
3761
            if (!is_error(ret)
3762
                && arg1
3763
                && put_user_sal(host_time, arg1))
3764
                goto efault;
3765
        }
3766
        break;
3767
#endif
3768
    case TARGET_NR_mknod:
3769
        if (!(p = lock_user_string(arg1)))
3770
            goto efault;
3771
        ret = get_errno(mknod(p, arg2, arg3));
3772
        unlock_user(p, arg1, 0);
3773
        break;
3774
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
3775
    case TARGET_NR_mknodat:
3776
        if (!(p = lock_user_string(arg2)))
3777
            goto efault;
3778
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
3779
        unlock_user(p, arg2, 0);
3780
        break;
3781
#endif
3782
    case TARGET_NR_chmod:
3783
        if (!(p = lock_user_string(arg1)))
3784
            goto efault;
3785
        ret = get_errno(chmod(p, arg2));
3786
        unlock_user(p, arg1, 0);
3787
        break;
3788
#ifdef TARGET_NR_break
3789
    case TARGET_NR_break:
3790
        goto unimplemented;
3791
#endif
3792
#ifdef TARGET_NR_oldstat
3793
    case TARGET_NR_oldstat:
3794
        goto unimplemented;
3795
#endif
3796
    case TARGET_NR_lseek:
3797
        ret = get_errno(lseek(arg1, arg2, arg3));
3798
        break;
3799
#ifdef TARGET_NR_getxpid
3800
    case TARGET_NR_getxpid:
3801
#else
3802
    case TARGET_NR_getpid:
3803
#endif
3804
        ret = get_errno(getpid());
3805
        break;
3806
    case TARGET_NR_mount:
3807
                {
3808
                        /* need to look at the data field */
3809
                        void *p2, *p3;
3810
                        p = lock_user_string(arg1);
3811
                        p2 = lock_user_string(arg2);
3812
                        p3 = lock_user_string(arg3);
3813
                        if (!p || !p2 || !p3)
3814
                            ret = -TARGET_EFAULT;
3815
                        else
3816
                            /* FIXME - arg5 should be locked, but it isn't clear how to
3817
                             * do that since it's not guaranteed to be a NULL-terminated
3818
                             * string.
3819
                             */
3820
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
3821
                        unlock_user(p, arg1, 0);
3822
                        unlock_user(p2, arg2, 0);
3823
                        unlock_user(p3, arg3, 0);
3824
                        break;
3825
                }
3826
#ifdef TARGET_NR_umount
3827
    case TARGET_NR_umount:
3828
        if (!(p = lock_user_string(arg1)))
3829
            goto efault;
3830
        ret = get_errno(umount(p));
3831
        unlock_user(p, arg1, 0);
3832
        break;
3833
#endif
3834
#ifdef TARGET_NR_stime /* not on alpha */
3835
    case TARGET_NR_stime:
3836
        {
3837
            time_t host_time;
3838
            if (get_user_sal(host_time, arg1))
3839
                goto efault;
3840
            ret = get_errno(stime(&host_time));
3841
        }
3842
        break;
3843
#endif
3844
    case TARGET_NR_ptrace:
3845
        goto unimplemented;
3846
#ifdef TARGET_NR_alarm /* not on alpha */
3847
    case TARGET_NR_alarm:
3848
        ret = alarm(arg1);
3849
        break;
3850
#endif
3851
#ifdef TARGET_NR_oldfstat
3852
    case TARGET_NR_oldfstat:
3853
        goto unimplemented;
3854
#endif
3855
#ifdef TARGET_NR_pause /* not on alpha */
3856
    case TARGET_NR_pause:
3857
        ret = get_errno(pause());
3858
        break;
3859
#endif
3860
#ifdef TARGET_NR_utime
3861
    case TARGET_NR_utime:
3862
        {
3863
            struct utimbuf tbuf, *host_tbuf;
3864
            struct target_utimbuf *target_tbuf;
3865
            if (arg2) {
3866
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
3867
                    goto efault;
3868
                tbuf.actime = tswapl(target_tbuf->actime);
3869
                tbuf.modtime = tswapl(target_tbuf->modtime);
3870
                unlock_user_struct(target_tbuf, arg2, 0);
3871
                host_tbuf = &tbuf;
3872
            } else {
3873
                host_tbuf = NULL;
3874
            }
3875
            if (!(p = lock_user_string(arg1)))
3876
                goto efault;
3877
            ret = get_errno(utime(p, host_tbuf));
3878
            unlock_user(p, arg1, 0);
3879
        }
3880
        break;
3881
#endif
3882
    case TARGET_NR_utimes:
3883
        {
3884
            struct timeval *tvp, tv[2];
3885
            if (arg2) {
3886
                if (copy_from_user_timeval(&tv[0], arg2)
3887
                    || copy_from_user_timeval(&tv[1],
3888
                                              arg2 + sizeof(struct target_timeval)))
3889
                    goto efault;
3890
                tvp = tv;
3891
            } else {
3892
                tvp = NULL;
3893
            }
3894
            if (!(p = lock_user_string(arg1)))
3895
                goto efault;
3896
            ret = get_errno(utimes(p, tvp));
3897
            unlock_user(p, arg1, 0);
3898
        }
3899
        break;
3900
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
3901
    case TARGET_NR_futimesat:
3902
        {
3903
            struct timeval *tvp, tv[2];
3904
            if (arg3) {
3905
                if (copy_from_user_timeval(&tv[0], arg3)
3906
                    || copy_from_user_timeval(&tv[1],
3907
                                              arg3 + sizeof(struct target_timeval)))
3908
                    goto efault;
3909
                tvp = tv;
3910
            } else {
3911
                tvp = NULL;
3912
            }
3913
            if (!(p = lock_user_string(arg2)))
3914
                goto efault;
3915
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
3916
            unlock_user(p, arg2, 0);
3917
        }
3918
        break;
3919
#endif
3920
#ifdef TARGET_NR_stty
3921
    case TARGET_NR_stty:
3922
        goto unimplemented;
3923
#endif
3924
#ifdef TARGET_NR_gtty
3925
    case TARGET_NR_gtty:
3926
        goto unimplemented;
3927
#endif
3928
    case TARGET_NR_access:
3929
        if (!(p = lock_user_string(arg1)))
3930
            goto efault;
3931
        ret = get_errno(access(p, arg2));
3932
        unlock_user(p, arg1, 0);
3933
        break;
3934
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
3935
    case TARGET_NR_faccessat:
3936
        if (!(p = lock_user_string(arg2)))
3937
            goto efault;
3938
        ret = get_errno(sys_faccessat(arg1, p, arg3, arg4));
3939
        unlock_user(p, arg2, 0);
3940
        break;
3941
#endif
3942
#ifdef TARGET_NR_nice /* not on alpha */
3943
    case TARGET_NR_nice:
3944
        ret = get_errno(nice(arg1));
3945
        break;
3946
#endif
3947
#ifdef TARGET_NR_ftime
3948
    case TARGET_NR_ftime:
3949
        goto unimplemented;
3950
#endif
3951
    case TARGET_NR_sync:
3952
        sync();
3953
        ret = 0;
3954
        break;
3955
    case TARGET_NR_kill:
3956
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
3957
        break;
3958
    case TARGET_NR_rename:
3959
        {
3960
            void *p2;
3961
            p = lock_user_string(arg1);
3962
            p2 = lock_user_string(arg2);
3963
            if (!p || !p2)
3964
                ret = -TARGET_EFAULT;
3965
            else
3966
                ret = get_errno(rename(p, p2));
3967
            unlock_user(p2, arg2, 0);
3968
            unlock_user(p, arg1, 0);
3969
        }
3970
        break;
3971
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
3972
    case TARGET_NR_renameat:
3973
        {
3974
            void *p2;
3975
            p  = lock_user_string(arg2);
3976
            p2 = lock_user_string(arg4);
3977
            if (!p || !p2)
3978
                ret = -TARGET_EFAULT;
3979
            else
3980
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
3981
            unlock_user(p2, arg4, 0);
3982
            unlock_user(p, arg2, 0);
3983
        }
3984
        break;
3985
#endif
3986
    case TARGET_NR_mkdir:
3987
        if (!(p = lock_user_string(arg1)))
3988
            goto efault;
3989
        ret = get_errno(mkdir(p, arg2));
3990
        unlock_user(p, arg1, 0);
3991
        break;
3992
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
3993
    case TARGET_NR_mkdirat:
3994
        if (!(p = lock_user_string(arg2)))
3995
            goto efault;
3996
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
3997
        unlock_user(p, arg2, 0);
3998
        break;
3999
#endif
4000
    case TARGET_NR_rmdir:
4001
        if (!(p = lock_user_string(arg1)))
4002
            goto efault;
4003
        ret = get_errno(rmdir(p));
4004
        unlock_user(p, arg1, 0);
4005
        break;
4006
    case TARGET_NR_dup:
4007
        ret = get_errno(dup(arg1));
4008
        break;
4009
    case TARGET_NR_pipe:
4010
        {
4011
            int host_pipe[2];
4012
            ret = get_errno(pipe(host_pipe));
4013
            if (!is_error(ret)) {
4014
#if defined(TARGET_MIPS)
4015
                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
4016
                env->active_tc.gpr[3] = host_pipe[1];
4017
                ret = host_pipe[0];
4018
#elif defined(TARGET_SH4)
4019
                ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
4020
                ret = host_pipe[0];
4021
#else
4022
                if (put_user_s32(host_pipe[0], arg1)
4023
                    || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
4024
                    goto efault;
4025
#endif
4026
            }
4027
        }
4028
        break;
4029
    case TARGET_NR_times:
4030
        {
4031
            struct target_tms *tmsp;
4032
            struct tms tms;
4033
            ret = get_errno(times(&tms));
4034
            if (arg1) {
4035
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4036
                if (!tmsp)
4037
                    goto efault;
4038
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4039
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4040
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4041
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4042
            }
4043
            if (!is_error(ret))
4044
                ret = host_to_target_clock_t(ret);
4045
        }
4046
        break;
4047
#ifdef TARGET_NR_prof
4048
    case TARGET_NR_prof:
4049
        goto unimplemented;
4050
#endif
4051
#ifdef TARGET_NR_signal
4052
    case TARGET_NR_signal:
4053
        goto unimplemented;
4054
#endif
4055
    case TARGET_NR_acct:
4056
        if (arg1 == 0) {
4057
            ret = get_errno(acct(NULL));
4058
        } else {
4059
            if (!(p = lock_user_string(arg1)))
4060
                goto efault;
4061
            ret = get_errno(acct(path(p)));
4062
            unlock_user(p, arg1, 0);
4063
        }
4064
        break;
4065
#ifdef TARGET_NR_umount2 /* not on alpha */
4066
    case TARGET_NR_umount2:
4067
        if (!(p = lock_user_string(arg1)))
4068
            goto efault;
4069
        ret = get_errno(umount2(p, arg2));
4070
        unlock_user(p, arg1, 0);
4071
        break;
4072
#endif
4073
#ifdef TARGET_NR_lock
4074
    case TARGET_NR_lock:
4075
        goto unimplemented;
4076
#endif
4077
    case TARGET_NR_ioctl:
4078
        ret = do_ioctl(arg1, arg2, arg3);
4079
        break;
4080
    case TARGET_NR_fcntl:
4081
        ret = do_fcntl(arg1, arg2, arg3);
4082
        break;
4083
#ifdef TARGET_NR_mpx
4084
    case TARGET_NR_mpx:
4085
        goto unimplemented;
4086
#endif
4087
    case TARGET_NR_setpgid:
4088
        ret = get_errno(setpgid(arg1, arg2));
4089
        break;
4090
#ifdef TARGET_NR_ulimit
4091
    case TARGET_NR_ulimit:
4092
        goto unimplemented;
4093
#endif
4094
#ifdef TARGET_NR_oldolduname
4095
    case TARGET_NR_oldolduname:
4096
        goto unimplemented;
4097
#endif
4098
    case TARGET_NR_umask:
4099
        ret = get_errno(umask(arg1));
4100
        break;
4101
    case TARGET_NR_chroot:
4102
        if (!(p = lock_user_string(arg1)))
4103
            goto efault;
4104
        ret = get_errno(chroot(p));
4105
        unlock_user(p, arg1, 0);
4106
        break;
4107
    case TARGET_NR_ustat:
4108
        goto unimplemented;
4109
    case TARGET_NR_dup2:
4110
        ret = get_errno(dup2(arg1, arg2));
4111
        break;
4112
#ifdef TARGET_NR_getppid /* not on alpha */
4113
    case TARGET_NR_getppid:
4114
        ret = get_errno(getppid());
4115
        break;
4116
#endif
4117
    case TARGET_NR_getpgrp:
4118
        ret = get_errno(getpgrp());
4119
        break;
4120
    case TARGET_NR_setsid:
4121
        ret = get_errno(setsid());
4122
        break;
4123
#ifdef TARGET_NR_sigaction
4124
    case TARGET_NR_sigaction:
4125
        {
4126
#if !defined(TARGET_MIPS)
4127
            struct target_old_sigaction *old_act;
4128
            struct target_sigaction act, oact, *pact;
4129
            if (arg2) {
4130
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4131
                    goto efault;
4132
                act._sa_handler = old_act->_sa_handler;
4133
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4134
                act.sa_flags = old_act->sa_flags;
4135
                act.sa_restorer = old_act->sa_restorer;
4136
                unlock_user_struct(old_act, arg2, 0);
4137
                pact = &act;
4138
            } else {
4139
                pact = NULL;
4140
            }
4141
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4142
            if (!is_error(ret) && arg3) {
4143
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4144
                    goto efault;
4145
                old_act->_sa_handler = oact._sa_handler;
4146
                old_act->sa_mask = oact.sa_mask.sig[0];
4147
                old_act->sa_flags = oact.sa_flags;
4148
                old_act->sa_restorer = oact.sa_restorer;
4149
                unlock_user_struct(old_act, arg3, 1);
4150
            }
4151
#else
4152
            struct target_sigaction act, oact, *pact, *old_act;
4153

    
4154
            if (arg2) {
4155
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4156
                    goto efault;
4157
                act._sa_handler = old_act->_sa_handler;
4158
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4159
                act.sa_flags = old_act->sa_flags;
4160
                unlock_user_struct(old_act, arg2, 0);
4161
                pact = &act;
4162
            } else {
4163
                pact = NULL;
4164
            }
4165

    
4166
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4167

    
4168
            if (!is_error(ret) && arg3) {
4169
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4170
                    goto efault;
4171
                old_act->_sa_handler = oact._sa_handler;
4172
                old_act->sa_flags = oact.sa_flags;
4173
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4174
                old_act->sa_mask.sig[1] = 0;
4175
                old_act->sa_mask.sig[2] = 0;
4176
                old_act->sa_mask.sig[3] = 0;
4177
                unlock_user_struct(old_act, arg3, 1);
4178
            }
4179
#endif
4180
        }
4181
        break;
4182
#endif
4183
    case TARGET_NR_rt_sigaction:
4184
        {
4185
            struct target_sigaction *act;
4186
            struct target_sigaction *oact;
4187

    
4188
            if (arg2) {
4189
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4190
                    goto efault;
4191
            } else
4192
                act = NULL;
4193
            if (arg3) {
4194
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4195
                    ret = -TARGET_EFAULT;
4196
                    goto rt_sigaction_fail;
4197
                }
4198
            } else
4199
                oact = NULL;
4200
            ret = get_errno(do_sigaction(arg1, act, oact));
4201
        rt_sigaction_fail:
4202
            if (act)
4203
                unlock_user_struct(act, arg2, 0);
4204
            if (oact)
4205
                unlock_user_struct(oact, arg3, 1);
4206
        }
4207
        break;
4208
#ifdef TARGET_NR_sgetmask /* not on alpha */
4209
    case TARGET_NR_sgetmask:
4210
        {
4211
            sigset_t cur_set;
4212
            abi_ulong target_set;
4213
            sigprocmask(0, NULL, &cur_set);
4214
            host_to_target_old_sigset(&target_set, &cur_set);
4215
            ret = target_set;
4216
        }
4217
        break;
4218
#endif
4219
#ifdef TARGET_NR_ssetmask /* not on alpha */
4220
    case TARGET_NR_ssetmask:
4221
        {
4222
            sigset_t set, oset, cur_set;
4223
            abi_ulong target_set = arg1;
4224
            sigprocmask(0, NULL, &cur_set);
4225
            target_to_host_old_sigset(&set, &target_set);
4226
            sigorset(&set, &set, &cur_set);
4227
            sigprocmask(SIG_SETMASK, &set, &oset);
4228
            host_to_target_old_sigset(&target_set, &oset);
4229
            ret = target_set;
4230
        }
4231
        break;
4232
#endif
4233
#ifdef TARGET_NR_sigprocmask
4234
    case TARGET_NR_sigprocmask:
4235
        {
4236
            int how = arg1;
4237
            sigset_t set, oldset, *set_ptr;
4238

    
4239
            if (arg2) {
4240
                switch(how) {
4241
                case TARGET_SIG_BLOCK:
4242
                    how = SIG_BLOCK;
4243
                    break;
4244
                case TARGET_SIG_UNBLOCK:
4245
                    how = SIG_UNBLOCK;
4246
                    break;
4247
                case TARGET_SIG_SETMASK:
4248
                    how = SIG_SETMASK;
4249
                    break;
4250
                default:
4251
                    ret = -TARGET_EINVAL;
4252
                    goto fail;
4253
                }
4254
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4255
                    goto efault;
4256
                target_to_host_old_sigset(&set, p);
4257
                unlock_user(p, arg2, 0);
4258
                set_ptr = &set;
4259
            } else {
4260
                how = 0;
4261
                set_ptr = NULL;
4262
            }
4263
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4264
            if (!is_error(ret) && arg3) {
4265
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4266
                    goto efault;
4267
                host_to_target_old_sigset(p, &oldset);
4268
                unlock_user(p, arg3, sizeof(target_sigset_t));
4269
            }
4270
        }
4271
        break;
4272
#endif
4273
    case TARGET_NR_rt_sigprocmask:
4274
        {
4275
            int how = arg1;
4276
            sigset_t set, oldset, *set_ptr;
4277

    
4278
            if (arg2) {
4279
                switch(how) {
4280
                case TARGET_SIG_BLOCK:
4281
                    how = SIG_BLOCK;
4282
                    break;
4283
                case TARGET_SIG_UNBLOCK:
4284
                    how = SIG_UNBLOCK;
4285
                    break;
4286
                case TARGET_SIG_SETMASK:
4287
                    how = SIG_SETMASK;
4288
                    break;
4289
                default:
4290
                    ret = -TARGET_EINVAL;
4291
                    goto fail;
4292
                }
4293
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4294
                    goto efault;
4295
                target_to_host_sigset(&set, p);
4296
                unlock_user(p, arg2, 0);
4297
                set_ptr = &set;
4298
            } else {
4299
                how = 0;
4300
                set_ptr = NULL;
4301
            }
4302
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4303
            if (!is_error(ret) && arg3) {
4304
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4305
                    goto efault;
4306
                host_to_target_sigset(p, &oldset);
4307
                unlock_user(p, arg3, sizeof(target_sigset_t));
4308
            }
4309
        }
4310
        break;
4311
#ifdef TARGET_NR_sigpending
4312
    case TARGET_NR_sigpending:
4313
        {
4314
            sigset_t set;
4315
            ret = get_errno(sigpending(&set));
4316
            if (!is_error(ret)) {
4317
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4318
                    goto efault;
4319
                host_to_target_old_sigset(p, &set);
4320
                unlock_user(p, arg1, sizeof(target_sigset_t));
4321
            }
4322
        }
4323
        break;
4324
#endif
4325
    case TARGET_NR_rt_sigpending:
4326
        {
4327
            sigset_t set;
4328
            ret = get_errno(sigpending(&set));
4329
            if (!is_error(ret)) {
4330
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4331
                    goto efault;
4332
                host_to_target_sigset(p, &set);
4333
                unlock_user(p, arg1, sizeof(target_sigset_t));
4334
            }
4335
        }
4336
        break;
4337
#ifdef TARGET_NR_sigsuspend
4338
    case TARGET_NR_sigsuspend:
4339
        {
4340
            sigset_t set;
4341
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4342
                goto efault;
4343
            target_to_host_old_sigset(&set, p);
4344
            unlock_user(p, arg1, 0);
4345
            ret = get_errno(sigsuspend(&set));
4346
        }
4347
        break;
4348
#endif
4349
    case TARGET_NR_rt_sigsuspend:
4350
        {
4351
            sigset_t set;
4352
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4353
                goto efault;
4354
            target_to_host_sigset(&set, p);
4355
            unlock_user(p, arg1, 0);
4356
            ret = get_errno(sigsuspend(&set));
4357
        }
4358
        break;
4359
    case TARGET_NR_rt_sigtimedwait:
4360
        {
4361
            sigset_t set;
4362
            struct timespec uts, *puts;
4363
            siginfo_t uinfo;
4364

    
4365
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4366
                goto efault;
4367
            target_to_host_sigset(&set, p);
4368
            unlock_user(p, arg1, 0);
4369
            if (arg3) {
4370
                puts = &uts;
4371
                target_to_host_timespec(puts, arg3);
4372
            } else {
4373
                puts = NULL;
4374
            }
4375
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4376
            if (!is_error(ret) && arg2) {
4377
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4378
                    goto efault;
4379
                host_to_target_siginfo(p, &uinfo);
4380
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4381
            }
4382
        }
4383
        break;
4384
    case TARGET_NR_rt_sigqueueinfo:
4385
        {
4386
            siginfo_t uinfo;
4387
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
4388
                goto efault;
4389
            target_to_host_siginfo(&uinfo, p);
4390
            unlock_user(p, arg1, 0);
4391
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
4392
        }
4393
        break;
4394
#ifdef TARGET_NR_sigreturn
4395
    case TARGET_NR_sigreturn:
4396
        /* NOTE: ret is eax, so not transcoding must be done */
4397
        ret = do_sigreturn(cpu_env);
4398
        break;
4399
#endif
4400
    case TARGET_NR_rt_sigreturn:
4401
        /* NOTE: ret is eax, so not transcoding must be done */
4402
        ret = do_rt_sigreturn(cpu_env);
4403
        break;
4404
    case TARGET_NR_sethostname:
4405
        if (!(p = lock_user_string(arg1)))
4406
            goto efault;
4407
        ret = get_errno(sethostname(p, arg2));
4408
        unlock_user(p, arg1, 0);
4409
        break;
4410
    case TARGET_NR_setrlimit:
4411
        {
4412
            /* XXX: convert resource ? */
4413
            int resource = arg1;
4414
            struct target_rlimit *target_rlim;
4415
            struct rlimit rlim;
4416
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
4417
                goto efault;
4418
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4419
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
4420
            unlock_user_struct(target_rlim, arg2, 0);
4421
            ret = get_errno(setrlimit(resource, &rlim));
4422
        }
4423
        break;
4424
    case TARGET_NR_getrlimit:
4425
        {
4426
            /* XXX: convert resource ? */
4427
            int resource = arg1;
4428
            struct target_rlimit *target_rlim;
4429
            struct rlimit rlim;
4430

    
4431
            ret = get_errno(getrlimit(resource, &rlim));
4432
            if (!is_error(ret)) {
4433
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
4434
                    goto efault;
4435
                rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
4436
                rlim.rlim_max = tswapl(target_rlim->rlim_max);
4437
                unlock_user_struct(target_rlim, arg2, 1);
4438
            }
4439
        }
4440
        break;
4441
    case TARGET_NR_getrusage:
4442
        {
4443
            struct rusage rusage;
4444
            ret = get_errno(getrusage(arg1, &rusage));
4445
            if (!is_error(ret)) {
4446
                host_to_target_rusage(arg2, &rusage);
4447
            }
4448
        }
4449
        break;
4450
    case TARGET_NR_gettimeofday:
4451
        {
4452
            struct timeval tv;
4453
            ret = get_errno(gettimeofday(&tv, NULL));
4454
            if (!is_error(ret)) {
4455
                if (copy_to_user_timeval(arg1, &tv))
4456
                    goto efault;
4457
            }
4458
        }
4459
        break;
4460
    case TARGET_NR_settimeofday:
4461
        {
4462
            struct timeval tv;
4463
            if (copy_from_user_timeval(&tv, arg1))
4464
                goto efault;
4465
            ret = get_errno(settimeofday(&tv, NULL));
4466
        }
4467
        break;
4468
#ifdef TARGET_NR_select
4469
    case TARGET_NR_select:
4470
        {
4471
            struct target_sel_arg_struct *sel;
4472
            abi_ulong inp, outp, exp, tvp;
4473
            long nsel;
4474

    
4475
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
4476
                goto efault;
4477
            nsel = tswapl(sel->n);
4478
            inp = tswapl(sel->inp);
4479
            outp = tswapl(sel->outp);
4480
            exp = tswapl(sel->exp);
4481
            tvp = tswapl(sel->tvp);
4482
            unlock_user_struct(sel, arg1, 0);
4483
            ret = do_select(nsel, inp, outp, exp, tvp);
4484
        }
4485
        break;
4486
#endif
4487
    case TARGET_NR_symlink:
4488
        {
4489
            void *p2;
4490
            p = lock_user_string(arg1);
4491
            p2 = lock_user_string(arg2);
4492
            if (!p || !p2)
4493
                ret = -TARGET_EFAULT;
4494
            else
4495
                ret = get_errno(symlink(p, p2));
4496
            unlock_user(p2, arg2, 0);
4497
            unlock_user(p, arg1, 0);
4498
        }
4499
        break;
4500
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
4501
    case TARGET_NR_symlinkat:
4502
        {
4503
            void *p2;
4504
            p  = lock_user_string(arg1);
4505
            p2 = lock_user_string(arg3);
4506
            if (!p || !p2)
4507
                ret = -TARGET_EFAULT;
4508
            else
4509
                ret = get_errno(sys_symlinkat(p, arg2, p2));
4510
            unlock_user(p2, arg3, 0);
4511
            unlock_user(p, arg1, 0);
4512
        }
4513
        break;
4514
#endif
4515
#ifdef TARGET_NR_oldlstat
4516
    case TARGET_NR_oldlstat:
4517
        goto unimplemented;
4518
#endif
4519
    case TARGET_NR_readlink:
4520
        {
4521
            void *p2, *temp;
4522
            p = lock_user_string(arg1);
4523
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
4524
            if (!p || !p2)
4525
                ret = -TARGET_EFAULT;
4526
            else {
4527
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
4528
                    char real[PATH_MAX];
4529
                    temp = realpath(exec_path,real);
4530
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
4531
                    snprintf((char *)p2, arg3, "%s", real);
4532
                    }
4533
                else
4534
                    ret = get_errno(readlink(path(p), p2, arg3));
4535
            }
4536
            unlock_user(p2, arg2, ret);
4537
            unlock_user(p, arg1, 0);
4538
        }
4539
        break;
4540
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
4541
    case TARGET_NR_readlinkat:
4542
        {
4543
            void *p2;
4544
            p  = lock_user_string(arg2);
4545
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
4546
            if (!p || !p2)
4547
                ret = -TARGET_EFAULT;
4548
            else
4549
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
4550
            unlock_user(p2, arg3, ret);
4551
            unlock_user(p, arg2, 0);
4552
        }
4553
        break;
4554
#endif
4555
#ifdef TARGET_NR_uselib
4556
    case TARGET_NR_uselib:
4557
        goto unimplemented;
4558
#endif
4559
#ifdef TARGET_NR_swapon
4560
    case TARGET_NR_swapon:
4561
        if (!(p = lock_user_string(arg1)))
4562
            goto efault;
4563
        ret = get_errno(swapon(p, arg2));
4564
        unlock_user(p, arg1, 0);
4565
        break;
4566
#endif
4567
    case TARGET_NR_reboot:
4568
        goto unimplemented;
4569
#ifdef TARGET_NR_readdir
4570
    case TARGET_NR_readdir:
4571
        goto unimplemented;
4572
#endif
4573
#ifdef TARGET_NR_mmap
4574
    case TARGET_NR_mmap:
4575
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS)
4576
        {
4577
            abi_ulong *v;
4578
            abi_ulong v1, v2, v3, v4, v5, v6;
4579
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
4580
                goto efault;
4581
            v1 = tswapl(v[0]);
4582
            v2 = tswapl(v[1]);
4583
            v3 = tswapl(v[2]);
4584
            v4 = tswapl(v[3]);
4585
            v5 = tswapl(v[4]);
4586
            v6 = tswapl(v[5]);
4587
            unlock_user(v, arg1, 0);
4588
            ret = get_errno(target_mmap(v1, v2, v3,
4589
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
4590
                                        v5, v6));
4591
        }
4592
#else
4593
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4594
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4595
                                    arg5,
4596
                                    arg6));
4597
#endif
4598
        break;
4599
#endif
4600
#ifdef TARGET_NR_mmap2
4601
    case TARGET_NR_mmap2:
4602
#ifndef MMAP_SHIFT
4603
#define MMAP_SHIFT 12
4604
#endif
4605
        ret = get_errno(target_mmap(arg1, arg2, arg3,
4606
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
4607
                                    arg5,
4608
                                    arg6 << MMAP_SHIFT));
4609
        break;
4610
#endif
4611
    case TARGET_NR_munmap:
4612
        ret = get_errno(target_munmap(arg1, arg2));
4613
        break;
4614
    case TARGET_NR_mprotect:
4615
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
4616
        break;
4617
#ifdef TARGET_NR_mremap
4618
    case TARGET_NR_mremap:
4619
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
4620
        break;
4621
#endif
4622
        /* ??? msync/mlock/munlock are broken for softmmu.  */
4623
#ifdef TARGET_NR_msync
4624
    case TARGET_NR_msync:
4625
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
4626
        break;
4627
#endif
4628
#ifdef TARGET_NR_mlock
4629
    case TARGET_NR_mlock:
4630
        ret = get_errno(mlock(g2h(arg1), arg2));
4631
        break;
4632
#endif
4633
#ifdef TARGET_NR_munlock
4634
    case TARGET_NR_munlock:
4635
        ret = get_errno(munlock(g2h(arg1), arg2));
4636
        break;
4637
#endif
4638
#ifdef TARGET_NR_mlockall
4639
    case TARGET_NR_mlockall:
4640
        ret = get_errno(mlockall(arg1));
4641
        break;
4642
#endif
4643
#ifdef TARGET_NR_munlockall
4644
    case TARGET_NR_munlockall:
4645
        ret = get_errno(munlockall());
4646
        break;
4647
#endif
4648
    case TARGET_NR_truncate:
4649
        if (!(p = lock_user_string(arg1)))
4650
            goto efault;
4651
        ret = get_errno(truncate(p, arg2));
4652
        unlock_user(p, arg1, 0);
4653
        break;
4654
    case TARGET_NR_ftruncate:
4655
        ret = get_errno(ftruncate(arg1, arg2));
4656
        break;
4657
    case TARGET_NR_fchmod:
4658
        ret = get_errno(fchmod(arg1, arg2));
4659
        break;
4660
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
4661
    case TARGET_NR_fchmodat:
4662
        if (!(p = lock_user_string(arg2)))
4663
            goto efault;
4664
        ret = get_errno(sys_fchmodat(arg1, p, arg3, arg4));
4665
        unlock_user(p, arg2, 0);
4666
        break;
4667
#endif
4668
    case TARGET_NR_getpriority:
4669
        /* libc does special remapping of the return value of
4670
         * sys_getpriority() so it's just easiest to call
4671
         * sys_getpriority() directly rather than through libc. */
4672
        ret = sys_getpriority(arg1, arg2);
4673
        break;
4674
    case TARGET_NR_setpriority:
4675
        ret = get_errno(setpriority(arg1, arg2, arg3));
4676
        break;
4677
#ifdef TARGET_NR_profil
4678
    case TARGET_NR_profil:
4679
        goto unimplemented;
4680
#endif
4681
    case TARGET_NR_statfs:
4682
        if (!(p = lock_user_string(arg1)))
4683
            goto efault;
4684
        ret = get_errno(statfs(path(p), &stfs));
4685
        unlock_user(p, arg1, 0);
4686
    convert_statfs:
4687
        if (!is_error(ret)) {
4688
            struct target_statfs *target_stfs;
4689

    
4690
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
4691
                goto efault;
4692
            __put_user(stfs.f_type, &target_stfs->f_type);
4693
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4694
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4695
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4696
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4697
            __put_user(stfs.f_files, &target_stfs->f_files);
4698
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4699
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4700
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4701
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4702
            unlock_user_struct(target_stfs, arg2, 1);
4703
        }
4704
        break;
4705
    case TARGET_NR_fstatfs:
4706
        ret = get_errno(fstatfs(arg1, &stfs));
4707
        goto convert_statfs;
4708
#ifdef TARGET_NR_statfs64
4709
    case TARGET_NR_statfs64:
4710
        if (!(p = lock_user_string(arg1)))
4711
            goto efault;
4712
        ret = get_errno(statfs(path(p), &stfs));
4713
        unlock_user(p, arg1, 0);
4714
    convert_statfs64:
4715
        if (!is_error(ret)) {
4716
            struct target_statfs64 *target_stfs;
4717

    
4718
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
4719
                goto efault;
4720
            __put_user(stfs.f_type, &target_stfs->f_type);
4721
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
4722
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
4723
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
4724
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
4725
            __put_user(stfs.f_files, &target_stfs->f_files);
4726
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
4727
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
4728
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
4729
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
4730
            unlock_user_struct(target_stfs, arg3, 1);
4731
        }
4732
        break;
4733
    case TARGET_NR_fstatfs64:
4734
        ret = get_errno(fstatfs(arg1, &stfs));
4735
        goto convert_statfs64;
4736
#endif
4737
#ifdef TARGET_NR_ioperm
4738
    case TARGET_NR_ioperm:
4739
        goto unimplemented;
4740
#endif
4741
#ifdef TARGET_NR_socketcall
4742
    case TARGET_NR_socketcall:
4743
        ret = do_socketcall(arg1, arg2);
4744
        break;
4745
#endif
4746
#ifdef TARGET_NR_accept
4747
    case TARGET_NR_accept:
4748
        ret = do_accept(arg1, arg2, arg3);
4749
        break;
4750
#endif
4751
#ifdef TARGET_NR_bind
4752
    case TARGET_NR_bind:
4753
        ret = do_bind(arg1, arg2, arg3);
4754
        break;
4755
#endif
4756
#ifdef TARGET_NR_connect
4757
    case TARGET_NR_connect:
4758
        ret = do_connect(arg1, arg2, arg3);
4759
        break;
4760
#endif
4761
#ifdef TARGET_NR_getpeername
4762
    case TARGET_NR_getpeername:
4763
        ret = do_getpeername(arg1, arg2, arg3);
4764
        break;
4765
#endif
4766
#ifdef TARGET_NR_getsockname
4767
    case TARGET_NR_getsockname:
4768
        ret = do_getsockname(arg1, arg2, arg3);
4769
        break;
4770
#endif
4771
#ifdef TARGET_NR_getsockopt
4772
    case TARGET_NR_getsockopt:
4773
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
4774
        break;
4775
#endif
4776
#ifdef TARGET_NR_listen
4777
    case TARGET_NR_listen:
4778
        ret = get_errno(listen(arg1, arg2));
4779
        break;
4780
#endif
4781
#ifdef TARGET_NR_recv
4782
    case TARGET_NR_recv:
4783
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
4784
        break;
4785
#endif
4786
#ifdef TARGET_NR_recvfrom
4787
    case TARGET_NR_recvfrom:
4788
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
4789
        break;
4790
#endif
4791
#ifdef TARGET_NR_recvmsg
4792
    case TARGET_NR_recvmsg:
4793
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
4794
        break;
4795
#endif
4796
#ifdef TARGET_NR_send
4797
    case TARGET_NR_send:
4798
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
4799
        break;
4800
#endif
4801
#ifdef TARGET_NR_sendmsg
4802
    case TARGET_NR_sendmsg:
4803
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
4804
        break;
4805
#endif
4806
#ifdef TARGET_NR_sendto
4807
    case TARGET_NR_sendto:
4808
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
4809
        break;
4810
#endif
4811
#ifdef TARGET_NR_shutdown
4812
    case TARGET_NR_shutdown:
4813
        ret = get_errno(shutdown(arg1, arg2));
4814
        break;
4815
#endif
4816
#ifdef TARGET_NR_socket
4817
    case TARGET_NR_socket:
4818
        ret = do_socket(arg1, arg2, arg3);
4819
        break;
4820
#endif
4821
#ifdef TARGET_NR_socketpair
4822
    case TARGET_NR_socketpair:
4823
        ret = do_socketpair(arg1, arg2, arg3, arg4);
4824
        break;
4825
#endif
4826
#ifdef TARGET_NR_setsockopt
4827
    case TARGET_NR_setsockopt:
4828
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
4829
        break;
4830
#endif
4831

    
4832
    case TARGET_NR_syslog:
4833
        if (!(p = lock_user_string(arg2)))
4834
            goto efault;
4835
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
4836
        unlock_user(p, arg2, 0);
4837
        break;
4838

    
4839
    case TARGET_NR_setitimer:
4840
        {
4841
            struct itimerval value, ovalue, *pvalue;
4842

    
4843
            if (arg2) {
4844
                pvalue = &value;
4845
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
4846
                    || copy_from_user_timeval(&pvalue->it_value,
4847
                                              arg2 + sizeof(struct target_timeval)))
4848
                    goto efault;
4849
            } else {
4850
                pvalue = NULL;
4851
            }
4852
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
4853
            if (!is_error(ret) && arg3) {
4854
                if (copy_to_user_timeval(arg3,
4855
                                         &ovalue.it_interval)
4856
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
4857
                                            &ovalue.it_value))
4858
                    goto efault;
4859
            }
4860
        }
4861
        break;
4862
    case TARGET_NR_getitimer:
4863
        {
4864
            struct itimerval value;
4865

    
4866
            ret = get_errno(getitimer(arg1, &value));
4867
            if (!is_error(ret) && arg2) {
4868
                if (copy_to_user_timeval(arg2,
4869
                                         &value.it_interval)
4870
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
4871
                                            &value.it_value))
4872
                    goto efault;
4873
            }
4874
        }
4875
        break;
4876
    case TARGET_NR_stat:
4877
        if (!(p = lock_user_string(arg1)))
4878
            goto efault;
4879
        ret = get_errno(stat(path(p), &st));
4880
        unlock_user(p, arg1, 0);
4881
        goto do_stat;
4882
    case TARGET_NR_lstat:
4883
        if (!(p = lock_user_string(arg1)))
4884
            goto efault;
4885
        ret = get_errno(lstat(path(p), &st));
4886
        unlock_user(p, arg1, 0);
4887
        goto do_stat;
4888
    case TARGET_NR_fstat:
4889
        {
4890
            ret = get_errno(fstat(arg1, &st));
4891
        do_stat:
4892
            if (!is_error(ret)) {
4893
                struct target_stat *target_st;
4894

    
4895
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
4896
                    goto efault;
4897
                __put_user(st.st_dev, &target_st->st_dev);
4898
                __put_user(st.st_ino, &target_st->st_ino);
4899
                __put_user(st.st_mode, &target_st->st_mode);
4900
                __put_user(st.st_uid, &target_st->st_uid);
4901
                __put_user(st.st_gid, &target_st->st_gid);
4902
                __put_user(st.st_nlink, &target_st->st_nlink);
4903
                __put_user(st.st_rdev, &target_st->st_rdev);
4904
                __put_user(st.st_size, &target_st->st_size);
4905
                __put_user(st.st_blksize, &target_st->st_blksize);
4906
                __put_user(st.st_blocks, &target_st->st_blocks);
4907
                __put_user(st.st_atime, &target_st->target_st_atime);
4908
                __put_user(st.st_mtime, &target_st->target_st_mtime);
4909
                __put_user(st.st_ctime, &target_st->target_st_ctime);
4910
                unlock_user_struct(target_st, arg2, 1);
4911
            }
4912
        }
4913
        break;
4914
#ifdef TARGET_NR_olduname
4915
    case TARGET_NR_olduname:
4916
        goto unimplemented;
4917
#endif
4918
#ifdef TARGET_NR_iopl
4919
    case TARGET_NR_iopl:
4920
        goto unimplemented;
4921
#endif
4922
    case TARGET_NR_vhangup:
4923
        ret = get_errno(vhangup());
4924
        break;
4925
#ifdef TARGET_NR_idle
4926
    case TARGET_NR_idle:
4927
        goto unimplemented;
4928
#endif
4929
#ifdef TARGET_NR_syscall
4930
    case TARGET_NR_syscall:
4931
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
4932
            break;
4933
#endif
4934
    case TARGET_NR_wait4:
4935
        {
4936
            int status;
4937
            abi_long status_ptr = arg2;
4938
            struct rusage rusage, *rusage_ptr;
4939
            abi_ulong target_rusage = arg4;
4940
            if (target_rusage)
4941
                rusage_ptr = &rusage;
4942
            else
4943
                rusage_ptr = NULL;
4944
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
4945
            if (!is_error(ret)) {
4946
                if (status_ptr) {
4947
                    if (put_user_s32(status, status_ptr))
4948
                        goto efault;
4949
                }
4950
                if (target_rusage)
4951
                    host_to_target_rusage(target_rusage, &rusage);
4952
            }
4953
        }
4954
        break;
4955
#ifdef TARGET_NR_swapoff
4956
    case TARGET_NR_swapoff:
4957
        if (!(p = lock_user_string(arg1)))
4958
            goto efault;
4959
        ret = get_errno(swapoff(p));
4960
        unlock_user(p, arg1, 0);
4961
        break;
4962
#endif
4963
    case TARGET_NR_sysinfo:
4964
        {
4965
            struct target_sysinfo *target_value;
4966
            struct sysinfo value;
4967
            ret = get_errno(sysinfo(&value));
4968
            if (!is_error(ret) && arg1)
4969
            {
4970
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
4971
                    goto efault;
4972
                __put_user(value.uptime, &target_value->uptime);
4973
                __put_user(value.loads[0], &target_value->loads[0]);
4974
                __put_user(value.loads[1], &target_value->loads[1]);
4975
                __put_user(value.loads[2], &target_value->loads[2]);
4976
                __put_user(value.totalram, &target_value->totalram);
4977
                __put_user(value.freeram, &target_value->freeram);
4978
                __put_user(value.sharedram, &target_value->sharedram);
4979
                __put_user(value.bufferram, &target_value->bufferram);
4980
                __put_user(value.totalswap, &target_value->totalswap);
4981
                __put_user(value.freeswap, &target_value->freeswap);
4982
                __put_user(value.procs, &target_value->procs);
4983
                __put_user(value.totalhigh, &target_value->totalhigh);
4984
                __put_user(value.freehigh, &target_value->freehigh);
4985
                __put_user(value.mem_unit, &target_value->mem_unit);
4986
                unlock_user_struct(target_value, arg1, 1);
4987
            }
4988
        }
4989
        break;
4990
#ifdef TARGET_NR_ipc
4991
    case TARGET_NR_ipc:
4992
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
4993
        break;
4994
#endif
4995

    
4996
#ifdef TARGET_NR_msgctl
4997
    case TARGET_NR_msgctl:
4998
        ret = do_msgctl(arg1, arg2, arg3);
4999
        break;
5000
#endif
5001
#ifdef TARGET_NR_msgget
5002
    case TARGET_NR_msgget:
5003
        ret = get_errno(msgget(arg1, arg2));
5004
        break;
5005
#endif
5006
#ifdef TARGET_NR_msgrcv
5007
    case TARGET_NR_msgrcv:
5008
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5009
        break;
5010
#endif
5011
#ifdef TARGET_NR_msgsnd
5012
    case TARGET_NR_msgsnd:
5013
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
5014
        break;
5015
#endif
5016
    case TARGET_NR_fsync:
5017
        ret = get_errno(fsync(arg1));
5018
        break;
5019
    case TARGET_NR_clone:
5020
#if defined(TARGET_SH4)
5021
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5022
#elif defined(TARGET_CRIS)
5023
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5024
#else
5025
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5026
#endif
5027
        break;
5028
#ifdef __NR_exit_group
5029
        /* new thread calls */
5030
    case TARGET_NR_exit_group:
5031
#ifdef HAVE_GPROF
5032
        _mcleanup();
5033
#endif
5034
        gdb_exit(cpu_env, arg1);
5035
        ret = get_errno(exit_group(arg1));
5036
        break;
5037
#endif
5038
    case TARGET_NR_setdomainname:
5039
        if (!(p = lock_user_string(arg1)))
5040
            goto efault;
5041
        ret = get_errno(setdomainname(p, arg2));
5042
        unlock_user(p, arg1, 0);
5043
        break;
5044
    case TARGET_NR_uname:
5045
        /* no need to transcode because we use the linux syscall */
5046
        {
5047
            struct new_utsname * buf;
5048

    
5049
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5050
                goto efault;
5051
            ret = get_errno(sys_uname(buf));
5052
            if (!is_error(ret)) {
5053
                /* Overrite the native machine name with whatever is being
5054
                   emulated. */
5055
                strcpy (buf->machine, UNAME_MACHINE);
5056
                /* Allow the user to override the reported release.  */
5057
                if (qemu_uname_release && *qemu_uname_release)
5058
                  strcpy (buf->release, qemu_uname_release);
5059
            }
5060
            unlock_user_struct(buf, arg1, 1);
5061
        }
5062
        break;
5063
#ifdef TARGET_I386
5064
    case TARGET_NR_modify_ldt:
5065
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5066
        break;
5067
#if !defined(TARGET_X86_64)
5068
    case TARGET_NR_vm86old:
5069
        goto unimplemented;
5070
    case TARGET_NR_vm86:
5071
        ret = do_vm86(cpu_env, arg1, arg2);
5072
        break;
5073
#endif
5074
#endif
5075
    case TARGET_NR_adjtimex:
5076
        goto unimplemented;
5077
#ifdef TARGET_NR_create_module
5078
    case TARGET_NR_create_module:
5079
#endif
5080
    case TARGET_NR_init_module:
5081
    case TARGET_NR_delete_module:
5082
#ifdef TARGET_NR_get_kernel_syms
5083
    case TARGET_NR_get_kernel_syms:
5084
#endif
5085
        goto unimplemented;
5086
    case TARGET_NR_quotactl:
5087
        goto unimplemented;
5088
    case TARGET_NR_getpgid:
5089
        ret = get_errno(getpgid(arg1));
5090
        break;
5091
    case TARGET_NR_fchdir:
5092
        ret = get_errno(fchdir(arg1));
5093
        break;
5094
#ifdef TARGET_NR_bdflush /* not on x86_64 */
5095
    case TARGET_NR_bdflush:
5096
        goto unimplemented;
5097
#endif
5098
#ifdef TARGET_NR_sysfs
5099
    case TARGET_NR_sysfs:
5100
        goto unimplemented;
5101
#endif
5102
    case TARGET_NR_personality:
5103
        ret = get_errno(personality(arg1));
5104
        break;
5105
#ifdef TARGET_NR_afs_syscall
5106
    case TARGET_NR_afs_syscall:
5107
        goto unimplemented;
5108
#endif
5109
#ifdef TARGET_NR__llseek /* Not on alpha */
5110
    case TARGET_NR__llseek:
5111
        {
5112
#if defined (__x86_64__)
5113
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5114
            if (put_user_s64(ret, arg4))
5115
                goto efault;
5116
#else
5117
            int64_t res;
5118
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5119
            if (put_user_s64(res, arg4))
5120
                goto efault;
5121
#endif
5122
        }
5123
        break;
5124
#endif
5125
    case TARGET_NR_getdents:
5126
#if TARGET_ABI_BITS != 32
5127
        goto unimplemented;
5128
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5129
        {
5130
            struct target_dirent *target_dirp;
5131
            struct linux_dirent *dirp;
5132
            abi_long count = arg3;
5133

    
5134
            dirp = malloc(count);
5135
            if (!dirp) {
5136
                ret = -TARGET_ENOMEM;
5137
                goto fail;
5138
            }
5139

    
5140
            ret = get_errno(sys_getdents(arg1, dirp, count));
5141
            if (!is_error(ret)) {
5142
                struct linux_dirent *de;
5143
                struct target_dirent *tde;
5144
                int len = ret;
5145
                int reclen, treclen;
5146
                int count1, tnamelen;
5147

    
5148
                count1 = 0;
5149
                de = dirp;
5150
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5151
                    goto efault;
5152
                tde = target_dirp;
5153
                while (len > 0) {
5154
                    reclen = de->d_reclen;
5155
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5156
                    tde->d_reclen = tswap16(treclen);
5157
                    tde->d_ino = tswapl(de->d_ino);
5158
                    tde->d_off = tswapl(de->d_off);
5159
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5160
                    if (tnamelen > 256)
5161
                        tnamelen = 256;
5162
                    /* XXX: may not be correct */
5163
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5164
                    de = (struct linux_dirent *)((char *)de + reclen);
5165
                    len -= reclen;
5166
                    tde = (struct target_dirent *)((char *)tde + treclen);
5167
                    count1 += treclen;
5168
                }
5169
                ret = count1;
5170
                unlock_user(target_dirp, arg2, ret);
5171
            }
5172
            free(dirp);
5173
        }
5174
#else
5175
        {
5176
            struct linux_dirent *dirp;
5177
            abi_long count = arg3;
5178

    
5179
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5180
                goto efault;
5181
            ret = get_errno(sys_getdents(arg1, dirp, count));
5182
            if (!is_error(ret)) {
5183
                struct linux_dirent *de;
5184
                int len = ret;
5185
                int reclen;
5186
                de = dirp;
5187
                while (len > 0) {
5188
                    reclen = de->d_reclen;
5189
                    if (reclen > len)
5190
                        break;
5191
                    de->d_reclen = tswap16(reclen);
5192
                    tswapls(&de->d_ino);
5193
                    tswapls(&de->d_off);
5194
                    de = (struct linux_dirent *)((char *)de + reclen);
5195
                    len -= reclen;
5196
                }
5197
            }
5198
            unlock_user(dirp, arg2, ret);
5199
        }
5200
#endif
5201
        break;
5202
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5203
    case TARGET_NR_getdents64:
5204
        {
5205
            struct linux_dirent64 *dirp;
5206
            abi_long count = arg3;
5207
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5208
                goto efault;
5209
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5210
            if (!is_error(ret)) {
5211
                struct linux_dirent64 *de;
5212
                int len = ret;
5213
                int reclen;
5214
                de = dirp;
5215
                while (len > 0) {
5216
                    reclen = de->d_reclen;
5217
                    if (reclen > len)
5218
                        break;
5219
                    de->d_reclen = tswap16(reclen);
5220
                    tswap64s((uint64_t *)&de->d_ino);
5221
                    tswap64s((uint64_t *)&de->d_off);
5222
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5223
                    len -= reclen;
5224
                }
5225
            }
5226
            unlock_user(dirp, arg2, ret);
5227
        }
5228
        break;
5229
#endif /* TARGET_NR_getdents64 */
5230
#ifdef TARGET_NR__newselect
5231
    case TARGET_NR__newselect:
5232
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5233
        break;
5234
#endif
5235
#ifdef TARGET_NR_poll
5236
    case TARGET_NR_poll:
5237
        {
5238
            struct target_pollfd *target_pfd;
5239
            unsigned int nfds = arg2;
5240
            int timeout = arg3;
5241
            struct pollfd *pfd;
5242
            unsigned int i;
5243

    
5244
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5245
            if (!target_pfd)
5246
                goto efault;
5247
            pfd = alloca(sizeof(struct pollfd) * nfds);
5248
            for(i = 0; i < nfds; i++) {
5249
                pfd[i].fd = tswap32(target_pfd[i].fd);
5250
                pfd[i].events = tswap16(target_pfd[i].events);
5251
            }
5252
            ret = get_errno(poll(pfd, nfds, timeout));
5253
            if (!is_error(ret)) {
5254
                for(i = 0; i < nfds; i++) {
5255
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5256
                }
5257
                ret += nfds * (sizeof(struct target_pollfd)
5258
                               - sizeof(struct pollfd));
5259
            }
5260
            unlock_user(target_pfd, arg1, ret);
5261
        }
5262
        break;
5263
#endif
5264
    case TARGET_NR_flock:
5265
        /* NOTE: the flock constant seems to be the same for every
5266
           Linux platform */
5267
        ret = get_errno(flock(arg1, arg2));
5268
        break;
5269
    case TARGET_NR_readv:
5270
        {
5271
            int count = arg3;
5272
            struct iovec *vec;
5273

    
5274
            vec = alloca(count * sizeof(struct iovec));
5275
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5276
                goto efault;
5277
            ret = get_errno(readv(arg1, vec, count));
5278
            unlock_iovec(vec, arg2, count, 1);
5279
        }
5280
        break;
5281
    case TARGET_NR_writev:
5282
        {
5283
            int count = arg3;
5284
            struct iovec *vec;
5285

    
5286
            vec = alloca(count * sizeof(struct iovec));
5287
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5288
                goto efault;
5289
            ret = get_errno(writev(arg1, vec, count));
5290
            unlock_iovec(vec, arg2, count, 0);
5291
        }
5292
        break;
5293
    case TARGET_NR_getsid:
5294
        ret = get_errno(getsid(arg1));
5295
        break;
5296
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5297
    case TARGET_NR_fdatasync:
5298
        ret = get_errno(fdatasync(arg1));
5299
        break;
5300
#endif
5301
    case TARGET_NR__sysctl:
5302
        /* We don't implement this, but ENOTDIR is always a safe
5303
           return value. */
5304
        ret = -TARGET_ENOTDIR;
5305
        break;
5306
    case TARGET_NR_sched_setparam:
5307
        {
5308
            struct sched_param *target_schp;
5309
            struct sched_param schp;
5310

    
5311
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5312
                goto efault;
5313
            schp.sched_priority = tswap32(target_schp->sched_priority);
5314
            unlock_user_struct(target_schp, arg2, 0);
5315
            ret = get_errno(sched_setparam(arg1, &schp));
5316
        }
5317
        break;
5318
    case TARGET_NR_sched_getparam:
5319
        {
5320
            struct sched_param *target_schp;
5321
            struct sched_param schp;
5322
            ret = get_errno(sched_getparam(arg1, &schp));
5323
            if (!is_error(ret)) {
5324
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5325
                    goto efault;
5326
                target_schp->sched_priority = tswap32(schp.sched_priority);
5327
                unlock_user_struct(target_schp, arg2, 1);
5328
            }
5329
        }
5330
        break;
5331
    case TARGET_NR_sched_setscheduler:
5332
        {
5333
            struct sched_param *target_schp;
5334
            struct sched_param schp;
5335
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5336
                goto efault;
5337
            schp.sched_priority = tswap32(target_schp->sched_priority);
5338
            unlock_user_struct(target_schp, arg3, 0);
5339
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5340
        }
5341
        break;
5342
    case TARGET_NR_sched_getscheduler:
5343
        ret = get_errno(sched_getscheduler(arg1));
5344
        break;
5345
    case TARGET_NR_sched_yield:
5346
        ret = get_errno(sched_yield());
5347
        break;
5348
    case TARGET_NR_sched_get_priority_max:
5349
        ret = get_errno(sched_get_priority_max(arg1));
5350
        break;
5351
    case TARGET_NR_sched_get_priority_min:
5352
        ret = get_errno(sched_get_priority_min(arg1));
5353
        break;
5354
    case TARGET_NR_sched_rr_get_interval:
5355
        {
5356
            struct timespec ts;
5357
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
5358
            if (!is_error(ret)) {
5359
                host_to_target_timespec(arg2, &ts);
5360
            }
5361
        }
5362
        break;
5363
    case TARGET_NR_nanosleep:
5364
        {
5365
            struct timespec req, rem;
5366
            target_to_host_timespec(&req, arg1);
5367
            ret = get_errno(nanosleep(&req, &rem));
5368
            if (is_error(ret) && arg2) {
5369
                host_to_target_timespec(arg2, &rem);
5370
            }
5371
        }
5372
        break;
5373
#ifdef TARGET_NR_query_module
5374
    case TARGET_NR_query_module:
5375
        goto unimplemented;
5376
#endif
5377
#ifdef TARGET_NR_nfsservctl
5378
    case TARGET_NR_nfsservctl:
5379
        goto unimplemented;
5380
#endif
5381
    case TARGET_NR_prctl:
5382
        switch (arg1)
5383
            {
5384
            case PR_GET_PDEATHSIG:
5385
                {
5386
                    int deathsig;
5387
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
5388
                    if (!is_error(ret) && arg2
5389
                        && put_user_ual(deathsig, arg2))
5390
                        goto efault;
5391
                }
5392
                break;
5393
            default:
5394
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
5395
                break;
5396
            }
5397
        break;
5398
#ifdef TARGET_NR_arch_prctl
5399
    case TARGET_NR_arch_prctl:
5400
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
5401
        ret = do_arch_prctl(cpu_env, arg1, arg2);
5402
        break;
5403
#else
5404
        goto unimplemented;
5405
#endif
5406
#endif
5407
#ifdef TARGET_NR_pread
5408
    case TARGET_NR_pread:
5409
#ifdef TARGET_ARM
5410
        if (((CPUARMState *)cpu_env)->eabi)
5411
            arg4 = arg5;
5412
#endif
5413
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5414
            goto efault;
5415
        ret = get_errno(pread(arg1, p, arg3, arg4));
5416
        unlock_user(p, arg2, ret);
5417
        break;
5418
    case TARGET_NR_pwrite:
5419
#ifdef TARGET_ARM
5420
        if (((CPUARMState *)cpu_env)->eabi)
5421
            arg4 = arg5;
5422
#endif
5423
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5424
            goto efault;
5425
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
5426
        unlock_user(p, arg2, 0);
5427
        break;
5428
#endif
5429
#ifdef TARGET_NR_pread64
5430
    case TARGET_NR_pread64:
5431
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5432
            goto efault;
5433
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
5434
        unlock_user(p, arg2, ret);
5435
        break;
5436
    case TARGET_NR_pwrite64:
5437
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5438
            goto efault;
5439
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
5440
        unlock_user(p, arg2, 0);
5441
        break;
5442
#endif
5443
    case TARGET_NR_getcwd:
5444
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
5445
            goto efault;
5446
        ret = get_errno(sys_getcwd1(p, arg2));
5447
        unlock_user(p, arg1, ret);
5448
        break;
5449
    case TARGET_NR_capget:
5450
        goto unimplemented;
5451
    case TARGET_NR_capset:
5452
        goto unimplemented;
5453
    case TARGET_NR_sigaltstack:
5454
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
5455
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
5456
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
5457
        break;
5458
#else
5459
        goto unimplemented;
5460
#endif
5461
    case TARGET_NR_sendfile:
5462
        goto unimplemented;
5463
#ifdef TARGET_NR_getpmsg
5464
    case TARGET_NR_getpmsg:
5465
        goto unimplemented;
5466
#endif
5467
#ifdef TARGET_NR_putpmsg
5468
    case TARGET_NR_putpmsg:
5469
        goto unimplemented;
5470
#endif
5471
#ifdef TARGET_NR_vfork
5472
    case TARGET_NR_vfork:
5473
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
5474
                        0, 0, 0, 0));
5475
        break;
5476
#endif
5477
#ifdef TARGET_NR_ugetrlimit
5478
    case TARGET_NR_ugetrlimit:
5479
    {
5480
        struct rlimit rlim;
5481
        ret = get_errno(getrlimit(arg1, &rlim));
5482
        if (!is_error(ret)) {
5483
            struct target_rlimit *target_rlim;
5484
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5485
                goto efault;
5486
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5487
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
5488
            unlock_user_struct(target_rlim, arg2, 1);
5489
        }
5490
        break;
5491
    }
5492
#endif
5493
#ifdef TARGET_NR_truncate64
5494
    case TARGET_NR_truncate64:
5495
        if (!(p = lock_user_string(arg1)))
5496
            goto efault;
5497
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
5498
        unlock_user(p, arg1, 0);
5499
        break;
5500
#endif
5501
#ifdef TARGET_NR_ftruncate64
5502
    case TARGET_NR_ftruncate64:
5503
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
5504
        break;
5505
#endif
5506
#ifdef TARGET_NR_stat64
5507
    case TARGET_NR_stat64:
5508
        if (!(p = lock_user_string(arg1)))
5509
            goto efault;
5510
        ret = get_errno(stat(path(p), &st));
5511
        unlock_user(p, arg1, 0);
5512
        if (!is_error(ret))
5513
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5514
        break;
5515
#endif
5516
#ifdef TARGET_NR_lstat64
5517
    case TARGET_NR_lstat64:
5518
        if (!(p = lock_user_string(arg1)))
5519
            goto efault;
5520
        ret = get_errno(lstat(path(p), &st));
5521
        unlock_user(p, arg1, 0);
5522
        if (!is_error(ret))
5523
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5524
        break;
5525
#endif
5526
#ifdef TARGET_NR_fstat64
5527
    case TARGET_NR_fstat64:
5528
        ret = get_errno(fstat(arg1, &st));
5529
        if (!is_error(ret))
5530
            ret = host_to_target_stat64(cpu_env, arg2, &st);
5531
        break;
5532
#endif
5533
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
5534
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
5535
#ifdef TARGET_NR_fstatat64
5536
    case TARGET_NR_fstatat64:
5537
#endif
5538
#ifdef TARGET_NR_newfstatat
5539
    case TARGET_NR_newfstatat:
5540
#endif
5541
        if (!(p = lock_user_string(arg2)))
5542
            goto efault;
5543
#ifdef __NR_fstatat64
5544
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
5545
#else
5546
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
5547
#endif
5548
        if (!is_error(ret))
5549
            ret = host_to_target_stat64(cpu_env, arg3, &st);
5550
        break;
5551
#endif
5552
#ifdef USE_UID16
5553
    case TARGET_NR_lchown:
5554
        if (!(p = lock_user_string(arg1)))
5555
            goto efault;
5556
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
5557
        unlock_user(p, arg1, 0);
5558
        break;
5559
    case TARGET_NR_getuid:
5560
        ret = get_errno(high2lowuid(getuid()));
5561
        break;
5562
    case TARGET_NR_getgid:
5563
        ret = get_errno(high2lowgid(getgid()));
5564
        break;
5565
    case TARGET_NR_geteuid:
5566
        ret = get_errno(high2lowuid(geteuid()));
5567
        break;
5568
    case TARGET_NR_getegid:
5569
        ret = get_errno(high2lowgid(getegid()));
5570
        break;
5571
    case TARGET_NR_setreuid:
5572
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
5573
        break;
5574
    case TARGET_NR_setregid:
5575
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
5576
        break;
5577
    case TARGET_NR_getgroups:
5578
        {
5579
            int gidsetsize = arg1;
5580
            uint16_t *target_grouplist;
5581
            gid_t *grouplist;
5582
            int i;
5583

    
5584
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5585
            ret = get_errno(getgroups(gidsetsize, grouplist));
5586
            if (gidsetsize == 0)
5587
                break;
5588
            if (!is_error(ret)) {
5589
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
5590
                if (!target_grouplist)
5591
                    goto efault;
5592
                for(i = 0;i < ret; i++)
5593
                    target_grouplist[i] = tswap16(grouplist[i]);
5594
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
5595
            }
5596
        }
5597
        break;
5598
    case TARGET_NR_setgroups:
5599
        {
5600
            int gidsetsize = arg1;
5601
            uint16_t *target_grouplist;
5602
            gid_t *grouplist;
5603
            int i;
5604

    
5605
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5606
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
5607
            if (!target_grouplist) {
5608
                ret = -TARGET_EFAULT;
5609
                goto fail;
5610
            }
5611
            for(i = 0;i < gidsetsize; i++)
5612
                grouplist[i] = tswap16(target_grouplist[i]);
5613
            unlock_user(target_grouplist, arg2, 0);
5614
            ret = get_errno(setgroups(gidsetsize, grouplist));
5615
        }
5616
        break;
5617
    case TARGET_NR_fchown:
5618
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
5619
        break;
5620
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
5621
    case TARGET_NR_fchownat:
5622
        if (!(p = lock_user_string(arg2))) 
5623
            goto efault;
5624
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
5625
        unlock_user(p, arg2, 0);
5626
        break;
5627
#endif
5628
#ifdef TARGET_NR_setresuid
5629
    case TARGET_NR_setresuid:
5630
        ret = get_errno(setresuid(low2highuid(arg1),
5631
                                  low2highuid(arg2),
5632
                                  low2highuid(arg3)));
5633
        break;
5634
#endif
5635
#ifdef TARGET_NR_getresuid
5636
    case TARGET_NR_getresuid:
5637
        {
5638
            uid_t ruid, euid, suid;
5639
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5640
            if (!is_error(ret)) {
5641
                if (put_user_u16(high2lowuid(ruid), arg1)
5642
                    || put_user_u16(high2lowuid(euid), arg2)
5643
                    || put_user_u16(high2lowuid(suid), arg3))
5644
                    goto efault;
5645
            }
5646
        }
5647
        break;
5648
#endif
5649
#ifdef TARGET_NR_getresgid
5650
    case TARGET_NR_setresgid:
5651
        ret = get_errno(setresgid(low2highgid(arg1),
5652
                                  low2highgid(arg2),
5653
                                  low2highgid(arg3)));
5654
        break;
5655
#endif
5656
#ifdef TARGET_NR_getresgid
5657
    case TARGET_NR_getresgid:
5658
        {
5659
            gid_t rgid, egid, sgid;
5660
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5661
            if (!is_error(ret)) {
5662
                if (put_user_u16(high2lowgid(rgid), arg1)
5663
                    || put_user_u16(high2lowgid(egid), arg2)
5664
                    || put_user_u16(high2lowgid(sgid), arg3))
5665
                    goto efault;
5666
            }
5667
        }
5668
        break;
5669
#endif
5670
    case TARGET_NR_chown:
5671
        if (!(p = lock_user_string(arg1)))
5672
            goto efault;
5673
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
5674
        unlock_user(p, arg1, 0);
5675
        break;
5676
    case TARGET_NR_setuid:
5677
        ret = get_errno(setuid(low2highuid(arg1)));
5678
        break;
5679
    case TARGET_NR_setgid:
5680
        ret = get_errno(setgid(low2highgid(arg1)));
5681
        break;
5682
    case TARGET_NR_setfsuid:
5683
        ret = get_errno(setfsuid(arg1));
5684
        break;
5685
    case TARGET_NR_setfsgid:
5686
        ret = get_errno(setfsgid(arg1));
5687
        break;
5688
#endif /* USE_UID16 */
5689

    
5690
#ifdef TARGET_NR_lchown32
5691
    case TARGET_NR_lchown32:
5692
        if (!(p = lock_user_string(arg1)))
5693
            goto efault;
5694
        ret = get_errno(lchown(p, arg2, arg3));
5695
        unlock_user(p, arg1, 0);
5696
        break;
5697
#endif
5698
#ifdef TARGET_NR_getuid32
5699
    case TARGET_NR_getuid32:
5700
        ret = get_errno(getuid());
5701
        break;
5702
#endif
5703

    
5704
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
5705
   /* Alpha specific */
5706
    case TARGET_NR_getxuid:
5707
         {
5708
            uid_t euid;
5709
            euid=geteuid();
5710
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
5711
         }
5712
        ret = get_errno(getuid());
5713
        break;
5714
#endif
5715
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
5716
   /* Alpha specific */
5717
    case TARGET_NR_getxgid:
5718
         {
5719
            uid_t egid;
5720
            egid=getegid();
5721
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
5722
         }
5723
        ret = get_errno(getgid());
5724
        break;
5725
#endif
5726

    
5727
#ifdef TARGET_NR_getgid32
5728
    case TARGET_NR_getgid32:
5729
        ret = get_errno(getgid());
5730
        break;
5731
#endif
5732
#ifdef TARGET_NR_geteuid32
5733
    case TARGET_NR_geteuid32:
5734
        ret = get_errno(geteuid());
5735
        break;
5736
#endif
5737
#ifdef TARGET_NR_getegid32
5738
    case TARGET_NR_getegid32:
5739
        ret = get_errno(getegid());
5740
        break;
5741
#endif
5742
#ifdef TARGET_NR_setreuid32
5743
    case TARGET_NR_setreuid32:
5744
        ret = get_errno(setreuid(arg1, arg2));
5745
        break;
5746
#endif
5747
#ifdef TARGET_NR_setregid32
5748
    case TARGET_NR_setregid32:
5749
        ret = get_errno(setregid(arg1, arg2));
5750
        break;
5751
#endif
5752
#ifdef TARGET_NR_getgroups32
5753
    case TARGET_NR_getgroups32:
5754
        {
5755
            int gidsetsize = arg1;
5756
            uint32_t *target_grouplist;
5757
            gid_t *grouplist;
5758
            int i;
5759

    
5760
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5761
            ret = get_errno(getgroups(gidsetsize, grouplist));
5762
            if (gidsetsize == 0)
5763
                break;
5764
            if (!is_error(ret)) {
5765
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
5766
                if (!target_grouplist) {
5767
                    ret = -TARGET_EFAULT;
5768
                    goto fail;
5769
                }
5770
                for(i = 0;i < ret; i++)
5771
                    target_grouplist[i] = tswap32(grouplist[i]);
5772
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
5773
            }
5774
        }
5775
        break;
5776
#endif
5777
#ifdef TARGET_NR_setgroups32
5778
    case TARGET_NR_setgroups32:
5779
        {
5780
            int gidsetsize = arg1;
5781
            uint32_t *target_grouplist;
5782
            gid_t *grouplist;
5783
            int i;
5784

    
5785
            grouplist = alloca(gidsetsize * sizeof(gid_t));
5786
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
5787
            if (!target_grouplist) {
5788
                ret = -TARGET_EFAULT;
5789
                goto fail;
5790
            }
5791
            for(i = 0;i < gidsetsize; i++)
5792
                grouplist[i] = tswap32(target_grouplist[i]);
5793
            unlock_user(target_grouplist, arg2, 0);
5794
            ret = get_errno(setgroups(gidsetsize, grouplist));
5795
        }
5796
        break;
5797
#endif
5798
#ifdef TARGET_NR_fchown32
5799
    case TARGET_NR_fchown32:
5800
        ret = get_errno(fchown(arg1, arg2, arg3));
5801
        break;
5802
#endif
5803
#ifdef TARGET_NR_setresuid32
5804
    case TARGET_NR_setresuid32:
5805
        ret = get_errno(setresuid(arg1, arg2, arg3));
5806
        break;
5807
#endif
5808
#ifdef TARGET_NR_getresuid32
5809
    case TARGET_NR_getresuid32:
5810
        {
5811
            uid_t ruid, euid, suid;
5812
            ret = get_errno(getresuid(&ruid, &euid, &suid));
5813
            if (!is_error(ret)) {
5814
                if (put_user_u32(ruid, arg1)
5815
                    || put_user_u32(euid, arg2)
5816
                    || put_user_u32(suid, arg3))
5817
                    goto efault;
5818
            }
5819
        }
5820
        break;
5821
#endif
5822
#ifdef TARGET_NR_setresgid32
5823
    case TARGET_NR_setresgid32:
5824
        ret = get_errno(setresgid(arg1, arg2, arg3));
5825
        break;
5826
#endif
5827
#ifdef TARGET_NR_getresgid32
5828
    case TARGET_NR_getresgid32:
5829
        {
5830
            gid_t rgid, egid, sgid;
5831
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
5832
            if (!is_error(ret)) {
5833
                if (put_user_u32(rgid, arg1)
5834
                    || put_user_u32(egid, arg2)
5835
                    || put_user_u32(sgid, arg3))
5836
                    goto efault;
5837
            }
5838
        }
5839
        break;
5840
#endif
5841
#ifdef TARGET_NR_chown32
5842
    case TARGET_NR_chown32:
5843
        if (!(p = lock_user_string(arg1)))
5844
            goto efault;
5845
        ret = get_errno(chown(p, arg2, arg3));
5846
        unlock_user(p, arg1, 0);
5847
        break;
5848
#endif
5849
#ifdef TARGET_NR_setuid32
5850
    case TARGET_NR_setuid32:
5851
        ret = get_errno(setuid(arg1));
5852
        break;
5853
#endif
5854
#ifdef TARGET_NR_setgid32
5855
    case TARGET_NR_setgid32:
5856
        ret = get_errno(setgid(arg1));
5857
        break;
5858
#endif
5859
#ifdef TARGET_NR_setfsuid32
5860
    case TARGET_NR_setfsuid32:
5861
        ret = get_errno(setfsuid(arg1));
5862
        break;
5863
#endif
5864
#ifdef TARGET_NR_setfsgid32
5865
    case TARGET_NR_setfsgid32:
5866
        ret = get_errno(setfsgid(arg1));
5867
        break;
5868
#endif
5869

    
5870
    case TARGET_NR_pivot_root:
5871
        goto unimplemented;
5872
#ifdef TARGET_NR_mincore
5873
    case TARGET_NR_mincore:
5874
        {
5875
            void *a;
5876
            ret = -TARGET_EFAULT;
5877
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
5878
                goto efault;
5879
            if (!(p = lock_user_string(arg3)))
5880
                goto mincore_fail;
5881
            ret = get_errno(mincore(a, arg2, p));
5882
            unlock_user(p, arg3, ret);
5883
            mincore_fail:
5884
            unlock_user(a, arg1, 0);
5885
        }
5886
        break;
5887
#endif
5888
#ifdef TARGET_NR_arm_fadvise64_64
5889
    case TARGET_NR_arm_fadvise64_64:
5890
        {
5891
                /*
5892
                 * arm_fadvise64_64 looks like fadvise64_64 but
5893
                 * with different argument order
5894
                 */
5895
                abi_long temp;
5896
                temp = arg3;
5897
                arg3 = arg4;
5898
                arg4 = temp;
5899
        }
5900
#endif
5901
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
5902
#ifdef TARGET_NR_fadvise64_64
5903
    case TARGET_NR_fadvise64_64:
5904
#endif
5905
        /* This is a hint, so ignoring and returning success is ok.  */
5906
        ret = get_errno(0);
5907
        break;
5908
#endif
5909
#ifdef TARGET_NR_madvise
5910
    case TARGET_NR_madvise:
5911
        /* A straight passthrough may not be safe because qemu sometimes
5912
           turns private flie-backed mappings into anonymous mappings.
5913
           This will break MADV_DONTNEED.
5914
           This is a hint, so ignoring and returning success is ok.  */
5915
        ret = get_errno(0);
5916
        break;
5917
#endif
5918
#if TARGET_ABI_BITS == 32
5919
    case TARGET_NR_fcntl64:
5920
    {
5921
        int cmd;
5922
        struct flock64 fl;
5923
        struct target_flock64 *target_fl;
5924
#ifdef TARGET_ARM
5925
        struct target_eabi_flock64 *target_efl;
5926
#endif
5927

    
5928
        switch(arg2){
5929
        case TARGET_F_GETLK64:
5930
            cmd = F_GETLK64;
5931
            break;
5932
        case TARGET_F_SETLK64:
5933
            cmd = F_SETLK64;
5934
            break;
5935
        case TARGET_F_SETLKW64:
5936
            cmd = F_SETLK64;
5937
            break;
5938
        default:
5939
            cmd = arg2;
5940
            break;
5941
        }
5942

    
5943
        switch(arg2) {
5944
        case TARGET_F_GETLK64:
5945
#ifdef TARGET_ARM
5946
            if (((CPUARMState *)cpu_env)->eabi) {
5947
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5948
                    goto efault;
5949
                fl.l_type = tswap16(target_efl->l_type);
5950
                fl.l_whence = tswap16(target_efl->l_whence);
5951
                fl.l_start = tswap64(target_efl->l_start);
5952
                fl.l_len = tswap64(target_efl->l_len);
5953
                fl.l_pid = tswapl(target_efl->l_pid);
5954
                unlock_user_struct(target_efl, arg3, 0);
5955
            } else
5956
#endif
5957
            {
5958
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
5959
                    goto efault;
5960
                fl.l_type = tswap16(target_fl->l_type);
5961
                fl.l_whence = tswap16(target_fl->l_whence);
5962
                fl.l_start = tswap64(target_fl->l_start);
5963
                fl.l_len = tswap64(target_fl->l_len);
5964
                fl.l_pid = tswapl(target_fl->l_pid);
5965
                unlock_user_struct(target_fl, arg3, 0);
5966
            }
5967
            ret = get_errno(fcntl(arg1, cmd, &fl));
5968
            if (ret == 0) {
5969
#ifdef TARGET_ARM
5970
                if (((CPUARMState *)cpu_env)->eabi) {
5971
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
5972
                        goto efault;
5973
                    target_efl->l_type = tswap16(fl.l_type);
5974
                    target_efl->l_whence = tswap16(fl.l_whence);
5975
                    target_efl->l_start = tswap64(fl.l_start);
5976
                    target_efl->l_len = tswap64(fl.l_len);
5977
                    target_efl->l_pid = tswapl(fl.l_pid);
5978
                    unlock_user_struct(target_efl, arg3, 1);
5979
                } else
5980
#endif
5981
                {
5982
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
5983
                        goto efault;
5984
                    target_fl->l_type = tswap16(fl.l_type);
5985
                    target_fl->l_whence = tswap16(fl.l_whence);
5986
                    target_fl->l_start = tswap64(fl.l_start);
5987
                    target_fl->l_len = tswap64(fl.l_len);
5988
                    target_fl->l_pid = tswapl(fl.l_pid);
5989
                    unlock_user_struct(target_fl, arg3, 1);
5990
                }
5991
            }
5992
            break;
5993

    
5994
        case TARGET_F_SETLK64:
5995
        case TARGET_F_SETLKW64:
5996
#ifdef TARGET_ARM
5997
            if (((CPUARMState *)cpu_env)->eabi) {
5998
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
5999
                    goto efault;
6000
                fl.l_type = tswap16(target_efl->l_type);
6001
                fl.l_whence = tswap16(target_efl->l_whence);
6002
                fl.l_start = tswap64(target_efl->l_start);
6003
                fl.l_len = tswap64(target_efl->l_len);
6004
                fl.l_pid = tswapl(target_efl->l_pid);
6005
                unlock_user_struct(target_efl, arg3, 0);
6006
            } else
6007
#endif
6008
            {
6009
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6010
                    goto efault;
6011
                fl.l_type = tswap16(target_fl->l_type);
6012
                fl.l_whence = tswap16(target_fl->l_whence);
6013
                fl.l_start = tswap64(target_fl->l_start);
6014
                fl.l_len = tswap64(target_fl->l_len);
6015
                fl.l_pid = tswapl(target_fl->l_pid);
6016
                unlock_user_struct(target_fl, arg3, 0);
6017
            }
6018
            ret = get_errno(fcntl(arg1, cmd, &fl));
6019
            break;
6020
        default:
6021
            ret = do_fcntl(arg1, cmd, arg3);
6022
            break;
6023
        }
6024
        break;
6025
    }
6026
#endif
6027
#ifdef TARGET_NR_cacheflush
6028
    case TARGET_NR_cacheflush:
6029
        /* self-modifying code is handled automatically, so nothing needed */
6030
        ret = 0;
6031
        break;
6032
#endif
6033
#ifdef TARGET_NR_security
6034
    case TARGET_NR_security:
6035
        goto unimplemented;
6036
#endif
6037
#ifdef TARGET_NR_getpagesize
6038
    case TARGET_NR_getpagesize:
6039
        ret = TARGET_PAGE_SIZE;
6040
        break;
6041
#endif
6042
    case TARGET_NR_gettid:
6043
        ret = get_errno(gettid());
6044
        break;
6045
#ifdef TARGET_NR_readahead
6046
    case TARGET_NR_readahead:
6047
#if TARGET_ABI_BITS == 32
6048
#ifdef TARGET_ARM
6049
        if (((CPUARMState *)cpu_env)->eabi)
6050
        {
6051
            arg2 = arg3;
6052
            arg3 = arg4;
6053
            arg4 = arg5;
6054
        }
6055
#endif
6056
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6057
#else
6058
        ret = get_errno(readahead(arg1, arg2, arg3));
6059
#endif
6060
        break;
6061
#endif
6062
#ifdef TARGET_NR_setxattr
6063
    case TARGET_NR_setxattr:
6064
    case TARGET_NR_lsetxattr:
6065
    case TARGET_NR_fsetxattr:
6066
    case TARGET_NR_getxattr:
6067
    case TARGET_NR_lgetxattr:
6068
    case TARGET_NR_fgetxattr:
6069
    case TARGET_NR_listxattr:
6070
    case TARGET_NR_llistxattr:
6071
    case TARGET_NR_flistxattr:
6072
    case TARGET_NR_removexattr:
6073
    case TARGET_NR_lremovexattr:
6074
    case TARGET_NR_fremovexattr:
6075
        goto unimplemented_nowarn;
6076
#endif
6077
#ifdef TARGET_NR_set_thread_area
6078
    case TARGET_NR_set_thread_area:
6079
#if defined(TARGET_MIPS)
6080
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6081
      ret = 0;
6082
      break;
6083
#elif defined(TARGET_CRIS)
6084
      if (arg1 & 0xff)
6085
          ret = -TARGET_EINVAL;
6086
      else {
6087
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6088
          ret = 0;
6089
      }
6090
      break;
6091
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
6092
      ret = do_set_thread_area(cpu_env, arg1);
6093
      break;
6094
#else
6095
      goto unimplemented_nowarn;
6096
#endif
6097
#endif
6098
#ifdef TARGET_NR_get_thread_area
6099
    case TARGET_NR_get_thread_area:
6100
#if defined(TARGET_I386) && defined(TARGET_ABI32)
6101
        ret = do_get_thread_area(cpu_env, arg1);
6102
#else
6103
        goto unimplemented_nowarn;
6104
#endif
6105
#endif
6106
#ifdef TARGET_NR_getdomainname
6107
    case TARGET_NR_getdomainname:
6108
        goto unimplemented_nowarn;
6109
#endif
6110

    
6111
#ifdef TARGET_NR_clock_gettime
6112
    case TARGET_NR_clock_gettime:
6113
    {
6114
        struct timespec ts;
6115
        ret = get_errno(clock_gettime(arg1, &ts));
6116
        if (!is_error(ret)) {
6117
            host_to_target_timespec(arg2, &ts);
6118
        }
6119
        break;
6120
    }
6121
#endif
6122
#ifdef TARGET_NR_clock_getres
6123
    case TARGET_NR_clock_getres:
6124
    {
6125
        struct timespec ts;
6126
        ret = get_errno(clock_getres(arg1, &ts));
6127
        if (!is_error(ret)) {
6128
            host_to_target_timespec(arg2, &ts);
6129
        }
6130
        break;
6131
    }
6132
#endif
6133
#ifdef TARGET_NR_clock_nanosleep
6134
    case TARGET_NR_clock_nanosleep:
6135
    {
6136
        struct timespec ts;
6137
        target_to_host_timespec(&ts, arg3);
6138
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6139
        if (arg4)
6140
            host_to_target_timespec(arg4, &ts);
6141
        break;
6142
    }
6143
#endif
6144

    
6145
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6146
    case TARGET_NR_set_tid_address:
6147
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
6148
        break;
6149
#endif
6150

    
6151
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6152
    case TARGET_NR_tkill:
6153
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6154
        break;
6155
#endif
6156

    
6157
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6158
    case TARGET_NR_tgkill:
6159
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6160
                        target_to_host_signal(arg3)));
6161
        break;
6162
#endif
6163

    
6164
#ifdef TARGET_NR_set_robust_list
6165
    case TARGET_NR_set_robust_list:
6166
        goto unimplemented_nowarn;
6167
#endif
6168

    
6169
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6170
    case TARGET_NR_utimensat:
6171
        {
6172
            struct timespec ts[2];
6173
            target_to_host_timespec(ts, arg3);
6174
            target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6175
            if (!arg2)
6176
                ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
6177
            else {
6178
                if (!(p = lock_user_string(arg2))) {
6179
                    ret = -TARGET_EFAULT;
6180
                    goto fail;
6181
                }
6182
                ret = get_errno(sys_utimensat(arg1, path(p), ts, arg4));
6183
                unlock_user(p, arg2, 0);
6184
            }
6185
        }
6186
        break;
6187
#endif
6188
#if defined(USE_NPTL)
6189
    case TARGET_NR_futex:
6190
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6191
        break;
6192
#endif
6193
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6194
    case TARGET_NR_inotify_init:
6195
        ret = get_errno(sys_inotify_init());
6196
        break;
6197
#endif
6198
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6199
    case TARGET_NR_inotify_add_watch:
6200
        p = lock_user_string(arg2);
6201
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6202
        unlock_user(p, arg2, 0);
6203
        break;
6204
#endif
6205
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6206
    case TARGET_NR_inotify_rm_watch:
6207
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6208
        break;
6209
#endif
6210

    
6211
#ifdef TARGET_NR_mq_open
6212
    case TARGET_NR_mq_open:
6213
        {
6214
            struct mq_attr posix_mq_attr;
6215

    
6216
            p = lock_user_string(arg1 - 1);
6217
            if (arg4 != 0)
6218
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
6219
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6220
            unlock_user (p, arg1, 0);
6221
        }
6222
        break;
6223

    
6224
    case TARGET_NR_mq_unlink:
6225
        p = lock_user_string(arg1 - 1);
6226
        ret = get_errno(mq_unlink(p));
6227
        unlock_user (p, arg1, 0);
6228
        break;
6229

    
6230
    case TARGET_NR_mq_timedsend:
6231
        {
6232
            struct timespec ts;
6233

    
6234
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6235
            if (arg5 != 0) {
6236
                target_to_host_timespec(&ts, arg5);
6237
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
6238
                host_to_target_timespec(arg5, &ts);
6239
            }
6240
            else
6241
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
6242
            unlock_user (p, arg2, arg3);
6243
        }
6244
        break;
6245

    
6246
    case TARGET_NR_mq_timedreceive:
6247
        {
6248
            struct timespec ts;
6249
            unsigned int prio;
6250

    
6251
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6252
            if (arg5 != 0) {
6253
                target_to_host_timespec(&ts, arg5);
6254
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6255
                host_to_target_timespec(arg5, &ts);
6256
            }
6257
            else
6258
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6259
            unlock_user (p, arg2, arg3);
6260
            if (arg4 != 0)
6261
                put_user_u32(prio, arg4);
6262
        }
6263
        break;
6264

    
6265
    /* Not implemented for now... */
6266
/*     case TARGET_NR_mq_notify: */
6267
/*         break; */
6268

    
6269
    case TARGET_NR_mq_getsetattr:
6270
        {
6271
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6272
            ret = 0;
6273
            if (arg3 != 0) {
6274
                ret = mq_getattr(arg1, &posix_mq_attr_out);
6275
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6276
            }
6277
            if (arg2 != 0) {
6278
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6279
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6280
            }
6281

    
6282
        }
6283
        break;
6284
#endif
6285

    
6286
    default:
6287
    unimplemented:
6288
        gemu_log("qemu: Unsupported syscall: %d\n", num);
6289
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6290
    unimplemented_nowarn:
6291
#endif
6292
        ret = -TARGET_ENOSYS;
6293
        break;
6294
    }
6295
fail:
6296
#ifdef DEBUG
6297
    gemu_log(" = %ld\n", ret);
6298
#endif
6299
    if(do_strace)
6300
        print_syscall_ret(num, ret);
6301
    return ret;
6302
efault:
6303
    ret = -TARGET_EFAULT;
6304
    goto fail;
6305
}