Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 2f7bb878

History | View | Annotate | Download (213.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, see <http://www.gnu.org/licenses/>.
18
 */
19
#define _ATFILE_SOURCE
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <stdarg.h>
23
#include <string.h>
24
#include <elf.h>
25
#include <endian.h>
26
#include <errno.h>
27
#include <unistd.h>
28
#include <fcntl.h>
29
#include <time.h>
30
#include <limits.h>
31
#include <mqueue.h>
32
#include <sys/types.h>
33
#include <sys/ipc.h>
34
#include <sys/msg.h>
35
#include <sys/wait.h>
36
#include <sys/time.h>
37
#include <sys/stat.h>
38
#include <sys/mount.h>
39
#include <sys/prctl.h>
40
#include <sys/resource.h>
41
#include <sys/mman.h>
42
#include <sys/swap.h>
43
#include <signal.h>
44
#include <sched.h>
45
#include <sys/socket.h>
46
#include <sys/un.h>
47
#include <sys/uio.h>
48
#include <sys/poll.h>
49
#include <sys/times.h>
50
#include <sys/shm.h>
51
#include <sys/sem.h>
52
#include <sys/statfs.h>
53
#include <utime.h>
54
#include <sys/sysinfo.h>
55
#include <sys/utsname.h>
56
//#include <sys/user.h>
57
#include <netinet/ip.h>
58
#include <netinet/tcp.h>
59
#include <qemu-common.h>
60
#ifdef TARGET_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/fs.h>
80
#include "linux_loop.h"
81

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

    
85
#if defined(CONFIG_USE_NPTL)
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
//#include <linux/msdos_fs.h>
96
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
97
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
98

    
99

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

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

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

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

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

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

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

    
145

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

    
154

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

    
184
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
185
#define __NR__llseek __NR_lseek
186
#endif
187

    
188
#ifdef __NR_gettid
189
_syscall0(int, gettid)
190
#else
191
/* This is a replacement for the host gettid() and must return a host
192
   errno. */
193
static int gettid(void) {
194
    return -ENOSYS;
195
}
196
#endif
197
#if TARGET_ABI_BITS == 32
198
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
199
#endif
200
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
201
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
202
#endif
203
_syscall2(int, sys_getpriority, int, which, int, who);
204
#if defined(TARGET_NR__llseek) && !defined (__x86_64__)
205
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
206
          loff_t *, res, uint, wh);
207
#endif
208
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
209
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
210
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
211
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
212
#endif
213
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
214
_syscall2(int,sys_tkill,int,tid,int,sig)
215
#endif
216
#ifdef __NR_exit_group
217
_syscall1(int,exit_group,int,error_code)
218
#endif
219
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
220
_syscall1(int,set_tid_address,int *,tidptr)
221
#endif
222
#if defined(CONFIG_USE_NPTL)
223
#if defined(TARGET_NR_futex) && defined(__NR_futex)
224
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
225
          const struct timespec *,timeout,int *,uaddr2,int,val3)
226
#endif
227
#endif
228

    
229
static bitmask_transtbl fcntl_flags_tbl[] = {
230
  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
231
  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
232
  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
233
  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
234
  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
235
  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
236
  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
237
  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
238
  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
239
  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
240
  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
241
  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
242
  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
243
#if defined(O_DIRECT)
244
  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
245
#endif
246
  { 0, 0, 0, 0 }
247
};
248

    
249
#define COPY_UTSNAME_FIELD(dest, src) \
250
  do { \
251
      /* __NEW_UTS_LEN doesn't include terminating null */ \
252
      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
253
      (dest)[__NEW_UTS_LEN] = '\0'; \
254
  } while (0)
255

    
256
static int sys_uname(struct new_utsname *buf)
257
{
258
  struct utsname uts_buf;
259

    
260
  if (uname(&uts_buf) < 0)
261
      return (-1);
262

    
263
  /*
264
   * Just in case these have some differences, we
265
   * translate utsname to new_utsname (which is the
266
   * struct linux kernel uses).
267
   */
268

    
269
  bzero(buf, sizeof (*buf));
270
  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
271
  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
272
  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
273
  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
274
  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
275
#ifdef _GNU_SOURCE
276
  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
277
#endif
278
  return (0);
279

    
280
#undef COPY_UTSNAME_FIELD
281
}
282

    
283
static int sys_getcwd1(char *buf, size_t size)
284
{
285
  if (getcwd(buf, size) == NULL) {
286
      /* getcwd() sets errno */
287
      return (-1);
288
  }
289
  return strlen(buf)+1;
290
}
291

    
292
#ifdef CONFIG_ATFILE
293
/*
294
 * Host system seems to have atfile syscall stubs available.  We
295
 * now enable them one by one as specified by target syscall_nr.h.
296
 */
297

    
298
#ifdef TARGET_NR_faccessat
299
static int sys_faccessat(int dirfd, const char *pathname, int mode)
300
{
301
  return (faccessat(dirfd, pathname, mode, 0));
302
}
303
#endif
304
#ifdef TARGET_NR_fchmodat
305
static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
306
{
307
  return (fchmodat(dirfd, pathname, mode, 0));
308
}
309
#endif
310
#if defined(TARGET_NR_fchownat) && defined(USE_UID16)
311
static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
312
    gid_t group, int flags)
313
{
314
  return (fchownat(dirfd, pathname, owner, group, flags));
315
}
316
#endif
317
#ifdef __NR_fstatat64
318
static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
319
    int flags)
320
{
321
  return (fstatat(dirfd, pathname, buf, flags));
322
}
323
#endif
324
#ifdef __NR_newfstatat
325
static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
326
    int flags)
327
{
328
  return (fstatat(dirfd, pathname, buf, flags));
329
}
330
#endif
331
#ifdef TARGET_NR_futimesat
332
static int sys_futimesat(int dirfd, const char *pathname,
333
    const struct timeval times[2])
334
{
335
  return (futimesat(dirfd, pathname, times));
336
}
337
#endif
338
#ifdef TARGET_NR_linkat
339
static int sys_linkat(int olddirfd, const char *oldpath,
340
    int newdirfd, const char *newpath, int flags)
341
{
342
  return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
343
}
344
#endif
345
#ifdef TARGET_NR_mkdirat
346
static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
347
{
348
  return (mkdirat(dirfd, pathname, mode));
349
}
350
#endif
351
#ifdef TARGET_NR_mknodat
352
static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
353
    dev_t dev)
354
{
355
  return (mknodat(dirfd, pathname, mode, dev));
356
}
357
#endif
358
#ifdef TARGET_NR_openat
359
static int sys_openat(int dirfd, const char *pathname, int flags, ...)
360
{
361
  /*
362
   * open(2) has extra parameter 'mode' when called with
363
   * flag O_CREAT.
364
   */
365
  if ((flags & O_CREAT) != 0) {
366
      va_list ap;
367
      mode_t mode;
368

    
369
      /*
370
       * Get the 'mode' parameter and translate it to
371
       * host bits.
372
       */
373
      va_start(ap, flags);
374
      mode = va_arg(ap, mode_t);
375
      mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
376
      va_end(ap);
377

    
378
      return (openat(dirfd, pathname, flags, mode));
379
  }
380
  return (openat(dirfd, pathname, flags));
381
}
382
#endif
383
#ifdef TARGET_NR_readlinkat
384
static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
385
{
386
  return (readlinkat(dirfd, pathname, buf, bufsiz));
387
}
388
#endif
389
#ifdef TARGET_NR_renameat
390
static int sys_renameat(int olddirfd, const char *oldpath,
391
    int newdirfd, const char *newpath)
392
{
393
  return (renameat(olddirfd, oldpath, newdirfd, newpath));
394
}
395
#endif
396
#ifdef TARGET_NR_symlinkat
397
static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
398
{
399
  return (symlinkat(oldpath, newdirfd, newpath));
400
}
401
#endif
402
#ifdef TARGET_NR_unlinkat
403
static int sys_unlinkat(int dirfd, const char *pathname, int flags)
404
{
405
  return (unlinkat(dirfd, pathname, flags));
406
}
407
#endif
408
#else /* !CONFIG_ATFILE */
409

    
410
/*
411
 * Try direct syscalls instead
412
 */
413
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
414
_syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
415
#endif
416
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
417
_syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
418
#endif
419
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
420
_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
421
          uid_t,owner,gid_t,group,int,flags)
422
#endif
423
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
424
        defined(__NR_fstatat64)
425
_syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
426
          struct stat *,buf,int,flags)
427
#endif
428
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
429
_syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
430
         const struct timeval *,times)
431
#endif
432
#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
433
        defined(__NR_newfstatat)
434
_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
435
          struct stat *,buf,int,flags)
436
#endif
437
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
438
_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
439
      int,newdirfd,const char *,newpath,int,flags)
440
#endif
441
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
442
_syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
443
#endif
444
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
445
_syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
446
          mode_t,mode,dev_t,dev)
447
#endif
448
#if defined(TARGET_NR_openat) && defined(__NR_openat)
449
_syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
450
#endif
451
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
452
_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
453
          char *,buf,size_t,bufsize)
454
#endif
455
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
456
_syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
457
          int,newdirfd,const char *,newpath)
458
#endif
459
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
460
_syscall3(int,sys_symlinkat,const char *,oldpath,
461
          int,newdirfd,const char *,newpath)
462
#endif
463
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
464
_syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
465
#endif
466

    
467
#endif /* CONFIG_ATFILE */
468

    
469
#ifdef CONFIG_UTIMENSAT
470
static int sys_utimensat(int dirfd, const char *pathname,
471
    const struct timespec times[2], int flags)
472
{
473
    if (pathname == NULL)
474
        return futimens(dirfd, times);
475
    else
476
        return utimensat(dirfd, pathname, times, flags);
477
}
478
#else
479
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
480
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
481
          const struct timespec *,tsp,int,flags)
482
#endif
483
#endif /* CONFIG_UTIMENSAT  */
484

    
485
#ifdef CONFIG_INOTIFY
486
#include <sys/inotify.h>
487

    
488
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
489
static int sys_inotify_init(void)
490
{
491
  return (inotify_init());
492
}
493
#endif
494
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
495
static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
496
{
497
  return (inotify_add_watch(fd, pathname, mask));
498
}
499
#endif
500
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
501
static int sys_inotify_rm_watch(int fd, int32_t wd)
502
{
503
  return (inotify_rm_watch(fd, wd));
504
}
505
#endif
506
#else
507
/* Userspace can usually survive runtime without inotify */
508
#undef TARGET_NR_inotify_init
509
#undef TARGET_NR_inotify_add_watch
510
#undef TARGET_NR_inotify_rm_watch
511
#endif /* CONFIG_INOTIFY  */
512

    
513

    
514
extern int personality(int);
515
extern int flock(int, int);
516
extern int setfsuid(int);
517
extern int setfsgid(int);
518
extern int setgroups(int, gid_t *);
519

    
520
#define ERRNO_TABLE_SIZE 1200
521

    
522
/* target_to_host_errno_table[] is initialized from
523
 * host_to_target_errno_table[] in syscall_init(). */
524
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
525
};
526

    
527
/*
528
 * This list is the union of errno values overridden in asm-<arch>/errno.h
529
 * minus the errnos that are not actually generic to all archs.
530
 */
531
static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
532
    [EIDRM]                = TARGET_EIDRM,
533
    [ECHRNG]                = TARGET_ECHRNG,
534
    [EL2NSYNC]                = TARGET_EL2NSYNC,
535
    [EL3HLT]                = TARGET_EL3HLT,
536
    [EL3RST]                = TARGET_EL3RST,
537
    [ELNRNG]                = TARGET_ELNRNG,
538
    [EUNATCH]                = TARGET_EUNATCH,
539
    [ENOCSI]                = TARGET_ENOCSI,
540
    [EL2HLT]                = TARGET_EL2HLT,
541
    [EDEADLK]                = TARGET_EDEADLK,
542
    [ENOLCK]                = TARGET_ENOLCK,
543
    [EBADE]                = TARGET_EBADE,
544
    [EBADR]                = TARGET_EBADR,
545
    [EXFULL]                = TARGET_EXFULL,
546
    [ENOANO]                = TARGET_ENOANO,
547
    [EBADRQC]                = TARGET_EBADRQC,
548
    [EBADSLT]                = TARGET_EBADSLT,
549
    [EBFONT]                = TARGET_EBFONT,
550
    [ENOSTR]                = TARGET_ENOSTR,
551
    [ENODATA]                = TARGET_ENODATA,
552
    [ETIME]                = TARGET_ETIME,
553
    [ENOSR]                = TARGET_ENOSR,
554
    [ENONET]                = TARGET_ENONET,
555
    [ENOPKG]                = TARGET_ENOPKG,
556
    [EREMOTE]                = TARGET_EREMOTE,
557
    [ENOLINK]                = TARGET_ENOLINK,
558
    [EADV]                = TARGET_EADV,
559
    [ESRMNT]                = TARGET_ESRMNT,
560
    [ECOMM]                = TARGET_ECOMM,
561
    [EPROTO]                = TARGET_EPROTO,
562
    [EDOTDOT]                = TARGET_EDOTDOT,
563
    [EMULTIHOP]                = TARGET_EMULTIHOP,
564
    [EBADMSG]                = TARGET_EBADMSG,
565
    [ENAMETOOLONG]        = TARGET_ENAMETOOLONG,
566
    [EOVERFLOW]                = TARGET_EOVERFLOW,
567
    [ENOTUNIQ]                = TARGET_ENOTUNIQ,
568
    [EBADFD]                = TARGET_EBADFD,
569
    [EREMCHG]                = TARGET_EREMCHG,
570
    [ELIBACC]                = TARGET_ELIBACC,
571
    [ELIBBAD]                = TARGET_ELIBBAD,
572
    [ELIBSCN]                = TARGET_ELIBSCN,
573
    [ELIBMAX]                = TARGET_ELIBMAX,
574
    [ELIBEXEC]                = TARGET_ELIBEXEC,
575
    [EILSEQ]                = TARGET_EILSEQ,
576
    [ENOSYS]                = TARGET_ENOSYS,
577
    [ELOOP]                = TARGET_ELOOP,
578
    [ERESTART]                = TARGET_ERESTART,
579
    [ESTRPIPE]                = TARGET_ESTRPIPE,
580
    [ENOTEMPTY]                = TARGET_ENOTEMPTY,
581
    [EUSERS]                = TARGET_EUSERS,
582
    [ENOTSOCK]                = TARGET_ENOTSOCK,
583
    [EDESTADDRREQ]        = TARGET_EDESTADDRREQ,
584
    [EMSGSIZE]                = TARGET_EMSGSIZE,
585
    [EPROTOTYPE]        = TARGET_EPROTOTYPE,
586
    [ENOPROTOOPT]        = TARGET_ENOPROTOOPT,
587
    [EPROTONOSUPPORT]        = TARGET_EPROTONOSUPPORT,
588
    [ESOCKTNOSUPPORT]        = TARGET_ESOCKTNOSUPPORT,
589
    [EOPNOTSUPP]        = TARGET_EOPNOTSUPP,
590
    [EPFNOSUPPORT]        = TARGET_EPFNOSUPPORT,
591
    [EAFNOSUPPORT]        = TARGET_EAFNOSUPPORT,
592
    [EADDRINUSE]        = TARGET_EADDRINUSE,
593
    [EADDRNOTAVAIL]        = TARGET_EADDRNOTAVAIL,
594
    [ENETDOWN]                = TARGET_ENETDOWN,
595
    [ENETUNREACH]        = TARGET_ENETUNREACH,
596
    [ENETRESET]                = TARGET_ENETRESET,
597
    [ECONNABORTED]        = TARGET_ECONNABORTED,
598
    [ECONNRESET]        = TARGET_ECONNRESET,
599
    [ENOBUFS]                = TARGET_ENOBUFS,
600
    [EISCONN]                = TARGET_EISCONN,
601
    [ENOTCONN]                = TARGET_ENOTCONN,
602
    [EUCLEAN]                = TARGET_EUCLEAN,
603
    [ENOTNAM]                = TARGET_ENOTNAM,
604
    [ENAVAIL]                = TARGET_ENAVAIL,
605
    [EISNAM]                = TARGET_EISNAM,
606
    [EREMOTEIO]                = TARGET_EREMOTEIO,
607
    [ESHUTDOWN]                = TARGET_ESHUTDOWN,
608
    [ETOOMANYREFS]        = TARGET_ETOOMANYREFS,
609
    [ETIMEDOUT]                = TARGET_ETIMEDOUT,
610
    [ECONNREFUSED]        = TARGET_ECONNREFUSED,
611
    [EHOSTDOWN]                = TARGET_EHOSTDOWN,
612
    [EHOSTUNREACH]        = TARGET_EHOSTUNREACH,
613
    [EALREADY]                = TARGET_EALREADY,
614
    [EINPROGRESS]        = TARGET_EINPROGRESS,
615
    [ESTALE]                = TARGET_ESTALE,
616
    [ECANCELED]                = TARGET_ECANCELED,
617
    [ENOMEDIUM]                = TARGET_ENOMEDIUM,
618
    [EMEDIUMTYPE]        = TARGET_EMEDIUMTYPE,
619
#ifdef ENOKEY
620
    [ENOKEY]                = TARGET_ENOKEY,
621
#endif
622
#ifdef EKEYEXPIRED
623
    [EKEYEXPIRED]        = TARGET_EKEYEXPIRED,
624
#endif
625
#ifdef EKEYREVOKED
626
    [EKEYREVOKED]        = TARGET_EKEYREVOKED,
627
#endif
628
#ifdef EKEYREJECTED
629
    [EKEYREJECTED]        = TARGET_EKEYREJECTED,
630
#endif
631
#ifdef EOWNERDEAD
632
    [EOWNERDEAD]        = TARGET_EOWNERDEAD,
633
#endif
634
#ifdef ENOTRECOVERABLE
635
    [ENOTRECOVERABLE]        = TARGET_ENOTRECOVERABLE,
636
#endif
637
};
638

    
639
static inline int host_to_target_errno(int err)
640
{
641
    if(host_to_target_errno_table[err])
642
        return host_to_target_errno_table[err];
643
    return err;
644
}
645

    
646
static inline int target_to_host_errno(int err)
647
{
648
    if (target_to_host_errno_table[err])
649
        return target_to_host_errno_table[err];
650
    return err;
651
}
652

    
653
static inline abi_long get_errno(abi_long ret)
654
{
655
    if (ret == -1)
656
        return -host_to_target_errno(errno);
657
    else
658
        return ret;
659
}
660

    
661
static inline int is_error(abi_long ret)
662
{
663
    return (abi_ulong)ret >= (abi_ulong)(-4096);
664
}
665

    
666
char *target_strerror(int err)
667
{
668
    return strerror(target_to_host_errno(err));
669
}
670

    
671
static abi_ulong target_brk;
672
static abi_ulong target_original_brk;
673

    
674
void target_set_brk(abi_ulong new_brk)
675
{
676
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
677
}
678

    
679
/* do_brk() must return target values and target errnos. */
680
abi_long do_brk(abi_ulong new_brk)
681
{
682
    abi_ulong brk_page;
683
    abi_long mapped_addr;
684
    int        new_alloc_size;
685

    
686
    if (!new_brk)
687
        return target_brk;
688
    if (new_brk < target_original_brk)
689
        return target_brk;
690

    
691
    brk_page = HOST_PAGE_ALIGN(target_brk);
692

    
693
    /* If the new brk is less than this, set it and we're done... */
694
    if (new_brk < brk_page) {
695
        target_brk = new_brk;
696
            return target_brk;
697
    }
698

    
699
    /* We need to allocate more memory after the brk... */
700
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
701
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
702
                                        PROT_READ|PROT_WRITE,
703
                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
704

    
705
    if (!is_error(mapped_addr))
706
        target_brk = new_brk;
707
    
708
    return target_brk;
709
}
710

    
711
static inline abi_long copy_from_user_fdset(fd_set *fds,
712
                                            abi_ulong target_fds_addr,
713
                                            int n)
714
{
715
    int i, nw, j, k;
716
    abi_ulong b, *target_fds;
717

    
718
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
719
    if (!(target_fds = lock_user(VERIFY_READ,
720
                                 target_fds_addr,
721
                                 sizeof(abi_ulong) * nw,
722
                                 1)))
723
        return -TARGET_EFAULT;
724

    
725
    FD_ZERO(fds);
726
    k = 0;
727
    for (i = 0; i < nw; i++) {
728
        /* grab the abi_ulong */
729
        __get_user(b, &target_fds[i]);
730
        for (j = 0; j < TARGET_ABI_BITS; j++) {
731
            /* check the bit inside the abi_ulong */
732
            if ((b >> j) & 1)
733
                FD_SET(k, fds);
734
            k++;
735
        }
736
    }
737

    
738
    unlock_user(target_fds, target_fds_addr, 0);
739

    
740
    return 0;
741
}
742

    
743
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
744
                                          const fd_set *fds,
745
                                          int n)
746
{
747
    int i, nw, j, k;
748
    abi_long v;
749
    abi_ulong *target_fds;
750

    
751
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
752
    if (!(target_fds = lock_user(VERIFY_WRITE,
753
                                 target_fds_addr,
754
                                 sizeof(abi_ulong) * nw,
755
                                 0)))
756
        return -TARGET_EFAULT;
757

    
758
    k = 0;
759
    for (i = 0; i < nw; i++) {
760
        v = 0;
761
        for (j = 0; j < TARGET_ABI_BITS; j++) {
762
            v |= ((FD_ISSET(k, fds) != 0) << j);
763
            k++;
764
        }
765
        __put_user(v, &target_fds[i]);
766
    }
767

    
768
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
769

    
770
    return 0;
771
}
772

    
773
#if defined(__alpha__)
774
#define HOST_HZ 1024
775
#else
776
#define HOST_HZ 100
777
#endif
778

    
779
static inline abi_long host_to_target_clock_t(long ticks)
780
{
781
#if HOST_HZ == TARGET_HZ
782
    return ticks;
783
#else
784
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
785
#endif
786
}
787

    
788
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
789
                                             const struct rusage *rusage)
790
{
791
    struct target_rusage *target_rusage;
792

    
793
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
794
        return -TARGET_EFAULT;
795
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
796
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
797
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
798
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
799
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
800
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
801
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
802
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
803
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
804
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
805
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
806
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
807
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
808
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
809
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
810
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
811
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
812
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
813
    unlock_user_struct(target_rusage, target_addr, 1);
814

    
815
    return 0;
816
}
817

    
818
static inline abi_long copy_from_user_timeval(struct timeval *tv,
819
                                              abi_ulong target_tv_addr)
820
{
821
    struct target_timeval *target_tv;
822

    
823
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
824
        return -TARGET_EFAULT;
825

    
826
    __get_user(tv->tv_sec, &target_tv->tv_sec);
827
    __get_user(tv->tv_usec, &target_tv->tv_usec);
828

    
829
    unlock_user_struct(target_tv, target_tv_addr, 0);
830

    
831
    return 0;
832
}
833

    
834
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
835
                                            const struct timeval *tv)
836
{
837
    struct target_timeval *target_tv;
838

    
839
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
840
        return -TARGET_EFAULT;
841

    
842
    __put_user(tv->tv_sec, &target_tv->tv_sec);
843
    __put_user(tv->tv_usec, &target_tv->tv_usec);
844

    
845
    unlock_user_struct(target_tv, target_tv_addr, 1);
846

    
847
    return 0;
848
}
849

    
850
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
851
                                              abi_ulong target_mq_attr_addr)
852
{
853
    struct target_mq_attr *target_mq_attr;
854

    
855
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
856
                          target_mq_attr_addr, 1))
857
        return -TARGET_EFAULT;
858

    
859
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
860
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
861
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
862
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
863

    
864
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
865

    
866
    return 0;
867
}
868

    
869
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
870
                                            const struct mq_attr *attr)
871
{
872
    struct target_mq_attr *target_mq_attr;
873

    
874
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
875
                          target_mq_attr_addr, 0))
876
        return -TARGET_EFAULT;
877

    
878
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
879
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
880
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
881
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
882

    
883
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
884

    
885
    return 0;
886
}
887

    
888
/* do_select() must return target values and target errnos. */
889
static abi_long do_select(int n,
890
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
891
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
892
{
893
    fd_set rfds, wfds, efds;
894
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
895
    struct timeval tv, *tv_ptr;
896
    abi_long ret;
897

    
898
    if (rfd_addr) {
899
        if (copy_from_user_fdset(&rfds, rfd_addr, n))
900
            return -TARGET_EFAULT;
901
        rfds_ptr = &rfds;
902
    } else {
903
        rfds_ptr = NULL;
904
    }
905
    if (wfd_addr) {
906
        if (copy_from_user_fdset(&wfds, wfd_addr, n))
907
            return -TARGET_EFAULT;
908
        wfds_ptr = &wfds;
909
    } else {
910
        wfds_ptr = NULL;
911
    }
912
    if (efd_addr) {
913
        if (copy_from_user_fdset(&efds, efd_addr, n))
914
            return -TARGET_EFAULT;
915
        efds_ptr = &efds;
916
    } else {
917
        efds_ptr = NULL;
918
    }
919

    
920
    if (target_tv_addr) {
921
        if (copy_from_user_timeval(&tv, target_tv_addr))
922
            return -TARGET_EFAULT;
923
        tv_ptr = &tv;
924
    } else {
925
        tv_ptr = NULL;
926
    }
927

    
928
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
929

    
930
    if (!is_error(ret)) {
931
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
932
            return -TARGET_EFAULT;
933
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
934
            return -TARGET_EFAULT;
935
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
936
            return -TARGET_EFAULT;
937

    
938
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
939
            return -TARGET_EFAULT;
940
    }
941

    
942
    return ret;
943
}
944

    
945
static abi_long do_pipe2(int host_pipe[], int flags)
946
{
947
#ifdef CONFIG_PIPE2
948
    return pipe2(host_pipe, flags);
949
#else
950
    return -ENOSYS;
951
#endif
952
}
953

    
954
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, int flags)
955
{
956
    int host_pipe[2];
957
    abi_long ret;
958
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
959

    
960
    if (is_error(ret))
961
        return get_errno(ret);
962
#if defined(TARGET_MIPS)
963
    ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
964
    ret = host_pipe[0];
965
#elif defined(TARGET_SH4)
966
    ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
967
    ret = host_pipe[0];
968
#else
969
    if (put_user_s32(host_pipe[0], pipedes)
970
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
971
        return -TARGET_EFAULT;
972
#endif
973
    return get_errno(ret);
974
}
975

    
976
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
977
                                              abi_ulong target_addr,
978
                                              socklen_t len)
979
{
980
    struct target_ip_mreqn *target_smreqn;
981

    
982
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
983
    if (!target_smreqn)
984
        return -TARGET_EFAULT;
985
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
986
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
987
    if (len == sizeof(struct target_ip_mreqn))
988
        mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
989
    unlock_user(target_smreqn, target_addr, 0);
990

    
991
    return 0;
992
}
993

    
994
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
995
                                               abi_ulong target_addr,
996
                                               socklen_t len)
997
{
998
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
999
    sa_family_t sa_family;
1000
    struct target_sockaddr *target_saddr;
1001

    
1002
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1003
    if (!target_saddr)
1004
        return -TARGET_EFAULT;
1005

    
1006
    sa_family = tswap16(target_saddr->sa_family);
1007

    
1008
    /* Oops. The caller might send a incomplete sun_path; sun_path
1009
     * must be terminated by \0 (see the manual page), but
1010
     * unfortunately it is quite common to specify sockaddr_un
1011
     * length as "strlen(x->sun_path)" while it should be
1012
     * "strlen(...) + 1". We'll fix that here if needed.
1013
     * Linux kernel has a similar feature.
1014
     */
1015

    
1016
    if (sa_family == AF_UNIX) {
1017
        if (len < unix_maxlen && len > 0) {
1018
            char *cp = (char*)target_saddr;
1019

    
1020
            if ( cp[len-1] && !cp[len] )
1021
                len++;
1022
        }
1023
        if (len > unix_maxlen)
1024
            len = unix_maxlen;
1025
    }
1026

    
1027
    memcpy(addr, target_saddr, len);
1028
    addr->sa_family = sa_family;
1029
    unlock_user(target_saddr, target_addr, 0);
1030

    
1031
    return 0;
1032
}
1033

    
1034
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1035
                                               struct sockaddr *addr,
1036
                                               socklen_t len)
1037
{
1038
    struct target_sockaddr *target_saddr;
1039

    
1040
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1041
    if (!target_saddr)
1042
        return -TARGET_EFAULT;
1043
    memcpy(target_saddr, addr, len);
1044
    target_saddr->sa_family = tswap16(addr->sa_family);
1045
    unlock_user(target_saddr, target_addr, len);
1046

    
1047
    return 0;
1048
}
1049

    
1050
/* ??? Should this also swap msgh->name?  */
1051
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1052
                                           struct target_msghdr *target_msgh)
1053
{
1054
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1055
    abi_long msg_controllen;
1056
    abi_ulong target_cmsg_addr;
1057
    struct target_cmsghdr *target_cmsg;
1058
    socklen_t space = 0;
1059
    
1060
    msg_controllen = tswapl(target_msgh->msg_controllen);
1061
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1062
        goto the_end;
1063
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1064
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1065
    if (!target_cmsg)
1066
        return -TARGET_EFAULT;
1067

    
1068
    while (cmsg && target_cmsg) {
1069
        void *data = CMSG_DATA(cmsg);
1070
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1071

    
1072
        int len = tswapl(target_cmsg->cmsg_len)
1073
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1074

    
1075
        space += CMSG_SPACE(len);
1076
        if (space > msgh->msg_controllen) {
1077
            space -= CMSG_SPACE(len);
1078
            gemu_log("Host cmsg overflow\n");
1079
            break;
1080
        }
1081

    
1082
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1083
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1084
        cmsg->cmsg_len = CMSG_LEN(len);
1085

    
1086
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1087
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1088
            memcpy(data, target_data, len);
1089
        } else {
1090
            int *fd = (int *)data;
1091
            int *target_fd = (int *)target_data;
1092
            int i, numfds = len / sizeof(int);
1093

    
1094
            for (i = 0; i < numfds; i++)
1095
                fd[i] = tswap32(target_fd[i]);
1096
        }
1097

    
1098
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1099
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1100
    }
1101
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1102
 the_end:
1103
    msgh->msg_controllen = space;
1104
    return 0;
1105
}
1106

    
1107
/* ??? Should this also swap msgh->name?  */
1108
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1109
                                           struct msghdr *msgh)
1110
{
1111
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1112
    abi_long msg_controllen;
1113
    abi_ulong target_cmsg_addr;
1114
    struct target_cmsghdr *target_cmsg;
1115
    socklen_t space = 0;
1116

    
1117
    msg_controllen = tswapl(target_msgh->msg_controllen);
1118
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1119
        goto the_end;
1120
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1121
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1122
    if (!target_cmsg)
1123
        return -TARGET_EFAULT;
1124

    
1125
    while (cmsg && target_cmsg) {
1126
        void *data = CMSG_DATA(cmsg);
1127
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1128

    
1129
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1130

    
1131
        space += TARGET_CMSG_SPACE(len);
1132
        if (space > msg_controllen) {
1133
            space -= TARGET_CMSG_SPACE(len);
1134
            gemu_log("Target cmsg overflow\n");
1135
            break;
1136
        }
1137

    
1138
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1139
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1140
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1141

    
1142
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1143
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1144
            memcpy(target_data, data, len);
1145
        } else {
1146
            int *fd = (int *)data;
1147
            int *target_fd = (int *)target_data;
1148
            int i, numfds = len / sizeof(int);
1149

    
1150
            for (i = 0; i < numfds; i++)
1151
                target_fd[i] = tswap32(fd[i]);
1152
        }
1153

    
1154
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1155
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1156
    }
1157
    unlock_user(target_cmsg, target_cmsg_addr, space);
1158
 the_end:
1159
    target_msgh->msg_controllen = tswapl(space);
1160
    return 0;
1161
}
1162

    
1163
/* do_setsockopt() Must return target values and target errnos. */
1164
static abi_long do_setsockopt(int sockfd, int level, int optname,
1165
                              abi_ulong optval_addr, socklen_t optlen)
1166
{
1167
    abi_long ret;
1168
    int val;
1169
    struct ip_mreqn *ip_mreq;
1170
    struct ip_mreq_source *ip_mreq_source;
1171

    
1172
    switch(level) {
1173
    case SOL_TCP:
1174
        /* TCP options all take an 'int' value.  */
1175
        if (optlen < sizeof(uint32_t))
1176
            return -TARGET_EINVAL;
1177

    
1178
        if (get_user_u32(val, optval_addr))
1179
            return -TARGET_EFAULT;
1180
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1181
        break;
1182
    case SOL_IP:
1183
        switch(optname) {
1184
        case IP_TOS:
1185
        case IP_TTL:
1186
        case IP_HDRINCL:
1187
        case IP_ROUTER_ALERT:
1188
        case IP_RECVOPTS:
1189
        case IP_RETOPTS:
1190
        case IP_PKTINFO:
1191
        case IP_MTU_DISCOVER:
1192
        case IP_RECVERR:
1193
        case IP_RECVTOS:
1194
#ifdef IP_FREEBIND
1195
        case IP_FREEBIND:
1196
#endif
1197
        case IP_MULTICAST_TTL:
1198
        case IP_MULTICAST_LOOP:
1199
            val = 0;
1200
            if (optlen >= sizeof(uint32_t)) {
1201
                if (get_user_u32(val, optval_addr))
1202
                    return -TARGET_EFAULT;
1203
            } else if (optlen >= 1) {
1204
                if (get_user_u8(val, optval_addr))
1205
                    return -TARGET_EFAULT;
1206
            }
1207
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1208
            break;
1209
        case IP_ADD_MEMBERSHIP:
1210
        case IP_DROP_MEMBERSHIP:
1211
            if (optlen < sizeof (struct target_ip_mreq) ||
1212
                optlen > sizeof (struct target_ip_mreqn))
1213
                return -TARGET_EINVAL;
1214

    
1215
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1216
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1217
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1218
            break;
1219

    
1220
        case IP_BLOCK_SOURCE:
1221
        case IP_UNBLOCK_SOURCE:
1222
        case IP_ADD_SOURCE_MEMBERSHIP:
1223
        case IP_DROP_SOURCE_MEMBERSHIP:
1224
            if (optlen != sizeof (struct target_ip_mreq_source))
1225
                return -TARGET_EINVAL;
1226

    
1227
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1228
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1229
            unlock_user (ip_mreq_source, optval_addr, 0);
1230
            break;
1231

    
1232
        default:
1233
            goto unimplemented;
1234
        }
1235
        break;
1236
    case TARGET_SOL_SOCKET:
1237
        switch (optname) {
1238
            /* Options with 'int' argument.  */
1239
        case TARGET_SO_DEBUG:
1240
                optname = SO_DEBUG;
1241
                break;
1242
        case TARGET_SO_REUSEADDR:
1243
                optname = SO_REUSEADDR;
1244
                break;
1245
        case TARGET_SO_TYPE:
1246
                optname = SO_TYPE;
1247
                break;
1248
        case TARGET_SO_ERROR:
1249
                optname = SO_ERROR;
1250
                break;
1251
        case TARGET_SO_DONTROUTE:
1252
                optname = SO_DONTROUTE;
1253
                break;
1254
        case TARGET_SO_BROADCAST:
1255
                optname = SO_BROADCAST;
1256
                break;
1257
        case TARGET_SO_SNDBUF:
1258
                optname = SO_SNDBUF;
1259
                break;
1260
        case TARGET_SO_RCVBUF:
1261
                optname = SO_RCVBUF;
1262
                break;
1263
        case TARGET_SO_KEEPALIVE:
1264
                optname = SO_KEEPALIVE;
1265
                break;
1266
        case TARGET_SO_OOBINLINE:
1267
                optname = SO_OOBINLINE;
1268
                break;
1269
        case TARGET_SO_NO_CHECK:
1270
                optname = SO_NO_CHECK;
1271
                break;
1272
        case TARGET_SO_PRIORITY:
1273
                optname = SO_PRIORITY;
1274
                break;
1275
#ifdef SO_BSDCOMPAT
1276
        case TARGET_SO_BSDCOMPAT:
1277
                optname = SO_BSDCOMPAT;
1278
                break;
1279
#endif
1280
        case TARGET_SO_PASSCRED:
1281
                optname = SO_PASSCRED;
1282
                break;
1283
        case TARGET_SO_TIMESTAMP:
1284
                optname = SO_TIMESTAMP;
1285
                break;
1286
        case TARGET_SO_RCVLOWAT:
1287
                optname = SO_RCVLOWAT;
1288
                break;
1289
        case TARGET_SO_RCVTIMEO:
1290
                optname = SO_RCVTIMEO;
1291
                break;
1292
        case TARGET_SO_SNDTIMEO:
1293
                optname = SO_SNDTIMEO;
1294
                break;
1295
            break;
1296
        default:
1297
            goto unimplemented;
1298
        }
1299
        if (optlen < sizeof(uint32_t))
1300
            return -TARGET_EINVAL;
1301

    
1302
        if (get_user_u32(val, optval_addr))
1303
            return -TARGET_EFAULT;
1304
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1305
        break;
1306
    default:
1307
    unimplemented:
1308
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1309
        ret = -TARGET_ENOPROTOOPT;
1310
    }
1311
    return ret;
1312
}
1313

    
1314
/* do_getsockopt() Must return target values and target errnos. */
1315
static abi_long do_getsockopt(int sockfd, int level, int optname,
1316
                              abi_ulong optval_addr, abi_ulong optlen)
1317
{
1318
    abi_long ret;
1319
    int len, val;
1320
    socklen_t lv;
1321

    
1322
    switch(level) {
1323
    case TARGET_SOL_SOCKET:
1324
            level = SOL_SOCKET;
1325
        switch (optname) {
1326
        case TARGET_SO_LINGER:
1327
        case TARGET_SO_RCVTIMEO:
1328
        case TARGET_SO_SNDTIMEO:
1329
        case TARGET_SO_PEERCRED:
1330
        case TARGET_SO_PEERNAME:
1331
            /* These don't just return a single integer */
1332
            goto unimplemented;
1333
        default:
1334
            goto int_case;
1335
        }
1336
        break;
1337
    case SOL_TCP:
1338
        /* TCP options all take an 'int' value.  */
1339
    int_case:
1340
        if (get_user_u32(len, optlen))
1341
            return -TARGET_EFAULT;
1342
        if (len < 0)
1343
            return -TARGET_EINVAL;
1344
        lv = sizeof(int);
1345
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1346
        if (ret < 0)
1347
            return ret;
1348
        if (len > lv)
1349
            len = lv;
1350
        if (len == 4) {
1351
            if (put_user_u32(val, optval_addr))
1352
                return -TARGET_EFAULT;
1353
        } else {
1354
            if (put_user_u8(val, optval_addr))
1355
                return -TARGET_EFAULT;
1356
        }
1357
        if (put_user_u32(len, optlen))
1358
            return -TARGET_EFAULT;
1359
        break;
1360
    case SOL_IP:
1361
        switch(optname) {
1362
        case IP_TOS:
1363
        case IP_TTL:
1364
        case IP_HDRINCL:
1365
        case IP_ROUTER_ALERT:
1366
        case IP_RECVOPTS:
1367
        case IP_RETOPTS:
1368
        case IP_PKTINFO:
1369
        case IP_MTU_DISCOVER:
1370
        case IP_RECVERR:
1371
        case IP_RECVTOS:
1372
#ifdef IP_FREEBIND
1373
        case IP_FREEBIND:
1374
#endif
1375
        case IP_MULTICAST_TTL:
1376
        case IP_MULTICAST_LOOP:
1377
            if (get_user_u32(len, optlen))
1378
                return -TARGET_EFAULT;
1379
            if (len < 0)
1380
                return -TARGET_EINVAL;
1381
            lv = sizeof(int);
1382
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1383
            if (ret < 0)
1384
                return ret;
1385
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1386
                len = 1;
1387
                if (put_user_u32(len, optlen)
1388
                    || put_user_u8(val, optval_addr))
1389
                    return -TARGET_EFAULT;
1390
            } else {
1391
                if (len > sizeof(int))
1392
                    len = sizeof(int);
1393
                if (put_user_u32(len, optlen)
1394
                    || put_user_u32(val, optval_addr))
1395
                    return -TARGET_EFAULT;
1396
            }
1397
            break;
1398
        default:
1399
            ret = -TARGET_ENOPROTOOPT;
1400
            break;
1401
        }
1402
        break;
1403
    default:
1404
    unimplemented:
1405
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1406
                 level, optname);
1407
        ret = -TARGET_EOPNOTSUPP;
1408
        break;
1409
    }
1410
    return ret;
1411
}
1412

    
1413
/* FIXME
1414
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1415
 * other lock functions have a return code of 0 for failure.
1416
 */
1417
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1418
                           int count, int copy)
1419
{
1420
    struct target_iovec *target_vec;
1421
    abi_ulong base;
1422
    int i;
1423

    
1424
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1425
    if (!target_vec)
1426
        return -TARGET_EFAULT;
1427
    for(i = 0;i < count; i++) {
1428
        base = tswapl(target_vec[i].iov_base);
1429
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1430
        if (vec[i].iov_len != 0) {
1431
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1432
            /* Don't check lock_user return value. We must call writev even
1433
               if a element has invalid base address. */
1434
        } else {
1435
            /* zero length pointer is ignored */
1436
            vec[i].iov_base = NULL;
1437
        }
1438
    }
1439
    unlock_user (target_vec, target_addr, 0);
1440
    return 0;
1441
}
1442

    
1443
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1444
                             int count, int copy)
1445
{
1446
    struct target_iovec *target_vec;
1447
    abi_ulong base;
1448
    int i;
1449

    
1450
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1451
    if (!target_vec)
1452
        return -TARGET_EFAULT;
1453
    for(i = 0;i < count; i++) {
1454
        if (target_vec[i].iov_base) {
1455
            base = tswapl(target_vec[i].iov_base);
1456
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1457
        }
1458
    }
1459
    unlock_user (target_vec, target_addr, 0);
1460

    
1461
    return 0;
1462
}
1463

    
1464
/* do_socket() Must return target values and target errnos. */
1465
static abi_long do_socket(int domain, int type, int protocol)
1466
{
1467
#if defined(TARGET_MIPS)
1468
    switch(type) {
1469
    case TARGET_SOCK_DGRAM:
1470
        type = SOCK_DGRAM;
1471
        break;
1472
    case TARGET_SOCK_STREAM:
1473
        type = SOCK_STREAM;
1474
        break;
1475
    case TARGET_SOCK_RAW:
1476
        type = SOCK_RAW;
1477
        break;
1478
    case TARGET_SOCK_RDM:
1479
        type = SOCK_RDM;
1480
        break;
1481
    case TARGET_SOCK_SEQPACKET:
1482
        type = SOCK_SEQPACKET;
1483
        break;
1484
    case TARGET_SOCK_PACKET:
1485
        type = SOCK_PACKET;
1486
        break;
1487
    }
1488
#endif
1489
    if (domain == PF_NETLINK)
1490
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1491
    return get_errno(socket(domain, type, protocol));
1492
}
1493

    
1494
/* do_bind() Must return target values and target errnos. */
1495
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1496
                        socklen_t addrlen)
1497
{
1498
    void *addr;
1499
    abi_long ret;
1500

    
1501
    if (addrlen < 0)
1502
        return -TARGET_EINVAL;
1503

    
1504
    addr = alloca(addrlen+1);
1505

    
1506
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1507
    if (ret)
1508
        return ret;
1509

    
1510
    return get_errno(bind(sockfd, addr, addrlen));
1511
}
1512

    
1513
/* do_connect() Must return target values and target errnos. */
1514
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1515
                           socklen_t addrlen)
1516
{
1517
    void *addr;
1518
    abi_long ret;
1519

    
1520
    if (addrlen < 0)
1521
        return -TARGET_EINVAL;
1522

    
1523
    addr = alloca(addrlen);
1524

    
1525
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1526
    if (ret)
1527
        return ret;
1528

    
1529
    return get_errno(connect(sockfd, addr, addrlen));
1530
}
1531

    
1532
/* do_sendrecvmsg() Must return target values and target errnos. */
1533
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1534
                               int flags, int send)
1535
{
1536
    abi_long ret, len;
1537
    struct target_msghdr *msgp;
1538
    struct msghdr msg;
1539
    int count;
1540
    struct iovec *vec;
1541
    abi_ulong target_vec;
1542

    
1543
    /* FIXME */
1544
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1545
                          msgp,
1546
                          target_msg,
1547
                          send ? 1 : 0))
1548
        return -TARGET_EFAULT;
1549
    if (msgp->msg_name) {
1550
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1551
        msg.msg_name = alloca(msg.msg_namelen);
1552
        ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1553
                                msg.msg_namelen);
1554
        if (ret) {
1555
            unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1556
            return ret;
1557
        }
1558
    } else {
1559
        msg.msg_name = NULL;
1560
        msg.msg_namelen = 0;
1561
    }
1562
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1563
    msg.msg_control = alloca(msg.msg_controllen);
1564
    msg.msg_flags = tswap32(msgp->msg_flags);
1565

    
1566
    count = tswapl(msgp->msg_iovlen);
1567
    vec = alloca(count * sizeof(struct iovec));
1568
    target_vec = tswapl(msgp->msg_iov);
1569
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1570
    msg.msg_iovlen = count;
1571
    msg.msg_iov = vec;
1572

    
1573
    if (send) {
1574
        ret = target_to_host_cmsg(&msg, msgp);
1575
        if (ret == 0)
1576
            ret = get_errno(sendmsg(fd, &msg, flags));
1577
    } else {
1578
        ret = get_errno(recvmsg(fd, &msg, flags));
1579
        if (!is_error(ret)) {
1580
            len = ret;
1581
            ret = host_to_target_cmsg(msgp, &msg);
1582
            if (!is_error(ret))
1583
                ret = len;
1584
        }
1585
    }
1586
    unlock_iovec(vec, target_vec, count, !send);
1587
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1588
    return ret;
1589
}
1590

    
1591
/* do_accept() Must return target values and target errnos. */
1592
static abi_long do_accept(int fd, abi_ulong target_addr,
1593
                          abi_ulong target_addrlen_addr)
1594
{
1595
    socklen_t addrlen;
1596
    void *addr;
1597
    abi_long ret;
1598

    
1599
    if (target_addr == 0)
1600
       return get_errno(accept(fd, NULL, NULL));
1601

    
1602
    /* linux returns EINVAL if addrlen pointer is invalid */
1603
    if (get_user_u32(addrlen, target_addrlen_addr))
1604
        return -TARGET_EINVAL;
1605

    
1606
    if (addrlen < 0)
1607
        return -TARGET_EINVAL;
1608

    
1609
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1610
        return -TARGET_EINVAL;
1611

    
1612
    addr = alloca(addrlen);
1613

    
1614
    ret = get_errno(accept(fd, addr, &addrlen));
1615
    if (!is_error(ret)) {
1616
        host_to_target_sockaddr(target_addr, addr, addrlen);
1617
        if (put_user_u32(addrlen, target_addrlen_addr))
1618
            ret = -TARGET_EFAULT;
1619
    }
1620
    return ret;
1621
}
1622

    
1623
/* do_getpeername() Must return target values and target errnos. */
1624
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1625
                               abi_ulong target_addrlen_addr)
1626
{
1627
    socklen_t addrlen;
1628
    void *addr;
1629
    abi_long ret;
1630

    
1631
    if (get_user_u32(addrlen, target_addrlen_addr))
1632
        return -TARGET_EFAULT;
1633

    
1634
    if (addrlen < 0)
1635
        return -TARGET_EINVAL;
1636

    
1637
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1638
        return -TARGET_EFAULT;
1639

    
1640
    addr = alloca(addrlen);
1641

    
1642
    ret = get_errno(getpeername(fd, addr, &addrlen));
1643
    if (!is_error(ret)) {
1644
        host_to_target_sockaddr(target_addr, addr, addrlen);
1645
        if (put_user_u32(addrlen, target_addrlen_addr))
1646
            ret = -TARGET_EFAULT;
1647
    }
1648
    return ret;
1649
}
1650

    
1651
/* do_getsockname() Must return target values and target errnos. */
1652
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1653
                               abi_ulong target_addrlen_addr)
1654
{
1655
    socklen_t addrlen;
1656
    void *addr;
1657
    abi_long ret;
1658

    
1659
    if (get_user_u32(addrlen, target_addrlen_addr))
1660
        return -TARGET_EFAULT;
1661

    
1662
    if (addrlen < 0)
1663
        return -TARGET_EINVAL;
1664

    
1665
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1666
        return -TARGET_EFAULT;
1667

    
1668
    addr = alloca(addrlen);
1669

    
1670
    ret = get_errno(getsockname(fd, addr, &addrlen));
1671
    if (!is_error(ret)) {
1672
        host_to_target_sockaddr(target_addr, addr, addrlen);
1673
        if (put_user_u32(addrlen, target_addrlen_addr))
1674
            ret = -TARGET_EFAULT;
1675
    }
1676
    return ret;
1677
}
1678

    
1679
/* do_socketpair() Must return target values and target errnos. */
1680
static abi_long do_socketpair(int domain, int type, int protocol,
1681
                              abi_ulong target_tab_addr)
1682
{
1683
    int tab[2];
1684
    abi_long ret;
1685

    
1686
    ret = get_errno(socketpair(domain, type, protocol, tab));
1687
    if (!is_error(ret)) {
1688
        if (put_user_s32(tab[0], target_tab_addr)
1689
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1690
            ret = -TARGET_EFAULT;
1691
    }
1692
    return ret;
1693
}
1694

    
1695
/* do_sendto() Must return target values and target errnos. */
1696
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1697
                          abi_ulong target_addr, socklen_t addrlen)
1698
{
1699
    void *addr;
1700
    void *host_msg;
1701
    abi_long ret;
1702

    
1703
    if (addrlen < 0)
1704
        return -TARGET_EINVAL;
1705

    
1706
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1707
    if (!host_msg)
1708
        return -TARGET_EFAULT;
1709
    if (target_addr) {
1710
        addr = alloca(addrlen);
1711
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1712
        if (ret) {
1713
            unlock_user(host_msg, msg, 0);
1714
            return ret;
1715
        }
1716
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1717
    } else {
1718
        ret = get_errno(send(fd, host_msg, len, flags));
1719
    }
1720
    unlock_user(host_msg, msg, 0);
1721
    return ret;
1722
}
1723

    
1724
/* do_recvfrom() Must return target values and target errnos. */
1725
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1726
                            abi_ulong target_addr,
1727
                            abi_ulong target_addrlen)
1728
{
1729
    socklen_t addrlen;
1730
    void *addr;
1731
    void *host_msg;
1732
    abi_long ret;
1733

    
1734
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1735
    if (!host_msg)
1736
        return -TARGET_EFAULT;
1737
    if (target_addr) {
1738
        if (get_user_u32(addrlen, target_addrlen)) {
1739
            ret = -TARGET_EFAULT;
1740
            goto fail;
1741
        }
1742
        if (addrlen < 0) {
1743
            ret = -TARGET_EINVAL;
1744
            goto fail;
1745
        }
1746
        addr = alloca(addrlen);
1747
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1748
    } else {
1749
        addr = NULL; /* To keep compiler quiet.  */
1750
        ret = get_errno(recv(fd, host_msg, len, flags));
1751
    }
1752
    if (!is_error(ret)) {
1753
        if (target_addr) {
1754
            host_to_target_sockaddr(target_addr, addr, addrlen);
1755
            if (put_user_u32(addrlen, target_addrlen)) {
1756
                ret = -TARGET_EFAULT;
1757
                goto fail;
1758
            }
1759
        }
1760
        unlock_user(host_msg, msg, len);
1761
    } else {
1762
fail:
1763
        unlock_user(host_msg, msg, 0);
1764
    }
1765
    return ret;
1766
}
1767

    
1768
#ifdef TARGET_NR_socketcall
1769
/* do_socketcall() Must return target values and target errnos. */
1770
static abi_long do_socketcall(int num, abi_ulong vptr)
1771
{
1772
    abi_long ret;
1773
    const int n = sizeof(abi_ulong);
1774

    
1775
    switch(num) {
1776
    case SOCKOP_socket:
1777
        {
1778
            abi_ulong domain, type, protocol;
1779

    
1780
            if (get_user_ual(domain, vptr)
1781
                || get_user_ual(type, vptr + n)
1782
                || get_user_ual(protocol, vptr + 2 * n))
1783
                return -TARGET_EFAULT;
1784

    
1785
            ret = do_socket(domain, type, protocol);
1786
        }
1787
        break;
1788
    case SOCKOP_bind:
1789
        {
1790
            abi_ulong sockfd;
1791
            abi_ulong target_addr;
1792
            socklen_t addrlen;
1793

    
1794
            if (get_user_ual(sockfd, vptr)
1795
                || get_user_ual(target_addr, vptr + n)
1796
                || get_user_ual(addrlen, vptr + 2 * n))
1797
                return -TARGET_EFAULT;
1798

    
1799
            ret = do_bind(sockfd, target_addr, addrlen);
1800
        }
1801
        break;
1802
    case SOCKOP_connect:
1803
        {
1804
            abi_ulong sockfd;
1805
            abi_ulong target_addr;
1806
            socklen_t addrlen;
1807

    
1808
            if (get_user_ual(sockfd, vptr)
1809
                || get_user_ual(target_addr, vptr + n)
1810
                || get_user_ual(addrlen, vptr + 2 * n))
1811
                return -TARGET_EFAULT;
1812

    
1813
            ret = do_connect(sockfd, target_addr, addrlen);
1814
        }
1815
        break;
1816
    case SOCKOP_listen:
1817
        {
1818
            abi_ulong sockfd, backlog;
1819

    
1820
            if (get_user_ual(sockfd, vptr)
1821
                || get_user_ual(backlog, vptr + n))
1822
                return -TARGET_EFAULT;
1823

    
1824
            ret = get_errno(listen(sockfd, backlog));
1825
        }
1826
        break;
1827
    case SOCKOP_accept:
1828
        {
1829
            abi_ulong sockfd;
1830
            abi_ulong target_addr, target_addrlen;
1831

    
1832
            if (get_user_ual(sockfd, vptr)
1833
                || get_user_ual(target_addr, vptr + n)
1834
                || get_user_ual(target_addrlen, vptr + 2 * n))
1835
                return -TARGET_EFAULT;
1836

    
1837
            ret = do_accept(sockfd, target_addr, target_addrlen);
1838
        }
1839
        break;
1840
    case SOCKOP_getsockname:
1841
        {
1842
            abi_ulong sockfd;
1843
            abi_ulong target_addr, target_addrlen;
1844

    
1845
            if (get_user_ual(sockfd, vptr)
1846
                || get_user_ual(target_addr, vptr + n)
1847
                || get_user_ual(target_addrlen, vptr + 2 * n))
1848
                return -TARGET_EFAULT;
1849

    
1850
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
1851
        }
1852
        break;
1853
    case SOCKOP_getpeername:
1854
        {
1855
            abi_ulong sockfd;
1856
            abi_ulong target_addr, target_addrlen;
1857

    
1858
            if (get_user_ual(sockfd, vptr)
1859
                || get_user_ual(target_addr, vptr + n)
1860
                || get_user_ual(target_addrlen, vptr + 2 * n))
1861
                return -TARGET_EFAULT;
1862

    
1863
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
1864
        }
1865
        break;
1866
    case SOCKOP_socketpair:
1867
        {
1868
            abi_ulong domain, type, protocol;
1869
            abi_ulong tab;
1870

    
1871
            if (get_user_ual(domain, vptr)
1872
                || get_user_ual(type, vptr + n)
1873
                || get_user_ual(protocol, vptr + 2 * n)
1874
                || get_user_ual(tab, vptr + 3 * n))
1875
                return -TARGET_EFAULT;
1876

    
1877
            ret = do_socketpair(domain, type, protocol, tab);
1878
        }
1879
        break;
1880
    case SOCKOP_send:
1881
        {
1882
            abi_ulong sockfd;
1883
            abi_ulong msg;
1884
            size_t len;
1885
            abi_ulong flags;
1886

    
1887
            if (get_user_ual(sockfd, vptr)
1888
                || get_user_ual(msg, vptr + n)
1889
                || get_user_ual(len, vptr + 2 * n)
1890
                || get_user_ual(flags, vptr + 3 * n))
1891
                return -TARGET_EFAULT;
1892

    
1893
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
1894
        }
1895
        break;
1896
    case SOCKOP_recv:
1897
        {
1898
            abi_ulong sockfd;
1899
            abi_ulong msg;
1900
            size_t len;
1901
            abi_ulong flags;
1902

    
1903
            if (get_user_ual(sockfd, vptr)
1904
                || get_user_ual(msg, vptr + n)
1905
                || get_user_ual(len, vptr + 2 * n)
1906
                || get_user_ual(flags, vptr + 3 * n))
1907
                return -TARGET_EFAULT;
1908

    
1909
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
1910
        }
1911
        break;
1912
    case SOCKOP_sendto:
1913
        {
1914
            abi_ulong sockfd;
1915
            abi_ulong msg;
1916
            size_t len;
1917
            abi_ulong flags;
1918
            abi_ulong addr;
1919
            socklen_t addrlen;
1920

    
1921
            if (get_user_ual(sockfd, vptr)
1922
                || get_user_ual(msg, vptr + n)
1923
                || get_user_ual(len, vptr + 2 * n)
1924
                || get_user_ual(flags, vptr + 3 * n)
1925
                || get_user_ual(addr, vptr + 4 * n)
1926
                || get_user_ual(addrlen, vptr + 5 * n))
1927
                return -TARGET_EFAULT;
1928

    
1929
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
1930
        }
1931
        break;
1932
    case SOCKOP_recvfrom:
1933
        {
1934
            abi_ulong sockfd;
1935
            abi_ulong msg;
1936
            size_t len;
1937
            abi_ulong flags;
1938
            abi_ulong addr;
1939
            socklen_t addrlen;
1940

    
1941
            if (get_user_ual(sockfd, vptr)
1942
                || get_user_ual(msg, vptr + n)
1943
                || get_user_ual(len, vptr + 2 * n)
1944
                || get_user_ual(flags, vptr + 3 * n)
1945
                || get_user_ual(addr, vptr + 4 * n)
1946
                || get_user_ual(addrlen, vptr + 5 * n))
1947
                return -TARGET_EFAULT;
1948

    
1949
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
1950
        }
1951
        break;
1952
    case SOCKOP_shutdown:
1953
        {
1954
            abi_ulong sockfd, how;
1955

    
1956
            if (get_user_ual(sockfd, vptr)
1957
                || get_user_ual(how, vptr + n))
1958
                return -TARGET_EFAULT;
1959

    
1960
            ret = get_errno(shutdown(sockfd, how));
1961
        }
1962
        break;
1963
    case SOCKOP_sendmsg:
1964
    case SOCKOP_recvmsg:
1965
        {
1966
            abi_ulong fd;
1967
            abi_ulong target_msg;
1968
            abi_ulong flags;
1969

    
1970
            if (get_user_ual(fd, vptr)
1971
                || get_user_ual(target_msg, vptr + n)
1972
                || get_user_ual(flags, vptr + 2 * n))
1973
                return -TARGET_EFAULT;
1974

    
1975
            ret = do_sendrecvmsg(fd, target_msg, flags,
1976
                                 (num == SOCKOP_sendmsg));
1977
        }
1978
        break;
1979
    case SOCKOP_setsockopt:
1980
        {
1981
            abi_ulong sockfd;
1982
            abi_ulong level;
1983
            abi_ulong optname;
1984
            abi_ulong optval;
1985
            socklen_t optlen;
1986

    
1987
            if (get_user_ual(sockfd, vptr)
1988
                || get_user_ual(level, vptr + n)
1989
                || get_user_ual(optname, vptr + 2 * n)
1990
                || get_user_ual(optval, vptr + 3 * n)
1991
                || get_user_ual(optlen, vptr + 4 * n))
1992
                return -TARGET_EFAULT;
1993

    
1994
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
1995
        }
1996
        break;
1997
    case SOCKOP_getsockopt:
1998
        {
1999
            abi_ulong sockfd;
2000
            abi_ulong level;
2001
            abi_ulong optname;
2002
            abi_ulong optval;
2003
            socklen_t optlen;
2004

    
2005
            if (get_user_ual(sockfd, vptr)
2006
                || get_user_ual(level, vptr + n)
2007
                || get_user_ual(optname, vptr + 2 * n)
2008
                || get_user_ual(optval, vptr + 3 * n)
2009
                || get_user_ual(optlen, vptr + 4 * n))
2010
                return -TARGET_EFAULT;
2011

    
2012
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2013
        }
2014
        break;
2015
    default:
2016
        gemu_log("Unsupported socketcall: %d\n", num);
2017
        ret = -TARGET_ENOSYS;
2018
        break;
2019
    }
2020
    return ret;
2021
}
2022
#endif
2023

    
2024
#define N_SHM_REGIONS        32
2025

    
2026
static struct shm_region {
2027
    abi_ulong        start;
2028
    abi_ulong        size;
2029
} shm_regions[N_SHM_REGIONS];
2030

    
2031
struct target_ipc_perm
2032
{
2033
    abi_long __key;
2034
    abi_ulong uid;
2035
    abi_ulong gid;
2036
    abi_ulong cuid;
2037
    abi_ulong cgid;
2038
    unsigned short int mode;
2039
    unsigned short int __pad1;
2040
    unsigned short int __seq;
2041
    unsigned short int __pad2;
2042
    abi_ulong __unused1;
2043
    abi_ulong __unused2;
2044
};
2045

    
2046
struct target_semid_ds
2047
{
2048
  struct target_ipc_perm sem_perm;
2049
  abi_ulong sem_otime;
2050
  abi_ulong __unused1;
2051
  abi_ulong sem_ctime;
2052
  abi_ulong __unused2;
2053
  abi_ulong sem_nsems;
2054
  abi_ulong __unused3;
2055
  abi_ulong __unused4;
2056
};
2057

    
2058
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2059
                                               abi_ulong target_addr)
2060
{
2061
    struct target_ipc_perm *target_ip;
2062
    struct target_semid_ds *target_sd;
2063

    
2064
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2065
        return -TARGET_EFAULT;
2066
    target_ip=&(target_sd->sem_perm);
2067
    host_ip->__key = tswapl(target_ip->__key);
2068
    host_ip->uid = tswapl(target_ip->uid);
2069
    host_ip->gid = tswapl(target_ip->gid);
2070
    host_ip->cuid = tswapl(target_ip->cuid);
2071
    host_ip->cgid = tswapl(target_ip->cgid);
2072
    host_ip->mode = tswapl(target_ip->mode);
2073
    unlock_user_struct(target_sd, target_addr, 0);
2074
    return 0;
2075
}
2076

    
2077
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2078
                                               struct ipc_perm *host_ip)
2079
{
2080
    struct target_ipc_perm *target_ip;
2081
    struct target_semid_ds *target_sd;
2082

    
2083
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2084
        return -TARGET_EFAULT;
2085
    target_ip = &(target_sd->sem_perm);
2086
    target_ip->__key = tswapl(host_ip->__key);
2087
    target_ip->uid = tswapl(host_ip->uid);
2088
    target_ip->gid = tswapl(host_ip->gid);
2089
    target_ip->cuid = tswapl(host_ip->cuid);
2090
    target_ip->cgid = tswapl(host_ip->cgid);
2091
    target_ip->mode = tswapl(host_ip->mode);
2092
    unlock_user_struct(target_sd, target_addr, 1);
2093
    return 0;
2094
}
2095

    
2096
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2097
                                               abi_ulong target_addr)
2098
{
2099
    struct target_semid_ds *target_sd;
2100

    
2101
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2102
        return -TARGET_EFAULT;
2103
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2104
        return -TARGET_EFAULT;
2105
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2106
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
2107
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2108
    unlock_user_struct(target_sd, target_addr, 0);
2109
    return 0;
2110
}
2111

    
2112
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2113
                                               struct semid_ds *host_sd)
2114
{
2115
    struct target_semid_ds *target_sd;
2116

    
2117
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2118
        return -TARGET_EFAULT;
2119
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2120
        return -TARGET_EFAULT;;
2121
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2122
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2123
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2124
    unlock_user_struct(target_sd, target_addr, 1);
2125
    return 0;
2126
}
2127

    
2128
struct target_seminfo {
2129
    int semmap;
2130
    int semmni;
2131
    int semmns;
2132
    int semmnu;
2133
    int semmsl;
2134
    int semopm;
2135
    int semume;
2136
    int semusz;
2137
    int semvmx;
2138
    int semaem;
2139
};
2140

    
2141
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2142
                                              struct seminfo *host_seminfo)
2143
{
2144
    struct target_seminfo *target_seminfo;
2145
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2146
        return -TARGET_EFAULT;
2147
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2148
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2149
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2150
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2151
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2152
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2153
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2154
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2155
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2156
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2157
    unlock_user_struct(target_seminfo, target_addr, 1);
2158
    return 0;
2159
}
2160

    
2161
union semun {
2162
        int val;
2163
        struct semid_ds *buf;
2164
        unsigned short *array;
2165
        struct seminfo *__buf;
2166
};
2167

    
2168
union target_semun {
2169
        int val;
2170
        abi_ulong buf;
2171
        abi_ulong array;
2172
        abi_ulong __buf;
2173
};
2174

    
2175
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2176
                                               abi_ulong target_addr)
2177
{
2178
    int nsems;
2179
    unsigned short *array;
2180
    union semun semun;
2181
    struct semid_ds semid_ds;
2182
    int i, ret;
2183

    
2184
    semun.buf = &semid_ds;
2185

    
2186
    ret = semctl(semid, 0, IPC_STAT, semun);
2187
    if (ret == -1)
2188
        return get_errno(ret);
2189

    
2190
    nsems = semid_ds.sem_nsems;
2191

    
2192
    *host_array = malloc(nsems*sizeof(unsigned short));
2193
    array = lock_user(VERIFY_READ, target_addr,
2194
                      nsems*sizeof(unsigned short), 1);
2195
    if (!array)
2196
        return -TARGET_EFAULT;
2197

    
2198
    for(i=0; i<nsems; i++) {
2199
        __get_user((*host_array)[i], &array[i]);
2200
    }
2201
    unlock_user(array, target_addr, 0);
2202

    
2203
    return 0;
2204
}
2205

    
2206
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2207
                                               unsigned short **host_array)
2208
{
2209
    int nsems;
2210
    unsigned short *array;
2211
    union semun semun;
2212
    struct semid_ds semid_ds;
2213
    int i, ret;
2214

    
2215
    semun.buf = &semid_ds;
2216

    
2217
    ret = semctl(semid, 0, IPC_STAT, semun);
2218
    if (ret == -1)
2219
        return get_errno(ret);
2220

    
2221
    nsems = semid_ds.sem_nsems;
2222

    
2223
    array = lock_user(VERIFY_WRITE, target_addr,
2224
                      nsems*sizeof(unsigned short), 0);
2225
    if (!array)
2226
        return -TARGET_EFAULT;
2227

    
2228
    for(i=0; i<nsems; i++) {
2229
        __put_user((*host_array)[i], &array[i]);
2230
    }
2231
    free(*host_array);
2232
    unlock_user(array, target_addr, 1);
2233

    
2234
    return 0;
2235
}
2236

    
2237
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2238
                                 union target_semun target_su)
2239
{
2240
    union semun arg;
2241
    struct semid_ds dsarg;
2242
    unsigned short *array = NULL;
2243
    struct seminfo seminfo;
2244
    abi_long ret = -TARGET_EINVAL;
2245
    abi_long err;
2246
    cmd &= 0xff;
2247

    
2248
    switch( cmd ) {
2249
        case GETVAL:
2250
        case SETVAL:
2251
            arg.val = tswapl(target_su.val);
2252
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2253
            target_su.val = tswapl(arg.val);
2254
            break;
2255
        case GETALL:
2256
        case SETALL:
2257
            err = target_to_host_semarray(semid, &array, target_su.array);
2258
            if (err)
2259
                return err;
2260
            arg.array = array;
2261
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2262
            err = host_to_target_semarray(semid, target_su.array, &array);
2263
            if (err)
2264
                return err;
2265
            break;
2266
        case IPC_STAT:
2267
        case IPC_SET:
2268
        case SEM_STAT:
2269
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2270
            if (err)
2271
                return err;
2272
            arg.buf = &dsarg;
2273
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2274
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2275
            if (err)
2276
                return err;
2277
            break;
2278
        case IPC_INFO:
2279
        case SEM_INFO:
2280
            arg.__buf = &seminfo;
2281
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2282
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2283
            if (err)
2284
                return err;
2285
            break;
2286
        case IPC_RMID:
2287
        case GETPID:
2288
        case GETNCNT:
2289
        case GETZCNT:
2290
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2291
            break;
2292
    }
2293

    
2294
    return ret;
2295
}
2296

    
2297
struct target_sembuf {
2298
    unsigned short sem_num;
2299
    short sem_op;
2300
    short sem_flg;
2301
};
2302

    
2303
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2304
                                             abi_ulong target_addr,
2305
                                             unsigned nsops)
2306
{
2307
    struct target_sembuf *target_sembuf;
2308
    int i;
2309

    
2310
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2311
                              nsops*sizeof(struct target_sembuf), 1);
2312
    if (!target_sembuf)
2313
        return -TARGET_EFAULT;
2314

    
2315
    for(i=0; i<nsops; i++) {
2316
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2317
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2318
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2319
    }
2320

    
2321
    unlock_user(target_sembuf, target_addr, 0);
2322

    
2323
    return 0;
2324
}
2325

    
2326
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2327
{
2328
    struct sembuf sops[nsops];
2329

    
2330
    if (target_to_host_sembuf(sops, ptr, nsops))
2331
        return -TARGET_EFAULT;
2332

    
2333
    return semop(semid, sops, nsops);
2334
}
2335

    
2336
struct target_msqid_ds
2337
{
2338
    struct target_ipc_perm msg_perm;
2339
    abi_ulong msg_stime;
2340
#if TARGET_ABI_BITS == 32
2341
    abi_ulong __unused1;
2342
#endif
2343
    abi_ulong msg_rtime;
2344
#if TARGET_ABI_BITS == 32
2345
    abi_ulong __unused2;
2346
#endif
2347
    abi_ulong msg_ctime;
2348
#if TARGET_ABI_BITS == 32
2349
    abi_ulong __unused3;
2350
#endif
2351
    abi_ulong __msg_cbytes;
2352
    abi_ulong msg_qnum;
2353
    abi_ulong msg_qbytes;
2354
    abi_ulong msg_lspid;
2355
    abi_ulong msg_lrpid;
2356
    abi_ulong __unused4;
2357
    abi_ulong __unused5;
2358
};
2359

    
2360
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2361
                                               abi_ulong target_addr)
2362
{
2363
    struct target_msqid_ds *target_md;
2364

    
2365
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2366
        return -TARGET_EFAULT;
2367
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2368
        return -TARGET_EFAULT;
2369
    host_md->msg_stime = tswapl(target_md->msg_stime);
2370
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2371
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2372
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2373
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2374
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2375
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2376
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2377
    unlock_user_struct(target_md, target_addr, 0);
2378
    return 0;
2379
}
2380

    
2381
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2382
                                               struct msqid_ds *host_md)
2383
{
2384
    struct target_msqid_ds *target_md;
2385

    
2386
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2387
        return -TARGET_EFAULT;
2388
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2389
        return -TARGET_EFAULT;
2390
    target_md->msg_stime = tswapl(host_md->msg_stime);
2391
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2392
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2393
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2394
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2395
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2396
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2397
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2398
    unlock_user_struct(target_md, target_addr, 1);
2399
    return 0;
2400
}
2401

    
2402
struct target_msginfo {
2403
    int msgpool;
2404
    int msgmap;
2405
    int msgmax;
2406
    int msgmnb;
2407
    int msgmni;
2408
    int msgssz;
2409
    int msgtql;
2410
    unsigned short int msgseg;
2411
};
2412

    
2413
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2414
                                              struct msginfo *host_msginfo)
2415
{
2416
    struct target_msginfo *target_msginfo;
2417
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2418
        return -TARGET_EFAULT;
2419
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2420
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2421
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2422
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2423
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2424
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2425
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2426
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2427
    unlock_user_struct(target_msginfo, target_addr, 1);
2428
    return 0;
2429
}
2430

    
2431
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2432
{
2433
    struct msqid_ds dsarg;
2434
    struct msginfo msginfo;
2435
    abi_long ret = -TARGET_EINVAL;
2436

    
2437
    cmd &= 0xff;
2438

    
2439
    switch (cmd) {
2440
    case IPC_STAT:
2441
    case IPC_SET:
2442
    case MSG_STAT:
2443
        if (target_to_host_msqid_ds(&dsarg,ptr))
2444
            return -TARGET_EFAULT;
2445
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2446
        if (host_to_target_msqid_ds(ptr,&dsarg))
2447
            return -TARGET_EFAULT;
2448
        break;
2449
    case IPC_RMID:
2450
        ret = get_errno(msgctl(msgid, cmd, NULL));
2451
        break;
2452
    case IPC_INFO:
2453
    case MSG_INFO:
2454
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2455
        if (host_to_target_msginfo(ptr, &msginfo))
2456
            return -TARGET_EFAULT;
2457
        break;
2458
    }
2459

    
2460
    return ret;
2461
}
2462

    
2463
struct target_msgbuf {
2464
    abi_long mtype;
2465
    char        mtext[1];
2466
};
2467

    
2468
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2469
                                 unsigned int msgsz, int msgflg)
2470
{
2471
    struct target_msgbuf *target_mb;
2472
    struct msgbuf *host_mb;
2473
    abi_long ret = 0;
2474

    
2475
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2476
        return -TARGET_EFAULT;
2477
    host_mb = malloc(msgsz+sizeof(long));
2478
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2479
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2480
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2481
    free(host_mb);
2482
    unlock_user_struct(target_mb, msgp, 0);
2483

    
2484
    return ret;
2485
}
2486

    
2487
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2488
                                 unsigned int msgsz, abi_long msgtyp,
2489
                                 int msgflg)
2490
{
2491
    struct target_msgbuf *target_mb;
2492
    char *target_mtext;
2493
    struct msgbuf *host_mb;
2494
    abi_long ret = 0;
2495

    
2496
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2497
        return -TARGET_EFAULT;
2498

    
2499
    host_mb = malloc(msgsz+sizeof(long));
2500
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2501

    
2502
    if (ret > 0) {
2503
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2504
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2505
        if (!target_mtext) {
2506
            ret = -TARGET_EFAULT;
2507
            goto end;
2508
        }
2509
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2510
        unlock_user(target_mtext, target_mtext_addr, ret);
2511
    }
2512

    
2513
    target_mb->mtype = tswapl(host_mb->mtype);
2514
    free(host_mb);
2515

    
2516
end:
2517
    if (target_mb)
2518
        unlock_user_struct(target_mb, msgp, 1);
2519
    return ret;
2520
}
2521

    
2522
struct target_shmid_ds
2523
{
2524
    struct target_ipc_perm shm_perm;
2525
    abi_ulong shm_segsz;
2526
    abi_ulong shm_atime;
2527
#if TARGET_ABI_BITS == 32
2528
    abi_ulong __unused1;
2529
#endif
2530
    abi_ulong shm_dtime;
2531
#if TARGET_ABI_BITS == 32
2532
    abi_ulong __unused2;
2533
#endif
2534
    abi_ulong shm_ctime;
2535
#if TARGET_ABI_BITS == 32
2536
    abi_ulong __unused3;
2537
#endif
2538
    int shm_cpid;
2539
    int shm_lpid;
2540
    abi_ulong shm_nattch;
2541
    unsigned long int __unused4;
2542
    unsigned long int __unused5;
2543
};
2544

    
2545
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2546
                                               abi_ulong target_addr)
2547
{
2548
    struct target_shmid_ds *target_sd;
2549

    
2550
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2551
        return -TARGET_EFAULT;
2552
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2553
        return -TARGET_EFAULT;
2554
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2555
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2556
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2557
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2558
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2559
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2560
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2561
    unlock_user_struct(target_sd, target_addr, 0);
2562
    return 0;
2563
}
2564

    
2565
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2566
                                               struct shmid_ds *host_sd)
2567
{
2568
    struct target_shmid_ds *target_sd;
2569

    
2570
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2571
        return -TARGET_EFAULT;
2572
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2573
        return -TARGET_EFAULT;
2574
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2575
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2576
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2577
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2578
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2579
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2580
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2581
    unlock_user_struct(target_sd, target_addr, 1);
2582
    return 0;
2583
}
2584

    
2585
struct  target_shminfo {
2586
    abi_ulong shmmax;
2587
    abi_ulong shmmin;
2588
    abi_ulong shmmni;
2589
    abi_ulong shmseg;
2590
    abi_ulong shmall;
2591
};
2592

    
2593
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2594
                                              struct shminfo *host_shminfo)
2595
{
2596
    struct target_shminfo *target_shminfo;
2597
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2598
        return -TARGET_EFAULT;
2599
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2600
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2601
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2602
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2603
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2604
    unlock_user_struct(target_shminfo, target_addr, 1);
2605
    return 0;
2606
}
2607

    
2608
struct target_shm_info {
2609
    int used_ids;
2610
    abi_ulong shm_tot;
2611
    abi_ulong shm_rss;
2612
    abi_ulong shm_swp;
2613
    abi_ulong swap_attempts;
2614
    abi_ulong swap_successes;
2615
};
2616

    
2617
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2618
                                               struct shm_info *host_shm_info)
2619
{
2620
    struct target_shm_info *target_shm_info;
2621
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2622
        return -TARGET_EFAULT;
2623
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2624
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2625
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2626
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2627
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2628
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2629
    unlock_user_struct(target_shm_info, target_addr, 1);
2630
    return 0;
2631
}
2632

    
2633
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2634
{
2635
    struct shmid_ds dsarg;
2636
    struct shminfo shminfo;
2637
    struct shm_info shm_info;
2638
    abi_long ret = -TARGET_EINVAL;
2639

    
2640
    cmd &= 0xff;
2641

    
2642
    switch(cmd) {
2643
    case IPC_STAT:
2644
    case IPC_SET:
2645
    case SHM_STAT:
2646
        if (target_to_host_shmid_ds(&dsarg, buf))
2647
            return -TARGET_EFAULT;
2648
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2649
        if (host_to_target_shmid_ds(buf, &dsarg))
2650
            return -TARGET_EFAULT;
2651
        break;
2652
    case IPC_INFO:
2653
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2654
        if (host_to_target_shminfo(buf, &shminfo))
2655
            return -TARGET_EFAULT;
2656
        break;
2657
    case SHM_INFO:
2658
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2659
        if (host_to_target_shm_info(buf, &shm_info))
2660
            return -TARGET_EFAULT;
2661
        break;
2662
    case IPC_RMID:
2663
    case SHM_LOCK:
2664
    case SHM_UNLOCK:
2665
        ret = get_errno(shmctl(shmid, cmd, NULL));
2666
        break;
2667
    }
2668

    
2669
    return ret;
2670
}
2671

    
2672
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2673
{
2674
    abi_long raddr;
2675
    void *host_raddr;
2676
    struct shmid_ds shm_info;
2677
    int i,ret;
2678

    
2679
    /* find out the length of the shared memory segment */
2680
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2681
    if (is_error(ret)) {
2682
        /* can't get length, bail out */
2683
        return ret;
2684
    }
2685

    
2686
    mmap_lock();
2687

    
2688
    if (shmaddr)
2689
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2690
    else {
2691
        abi_ulong mmap_start;
2692

    
2693
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2694

    
2695
        if (mmap_start == -1) {
2696
            errno = ENOMEM;
2697
            host_raddr = (void *)-1;
2698
        } else
2699
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2700
    }
2701

    
2702
    if (host_raddr == (void *)-1) {
2703
        mmap_unlock();
2704
        return get_errno((long)host_raddr);
2705
    }
2706
    raddr=h2g((unsigned long)host_raddr);
2707

    
2708
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2709
                   PAGE_VALID | PAGE_READ |
2710
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2711

    
2712
    for (i = 0; i < N_SHM_REGIONS; i++) {
2713
        if (shm_regions[i].start == 0) {
2714
            shm_regions[i].start = raddr;
2715
            shm_regions[i].size = shm_info.shm_segsz;
2716
            break;
2717
        }
2718
    }
2719

    
2720
    mmap_unlock();
2721
    return raddr;
2722

    
2723
}
2724

    
2725
static inline abi_long do_shmdt(abi_ulong shmaddr)
2726
{
2727
    int i;
2728

    
2729
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2730
        if (shm_regions[i].start == shmaddr) {
2731
            shm_regions[i].start = 0;
2732
            page_set_flags(shmaddr, shm_regions[i].size, 0);
2733
            break;
2734
        }
2735
    }
2736

    
2737
    return get_errno(shmdt(g2h(shmaddr)));
2738
}
2739

    
2740
#ifdef TARGET_NR_ipc
2741
/* ??? This only works with linear mappings.  */
2742
/* do_ipc() must return target values and target errnos. */
2743
static abi_long do_ipc(unsigned int call, int first,
2744
                       int second, int third,
2745
                       abi_long ptr, abi_long fifth)
2746
{
2747
    int version;
2748
    abi_long ret = 0;
2749

    
2750
    version = call >> 16;
2751
    call &= 0xffff;
2752

    
2753
    switch (call) {
2754
    case IPCOP_semop:
2755
        ret = do_semop(first, ptr, second);
2756
        break;
2757

    
2758
    case IPCOP_semget:
2759
        ret = get_errno(semget(first, second, third));
2760
        break;
2761

    
2762
    case IPCOP_semctl:
2763
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2764
        break;
2765

    
2766
    case IPCOP_msgget:
2767
        ret = get_errno(msgget(first, second));
2768
        break;
2769

    
2770
    case IPCOP_msgsnd:
2771
        ret = do_msgsnd(first, ptr, second, third);
2772
        break;
2773

    
2774
    case IPCOP_msgctl:
2775
        ret = do_msgctl(first, second, ptr);
2776
        break;
2777

    
2778
    case IPCOP_msgrcv:
2779
        switch (version) {
2780
        case 0:
2781
            {
2782
                struct target_ipc_kludge {
2783
                    abi_long msgp;
2784
                    abi_long msgtyp;
2785
                } *tmp;
2786

    
2787
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2788
                    ret = -TARGET_EFAULT;
2789
                    break;
2790
                }
2791

    
2792
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
2793

    
2794
                unlock_user_struct(tmp, ptr, 0);
2795
                break;
2796
            }
2797
        default:
2798
            ret = do_msgrcv(first, ptr, second, fifth, third);
2799
        }
2800
        break;
2801

    
2802
    case IPCOP_shmat:
2803
        switch (version) {
2804
        default:
2805
        {
2806
            abi_ulong raddr;
2807
            raddr = do_shmat(first, ptr, second);
2808
            if (is_error(raddr))
2809
                return get_errno(raddr);
2810
            if (put_user_ual(raddr, third))
2811
                return -TARGET_EFAULT;
2812
            break;
2813
        }
2814
        case 1:
2815
            ret = -TARGET_EINVAL;
2816
            break;
2817
        }
2818
        break;
2819
    case IPCOP_shmdt:
2820
        ret = do_shmdt(ptr);
2821
        break;
2822

    
2823
    case IPCOP_shmget:
2824
        /* IPC_* flag values are the same on all linux platforms */
2825
        ret = get_errno(shmget(first, second, third));
2826
        break;
2827

    
2828
        /* IPC_* and SHM_* command values are the same on all linux platforms */
2829
    case IPCOP_shmctl:
2830
        ret = do_shmctl(first, second, third);
2831
        break;
2832
    default:
2833
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
2834
        ret = -TARGET_ENOSYS;
2835
        break;
2836
    }
2837
    return ret;
2838
}
2839
#endif
2840

    
2841
/* kernel structure types definitions */
2842
#define IFNAMSIZ        16
2843

    
2844
#define STRUCT(name, ...) STRUCT_ ## name,
2845
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
2846
enum {
2847
#include "syscall_types.h"
2848
};
2849
#undef STRUCT
2850
#undef STRUCT_SPECIAL
2851

    
2852
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
2853
#define STRUCT_SPECIAL(name)
2854
#include "syscall_types.h"
2855
#undef STRUCT
2856
#undef STRUCT_SPECIAL
2857

    
2858
typedef struct IOCTLEntry {
2859
    unsigned int target_cmd;
2860
    unsigned int host_cmd;
2861
    const char *name;
2862
    int access;
2863
    const argtype arg_type[5];
2864
} IOCTLEntry;
2865

    
2866
#define IOC_R 0x0001
2867
#define IOC_W 0x0002
2868
#define IOC_RW (IOC_R | IOC_W)
2869

    
2870
#define MAX_STRUCT_SIZE 4096
2871

    
2872
static IOCTLEntry ioctl_entries[] = {
2873
#define IOCTL(cmd, access, ...) \
2874
    { TARGET_ ## cmd, cmd, #cmd, access, {  __VA_ARGS__ } },
2875
#include "ioctls.h"
2876
    { 0, 0, },
2877
};
2878

    
2879
/* ??? Implement proper locking for ioctls.  */
2880
/* do_ioctl() Must return target values and target errnos. */
2881
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
2882
{
2883
    const IOCTLEntry *ie;
2884
    const argtype *arg_type;
2885
    abi_long ret;
2886
    uint8_t buf_temp[MAX_STRUCT_SIZE];
2887
    int target_size;
2888
    void *argptr;
2889

    
2890
    ie = ioctl_entries;
2891
    for(;;) {
2892
        if (ie->target_cmd == 0) {
2893
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
2894
            return -TARGET_ENOSYS;
2895
        }
2896
        if (ie->target_cmd == cmd)
2897
            break;
2898
        ie++;
2899
    }
2900
    arg_type = ie->arg_type;
2901
#if defined(DEBUG)
2902
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
2903
#endif
2904
    switch(arg_type[0]) {
2905
    case TYPE_NULL:
2906
        /* no argument */
2907
        ret = get_errno(ioctl(fd, ie->host_cmd));
2908
        break;
2909
    case TYPE_PTRVOID:
2910
    case TYPE_INT:
2911
        /* int argment */
2912
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
2913
        break;
2914
    case TYPE_PTR:
2915
        arg_type++;
2916
        target_size = thunk_type_size(arg_type, 0);
2917
        switch(ie->access) {
2918
        case IOC_R:
2919
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2920
            if (!is_error(ret)) {
2921
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2922
                if (!argptr)
2923
                    return -TARGET_EFAULT;
2924
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2925
                unlock_user(argptr, arg, target_size);
2926
            }
2927
            break;
2928
        case IOC_W:
2929
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2930
            if (!argptr)
2931
                return -TARGET_EFAULT;
2932
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2933
            unlock_user(argptr, arg, 0);
2934
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2935
            break;
2936
        default:
2937
        case IOC_RW:
2938
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
2939
            if (!argptr)
2940
                return -TARGET_EFAULT;
2941
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
2942
            unlock_user(argptr, arg, 0);
2943
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
2944
            if (!is_error(ret)) {
2945
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
2946
                if (!argptr)
2947
                    return -TARGET_EFAULT;
2948
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
2949
                unlock_user(argptr, arg, target_size);
2950
            }
2951
            break;
2952
        }
2953
        break;
2954
    default:
2955
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
2956
                 (long)cmd, arg_type[0]);
2957
        ret = -TARGET_ENOSYS;
2958
        break;
2959
    }
2960
    return ret;
2961
}
2962

    
2963
static const bitmask_transtbl iflag_tbl[] = {
2964
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
2965
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
2966
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
2967
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
2968
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
2969
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
2970
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
2971
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
2972
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
2973
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
2974
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
2975
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
2976
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
2977
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
2978
        { 0, 0, 0, 0 }
2979
};
2980

    
2981
static const bitmask_transtbl oflag_tbl[] = {
2982
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
2983
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
2984
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
2985
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
2986
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
2987
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
2988
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
2989
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
2990
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
2991
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
2992
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
2993
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
2994
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
2995
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
2996
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
2997
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
2998
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
2999
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3000
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3001
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3002
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3003
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3004
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3005
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3006
        { 0, 0, 0, 0 }
3007
};
3008

    
3009
static const bitmask_transtbl cflag_tbl[] = {
3010
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3011
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3012
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3013
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3014
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3015
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3016
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3017
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3018
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3019
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3020
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3021
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3022
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3023
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3024
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3025
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3026
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3027
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3028
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3029
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3030
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3031
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3032
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3033
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3034
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3035
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3036
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3037
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3038
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3039
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3040
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3041
        { 0, 0, 0, 0 }
3042
};
3043

    
3044
static const bitmask_transtbl lflag_tbl[] = {
3045
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3046
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3047
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3048
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3049
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3050
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3051
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3052
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3053
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3054
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3055
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3056
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3057
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3058
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3059
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3060
        { 0, 0, 0, 0 }
3061
};
3062

    
3063
static void target_to_host_termios (void *dst, const void *src)
3064
{
3065
    struct host_termios *host = dst;
3066
    const struct target_termios *target = src;
3067

    
3068
    host->c_iflag =
3069
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3070
    host->c_oflag =
3071
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3072
    host->c_cflag =
3073
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3074
    host->c_lflag =
3075
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3076
    host->c_line = target->c_line;
3077

    
3078
    memset(host->c_cc, 0, sizeof(host->c_cc));
3079
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3080
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3081
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3082
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3083
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3084
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3085
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3086
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3087
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3088
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3089
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3090
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3091
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3092
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3093
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3094
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3095
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3096
}
3097

    
3098
static void host_to_target_termios (void *dst, const void *src)
3099
{
3100
    struct target_termios *target = dst;
3101
    const struct host_termios *host = src;
3102

    
3103
    target->c_iflag =
3104
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3105
    target->c_oflag =
3106
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3107
    target->c_cflag =
3108
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3109
    target->c_lflag =
3110
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3111
    target->c_line = host->c_line;
3112

    
3113
    memset(target->c_cc, 0, sizeof(target->c_cc));
3114
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3115
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3116
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3117
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3118
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3119
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3120
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3121
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3122
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3123
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3124
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3125
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3126
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3127
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3128
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3129
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3130
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3131
}
3132

    
3133
static const StructEntry struct_termios_def = {
3134
    .convert = { host_to_target_termios, target_to_host_termios },
3135
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3136
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3137
};
3138

    
3139
static bitmask_transtbl mmap_flags_tbl[] = {
3140
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3141
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3142
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3143
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3144
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3145
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3146
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3147
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3148
        { 0, 0, 0, 0 }
3149
};
3150

    
3151
#if defined(TARGET_I386)
3152

    
3153
/* NOTE: there is really one LDT for all the threads */
3154
static uint8_t *ldt_table;
3155

    
3156
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3157
{
3158
    int size;
3159
    void *p;
3160

    
3161
    if (!ldt_table)
3162
        return 0;
3163
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3164
    if (size > bytecount)
3165
        size = bytecount;
3166
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3167
    if (!p)
3168
        return -TARGET_EFAULT;
3169
    /* ??? Should this by byteswapped?  */
3170
    memcpy(p, ldt_table, size);
3171
    unlock_user(p, ptr, size);
3172
    return size;
3173
}
3174

    
3175
/* XXX: add locking support */
3176
static abi_long write_ldt(CPUX86State *env,
3177
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3178
{
3179
    struct target_modify_ldt_ldt_s ldt_info;
3180
    struct target_modify_ldt_ldt_s *target_ldt_info;
3181
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3182
    int seg_not_present, useable, lm;
3183
    uint32_t *lp, entry_1, entry_2;
3184

    
3185
    if (bytecount != sizeof(ldt_info))
3186
        return -TARGET_EINVAL;
3187
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3188
        return -TARGET_EFAULT;
3189
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3190
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3191
    ldt_info.limit = tswap32(target_ldt_info->limit);
3192
    ldt_info.flags = tswap32(target_ldt_info->flags);
3193
    unlock_user_struct(target_ldt_info, ptr, 0);
3194

    
3195
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3196
        return -TARGET_EINVAL;
3197
    seg_32bit = ldt_info.flags & 1;
3198
    contents = (ldt_info.flags >> 1) & 3;
3199
    read_exec_only = (ldt_info.flags >> 3) & 1;
3200
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3201
    seg_not_present = (ldt_info.flags >> 5) & 1;
3202
    useable = (ldt_info.flags >> 6) & 1;
3203
#ifdef TARGET_ABI32
3204
    lm = 0;
3205
#else
3206
    lm = (ldt_info.flags >> 7) & 1;
3207
#endif
3208
    if (contents == 3) {
3209
        if (oldmode)
3210
            return -TARGET_EINVAL;
3211
        if (seg_not_present == 0)
3212
            return -TARGET_EINVAL;
3213
    }
3214
    /* allocate the LDT */
3215
    if (!ldt_table) {
3216
        env->ldt.base = target_mmap(0,
3217
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3218
                                    PROT_READ|PROT_WRITE,
3219
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3220
        if (env->ldt.base == -1)
3221
            return -TARGET_ENOMEM;
3222
        memset(g2h(env->ldt.base), 0,
3223
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3224
        env->ldt.limit = 0xffff;
3225
        ldt_table = g2h(env->ldt.base);
3226
    }
3227

    
3228
    /* NOTE: same code as Linux kernel */
3229
    /* Allow LDTs to be cleared by the user. */
3230
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3231
        if (oldmode ||
3232
            (contents == 0                &&
3233
             read_exec_only == 1        &&
3234
             seg_32bit == 0                &&
3235
             limit_in_pages == 0        &&
3236
             seg_not_present == 1        &&
3237
             useable == 0 )) {
3238
            entry_1 = 0;
3239
            entry_2 = 0;
3240
            goto install;
3241
        }
3242
    }
3243

    
3244
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3245
        (ldt_info.limit & 0x0ffff);
3246
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3247
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3248
        (ldt_info.limit & 0xf0000) |
3249
        ((read_exec_only ^ 1) << 9) |
3250
        (contents << 10) |
3251
        ((seg_not_present ^ 1) << 15) |
3252
        (seg_32bit << 22) |
3253
        (limit_in_pages << 23) |
3254
        (lm << 21) |
3255
        0x7000;
3256
    if (!oldmode)
3257
        entry_2 |= (useable << 20);
3258

    
3259
    /* Install the new entry ...  */
3260
install:
3261
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3262
    lp[0] = tswap32(entry_1);
3263
    lp[1] = tswap32(entry_2);
3264
    return 0;
3265
}
3266

    
3267
/* specific and weird i386 syscalls */
3268
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3269
                              unsigned long bytecount)
3270
{
3271
    abi_long ret;
3272

    
3273
    switch (func) {
3274
    case 0:
3275
        ret = read_ldt(ptr, bytecount);
3276
        break;
3277
    case 1:
3278
        ret = write_ldt(env, ptr, bytecount, 1);
3279
        break;
3280
    case 0x11:
3281
        ret = write_ldt(env, ptr, bytecount, 0);
3282
        break;
3283
    default:
3284
        ret = -TARGET_ENOSYS;
3285
        break;
3286
    }
3287
    return ret;
3288
}
3289

    
3290
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3291
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3292
{
3293
    uint64_t *gdt_table = g2h(env->gdt.base);
3294
    struct target_modify_ldt_ldt_s ldt_info;
3295
    struct target_modify_ldt_ldt_s *target_ldt_info;
3296
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3297
    int seg_not_present, useable, lm;
3298
    uint32_t *lp, entry_1, entry_2;
3299
    int i;
3300

    
3301
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3302
    if (!target_ldt_info)
3303
        return -TARGET_EFAULT;
3304
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3305
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3306
    ldt_info.limit = tswap32(target_ldt_info->limit);
3307
    ldt_info.flags = tswap32(target_ldt_info->flags);
3308
    if (ldt_info.entry_number == -1) {
3309
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3310
            if (gdt_table[i] == 0) {
3311
                ldt_info.entry_number = i;
3312
                target_ldt_info->entry_number = tswap32(i);
3313
                break;
3314
            }
3315
        }
3316
    }
3317
    unlock_user_struct(target_ldt_info, ptr, 1);
3318

    
3319
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3320
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3321
           return -TARGET_EINVAL;
3322
    seg_32bit = ldt_info.flags & 1;
3323
    contents = (ldt_info.flags >> 1) & 3;
3324
    read_exec_only = (ldt_info.flags >> 3) & 1;
3325
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3326
    seg_not_present = (ldt_info.flags >> 5) & 1;
3327
    useable = (ldt_info.flags >> 6) & 1;
3328
#ifdef TARGET_ABI32
3329
    lm = 0;
3330
#else
3331
    lm = (ldt_info.flags >> 7) & 1;
3332
#endif
3333

    
3334
    if (contents == 3) {
3335
        if (seg_not_present == 0)
3336
            return -TARGET_EINVAL;
3337
    }
3338

    
3339
    /* NOTE: same code as Linux kernel */
3340
    /* Allow LDTs to be cleared by the user. */
3341
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3342
        if ((contents == 0             &&
3343
             read_exec_only == 1       &&
3344
             seg_32bit == 0            &&
3345
             limit_in_pages == 0       &&
3346
             seg_not_present == 1      &&
3347
             useable == 0 )) {
3348
            entry_1 = 0;
3349
            entry_2 = 0;
3350
            goto install;
3351
        }
3352
    }
3353

    
3354
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3355
        (ldt_info.limit & 0x0ffff);
3356
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3357
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3358
        (ldt_info.limit & 0xf0000) |
3359
        ((read_exec_only ^ 1) << 9) |
3360
        (contents << 10) |
3361
        ((seg_not_present ^ 1) << 15) |
3362
        (seg_32bit << 22) |
3363
        (limit_in_pages << 23) |
3364
        (useable << 20) |
3365
        (lm << 21) |
3366
        0x7000;
3367

    
3368
    /* Install the new entry ...  */
3369
install:
3370
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3371
    lp[0] = tswap32(entry_1);
3372
    lp[1] = tswap32(entry_2);
3373
    return 0;
3374
}
3375

    
3376
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3377
{
3378
    struct target_modify_ldt_ldt_s *target_ldt_info;
3379
    uint64_t *gdt_table = g2h(env->gdt.base);
3380
    uint32_t base_addr, limit, flags;
3381
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3382
    int seg_not_present, useable, lm;
3383
    uint32_t *lp, entry_1, entry_2;
3384

    
3385
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3386
    if (!target_ldt_info)
3387
        return -TARGET_EFAULT;
3388
    idx = tswap32(target_ldt_info->entry_number);
3389
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3390
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3391
        unlock_user_struct(target_ldt_info, ptr, 1);
3392
        return -TARGET_EINVAL;
3393
    }
3394
    lp = (uint32_t *)(gdt_table + idx);
3395
    entry_1 = tswap32(lp[0]);
3396
    entry_2 = tswap32(lp[1]);
3397
    
3398
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3399
    contents = (entry_2 >> 10) & 3;
3400
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3401
    seg_32bit = (entry_2 >> 22) & 1;
3402
    limit_in_pages = (entry_2 >> 23) & 1;
3403
    useable = (entry_2 >> 20) & 1;
3404
#ifdef TARGET_ABI32
3405
    lm = 0;
3406
#else
3407
    lm = (entry_2 >> 21) & 1;
3408
#endif
3409
    flags = (seg_32bit << 0) | (contents << 1) |
3410
        (read_exec_only << 3) | (limit_in_pages << 4) |
3411
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3412
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3413
    base_addr = (entry_1 >> 16) | 
3414
        (entry_2 & 0xff000000) | 
3415
        ((entry_2 & 0xff) << 16);
3416
    target_ldt_info->base_addr = tswapl(base_addr);
3417
    target_ldt_info->limit = tswap32(limit);
3418
    target_ldt_info->flags = tswap32(flags);
3419
    unlock_user_struct(target_ldt_info, ptr, 1);
3420
    return 0;
3421
}
3422
#endif /* TARGET_I386 && TARGET_ABI32 */
3423

    
3424
#ifndef TARGET_ABI32
3425
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3426
{
3427
    abi_long ret;
3428
    abi_ulong val;
3429
    int idx;
3430
    
3431
    switch(code) {
3432
    case TARGET_ARCH_SET_GS:
3433
    case TARGET_ARCH_SET_FS:
3434
        if (code == TARGET_ARCH_SET_GS)
3435
            idx = R_GS;
3436
        else
3437
            idx = R_FS;
3438
        cpu_x86_load_seg(env, idx, 0);
3439
        env->segs[idx].base = addr;
3440
        break;
3441
    case TARGET_ARCH_GET_GS:
3442
    case TARGET_ARCH_GET_FS:
3443
        if (code == TARGET_ARCH_GET_GS)
3444
            idx = R_GS;
3445
        else
3446
            idx = R_FS;
3447
        val = env->segs[idx].base;
3448
        if (put_user(val, addr, abi_ulong))
3449
            return -TARGET_EFAULT;
3450
        break;
3451
    default:
3452
        ret = -TARGET_EINVAL;
3453
        break;
3454
    }
3455
    return 0;
3456
}
3457
#endif
3458

    
3459
#endif /* defined(TARGET_I386) */
3460

    
3461
#if defined(CONFIG_USE_NPTL)
3462

    
3463
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
3464

    
3465
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3466
typedef struct {
3467
    CPUState *env;
3468
    pthread_mutex_t mutex;
3469
    pthread_cond_t cond;
3470
    pthread_t thread;
3471
    uint32_t tid;
3472
    abi_ulong child_tidptr;
3473
    abi_ulong parent_tidptr;
3474
    sigset_t sigmask;
3475
} new_thread_info;
3476

    
3477
static void *clone_func(void *arg)
3478
{
3479
    new_thread_info *info = arg;
3480
    CPUState *env;
3481
    TaskState *ts;
3482

    
3483
    env = info->env;
3484
    thread_env = env;
3485
    ts = (TaskState *)thread_env->opaque;
3486
    info->tid = gettid();
3487
    env->host_tid = info->tid;
3488
    task_settid(ts);
3489
    if (info->child_tidptr)
3490
        put_user_u32(info->tid, info->child_tidptr);
3491
    if (info->parent_tidptr)
3492
        put_user_u32(info->tid, info->parent_tidptr);
3493
    /* Enable signals.  */
3494
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3495
    /* Signal to the parent that we're ready.  */
3496
    pthread_mutex_lock(&info->mutex);
3497
    pthread_cond_broadcast(&info->cond);
3498
    pthread_mutex_unlock(&info->mutex);
3499
    /* Wait until the parent has finshed initializing the tls state.  */
3500
    pthread_mutex_lock(&clone_lock);
3501
    pthread_mutex_unlock(&clone_lock);
3502
    cpu_loop(env);
3503
    /* never exits */
3504
    return NULL;
3505
}
3506
#else
3507
/* this stack is the equivalent of the kernel stack associated with a
3508
   thread/process */
3509
#define NEW_STACK_SIZE 8192
3510

    
3511
static int clone_func(void *arg)
3512
{
3513
    CPUState *env = arg;
3514
    cpu_loop(env);
3515
    /* never exits */
3516
    return 0;
3517
}
3518
#endif
3519

    
3520
/* do_fork() Must return host values and target errnos (unlike most
3521
   do_*() functions). */
3522
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3523
                   abi_ulong parent_tidptr, target_ulong newtls,
3524
                   abi_ulong child_tidptr)
3525
{
3526
    int ret;
3527
    TaskState *ts;
3528
    uint8_t *new_stack;
3529
    CPUState *new_env;
3530
#if defined(CONFIG_USE_NPTL)
3531
    unsigned int nptl_flags;
3532
    sigset_t sigmask;
3533
#endif
3534

    
3535
    /* Emulate vfork() with fork() */
3536
    if (flags & CLONE_VFORK)
3537
        flags &= ~(CLONE_VFORK | CLONE_VM);
3538

    
3539
    if (flags & CLONE_VM) {
3540
        TaskState *parent_ts = (TaskState *)env->opaque;
3541
#if defined(CONFIG_USE_NPTL)
3542
        new_thread_info info;
3543
        pthread_attr_t attr;
3544
#endif
3545
        ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
3546
        init_task_state(ts);
3547
        new_stack = ts->stack;
3548
        /* we create a new CPU instance. */
3549
        new_env = cpu_copy(env);
3550
        /* Init regs that differ from the parent.  */
3551
        cpu_clone_regs(new_env, newsp);
3552
        new_env->opaque = ts;
3553
        ts->bprm = parent_ts->bprm;
3554
        ts->info = parent_ts->info;
3555
#if defined(CONFIG_USE_NPTL)
3556
        nptl_flags = flags;
3557
        flags &= ~CLONE_NPTL_FLAGS2;
3558

    
3559
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3560
            ts->child_tidptr = child_tidptr;
3561
        }
3562

    
3563
        if (nptl_flags & CLONE_SETTLS)
3564
            cpu_set_tls (new_env, newtls);
3565

    
3566
        /* Grab a mutex so that thread setup appears atomic.  */
3567
        pthread_mutex_lock(&clone_lock);
3568

    
3569
        memset(&info, 0, sizeof(info));
3570
        pthread_mutex_init(&info.mutex, NULL);
3571
        pthread_mutex_lock(&info.mutex);
3572
        pthread_cond_init(&info.cond, NULL);
3573
        info.env = new_env;
3574
        if (nptl_flags & CLONE_CHILD_SETTID)
3575
            info.child_tidptr = child_tidptr;
3576
        if (nptl_flags & CLONE_PARENT_SETTID)
3577
            info.parent_tidptr = parent_tidptr;
3578

    
3579
        ret = pthread_attr_init(&attr);
3580
        ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
3581
        /* It is not safe to deliver signals until the child has finished
3582
           initializing, so temporarily block all signals.  */
3583
        sigfillset(&sigmask);
3584
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3585

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

    
3589
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3590
        pthread_attr_destroy(&attr);
3591
        if (ret == 0) {
3592
            /* Wait for the child to initialize.  */
3593
            pthread_cond_wait(&info.cond, &info.mutex);
3594
            ret = info.tid;
3595
            if (flags & CLONE_PARENT_SETTID)
3596
                put_user_u32(ret, parent_tidptr);
3597
        } else {
3598
            ret = -1;
3599
        }
3600
        pthread_mutex_unlock(&info.mutex);
3601
        pthread_cond_destroy(&info.cond);
3602
        pthread_mutex_destroy(&info.mutex);
3603
        pthread_mutex_unlock(&clone_lock);
3604
#else
3605
        if (flags & CLONE_NPTL_FLAGS2)
3606
            return -EINVAL;
3607
        /* This is probably going to die very quickly, but do it anyway.  */
3608
#ifdef __ia64__
3609
        ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3610
#else
3611
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
3612
#endif
3613
#endif
3614
    } else {
3615
        /* if no CLONE_VM, we consider it is a fork */
3616
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
3617
            return -EINVAL;
3618
        fork_start();
3619
        ret = fork();
3620
        if (ret == 0) {
3621
            /* Child Process.  */
3622
            cpu_clone_regs(env, newsp);
3623
            fork_end(1);
3624
#if defined(CONFIG_USE_NPTL)
3625
            /* There is a race condition here.  The parent process could
3626
               theoretically read the TID in the child process before the child
3627
               tid is set.  This would require using either ptrace
3628
               (not implemented) or having *_tidptr to point at a shared memory
3629
               mapping.  We can't repeat the spinlock hack used above because
3630
               the child process gets its own copy of the lock.  */
3631
            if (flags & CLONE_CHILD_SETTID)
3632
                put_user_u32(gettid(), child_tidptr);
3633
            if (flags & CLONE_PARENT_SETTID)
3634
                put_user_u32(gettid(), parent_tidptr);
3635
            ts = (TaskState *)env->opaque;
3636
            if (flags & CLONE_SETTLS)
3637
                cpu_set_tls (env, newtls);
3638
            if (flags & CLONE_CHILD_CLEARTID)
3639
                ts->child_tidptr = child_tidptr;
3640
#endif
3641
        } else {
3642
            fork_end(0);
3643
        }
3644
    }
3645
    return ret;
3646
}
3647

    
3648
/* warning : doesn't handle linux specific flags... */
3649
static int target_to_host_fcntl_cmd(int cmd)
3650
{
3651
    switch(cmd) {
3652
        case TARGET_F_DUPFD:
3653
        case TARGET_F_GETFD:
3654
        case TARGET_F_SETFD:
3655
        case TARGET_F_GETFL:
3656
        case TARGET_F_SETFL:
3657
            return cmd;
3658
        case TARGET_F_GETLK:
3659
            return F_GETLK;
3660
        case TARGET_F_SETLK:
3661
            return F_SETLK;
3662
        case TARGET_F_SETLKW:
3663
            return F_SETLKW;
3664
        case TARGET_F_GETOWN:
3665
            return F_GETOWN;
3666
        case TARGET_F_SETOWN:
3667
            return F_SETOWN;
3668
        case TARGET_F_GETSIG:
3669
            return F_GETSIG;
3670
        case TARGET_F_SETSIG:
3671
            return F_SETSIG;
3672
#if TARGET_ABI_BITS == 32
3673
        case TARGET_F_GETLK64:
3674
            return F_GETLK64;
3675
        case TARGET_F_SETLK64:
3676
            return F_SETLK64;
3677
        case TARGET_F_SETLKW64:
3678
            return F_SETLKW64;
3679
#endif
3680
        default:
3681
            return -TARGET_EINVAL;
3682
    }
3683
    return -TARGET_EINVAL;
3684
}
3685

    
3686
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3687
{
3688
    struct flock fl;
3689
    struct target_flock *target_fl;
3690
    struct flock64 fl64;
3691
    struct target_flock64 *target_fl64;
3692
    abi_long ret;
3693
    int host_cmd = target_to_host_fcntl_cmd(cmd);
3694

    
3695
    if (host_cmd == -TARGET_EINVAL)
3696
            return host_cmd;
3697

    
3698
    switch(cmd) {
3699
    case TARGET_F_GETLK:
3700
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3701
            return -TARGET_EFAULT;
3702
        fl.l_type = tswap16(target_fl->l_type);
3703
        fl.l_whence = tswap16(target_fl->l_whence);
3704
        fl.l_start = tswapl(target_fl->l_start);
3705
        fl.l_len = tswapl(target_fl->l_len);
3706
        fl.l_pid = tswapl(target_fl->l_pid);
3707
        unlock_user_struct(target_fl, arg, 0);
3708
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3709
        if (ret == 0) {
3710
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3711
                return -TARGET_EFAULT;
3712
            target_fl->l_type = tswap16(fl.l_type);
3713
            target_fl->l_whence = tswap16(fl.l_whence);
3714
            target_fl->l_start = tswapl(fl.l_start);
3715
            target_fl->l_len = tswapl(fl.l_len);
3716
            target_fl->l_pid = tswapl(fl.l_pid);
3717
            unlock_user_struct(target_fl, arg, 1);
3718
        }
3719
        break;
3720

    
3721
    case TARGET_F_SETLK:
3722
    case TARGET_F_SETLKW:
3723
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
3724
            return -TARGET_EFAULT;
3725
        fl.l_type = tswap16(target_fl->l_type);
3726
        fl.l_whence = tswap16(target_fl->l_whence);
3727
        fl.l_start = tswapl(target_fl->l_start);
3728
        fl.l_len = tswapl(target_fl->l_len);
3729
        fl.l_pid = tswapl(target_fl->l_pid);
3730
        unlock_user_struct(target_fl, arg, 0);
3731
        ret = get_errno(fcntl(fd, host_cmd, &fl));
3732
        break;
3733

    
3734
    case TARGET_F_GETLK64:
3735
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3736
            return -TARGET_EFAULT;
3737
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3738
        fl64.l_whence = tswap16(target_fl64->l_whence);
3739
        fl64.l_start = tswapl(target_fl64->l_start);
3740
        fl64.l_len = tswapl(target_fl64->l_len);
3741
        fl64.l_pid = tswap16(target_fl64->l_pid);
3742
        unlock_user_struct(target_fl64, arg, 0);
3743
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3744
        if (ret == 0) {
3745
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3746
                return -TARGET_EFAULT;
3747
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
3748
            target_fl64->l_whence = tswap16(fl64.l_whence);
3749
            target_fl64->l_start = tswapl(fl64.l_start);
3750
            target_fl64->l_len = tswapl(fl64.l_len);
3751
            target_fl64->l_pid = tswapl(fl64.l_pid);
3752
            unlock_user_struct(target_fl64, arg, 1);
3753
        }
3754
        break;
3755
    case TARGET_F_SETLK64:
3756
    case TARGET_F_SETLKW64:
3757
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
3758
            return -TARGET_EFAULT;
3759
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
3760
        fl64.l_whence = tswap16(target_fl64->l_whence);
3761
        fl64.l_start = tswapl(target_fl64->l_start);
3762
        fl64.l_len = tswapl(target_fl64->l_len);
3763
        fl64.l_pid = tswap16(target_fl64->l_pid);
3764
        unlock_user_struct(target_fl64, arg, 0);
3765
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
3766
        break;
3767

    
3768
    case TARGET_F_GETFL:
3769
        ret = get_errno(fcntl(fd, host_cmd, arg));
3770
        if (ret >= 0) {
3771
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3772
        }
3773
        break;
3774

    
3775
    case TARGET_F_SETFL:
3776
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
3777
        break;
3778

    
3779
    case TARGET_F_SETOWN:
3780
    case TARGET_F_GETOWN:
3781
    case TARGET_F_SETSIG:
3782
    case TARGET_F_GETSIG:
3783
        ret = get_errno(fcntl(fd, host_cmd, arg));
3784
        break;
3785

    
3786
    default:
3787
        ret = get_errno(fcntl(fd, cmd, arg));
3788
        break;
3789
    }
3790
    return ret;
3791
}
3792

    
3793
#ifdef USE_UID16
3794

    
3795
static inline int high2lowuid(int uid)
3796
{
3797
    if (uid > 65535)
3798
        return 65534;
3799
    else
3800
        return uid;
3801
}
3802

    
3803
static inline int high2lowgid(int gid)
3804
{
3805
    if (gid > 65535)
3806
        return 65534;
3807
    else
3808
        return gid;
3809
}
3810

    
3811
static inline int low2highuid(int uid)
3812
{
3813
    if ((int16_t)uid == -1)
3814
        return -1;
3815
    else
3816
        return uid;
3817
}
3818

    
3819
static inline int low2highgid(int gid)
3820
{
3821
    if ((int16_t)gid == -1)
3822
        return -1;
3823
    else
3824
        return gid;
3825
}
3826

    
3827
#endif /* USE_UID16 */
3828

    
3829
void syscall_init(void)
3830
{
3831
    IOCTLEntry *ie;
3832
    const argtype *arg_type;
3833
    int size;
3834
    int i;
3835

    
3836
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
3837
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
3838
#include "syscall_types.h"
3839
#undef STRUCT
3840
#undef STRUCT_SPECIAL
3841

    
3842
    /* we patch the ioctl size if necessary. We rely on the fact that
3843
       no ioctl has all the bits at '1' in the size field */
3844
    ie = ioctl_entries;
3845
    while (ie->target_cmd != 0) {
3846
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
3847
            TARGET_IOC_SIZEMASK) {
3848
            arg_type = ie->arg_type;
3849
            if (arg_type[0] != TYPE_PTR) {
3850
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
3851
                        ie->target_cmd);
3852
                exit(1);
3853
            }
3854
            arg_type++;
3855
            size = thunk_type_size(arg_type, 0);
3856
            ie->target_cmd = (ie->target_cmd &
3857
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
3858
                (size << TARGET_IOC_SIZESHIFT);
3859
        }
3860

    
3861
        /* Build target_to_host_errno_table[] table from
3862
         * host_to_target_errno_table[]. */
3863
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
3864
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
3865

    
3866
        /* automatic consistency check if same arch */
3867
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
3868
    (defined(__x86_64__) && defined(TARGET_X86_64))
3869
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
3870
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
3871
                    ie->name, ie->target_cmd, ie->host_cmd);
3872
        }
3873
#endif
3874
        ie++;
3875
    }
3876
}
3877

    
3878
#if TARGET_ABI_BITS == 32
3879
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
3880
{
3881
#ifdef TARGET_WORDS_BIGENDIAN
3882
    return ((uint64_t)word0 << 32) | word1;
3883
#else
3884
    return ((uint64_t)word1 << 32) | word0;
3885
#endif
3886
}
3887
#else /* TARGET_ABI_BITS == 32 */
3888
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
3889
{
3890
    return word0;
3891
}
3892
#endif /* TARGET_ABI_BITS != 32 */
3893

    
3894
#ifdef TARGET_NR_truncate64
3895
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
3896
                                         abi_long arg2,
3897
                                         abi_long arg3,
3898
                                         abi_long arg4)
3899
{
3900
#ifdef TARGET_ARM
3901
    if (((CPUARMState *)cpu_env)->eabi)
3902
      {
3903
        arg2 = arg3;
3904
        arg3 = arg4;
3905
      }
3906
#endif
3907
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
3908
}
3909
#endif
3910

    
3911
#ifdef TARGET_NR_ftruncate64
3912
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
3913
                                          abi_long arg2,
3914
                                          abi_long arg3,
3915
                                          abi_long arg4)
3916
{
3917
#ifdef TARGET_ARM
3918
    if (((CPUARMState *)cpu_env)->eabi)
3919
      {
3920
        arg2 = arg3;
3921
        arg3 = arg4;
3922
      }
3923
#endif
3924
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
3925
}
3926
#endif
3927

    
3928
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
3929
                                               abi_ulong target_addr)
3930
{
3931
    struct target_timespec *target_ts;
3932

    
3933
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
3934
        return -TARGET_EFAULT;
3935
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
3936
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
3937
    unlock_user_struct(target_ts, target_addr, 0);
3938
    return 0;
3939
}
3940

    
3941
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3942
                                               struct timespec *host_ts)
3943
{
3944
    struct target_timespec *target_ts;
3945

    
3946
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
3947
        return -TARGET_EFAULT;
3948
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
3949
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
3950
    unlock_user_struct(target_ts, target_addr, 1);
3951
    return 0;
3952
}
3953

    
3954
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
3955
static inline abi_long host_to_target_stat64(void *cpu_env,
3956
                                             abi_ulong target_addr,
3957
                                             struct stat *host_st)
3958
{
3959
#ifdef TARGET_ARM
3960
    if (((CPUARMState *)cpu_env)->eabi) {
3961
        struct target_eabi_stat64 *target_st;
3962

    
3963
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3964
            return -TARGET_EFAULT;
3965
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
3966
        __put_user(host_st->st_dev, &target_st->st_dev);
3967
        __put_user(host_st->st_ino, &target_st->st_ino);
3968
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3969
        __put_user(host_st->st_ino, &target_st->__st_ino);
3970
#endif
3971
        __put_user(host_st->st_mode, &target_st->st_mode);
3972
        __put_user(host_st->st_nlink, &target_st->st_nlink);
3973
        __put_user(host_st->st_uid, &target_st->st_uid);
3974
        __put_user(host_st->st_gid, &target_st->st_gid);
3975
        __put_user(host_st->st_rdev, &target_st->st_rdev);
3976
        __put_user(host_st->st_size, &target_st->st_size);
3977
        __put_user(host_st->st_blksize, &target_st->st_blksize);
3978
        __put_user(host_st->st_blocks, &target_st->st_blocks);
3979
        __put_user(host_st->st_atime, &target_st->target_st_atime);
3980
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
3981
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
3982
        unlock_user_struct(target_st, target_addr, 1);
3983
    } else
3984
#endif
3985
    {
3986
#if TARGET_LONG_BITS == 64
3987
        struct target_stat *target_st;
3988
#else
3989
        struct target_stat64 *target_st;
3990
#endif
3991

    
3992
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
3993
            return -TARGET_EFAULT;
3994
        memset(target_st, 0, sizeof(*target_st));
3995
        __put_user(host_st->st_dev, &target_st->st_dev);
3996
        __put_user(host_st->st_ino, &target_st->st_ino);
3997
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
3998
        __put_user(host_st->st_ino, &target_st->__st_ino);
3999
#endif
4000
        __put_user(host_st->st_mode, &target_st->st_mode);
4001
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4002
        __put_user(host_st->st_uid, &target_st->st_uid);
4003
        __put_user(host_st->st_gid, &target_st->st_gid);
4004
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4005
        /* XXX: better use of kernel struct */
4006
        __put_user(host_st->st_size, &target_st->st_size);
4007
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4008
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4009
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4010
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4011
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4012
        unlock_user_struct(target_st, target_addr, 1);
4013
    }
4014

    
4015
    return 0;
4016
}
4017
#endif
4018

    
4019
#if defined(CONFIG_USE_NPTL)
4020
/* ??? Using host futex calls even when target atomic operations
4021
   are not really atomic probably breaks things.  However implementing
4022
   futexes locally would make futexes shared between multiple processes
4023
   tricky.  However they're probably useless because guest atomic
4024
   operations won't work either.  */
4025
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4026
                    target_ulong uaddr2, int val3)
4027
{
4028
    struct timespec ts, *pts;
4029

    
4030
    /* ??? We assume FUTEX_* constants are the same on both host
4031
       and target.  */
4032
#ifdef FUTEX_CMD_MASK
4033
    switch ((op&FUTEX_CMD_MASK)) {
4034
#else
4035
    switch (op) {
4036
#endif
4037
    case FUTEX_WAIT:
4038
        if (timeout) {
4039
            pts = &ts;
4040
            target_to_host_timespec(pts, timeout);
4041
        } else {
4042
            pts = NULL;
4043
        }
4044
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4045
                         pts, NULL, 0));
4046
    case FUTEX_WAKE:
4047
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4048
    case FUTEX_WAKE_OP:
4049
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, g2h(uaddr2), val3 ));
4050
    case FUTEX_FD:
4051
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4052
    case FUTEX_REQUEUE:
4053
        return get_errno(sys_futex(g2h(uaddr), op, val,
4054
                         NULL, g2h(uaddr2), 0));
4055
    case FUTEX_CMP_REQUEUE:
4056
        return get_errno(sys_futex(g2h(uaddr), op, val,
4057
                         NULL, g2h(uaddr2), tswap32(val3)));
4058
    default:
4059
        return -TARGET_ENOSYS;
4060
    }
4061
}
4062
#endif
4063

    
4064
/* Map host to target signal numbers for the wait family of syscalls.
4065
   Assume all other status bits are the same.  */
4066
static int host_to_target_waitstatus(int status)
4067
{
4068
    if (WIFSIGNALED(status)) {
4069
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4070
    }
4071
    if (WIFSTOPPED(status)) {
4072
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4073
               | (status & 0xff);
4074
    }
4075
    return status;
4076
}
4077

    
4078
int get_osversion(void)
4079
{
4080
    static int osversion;
4081
    struct new_utsname buf;
4082
    const char *s;
4083
    int i, n, tmp;
4084
    if (osversion)
4085
        return osversion;
4086
    if (qemu_uname_release && *qemu_uname_release) {
4087
        s = qemu_uname_release;
4088
    } else {
4089
        if (sys_uname(&buf))
4090
            return 0;
4091
        s = buf.release;
4092
    }
4093
    tmp = 0;
4094
    for (i = 0; i < 3; i++) {
4095
        n = 0;
4096
        while (*s >= '0' && *s <= '9') {
4097
            n *= 10;
4098
            n += *s - '0';
4099
            s++;
4100
        }
4101
        tmp = (tmp << 8) + n;
4102
        if (*s == '.')
4103
            s++;
4104
    }
4105
    osversion = tmp;
4106
    return osversion;
4107
}
4108

    
4109
/* do_syscall() should always have a single exit point at the end so
4110
   that actions, such as logging of syscall results, can be performed.
4111
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4112
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4113
                    abi_long arg2, abi_long arg3, abi_long arg4,
4114
                    abi_long arg5, abi_long arg6)
4115
{
4116
    abi_long ret;
4117
    struct stat st;
4118
    struct statfs stfs;
4119
    void *p;
4120

    
4121
#ifdef DEBUG
4122
    gemu_log("syscall %d", num);
4123
#endif
4124
    if(do_strace)
4125
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4126

    
4127
    switch(num) {
4128
    case TARGET_NR_exit:
4129
#ifdef CONFIG_USE_NPTL
4130
      /* In old applications this may be used to implement _exit(2).
4131
         However in threaded applictions it is used for thread termination,
4132
         and _exit_group is used for application termination.
4133
         Do thread termination if we have more then one thread.  */
4134
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4135
         be disabling signals.  */
4136
      if (first_cpu->next_cpu) {
4137
          TaskState *ts;
4138
          CPUState **lastp;
4139
          CPUState *p;
4140

    
4141
          cpu_list_lock();
4142
          lastp = &first_cpu;
4143
          p = first_cpu;
4144
          while (p && p != (CPUState *)cpu_env) {
4145
              lastp = &p->next_cpu;
4146
              p = p->next_cpu;
4147
          }
4148
          /* If we didn't find the CPU for this thread then something is
4149
             horribly wrong.  */
4150
          if (!p)
4151
              abort();
4152
          /* Remove the CPU from the list.  */
4153
          *lastp = p->next_cpu;
4154
          cpu_list_unlock();
4155
          ts = ((CPUState *)cpu_env)->opaque;
4156
          if (ts->child_tidptr) {
4157
              put_user_u32(0, ts->child_tidptr);
4158
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4159
                        NULL, NULL, 0);
4160
          }
4161
          /* TODO: Free CPU state.  */
4162
          pthread_exit(NULL);
4163
      }
4164
#endif
4165
#ifdef TARGET_GPROF
4166
        _mcleanup();
4167
#endif
4168
        gdb_exit(cpu_env, arg1);
4169
        _exit(arg1);
4170
        ret = 0; /* avoid warning */
4171
        break;
4172
    case TARGET_NR_read:
4173
        if (arg3 == 0)
4174
            ret = 0;
4175
        else {
4176
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4177
                goto efault;
4178
            ret = get_errno(read(arg1, p, arg3));
4179
            unlock_user(p, arg2, ret);
4180
        }
4181
        break;
4182
    case TARGET_NR_write:
4183
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4184
            goto efault;
4185
        ret = get_errno(write(arg1, p, arg3));
4186
        unlock_user(p, arg2, 0);
4187
        break;
4188
    case TARGET_NR_open:
4189
        if (!(p = lock_user_string(arg1)))
4190
            goto efault;
4191
        ret = get_errno(open(path(p),
4192
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
4193
                             arg3));
4194
        unlock_user(p, arg1, 0);
4195
        break;
4196
#if defined(TARGET_NR_openat) && defined(__NR_openat)
4197
    case TARGET_NR_openat:
4198
        if (!(p = lock_user_string(arg2)))
4199
            goto efault;
4200
        ret = get_errno(sys_openat(arg1,
4201
                                   path(p),
4202
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
4203
                                   arg4));
4204
        unlock_user(p, arg2, 0);
4205
        break;
4206
#endif
4207
    case TARGET_NR_close:
4208
        ret = get_errno(close(arg1));
4209
        break;
4210
    case TARGET_NR_brk:
4211
        ret = do_brk(arg1);
4212
        break;
4213
    case TARGET_NR_fork:
4214
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4215
        break;
4216
#ifdef TARGET_NR_waitpid
4217
    case TARGET_NR_waitpid:
4218
        {
4219
            int status;
4220
            ret = get_errno(waitpid(arg1, &status, arg3));
4221
            if (!is_error(ret) && arg2
4222
                && put_user_s32(host_to_target_waitstatus(status), arg2))
4223
                goto efault;
4224
        }
4225
        break;
4226
#endif
4227
#ifdef TARGET_NR_waitid
4228
    case TARGET_NR_waitid:
4229
        {
4230
            siginfo_t info;
4231
            info.si_pid = 0;
4232
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
4233
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
4234
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4235
                    goto efault;
4236
                host_to_target_siginfo(p, &info);
4237
                unlock_user(p, arg3, sizeof(target_siginfo_t));
4238
            }
4239
        }
4240
        break;
4241
#endif
4242
#ifdef TARGET_NR_creat /* not on alpha */
4243
    case TARGET_NR_creat:
4244
        if (!(p = lock_user_string(arg1)))
4245
            goto efault;
4246
        ret = get_errno(creat(p, arg2));
4247
        unlock_user(p, arg1, 0);
4248
        break;
4249
#endif
4250
    case TARGET_NR_link:
4251
        {
4252
            void * p2;
4253
            p = lock_user_string(arg1);
4254
            p2 = lock_user_string(arg2);
4255
            if (!p || !p2)
4256
                ret = -TARGET_EFAULT;
4257
            else
4258
                ret = get_errno(link(p, p2));
4259
            unlock_user(p2, arg2, 0);
4260
            unlock_user(p, arg1, 0);
4261
        }
4262
        break;
4263
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4264
    case TARGET_NR_linkat:
4265
        {
4266
            void * p2 = NULL;
4267
            if (!arg2 || !arg4)
4268
                goto efault;
4269
            p  = lock_user_string(arg2);
4270
            p2 = lock_user_string(arg4);
4271
            if (!p || !p2)
4272
                ret = -TARGET_EFAULT;
4273
            else
4274
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4275
            unlock_user(p, arg2, 0);
4276
            unlock_user(p2, arg4, 0);
4277
        }
4278
        break;
4279
#endif
4280
    case TARGET_NR_unlink:
4281
        if (!(p = lock_user_string(arg1)))
4282
            goto efault;
4283
        ret = get_errno(unlink(p));
4284
        unlock_user(p, arg1, 0);
4285
        break;
4286
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4287
    case TARGET_NR_unlinkat:
4288
        if (!(p = lock_user_string(arg2)))
4289
            goto efault;
4290
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
4291
        unlock_user(p, arg2, 0);
4292
        break;
4293
#endif
4294
    case TARGET_NR_execve:
4295
        {
4296
            char **argp, **envp;
4297
            int argc, envc;
4298
            abi_ulong gp;
4299
            abi_ulong guest_argp;
4300
            abi_ulong guest_envp;
4301
            abi_ulong addr;
4302
            char **q;
4303

    
4304
            argc = 0;
4305
            guest_argp = arg2;
4306
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4307
                if (get_user_ual(addr, gp))
4308
                    goto efault;
4309
                if (!addr)
4310
                    break;
4311
                argc++;
4312
            }
4313
            envc = 0;
4314
            guest_envp = arg3;
4315
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4316
                if (get_user_ual(addr, gp))
4317
                    goto efault;
4318
                if (!addr)
4319
                    break;
4320
                envc++;
4321
            }
4322

    
4323
            argp = alloca((argc + 1) * sizeof(void *));
4324
            envp = alloca((envc + 1) * sizeof(void *));
4325

    
4326
            for (gp = guest_argp, q = argp; gp;
4327
                  gp += sizeof(abi_ulong), q++) {
4328
                if (get_user_ual(addr, gp))
4329
                    goto execve_efault;
4330
                if (!addr)
4331
                    break;
4332
                if (!(*q = lock_user_string(addr)))
4333
                    goto execve_efault;
4334
            }
4335
            *q = NULL;
4336

    
4337
            for (gp = guest_envp, q = envp; gp;
4338
                  gp += sizeof(abi_ulong), q++) {
4339
                if (get_user_ual(addr, gp))
4340
                    goto execve_efault;
4341
                if (!addr)
4342
                    break;
4343
                if (!(*q = lock_user_string(addr)))
4344
                    goto execve_efault;
4345
            }
4346
            *q = NULL;
4347

    
4348
            if (!(p = lock_user_string(arg1)))
4349
                goto execve_efault;
4350
            ret = get_errno(execve(p, argp, envp));
4351
            unlock_user(p, arg1, 0);
4352

    
4353
            goto execve_end;
4354

    
4355
        execve_efault:
4356
            ret = -TARGET_EFAULT;
4357

    
4358
        execve_end:
4359
            for (gp = guest_argp, q = argp; *q;
4360
                  gp += sizeof(abi_ulong), q++) {
4361
                if (get_user_ual(addr, gp)
4362
                    || !addr)
4363
                    break;
4364
                unlock_user(*q, addr, 0);
4365
            }
4366
            for (gp = guest_envp, q = envp; *q;
4367
                  gp += sizeof(abi_ulong), q++) {
4368
                if (get_user_ual(addr, gp)
4369
                    || !addr)
4370
                    break;
4371
                unlock_user(*q, addr, 0);
4372
            }
4373
        }
4374
        break;
4375
    case TARGET_NR_chdir:
4376
        if (!(p = lock_user_string(arg1)))
4377
            goto efault;
4378
        ret = get_errno(chdir(p));
4379
        unlock_user(p, arg1, 0);
4380
        break;
4381
#ifdef TARGET_NR_time
4382
    case TARGET_NR_time:
4383
        {
4384
            time_t host_time;
4385
            ret = get_errno(time(&host_time));
4386
            if (!is_error(ret)
4387
                && arg1
4388
                && put_user_sal(host_time, arg1))
4389
                goto efault;
4390
        }
4391
        break;
4392
#endif
4393
    case TARGET_NR_mknod:
4394
        if (!(p = lock_user_string(arg1)))
4395
            goto efault;
4396
        ret = get_errno(mknod(p, arg2, arg3));
4397
        unlock_user(p, arg1, 0);
4398
        break;
4399
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4400
    case TARGET_NR_mknodat:
4401
        if (!(p = lock_user_string(arg2)))
4402
            goto efault;
4403
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4404
        unlock_user(p, arg2, 0);
4405
        break;
4406
#endif
4407
    case TARGET_NR_chmod:
4408
        if (!(p = lock_user_string(arg1)))
4409
            goto efault;
4410
        ret = get_errno(chmod(p, arg2));
4411
        unlock_user(p, arg1, 0);
4412
        break;
4413
#ifdef TARGET_NR_break
4414
    case TARGET_NR_break:
4415
        goto unimplemented;
4416
#endif
4417
#ifdef TARGET_NR_oldstat
4418
    case TARGET_NR_oldstat:
4419
        goto unimplemented;
4420
#endif
4421
    case TARGET_NR_lseek:
4422
        ret = get_errno(lseek(arg1, arg2, arg3));
4423
        break;
4424
#ifdef TARGET_NR_getxpid
4425
    case TARGET_NR_getxpid:
4426
#else
4427
    case TARGET_NR_getpid:
4428
#endif
4429
        ret = get_errno(getpid());
4430
        break;
4431
    case TARGET_NR_mount:
4432
                {
4433
                        /* need to look at the data field */
4434
                        void *p2, *p3;
4435
                        p = lock_user_string(arg1);
4436
                        p2 = lock_user_string(arg2);
4437
                        p3 = lock_user_string(arg3);
4438
                        if (!p || !p2 || !p3)
4439
                            ret = -TARGET_EFAULT;
4440
                        else
4441
                            /* FIXME - arg5 should be locked, but it isn't clear how to
4442
                             * do that since it's not guaranteed to be a NULL-terminated
4443
                             * string.
4444
                             */
4445
                            ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4446
                        unlock_user(p, arg1, 0);
4447
                        unlock_user(p2, arg2, 0);
4448
                        unlock_user(p3, arg3, 0);
4449
                        break;
4450
                }
4451
#ifdef TARGET_NR_umount
4452
    case TARGET_NR_umount:
4453
        if (!(p = lock_user_string(arg1)))
4454
            goto efault;
4455
        ret = get_errno(umount(p));
4456
        unlock_user(p, arg1, 0);
4457
        break;
4458
#endif
4459
#ifdef TARGET_NR_stime /* not on alpha */
4460
    case TARGET_NR_stime:
4461
        {
4462
            time_t host_time;
4463
            if (get_user_sal(host_time, arg1))
4464
                goto efault;
4465
            ret = get_errno(stime(&host_time));
4466
        }
4467
        break;
4468
#endif
4469
    case TARGET_NR_ptrace:
4470
        goto unimplemented;
4471
#ifdef TARGET_NR_alarm /* not on alpha */
4472
    case TARGET_NR_alarm:
4473
        ret = alarm(arg1);
4474
        break;
4475
#endif
4476
#ifdef TARGET_NR_oldfstat
4477
    case TARGET_NR_oldfstat:
4478
        goto unimplemented;
4479
#endif
4480
#ifdef TARGET_NR_pause /* not on alpha */
4481
    case TARGET_NR_pause:
4482
        ret = get_errno(pause());
4483
        break;
4484
#endif
4485
#ifdef TARGET_NR_utime
4486
    case TARGET_NR_utime:
4487
        {
4488
            struct utimbuf tbuf, *host_tbuf;
4489
            struct target_utimbuf *target_tbuf;
4490
            if (arg2) {
4491
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4492
                    goto efault;
4493
                tbuf.actime = tswapl(target_tbuf->actime);
4494
                tbuf.modtime = tswapl(target_tbuf->modtime);
4495
                unlock_user_struct(target_tbuf, arg2, 0);
4496
                host_tbuf = &tbuf;
4497
            } else {
4498
                host_tbuf = NULL;
4499
            }
4500
            if (!(p = lock_user_string(arg1)))
4501
                goto efault;
4502
            ret = get_errno(utime(p, host_tbuf));
4503
            unlock_user(p, arg1, 0);
4504
        }
4505
        break;
4506
#endif
4507
    case TARGET_NR_utimes:
4508
        {
4509
            struct timeval *tvp, tv[2];
4510
            if (arg2) {
4511
                if (copy_from_user_timeval(&tv[0], arg2)
4512
                    || copy_from_user_timeval(&tv[1],
4513
                                              arg2 + sizeof(struct target_timeval)))
4514
                    goto efault;
4515
                tvp = tv;
4516
            } else {
4517
                tvp = NULL;
4518
            }
4519
            if (!(p = lock_user_string(arg1)))
4520
                goto efault;
4521
            ret = get_errno(utimes(p, tvp));
4522
            unlock_user(p, arg1, 0);
4523
        }
4524
        break;
4525
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4526
    case TARGET_NR_futimesat:
4527
        {
4528
            struct timeval *tvp, tv[2];
4529
            if (arg3) {
4530
                if (copy_from_user_timeval(&tv[0], arg3)
4531
                    || copy_from_user_timeval(&tv[1],
4532
                                              arg3 + sizeof(struct target_timeval)))
4533
                    goto efault;
4534
                tvp = tv;
4535
            } else {
4536
                tvp = NULL;
4537
            }
4538
            if (!(p = lock_user_string(arg2)))
4539
                goto efault;
4540
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
4541
            unlock_user(p, arg2, 0);
4542
        }
4543
        break;
4544
#endif
4545
#ifdef TARGET_NR_stty
4546
    case TARGET_NR_stty:
4547
        goto unimplemented;
4548
#endif
4549
#ifdef TARGET_NR_gtty
4550
    case TARGET_NR_gtty:
4551
        goto unimplemented;
4552
#endif
4553
    case TARGET_NR_access:
4554
        if (!(p = lock_user_string(arg1)))
4555
            goto efault;
4556
        ret = get_errno(access(path(p), arg2));
4557
        unlock_user(p, arg1, 0);
4558
        break;
4559
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
4560
    case TARGET_NR_faccessat:
4561
        if (!(p = lock_user_string(arg2)))
4562
            goto efault;
4563
        ret = get_errno(sys_faccessat(arg1, p, arg3));
4564
        unlock_user(p, arg2, 0);
4565
        break;
4566
#endif
4567
#ifdef TARGET_NR_nice /* not on alpha */
4568
    case TARGET_NR_nice:
4569
        ret = get_errno(nice(arg1));
4570
        break;
4571
#endif
4572
#ifdef TARGET_NR_ftime
4573
    case TARGET_NR_ftime:
4574
        goto unimplemented;
4575
#endif
4576
    case TARGET_NR_sync:
4577
        sync();
4578
        ret = 0;
4579
        break;
4580
    case TARGET_NR_kill:
4581
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
4582
        break;
4583
    case TARGET_NR_rename:
4584
        {
4585
            void *p2;
4586
            p = lock_user_string(arg1);
4587
            p2 = lock_user_string(arg2);
4588
            if (!p || !p2)
4589
                ret = -TARGET_EFAULT;
4590
            else
4591
                ret = get_errno(rename(p, p2));
4592
            unlock_user(p2, arg2, 0);
4593
            unlock_user(p, arg1, 0);
4594
        }
4595
        break;
4596
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
4597
    case TARGET_NR_renameat:
4598
        {
4599
            void *p2;
4600
            p  = lock_user_string(arg2);
4601
            p2 = lock_user_string(arg4);
4602
            if (!p || !p2)
4603
                ret = -TARGET_EFAULT;
4604
            else
4605
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
4606
            unlock_user(p2, arg4, 0);
4607
            unlock_user(p, arg2, 0);
4608
        }
4609
        break;
4610
#endif
4611
    case TARGET_NR_mkdir:
4612
        if (!(p = lock_user_string(arg1)))
4613
            goto efault;
4614
        ret = get_errno(mkdir(p, arg2));
4615
        unlock_user(p, arg1, 0);
4616
        break;
4617
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
4618
    case TARGET_NR_mkdirat:
4619
        if (!(p = lock_user_string(arg2)))
4620
            goto efault;
4621
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
4622
        unlock_user(p, arg2, 0);
4623
        break;
4624
#endif
4625
    case TARGET_NR_rmdir:
4626
        if (!(p = lock_user_string(arg1)))
4627
            goto efault;
4628
        ret = get_errno(rmdir(p));
4629
        unlock_user(p, arg1, 0);
4630
        break;
4631
    case TARGET_NR_dup:
4632
        ret = get_errno(dup(arg1));
4633
        break;
4634
    case TARGET_NR_pipe:
4635
        ret = do_pipe(cpu_env, arg1, 0);
4636
        break;
4637
#ifdef TARGET_NR_pipe2
4638
    case TARGET_NR_pipe2:
4639
        ret = do_pipe(cpu_env, arg1, arg2);
4640
        break;
4641
#endif
4642
    case TARGET_NR_times:
4643
        {
4644
            struct target_tms *tmsp;
4645
            struct tms tms;
4646
            ret = get_errno(times(&tms));
4647
            if (arg1) {
4648
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
4649
                if (!tmsp)
4650
                    goto efault;
4651
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
4652
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
4653
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
4654
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
4655
            }
4656
            if (!is_error(ret))
4657
                ret = host_to_target_clock_t(ret);
4658
        }
4659
        break;
4660
#ifdef TARGET_NR_prof
4661
    case TARGET_NR_prof:
4662
        goto unimplemented;
4663
#endif
4664
#ifdef TARGET_NR_signal
4665
    case TARGET_NR_signal:
4666
        goto unimplemented;
4667
#endif
4668
    case TARGET_NR_acct:
4669
        if (arg1 == 0) {
4670
            ret = get_errno(acct(NULL));
4671
        } else {
4672
            if (!(p = lock_user_string(arg1)))
4673
                goto efault;
4674
            ret = get_errno(acct(path(p)));
4675
            unlock_user(p, arg1, 0);
4676
        }
4677
        break;
4678
#ifdef TARGET_NR_umount2 /* not on alpha */
4679
    case TARGET_NR_umount2:
4680
        if (!(p = lock_user_string(arg1)))
4681
            goto efault;
4682
        ret = get_errno(umount2(p, arg2));
4683
        unlock_user(p, arg1, 0);
4684
        break;
4685
#endif
4686
#ifdef TARGET_NR_lock
4687
    case TARGET_NR_lock:
4688
        goto unimplemented;
4689
#endif
4690
    case TARGET_NR_ioctl:
4691
        ret = do_ioctl(arg1, arg2, arg3);
4692
        break;
4693
    case TARGET_NR_fcntl:
4694
        ret = do_fcntl(arg1, arg2, arg3);
4695
        break;
4696
#ifdef TARGET_NR_mpx
4697
    case TARGET_NR_mpx:
4698
        goto unimplemented;
4699
#endif
4700
    case TARGET_NR_setpgid:
4701
        ret = get_errno(setpgid(arg1, arg2));
4702
        break;
4703
#ifdef TARGET_NR_ulimit
4704
    case TARGET_NR_ulimit:
4705
        goto unimplemented;
4706
#endif
4707
#ifdef TARGET_NR_oldolduname
4708
    case TARGET_NR_oldolduname:
4709
        goto unimplemented;
4710
#endif
4711
    case TARGET_NR_umask:
4712
        ret = get_errno(umask(arg1));
4713
        break;
4714
    case TARGET_NR_chroot:
4715
        if (!(p = lock_user_string(arg1)))
4716
            goto efault;
4717
        ret = get_errno(chroot(p));
4718
        unlock_user(p, arg1, 0);
4719
        break;
4720
    case TARGET_NR_ustat:
4721
        goto unimplemented;
4722
    case TARGET_NR_dup2:
4723
        ret = get_errno(dup2(arg1, arg2));
4724
        break;
4725
#ifdef TARGET_NR_getppid /* not on alpha */
4726
    case TARGET_NR_getppid:
4727
        ret = get_errno(getppid());
4728
        break;
4729
#endif
4730
    case TARGET_NR_getpgrp:
4731
        ret = get_errno(getpgrp());
4732
        break;
4733
    case TARGET_NR_setsid:
4734
        ret = get_errno(setsid());
4735
        break;
4736
#ifdef TARGET_NR_sigaction
4737
    case TARGET_NR_sigaction:
4738
        {
4739
#if !defined(TARGET_MIPS)
4740
            struct target_old_sigaction *old_act;
4741
            struct target_sigaction act, oact, *pact;
4742
            if (arg2) {
4743
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4744
                    goto efault;
4745
                act._sa_handler = old_act->_sa_handler;
4746
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4747
                act.sa_flags = old_act->sa_flags;
4748
                act.sa_restorer = old_act->sa_restorer;
4749
                unlock_user_struct(old_act, arg2, 0);
4750
                pact = &act;
4751
            } else {
4752
                pact = NULL;
4753
            }
4754
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4755
            if (!is_error(ret) && arg3) {
4756
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4757
                    goto efault;
4758
                old_act->_sa_handler = oact._sa_handler;
4759
                old_act->sa_mask = oact.sa_mask.sig[0];
4760
                old_act->sa_flags = oact.sa_flags;
4761
                old_act->sa_restorer = oact.sa_restorer;
4762
                unlock_user_struct(old_act, arg3, 1);
4763
            }
4764
#else
4765
            struct target_sigaction act, oact, *pact, *old_act;
4766

    
4767
            if (arg2) {
4768
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4769
                    goto efault;
4770
                act._sa_handler = old_act->_sa_handler;
4771
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
4772
                act.sa_flags = old_act->sa_flags;
4773
                unlock_user_struct(old_act, arg2, 0);
4774
                pact = &act;
4775
            } else {
4776
                pact = NULL;
4777
            }
4778

    
4779
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4780

    
4781
            if (!is_error(ret) && arg3) {
4782
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4783
                    goto efault;
4784
                old_act->_sa_handler = oact._sa_handler;
4785
                old_act->sa_flags = oact.sa_flags;
4786
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
4787
                old_act->sa_mask.sig[1] = 0;
4788
                old_act->sa_mask.sig[2] = 0;
4789
                old_act->sa_mask.sig[3] = 0;
4790
                unlock_user_struct(old_act, arg3, 1);
4791
            }
4792
#endif
4793
        }
4794
        break;
4795
#endif
4796
    case TARGET_NR_rt_sigaction:
4797
        {
4798
            struct target_sigaction *act;
4799
            struct target_sigaction *oact;
4800

    
4801
            if (arg2) {
4802
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
4803
                    goto efault;
4804
            } else
4805
                act = NULL;
4806
            if (arg3) {
4807
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
4808
                    ret = -TARGET_EFAULT;
4809
                    goto rt_sigaction_fail;
4810
                }
4811
            } else
4812
                oact = NULL;
4813
            ret = get_errno(do_sigaction(arg1, act, oact));
4814
        rt_sigaction_fail:
4815
            if (act)
4816
                unlock_user_struct(act, arg2, 0);
4817
            if (oact)
4818
                unlock_user_struct(oact, arg3, 1);
4819
        }
4820
        break;
4821
#ifdef TARGET_NR_sgetmask /* not on alpha */
4822
    case TARGET_NR_sgetmask:
4823
        {
4824
            sigset_t cur_set;
4825
            abi_ulong target_set;
4826
            sigprocmask(0, NULL, &cur_set);
4827
            host_to_target_old_sigset(&target_set, &cur_set);
4828
            ret = target_set;
4829
        }
4830
        break;
4831
#endif
4832
#ifdef TARGET_NR_ssetmask /* not on alpha */
4833
    case TARGET_NR_ssetmask:
4834
        {
4835
            sigset_t set, oset, cur_set;
4836
            abi_ulong target_set = arg1;
4837
            sigprocmask(0, NULL, &cur_set);
4838
            target_to_host_old_sigset(&set, &target_set);
4839
            sigorset(&set, &set, &cur_set);
4840
            sigprocmask(SIG_SETMASK, &set, &oset);
4841
            host_to_target_old_sigset(&target_set, &oset);
4842
            ret = target_set;
4843
        }
4844
        break;
4845
#endif
4846
#ifdef TARGET_NR_sigprocmask
4847
    case TARGET_NR_sigprocmask:
4848
        {
4849
            int how = arg1;
4850
            sigset_t set, oldset, *set_ptr;
4851

    
4852
            if (arg2) {
4853
                switch(how) {
4854
                case TARGET_SIG_BLOCK:
4855
                    how = SIG_BLOCK;
4856
                    break;
4857
                case TARGET_SIG_UNBLOCK:
4858
                    how = SIG_UNBLOCK;
4859
                    break;
4860
                case TARGET_SIG_SETMASK:
4861
                    how = SIG_SETMASK;
4862
                    break;
4863
                default:
4864
                    ret = -TARGET_EINVAL;
4865
                    goto fail;
4866
                }
4867
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4868
                    goto efault;
4869
                target_to_host_old_sigset(&set, p);
4870
                unlock_user(p, arg2, 0);
4871
                set_ptr = &set;
4872
            } else {
4873
                how = 0;
4874
                set_ptr = NULL;
4875
            }
4876
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
4877
            if (!is_error(ret) && arg3) {
4878
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4879
                    goto efault;
4880
                host_to_target_old_sigset(p, &oldset);
4881
                unlock_user(p, arg3, sizeof(target_sigset_t));
4882
            }
4883
        }
4884
        break;
4885
#endif
4886
    case TARGET_NR_rt_sigprocmask:
4887
        {
4888
            int how = arg1;
4889
            sigset_t set, oldset, *set_ptr;
4890

    
4891
            if (arg2) {
4892
                switch(how) {
4893
                case TARGET_SIG_BLOCK:
4894
                    how = SIG_BLOCK;
4895
                    break;
4896
                case TARGET_SIG_UNBLOCK:
4897
                    how = SIG_UNBLOCK;
4898
                    break;
4899
                case TARGET_SIG_SETMASK:
4900
                    how = SIG_SETMASK;
4901
                    break;
4902
                default:
4903
                    ret = -TARGET_EINVAL;
4904
                    goto fail;
4905
                }
4906
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
4907
                    goto efault;
4908
                target_to_host_sigset(&set, p);
4909
                unlock_user(p, arg2, 0);
4910
                set_ptr = &set;
4911
            } else {
4912
                how = 0;
4913
                set_ptr = NULL;
4914
            }
4915
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
4916
            if (!is_error(ret) && arg3) {
4917
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
4918
                    goto efault;
4919
                host_to_target_sigset(p, &oldset);
4920
                unlock_user(p, arg3, sizeof(target_sigset_t));
4921
            }
4922
        }
4923
        break;
4924
#ifdef TARGET_NR_sigpending
4925
    case TARGET_NR_sigpending:
4926
        {
4927
            sigset_t set;
4928
            ret = get_errno(sigpending(&set));
4929
            if (!is_error(ret)) {
4930
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4931
                    goto efault;
4932
                host_to_target_old_sigset(p, &set);
4933
                unlock_user(p, arg1, sizeof(target_sigset_t));
4934
            }
4935
        }
4936
        break;
4937
#endif
4938
    case TARGET_NR_rt_sigpending:
4939
        {
4940
            sigset_t set;
4941
            ret = get_errno(sigpending(&set));
4942
            if (!is_error(ret)) {
4943
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
4944
                    goto efault;
4945
                host_to_target_sigset(p, &set);
4946
                unlock_user(p, arg1, sizeof(target_sigset_t));
4947
            }
4948
        }
4949
        break;
4950
#ifdef TARGET_NR_sigsuspend
4951
    case TARGET_NR_sigsuspend:
4952
        {
4953
            sigset_t set;
4954
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4955
                goto efault;
4956
            target_to_host_old_sigset(&set, p);
4957
            unlock_user(p, arg1, 0);
4958
            ret = get_errno(sigsuspend(&set));
4959
        }
4960
        break;
4961
#endif
4962
    case TARGET_NR_rt_sigsuspend:
4963
        {
4964
            sigset_t set;
4965
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4966
                goto efault;
4967
            target_to_host_sigset(&set, p);
4968
            unlock_user(p, arg1, 0);
4969
            ret = get_errno(sigsuspend(&set));
4970
        }
4971
        break;
4972
    case TARGET_NR_rt_sigtimedwait:
4973
        {
4974
            sigset_t set;
4975
            struct timespec uts, *puts;
4976
            siginfo_t uinfo;
4977

    
4978
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
4979
                goto efault;
4980
            target_to_host_sigset(&set, p);
4981
            unlock_user(p, arg1, 0);
4982
            if (arg3) {
4983
                puts = &uts;
4984
                target_to_host_timespec(puts, arg3);
4985
            } else {
4986
                puts = NULL;
4987
            }
4988
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
4989
            if (!is_error(ret) && arg2) {
4990
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
4991
                    goto efault;
4992
                host_to_target_siginfo(p, &uinfo);
4993
                unlock_user(p, arg2, sizeof(target_siginfo_t));
4994
            }
4995
        }
4996
        break;
4997
    case TARGET_NR_rt_sigqueueinfo:
4998
        {
4999
            siginfo_t uinfo;
5000
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
5001
                goto efault;
5002
            target_to_host_siginfo(&uinfo, p);
5003
            unlock_user(p, arg1, 0);
5004
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
5005
        }
5006
        break;
5007
#ifdef TARGET_NR_sigreturn
5008
    case TARGET_NR_sigreturn:
5009
        /* NOTE: ret is eax, so not transcoding must be done */
5010
        ret = do_sigreturn(cpu_env);
5011
        break;
5012
#endif
5013
    case TARGET_NR_rt_sigreturn:
5014
        /* NOTE: ret is eax, so not transcoding must be done */
5015
        ret = do_rt_sigreturn(cpu_env);
5016
        break;
5017
    case TARGET_NR_sethostname:
5018
        if (!(p = lock_user_string(arg1)))
5019
            goto efault;
5020
        ret = get_errno(sethostname(p, arg2));
5021
        unlock_user(p, arg1, 0);
5022
        break;
5023
    case TARGET_NR_setrlimit:
5024
        {
5025
            /* XXX: convert resource ? */
5026
            int resource = arg1;
5027
            struct target_rlimit *target_rlim;
5028
            struct rlimit rlim;
5029
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
5030
                goto efault;
5031
            rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
5032
            rlim.rlim_max = tswapl(target_rlim->rlim_max);
5033
            unlock_user_struct(target_rlim, arg2, 0);
5034
            ret = get_errno(setrlimit(resource, &rlim));
5035
        }
5036
        break;
5037
    case TARGET_NR_getrlimit:
5038
        {
5039
            /* XXX: convert resource ? */
5040
            int resource = arg1;
5041
            struct target_rlimit *target_rlim;
5042
            struct rlimit rlim;
5043

    
5044
            ret = get_errno(getrlimit(resource, &rlim));
5045
            if (!is_error(ret)) {
5046
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5047
                    goto efault;
5048
                target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
5049
                target_rlim->rlim_max = tswapl(rlim.rlim_max);
5050
                unlock_user_struct(target_rlim, arg2, 1);
5051
            }
5052
        }
5053
        break;
5054
    case TARGET_NR_getrusage:
5055
        {
5056
            struct rusage rusage;
5057
            ret = get_errno(getrusage(arg1, &rusage));
5058
            if (!is_error(ret)) {
5059
                host_to_target_rusage(arg2, &rusage);
5060
            }
5061
        }
5062
        break;
5063
    case TARGET_NR_gettimeofday:
5064
        {
5065
            struct timeval tv;
5066
            ret = get_errno(gettimeofday(&tv, NULL));
5067
            if (!is_error(ret)) {
5068
                if (copy_to_user_timeval(arg1, &tv))
5069
                    goto efault;
5070
            }
5071
        }
5072
        break;
5073
    case TARGET_NR_settimeofday:
5074
        {
5075
            struct timeval tv;
5076
            if (copy_from_user_timeval(&tv, arg1))
5077
                goto efault;
5078
            ret = get_errno(settimeofday(&tv, NULL));
5079
        }
5080
        break;
5081
#ifdef TARGET_NR_select
5082
    case TARGET_NR_select:
5083
        {
5084
            struct target_sel_arg_struct *sel;
5085
            abi_ulong inp, outp, exp, tvp;
5086
            long nsel;
5087

    
5088
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
5089
                goto efault;
5090
            nsel = tswapl(sel->n);
5091
            inp = tswapl(sel->inp);
5092
            outp = tswapl(sel->outp);
5093
            exp = tswapl(sel->exp);
5094
            tvp = tswapl(sel->tvp);
5095
            unlock_user_struct(sel, arg1, 0);
5096
            ret = do_select(nsel, inp, outp, exp, tvp);
5097
        }
5098
        break;
5099
#endif
5100
    case TARGET_NR_symlink:
5101
        {
5102
            void *p2;
5103
            p = lock_user_string(arg1);
5104
            p2 = lock_user_string(arg2);
5105
            if (!p || !p2)
5106
                ret = -TARGET_EFAULT;
5107
            else
5108
                ret = get_errno(symlink(p, p2));
5109
            unlock_user(p2, arg2, 0);
5110
            unlock_user(p, arg1, 0);
5111
        }
5112
        break;
5113
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5114
    case TARGET_NR_symlinkat:
5115
        {
5116
            void *p2;
5117
            p  = lock_user_string(arg1);
5118
            p2 = lock_user_string(arg3);
5119
            if (!p || !p2)
5120
                ret = -TARGET_EFAULT;
5121
            else
5122
                ret = get_errno(sys_symlinkat(p, arg2, p2));
5123
            unlock_user(p2, arg3, 0);
5124
            unlock_user(p, arg1, 0);
5125
        }
5126
        break;
5127
#endif
5128
#ifdef TARGET_NR_oldlstat
5129
    case TARGET_NR_oldlstat:
5130
        goto unimplemented;
5131
#endif
5132
    case TARGET_NR_readlink:
5133
        {
5134
            void *p2, *temp;
5135
            p = lock_user_string(arg1);
5136
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
5137
            if (!p || !p2)
5138
                ret = -TARGET_EFAULT;
5139
            else {
5140
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5141
                    char real[PATH_MAX];
5142
                    temp = realpath(exec_path,real);
5143
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5144
                    snprintf((char *)p2, arg3, "%s", real);
5145
                    }
5146
                else
5147
                    ret = get_errno(readlink(path(p), p2, arg3));
5148
            }
5149
            unlock_user(p2, arg2, ret);
5150
            unlock_user(p, arg1, 0);
5151
        }
5152
        break;
5153
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5154
    case TARGET_NR_readlinkat:
5155
        {
5156
            void *p2;
5157
            p  = lock_user_string(arg2);
5158
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5159
            if (!p || !p2)
5160
                ret = -TARGET_EFAULT;
5161
            else
5162
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5163
            unlock_user(p2, arg3, ret);
5164
            unlock_user(p, arg2, 0);
5165
        }
5166
        break;
5167
#endif
5168
#ifdef TARGET_NR_uselib
5169
    case TARGET_NR_uselib:
5170
        goto unimplemented;
5171
#endif
5172
#ifdef TARGET_NR_swapon
5173
    case TARGET_NR_swapon:
5174
        if (!(p = lock_user_string(arg1)))
5175
            goto efault;
5176
        ret = get_errno(swapon(p, arg2));
5177
        unlock_user(p, arg1, 0);
5178
        break;
5179
#endif
5180
    case TARGET_NR_reboot:
5181
        goto unimplemented;
5182
#ifdef TARGET_NR_readdir
5183
    case TARGET_NR_readdir:
5184
        goto unimplemented;
5185
#endif
5186
#ifdef TARGET_NR_mmap
5187
    case TARGET_NR_mmap:
5188
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
5189
        {
5190
            abi_ulong *v;
5191
            abi_ulong v1, v2, v3, v4, v5, v6;
5192
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5193
                goto efault;
5194
            v1 = tswapl(v[0]);
5195
            v2 = tswapl(v[1]);
5196
            v3 = tswapl(v[2]);
5197
            v4 = tswapl(v[3]);
5198
            v5 = tswapl(v[4]);
5199
            v6 = tswapl(v[5]);
5200
            unlock_user(v, arg1, 0);
5201
            ret = get_errno(target_mmap(v1, v2, v3,
5202
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
5203
                                        v5, v6));
5204
        }
5205
#else
5206
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5207
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5208
                                    arg5,
5209
                                    arg6));
5210
#endif
5211
        break;
5212
#endif
5213
#ifdef TARGET_NR_mmap2
5214
    case TARGET_NR_mmap2:
5215
#ifndef MMAP_SHIFT
5216
#define MMAP_SHIFT 12
5217
#endif
5218
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5219
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5220
                                    arg5,
5221
                                    arg6 << MMAP_SHIFT));
5222
        break;
5223
#endif
5224
    case TARGET_NR_munmap:
5225
        ret = get_errno(target_munmap(arg1, arg2));
5226
        break;
5227
    case TARGET_NR_mprotect:
5228
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
5229
        break;
5230
#ifdef TARGET_NR_mremap
5231
    case TARGET_NR_mremap:
5232
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5233
        break;
5234
#endif
5235
        /* ??? msync/mlock/munlock are broken for softmmu.  */
5236
#ifdef TARGET_NR_msync
5237
    case TARGET_NR_msync:
5238
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
5239
        break;
5240
#endif
5241
#ifdef TARGET_NR_mlock
5242
    case TARGET_NR_mlock:
5243
        ret = get_errno(mlock(g2h(arg1), arg2));
5244
        break;
5245
#endif
5246
#ifdef TARGET_NR_munlock
5247
    case TARGET_NR_munlock:
5248
        ret = get_errno(munlock(g2h(arg1), arg2));
5249
        break;
5250
#endif
5251
#ifdef TARGET_NR_mlockall
5252
    case TARGET_NR_mlockall:
5253
        ret = get_errno(mlockall(arg1));
5254
        break;
5255
#endif
5256
#ifdef TARGET_NR_munlockall
5257
    case TARGET_NR_munlockall:
5258
        ret = get_errno(munlockall());
5259
        break;
5260
#endif
5261
    case TARGET_NR_truncate:
5262
        if (!(p = lock_user_string(arg1)))
5263
            goto efault;
5264
        ret = get_errno(truncate(p, arg2));
5265
        unlock_user(p, arg1, 0);
5266
        break;
5267
    case TARGET_NR_ftruncate:
5268
        ret = get_errno(ftruncate(arg1, arg2));
5269
        break;
5270
    case TARGET_NR_fchmod:
5271
        ret = get_errno(fchmod(arg1, arg2));
5272
        break;
5273
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5274
    case TARGET_NR_fchmodat:
5275
        if (!(p = lock_user_string(arg2)))
5276
            goto efault;
5277
        ret = get_errno(sys_fchmodat(arg1, p, arg3));
5278
        unlock_user(p, arg2, 0);
5279
        break;
5280
#endif
5281
    case TARGET_NR_getpriority:
5282
        /* libc does special remapping of the return value of
5283
         * sys_getpriority() so it's just easiest to call
5284
         * sys_getpriority() directly rather than through libc. */
5285
        ret = sys_getpriority(arg1, arg2);
5286
        break;
5287
    case TARGET_NR_setpriority:
5288
        ret = get_errno(setpriority(arg1, arg2, arg3));
5289
        break;
5290
#ifdef TARGET_NR_profil
5291
    case TARGET_NR_profil:
5292
        goto unimplemented;
5293
#endif
5294
    case TARGET_NR_statfs:
5295
        if (!(p = lock_user_string(arg1)))
5296
            goto efault;
5297
        ret = get_errno(statfs(path(p), &stfs));
5298
        unlock_user(p, arg1, 0);
5299
    convert_statfs:
5300
        if (!is_error(ret)) {
5301
            struct target_statfs *target_stfs;
5302

    
5303
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5304
                goto efault;
5305
            __put_user(stfs.f_type, &target_stfs->f_type);
5306
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5307
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5308
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5309
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5310
            __put_user(stfs.f_files, &target_stfs->f_files);
5311
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5312
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5313
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5314
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5315
            unlock_user_struct(target_stfs, arg2, 1);
5316
        }
5317
        break;
5318
    case TARGET_NR_fstatfs:
5319
        ret = get_errno(fstatfs(arg1, &stfs));
5320
        goto convert_statfs;
5321
#ifdef TARGET_NR_statfs64
5322
    case TARGET_NR_statfs64:
5323
        if (!(p = lock_user_string(arg1)))
5324
            goto efault;
5325
        ret = get_errno(statfs(path(p), &stfs));
5326
        unlock_user(p, arg1, 0);
5327
    convert_statfs64:
5328
        if (!is_error(ret)) {
5329
            struct target_statfs64 *target_stfs;
5330

    
5331
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5332
                goto efault;
5333
            __put_user(stfs.f_type, &target_stfs->f_type);
5334
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5335
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5336
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5337
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5338
            __put_user(stfs.f_files, &target_stfs->f_files);
5339
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5340
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5341
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5342
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5343
            unlock_user_struct(target_stfs, arg3, 1);
5344
        }
5345
        break;
5346
    case TARGET_NR_fstatfs64:
5347
        ret = get_errno(fstatfs(arg1, &stfs));
5348
        goto convert_statfs64;
5349
#endif
5350
#ifdef TARGET_NR_ioperm
5351
    case TARGET_NR_ioperm:
5352
        goto unimplemented;
5353
#endif
5354
#ifdef TARGET_NR_socketcall
5355
    case TARGET_NR_socketcall:
5356
        ret = do_socketcall(arg1, arg2);
5357
        break;
5358
#endif
5359
#ifdef TARGET_NR_accept
5360
    case TARGET_NR_accept:
5361
        ret = do_accept(arg1, arg2, arg3);
5362
        break;
5363
#endif
5364
#ifdef TARGET_NR_bind
5365
    case TARGET_NR_bind:
5366
        ret = do_bind(arg1, arg2, arg3);
5367
        break;
5368
#endif
5369
#ifdef TARGET_NR_connect
5370
    case TARGET_NR_connect:
5371
        ret = do_connect(arg1, arg2, arg3);
5372
        break;
5373
#endif
5374
#ifdef TARGET_NR_getpeername
5375
    case TARGET_NR_getpeername:
5376
        ret = do_getpeername(arg1, arg2, arg3);
5377
        break;
5378
#endif
5379
#ifdef TARGET_NR_getsockname
5380
    case TARGET_NR_getsockname:
5381
        ret = do_getsockname(arg1, arg2, arg3);
5382
        break;
5383
#endif
5384
#ifdef TARGET_NR_getsockopt
5385
    case TARGET_NR_getsockopt:
5386
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
5387
        break;
5388
#endif
5389
#ifdef TARGET_NR_listen
5390
    case TARGET_NR_listen:
5391
        ret = get_errno(listen(arg1, arg2));
5392
        break;
5393
#endif
5394
#ifdef TARGET_NR_recv
5395
    case TARGET_NR_recv:
5396
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
5397
        break;
5398
#endif
5399
#ifdef TARGET_NR_recvfrom
5400
    case TARGET_NR_recvfrom:
5401
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
5402
        break;
5403
#endif
5404
#ifdef TARGET_NR_recvmsg
5405
    case TARGET_NR_recvmsg:
5406
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
5407
        break;
5408
#endif
5409
#ifdef TARGET_NR_send
5410
    case TARGET_NR_send:
5411
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
5412
        break;
5413
#endif
5414
#ifdef TARGET_NR_sendmsg
5415
    case TARGET_NR_sendmsg:
5416
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
5417
        break;
5418
#endif
5419
#ifdef TARGET_NR_sendto
5420
    case TARGET_NR_sendto:
5421
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
5422
        break;
5423
#endif
5424
#ifdef TARGET_NR_shutdown
5425
    case TARGET_NR_shutdown:
5426
        ret = get_errno(shutdown(arg1, arg2));
5427
        break;
5428
#endif
5429
#ifdef TARGET_NR_socket
5430
    case TARGET_NR_socket:
5431
        ret = do_socket(arg1, arg2, arg3);
5432
        break;
5433
#endif
5434
#ifdef TARGET_NR_socketpair
5435
    case TARGET_NR_socketpair:
5436
        ret = do_socketpair(arg1, arg2, arg3, arg4);
5437
        break;
5438
#endif
5439
#ifdef TARGET_NR_setsockopt
5440
    case TARGET_NR_setsockopt:
5441
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
5442
        break;
5443
#endif
5444

    
5445
    case TARGET_NR_syslog:
5446
        if (!(p = lock_user_string(arg2)))
5447
            goto efault;
5448
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
5449
        unlock_user(p, arg2, 0);
5450
        break;
5451

    
5452
    case TARGET_NR_setitimer:
5453
        {
5454
            struct itimerval value, ovalue, *pvalue;
5455

    
5456
            if (arg2) {
5457
                pvalue = &value;
5458
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
5459
                    || copy_from_user_timeval(&pvalue->it_value,
5460
                                              arg2 + sizeof(struct target_timeval)))
5461
                    goto efault;
5462
            } else {
5463
                pvalue = NULL;
5464
            }
5465
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
5466
            if (!is_error(ret) && arg3) {
5467
                if (copy_to_user_timeval(arg3,
5468
                                         &ovalue.it_interval)
5469
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
5470
                                            &ovalue.it_value))
5471
                    goto efault;
5472
            }
5473
        }
5474
        break;
5475
    case TARGET_NR_getitimer:
5476
        {
5477
            struct itimerval value;
5478

    
5479
            ret = get_errno(getitimer(arg1, &value));
5480
            if (!is_error(ret) && arg2) {
5481
                if (copy_to_user_timeval(arg2,
5482
                                         &value.it_interval)
5483
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
5484
                                            &value.it_value))
5485
                    goto efault;
5486
            }
5487
        }
5488
        break;
5489
    case TARGET_NR_stat:
5490
        if (!(p = lock_user_string(arg1)))
5491
            goto efault;
5492
        ret = get_errno(stat(path(p), &st));
5493
        unlock_user(p, arg1, 0);
5494
        goto do_stat;
5495
    case TARGET_NR_lstat:
5496
        if (!(p = lock_user_string(arg1)))
5497
            goto efault;
5498
        ret = get_errno(lstat(path(p), &st));
5499
        unlock_user(p, arg1, 0);
5500
        goto do_stat;
5501
    case TARGET_NR_fstat:
5502
        {
5503
            ret = get_errno(fstat(arg1, &st));
5504
        do_stat:
5505
            if (!is_error(ret)) {
5506
                struct target_stat *target_st;
5507

    
5508
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5509
                    goto efault;
5510
                __put_user(st.st_dev, &target_st->st_dev);
5511
                __put_user(st.st_ino, &target_st->st_ino);
5512
                __put_user(st.st_mode, &target_st->st_mode);
5513
                __put_user(st.st_uid, &target_st->st_uid);
5514
                __put_user(st.st_gid, &target_st->st_gid);
5515
                __put_user(st.st_nlink, &target_st->st_nlink);
5516
                __put_user(st.st_rdev, &target_st->st_rdev);
5517
                __put_user(st.st_size, &target_st->st_size);
5518
                __put_user(st.st_blksize, &target_st->st_blksize);
5519
                __put_user(st.st_blocks, &target_st->st_blocks);
5520
                __put_user(st.st_atime, &target_st->target_st_atime);
5521
                __put_user(st.st_mtime, &target_st->target_st_mtime);
5522
                __put_user(st.st_ctime, &target_st->target_st_ctime);
5523
                unlock_user_struct(target_st, arg2, 1);
5524
            }
5525
        }
5526
        break;
5527
#ifdef TARGET_NR_olduname
5528
    case TARGET_NR_olduname:
5529
        goto unimplemented;
5530
#endif
5531
#ifdef TARGET_NR_iopl
5532
    case TARGET_NR_iopl:
5533
        goto unimplemented;
5534
#endif
5535
    case TARGET_NR_vhangup:
5536
        ret = get_errno(vhangup());
5537
        break;
5538
#ifdef TARGET_NR_idle
5539
    case TARGET_NR_idle:
5540
        goto unimplemented;
5541
#endif
5542
#ifdef TARGET_NR_syscall
5543
    case TARGET_NR_syscall:
5544
            ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
5545
            break;
5546
#endif
5547
    case TARGET_NR_wait4:
5548
        {
5549
            int status;
5550
            abi_long status_ptr = arg2;
5551
            struct rusage rusage, *rusage_ptr;
5552
            abi_ulong target_rusage = arg4;
5553
            if (target_rusage)
5554
                rusage_ptr = &rusage;
5555
            else
5556
                rusage_ptr = NULL;
5557
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
5558
            if (!is_error(ret)) {
5559
                if (status_ptr) {
5560
                    status = host_to_target_waitstatus(status);
5561
                    if (put_user_s32(status, status_ptr))
5562
                        goto efault;
5563
                }
5564
                if (target_rusage)
5565
                    host_to_target_rusage(target_rusage, &rusage);
5566
            }
5567
        }
5568
        break;
5569
#ifdef TARGET_NR_swapoff
5570
    case TARGET_NR_swapoff:
5571
        if (!(p = lock_user_string(arg1)))
5572
            goto efault;
5573
        ret = get_errno(swapoff(p));
5574
        unlock_user(p, arg1, 0);
5575
        break;
5576
#endif
5577
    case TARGET_NR_sysinfo:
5578
        {
5579
            struct target_sysinfo *target_value;
5580
            struct sysinfo value;
5581
            ret = get_errno(sysinfo(&value));
5582
            if (!is_error(ret) && arg1)
5583
            {
5584
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
5585
                    goto efault;
5586
                __put_user(value.uptime, &target_value->uptime);
5587
                __put_user(value.loads[0], &target_value->loads[0]);
5588
                __put_user(value.loads[1], &target_value->loads[1]);
5589
                __put_user(value.loads[2], &target_value->loads[2]);
5590
                __put_user(value.totalram, &target_value->totalram);
5591
                __put_user(value.freeram, &target_value->freeram);
5592
                __put_user(value.sharedram, &target_value->sharedram);
5593
                __put_user(value.bufferram, &target_value->bufferram);
5594
                __put_user(value.totalswap, &target_value->totalswap);
5595
                __put_user(value.freeswap, &target_value->freeswap);
5596
                __put_user(value.procs, &target_value->procs);
5597
                __put_user(value.totalhigh, &target_value->totalhigh);
5598
                __put_user(value.freehigh, &target_value->freehigh);
5599
                __put_user(value.mem_unit, &target_value->mem_unit);
5600
                unlock_user_struct(target_value, arg1, 1);
5601
            }
5602
        }
5603
        break;
5604
#ifdef TARGET_NR_ipc
5605
    case TARGET_NR_ipc:
5606
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
5607
        break;
5608
#endif
5609
#ifdef TARGET_NR_semget
5610
    case TARGET_NR_semget:
5611
        ret = get_errno(semget(arg1, arg2, arg3));
5612
        break;
5613
#endif
5614
#ifdef TARGET_NR_semop
5615
    case TARGET_NR_semop:
5616
        ret = get_errno(do_semop(arg1, arg2, arg3));
5617
        break;
5618
#endif
5619
#ifdef TARGET_NR_semctl
5620
    case TARGET_NR_semctl:
5621
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
5622
        break;
5623
#endif
5624
#ifdef TARGET_NR_msgctl
5625
    case TARGET_NR_msgctl:
5626
        ret = do_msgctl(arg1, arg2, arg3);
5627
        break;
5628
#endif
5629
#ifdef TARGET_NR_msgget
5630
    case TARGET_NR_msgget:
5631
        ret = get_errno(msgget(arg1, arg2));
5632
        break;
5633
#endif
5634
#ifdef TARGET_NR_msgrcv
5635
    case TARGET_NR_msgrcv:
5636
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
5637
        break;
5638
#endif
5639
#ifdef TARGET_NR_msgsnd
5640
    case TARGET_NR_msgsnd:
5641
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
5642
        break;
5643
#endif
5644
#ifdef TARGET_NR_shmget
5645
    case TARGET_NR_shmget:
5646
        ret = get_errno(shmget(arg1, arg2, arg3));
5647
        break;
5648
#endif
5649
#ifdef TARGET_NR_shmctl
5650
    case TARGET_NR_shmctl:
5651
        ret = do_shmctl(arg1, arg2, arg3);
5652
        break;
5653
#endif
5654
#ifdef TARGET_NR_shmat
5655
    case TARGET_NR_shmat:
5656
        ret = do_shmat(arg1, arg2, arg3);
5657
        break;
5658
#endif
5659
#ifdef TARGET_NR_shmdt
5660
    case TARGET_NR_shmdt:
5661
        ret = do_shmdt(arg1);
5662
        break;
5663
#endif
5664
    case TARGET_NR_fsync:
5665
        ret = get_errno(fsync(arg1));
5666
        break;
5667
    case TARGET_NR_clone:
5668
#if defined(TARGET_SH4)
5669
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
5670
#elif defined(TARGET_CRIS)
5671
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
5672
#else
5673
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
5674
#endif
5675
        break;
5676
#ifdef __NR_exit_group
5677
        /* new thread calls */
5678
    case TARGET_NR_exit_group:
5679
#ifdef TARGET_GPROF
5680
        _mcleanup();
5681
#endif
5682
        gdb_exit(cpu_env, arg1);
5683
        ret = get_errno(exit_group(arg1));
5684
        break;
5685
#endif
5686
    case TARGET_NR_setdomainname:
5687
        if (!(p = lock_user_string(arg1)))
5688
            goto efault;
5689
        ret = get_errno(setdomainname(p, arg2));
5690
        unlock_user(p, arg1, 0);
5691
        break;
5692
    case TARGET_NR_uname:
5693
        /* no need to transcode because we use the linux syscall */
5694
        {
5695
            struct new_utsname * buf;
5696

    
5697
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
5698
                goto efault;
5699
            ret = get_errno(sys_uname(buf));
5700
            if (!is_error(ret)) {
5701
                /* Overrite the native machine name with whatever is being
5702
                   emulated. */
5703
                strcpy (buf->machine, UNAME_MACHINE);
5704
                /* Allow the user to override the reported release.  */
5705
                if (qemu_uname_release && *qemu_uname_release)
5706
                  strcpy (buf->release, qemu_uname_release);
5707
            }
5708
            unlock_user_struct(buf, arg1, 1);
5709
        }
5710
        break;
5711
#ifdef TARGET_I386
5712
    case TARGET_NR_modify_ldt:
5713
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
5714
        break;
5715
#if !defined(TARGET_X86_64)
5716
    case TARGET_NR_vm86old:
5717
        goto unimplemented;
5718
    case TARGET_NR_vm86:
5719
        ret = do_vm86(cpu_env, arg1, arg2);
5720
        break;
5721
#endif
5722
#endif
5723
    case TARGET_NR_adjtimex:
5724
        goto unimplemented;
5725
#ifdef TARGET_NR_create_module
5726
    case TARGET_NR_create_module:
5727
#endif
5728
    case TARGET_NR_init_module:
5729
    case TARGET_NR_delete_module:
5730
#ifdef TARGET_NR_get_kernel_syms
5731
    case TARGET_NR_get_kernel_syms:
5732
#endif
5733
        goto unimplemented;
5734
    case TARGET_NR_quotactl:
5735
        goto unimplemented;
5736
    case TARGET_NR_getpgid:
5737
        ret = get_errno(getpgid(arg1));
5738
        break;
5739
    case TARGET_NR_fchdir:
5740
        ret = get_errno(fchdir(arg1));
5741
        break;
5742
#ifdef TARGET_NR_bdflush /* not on x86_64 */
5743
    case TARGET_NR_bdflush:
5744
        goto unimplemented;
5745
#endif
5746
#ifdef TARGET_NR_sysfs
5747
    case TARGET_NR_sysfs:
5748
        goto unimplemented;
5749
#endif
5750
    case TARGET_NR_personality:
5751
        ret = get_errno(personality(arg1));
5752
        break;
5753
#ifdef TARGET_NR_afs_syscall
5754
    case TARGET_NR_afs_syscall:
5755
        goto unimplemented;
5756
#endif
5757
#ifdef TARGET_NR__llseek /* Not on alpha */
5758
    case TARGET_NR__llseek:
5759
        {
5760
#if defined (__x86_64__)
5761
            ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
5762
            if (put_user_s64(ret, arg4))
5763
                goto efault;
5764
#else
5765
            int64_t res;
5766
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
5767
            if (put_user_s64(res, arg4))
5768
                goto efault;
5769
#endif
5770
        }
5771
        break;
5772
#endif
5773
    case TARGET_NR_getdents:
5774
#if TARGET_ABI_BITS != 32
5775
        goto unimplemented;
5776
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
5777
        {
5778
            struct target_dirent *target_dirp;
5779
            struct linux_dirent *dirp;
5780
            abi_long count = arg3;
5781

    
5782
            dirp = malloc(count);
5783
            if (!dirp) {
5784
                ret = -TARGET_ENOMEM;
5785
                goto fail;
5786
            }
5787

    
5788
            ret = get_errno(sys_getdents(arg1, dirp, count));
5789
            if (!is_error(ret)) {
5790
                struct linux_dirent *de;
5791
                struct target_dirent *tde;
5792
                int len = ret;
5793
                int reclen, treclen;
5794
                int count1, tnamelen;
5795

    
5796
                count1 = 0;
5797
                de = dirp;
5798
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5799
                    goto efault;
5800
                tde = target_dirp;
5801
                while (len > 0) {
5802
                    reclen = de->d_reclen;
5803
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
5804
                    tde->d_reclen = tswap16(treclen);
5805
                    tde->d_ino = tswapl(de->d_ino);
5806
                    tde->d_off = tswapl(de->d_off);
5807
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
5808
                    if (tnamelen > 256)
5809
                        tnamelen = 256;
5810
                    /* XXX: may not be correct */
5811
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
5812
                    de = (struct linux_dirent *)((char *)de + reclen);
5813
                    len -= reclen;
5814
                    tde = (struct target_dirent *)((char *)tde + treclen);
5815
                    count1 += treclen;
5816
                }
5817
                ret = count1;
5818
                unlock_user(target_dirp, arg2, ret);
5819
            }
5820
            free(dirp);
5821
        }
5822
#else
5823
        {
5824
            struct linux_dirent *dirp;
5825
            abi_long count = arg3;
5826

    
5827
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5828
                goto efault;
5829
            ret = get_errno(sys_getdents(arg1, dirp, count));
5830
            if (!is_error(ret)) {
5831
                struct linux_dirent *de;
5832
                int len = ret;
5833
                int reclen;
5834
                de = dirp;
5835
                while (len > 0) {
5836
                    reclen = de->d_reclen;
5837
                    if (reclen > len)
5838
                        break;
5839
                    de->d_reclen = tswap16(reclen);
5840
                    tswapls(&de->d_ino);
5841
                    tswapls(&de->d_off);
5842
                    de = (struct linux_dirent *)((char *)de + reclen);
5843
                    len -= reclen;
5844
                }
5845
            }
5846
            unlock_user(dirp, arg2, ret);
5847
        }
5848
#endif
5849
        break;
5850
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
5851
    case TARGET_NR_getdents64:
5852
        {
5853
            struct linux_dirent64 *dirp;
5854
            abi_long count = arg3;
5855
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
5856
                goto efault;
5857
            ret = get_errno(sys_getdents64(arg1, dirp, count));
5858
            if (!is_error(ret)) {
5859
                struct linux_dirent64 *de;
5860
                int len = ret;
5861
                int reclen;
5862
                de = dirp;
5863
                while (len > 0) {
5864
                    reclen = de->d_reclen;
5865
                    if (reclen > len)
5866
                        break;
5867
                    de->d_reclen = tswap16(reclen);
5868
                    tswap64s((uint64_t *)&de->d_ino);
5869
                    tswap64s((uint64_t *)&de->d_off);
5870
                    de = (struct linux_dirent64 *)((char *)de + reclen);
5871
                    len -= reclen;
5872
                }
5873
            }
5874
            unlock_user(dirp, arg2, ret);
5875
        }
5876
        break;
5877
#endif /* TARGET_NR_getdents64 */
5878
#ifdef TARGET_NR__newselect
5879
    case TARGET_NR__newselect:
5880
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
5881
        break;
5882
#endif
5883
#ifdef TARGET_NR_poll
5884
    case TARGET_NR_poll:
5885
        {
5886
            struct target_pollfd *target_pfd;
5887
            unsigned int nfds = arg2;
5888
            int timeout = arg3;
5889
            struct pollfd *pfd;
5890
            unsigned int i;
5891

    
5892
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
5893
            if (!target_pfd)
5894
                goto efault;
5895
            pfd = alloca(sizeof(struct pollfd) * nfds);
5896
            for(i = 0; i < nfds; i++) {
5897
                pfd[i].fd = tswap32(target_pfd[i].fd);
5898
                pfd[i].events = tswap16(target_pfd[i].events);
5899
            }
5900
            ret = get_errno(poll(pfd, nfds, timeout));
5901
            if (!is_error(ret)) {
5902
                for(i = 0; i < nfds; i++) {
5903
                    target_pfd[i].revents = tswap16(pfd[i].revents);
5904
                }
5905
                ret += nfds * (sizeof(struct target_pollfd)
5906
                               - sizeof(struct pollfd));
5907
            }
5908
            unlock_user(target_pfd, arg1, ret);
5909
        }
5910
        break;
5911
#endif
5912
    case TARGET_NR_flock:
5913
        /* NOTE: the flock constant seems to be the same for every
5914
           Linux platform */
5915
        ret = get_errno(flock(arg1, arg2));
5916
        break;
5917
    case TARGET_NR_readv:
5918
        {
5919
            int count = arg3;
5920
            struct iovec *vec;
5921

    
5922
            vec = alloca(count * sizeof(struct iovec));
5923
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
5924
                goto efault;
5925
            ret = get_errno(readv(arg1, vec, count));
5926
            unlock_iovec(vec, arg2, count, 1);
5927
        }
5928
        break;
5929
    case TARGET_NR_writev:
5930
        {
5931
            int count = arg3;
5932
            struct iovec *vec;
5933

    
5934
            vec = alloca(count * sizeof(struct iovec));
5935
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
5936
                goto efault;
5937
            ret = get_errno(writev(arg1, vec, count));
5938
            unlock_iovec(vec, arg2, count, 0);
5939
        }
5940
        break;
5941
    case TARGET_NR_getsid:
5942
        ret = get_errno(getsid(arg1));
5943
        break;
5944
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
5945
    case TARGET_NR_fdatasync:
5946
        ret = get_errno(fdatasync(arg1));
5947
        break;
5948
#endif
5949
    case TARGET_NR__sysctl:
5950
        /* We don't implement this, but ENOTDIR is always a safe
5951
           return value. */
5952
        ret = -TARGET_ENOTDIR;
5953
        break;
5954
    case TARGET_NR_sched_setparam:
5955
        {
5956
            struct sched_param *target_schp;
5957
            struct sched_param schp;
5958

    
5959
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
5960
                goto efault;
5961
            schp.sched_priority = tswap32(target_schp->sched_priority);
5962
            unlock_user_struct(target_schp, arg2, 0);
5963
            ret = get_errno(sched_setparam(arg1, &schp));
5964
        }
5965
        break;
5966
    case TARGET_NR_sched_getparam:
5967
        {
5968
            struct sched_param *target_schp;
5969
            struct sched_param schp;
5970
            ret = get_errno(sched_getparam(arg1, &schp));
5971
            if (!is_error(ret)) {
5972
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
5973
                    goto efault;
5974
                target_schp->sched_priority = tswap32(schp.sched_priority);
5975
                unlock_user_struct(target_schp, arg2, 1);
5976
            }
5977
        }
5978
        break;
5979
    case TARGET_NR_sched_setscheduler:
5980
        {
5981
            struct sched_param *target_schp;
5982
            struct sched_param schp;
5983
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
5984
                goto efault;
5985
            schp.sched_priority = tswap32(target_schp->sched_priority);
5986
            unlock_user_struct(target_schp, arg3, 0);
5987
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
5988
        }
5989
        break;
5990
    case TARGET_NR_sched_getscheduler:
5991
        ret = get_errno(sched_getscheduler(arg1));
5992
        break;
5993
    case TARGET_NR_sched_yield:
5994
        ret = get_errno(sched_yield());
5995
        break;
5996
    case TARGET_NR_sched_get_priority_max:
5997
        ret = get_errno(sched_get_priority_max(arg1));
5998
        break;
5999
    case TARGET_NR_sched_get_priority_min:
6000
        ret = get_errno(sched_get_priority_min(arg1));
6001
        break;
6002
    case TARGET_NR_sched_rr_get_interval:
6003
        {
6004
            struct timespec ts;
6005
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
6006
            if (!is_error(ret)) {
6007
                host_to_target_timespec(arg2, &ts);
6008
            }
6009
        }
6010
        break;
6011
    case TARGET_NR_nanosleep:
6012
        {
6013
            struct timespec req, rem;
6014
            target_to_host_timespec(&req, arg1);
6015
            ret = get_errno(nanosleep(&req, &rem));
6016
            if (is_error(ret) && arg2) {
6017
                host_to_target_timespec(arg2, &rem);
6018
            }
6019
        }
6020
        break;
6021
#ifdef TARGET_NR_query_module
6022
    case TARGET_NR_query_module:
6023
        goto unimplemented;
6024
#endif
6025
#ifdef TARGET_NR_nfsservctl
6026
    case TARGET_NR_nfsservctl:
6027
        goto unimplemented;
6028
#endif
6029
    case TARGET_NR_prctl:
6030
        switch (arg1)
6031
            {
6032
            case PR_GET_PDEATHSIG:
6033
                {
6034
                    int deathsig;
6035
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
6036
                    if (!is_error(ret) && arg2
6037
                        && put_user_ual(deathsig, arg2))
6038
                        goto efault;
6039
                }
6040
                break;
6041
            default:
6042
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
6043
                break;
6044
            }
6045
        break;
6046
#ifdef TARGET_NR_arch_prctl
6047
    case TARGET_NR_arch_prctl:
6048
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
6049
        ret = do_arch_prctl(cpu_env, arg1, arg2);
6050
        break;
6051
#else
6052
        goto unimplemented;
6053
#endif
6054
#endif
6055
#ifdef TARGET_NR_pread
6056
    case TARGET_NR_pread:
6057
#ifdef TARGET_ARM
6058
        if (((CPUARMState *)cpu_env)->eabi)
6059
            arg4 = arg5;
6060
#endif
6061
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6062
            goto efault;
6063
        ret = get_errno(pread(arg1, p, arg3, arg4));
6064
        unlock_user(p, arg2, ret);
6065
        break;
6066
    case TARGET_NR_pwrite:
6067
#ifdef TARGET_ARM
6068
        if (((CPUARMState *)cpu_env)->eabi)
6069
            arg4 = arg5;
6070
#endif
6071
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6072
            goto efault;
6073
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
6074
        unlock_user(p, arg2, 0);
6075
        break;
6076
#endif
6077
#ifdef TARGET_NR_pread64
6078
    case TARGET_NR_pread64:
6079
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6080
            goto efault;
6081
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
6082
        unlock_user(p, arg2, ret);
6083
        break;
6084
    case TARGET_NR_pwrite64:
6085
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6086
            goto efault;
6087
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
6088
        unlock_user(p, arg2, 0);
6089
        break;
6090
#endif
6091
    case TARGET_NR_getcwd:
6092
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
6093
            goto efault;
6094
        ret = get_errno(sys_getcwd1(p, arg2));
6095
        unlock_user(p, arg1, ret);
6096
        break;
6097
    case TARGET_NR_capget:
6098
        goto unimplemented;
6099
    case TARGET_NR_capset:
6100
        goto unimplemented;
6101
    case TARGET_NR_sigaltstack:
6102
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
6103
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA)
6104
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
6105
        break;
6106
#else
6107
        goto unimplemented;
6108
#endif
6109
    case TARGET_NR_sendfile:
6110
        goto unimplemented;
6111
#ifdef TARGET_NR_getpmsg
6112
    case TARGET_NR_getpmsg:
6113
        goto unimplemented;
6114
#endif
6115
#ifdef TARGET_NR_putpmsg
6116
    case TARGET_NR_putpmsg:
6117
        goto unimplemented;
6118
#endif
6119
#ifdef TARGET_NR_vfork
6120
    case TARGET_NR_vfork:
6121
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
6122
                        0, 0, 0, 0));
6123
        break;
6124
#endif
6125
#ifdef TARGET_NR_ugetrlimit
6126
    case TARGET_NR_ugetrlimit:
6127
    {
6128
        struct rlimit rlim;
6129
        ret = get_errno(getrlimit(arg1, &rlim));
6130
        if (!is_error(ret)) {
6131
            struct target_rlimit *target_rlim;
6132
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6133
                goto efault;
6134
            target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
6135
            target_rlim->rlim_max = tswapl(rlim.rlim_max);
6136
            unlock_user_struct(target_rlim, arg2, 1);
6137
        }
6138
        break;
6139
    }
6140
#endif
6141
#ifdef TARGET_NR_truncate64
6142
    case TARGET_NR_truncate64:
6143
        if (!(p = lock_user_string(arg1)))
6144
            goto efault;
6145
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
6146
        unlock_user(p, arg1, 0);
6147
        break;
6148
#endif
6149
#ifdef TARGET_NR_ftruncate64
6150
    case TARGET_NR_ftruncate64:
6151
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
6152
        break;
6153
#endif
6154
#ifdef TARGET_NR_stat64
6155
    case TARGET_NR_stat64:
6156
        if (!(p = lock_user_string(arg1)))
6157
            goto efault;
6158
        ret = get_errno(stat(path(p), &st));
6159
        unlock_user(p, arg1, 0);
6160
        if (!is_error(ret))
6161
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6162
        break;
6163
#endif
6164
#ifdef TARGET_NR_lstat64
6165
    case TARGET_NR_lstat64:
6166
        if (!(p = lock_user_string(arg1)))
6167
            goto efault;
6168
        ret = get_errno(lstat(path(p), &st));
6169
        unlock_user(p, arg1, 0);
6170
        if (!is_error(ret))
6171
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6172
        break;
6173
#endif
6174
#ifdef TARGET_NR_fstat64
6175
    case TARGET_NR_fstat64:
6176
        ret = get_errno(fstat(arg1, &st));
6177
        if (!is_error(ret))
6178
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6179
        break;
6180
#endif
6181
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6182
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6183
#ifdef TARGET_NR_fstatat64
6184
    case TARGET_NR_fstatat64:
6185
#endif
6186
#ifdef TARGET_NR_newfstatat
6187
    case TARGET_NR_newfstatat:
6188
#endif
6189
        if (!(p = lock_user_string(arg2)))
6190
            goto efault;
6191
#ifdef __NR_fstatat64
6192
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
6193
#else
6194
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
6195
#endif
6196
        if (!is_error(ret))
6197
            ret = host_to_target_stat64(cpu_env, arg3, &st);
6198
        break;
6199
#endif
6200
#ifdef USE_UID16
6201
    case TARGET_NR_lchown:
6202
        if (!(p = lock_user_string(arg1)))
6203
            goto efault;
6204
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
6205
        unlock_user(p, arg1, 0);
6206
        break;
6207
    case TARGET_NR_getuid:
6208
        ret = get_errno(high2lowuid(getuid()));
6209
        break;
6210
    case TARGET_NR_getgid:
6211
        ret = get_errno(high2lowgid(getgid()));
6212
        break;
6213
    case TARGET_NR_geteuid:
6214
        ret = get_errno(high2lowuid(geteuid()));
6215
        break;
6216
    case TARGET_NR_getegid:
6217
        ret = get_errno(high2lowgid(getegid()));
6218
        break;
6219
    case TARGET_NR_setreuid:
6220
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
6221
        break;
6222
    case TARGET_NR_setregid:
6223
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
6224
        break;
6225
    case TARGET_NR_getgroups:
6226
        {
6227
            int gidsetsize = arg1;
6228
            uint16_t *target_grouplist;
6229
            gid_t *grouplist;
6230
            int i;
6231

    
6232
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6233
            ret = get_errno(getgroups(gidsetsize, grouplist));
6234
            if (gidsetsize == 0)
6235
                break;
6236
            if (!is_error(ret)) {
6237
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
6238
                if (!target_grouplist)
6239
                    goto efault;
6240
                for(i = 0;i < ret; i++)
6241
                    target_grouplist[i] = tswap16(grouplist[i]);
6242
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
6243
            }
6244
        }
6245
        break;
6246
    case TARGET_NR_setgroups:
6247
        {
6248
            int gidsetsize = arg1;
6249
            uint16_t *target_grouplist;
6250
            gid_t *grouplist;
6251
            int i;
6252

    
6253
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6254
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
6255
            if (!target_grouplist) {
6256
                ret = -TARGET_EFAULT;
6257
                goto fail;
6258
            }
6259
            for(i = 0;i < gidsetsize; i++)
6260
                grouplist[i] = tswap16(target_grouplist[i]);
6261
            unlock_user(target_grouplist, arg2, 0);
6262
            ret = get_errno(setgroups(gidsetsize, grouplist));
6263
        }
6264
        break;
6265
    case TARGET_NR_fchown:
6266
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
6267
        break;
6268
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
6269
    case TARGET_NR_fchownat:
6270
        if (!(p = lock_user_string(arg2))) 
6271
            goto efault;
6272
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
6273
        unlock_user(p, arg2, 0);
6274
        break;
6275
#endif
6276
#ifdef TARGET_NR_setresuid
6277
    case TARGET_NR_setresuid:
6278
        ret = get_errno(setresuid(low2highuid(arg1),
6279
                                  low2highuid(arg2),
6280
                                  low2highuid(arg3)));
6281
        break;
6282
#endif
6283
#ifdef TARGET_NR_getresuid
6284
    case TARGET_NR_getresuid:
6285
        {
6286
            uid_t ruid, euid, suid;
6287
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6288
            if (!is_error(ret)) {
6289
                if (put_user_u16(high2lowuid(ruid), arg1)
6290
                    || put_user_u16(high2lowuid(euid), arg2)
6291
                    || put_user_u16(high2lowuid(suid), arg3))
6292
                    goto efault;
6293
            }
6294
        }
6295
        break;
6296
#endif
6297
#ifdef TARGET_NR_getresgid
6298
    case TARGET_NR_setresgid:
6299
        ret = get_errno(setresgid(low2highgid(arg1),
6300
                                  low2highgid(arg2),
6301
                                  low2highgid(arg3)));
6302
        break;
6303
#endif
6304
#ifdef TARGET_NR_getresgid
6305
    case TARGET_NR_getresgid:
6306
        {
6307
            gid_t rgid, egid, sgid;
6308
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6309
            if (!is_error(ret)) {
6310
                if (put_user_u16(high2lowgid(rgid), arg1)
6311
                    || put_user_u16(high2lowgid(egid), arg2)
6312
                    || put_user_u16(high2lowgid(sgid), arg3))
6313
                    goto efault;
6314
            }
6315
        }
6316
        break;
6317
#endif
6318
    case TARGET_NR_chown:
6319
        if (!(p = lock_user_string(arg1)))
6320
            goto efault;
6321
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
6322
        unlock_user(p, arg1, 0);
6323
        break;
6324
    case TARGET_NR_setuid:
6325
        ret = get_errno(setuid(low2highuid(arg1)));
6326
        break;
6327
    case TARGET_NR_setgid:
6328
        ret = get_errno(setgid(low2highgid(arg1)));
6329
        break;
6330
    case TARGET_NR_setfsuid:
6331
        ret = get_errno(setfsuid(arg1));
6332
        break;
6333
    case TARGET_NR_setfsgid:
6334
        ret = get_errno(setfsgid(arg1));
6335
        break;
6336
#endif /* USE_UID16 */
6337

    
6338
#ifdef TARGET_NR_lchown32
6339
    case TARGET_NR_lchown32:
6340
        if (!(p = lock_user_string(arg1)))
6341
            goto efault;
6342
        ret = get_errno(lchown(p, arg2, arg3));
6343
        unlock_user(p, arg1, 0);
6344
        break;
6345
#endif
6346
#ifdef TARGET_NR_getuid32
6347
    case TARGET_NR_getuid32:
6348
        ret = get_errno(getuid());
6349
        break;
6350
#endif
6351

    
6352
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
6353
   /* Alpha specific */
6354
    case TARGET_NR_getxuid:
6355
         {
6356
            uid_t euid;
6357
            euid=geteuid();
6358
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
6359
         }
6360
        ret = get_errno(getuid());
6361
        break;
6362
#endif
6363
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
6364
   /* Alpha specific */
6365
    case TARGET_NR_getxgid:
6366
         {
6367
            uid_t egid;
6368
            egid=getegid();
6369
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
6370
         }
6371
        ret = get_errno(getgid());
6372
        break;
6373
#endif
6374

    
6375
#ifdef TARGET_NR_getgid32
6376
    case TARGET_NR_getgid32:
6377
        ret = get_errno(getgid());
6378
        break;
6379
#endif
6380
#ifdef TARGET_NR_geteuid32
6381
    case TARGET_NR_geteuid32:
6382
        ret = get_errno(geteuid());
6383
        break;
6384
#endif
6385
#ifdef TARGET_NR_getegid32
6386
    case TARGET_NR_getegid32:
6387
        ret = get_errno(getegid());
6388
        break;
6389
#endif
6390
#ifdef TARGET_NR_setreuid32
6391
    case TARGET_NR_setreuid32:
6392
        ret = get_errno(setreuid(arg1, arg2));
6393
        break;
6394
#endif
6395
#ifdef TARGET_NR_setregid32
6396
    case TARGET_NR_setregid32:
6397
        ret = get_errno(setregid(arg1, arg2));
6398
        break;
6399
#endif
6400
#ifdef TARGET_NR_getgroups32
6401
    case TARGET_NR_getgroups32:
6402
        {
6403
            int gidsetsize = arg1;
6404
            uint32_t *target_grouplist;
6405
            gid_t *grouplist;
6406
            int i;
6407

    
6408
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6409
            ret = get_errno(getgroups(gidsetsize, grouplist));
6410
            if (gidsetsize == 0)
6411
                break;
6412
            if (!is_error(ret)) {
6413
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
6414
                if (!target_grouplist) {
6415
                    ret = -TARGET_EFAULT;
6416
                    goto fail;
6417
                }
6418
                for(i = 0;i < ret; i++)
6419
                    target_grouplist[i] = tswap32(grouplist[i]);
6420
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
6421
            }
6422
        }
6423
        break;
6424
#endif
6425
#ifdef TARGET_NR_setgroups32
6426
    case TARGET_NR_setgroups32:
6427
        {
6428
            int gidsetsize = arg1;
6429
            uint32_t *target_grouplist;
6430
            gid_t *grouplist;
6431
            int i;
6432

    
6433
            grouplist = alloca(gidsetsize * sizeof(gid_t));
6434
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
6435
            if (!target_grouplist) {
6436
                ret = -TARGET_EFAULT;
6437
                goto fail;
6438
            }
6439
            for(i = 0;i < gidsetsize; i++)
6440
                grouplist[i] = tswap32(target_grouplist[i]);
6441
            unlock_user(target_grouplist, arg2, 0);
6442
            ret = get_errno(setgroups(gidsetsize, grouplist));
6443
        }
6444
        break;
6445
#endif
6446
#ifdef TARGET_NR_fchown32
6447
    case TARGET_NR_fchown32:
6448
        ret = get_errno(fchown(arg1, arg2, arg3));
6449
        break;
6450
#endif
6451
#ifdef TARGET_NR_setresuid32
6452
    case TARGET_NR_setresuid32:
6453
        ret = get_errno(setresuid(arg1, arg2, arg3));
6454
        break;
6455
#endif
6456
#ifdef TARGET_NR_getresuid32
6457
    case TARGET_NR_getresuid32:
6458
        {
6459
            uid_t ruid, euid, suid;
6460
            ret = get_errno(getresuid(&ruid, &euid, &suid));
6461
            if (!is_error(ret)) {
6462
                if (put_user_u32(ruid, arg1)
6463
                    || put_user_u32(euid, arg2)
6464
                    || put_user_u32(suid, arg3))
6465
                    goto efault;
6466
            }
6467
        }
6468
        break;
6469
#endif
6470
#ifdef TARGET_NR_setresgid32
6471
    case TARGET_NR_setresgid32:
6472
        ret = get_errno(setresgid(arg1, arg2, arg3));
6473
        break;
6474
#endif
6475
#ifdef TARGET_NR_getresgid32
6476
    case TARGET_NR_getresgid32:
6477
        {
6478
            gid_t rgid, egid, sgid;
6479
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
6480
            if (!is_error(ret)) {
6481
                if (put_user_u32(rgid, arg1)
6482
                    || put_user_u32(egid, arg2)
6483
                    || put_user_u32(sgid, arg3))
6484
                    goto efault;
6485
            }
6486
        }
6487
        break;
6488
#endif
6489
#ifdef TARGET_NR_chown32
6490
    case TARGET_NR_chown32:
6491
        if (!(p = lock_user_string(arg1)))
6492
            goto efault;
6493
        ret = get_errno(chown(p, arg2, arg3));
6494
        unlock_user(p, arg1, 0);
6495
        break;
6496
#endif
6497
#ifdef TARGET_NR_setuid32
6498
    case TARGET_NR_setuid32:
6499
        ret = get_errno(setuid(arg1));
6500
        break;
6501
#endif
6502
#ifdef TARGET_NR_setgid32
6503
    case TARGET_NR_setgid32:
6504
        ret = get_errno(setgid(arg1));
6505
        break;
6506
#endif
6507
#ifdef TARGET_NR_setfsuid32
6508
    case TARGET_NR_setfsuid32:
6509
        ret = get_errno(setfsuid(arg1));
6510
        break;
6511
#endif
6512
#ifdef TARGET_NR_setfsgid32
6513
    case TARGET_NR_setfsgid32:
6514
        ret = get_errno(setfsgid(arg1));
6515
        break;
6516
#endif
6517

    
6518
    case TARGET_NR_pivot_root:
6519
        goto unimplemented;
6520
#ifdef TARGET_NR_mincore
6521
    case TARGET_NR_mincore:
6522
        {
6523
            void *a;
6524
            ret = -TARGET_EFAULT;
6525
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
6526
                goto efault;
6527
            if (!(p = lock_user_string(arg3)))
6528
                goto mincore_fail;
6529
            ret = get_errno(mincore(a, arg2, p));
6530
            unlock_user(p, arg3, ret);
6531
            mincore_fail:
6532
            unlock_user(a, arg1, 0);
6533
        }
6534
        break;
6535
#endif
6536
#ifdef TARGET_NR_arm_fadvise64_64
6537
    case TARGET_NR_arm_fadvise64_64:
6538
        {
6539
                /*
6540
                 * arm_fadvise64_64 looks like fadvise64_64 but
6541
                 * with different argument order
6542
                 */
6543
                abi_long temp;
6544
                temp = arg3;
6545
                arg3 = arg4;
6546
                arg4 = temp;
6547
        }
6548
#endif
6549
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
6550
#ifdef TARGET_NR_fadvise64_64
6551
    case TARGET_NR_fadvise64_64:
6552
#endif
6553
        /* This is a hint, so ignoring and returning success is ok.  */
6554
        ret = get_errno(0);
6555
        break;
6556
#endif
6557
#ifdef TARGET_NR_madvise
6558
    case TARGET_NR_madvise:
6559
        /* A straight passthrough may not be safe because qemu sometimes
6560
           turns private flie-backed mappings into anonymous mappings.
6561
           This will break MADV_DONTNEED.
6562
           This is a hint, so ignoring and returning success is ok.  */
6563
        ret = get_errno(0);
6564
        break;
6565
#endif
6566
#if TARGET_ABI_BITS == 32
6567
    case TARGET_NR_fcntl64:
6568
    {
6569
        int cmd;
6570
        struct flock64 fl;
6571
        struct target_flock64 *target_fl;
6572
#ifdef TARGET_ARM
6573
        struct target_eabi_flock64 *target_efl;
6574
#endif
6575

    
6576
        cmd = target_to_host_fcntl_cmd(arg2);
6577
        if (cmd == -TARGET_EINVAL)
6578
                return cmd;
6579

    
6580
        switch(arg2) {
6581
        case TARGET_F_GETLK64:
6582
#ifdef TARGET_ARM
6583
            if (((CPUARMState *)cpu_env)->eabi) {
6584
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6585
                    goto efault;
6586
                fl.l_type = tswap16(target_efl->l_type);
6587
                fl.l_whence = tswap16(target_efl->l_whence);
6588
                fl.l_start = tswap64(target_efl->l_start);
6589
                fl.l_len = tswap64(target_efl->l_len);
6590
                fl.l_pid = tswapl(target_efl->l_pid);
6591
                unlock_user_struct(target_efl, arg3, 0);
6592
            } else
6593
#endif
6594
            {
6595
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6596
                    goto efault;
6597
                fl.l_type = tswap16(target_fl->l_type);
6598
                fl.l_whence = tswap16(target_fl->l_whence);
6599
                fl.l_start = tswap64(target_fl->l_start);
6600
                fl.l_len = tswap64(target_fl->l_len);
6601
                fl.l_pid = tswapl(target_fl->l_pid);
6602
                unlock_user_struct(target_fl, arg3, 0);
6603
            }
6604
            ret = get_errno(fcntl(arg1, cmd, &fl));
6605
            if (ret == 0) {
6606
#ifdef TARGET_ARM
6607
                if (((CPUARMState *)cpu_env)->eabi) {
6608
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
6609
                        goto efault;
6610
                    target_efl->l_type = tswap16(fl.l_type);
6611
                    target_efl->l_whence = tswap16(fl.l_whence);
6612
                    target_efl->l_start = tswap64(fl.l_start);
6613
                    target_efl->l_len = tswap64(fl.l_len);
6614
                    target_efl->l_pid = tswapl(fl.l_pid);
6615
                    unlock_user_struct(target_efl, arg3, 1);
6616
                } else
6617
#endif
6618
                {
6619
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
6620
                        goto efault;
6621
                    target_fl->l_type = tswap16(fl.l_type);
6622
                    target_fl->l_whence = tswap16(fl.l_whence);
6623
                    target_fl->l_start = tswap64(fl.l_start);
6624
                    target_fl->l_len = tswap64(fl.l_len);
6625
                    target_fl->l_pid = tswapl(fl.l_pid);
6626
                    unlock_user_struct(target_fl, arg3, 1);
6627
                }
6628
            }
6629
            break;
6630

    
6631
        case TARGET_F_SETLK64:
6632
        case TARGET_F_SETLKW64:
6633
#ifdef TARGET_ARM
6634
            if (((CPUARMState *)cpu_env)->eabi) {
6635
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
6636
                    goto efault;
6637
                fl.l_type = tswap16(target_efl->l_type);
6638
                fl.l_whence = tswap16(target_efl->l_whence);
6639
                fl.l_start = tswap64(target_efl->l_start);
6640
                fl.l_len = tswap64(target_efl->l_len);
6641
                fl.l_pid = tswapl(target_efl->l_pid);
6642
                unlock_user_struct(target_efl, arg3, 0);
6643
            } else
6644
#endif
6645
            {
6646
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
6647
                    goto efault;
6648
                fl.l_type = tswap16(target_fl->l_type);
6649
                fl.l_whence = tswap16(target_fl->l_whence);
6650
                fl.l_start = tswap64(target_fl->l_start);
6651
                fl.l_len = tswap64(target_fl->l_len);
6652
                fl.l_pid = tswapl(target_fl->l_pid);
6653
                unlock_user_struct(target_fl, arg3, 0);
6654
            }
6655
            ret = get_errno(fcntl(arg1, cmd, &fl));
6656
            break;
6657
        default:
6658
            ret = do_fcntl(arg1, arg2, arg3);
6659
            break;
6660
        }
6661
        break;
6662
    }
6663
#endif
6664
#ifdef TARGET_NR_cacheflush
6665
    case TARGET_NR_cacheflush:
6666
        /* self-modifying code is handled automatically, so nothing needed */
6667
        ret = 0;
6668
        break;
6669
#endif
6670
#ifdef TARGET_NR_security
6671
    case TARGET_NR_security:
6672
        goto unimplemented;
6673
#endif
6674
#ifdef TARGET_NR_getpagesize
6675
    case TARGET_NR_getpagesize:
6676
        ret = TARGET_PAGE_SIZE;
6677
        break;
6678
#endif
6679
    case TARGET_NR_gettid:
6680
        ret = get_errno(gettid());
6681
        break;
6682
#ifdef TARGET_NR_readahead
6683
    case TARGET_NR_readahead:
6684
#if TARGET_ABI_BITS == 32
6685
#ifdef TARGET_ARM
6686
        if (((CPUARMState *)cpu_env)->eabi)
6687
        {
6688
            arg2 = arg3;
6689
            arg3 = arg4;
6690
            arg4 = arg5;
6691
        }
6692
#endif
6693
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
6694
#else
6695
        ret = get_errno(readahead(arg1, arg2, arg3));
6696
#endif
6697
        break;
6698
#endif
6699
#ifdef TARGET_NR_setxattr
6700
    case TARGET_NR_setxattr:
6701
    case TARGET_NR_lsetxattr:
6702
    case TARGET_NR_fsetxattr:
6703
    case TARGET_NR_getxattr:
6704
    case TARGET_NR_lgetxattr:
6705
    case TARGET_NR_fgetxattr:
6706
    case TARGET_NR_listxattr:
6707
    case TARGET_NR_llistxattr:
6708
    case TARGET_NR_flistxattr:
6709
    case TARGET_NR_removexattr:
6710
    case TARGET_NR_lremovexattr:
6711
    case TARGET_NR_fremovexattr:
6712
        ret = -TARGET_EOPNOTSUPP;
6713
        break;
6714
#endif
6715
#ifdef TARGET_NR_set_thread_area
6716
    case TARGET_NR_set_thread_area:
6717
#if defined(TARGET_MIPS)
6718
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
6719
      ret = 0;
6720
      break;
6721
#elif defined(TARGET_CRIS)
6722
      if (arg1 & 0xff)
6723
          ret = -TARGET_EINVAL;
6724
      else {
6725
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
6726
          ret = 0;
6727
      }
6728
      break;
6729
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
6730
      ret = do_set_thread_area(cpu_env, arg1);
6731
      break;
6732
#else
6733
      goto unimplemented_nowarn;
6734
#endif
6735
#endif
6736
#ifdef TARGET_NR_get_thread_area
6737
    case TARGET_NR_get_thread_area:
6738
#if defined(TARGET_I386) && defined(TARGET_ABI32)
6739
        ret = do_get_thread_area(cpu_env, arg1);
6740
#else
6741
        goto unimplemented_nowarn;
6742
#endif
6743
#endif
6744
#ifdef TARGET_NR_getdomainname
6745
    case TARGET_NR_getdomainname:
6746
        goto unimplemented_nowarn;
6747
#endif
6748

    
6749
#ifdef TARGET_NR_clock_gettime
6750
    case TARGET_NR_clock_gettime:
6751
    {
6752
        struct timespec ts;
6753
        ret = get_errno(clock_gettime(arg1, &ts));
6754
        if (!is_error(ret)) {
6755
            host_to_target_timespec(arg2, &ts);
6756
        }
6757
        break;
6758
    }
6759
#endif
6760
#ifdef TARGET_NR_clock_getres
6761
    case TARGET_NR_clock_getres:
6762
    {
6763
        struct timespec ts;
6764
        ret = get_errno(clock_getres(arg1, &ts));
6765
        if (!is_error(ret)) {
6766
            host_to_target_timespec(arg2, &ts);
6767
        }
6768
        break;
6769
    }
6770
#endif
6771
#ifdef TARGET_NR_clock_nanosleep
6772
    case TARGET_NR_clock_nanosleep:
6773
    {
6774
        struct timespec ts;
6775
        target_to_host_timespec(&ts, arg3);
6776
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
6777
        if (arg4)
6778
            host_to_target_timespec(arg4, &ts);
6779
        break;
6780
    }
6781
#endif
6782

    
6783
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
6784
    case TARGET_NR_set_tid_address:
6785
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
6786
        break;
6787
#endif
6788

    
6789
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
6790
    case TARGET_NR_tkill:
6791
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
6792
        break;
6793
#endif
6794

    
6795
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
6796
    case TARGET_NR_tgkill:
6797
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
6798
                        target_to_host_signal(arg3)));
6799
        break;
6800
#endif
6801

    
6802
#ifdef TARGET_NR_set_robust_list
6803
    case TARGET_NR_set_robust_list:
6804
        goto unimplemented_nowarn;
6805
#endif
6806

    
6807
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
6808
    case TARGET_NR_utimensat:
6809
        {
6810
            struct timespec *tsp, ts[2];
6811
            if (!arg3) {
6812
                tsp = NULL;
6813
            } else {
6814
                target_to_host_timespec(ts, arg3);
6815
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
6816
                tsp = ts;
6817
            }
6818
            if (!arg2)
6819
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
6820
            else {
6821
                if (!(p = lock_user_string(arg2))) {
6822
                    ret = -TARGET_EFAULT;
6823
                    goto fail;
6824
                }
6825
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
6826
                unlock_user(p, arg2, 0);
6827
            }
6828
        }
6829
        break;
6830
#endif
6831
#if defined(CONFIG_USE_NPTL)
6832
    case TARGET_NR_futex:
6833
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
6834
        break;
6835
#endif
6836
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
6837
    case TARGET_NR_inotify_init:
6838
        ret = get_errno(sys_inotify_init());
6839
        break;
6840
#endif
6841
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
6842
    case TARGET_NR_inotify_add_watch:
6843
        p = lock_user_string(arg2);
6844
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
6845
        unlock_user(p, arg2, 0);
6846
        break;
6847
#endif
6848
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
6849
    case TARGET_NR_inotify_rm_watch:
6850
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
6851
        break;
6852
#endif
6853

    
6854
#ifdef TARGET_NR_mq_open
6855
    case TARGET_NR_mq_open:
6856
        {
6857
            struct mq_attr posix_mq_attr;
6858

    
6859
            p = lock_user_string(arg1 - 1);
6860
            if (arg4 != 0)
6861
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
6862
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
6863
            unlock_user (p, arg1, 0);
6864
        }
6865
        break;
6866

    
6867
    case TARGET_NR_mq_unlink:
6868
        p = lock_user_string(arg1 - 1);
6869
        ret = get_errno(mq_unlink(p));
6870
        unlock_user (p, arg1, 0);
6871
        break;
6872

    
6873
    case TARGET_NR_mq_timedsend:
6874
        {
6875
            struct timespec ts;
6876

    
6877
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6878
            if (arg5 != 0) {
6879
                target_to_host_timespec(&ts, arg5);
6880
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
6881
                host_to_target_timespec(arg5, &ts);
6882
            }
6883
            else
6884
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
6885
            unlock_user (p, arg2, arg3);
6886
        }
6887
        break;
6888

    
6889
    case TARGET_NR_mq_timedreceive:
6890
        {
6891
            struct timespec ts;
6892
            unsigned int prio;
6893

    
6894
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
6895
            if (arg5 != 0) {
6896
                target_to_host_timespec(&ts, arg5);
6897
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
6898
                host_to_target_timespec(arg5, &ts);
6899
            }
6900
            else
6901
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
6902
            unlock_user (p, arg2, arg3);
6903
            if (arg4 != 0)
6904
                put_user_u32(prio, arg4);
6905
        }
6906
        break;
6907

    
6908
    /* Not implemented for now... */
6909
/*     case TARGET_NR_mq_notify: */
6910
/*         break; */
6911

    
6912
    case TARGET_NR_mq_getsetattr:
6913
        {
6914
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
6915
            ret = 0;
6916
            if (arg3 != 0) {
6917
                ret = mq_getattr(arg1, &posix_mq_attr_out);
6918
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
6919
            }
6920
            if (arg2 != 0) {
6921
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
6922
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
6923
            }
6924

    
6925
        }
6926
        break;
6927
#endif
6928

    
6929
#ifdef CONFIG_SPLICE
6930
#ifdef TARGET_NR_tee
6931
    case TARGET_NR_tee:
6932
        {
6933
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
6934
        }
6935
        break;
6936
#endif
6937
#ifdef TARGET_NR_splice
6938
    case TARGET_NR_splice:
6939
        {
6940
            loff_t loff_in, loff_out;
6941
            loff_t *ploff_in = NULL, *ploff_out = NULL;
6942
            if(arg2) {
6943
                get_user_u64(loff_in, arg2);
6944
                ploff_in = &loff_in;
6945
            }
6946
            if(arg4) {
6947
                get_user_u64(loff_out, arg2);
6948
                ploff_out = &loff_out;
6949
            }
6950
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
6951
        }
6952
        break;
6953
#endif
6954
#ifdef TARGET_NR_vmsplice
6955
        case TARGET_NR_vmsplice:
6956
        {
6957
            int count = arg3;
6958
            struct iovec *vec;
6959

    
6960
            vec = alloca(count * sizeof(struct iovec));
6961
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
6962
                goto efault;
6963
            ret = get_errno(vmsplice(arg1, vec, count, arg4));
6964
            unlock_iovec(vec, arg2, count, 0);
6965
        }
6966
        break;
6967
#endif
6968
#endif /* CONFIG_SPLICE */
6969
    default:
6970
    unimplemented:
6971
        gemu_log("qemu: Unsupported syscall: %d\n", num);
6972
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
6973
    unimplemented_nowarn:
6974
#endif
6975
        ret = -TARGET_ENOSYS;
6976
        break;
6977
    }
6978
fail:
6979
#ifdef DEBUG
6980
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
6981
#endif
6982
    if(do_strace)
6983
        print_syscall_ret(num, ret);
6984
    return ret;
6985
efault:
6986
    ret = -TARGET_EFAULT;
6987
    goto fail;
6988
}