Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 333858b7

History | View | Annotate | Download (273.1 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 <sys/types.h>
32
#include <sys/ipc.h>
33
#include <sys/msg.h>
34
#include <sys/wait.h>
35
#include <sys/time.h>
36
#include <sys/stat.h>
37
#include <sys/mount.h>
38
#include <sys/prctl.h>
39
#include <sys/resource.h>
40
#include <sys/mman.h>
41
#include <sys/swap.h>
42
#include <signal.h>
43
#include <sched.h>
44
#ifdef __ia64__
45
int __clone2(int (*fn)(void *), void *child_stack_base,
46
             size_t stack_size, int flags, void *arg, ...);
47
#endif
48
#include <sys/socket.h>
49
#include <sys/un.h>
50
#include <sys/uio.h>
51
#include <sys/poll.h>
52
#include <sys/times.h>
53
#include <sys/shm.h>
54
#include <sys/sem.h>
55
#include <sys/statfs.h>
56
#include <utime.h>
57
#include <sys/sysinfo.h>
58
#include <sys/utsname.h>
59
//#include <sys/user.h>
60
#include <netinet/ip.h>
61
#include <netinet/tcp.h>
62
#include <linux/wireless.h>
63
#include <linux/icmp.h>
64
#include "qemu-common.h"
65
#ifdef TARGET_GPROF
66
#include <sys/gmon.h>
67
#endif
68
#ifdef CONFIG_EVENTFD
69
#include <sys/eventfd.h>
70
#endif
71
#ifdef CONFIG_EPOLL
72
#include <sys/epoll.h>
73
#endif
74
#ifdef CONFIG_ATTR
75
#include "qemu-xattr.h"
76
#endif
77

    
78
#define termios host_termios
79
#define winsize host_winsize
80
#define termio host_termio
81
#define sgttyb host_sgttyb /* same as target */
82
#define tchars host_tchars /* same as target */
83
#define ltchars host_ltchars /* same as target */
84

    
85
#include <linux/termios.h>
86
#include <linux/unistd.h>
87
#include <linux/utsname.h>
88
#include <linux/cdrom.h>
89
#include <linux/hdreg.h>
90
#include <linux/soundcard.h>
91
#include <linux/kd.h>
92
#include <linux/mtio.h>
93
#include <linux/fs.h>
94
#if defined(CONFIG_FIEMAP)
95
#include <linux/fiemap.h>
96
#endif
97
#include <linux/fb.h>
98
#include <linux/vt.h>
99
#include <linux/dm-ioctl.h>
100
#include "linux_loop.h"
101
#include "cpu-uname.h"
102

    
103
#include "qemu.h"
104

    
105
#if defined(CONFIG_USE_NPTL)
106
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
107
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
108
#else
109
/* XXX: Hardcode the above values.  */
110
#define CLONE_NPTL_FLAGS2 0
111
#endif
112

    
113
//#define DEBUG
114

    
115
//#include <linux/msdos_fs.h>
116
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
117
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
118

    
119

    
120
#undef _syscall0
121
#undef _syscall1
122
#undef _syscall2
123
#undef _syscall3
124
#undef _syscall4
125
#undef _syscall5
126
#undef _syscall6
127

    
128
#define _syscall0(type,name)                \
129
static type name (void)                        \
130
{                                        \
131
        return syscall(__NR_##name);        \
132
}
133

    
134
#define _syscall1(type,name,type1,arg1)                \
135
static type name (type1 arg1)                        \
136
{                                                \
137
        return syscall(__NR_##name, arg1);        \
138
}
139

    
140
#define _syscall2(type,name,type1,arg1,type2,arg2)        \
141
static type name (type1 arg1,type2 arg2)                \
142
{                                                        \
143
        return syscall(__NR_##name, arg1, arg2);        \
144
}
145

    
146
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)        \
147
static type name (type1 arg1,type2 arg2,type3 arg3)                \
148
{                                                                \
149
        return syscall(__NR_##name, arg1, arg2, arg3);                \
150
}
151

    
152
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)        \
153
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)                        \
154
{                                                                                \
155
        return syscall(__NR_##name, arg1, arg2, arg3, arg4);                        \
156
}
157

    
158
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
159
                  type5,arg5)                                                        \
160
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)        \
161
{                                                                                \
162
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);                \
163
}
164

    
165

    
166
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
167
                  type5,arg5,type6,arg6)                                        \
168
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,        \
169
                  type6 arg6)                                                        \
170
{                                                                                \
171
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
172
}
173

    
174

    
175
#define __NR_sys_uname __NR_uname
176
#define __NR_sys_faccessat __NR_faccessat
177
#define __NR_sys_fchmodat __NR_fchmodat
178
#define __NR_sys_fchownat __NR_fchownat
179
#define __NR_sys_fstatat64 __NR_fstatat64
180
#define __NR_sys_futimesat __NR_futimesat
181
#define __NR_sys_getcwd1 __NR_getcwd
182
#define __NR_sys_getdents __NR_getdents
183
#define __NR_sys_getdents64 __NR_getdents64
184
#define __NR_sys_getpriority __NR_getpriority
185
#define __NR_sys_linkat __NR_linkat
186
#define __NR_sys_mkdirat __NR_mkdirat
187
#define __NR_sys_mknodat __NR_mknodat
188
#define __NR_sys_newfstatat __NR_newfstatat
189
#define __NR_sys_openat __NR_openat
190
#define __NR_sys_readlinkat __NR_readlinkat
191
#define __NR_sys_renameat __NR_renameat
192
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
193
#define __NR_sys_symlinkat __NR_symlinkat
194
#define __NR_sys_syslog __NR_syslog
195
#define __NR_sys_tgkill __NR_tgkill
196
#define __NR_sys_tkill __NR_tkill
197
#define __NR_sys_unlinkat __NR_unlinkat
198
#define __NR_sys_utimensat __NR_utimensat
199
#define __NR_sys_futex __NR_futex
200
#define __NR_sys_inotify_init __NR_inotify_init
201
#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
202
#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
203

    
204
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
205
    defined(__s390x__)
206
#define __NR__llseek __NR_lseek
207
#endif
208

    
209
#ifdef __NR_gettid
210
_syscall0(int, gettid)
211
#else
212
/* This is a replacement for the host gettid() and must return a host
213
   errno. */
214
static int gettid(void) {
215
    return -ENOSYS;
216
}
217
#endif
218
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
219
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
220
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
221
#endif
222
#if defined(TARGET_NR__llseek) && defined(__NR_llseek)
223
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
224
          loff_t *, res, uint, wh);
225
#endif
226
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
227
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
228
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
229
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
230
#endif
231
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
232
_syscall2(int,sys_tkill,int,tid,int,sig)
233
#endif
234
#ifdef __NR_exit_group
235
_syscall1(int,exit_group,int,error_code)
236
#endif
237
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
238
_syscall1(int,set_tid_address,int *,tidptr)
239
#endif
240
#if defined(CONFIG_USE_NPTL)
241
#if defined(TARGET_NR_futex) && defined(__NR_futex)
242
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
243
          const struct timespec *,timeout,int *,uaddr2,int,val3)
244
#endif
245
#endif
246
#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
247
_syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
248
          unsigned long *, user_mask_ptr);
249
#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
250
_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
251
          unsigned long *, user_mask_ptr);
252
_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
253
          void *, arg);
254

    
255
static bitmask_transtbl fcntl_flags_tbl[] = {
256
  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
257
  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
258
  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
259
  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
260
  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
261
  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
262
  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
263
  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
264
  { TARGET_O_SYNC,      TARGET_O_DSYNC,     O_SYNC,      O_DSYNC,     },
265
  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
266
  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
267
  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
268
  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
269
#if defined(O_DIRECT)
270
  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
271
#endif
272
#if defined(O_NOATIME)
273
  { TARGET_O_NOATIME,   TARGET_O_NOATIME,   O_NOATIME,   O_NOATIME    },
274
#endif
275
#if defined(O_CLOEXEC)
276
  { TARGET_O_CLOEXEC,   TARGET_O_CLOEXEC,   O_CLOEXEC,   O_CLOEXEC    },
277
#endif
278
#if defined(O_PATH)
279
  { TARGET_O_PATH,      TARGET_O_PATH,      O_PATH,      O_PATH       },
280
#endif
281
  /* Don't terminate the list prematurely on 64-bit host+guest.  */
282
#if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
283
  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
284
#endif
285
  { 0, 0, 0, 0 }
286
};
287

    
288
#define COPY_UTSNAME_FIELD(dest, src) \
289
  do { \
290
      /* __NEW_UTS_LEN doesn't include terminating null */ \
291
      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
292
      (dest)[__NEW_UTS_LEN] = '\0'; \
293
  } while (0)
294

    
295
static int sys_uname(struct new_utsname *buf)
296
{
297
  struct utsname uts_buf;
298

    
299
  if (uname(&uts_buf) < 0)
300
      return (-1);
301

    
302
  /*
303
   * Just in case these have some differences, we
304
   * translate utsname to new_utsname (which is the
305
   * struct linux kernel uses).
306
   */
307

    
308
  memset(buf, 0, sizeof(*buf));
309
  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
310
  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
311
  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
312
  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
313
  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
314
#ifdef _GNU_SOURCE
315
  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
316
#endif
317
  return (0);
318

    
319
#undef COPY_UTSNAME_FIELD
320
}
321

    
322
static int sys_getcwd1(char *buf, size_t size)
323
{
324
  if (getcwd(buf, size) == NULL) {
325
      /* getcwd() sets errno */
326
      return (-1);
327
  }
328
  return strlen(buf)+1;
329
}
330

    
331
#ifdef CONFIG_ATFILE
332
/*
333
 * Host system seems to have atfile syscall stubs available.  We
334
 * now enable them one by one as specified by target syscall_nr.h.
335
 */
336

    
337
#ifdef TARGET_NR_faccessat
338
static int sys_faccessat(int dirfd, const char *pathname, int mode)
339
{
340
  return (faccessat(dirfd, pathname, mode, 0));
341
}
342
#endif
343
#ifdef TARGET_NR_fchmodat
344
static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
345
{
346
  return (fchmodat(dirfd, pathname, mode, 0));
347
}
348
#endif
349
#if defined(TARGET_NR_fchownat)
350
static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
351
    gid_t group, int flags)
352
{
353
  return (fchownat(dirfd, pathname, owner, group, flags));
354
}
355
#endif
356
#ifdef __NR_fstatat64
357
static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
358
    int flags)
359
{
360
  return (fstatat(dirfd, pathname, buf, flags));
361
}
362
#endif
363
#ifdef __NR_newfstatat
364
static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
365
    int flags)
366
{
367
  return (fstatat(dirfd, pathname, buf, flags));
368
}
369
#endif
370
#ifdef TARGET_NR_futimesat
371
static int sys_futimesat(int dirfd, const char *pathname,
372
    const struct timeval times[2])
373
{
374
  return (futimesat(dirfd, pathname, times));
375
}
376
#endif
377
#ifdef TARGET_NR_linkat
378
static int sys_linkat(int olddirfd, const char *oldpath,
379
    int newdirfd, const char *newpath, int flags)
380
{
381
  return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
382
}
383
#endif
384
#ifdef TARGET_NR_mkdirat
385
static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
386
{
387
  return (mkdirat(dirfd, pathname, mode));
388
}
389
#endif
390
#ifdef TARGET_NR_mknodat
391
static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
392
    dev_t dev)
393
{
394
  return (mknodat(dirfd, pathname, mode, dev));
395
}
396
#endif
397
#ifdef TARGET_NR_openat
398
static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode)
399
{
400
  /*
401
   * open(2) has extra parameter 'mode' when called with
402
   * flag O_CREAT.
403
   */
404
  if ((flags & O_CREAT) != 0) {
405
      return (openat(dirfd, pathname, flags, mode));
406
  }
407
  return (openat(dirfd, pathname, flags));
408
}
409
#endif
410
#ifdef TARGET_NR_readlinkat
411
static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
412
{
413
  return (readlinkat(dirfd, pathname, buf, bufsiz));
414
}
415
#endif
416
#ifdef TARGET_NR_renameat
417
static int sys_renameat(int olddirfd, const char *oldpath,
418
    int newdirfd, const char *newpath)
419
{
420
  return (renameat(olddirfd, oldpath, newdirfd, newpath));
421
}
422
#endif
423
#ifdef TARGET_NR_symlinkat
424
static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
425
{
426
  return (symlinkat(oldpath, newdirfd, newpath));
427
}
428
#endif
429
#ifdef TARGET_NR_unlinkat
430
static int sys_unlinkat(int dirfd, const char *pathname, int flags)
431
{
432
  return (unlinkat(dirfd, pathname, flags));
433
}
434
#endif
435
#else /* !CONFIG_ATFILE */
436

    
437
/*
438
 * Try direct syscalls instead
439
 */
440
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
441
_syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
442
#endif
443
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
444
_syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
445
#endif
446
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
447
_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
448
          uid_t,owner,gid_t,group,int,flags)
449
#endif
450
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
451
        defined(__NR_fstatat64)
452
_syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
453
          struct stat *,buf,int,flags)
454
#endif
455
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
456
_syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
457
         const struct timeval *,times)
458
#endif
459
#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
460
        defined(__NR_newfstatat)
461
_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
462
          struct stat *,buf,int,flags)
463
#endif
464
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
465
_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
466
      int,newdirfd,const char *,newpath,int,flags)
467
#endif
468
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
469
_syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
470
#endif
471
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
472
_syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
473
          mode_t,mode,dev_t,dev)
474
#endif
475
#if defined(TARGET_NR_openat) && defined(__NR_openat)
476
_syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
477
#endif
478
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
479
_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
480
          char *,buf,size_t,bufsize)
481
#endif
482
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
483
_syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
484
          int,newdirfd,const char *,newpath)
485
#endif
486
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
487
_syscall3(int,sys_symlinkat,const char *,oldpath,
488
          int,newdirfd,const char *,newpath)
489
#endif
490
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
491
_syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
492
#endif
493

    
494
#endif /* CONFIG_ATFILE */
495

    
496
#ifdef CONFIG_UTIMENSAT
497
static int sys_utimensat(int dirfd, const char *pathname,
498
    const struct timespec times[2], int flags)
499
{
500
    if (pathname == NULL)
501
        return futimens(dirfd, times);
502
    else
503
        return utimensat(dirfd, pathname, times, flags);
504
}
505
#else
506
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
507
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
508
          const struct timespec *,tsp,int,flags)
509
#endif
510
#endif /* CONFIG_UTIMENSAT  */
511

    
512
#ifdef CONFIG_INOTIFY
513
#include <sys/inotify.h>
514

    
515
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
516
static int sys_inotify_init(void)
517
{
518
  return (inotify_init());
519
}
520
#endif
521
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
522
static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
523
{
524
  return (inotify_add_watch(fd, pathname, mask));
525
}
526
#endif
527
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
528
static int sys_inotify_rm_watch(int fd, int32_t wd)
529
{
530
  return (inotify_rm_watch(fd, wd));
531
}
532
#endif
533
#ifdef CONFIG_INOTIFY1
534
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
535
static int sys_inotify_init1(int flags)
536
{
537
  return (inotify_init1(flags));
538
}
539
#endif
540
#endif
541
#else
542
/* Userspace can usually survive runtime without inotify */
543
#undef TARGET_NR_inotify_init
544
#undef TARGET_NR_inotify_init1
545
#undef TARGET_NR_inotify_add_watch
546
#undef TARGET_NR_inotify_rm_watch
547
#endif /* CONFIG_INOTIFY  */
548

    
549
#if defined(TARGET_NR_ppoll)
550
#ifndef __NR_ppoll
551
# define __NR_ppoll -1
552
#endif
553
#define __NR_sys_ppoll __NR_ppoll
554
_syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
555
          struct timespec *, timeout, const __sigset_t *, sigmask,
556
          size_t, sigsetsize)
557
#endif
558

    
559
#if defined(TARGET_NR_pselect6)
560
#ifndef __NR_pselect6
561
# define __NR_pselect6 -1
562
#endif
563
#define __NR_sys_pselect6 __NR_pselect6
564
_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
565
          fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
566
#endif
567

    
568
#if defined(TARGET_NR_prlimit64)
569
#ifndef __NR_prlimit64
570
# define __NR_prlimit64 -1
571
#endif
572
#define __NR_sys_prlimit64 __NR_prlimit64
573
/* The glibc rlimit structure may not be that used by the underlying syscall */
574
struct host_rlimit64 {
575
    uint64_t rlim_cur;
576
    uint64_t rlim_max;
577
};
578
_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
579
          const struct host_rlimit64 *, new_limit,
580
          struct host_rlimit64 *, old_limit)
581
#endif
582

    
583
extern int personality(int);
584
extern int flock(int, int);
585
extern int setfsuid(int);
586
extern int setfsgid(int);
587
extern int setgroups(int, gid_t *);
588

    
589
/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
590
#ifdef TARGET_ARM 
591
static inline int regpairs_aligned(void *cpu_env) {
592
    return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
593
}
594
#elif defined(TARGET_MIPS)
595
static inline int regpairs_aligned(void *cpu_env) { return 1; }
596
#else
597
static inline int regpairs_aligned(void *cpu_env) { return 0; }
598
#endif
599

    
600
#define ERRNO_TABLE_SIZE 1200
601

    
602
/* target_to_host_errno_table[] is initialized from
603
 * host_to_target_errno_table[] in syscall_init(). */
604
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
605
};
606

    
607
/*
608
 * This list is the union of errno values overridden in asm-<arch>/errno.h
609
 * minus the errnos that are not actually generic to all archs.
610
 */
611
static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
612
    [EIDRM]                = TARGET_EIDRM,
613
    [ECHRNG]                = TARGET_ECHRNG,
614
    [EL2NSYNC]                = TARGET_EL2NSYNC,
615
    [EL3HLT]                = TARGET_EL3HLT,
616
    [EL3RST]                = TARGET_EL3RST,
617
    [ELNRNG]                = TARGET_ELNRNG,
618
    [EUNATCH]                = TARGET_EUNATCH,
619
    [ENOCSI]                = TARGET_ENOCSI,
620
    [EL2HLT]                = TARGET_EL2HLT,
621
    [EDEADLK]                = TARGET_EDEADLK,
622
    [ENOLCK]                = TARGET_ENOLCK,
623
    [EBADE]                = TARGET_EBADE,
624
    [EBADR]                = TARGET_EBADR,
625
    [EXFULL]                = TARGET_EXFULL,
626
    [ENOANO]                = TARGET_ENOANO,
627
    [EBADRQC]                = TARGET_EBADRQC,
628
    [EBADSLT]                = TARGET_EBADSLT,
629
    [EBFONT]                = TARGET_EBFONT,
630
    [ENOSTR]                = TARGET_ENOSTR,
631
    [ENODATA]                = TARGET_ENODATA,
632
    [ETIME]                = TARGET_ETIME,
633
    [ENOSR]                = TARGET_ENOSR,
634
    [ENONET]                = TARGET_ENONET,
635
    [ENOPKG]                = TARGET_ENOPKG,
636
    [EREMOTE]                = TARGET_EREMOTE,
637
    [ENOLINK]                = TARGET_ENOLINK,
638
    [EADV]                = TARGET_EADV,
639
    [ESRMNT]                = TARGET_ESRMNT,
640
    [ECOMM]                = TARGET_ECOMM,
641
    [EPROTO]                = TARGET_EPROTO,
642
    [EDOTDOT]                = TARGET_EDOTDOT,
643
    [EMULTIHOP]                = TARGET_EMULTIHOP,
644
    [EBADMSG]                = TARGET_EBADMSG,
645
    [ENAMETOOLONG]        = TARGET_ENAMETOOLONG,
646
    [EOVERFLOW]                = TARGET_EOVERFLOW,
647
    [ENOTUNIQ]                = TARGET_ENOTUNIQ,
648
    [EBADFD]                = TARGET_EBADFD,
649
    [EREMCHG]                = TARGET_EREMCHG,
650
    [ELIBACC]                = TARGET_ELIBACC,
651
    [ELIBBAD]                = TARGET_ELIBBAD,
652
    [ELIBSCN]                = TARGET_ELIBSCN,
653
    [ELIBMAX]                = TARGET_ELIBMAX,
654
    [ELIBEXEC]                = TARGET_ELIBEXEC,
655
    [EILSEQ]                = TARGET_EILSEQ,
656
    [ENOSYS]                = TARGET_ENOSYS,
657
    [ELOOP]                = TARGET_ELOOP,
658
    [ERESTART]                = TARGET_ERESTART,
659
    [ESTRPIPE]                = TARGET_ESTRPIPE,
660
    [ENOTEMPTY]                = TARGET_ENOTEMPTY,
661
    [EUSERS]                = TARGET_EUSERS,
662
    [ENOTSOCK]                = TARGET_ENOTSOCK,
663
    [EDESTADDRREQ]        = TARGET_EDESTADDRREQ,
664
    [EMSGSIZE]                = TARGET_EMSGSIZE,
665
    [EPROTOTYPE]        = TARGET_EPROTOTYPE,
666
    [ENOPROTOOPT]        = TARGET_ENOPROTOOPT,
667
    [EPROTONOSUPPORT]        = TARGET_EPROTONOSUPPORT,
668
    [ESOCKTNOSUPPORT]        = TARGET_ESOCKTNOSUPPORT,
669
    [EOPNOTSUPP]        = TARGET_EOPNOTSUPP,
670
    [EPFNOSUPPORT]        = TARGET_EPFNOSUPPORT,
671
    [EAFNOSUPPORT]        = TARGET_EAFNOSUPPORT,
672
    [EADDRINUSE]        = TARGET_EADDRINUSE,
673
    [EADDRNOTAVAIL]        = TARGET_EADDRNOTAVAIL,
674
    [ENETDOWN]                = TARGET_ENETDOWN,
675
    [ENETUNREACH]        = TARGET_ENETUNREACH,
676
    [ENETRESET]                = TARGET_ENETRESET,
677
    [ECONNABORTED]        = TARGET_ECONNABORTED,
678
    [ECONNRESET]        = TARGET_ECONNRESET,
679
    [ENOBUFS]                = TARGET_ENOBUFS,
680
    [EISCONN]                = TARGET_EISCONN,
681
    [ENOTCONN]                = TARGET_ENOTCONN,
682
    [EUCLEAN]                = TARGET_EUCLEAN,
683
    [ENOTNAM]                = TARGET_ENOTNAM,
684
    [ENAVAIL]                = TARGET_ENAVAIL,
685
    [EISNAM]                = TARGET_EISNAM,
686
    [EREMOTEIO]                = TARGET_EREMOTEIO,
687
    [ESHUTDOWN]                = TARGET_ESHUTDOWN,
688
    [ETOOMANYREFS]        = TARGET_ETOOMANYREFS,
689
    [ETIMEDOUT]                = TARGET_ETIMEDOUT,
690
    [ECONNREFUSED]        = TARGET_ECONNREFUSED,
691
    [EHOSTDOWN]                = TARGET_EHOSTDOWN,
692
    [EHOSTUNREACH]        = TARGET_EHOSTUNREACH,
693
    [EALREADY]                = TARGET_EALREADY,
694
    [EINPROGRESS]        = TARGET_EINPROGRESS,
695
    [ESTALE]                = TARGET_ESTALE,
696
    [ECANCELED]                = TARGET_ECANCELED,
697
    [ENOMEDIUM]                = TARGET_ENOMEDIUM,
698
    [EMEDIUMTYPE]        = TARGET_EMEDIUMTYPE,
699
#ifdef ENOKEY
700
    [ENOKEY]                = TARGET_ENOKEY,
701
#endif
702
#ifdef EKEYEXPIRED
703
    [EKEYEXPIRED]        = TARGET_EKEYEXPIRED,
704
#endif
705
#ifdef EKEYREVOKED
706
    [EKEYREVOKED]        = TARGET_EKEYREVOKED,
707
#endif
708
#ifdef EKEYREJECTED
709
    [EKEYREJECTED]        = TARGET_EKEYREJECTED,
710
#endif
711
#ifdef EOWNERDEAD
712
    [EOWNERDEAD]        = TARGET_EOWNERDEAD,
713
#endif
714
#ifdef ENOTRECOVERABLE
715
    [ENOTRECOVERABLE]        = TARGET_ENOTRECOVERABLE,
716
#endif
717
};
718

    
719
static inline int host_to_target_errno(int err)
720
{
721
    if(host_to_target_errno_table[err])
722
        return host_to_target_errno_table[err];
723
    return err;
724
}
725

    
726
static inline int target_to_host_errno(int err)
727
{
728
    if (target_to_host_errno_table[err])
729
        return target_to_host_errno_table[err];
730
    return err;
731
}
732

    
733
static inline abi_long get_errno(abi_long ret)
734
{
735
    if (ret == -1)
736
        return -host_to_target_errno(errno);
737
    else
738
        return ret;
739
}
740

    
741
static inline int is_error(abi_long ret)
742
{
743
    return (abi_ulong)ret >= (abi_ulong)(-4096);
744
}
745

    
746
char *target_strerror(int err)
747
{
748
    if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
749
        return NULL;
750
    }
751
    return strerror(target_to_host_errno(err));
752
}
753

    
754
static abi_ulong target_brk;
755
static abi_ulong target_original_brk;
756
static abi_ulong brk_page;
757

    
758
void target_set_brk(abi_ulong new_brk)
759
{
760
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
761
    brk_page = HOST_PAGE_ALIGN(target_brk);
762
}
763

    
764
//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
765
#define DEBUGF_BRK(message, args...)
766

    
767
/* do_brk() must return target values and target errnos. */
768
abi_long do_brk(abi_ulong new_brk)
769
{
770
    abi_long mapped_addr;
771
    int        new_alloc_size;
772

    
773
    DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
774

    
775
    if (!new_brk) {
776
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk);
777
        return target_brk;
778
    }
779
    if (new_brk < target_original_brk) {
780
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n",
781
                   target_brk);
782
        return target_brk;
783
    }
784

    
785
    /* If the new brk is less than the highest page reserved to the
786
     * target heap allocation, set it and we're almost done...  */
787
    if (new_brk <= brk_page) {
788
        /* Heap contents are initialized to zero, as for anonymous
789
         * mapped pages.  */
790
        if (new_brk > target_brk) {
791
            memset(g2h(target_brk), 0, new_brk - target_brk);
792
        }
793
        target_brk = new_brk;
794
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
795
            return target_brk;
796
    }
797

    
798
    /* We need to allocate more memory after the brk... Note that
799
     * we don't use MAP_FIXED because that will map over the top of
800
     * any existing mapping (like the one with the host libc or qemu
801
     * itself); instead we treat "mapped but at wrong address" as
802
     * a failure and unmap again.
803
     */
804
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
805
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
806
                                        PROT_READ|PROT_WRITE,
807
                                        MAP_ANON|MAP_PRIVATE, 0, 0));
808

    
809
    if (mapped_addr == brk_page) {
810
        /* Heap contents are initialized to zero, as for anonymous
811
         * mapped pages.  Technically the new pages are already
812
         * initialized to zero since they *are* anonymous mapped
813
         * pages, however we have to take care with the contents that
814
         * come from the remaining part of the previous page: it may
815
         * contains garbage data due to a previous heap usage (grown
816
         * then shrunken).  */
817
        memset(g2h(target_brk), 0, brk_page - target_brk);
818

    
819
        target_brk = new_brk;
820
        brk_page = HOST_PAGE_ALIGN(target_brk);
821
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n",
822
            target_brk);
823
        return target_brk;
824
    } else if (mapped_addr != -1) {
825
        /* Mapped but at wrong address, meaning there wasn't actually
826
         * enough space for this brk.
827
         */
828
        target_munmap(mapped_addr, new_alloc_size);
829
        mapped_addr = -1;
830
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk);
831
    }
832
    else {
833
        DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk);
834
    }
835

    
836
#if defined(TARGET_ALPHA)
837
    /* We (partially) emulate OSF/1 on Alpha, which requires we
838
       return a proper errno, not an unchanged brk value.  */
839
    return -TARGET_ENOMEM;
840
#endif
841
    /* For everything else, return the previous break. */
842
    return target_brk;
843
}
844

    
845
static inline abi_long copy_from_user_fdset(fd_set *fds,
846
                                            abi_ulong target_fds_addr,
847
                                            int n)
848
{
849
    int i, nw, j, k;
850
    abi_ulong b, *target_fds;
851

    
852
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
853
    if (!(target_fds = lock_user(VERIFY_READ,
854
                                 target_fds_addr,
855
                                 sizeof(abi_ulong) * nw,
856
                                 1)))
857
        return -TARGET_EFAULT;
858

    
859
    FD_ZERO(fds);
860
    k = 0;
861
    for (i = 0; i < nw; i++) {
862
        /* grab the abi_ulong */
863
        __get_user(b, &target_fds[i]);
864
        for (j = 0; j < TARGET_ABI_BITS; j++) {
865
            /* check the bit inside the abi_ulong */
866
            if ((b >> j) & 1)
867
                FD_SET(k, fds);
868
            k++;
869
        }
870
    }
871

    
872
    unlock_user(target_fds, target_fds_addr, 0);
873

    
874
    return 0;
875
}
876

    
877
static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
878
                                                 abi_ulong target_fds_addr,
879
                                                 int n)
880
{
881
    if (target_fds_addr) {
882
        if (copy_from_user_fdset(fds, target_fds_addr, n))
883
            return -TARGET_EFAULT;
884
        *fds_ptr = fds;
885
    } else {
886
        *fds_ptr = NULL;
887
    }
888
    return 0;
889
}
890

    
891
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
892
                                          const fd_set *fds,
893
                                          int n)
894
{
895
    int i, nw, j, k;
896
    abi_long v;
897
    abi_ulong *target_fds;
898

    
899
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
900
    if (!(target_fds = lock_user(VERIFY_WRITE,
901
                                 target_fds_addr,
902
                                 sizeof(abi_ulong) * nw,
903
                                 0)))
904
        return -TARGET_EFAULT;
905

    
906
    k = 0;
907
    for (i = 0; i < nw; i++) {
908
        v = 0;
909
        for (j = 0; j < TARGET_ABI_BITS; j++) {
910
            v |= ((FD_ISSET(k, fds) != 0) << j);
911
            k++;
912
        }
913
        __put_user(v, &target_fds[i]);
914
    }
915

    
916
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
917

    
918
    return 0;
919
}
920

    
921
#if defined(__alpha__)
922
#define HOST_HZ 1024
923
#else
924
#define HOST_HZ 100
925
#endif
926

    
927
static inline abi_long host_to_target_clock_t(long ticks)
928
{
929
#if HOST_HZ == TARGET_HZ
930
    return ticks;
931
#else
932
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
933
#endif
934
}
935

    
936
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
937
                                             const struct rusage *rusage)
938
{
939
    struct target_rusage *target_rusage;
940

    
941
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
942
        return -TARGET_EFAULT;
943
    target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
944
    target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
945
    target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
946
    target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
947
    target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
948
    target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
949
    target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
950
    target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
951
    target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
952
    target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
953
    target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
954
    target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
955
    target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
956
    target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
957
    target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
958
    target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
959
    target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
960
    target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
961
    unlock_user_struct(target_rusage, target_addr, 1);
962

    
963
    return 0;
964
}
965

    
966
static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
967
{
968
    abi_ulong target_rlim_swap;
969
    rlim_t result;
970
    
971
    target_rlim_swap = tswapal(target_rlim);
972
    if (target_rlim_swap == TARGET_RLIM_INFINITY)
973
        return RLIM_INFINITY;
974

    
975
    result = target_rlim_swap;
976
    if (target_rlim_swap != (rlim_t)result)
977
        return RLIM_INFINITY;
978
    
979
    return result;
980
}
981

    
982
static inline abi_ulong host_to_target_rlim(rlim_t rlim)
983
{
984
    abi_ulong target_rlim_swap;
985
    abi_ulong result;
986
    
987
    if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
988
        target_rlim_swap = TARGET_RLIM_INFINITY;
989
    else
990
        target_rlim_swap = rlim;
991
    result = tswapal(target_rlim_swap);
992
    
993
    return result;
994
}
995

    
996
static inline int target_to_host_resource(int code)
997
{
998
    switch (code) {
999
    case TARGET_RLIMIT_AS:
1000
        return RLIMIT_AS;
1001
    case TARGET_RLIMIT_CORE:
1002
        return RLIMIT_CORE;
1003
    case TARGET_RLIMIT_CPU:
1004
        return RLIMIT_CPU;
1005
    case TARGET_RLIMIT_DATA:
1006
        return RLIMIT_DATA;
1007
    case TARGET_RLIMIT_FSIZE:
1008
        return RLIMIT_FSIZE;
1009
    case TARGET_RLIMIT_LOCKS:
1010
        return RLIMIT_LOCKS;
1011
    case TARGET_RLIMIT_MEMLOCK:
1012
        return RLIMIT_MEMLOCK;
1013
    case TARGET_RLIMIT_MSGQUEUE:
1014
        return RLIMIT_MSGQUEUE;
1015
    case TARGET_RLIMIT_NICE:
1016
        return RLIMIT_NICE;
1017
    case TARGET_RLIMIT_NOFILE:
1018
        return RLIMIT_NOFILE;
1019
    case TARGET_RLIMIT_NPROC:
1020
        return RLIMIT_NPROC;
1021
    case TARGET_RLIMIT_RSS:
1022
        return RLIMIT_RSS;
1023
    case TARGET_RLIMIT_RTPRIO:
1024
        return RLIMIT_RTPRIO;
1025
    case TARGET_RLIMIT_SIGPENDING:
1026
        return RLIMIT_SIGPENDING;
1027
    case TARGET_RLIMIT_STACK:
1028
        return RLIMIT_STACK;
1029
    default:
1030
        return code;
1031
    }
1032
}
1033

    
1034
static inline abi_long copy_from_user_timeval(struct timeval *tv,
1035
                                              abi_ulong target_tv_addr)
1036
{
1037
    struct target_timeval *target_tv;
1038

    
1039
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
1040
        return -TARGET_EFAULT;
1041

    
1042
    __get_user(tv->tv_sec, &target_tv->tv_sec);
1043
    __get_user(tv->tv_usec, &target_tv->tv_usec);
1044

    
1045
    unlock_user_struct(target_tv, target_tv_addr, 0);
1046

    
1047
    return 0;
1048
}
1049

    
1050
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
1051
                                            const struct timeval *tv)
1052
{
1053
    struct target_timeval *target_tv;
1054

    
1055
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
1056
        return -TARGET_EFAULT;
1057

    
1058
    __put_user(tv->tv_sec, &target_tv->tv_sec);
1059
    __put_user(tv->tv_usec, &target_tv->tv_usec);
1060

    
1061
    unlock_user_struct(target_tv, target_tv_addr, 1);
1062

    
1063
    return 0;
1064
}
1065

    
1066
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
1067
#include <mqueue.h>
1068

    
1069
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
1070
                                              abi_ulong target_mq_attr_addr)
1071
{
1072
    struct target_mq_attr *target_mq_attr;
1073

    
1074
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
1075
                          target_mq_attr_addr, 1))
1076
        return -TARGET_EFAULT;
1077

    
1078
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
1079
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1080
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1081
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1082

    
1083
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
1084

    
1085
    return 0;
1086
}
1087

    
1088
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
1089
                                            const struct mq_attr *attr)
1090
{
1091
    struct target_mq_attr *target_mq_attr;
1092

    
1093
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
1094
                          target_mq_attr_addr, 0))
1095
        return -TARGET_EFAULT;
1096

    
1097
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
1098
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1099
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1100
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1101

    
1102
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
1103

    
1104
    return 0;
1105
}
1106
#endif
1107

    
1108
#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
1109
/* do_select() must return target values and target errnos. */
1110
static abi_long do_select(int n,
1111
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
1112
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
1113
{
1114
    fd_set rfds, wfds, efds;
1115
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
1116
    struct timeval tv, *tv_ptr;
1117
    abi_long ret;
1118

    
1119
    ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1120
    if (ret) {
1121
        return ret;
1122
    }
1123
    ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1124
    if (ret) {
1125
        return ret;
1126
    }
1127
    ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1128
    if (ret) {
1129
        return ret;
1130
    }
1131

    
1132
    if (target_tv_addr) {
1133
        if (copy_from_user_timeval(&tv, target_tv_addr))
1134
            return -TARGET_EFAULT;
1135
        tv_ptr = &tv;
1136
    } else {
1137
        tv_ptr = NULL;
1138
    }
1139

    
1140
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
1141

    
1142
    if (!is_error(ret)) {
1143
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1144
            return -TARGET_EFAULT;
1145
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1146
            return -TARGET_EFAULT;
1147
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1148
            return -TARGET_EFAULT;
1149

    
1150
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
1151
            return -TARGET_EFAULT;
1152
    }
1153

    
1154
    return ret;
1155
}
1156
#endif
1157

    
1158
static abi_long do_pipe2(int host_pipe[], int flags)
1159
{
1160
#ifdef CONFIG_PIPE2
1161
    return pipe2(host_pipe, flags);
1162
#else
1163
    return -ENOSYS;
1164
#endif
1165
}
1166

    
1167
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1168
                        int flags, int is_pipe2)
1169
{
1170
    int host_pipe[2];
1171
    abi_long ret;
1172
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1173

    
1174
    if (is_error(ret))
1175
        return get_errno(ret);
1176

    
1177
    /* Several targets have special calling conventions for the original
1178
       pipe syscall, but didn't replicate this into the pipe2 syscall.  */
1179
    if (!is_pipe2) {
1180
#if defined(TARGET_ALPHA)
1181
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1182
        return host_pipe[0];
1183
#elif defined(TARGET_MIPS)
1184
        ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1185
        return host_pipe[0];
1186
#elif defined(TARGET_SH4)
1187
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1188
        return host_pipe[0];
1189
#endif
1190
    }
1191

    
1192
    if (put_user_s32(host_pipe[0], pipedes)
1193
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1194
        return -TARGET_EFAULT;
1195
    return get_errno(ret);
1196
}
1197

    
1198
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1199
                                              abi_ulong target_addr,
1200
                                              socklen_t len)
1201
{
1202
    struct target_ip_mreqn *target_smreqn;
1203

    
1204
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1205
    if (!target_smreqn)
1206
        return -TARGET_EFAULT;
1207
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1208
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1209
    if (len == sizeof(struct target_ip_mreqn))
1210
        mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
1211
    unlock_user(target_smreqn, target_addr, 0);
1212

    
1213
    return 0;
1214
}
1215

    
1216
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1217
                                               abi_ulong target_addr,
1218
                                               socklen_t len)
1219
{
1220
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1221
    sa_family_t sa_family;
1222
    struct target_sockaddr *target_saddr;
1223

    
1224
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1225
    if (!target_saddr)
1226
        return -TARGET_EFAULT;
1227

    
1228
    sa_family = tswap16(target_saddr->sa_family);
1229

    
1230
    /* Oops. The caller might send a incomplete sun_path; sun_path
1231
     * must be terminated by \0 (see the manual page), but
1232
     * unfortunately it is quite common to specify sockaddr_un
1233
     * length as "strlen(x->sun_path)" while it should be
1234
     * "strlen(...) + 1". We'll fix that here if needed.
1235
     * Linux kernel has a similar feature.
1236
     */
1237

    
1238
    if (sa_family == AF_UNIX) {
1239
        if (len < unix_maxlen && len > 0) {
1240
            char *cp = (char*)target_saddr;
1241

    
1242
            if ( cp[len-1] && !cp[len] )
1243
                len++;
1244
        }
1245
        if (len > unix_maxlen)
1246
            len = unix_maxlen;
1247
    }
1248

    
1249
    memcpy(addr, target_saddr, len);
1250
    addr->sa_family = sa_family;
1251
    unlock_user(target_saddr, target_addr, 0);
1252

    
1253
    return 0;
1254
}
1255

    
1256
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1257
                                               struct sockaddr *addr,
1258
                                               socklen_t len)
1259
{
1260
    struct target_sockaddr *target_saddr;
1261

    
1262
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1263
    if (!target_saddr)
1264
        return -TARGET_EFAULT;
1265
    memcpy(target_saddr, addr, len);
1266
    target_saddr->sa_family = tswap16(addr->sa_family);
1267
    unlock_user(target_saddr, target_addr, len);
1268

    
1269
    return 0;
1270
}
1271

    
1272
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1273
                                           struct target_msghdr *target_msgh)
1274
{
1275
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1276
    abi_long msg_controllen;
1277
    abi_ulong target_cmsg_addr;
1278
    struct target_cmsghdr *target_cmsg;
1279
    socklen_t space = 0;
1280
    
1281
    msg_controllen = tswapal(target_msgh->msg_controllen);
1282
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1283
        goto the_end;
1284
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1285
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1286
    if (!target_cmsg)
1287
        return -TARGET_EFAULT;
1288

    
1289
    while (cmsg && target_cmsg) {
1290
        void *data = CMSG_DATA(cmsg);
1291
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1292

    
1293
        int len = tswapal(target_cmsg->cmsg_len)
1294
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1295

    
1296
        space += CMSG_SPACE(len);
1297
        if (space > msgh->msg_controllen) {
1298
            space -= CMSG_SPACE(len);
1299
            gemu_log("Host cmsg overflow\n");
1300
            break;
1301
        }
1302

    
1303
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1304
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1305
        cmsg->cmsg_len = CMSG_LEN(len);
1306

    
1307
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1308
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1309
            memcpy(data, target_data, len);
1310
        } else {
1311
            int *fd = (int *)data;
1312
            int *target_fd = (int *)target_data;
1313
            int i, numfds = len / sizeof(int);
1314

    
1315
            for (i = 0; i < numfds; i++)
1316
                fd[i] = tswap32(target_fd[i]);
1317
        }
1318

    
1319
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1320
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1321
    }
1322
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1323
 the_end:
1324
    msgh->msg_controllen = space;
1325
    return 0;
1326
}
1327

    
1328
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1329
                                           struct msghdr *msgh)
1330
{
1331
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1332
    abi_long msg_controllen;
1333
    abi_ulong target_cmsg_addr;
1334
    struct target_cmsghdr *target_cmsg;
1335
    socklen_t space = 0;
1336

    
1337
    msg_controllen = tswapal(target_msgh->msg_controllen);
1338
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1339
        goto the_end;
1340
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1341
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1342
    if (!target_cmsg)
1343
        return -TARGET_EFAULT;
1344

    
1345
    while (cmsg && target_cmsg) {
1346
        void *data = CMSG_DATA(cmsg);
1347
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1348

    
1349
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1350

    
1351
        space += TARGET_CMSG_SPACE(len);
1352
        if (space > msg_controllen) {
1353
            space -= TARGET_CMSG_SPACE(len);
1354
            gemu_log("Target cmsg overflow\n");
1355
            break;
1356
        }
1357

    
1358
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1359
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1360
        target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len));
1361

    
1362
        if ((cmsg->cmsg_level == TARGET_SOL_SOCKET) &&
1363
                                (cmsg->cmsg_type == SCM_RIGHTS)) {
1364
            int *fd = (int *)data;
1365
            int *target_fd = (int *)target_data;
1366
            int i, numfds = len / sizeof(int);
1367

    
1368
            for (i = 0; i < numfds; i++)
1369
                target_fd[i] = tswap32(fd[i]);
1370
        } else if ((cmsg->cmsg_level == TARGET_SOL_SOCKET) &&
1371
                                (cmsg->cmsg_type == SO_TIMESTAMP) &&
1372
                                (len == sizeof(struct timeval))) {
1373
            /* copy struct timeval to target */
1374
            struct timeval *tv = (struct timeval *)data;
1375
            struct target_timeval *target_tv =
1376
                                        (struct target_timeval *)target_data;
1377

    
1378
            target_tv->tv_sec = tswapal(tv->tv_sec);
1379
            target_tv->tv_usec = tswapal(tv->tv_usec);
1380
        } else {
1381
            gemu_log("Unsupported ancillary data: %d/%d\n",
1382
                                        cmsg->cmsg_level, cmsg->cmsg_type);
1383
            memcpy(target_data, data, len);
1384
        }
1385

    
1386
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1387
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1388
    }
1389
    unlock_user(target_cmsg, target_cmsg_addr, space);
1390
 the_end:
1391
    target_msgh->msg_controllen = tswapal(space);
1392
    return 0;
1393
}
1394

    
1395
/* do_setsockopt() Must return target values and target errnos. */
1396
static abi_long do_setsockopt(int sockfd, int level, int optname,
1397
                              abi_ulong optval_addr, socklen_t optlen)
1398
{
1399
    abi_long ret;
1400
    int val;
1401
    struct ip_mreqn *ip_mreq;
1402
    struct ip_mreq_source *ip_mreq_source;
1403

    
1404
    switch(level) {
1405
    case SOL_TCP:
1406
        /* TCP options all take an 'int' value.  */
1407
        if (optlen < sizeof(uint32_t))
1408
            return -TARGET_EINVAL;
1409

    
1410
        if (get_user_u32(val, optval_addr))
1411
            return -TARGET_EFAULT;
1412
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1413
        break;
1414
    case SOL_IP:
1415
        switch(optname) {
1416
        case IP_TOS:
1417
        case IP_TTL:
1418
        case IP_HDRINCL:
1419
        case IP_ROUTER_ALERT:
1420
        case IP_RECVOPTS:
1421
        case IP_RETOPTS:
1422
        case IP_PKTINFO:
1423
        case IP_MTU_DISCOVER:
1424
        case IP_RECVERR:
1425
        case IP_RECVTOS:
1426
#ifdef IP_FREEBIND
1427
        case IP_FREEBIND:
1428
#endif
1429
        case IP_MULTICAST_TTL:
1430
        case IP_MULTICAST_LOOP:
1431
            val = 0;
1432
            if (optlen >= sizeof(uint32_t)) {
1433
                if (get_user_u32(val, optval_addr))
1434
                    return -TARGET_EFAULT;
1435
            } else if (optlen >= 1) {
1436
                if (get_user_u8(val, optval_addr))
1437
                    return -TARGET_EFAULT;
1438
            }
1439
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1440
            break;
1441
        case IP_ADD_MEMBERSHIP:
1442
        case IP_DROP_MEMBERSHIP:
1443
            if (optlen < sizeof (struct target_ip_mreq) ||
1444
                optlen > sizeof (struct target_ip_mreqn))
1445
                return -TARGET_EINVAL;
1446

    
1447
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1448
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1449
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1450
            break;
1451

    
1452
        case IP_BLOCK_SOURCE:
1453
        case IP_UNBLOCK_SOURCE:
1454
        case IP_ADD_SOURCE_MEMBERSHIP:
1455
        case IP_DROP_SOURCE_MEMBERSHIP:
1456
            if (optlen != sizeof (struct target_ip_mreq_source))
1457
                return -TARGET_EINVAL;
1458

    
1459
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1460
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1461
            unlock_user (ip_mreq_source, optval_addr, 0);
1462
            break;
1463

    
1464
        default:
1465
            goto unimplemented;
1466
        }
1467
        break;
1468
    case SOL_RAW:
1469
        switch (optname) {
1470
        case ICMP_FILTER:
1471
            /* struct icmp_filter takes an u32 value */
1472
            if (optlen < sizeof(uint32_t)) {
1473
                return -TARGET_EINVAL;
1474
            }
1475

    
1476
            if (get_user_u32(val, optval_addr)) {
1477
                return -TARGET_EFAULT;
1478
            }
1479
            ret = get_errno(setsockopt(sockfd, level, optname,
1480
                                       &val, sizeof(val)));
1481
            break;
1482

    
1483
        default:
1484
            goto unimplemented;
1485
        }
1486
        break;
1487
    case TARGET_SOL_SOCKET:
1488
        switch (optname) {
1489
            /* Options with 'int' argument.  */
1490
        case TARGET_SO_DEBUG:
1491
                optname = SO_DEBUG;
1492
                break;
1493
        case TARGET_SO_REUSEADDR:
1494
                optname = SO_REUSEADDR;
1495
                break;
1496
        case TARGET_SO_TYPE:
1497
                optname = SO_TYPE;
1498
                break;
1499
        case TARGET_SO_ERROR:
1500
                optname = SO_ERROR;
1501
                break;
1502
        case TARGET_SO_DONTROUTE:
1503
                optname = SO_DONTROUTE;
1504
                break;
1505
        case TARGET_SO_BROADCAST:
1506
                optname = SO_BROADCAST;
1507
                break;
1508
        case TARGET_SO_SNDBUF:
1509
                optname = SO_SNDBUF;
1510
                break;
1511
        case TARGET_SO_RCVBUF:
1512
                optname = SO_RCVBUF;
1513
                break;
1514
        case TARGET_SO_KEEPALIVE:
1515
                optname = SO_KEEPALIVE;
1516
                break;
1517
        case TARGET_SO_OOBINLINE:
1518
                optname = SO_OOBINLINE;
1519
                break;
1520
        case TARGET_SO_NO_CHECK:
1521
                optname = SO_NO_CHECK;
1522
                break;
1523
        case TARGET_SO_PRIORITY:
1524
                optname = SO_PRIORITY;
1525
                break;
1526
#ifdef SO_BSDCOMPAT
1527
        case TARGET_SO_BSDCOMPAT:
1528
                optname = SO_BSDCOMPAT;
1529
                break;
1530
#endif
1531
        case TARGET_SO_PASSCRED:
1532
                optname = SO_PASSCRED;
1533
                break;
1534
        case TARGET_SO_TIMESTAMP:
1535
                optname = SO_TIMESTAMP;
1536
                break;
1537
        case TARGET_SO_RCVLOWAT:
1538
                optname = SO_RCVLOWAT;
1539
                break;
1540
        case TARGET_SO_RCVTIMEO:
1541
                optname = SO_RCVTIMEO;
1542
                break;
1543
        case TARGET_SO_SNDTIMEO:
1544
                optname = SO_SNDTIMEO;
1545
                break;
1546
            break;
1547
        default:
1548
            goto unimplemented;
1549
        }
1550
        if (optlen < sizeof(uint32_t))
1551
            return -TARGET_EINVAL;
1552

    
1553
        if (get_user_u32(val, optval_addr))
1554
            return -TARGET_EFAULT;
1555
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1556
        break;
1557
    default:
1558
    unimplemented:
1559
        gemu_log("Unsupported setsockopt level=%d optname=%d\n", level, optname);
1560
        ret = -TARGET_ENOPROTOOPT;
1561
    }
1562
    return ret;
1563
}
1564

    
1565
/* do_getsockopt() Must return target values and target errnos. */
1566
static abi_long do_getsockopt(int sockfd, int level, int optname,
1567
                              abi_ulong optval_addr, abi_ulong optlen)
1568
{
1569
    abi_long ret;
1570
    int len, val;
1571
    socklen_t lv;
1572

    
1573
    switch(level) {
1574
    case TARGET_SOL_SOCKET:
1575
        level = SOL_SOCKET;
1576
        switch (optname) {
1577
        /* These don't just return a single integer */
1578
        case TARGET_SO_LINGER:
1579
        case TARGET_SO_RCVTIMEO:
1580
        case TARGET_SO_SNDTIMEO:
1581
        case TARGET_SO_PEERNAME:
1582
            goto unimplemented;
1583
        case TARGET_SO_PEERCRED: {
1584
            struct ucred cr;
1585
            socklen_t crlen;
1586
            struct target_ucred *tcr;
1587

    
1588
            if (get_user_u32(len, optlen)) {
1589
                return -TARGET_EFAULT;
1590
            }
1591
            if (len < 0) {
1592
                return -TARGET_EINVAL;
1593
            }
1594

    
1595
            crlen = sizeof(cr);
1596
            ret = get_errno(getsockopt(sockfd, level, SO_PEERCRED,
1597
                                       &cr, &crlen));
1598
            if (ret < 0) {
1599
                return ret;
1600
            }
1601
            if (len > crlen) {
1602
                len = crlen;
1603
            }
1604
            if (!lock_user_struct(VERIFY_WRITE, tcr, optval_addr, 0)) {
1605
                return -TARGET_EFAULT;
1606
            }
1607
            __put_user(cr.pid, &tcr->pid);
1608
            __put_user(cr.uid, &tcr->uid);
1609
            __put_user(cr.gid, &tcr->gid);
1610
            unlock_user_struct(tcr, optval_addr, 1);
1611
            if (put_user_u32(len, optlen)) {
1612
                return -TARGET_EFAULT;
1613
            }
1614
            break;
1615
        }
1616
        /* Options with 'int' argument.  */
1617
        case TARGET_SO_DEBUG:
1618
            optname = SO_DEBUG;
1619
            goto int_case;
1620
        case TARGET_SO_REUSEADDR:
1621
            optname = SO_REUSEADDR;
1622
            goto int_case;
1623
        case TARGET_SO_TYPE:
1624
            optname = SO_TYPE;
1625
            goto int_case;
1626
        case TARGET_SO_ERROR:
1627
            optname = SO_ERROR;
1628
            goto int_case;
1629
        case TARGET_SO_DONTROUTE:
1630
            optname = SO_DONTROUTE;
1631
            goto int_case;
1632
        case TARGET_SO_BROADCAST:
1633
            optname = SO_BROADCAST;
1634
            goto int_case;
1635
        case TARGET_SO_SNDBUF:
1636
            optname = SO_SNDBUF;
1637
            goto int_case;
1638
        case TARGET_SO_RCVBUF:
1639
            optname = SO_RCVBUF;
1640
            goto int_case;
1641
        case TARGET_SO_KEEPALIVE:
1642
            optname = SO_KEEPALIVE;
1643
            goto int_case;
1644
        case TARGET_SO_OOBINLINE:
1645
            optname = SO_OOBINLINE;
1646
            goto int_case;
1647
        case TARGET_SO_NO_CHECK:
1648
            optname = SO_NO_CHECK;
1649
            goto int_case;
1650
        case TARGET_SO_PRIORITY:
1651
            optname = SO_PRIORITY;
1652
            goto int_case;
1653
#ifdef SO_BSDCOMPAT
1654
        case TARGET_SO_BSDCOMPAT:
1655
            optname = SO_BSDCOMPAT;
1656
            goto int_case;
1657
#endif
1658
        case TARGET_SO_PASSCRED:
1659
            optname = SO_PASSCRED;
1660
            goto int_case;
1661
        case TARGET_SO_TIMESTAMP:
1662
            optname = SO_TIMESTAMP;
1663
            goto int_case;
1664
        case TARGET_SO_RCVLOWAT:
1665
            optname = SO_RCVLOWAT;
1666
            goto int_case;
1667
        default:
1668
            goto int_case;
1669
        }
1670
        break;
1671
    case SOL_TCP:
1672
        /* TCP options all take an 'int' value.  */
1673
    int_case:
1674
        if (get_user_u32(len, optlen))
1675
            return -TARGET_EFAULT;
1676
        if (len < 0)
1677
            return -TARGET_EINVAL;
1678
        lv = sizeof(lv);
1679
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1680
        if (ret < 0)
1681
            return ret;
1682
        if (len > lv)
1683
            len = lv;
1684
        if (len == 4) {
1685
            if (put_user_u32(val, optval_addr))
1686
                return -TARGET_EFAULT;
1687
        } else {
1688
            if (put_user_u8(val, optval_addr))
1689
                return -TARGET_EFAULT;
1690
        }
1691
        if (put_user_u32(len, optlen))
1692
            return -TARGET_EFAULT;
1693
        break;
1694
    case SOL_IP:
1695
        switch(optname) {
1696
        case IP_TOS:
1697
        case IP_TTL:
1698
        case IP_HDRINCL:
1699
        case IP_ROUTER_ALERT:
1700
        case IP_RECVOPTS:
1701
        case IP_RETOPTS:
1702
        case IP_PKTINFO:
1703
        case IP_MTU_DISCOVER:
1704
        case IP_RECVERR:
1705
        case IP_RECVTOS:
1706
#ifdef IP_FREEBIND
1707
        case IP_FREEBIND:
1708
#endif
1709
        case IP_MULTICAST_TTL:
1710
        case IP_MULTICAST_LOOP:
1711
            if (get_user_u32(len, optlen))
1712
                return -TARGET_EFAULT;
1713
            if (len < 0)
1714
                return -TARGET_EINVAL;
1715
            lv = sizeof(lv);
1716
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1717
            if (ret < 0)
1718
                return ret;
1719
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1720
                len = 1;
1721
                if (put_user_u32(len, optlen)
1722
                    || put_user_u8(val, optval_addr))
1723
                    return -TARGET_EFAULT;
1724
            } else {
1725
                if (len > sizeof(int))
1726
                    len = sizeof(int);
1727
                if (put_user_u32(len, optlen)
1728
                    || put_user_u32(val, optval_addr))
1729
                    return -TARGET_EFAULT;
1730
            }
1731
            break;
1732
        default:
1733
            ret = -TARGET_ENOPROTOOPT;
1734
            break;
1735
        }
1736
        break;
1737
    default:
1738
    unimplemented:
1739
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1740
                 level, optname);
1741
        ret = -TARGET_EOPNOTSUPP;
1742
        break;
1743
    }
1744
    return ret;
1745
}
1746

    
1747
/* FIXME
1748
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1749
 * other lock functions have a return code of 0 for failure.
1750
 */
1751
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1752
                           int count, int copy)
1753
{
1754
    struct target_iovec *target_vec;
1755
    abi_ulong base;
1756
    int i;
1757

    
1758
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1759
    if (!target_vec)
1760
        return -TARGET_EFAULT;
1761
    for(i = 0;i < count; i++) {
1762
        base = tswapal(target_vec[i].iov_base);
1763
        vec[i].iov_len = tswapal(target_vec[i].iov_len);
1764
        if (vec[i].iov_len != 0) {
1765
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1766
            /* Don't check lock_user return value. We must call writev even
1767
               if a element has invalid base address. */
1768
        } else {
1769
            /* zero length pointer is ignored */
1770
            vec[i].iov_base = NULL;
1771
        }
1772
    }
1773
    unlock_user (target_vec, target_addr, 0);
1774
    return 0;
1775
}
1776

    
1777
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1778
                             int count, int copy)
1779
{
1780
    struct target_iovec *target_vec;
1781
    abi_ulong base;
1782
    int i;
1783

    
1784
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1785
    if (!target_vec)
1786
        return -TARGET_EFAULT;
1787
    for(i = 0;i < count; i++) {
1788
        if (target_vec[i].iov_base) {
1789
            base = tswapal(target_vec[i].iov_base);
1790
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1791
        }
1792
    }
1793
    unlock_user (target_vec, target_addr, 0);
1794

    
1795
    return 0;
1796
}
1797

    
1798
/* do_socket() Must return target values and target errnos. */
1799
static abi_long do_socket(int domain, int type, int protocol)
1800
{
1801
#if defined(TARGET_MIPS)
1802
    switch(type) {
1803
    case TARGET_SOCK_DGRAM:
1804
        type = SOCK_DGRAM;
1805
        break;
1806
    case TARGET_SOCK_STREAM:
1807
        type = SOCK_STREAM;
1808
        break;
1809
    case TARGET_SOCK_RAW:
1810
        type = SOCK_RAW;
1811
        break;
1812
    case TARGET_SOCK_RDM:
1813
        type = SOCK_RDM;
1814
        break;
1815
    case TARGET_SOCK_SEQPACKET:
1816
        type = SOCK_SEQPACKET;
1817
        break;
1818
    case TARGET_SOCK_PACKET:
1819
        type = SOCK_PACKET;
1820
        break;
1821
    }
1822
#endif
1823
    if (domain == PF_NETLINK)
1824
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1825
    return get_errno(socket(domain, type, protocol));
1826
}
1827

    
1828
/* do_bind() Must return target values and target errnos. */
1829
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1830
                        socklen_t addrlen)
1831
{
1832
    void *addr;
1833
    abi_long ret;
1834

    
1835
    if ((int)addrlen < 0) {
1836
        return -TARGET_EINVAL;
1837
    }
1838

    
1839
    addr = alloca(addrlen+1);
1840

    
1841
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1842
    if (ret)
1843
        return ret;
1844

    
1845
    return get_errno(bind(sockfd, addr, addrlen));
1846
}
1847

    
1848
/* do_connect() Must return target values and target errnos. */
1849
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1850
                           socklen_t addrlen)
1851
{
1852
    void *addr;
1853
    abi_long ret;
1854

    
1855
    if ((int)addrlen < 0) {
1856
        return -TARGET_EINVAL;
1857
    }
1858

    
1859
    addr = alloca(addrlen);
1860

    
1861
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1862
    if (ret)
1863
        return ret;
1864

    
1865
    return get_errno(connect(sockfd, addr, addrlen));
1866
}
1867

    
1868
/* do_sendrecvmsg() Must return target values and target errnos. */
1869
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1870
                               int flags, int send)
1871
{
1872
    abi_long ret, len;
1873
    struct target_msghdr *msgp;
1874
    struct msghdr msg;
1875
    int count;
1876
    struct iovec *vec;
1877
    abi_ulong target_vec;
1878

    
1879
    /* FIXME */
1880
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1881
                          msgp,
1882
                          target_msg,
1883
                          send ? 1 : 0))
1884
        return -TARGET_EFAULT;
1885
    if (msgp->msg_name) {
1886
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1887
        msg.msg_name = alloca(msg.msg_namelen);
1888
        ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name),
1889
                                msg.msg_namelen);
1890
        if (ret) {
1891
            unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1892
            return ret;
1893
        }
1894
    } else {
1895
        msg.msg_name = NULL;
1896
        msg.msg_namelen = 0;
1897
    }
1898
    msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
1899
    msg.msg_control = alloca(msg.msg_controllen);
1900
    msg.msg_flags = tswap32(msgp->msg_flags);
1901

    
1902
    count = tswapal(msgp->msg_iovlen);
1903
    vec = alloca(count * sizeof(struct iovec));
1904
    target_vec = tswapal(msgp->msg_iov);
1905
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1906
    msg.msg_iovlen = count;
1907
    msg.msg_iov = vec;
1908

    
1909
    if (send) {
1910
        ret = target_to_host_cmsg(&msg, msgp);
1911
        if (ret == 0)
1912
            ret = get_errno(sendmsg(fd, &msg, flags));
1913
    } else {
1914
        ret = get_errno(recvmsg(fd, &msg, flags));
1915
        if (!is_error(ret)) {
1916
            len = ret;
1917
            ret = host_to_target_cmsg(msgp, &msg);
1918
            if (!is_error(ret)) {
1919
                msgp->msg_namelen = tswap32(msg.msg_namelen);
1920
                if (msg.msg_name != NULL) {
1921
                    ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
1922
                                    msg.msg_name, msg.msg_namelen);
1923
                    if (ret) {
1924
                        goto out;
1925
                    }
1926
                }
1927

    
1928
                ret = len;
1929
            }
1930
        }
1931
    }
1932

    
1933
out:
1934
    unlock_iovec(vec, target_vec, count, !send);
1935
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1936
    return ret;
1937
}
1938

    
1939
/* do_accept() Must return target values and target errnos. */
1940
static abi_long do_accept(int fd, abi_ulong target_addr,
1941
                          abi_ulong target_addrlen_addr)
1942
{
1943
    socklen_t addrlen;
1944
    void *addr;
1945
    abi_long ret;
1946

    
1947
    if (target_addr == 0)
1948
       return get_errno(accept(fd, NULL, NULL));
1949

    
1950
    /* linux returns EINVAL if addrlen pointer is invalid */
1951
    if (get_user_u32(addrlen, target_addrlen_addr))
1952
        return -TARGET_EINVAL;
1953

    
1954
    if ((int)addrlen < 0) {
1955
        return -TARGET_EINVAL;
1956
    }
1957

    
1958
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1959
        return -TARGET_EINVAL;
1960

    
1961
    addr = alloca(addrlen);
1962

    
1963
    ret = get_errno(accept(fd, addr, &addrlen));
1964
    if (!is_error(ret)) {
1965
        host_to_target_sockaddr(target_addr, addr, addrlen);
1966
        if (put_user_u32(addrlen, target_addrlen_addr))
1967
            ret = -TARGET_EFAULT;
1968
    }
1969
    return ret;
1970
}
1971

    
1972
/* do_getpeername() Must return target values and target errnos. */
1973
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1974
                               abi_ulong target_addrlen_addr)
1975
{
1976
    socklen_t addrlen;
1977
    void *addr;
1978
    abi_long ret;
1979

    
1980
    if (get_user_u32(addrlen, target_addrlen_addr))
1981
        return -TARGET_EFAULT;
1982

    
1983
    if ((int)addrlen < 0) {
1984
        return -TARGET_EINVAL;
1985
    }
1986

    
1987
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1988
        return -TARGET_EFAULT;
1989

    
1990
    addr = alloca(addrlen);
1991

    
1992
    ret = get_errno(getpeername(fd, addr, &addrlen));
1993
    if (!is_error(ret)) {
1994
        host_to_target_sockaddr(target_addr, addr, addrlen);
1995
        if (put_user_u32(addrlen, target_addrlen_addr))
1996
            ret = -TARGET_EFAULT;
1997
    }
1998
    return ret;
1999
}
2000

    
2001
/* do_getsockname() Must return target values and target errnos. */
2002
static abi_long do_getsockname(int fd, abi_ulong target_addr,
2003
                               abi_ulong target_addrlen_addr)
2004
{
2005
    socklen_t addrlen;
2006
    void *addr;
2007
    abi_long ret;
2008

    
2009
    if (get_user_u32(addrlen, target_addrlen_addr))
2010
        return -TARGET_EFAULT;
2011

    
2012
    if ((int)addrlen < 0) {
2013
        return -TARGET_EINVAL;
2014
    }
2015

    
2016
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2017
        return -TARGET_EFAULT;
2018

    
2019
    addr = alloca(addrlen);
2020

    
2021
    ret = get_errno(getsockname(fd, addr, &addrlen));
2022
    if (!is_error(ret)) {
2023
        host_to_target_sockaddr(target_addr, addr, addrlen);
2024
        if (put_user_u32(addrlen, target_addrlen_addr))
2025
            ret = -TARGET_EFAULT;
2026
    }
2027
    return ret;
2028
}
2029

    
2030
/* do_socketpair() Must return target values and target errnos. */
2031
static abi_long do_socketpair(int domain, int type, int protocol,
2032
                              abi_ulong target_tab_addr)
2033
{
2034
    int tab[2];
2035
    abi_long ret;
2036

    
2037
    ret = get_errno(socketpair(domain, type, protocol, tab));
2038
    if (!is_error(ret)) {
2039
        if (put_user_s32(tab[0], target_tab_addr)
2040
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
2041
            ret = -TARGET_EFAULT;
2042
    }
2043
    return ret;
2044
}
2045

    
2046
/* do_sendto() Must return target values and target errnos. */
2047
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
2048
                          abi_ulong target_addr, socklen_t addrlen)
2049
{
2050
    void *addr;
2051
    void *host_msg;
2052
    abi_long ret;
2053

    
2054
    if ((int)addrlen < 0) {
2055
        return -TARGET_EINVAL;
2056
    }
2057

    
2058
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
2059
    if (!host_msg)
2060
        return -TARGET_EFAULT;
2061
    if (target_addr) {
2062
        addr = alloca(addrlen);
2063
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
2064
        if (ret) {
2065
            unlock_user(host_msg, msg, 0);
2066
            return ret;
2067
        }
2068
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
2069
    } else {
2070
        ret = get_errno(send(fd, host_msg, len, flags));
2071
    }
2072
    unlock_user(host_msg, msg, 0);
2073
    return ret;
2074
}
2075

    
2076
/* do_recvfrom() Must return target values and target errnos. */
2077
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
2078
                            abi_ulong target_addr,
2079
                            abi_ulong target_addrlen)
2080
{
2081
    socklen_t addrlen;
2082
    void *addr;
2083
    void *host_msg;
2084
    abi_long ret;
2085

    
2086
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
2087
    if (!host_msg)
2088
        return -TARGET_EFAULT;
2089
    if (target_addr) {
2090
        if (get_user_u32(addrlen, target_addrlen)) {
2091
            ret = -TARGET_EFAULT;
2092
            goto fail;
2093
        }
2094
        if ((int)addrlen < 0) {
2095
            ret = -TARGET_EINVAL;
2096
            goto fail;
2097
        }
2098
        addr = alloca(addrlen);
2099
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
2100
    } else {
2101
        addr = NULL; /* To keep compiler quiet.  */
2102
        ret = get_errno(qemu_recv(fd, host_msg, len, flags));
2103
    }
2104
    if (!is_error(ret)) {
2105
        if (target_addr) {
2106
            host_to_target_sockaddr(target_addr, addr, addrlen);
2107
            if (put_user_u32(addrlen, target_addrlen)) {
2108
                ret = -TARGET_EFAULT;
2109
                goto fail;
2110
            }
2111
        }
2112
        unlock_user(host_msg, msg, len);
2113
    } else {
2114
fail:
2115
        unlock_user(host_msg, msg, 0);
2116
    }
2117
    return ret;
2118
}
2119

    
2120
#ifdef TARGET_NR_socketcall
2121
/* do_socketcall() Must return target values and target errnos. */
2122
static abi_long do_socketcall(int num, abi_ulong vptr)
2123
{
2124
    abi_long ret;
2125
    const int n = sizeof(abi_ulong);
2126

    
2127
    switch(num) {
2128
    case SOCKOP_socket:
2129
        {
2130
            abi_ulong domain, type, protocol;
2131

    
2132
            if (get_user_ual(domain, vptr)
2133
                || get_user_ual(type, vptr + n)
2134
                || get_user_ual(protocol, vptr + 2 * n))
2135
                return -TARGET_EFAULT;
2136

    
2137
            ret = do_socket(domain, type, protocol);
2138
        }
2139
        break;
2140
    case SOCKOP_bind:
2141
        {
2142
            abi_ulong sockfd;
2143
            abi_ulong target_addr;
2144
            socklen_t addrlen;
2145

    
2146
            if (get_user_ual(sockfd, vptr)
2147
                || get_user_ual(target_addr, vptr + n)
2148
                || get_user_ual(addrlen, vptr + 2 * n))
2149
                return -TARGET_EFAULT;
2150

    
2151
            ret = do_bind(sockfd, target_addr, addrlen);
2152
        }
2153
        break;
2154
    case SOCKOP_connect:
2155
        {
2156
            abi_ulong sockfd;
2157
            abi_ulong target_addr;
2158
            socklen_t addrlen;
2159

    
2160
            if (get_user_ual(sockfd, vptr)
2161
                || get_user_ual(target_addr, vptr + n)
2162
                || get_user_ual(addrlen, vptr + 2 * n))
2163
                return -TARGET_EFAULT;
2164

    
2165
            ret = do_connect(sockfd, target_addr, addrlen);
2166
        }
2167
        break;
2168
    case SOCKOP_listen:
2169
        {
2170
            abi_ulong sockfd, backlog;
2171

    
2172
            if (get_user_ual(sockfd, vptr)
2173
                || get_user_ual(backlog, vptr + n))
2174
                return -TARGET_EFAULT;
2175

    
2176
            ret = get_errno(listen(sockfd, backlog));
2177
        }
2178
        break;
2179
    case SOCKOP_accept:
2180
        {
2181
            abi_ulong sockfd;
2182
            abi_ulong target_addr, target_addrlen;
2183

    
2184
            if (get_user_ual(sockfd, vptr)
2185
                || get_user_ual(target_addr, vptr + n)
2186
                || get_user_ual(target_addrlen, vptr + 2 * n))
2187
                return -TARGET_EFAULT;
2188

    
2189
            ret = do_accept(sockfd, target_addr, target_addrlen);
2190
        }
2191
        break;
2192
    case SOCKOP_getsockname:
2193
        {
2194
            abi_ulong sockfd;
2195
            abi_ulong target_addr, target_addrlen;
2196

    
2197
            if (get_user_ual(sockfd, vptr)
2198
                || get_user_ual(target_addr, vptr + n)
2199
                || get_user_ual(target_addrlen, vptr + 2 * n))
2200
                return -TARGET_EFAULT;
2201

    
2202
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
2203
        }
2204
        break;
2205
    case SOCKOP_getpeername:
2206
        {
2207
            abi_ulong sockfd;
2208
            abi_ulong target_addr, target_addrlen;
2209

    
2210
            if (get_user_ual(sockfd, vptr)
2211
                || get_user_ual(target_addr, vptr + n)
2212
                || get_user_ual(target_addrlen, vptr + 2 * n))
2213
                return -TARGET_EFAULT;
2214

    
2215
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
2216
        }
2217
        break;
2218
    case SOCKOP_socketpair:
2219
        {
2220
            abi_ulong domain, type, protocol;
2221
            abi_ulong tab;
2222

    
2223
            if (get_user_ual(domain, vptr)
2224
                || get_user_ual(type, vptr + n)
2225
                || get_user_ual(protocol, vptr + 2 * n)
2226
                || get_user_ual(tab, vptr + 3 * n))
2227
                return -TARGET_EFAULT;
2228

    
2229
            ret = do_socketpair(domain, type, protocol, tab);
2230
        }
2231
        break;
2232
    case SOCKOP_send:
2233
        {
2234
            abi_ulong sockfd;
2235
            abi_ulong msg;
2236
            size_t len;
2237
            abi_ulong flags;
2238

    
2239
            if (get_user_ual(sockfd, vptr)
2240
                || get_user_ual(msg, vptr + n)
2241
                || get_user_ual(len, vptr + 2 * n)
2242
                || get_user_ual(flags, vptr + 3 * n))
2243
                return -TARGET_EFAULT;
2244

    
2245
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
2246
        }
2247
        break;
2248
    case SOCKOP_recv:
2249
        {
2250
            abi_ulong sockfd;
2251
            abi_ulong msg;
2252
            size_t len;
2253
            abi_ulong flags;
2254

    
2255
            if (get_user_ual(sockfd, vptr)
2256
                || get_user_ual(msg, vptr + n)
2257
                || get_user_ual(len, vptr + 2 * n)
2258
                || get_user_ual(flags, vptr + 3 * n))
2259
                return -TARGET_EFAULT;
2260

    
2261
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
2262
        }
2263
        break;
2264
    case SOCKOP_sendto:
2265
        {
2266
            abi_ulong sockfd;
2267
            abi_ulong msg;
2268
            size_t len;
2269
            abi_ulong flags;
2270
            abi_ulong addr;
2271
            socklen_t addrlen;
2272

    
2273
            if (get_user_ual(sockfd, vptr)
2274
                || get_user_ual(msg, vptr + n)
2275
                || get_user_ual(len, vptr + 2 * n)
2276
                || get_user_ual(flags, vptr + 3 * n)
2277
                || get_user_ual(addr, vptr + 4 * n)
2278
                || get_user_ual(addrlen, vptr + 5 * n))
2279
                return -TARGET_EFAULT;
2280

    
2281
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
2282
        }
2283
        break;
2284
    case SOCKOP_recvfrom:
2285
        {
2286
            abi_ulong sockfd;
2287
            abi_ulong msg;
2288
            size_t len;
2289
            abi_ulong flags;
2290
            abi_ulong addr;
2291
            socklen_t addrlen;
2292

    
2293
            if (get_user_ual(sockfd, vptr)
2294
                || get_user_ual(msg, vptr + n)
2295
                || get_user_ual(len, vptr + 2 * n)
2296
                || get_user_ual(flags, vptr + 3 * n)
2297
                || get_user_ual(addr, vptr + 4 * n)
2298
                || get_user_ual(addrlen, vptr + 5 * n))
2299
                return -TARGET_EFAULT;
2300

    
2301
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
2302
        }
2303
        break;
2304
    case SOCKOP_shutdown:
2305
        {
2306
            abi_ulong sockfd, how;
2307

    
2308
            if (get_user_ual(sockfd, vptr)
2309
                || get_user_ual(how, vptr + n))
2310
                return -TARGET_EFAULT;
2311

    
2312
            ret = get_errno(shutdown(sockfd, how));
2313
        }
2314
        break;
2315
    case SOCKOP_sendmsg:
2316
    case SOCKOP_recvmsg:
2317
        {
2318
            abi_ulong fd;
2319
            abi_ulong target_msg;
2320
            abi_ulong flags;
2321

    
2322
            if (get_user_ual(fd, vptr)
2323
                || get_user_ual(target_msg, vptr + n)
2324
                || get_user_ual(flags, vptr + 2 * n))
2325
                return -TARGET_EFAULT;
2326

    
2327
            ret = do_sendrecvmsg(fd, target_msg, flags,
2328
                                 (num == SOCKOP_sendmsg));
2329
        }
2330
        break;
2331
    case SOCKOP_setsockopt:
2332
        {
2333
            abi_ulong sockfd;
2334
            abi_ulong level;
2335
            abi_ulong optname;
2336
            abi_ulong optval;
2337
            socklen_t optlen;
2338

    
2339
            if (get_user_ual(sockfd, vptr)
2340
                || get_user_ual(level, vptr + n)
2341
                || get_user_ual(optname, vptr + 2 * n)
2342
                || get_user_ual(optval, vptr + 3 * n)
2343
                || get_user_ual(optlen, vptr + 4 * n))
2344
                return -TARGET_EFAULT;
2345

    
2346
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2347
        }
2348
        break;
2349
    case SOCKOP_getsockopt:
2350
        {
2351
            abi_ulong sockfd;
2352
            abi_ulong level;
2353
            abi_ulong optname;
2354
            abi_ulong optval;
2355
            socklen_t optlen;
2356

    
2357
            if (get_user_ual(sockfd, vptr)
2358
                || get_user_ual(level, vptr + n)
2359
                || get_user_ual(optname, vptr + 2 * n)
2360
                || get_user_ual(optval, vptr + 3 * n)
2361
                || get_user_ual(optlen, vptr + 4 * n))
2362
                return -TARGET_EFAULT;
2363

    
2364
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2365
        }
2366
        break;
2367
    default:
2368
        gemu_log("Unsupported socketcall: %d\n", num);
2369
        ret = -TARGET_ENOSYS;
2370
        break;
2371
    }
2372
    return ret;
2373
}
2374
#endif
2375

    
2376
#define N_SHM_REGIONS        32
2377

    
2378
static struct shm_region {
2379
    abi_ulong        start;
2380
    abi_ulong        size;
2381
} shm_regions[N_SHM_REGIONS];
2382

    
2383
struct target_ipc_perm
2384
{
2385
    abi_long __key;
2386
    abi_ulong uid;
2387
    abi_ulong gid;
2388
    abi_ulong cuid;
2389
    abi_ulong cgid;
2390
    unsigned short int mode;
2391
    unsigned short int __pad1;
2392
    unsigned short int __seq;
2393
    unsigned short int __pad2;
2394
    abi_ulong __unused1;
2395
    abi_ulong __unused2;
2396
};
2397

    
2398
struct target_semid_ds
2399
{
2400
  struct target_ipc_perm sem_perm;
2401
  abi_ulong sem_otime;
2402
  abi_ulong __unused1;
2403
  abi_ulong sem_ctime;
2404
  abi_ulong __unused2;
2405
  abi_ulong sem_nsems;
2406
  abi_ulong __unused3;
2407
  abi_ulong __unused4;
2408
};
2409

    
2410
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2411
                                               abi_ulong target_addr)
2412
{
2413
    struct target_ipc_perm *target_ip;
2414
    struct target_semid_ds *target_sd;
2415

    
2416
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2417
        return -TARGET_EFAULT;
2418
    target_ip = &(target_sd->sem_perm);
2419
    host_ip->__key = tswapal(target_ip->__key);
2420
    host_ip->uid = tswapal(target_ip->uid);
2421
    host_ip->gid = tswapal(target_ip->gid);
2422
    host_ip->cuid = tswapal(target_ip->cuid);
2423
    host_ip->cgid = tswapal(target_ip->cgid);
2424
    host_ip->mode = tswap16(target_ip->mode);
2425
    unlock_user_struct(target_sd, target_addr, 0);
2426
    return 0;
2427
}
2428

    
2429
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2430
                                               struct ipc_perm *host_ip)
2431
{
2432
    struct target_ipc_perm *target_ip;
2433
    struct target_semid_ds *target_sd;
2434

    
2435
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2436
        return -TARGET_EFAULT;
2437
    target_ip = &(target_sd->sem_perm);
2438
    target_ip->__key = tswapal(host_ip->__key);
2439
    target_ip->uid = tswapal(host_ip->uid);
2440
    target_ip->gid = tswapal(host_ip->gid);
2441
    target_ip->cuid = tswapal(host_ip->cuid);
2442
    target_ip->cgid = tswapal(host_ip->cgid);
2443
    target_ip->mode = tswap16(host_ip->mode);
2444
    unlock_user_struct(target_sd, target_addr, 1);
2445
    return 0;
2446
}
2447

    
2448
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2449
                                               abi_ulong target_addr)
2450
{
2451
    struct target_semid_ds *target_sd;
2452

    
2453
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2454
        return -TARGET_EFAULT;
2455
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2456
        return -TARGET_EFAULT;
2457
    host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
2458
    host_sd->sem_otime = tswapal(target_sd->sem_otime);
2459
    host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
2460
    unlock_user_struct(target_sd, target_addr, 0);
2461
    return 0;
2462
}
2463

    
2464
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2465
                                               struct semid_ds *host_sd)
2466
{
2467
    struct target_semid_ds *target_sd;
2468

    
2469
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2470
        return -TARGET_EFAULT;
2471
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2472
        return -TARGET_EFAULT;
2473
    target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
2474
    target_sd->sem_otime = tswapal(host_sd->sem_otime);
2475
    target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
2476
    unlock_user_struct(target_sd, target_addr, 1);
2477
    return 0;
2478
}
2479

    
2480
struct target_seminfo {
2481
    int semmap;
2482
    int semmni;
2483
    int semmns;
2484
    int semmnu;
2485
    int semmsl;
2486
    int semopm;
2487
    int semume;
2488
    int semusz;
2489
    int semvmx;
2490
    int semaem;
2491
};
2492

    
2493
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2494
                                              struct seminfo *host_seminfo)
2495
{
2496
    struct target_seminfo *target_seminfo;
2497
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2498
        return -TARGET_EFAULT;
2499
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2500
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2501
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2502
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2503
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2504
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2505
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2506
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2507
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2508
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2509
    unlock_user_struct(target_seminfo, target_addr, 1);
2510
    return 0;
2511
}
2512

    
2513
union semun {
2514
        int val;
2515
        struct semid_ds *buf;
2516
        unsigned short *array;
2517
        struct seminfo *__buf;
2518
};
2519

    
2520
union target_semun {
2521
        int val;
2522
        abi_ulong buf;
2523
        abi_ulong array;
2524
        abi_ulong __buf;
2525
};
2526

    
2527
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2528
                                               abi_ulong target_addr)
2529
{
2530
    int nsems;
2531
    unsigned short *array;
2532
    union semun semun;
2533
    struct semid_ds semid_ds;
2534
    int i, ret;
2535

    
2536
    semun.buf = &semid_ds;
2537

    
2538
    ret = semctl(semid, 0, IPC_STAT, semun);
2539
    if (ret == -1)
2540
        return get_errno(ret);
2541

    
2542
    nsems = semid_ds.sem_nsems;
2543

    
2544
    *host_array = malloc(nsems*sizeof(unsigned short));
2545
    array = lock_user(VERIFY_READ, target_addr,
2546
                      nsems*sizeof(unsigned short), 1);
2547
    if (!array)
2548
        return -TARGET_EFAULT;
2549

    
2550
    for(i=0; i<nsems; i++) {
2551
        __get_user((*host_array)[i], &array[i]);
2552
    }
2553
    unlock_user(array, target_addr, 0);
2554

    
2555
    return 0;
2556
}
2557

    
2558
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2559
                                               unsigned short **host_array)
2560
{
2561
    int nsems;
2562
    unsigned short *array;
2563
    union semun semun;
2564
    struct semid_ds semid_ds;
2565
    int i, ret;
2566

    
2567
    semun.buf = &semid_ds;
2568

    
2569
    ret = semctl(semid, 0, IPC_STAT, semun);
2570
    if (ret == -1)
2571
        return get_errno(ret);
2572

    
2573
    nsems = semid_ds.sem_nsems;
2574

    
2575
    array = lock_user(VERIFY_WRITE, target_addr,
2576
                      nsems*sizeof(unsigned short), 0);
2577
    if (!array)
2578
        return -TARGET_EFAULT;
2579

    
2580
    for(i=0; i<nsems; i++) {
2581
        __put_user((*host_array)[i], &array[i]);
2582
    }
2583
    free(*host_array);
2584
    unlock_user(array, target_addr, 1);
2585

    
2586
    return 0;
2587
}
2588

    
2589
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2590
                                 union target_semun target_su)
2591
{
2592
    union semun arg;
2593
    struct semid_ds dsarg;
2594
    unsigned short *array = NULL;
2595
    struct seminfo seminfo;
2596
    abi_long ret = -TARGET_EINVAL;
2597
    abi_long err;
2598
    cmd &= 0xff;
2599

    
2600
    switch( cmd ) {
2601
        case GETVAL:
2602
        case SETVAL:
2603
            arg.val = tswap32(target_su.val);
2604
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2605
            target_su.val = tswap32(arg.val);
2606
            break;
2607
        case GETALL:
2608
        case SETALL:
2609
            err = target_to_host_semarray(semid, &array, target_su.array);
2610
            if (err)
2611
                return err;
2612
            arg.array = array;
2613
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2614
            err = host_to_target_semarray(semid, target_su.array, &array);
2615
            if (err)
2616
                return err;
2617
            break;
2618
        case IPC_STAT:
2619
        case IPC_SET:
2620
        case SEM_STAT:
2621
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2622
            if (err)
2623
                return err;
2624
            arg.buf = &dsarg;
2625
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2626
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2627
            if (err)
2628
                return err;
2629
            break;
2630
        case IPC_INFO:
2631
        case SEM_INFO:
2632
            arg.__buf = &seminfo;
2633
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2634
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2635
            if (err)
2636
                return err;
2637
            break;
2638
        case IPC_RMID:
2639
        case GETPID:
2640
        case GETNCNT:
2641
        case GETZCNT:
2642
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2643
            break;
2644
    }
2645

    
2646
    return ret;
2647
}
2648

    
2649
struct target_sembuf {
2650
    unsigned short sem_num;
2651
    short sem_op;
2652
    short sem_flg;
2653
};
2654

    
2655
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2656
                                             abi_ulong target_addr,
2657
                                             unsigned nsops)
2658
{
2659
    struct target_sembuf *target_sembuf;
2660
    int i;
2661

    
2662
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2663
                              nsops*sizeof(struct target_sembuf), 1);
2664
    if (!target_sembuf)
2665
        return -TARGET_EFAULT;
2666

    
2667
    for(i=0; i<nsops; i++) {
2668
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2669
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2670
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2671
    }
2672

    
2673
    unlock_user(target_sembuf, target_addr, 0);
2674

    
2675
    return 0;
2676
}
2677

    
2678
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2679
{
2680
    struct sembuf sops[nsops];
2681

    
2682
    if (target_to_host_sembuf(sops, ptr, nsops))
2683
        return -TARGET_EFAULT;
2684

    
2685
    return semop(semid, sops, nsops);
2686
}
2687

    
2688
struct target_msqid_ds
2689
{
2690
    struct target_ipc_perm msg_perm;
2691
    abi_ulong msg_stime;
2692
#if TARGET_ABI_BITS == 32
2693
    abi_ulong __unused1;
2694
#endif
2695
    abi_ulong msg_rtime;
2696
#if TARGET_ABI_BITS == 32
2697
    abi_ulong __unused2;
2698
#endif
2699
    abi_ulong msg_ctime;
2700
#if TARGET_ABI_BITS == 32
2701
    abi_ulong __unused3;
2702
#endif
2703
    abi_ulong __msg_cbytes;
2704
    abi_ulong msg_qnum;
2705
    abi_ulong msg_qbytes;
2706
    abi_ulong msg_lspid;
2707
    abi_ulong msg_lrpid;
2708
    abi_ulong __unused4;
2709
    abi_ulong __unused5;
2710
};
2711

    
2712
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2713
                                               abi_ulong target_addr)
2714
{
2715
    struct target_msqid_ds *target_md;
2716

    
2717
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2718
        return -TARGET_EFAULT;
2719
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2720
        return -TARGET_EFAULT;
2721
    host_md->msg_stime = tswapal(target_md->msg_stime);
2722
    host_md->msg_rtime = tswapal(target_md->msg_rtime);
2723
    host_md->msg_ctime = tswapal(target_md->msg_ctime);
2724
    host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
2725
    host_md->msg_qnum = tswapal(target_md->msg_qnum);
2726
    host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
2727
    host_md->msg_lspid = tswapal(target_md->msg_lspid);
2728
    host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
2729
    unlock_user_struct(target_md, target_addr, 0);
2730
    return 0;
2731
}
2732

    
2733
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2734
                                               struct msqid_ds *host_md)
2735
{
2736
    struct target_msqid_ds *target_md;
2737

    
2738
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2739
        return -TARGET_EFAULT;
2740
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2741
        return -TARGET_EFAULT;
2742
    target_md->msg_stime = tswapal(host_md->msg_stime);
2743
    target_md->msg_rtime = tswapal(host_md->msg_rtime);
2744
    target_md->msg_ctime = tswapal(host_md->msg_ctime);
2745
    target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
2746
    target_md->msg_qnum = tswapal(host_md->msg_qnum);
2747
    target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
2748
    target_md->msg_lspid = tswapal(host_md->msg_lspid);
2749
    target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
2750
    unlock_user_struct(target_md, target_addr, 1);
2751
    return 0;
2752
}
2753

    
2754
struct target_msginfo {
2755
    int msgpool;
2756
    int msgmap;
2757
    int msgmax;
2758
    int msgmnb;
2759
    int msgmni;
2760
    int msgssz;
2761
    int msgtql;
2762
    unsigned short int msgseg;
2763
};
2764

    
2765
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2766
                                              struct msginfo *host_msginfo)
2767
{
2768
    struct target_msginfo *target_msginfo;
2769
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2770
        return -TARGET_EFAULT;
2771
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2772
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2773
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2774
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2775
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2776
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2777
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2778
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2779
    unlock_user_struct(target_msginfo, target_addr, 1);
2780
    return 0;
2781
}
2782

    
2783
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2784
{
2785
    struct msqid_ds dsarg;
2786
    struct msginfo msginfo;
2787
    abi_long ret = -TARGET_EINVAL;
2788

    
2789
    cmd &= 0xff;
2790

    
2791
    switch (cmd) {
2792
    case IPC_STAT:
2793
    case IPC_SET:
2794
    case MSG_STAT:
2795
        if (target_to_host_msqid_ds(&dsarg,ptr))
2796
            return -TARGET_EFAULT;
2797
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2798
        if (host_to_target_msqid_ds(ptr,&dsarg))
2799
            return -TARGET_EFAULT;
2800
        break;
2801
    case IPC_RMID:
2802
        ret = get_errno(msgctl(msgid, cmd, NULL));
2803
        break;
2804
    case IPC_INFO:
2805
    case MSG_INFO:
2806
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2807
        if (host_to_target_msginfo(ptr, &msginfo))
2808
            return -TARGET_EFAULT;
2809
        break;
2810
    }
2811

    
2812
    return ret;
2813
}
2814

    
2815
struct target_msgbuf {
2816
    abi_long mtype;
2817
    char        mtext[1];
2818
};
2819

    
2820
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2821
                                 unsigned int msgsz, int msgflg)
2822
{
2823
    struct target_msgbuf *target_mb;
2824
    struct msgbuf *host_mb;
2825
    abi_long ret = 0;
2826

    
2827
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2828
        return -TARGET_EFAULT;
2829
    host_mb = malloc(msgsz+sizeof(long));
2830
    host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
2831
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2832
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2833
    free(host_mb);
2834
    unlock_user_struct(target_mb, msgp, 0);
2835

    
2836
    return ret;
2837
}
2838

    
2839
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2840
                                 unsigned int msgsz, abi_long msgtyp,
2841
                                 int msgflg)
2842
{
2843
    struct target_msgbuf *target_mb;
2844
    char *target_mtext;
2845
    struct msgbuf *host_mb;
2846
    abi_long ret = 0;
2847

    
2848
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2849
        return -TARGET_EFAULT;
2850

    
2851
    host_mb = g_malloc(msgsz+sizeof(long));
2852
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapal(msgtyp), msgflg));
2853

    
2854
    if (ret > 0) {
2855
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2856
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2857
        if (!target_mtext) {
2858
            ret = -TARGET_EFAULT;
2859
            goto end;
2860
        }
2861
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2862
        unlock_user(target_mtext, target_mtext_addr, ret);
2863
    }
2864

    
2865
    target_mb->mtype = tswapal(host_mb->mtype);
2866

    
2867
end:
2868
    if (target_mb)
2869
        unlock_user_struct(target_mb, msgp, 1);
2870
    g_free(host_mb);
2871
    return ret;
2872
}
2873

    
2874
struct target_shmid_ds
2875
{
2876
    struct target_ipc_perm shm_perm;
2877
    abi_ulong shm_segsz;
2878
    abi_ulong shm_atime;
2879
#if TARGET_ABI_BITS == 32
2880
    abi_ulong __unused1;
2881
#endif
2882
    abi_ulong shm_dtime;
2883
#if TARGET_ABI_BITS == 32
2884
    abi_ulong __unused2;
2885
#endif
2886
    abi_ulong shm_ctime;
2887
#if TARGET_ABI_BITS == 32
2888
    abi_ulong __unused3;
2889
#endif
2890
    int shm_cpid;
2891
    int shm_lpid;
2892
    abi_ulong shm_nattch;
2893
    unsigned long int __unused4;
2894
    unsigned long int __unused5;
2895
};
2896

    
2897
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2898
                                               abi_ulong target_addr)
2899
{
2900
    struct target_shmid_ds *target_sd;
2901

    
2902
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2903
        return -TARGET_EFAULT;
2904
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2905
        return -TARGET_EFAULT;
2906
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2907
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2908
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2909
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2910
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2911
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2912
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2913
    unlock_user_struct(target_sd, target_addr, 0);
2914
    return 0;
2915
}
2916

    
2917
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2918
                                               struct shmid_ds *host_sd)
2919
{
2920
    struct target_shmid_ds *target_sd;
2921

    
2922
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2923
        return -TARGET_EFAULT;
2924
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2925
        return -TARGET_EFAULT;
2926
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2927
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2928
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2929
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2930
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2931
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2932
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2933
    unlock_user_struct(target_sd, target_addr, 1);
2934
    return 0;
2935
}
2936

    
2937
struct  target_shminfo {
2938
    abi_ulong shmmax;
2939
    abi_ulong shmmin;
2940
    abi_ulong shmmni;
2941
    abi_ulong shmseg;
2942
    abi_ulong shmall;
2943
};
2944

    
2945
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2946
                                              struct shminfo *host_shminfo)
2947
{
2948
    struct target_shminfo *target_shminfo;
2949
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2950
        return -TARGET_EFAULT;
2951
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2952
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2953
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2954
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2955
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2956
    unlock_user_struct(target_shminfo, target_addr, 1);
2957
    return 0;
2958
}
2959

    
2960
struct target_shm_info {
2961
    int used_ids;
2962
    abi_ulong shm_tot;
2963
    abi_ulong shm_rss;
2964
    abi_ulong shm_swp;
2965
    abi_ulong swap_attempts;
2966
    abi_ulong swap_successes;
2967
};
2968

    
2969
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2970
                                               struct shm_info *host_shm_info)
2971
{
2972
    struct target_shm_info *target_shm_info;
2973
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2974
        return -TARGET_EFAULT;
2975
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2976
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2977
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2978
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2979
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2980
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2981
    unlock_user_struct(target_shm_info, target_addr, 1);
2982
    return 0;
2983
}
2984

    
2985
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2986
{
2987
    struct shmid_ds dsarg;
2988
    struct shminfo shminfo;
2989
    struct shm_info shm_info;
2990
    abi_long ret = -TARGET_EINVAL;
2991

    
2992
    cmd &= 0xff;
2993

    
2994
    switch(cmd) {
2995
    case IPC_STAT:
2996
    case IPC_SET:
2997
    case SHM_STAT:
2998
        if (target_to_host_shmid_ds(&dsarg, buf))
2999
            return -TARGET_EFAULT;
3000
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
3001
        if (host_to_target_shmid_ds(buf, &dsarg))
3002
            return -TARGET_EFAULT;
3003
        break;
3004
    case IPC_INFO:
3005
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
3006
        if (host_to_target_shminfo(buf, &shminfo))
3007
            return -TARGET_EFAULT;
3008
        break;
3009
    case SHM_INFO:
3010
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
3011
        if (host_to_target_shm_info(buf, &shm_info))
3012
            return -TARGET_EFAULT;
3013
        break;
3014
    case IPC_RMID:
3015
    case SHM_LOCK:
3016
    case SHM_UNLOCK:
3017
        ret = get_errno(shmctl(shmid, cmd, NULL));
3018
        break;
3019
    }
3020

    
3021
    return ret;
3022
}
3023

    
3024
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
3025
{
3026
    abi_long raddr;
3027
    void *host_raddr;
3028
    struct shmid_ds shm_info;
3029
    int i,ret;
3030

    
3031
    /* find out the length of the shared memory segment */
3032
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
3033
    if (is_error(ret)) {
3034
        /* can't get length, bail out */
3035
        return ret;
3036
    }
3037

    
3038
    mmap_lock();
3039

    
3040
    if (shmaddr)
3041
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
3042
    else {
3043
        abi_ulong mmap_start;
3044

    
3045
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
3046

    
3047
        if (mmap_start == -1) {
3048
            errno = ENOMEM;
3049
            host_raddr = (void *)-1;
3050
        } else
3051
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
3052
    }
3053

    
3054
    if (host_raddr == (void *)-1) {
3055
        mmap_unlock();
3056
        return get_errno((long)host_raddr);
3057
    }
3058
    raddr=h2g((unsigned long)host_raddr);
3059

    
3060
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
3061
                   PAGE_VALID | PAGE_READ |
3062
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
3063

    
3064
    for (i = 0; i < N_SHM_REGIONS; i++) {
3065
        if (shm_regions[i].start == 0) {
3066
            shm_regions[i].start = raddr;
3067
            shm_regions[i].size = shm_info.shm_segsz;
3068
            break;
3069
        }
3070
    }
3071

    
3072
    mmap_unlock();
3073
    return raddr;
3074

    
3075
}
3076

    
3077
static inline abi_long do_shmdt(abi_ulong shmaddr)
3078
{
3079
    int i;
3080

    
3081
    for (i = 0; i < N_SHM_REGIONS; ++i) {
3082
        if (shm_regions[i].start == shmaddr) {
3083
            shm_regions[i].start = 0;
3084
            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
3085
            break;
3086
        }
3087
    }
3088

    
3089
    return get_errno(shmdt(g2h(shmaddr)));
3090
}
3091

    
3092
#ifdef TARGET_NR_ipc
3093
/* ??? This only works with linear mappings.  */
3094
/* do_ipc() must return target values and target errnos. */
3095
static abi_long do_ipc(unsigned int call, int first,
3096
                       int second, int third,
3097
                       abi_long ptr, abi_long fifth)
3098
{
3099
    int version;
3100
    abi_long ret = 0;
3101

    
3102
    version = call >> 16;
3103
    call &= 0xffff;
3104

    
3105
    switch (call) {
3106
    case IPCOP_semop:
3107
        ret = do_semop(first, ptr, second);
3108
        break;
3109

    
3110
    case IPCOP_semget:
3111
        ret = get_errno(semget(first, second, third));
3112
        break;
3113

    
3114
    case IPCOP_semctl:
3115
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
3116
        break;
3117

    
3118
    case IPCOP_msgget:
3119
        ret = get_errno(msgget(first, second));
3120
        break;
3121

    
3122
    case IPCOP_msgsnd:
3123
        ret = do_msgsnd(first, ptr, second, third);
3124
        break;
3125

    
3126
    case IPCOP_msgctl:
3127
        ret = do_msgctl(first, second, ptr);
3128
        break;
3129

    
3130
    case IPCOP_msgrcv:
3131
        switch (version) {
3132
        case 0:
3133
            {
3134
                struct target_ipc_kludge {
3135
                    abi_long msgp;
3136
                    abi_long msgtyp;
3137
                } *tmp;
3138

    
3139
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
3140
                    ret = -TARGET_EFAULT;
3141
                    break;
3142
                }
3143

    
3144
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
3145

    
3146
                unlock_user_struct(tmp, ptr, 0);
3147
                break;
3148
            }
3149
        default:
3150
            ret = do_msgrcv(first, ptr, second, fifth, third);
3151
        }
3152
        break;
3153

    
3154
    case IPCOP_shmat:
3155
        switch (version) {
3156
        default:
3157
        {
3158
            abi_ulong raddr;
3159
            raddr = do_shmat(first, ptr, second);
3160
            if (is_error(raddr))
3161
                return get_errno(raddr);
3162
            if (put_user_ual(raddr, third))
3163
                return -TARGET_EFAULT;
3164
            break;
3165
        }
3166
        case 1:
3167
            ret = -TARGET_EINVAL;
3168
            break;
3169
        }
3170
        break;
3171
    case IPCOP_shmdt:
3172
        ret = do_shmdt(ptr);
3173
        break;
3174

    
3175
    case IPCOP_shmget:
3176
        /* IPC_* flag values are the same on all linux platforms */
3177
        ret = get_errno(shmget(first, second, third));
3178
        break;
3179

    
3180
        /* IPC_* and SHM_* command values are the same on all linux platforms */
3181
    case IPCOP_shmctl:
3182
        ret = do_shmctl(first, second, third);
3183
        break;
3184
    default:
3185
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3186
        ret = -TARGET_ENOSYS;
3187
        break;
3188
    }
3189
    return ret;
3190
}
3191
#endif
3192

    
3193
/* kernel structure types definitions */
3194

    
3195
#define STRUCT(name, ...) STRUCT_ ## name,
3196
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
3197
enum {
3198
#include "syscall_types.h"
3199
};
3200
#undef STRUCT
3201
#undef STRUCT_SPECIAL
3202

    
3203
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
3204
#define STRUCT_SPECIAL(name)
3205
#include "syscall_types.h"
3206
#undef STRUCT
3207
#undef STRUCT_SPECIAL
3208

    
3209
typedef struct IOCTLEntry IOCTLEntry;
3210

    
3211
typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3212
                             int fd, abi_long cmd, abi_long arg);
3213

    
3214
struct IOCTLEntry {
3215
    unsigned int target_cmd;
3216
    unsigned int host_cmd;
3217
    const char *name;
3218
    int access;
3219
    do_ioctl_fn *do_ioctl;
3220
    const argtype arg_type[5];
3221
};
3222

    
3223
#define IOC_R 0x0001
3224
#define IOC_W 0x0002
3225
#define IOC_RW (IOC_R | IOC_W)
3226

    
3227
#define MAX_STRUCT_SIZE 4096
3228

    
3229
#ifdef CONFIG_FIEMAP
3230
/* So fiemap access checks don't overflow on 32 bit systems.
3231
 * This is very slightly smaller than the limit imposed by
3232
 * the underlying kernel.
3233
 */
3234
#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
3235
                            / sizeof(struct fiemap_extent))
3236

    
3237
static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3238
                                       int fd, abi_long cmd, abi_long arg)
3239
{
3240
    /* The parameter for this ioctl is a struct fiemap followed
3241
     * by an array of struct fiemap_extent whose size is set
3242
     * in fiemap->fm_extent_count. The array is filled in by the
3243
     * ioctl.
3244
     */
3245
    int target_size_in, target_size_out;
3246
    struct fiemap *fm;
3247
    const argtype *arg_type = ie->arg_type;
3248
    const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3249
    void *argptr, *p;
3250
    abi_long ret;
3251
    int i, extent_size = thunk_type_size(extent_arg_type, 0);
3252
    uint32_t outbufsz;
3253
    int free_fm = 0;
3254

    
3255
    assert(arg_type[0] == TYPE_PTR);
3256
    assert(ie->access == IOC_RW);
3257
    arg_type++;
3258
    target_size_in = thunk_type_size(arg_type, 0);
3259
    argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3260
    if (!argptr) {
3261
        return -TARGET_EFAULT;
3262
    }
3263
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3264
    unlock_user(argptr, arg, 0);
3265
    fm = (struct fiemap *)buf_temp;
3266
    if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3267
        return -TARGET_EINVAL;
3268
    }
3269

    
3270
    outbufsz = sizeof (*fm) +
3271
        (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3272

    
3273
    if (outbufsz > MAX_STRUCT_SIZE) {
3274
        /* We can't fit all the extents into the fixed size buffer.
3275
         * Allocate one that is large enough and use it instead.
3276
         */
3277
        fm = malloc(outbufsz);
3278
        if (!fm) {
3279
            return -TARGET_ENOMEM;
3280
        }
3281
        memcpy(fm, buf_temp, sizeof(struct fiemap));
3282
        free_fm = 1;
3283
    }
3284
    ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3285
    if (!is_error(ret)) {
3286
        target_size_out = target_size_in;
3287
        /* An extent_count of 0 means we were only counting the extents
3288
         * so there are no structs to copy
3289
         */
3290
        if (fm->fm_extent_count != 0) {
3291
            target_size_out += fm->fm_mapped_extents * extent_size;
3292
        }
3293
        argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3294
        if (!argptr) {
3295
            ret = -TARGET_EFAULT;
3296
        } else {
3297
            /* Convert the struct fiemap */
3298
            thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3299
            if (fm->fm_extent_count != 0) {
3300
                p = argptr + target_size_in;
3301
                /* ...and then all the struct fiemap_extents */
3302
                for (i = 0; i < fm->fm_mapped_extents; i++) {
3303
                    thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3304
                                  THUNK_TARGET);
3305
                    p += extent_size;
3306
                }
3307
            }
3308
            unlock_user(argptr, arg, target_size_out);
3309
        }
3310
    }
3311
    if (free_fm) {
3312
        free(fm);
3313
    }
3314
    return ret;
3315
}
3316
#endif
3317

    
3318
static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3319
                                int fd, abi_long cmd, abi_long arg)
3320
{
3321
    const argtype *arg_type = ie->arg_type;
3322
    int target_size;
3323
    void *argptr;
3324
    int ret;
3325
    struct ifconf *host_ifconf;
3326
    uint32_t outbufsz;
3327
    const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3328
    int target_ifreq_size;
3329
    int nb_ifreq;
3330
    int free_buf = 0;
3331
    int i;
3332
    int target_ifc_len;
3333
    abi_long target_ifc_buf;
3334
    int host_ifc_len;
3335
    char *host_ifc_buf;
3336

    
3337
    assert(arg_type[0] == TYPE_PTR);
3338
    assert(ie->access == IOC_RW);
3339

    
3340
    arg_type++;
3341
    target_size = thunk_type_size(arg_type, 0);
3342

    
3343
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3344
    if (!argptr)
3345
        return -TARGET_EFAULT;
3346
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3347
    unlock_user(argptr, arg, 0);
3348

    
3349
    host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3350
    target_ifc_len = host_ifconf->ifc_len;
3351
    target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3352

    
3353
    target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3354
    nb_ifreq = target_ifc_len / target_ifreq_size;
3355
    host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3356

    
3357
    outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3358
    if (outbufsz > MAX_STRUCT_SIZE) {
3359
        /* We can't fit all the extents into the fixed size buffer.
3360
         * Allocate one that is large enough and use it instead.
3361
         */
3362
        host_ifconf = malloc(outbufsz);
3363
        if (!host_ifconf) {
3364
            return -TARGET_ENOMEM;
3365
        }
3366
        memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3367
        free_buf = 1;
3368
    }
3369
    host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3370

    
3371
    host_ifconf->ifc_len = host_ifc_len;
3372
    host_ifconf->ifc_buf = host_ifc_buf;
3373

    
3374
    ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3375
    if (!is_error(ret)) {
3376
        /* convert host ifc_len to target ifc_len */
3377

    
3378
        nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3379
        target_ifc_len = nb_ifreq * target_ifreq_size;
3380
        host_ifconf->ifc_len = target_ifc_len;
3381

    
3382
        /* restore target ifc_buf */
3383

    
3384
        host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3385

    
3386
        /* copy struct ifconf to target user */
3387

    
3388
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3389
        if (!argptr)
3390
            return -TARGET_EFAULT;
3391
        thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3392
        unlock_user(argptr, arg, target_size);
3393

    
3394
        /* copy ifreq[] to target user */
3395

    
3396
        argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3397
        for (i = 0; i < nb_ifreq ; i++) {
3398
            thunk_convert(argptr + i * target_ifreq_size,
3399
                          host_ifc_buf + i * sizeof(struct ifreq),
3400
                          ifreq_arg_type, THUNK_TARGET);
3401
        }
3402
        unlock_user(argptr, target_ifc_buf, target_ifc_len);
3403
    }
3404

    
3405
    if (free_buf) {
3406
        free(host_ifconf);
3407
    }
3408

    
3409
    return ret;
3410
}
3411

    
3412
static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
3413
                            abi_long cmd, abi_long arg)
3414
{
3415
    void *argptr;
3416
    struct dm_ioctl *host_dm;
3417
    abi_long guest_data;
3418
    uint32_t guest_data_size;
3419
    int target_size;
3420
    const argtype *arg_type = ie->arg_type;
3421
    abi_long ret;
3422
    void *big_buf = NULL;
3423
    char *host_data;
3424

    
3425
    arg_type++;
3426
    target_size = thunk_type_size(arg_type, 0);
3427
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3428
    if (!argptr) {
3429
        ret = -TARGET_EFAULT;
3430
        goto out;
3431
    }
3432
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3433
    unlock_user(argptr, arg, 0);
3434

    
3435
    /* buf_temp is too small, so fetch things into a bigger buffer */
3436
    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
3437
    memcpy(big_buf, buf_temp, target_size);
3438
    buf_temp = big_buf;
3439
    host_dm = big_buf;
3440

    
3441
    guest_data = arg + host_dm->data_start;
3442
    if ((guest_data - arg) < 0) {
3443
        ret = -EINVAL;
3444
        goto out;
3445
    }
3446
    guest_data_size = host_dm->data_size - host_dm->data_start;
3447
    host_data = (char*)host_dm + host_dm->data_start;
3448

    
3449
    argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
3450
    switch (ie->host_cmd) {
3451
    case DM_REMOVE_ALL:
3452
    case DM_LIST_DEVICES:
3453
    case DM_DEV_CREATE:
3454
    case DM_DEV_REMOVE:
3455
    case DM_DEV_SUSPEND:
3456
    case DM_DEV_STATUS:
3457
    case DM_DEV_WAIT:
3458
    case DM_TABLE_STATUS:
3459
    case DM_TABLE_CLEAR:
3460
    case DM_TABLE_DEPS:
3461
    case DM_LIST_VERSIONS:
3462
        /* no input data */
3463
        break;
3464
    case DM_DEV_RENAME:
3465
    case DM_DEV_SET_GEOMETRY:
3466
        /* data contains only strings */
3467
        memcpy(host_data, argptr, guest_data_size);
3468
        break;
3469
    case DM_TARGET_MSG:
3470
        memcpy(host_data, argptr, guest_data_size);
3471
        *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
3472
        break;
3473
    case DM_TABLE_LOAD:
3474
    {
3475
        void *gspec = argptr;
3476
        void *cur_data = host_data;
3477
        const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3478
        int spec_size = thunk_type_size(arg_type, 0);
3479
        int i;
3480

    
3481
        for (i = 0; i < host_dm->target_count; i++) {
3482
            struct dm_target_spec *spec = cur_data;
3483
            uint32_t next;
3484
            int slen;
3485

    
3486
            thunk_convert(spec, gspec, arg_type, THUNK_HOST);
3487
            slen = strlen((char*)gspec + spec_size) + 1;
3488
            next = spec->next;
3489
            spec->next = sizeof(*spec) + slen;
3490
            strcpy((char*)&spec[1], gspec + spec_size);
3491
            gspec += next;
3492
            cur_data += spec->next;
3493
        }
3494
        break;
3495
    }
3496
    default:
3497
        ret = -TARGET_EINVAL;
3498
        goto out;
3499
    }
3500
    unlock_user(argptr, guest_data, 0);
3501

    
3502
    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3503
    if (!is_error(ret)) {
3504
        guest_data = arg + host_dm->data_start;
3505
        guest_data_size = host_dm->data_size - host_dm->data_start;
3506
        argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
3507
        switch (ie->host_cmd) {
3508
        case DM_REMOVE_ALL:
3509
        case DM_DEV_CREATE:
3510
        case DM_DEV_REMOVE:
3511
        case DM_DEV_RENAME:
3512
        case DM_DEV_SUSPEND:
3513
        case DM_DEV_STATUS:
3514
        case DM_TABLE_LOAD:
3515
        case DM_TABLE_CLEAR:
3516
        case DM_TARGET_MSG:
3517
        case DM_DEV_SET_GEOMETRY:
3518
            /* no return data */
3519
            break;
3520
        case DM_LIST_DEVICES:
3521
        {
3522
            struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
3523
            uint32_t remaining_data = guest_data_size;
3524
            void *cur_data = argptr;
3525
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
3526
            int nl_size = 12; /* can't use thunk_size due to alignment */
3527

    
3528
            while (1) {
3529
                uint32_t next = nl->next;
3530
                if (next) {
3531
                    nl->next = nl_size + (strlen(nl->name) + 1);
3532
                }
3533
                if (remaining_data < nl->next) {
3534
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3535
                    break;
3536
                }
3537
                thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
3538
                strcpy(cur_data + nl_size, nl->name);
3539
                cur_data += nl->next;
3540
                remaining_data -= nl->next;
3541
                if (!next) {
3542
                    break;
3543
                }
3544
                nl = (void*)nl + next;
3545
            }
3546
            break;
3547
        }
3548
        case DM_DEV_WAIT:
3549
        case DM_TABLE_STATUS:
3550
        {
3551
            struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
3552
            void *cur_data = argptr;
3553
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3554
            int spec_size = thunk_type_size(arg_type, 0);
3555
            int i;
3556

    
3557
            for (i = 0; i < host_dm->target_count; i++) {
3558
                uint32_t next = spec->next;
3559
                int slen = strlen((char*)&spec[1]) + 1;
3560
                spec->next = (cur_data - argptr) + spec_size + slen;
3561
                if (guest_data_size < spec->next) {
3562
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3563
                    break;
3564
                }
3565
                thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
3566
                strcpy(cur_data + spec_size, (char*)&spec[1]);
3567
                cur_data = argptr + spec->next;
3568
                spec = (void*)host_dm + host_dm->data_start + next;
3569
            }
3570
            break;
3571
        }
3572
        case DM_TABLE_DEPS:
3573
        {
3574
            void *hdata = (void*)host_dm + host_dm->data_start;
3575
            int count = *(uint32_t*)hdata;
3576
            uint64_t *hdev = hdata + 8;
3577
            uint64_t *gdev = argptr + 8;
3578
            int i;
3579

    
3580
            *(uint32_t*)argptr = tswap32(count);
3581
            for (i = 0; i < count; i++) {
3582
                *gdev = tswap64(*hdev);
3583
                gdev++;
3584
                hdev++;
3585
            }
3586
            break;
3587
        }
3588
        case DM_LIST_VERSIONS:
3589
        {
3590
            struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
3591
            uint32_t remaining_data = guest_data_size;
3592
            void *cur_data = argptr;
3593
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
3594
            int vers_size = thunk_type_size(arg_type, 0);
3595

    
3596
            while (1) {
3597
                uint32_t next = vers->next;
3598
                if (next) {
3599
                    vers->next = vers_size + (strlen(vers->name) + 1);
3600
                }
3601
                if (remaining_data < vers->next) {
3602
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
3603
                    break;
3604
                }
3605
                thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
3606
                strcpy(cur_data + vers_size, vers->name);
3607
                cur_data += vers->next;
3608
                remaining_data -= vers->next;
3609
                if (!next) {
3610
                    break;
3611
                }
3612
                vers = (void*)vers + next;
3613
            }
3614
            break;
3615
        }
3616
        default:
3617
            ret = -TARGET_EINVAL;
3618
            goto out;
3619
        }
3620
        unlock_user(argptr, guest_data, guest_data_size);
3621

    
3622
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3623
        if (!argptr) {
3624
            ret = -TARGET_EFAULT;
3625
            goto out;
3626
        }
3627
        thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3628
        unlock_user(argptr, arg, target_size);
3629
    }
3630
out:
3631
    if (big_buf) {
3632
        free(big_buf);
3633
    }
3634
    return ret;
3635
}
3636

    
3637
static IOCTLEntry ioctl_entries[] = {
3638
#define IOCTL(cmd, access, ...) \
3639
    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
3640
#define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
3641
    { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
3642
#include "ioctls.h"
3643
    { 0, 0, },
3644
};
3645

    
3646
/* ??? Implement proper locking for ioctls.  */
3647
/* do_ioctl() Must return target values and target errnos. */
3648
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3649
{
3650
    const IOCTLEntry *ie;
3651
    const argtype *arg_type;
3652
    abi_long ret;
3653
    uint8_t buf_temp[MAX_STRUCT_SIZE];
3654
    int target_size;
3655
    void *argptr;
3656

    
3657
    ie = ioctl_entries;
3658
    for(;;) {
3659
        if (ie->target_cmd == 0) {
3660
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3661
            return -TARGET_ENOSYS;
3662
        }
3663
        if (ie->target_cmd == cmd)
3664
            break;
3665
        ie++;
3666
    }
3667
    arg_type = ie->arg_type;
3668
#if defined(DEBUG)
3669
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3670
#endif
3671
    if (ie->do_ioctl) {
3672
        return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3673
    }
3674

    
3675
    switch(arg_type[0]) {
3676
    case TYPE_NULL:
3677
        /* no argument */
3678
        ret = get_errno(ioctl(fd, ie->host_cmd));
3679
        break;
3680
    case TYPE_PTRVOID:
3681
    case TYPE_INT:
3682
        /* int argment */
3683
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3684
        break;
3685
    case TYPE_PTR:
3686
        arg_type++;
3687
        target_size = thunk_type_size(arg_type, 0);
3688
        switch(ie->access) {
3689
        case IOC_R:
3690
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3691
            if (!is_error(ret)) {
3692
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3693
                if (!argptr)
3694
                    return -TARGET_EFAULT;
3695
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3696
                unlock_user(argptr, arg, target_size);
3697
            }
3698
            break;
3699
        case IOC_W:
3700
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3701
            if (!argptr)
3702
                return -TARGET_EFAULT;
3703
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3704
            unlock_user(argptr, arg, 0);
3705
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3706
            break;
3707
        default:
3708
        case IOC_RW:
3709
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3710
            if (!argptr)
3711
                return -TARGET_EFAULT;
3712
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3713
            unlock_user(argptr, arg, 0);
3714
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3715
            if (!is_error(ret)) {
3716
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3717
                if (!argptr)
3718
                    return -TARGET_EFAULT;
3719
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3720
                unlock_user(argptr, arg, target_size);
3721
            }
3722
            break;
3723
        }
3724
        break;
3725
    default:
3726
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3727
                 (long)cmd, arg_type[0]);
3728
        ret = -TARGET_ENOSYS;
3729
        break;
3730
    }
3731
    return ret;
3732
}
3733

    
3734
static const bitmask_transtbl iflag_tbl[] = {
3735
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3736
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3737
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3738
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3739
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3740
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3741
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3742
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3743
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3744
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3745
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
3746
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3747
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3748
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3749
        { 0, 0, 0, 0 }
3750
};
3751

    
3752
static const bitmask_transtbl oflag_tbl[] = {
3753
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3754
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3755
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3756
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3757
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3758
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3759
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3760
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3761
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3762
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3763
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3764
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3765
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3766
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3767
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3768
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3769
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3770
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3771
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3772
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3773
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3774
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3775
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3776
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3777
        { 0, 0, 0, 0 }
3778
};
3779

    
3780
static const bitmask_transtbl cflag_tbl[] = {
3781
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3782
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3783
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3784
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3785
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3786
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3787
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3788
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3789
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3790
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3791
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3792
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3793
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3794
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3795
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3796
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3797
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3798
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3799
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3800
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3801
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3802
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3803
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3804
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3805
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3806
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3807
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3808
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3809
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3810
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3811
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3812
        { 0, 0, 0, 0 }
3813
};
3814

    
3815
static const bitmask_transtbl lflag_tbl[] = {
3816
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3817
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3818
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3819
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3820
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3821
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3822
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3823
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3824
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3825
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3826
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3827
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3828
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3829
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3830
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3831
        { 0, 0, 0, 0 }
3832
};
3833

    
3834
static void target_to_host_termios (void *dst, const void *src)
3835
{
3836
    struct host_termios *host = dst;
3837
    const struct target_termios *target = src;
3838

    
3839
    host->c_iflag =
3840
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3841
    host->c_oflag =
3842
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3843
    host->c_cflag =
3844
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3845
    host->c_lflag =
3846
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3847
    host->c_line = target->c_line;
3848

    
3849
    memset(host->c_cc, 0, sizeof(host->c_cc));
3850
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3851
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3852
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3853
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3854
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3855
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3856
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3857
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3858
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3859
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3860
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3861
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3862
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3863
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3864
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3865
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3866
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3867
}
3868

    
3869
static void host_to_target_termios (void *dst, const void *src)
3870
{
3871
    struct target_termios *target = dst;
3872
    const struct host_termios *host = src;
3873

    
3874
    target->c_iflag =
3875
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3876
    target->c_oflag =
3877
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3878
    target->c_cflag =
3879
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3880
    target->c_lflag =
3881
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3882
    target->c_line = host->c_line;
3883

    
3884
    memset(target->c_cc, 0, sizeof(target->c_cc));
3885
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3886
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3887
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3888
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3889
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3890
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3891
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3892
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3893
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3894
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3895
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3896
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3897
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3898
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3899
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3900
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3901
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3902
}
3903

    
3904
static const StructEntry struct_termios_def = {
3905
    .convert = { host_to_target_termios, target_to_host_termios },
3906
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3907
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3908
};
3909

    
3910
static bitmask_transtbl mmap_flags_tbl[] = {
3911
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3912
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3913
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3914
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3915
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3916
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3917
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3918
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3919
        { 0, 0, 0, 0 }
3920
};
3921

    
3922
#if defined(TARGET_I386)
3923

    
3924
/* NOTE: there is really one LDT for all the threads */
3925
static uint8_t *ldt_table;
3926

    
3927
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3928
{
3929
    int size;
3930
    void *p;
3931

    
3932
    if (!ldt_table)
3933
        return 0;
3934
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3935
    if (size > bytecount)
3936
        size = bytecount;
3937
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3938
    if (!p)
3939
        return -TARGET_EFAULT;
3940
    /* ??? Should this by byteswapped?  */
3941
    memcpy(p, ldt_table, size);
3942
    unlock_user(p, ptr, size);
3943
    return size;
3944
}
3945

    
3946
/* XXX: add locking support */
3947
static abi_long write_ldt(CPUX86State *env,
3948
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3949
{
3950
    struct target_modify_ldt_ldt_s ldt_info;
3951
    struct target_modify_ldt_ldt_s *target_ldt_info;
3952
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3953
    int seg_not_present, useable, lm;
3954
    uint32_t *lp, entry_1, entry_2;
3955

    
3956
    if (bytecount != sizeof(ldt_info))
3957
        return -TARGET_EINVAL;
3958
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3959
        return -TARGET_EFAULT;
3960
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3961
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
3962
    ldt_info.limit = tswap32(target_ldt_info->limit);
3963
    ldt_info.flags = tswap32(target_ldt_info->flags);
3964
    unlock_user_struct(target_ldt_info, ptr, 0);
3965

    
3966
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3967
        return -TARGET_EINVAL;
3968
    seg_32bit = ldt_info.flags & 1;
3969
    contents = (ldt_info.flags >> 1) & 3;
3970
    read_exec_only = (ldt_info.flags >> 3) & 1;
3971
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3972
    seg_not_present = (ldt_info.flags >> 5) & 1;
3973
    useable = (ldt_info.flags >> 6) & 1;
3974
#ifdef TARGET_ABI32
3975
    lm = 0;
3976
#else
3977
    lm = (ldt_info.flags >> 7) & 1;
3978
#endif
3979
    if (contents == 3) {
3980
        if (oldmode)
3981
            return -TARGET_EINVAL;
3982
        if (seg_not_present == 0)
3983
            return -TARGET_EINVAL;
3984
    }
3985
    /* allocate the LDT */
3986
    if (!ldt_table) {
3987
        env->ldt.base = target_mmap(0,
3988
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3989
                                    PROT_READ|PROT_WRITE,
3990
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3991
        if (env->ldt.base == -1)
3992
            return -TARGET_ENOMEM;
3993
        memset(g2h(env->ldt.base), 0,
3994
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3995
        env->ldt.limit = 0xffff;
3996
        ldt_table = g2h(env->ldt.base);
3997
    }
3998

    
3999
    /* NOTE: same code as Linux kernel */
4000
    /* Allow LDTs to be cleared by the user. */
4001
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4002
        if (oldmode ||
4003
            (contents == 0                &&
4004
             read_exec_only == 1        &&
4005
             seg_32bit == 0                &&
4006
             limit_in_pages == 0        &&
4007
             seg_not_present == 1        &&
4008
             useable == 0 )) {
4009
            entry_1 = 0;
4010
            entry_2 = 0;
4011
            goto install;
4012
        }
4013
    }
4014

    
4015
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4016
        (ldt_info.limit & 0x0ffff);
4017
    entry_2 = (ldt_info.base_addr & 0xff000000) |
4018
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4019
        (ldt_info.limit & 0xf0000) |
4020
        ((read_exec_only ^ 1) << 9) |
4021
        (contents << 10) |
4022
        ((seg_not_present ^ 1) << 15) |
4023
        (seg_32bit << 22) |
4024
        (limit_in_pages << 23) |
4025
        (lm << 21) |
4026
        0x7000;
4027
    if (!oldmode)
4028
        entry_2 |= (useable << 20);
4029

    
4030
    /* Install the new entry ...  */
4031
install:
4032
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
4033
    lp[0] = tswap32(entry_1);
4034
    lp[1] = tswap32(entry_2);
4035
    return 0;
4036
}
4037

    
4038
/* specific and weird i386 syscalls */
4039
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
4040
                              unsigned long bytecount)
4041
{
4042
    abi_long ret;
4043

    
4044
    switch (func) {
4045
    case 0:
4046
        ret = read_ldt(ptr, bytecount);
4047
        break;
4048
    case 1:
4049
        ret = write_ldt(env, ptr, bytecount, 1);
4050
        break;
4051
    case 0x11:
4052
        ret = write_ldt(env, ptr, bytecount, 0);
4053
        break;
4054
    default:
4055
        ret = -TARGET_ENOSYS;
4056
        break;
4057
    }
4058
    return ret;
4059
}
4060

    
4061
#if defined(TARGET_I386) && defined(TARGET_ABI32)
4062
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
4063
{
4064
    uint64_t *gdt_table = g2h(env->gdt.base);
4065
    struct target_modify_ldt_ldt_s ldt_info;
4066
    struct target_modify_ldt_ldt_s *target_ldt_info;
4067
    int seg_32bit, contents, read_exec_only, limit_in_pages;
4068
    int seg_not_present, useable, lm;
4069
    uint32_t *lp, entry_1, entry_2;
4070
    int i;
4071

    
4072
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4073
    if (!target_ldt_info)
4074
        return -TARGET_EFAULT;
4075
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4076
    ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4077
    ldt_info.limit = tswap32(target_ldt_info->limit);
4078
    ldt_info.flags = tswap32(target_ldt_info->flags);
4079
    if (ldt_info.entry_number == -1) {
4080
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
4081
            if (gdt_table[i] == 0) {
4082
                ldt_info.entry_number = i;
4083
                target_ldt_info->entry_number = tswap32(i);
4084
                break;
4085
            }
4086
        }
4087
    }
4088
    unlock_user_struct(target_ldt_info, ptr, 1);
4089

    
4090
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
4091
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
4092
           return -TARGET_EINVAL;
4093
    seg_32bit = ldt_info.flags & 1;
4094
    contents = (ldt_info.flags >> 1) & 3;
4095
    read_exec_only = (ldt_info.flags >> 3) & 1;
4096
    limit_in_pages = (ldt_info.flags >> 4) & 1;
4097
    seg_not_present = (ldt_info.flags >> 5) & 1;
4098
    useable = (ldt_info.flags >> 6) & 1;
4099
#ifdef TARGET_ABI32
4100
    lm = 0;
4101
#else
4102
    lm = (ldt_info.flags >> 7) & 1;
4103
#endif
4104

    
4105
    if (contents == 3) {
4106
        if (seg_not_present == 0)
4107
            return -TARGET_EINVAL;
4108
    }
4109

    
4110
    /* NOTE: same code as Linux kernel */
4111
    /* Allow LDTs to be cleared by the user. */
4112
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4113
        if ((contents == 0             &&
4114
             read_exec_only == 1       &&
4115
             seg_32bit == 0            &&
4116
             limit_in_pages == 0       &&
4117
             seg_not_present == 1      &&
4118
             useable == 0 )) {
4119
            entry_1 = 0;
4120
            entry_2 = 0;
4121
            goto install;
4122
        }
4123
    }
4124

    
4125
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4126
        (ldt_info.limit & 0x0ffff);
4127
    entry_2 = (ldt_info.base_addr & 0xff000000) |
4128
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4129
        (ldt_info.limit & 0xf0000) |
4130
        ((read_exec_only ^ 1) << 9) |
4131
        (contents << 10) |
4132
        ((seg_not_present ^ 1) << 15) |
4133
        (seg_32bit << 22) |
4134
        (limit_in_pages << 23) |
4135
        (useable << 20) |
4136
        (lm << 21) |
4137
        0x7000;
4138

    
4139
    /* Install the new entry ...  */
4140
install:
4141
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
4142
    lp[0] = tswap32(entry_1);
4143
    lp[1] = tswap32(entry_2);
4144
    return 0;
4145
}
4146

    
4147
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
4148
{
4149
    struct target_modify_ldt_ldt_s *target_ldt_info;
4150
    uint64_t *gdt_table = g2h(env->gdt.base);
4151
    uint32_t base_addr, limit, flags;
4152
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
4153
    int seg_not_present, useable, lm;
4154
    uint32_t *lp, entry_1, entry_2;
4155

    
4156
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4157
    if (!target_ldt_info)
4158
        return -TARGET_EFAULT;
4159
    idx = tswap32(target_ldt_info->entry_number);
4160
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
4161
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
4162
        unlock_user_struct(target_ldt_info, ptr, 1);
4163
        return -TARGET_EINVAL;
4164
    }
4165
    lp = (uint32_t *)(gdt_table + idx);
4166
    entry_1 = tswap32(lp[0]);
4167
    entry_2 = tswap32(lp[1]);
4168
    
4169
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
4170
    contents = (entry_2 >> 10) & 3;
4171
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
4172
    seg_32bit = (entry_2 >> 22) & 1;
4173
    limit_in_pages = (entry_2 >> 23) & 1;
4174
    useable = (entry_2 >> 20) & 1;
4175
#ifdef TARGET_ABI32
4176
    lm = 0;
4177
#else
4178
    lm = (entry_2 >> 21) & 1;
4179
#endif
4180
    flags = (seg_32bit << 0) | (contents << 1) |
4181
        (read_exec_only << 3) | (limit_in_pages << 4) |
4182
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
4183
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
4184
    base_addr = (entry_1 >> 16) | 
4185
        (entry_2 & 0xff000000) | 
4186
        ((entry_2 & 0xff) << 16);
4187
    target_ldt_info->base_addr = tswapal(base_addr);
4188
    target_ldt_info->limit = tswap32(limit);
4189
    target_ldt_info->flags = tswap32(flags);
4190
    unlock_user_struct(target_ldt_info, ptr, 1);
4191
    return 0;
4192
}
4193
#endif /* TARGET_I386 && TARGET_ABI32 */
4194

    
4195
#ifndef TARGET_ABI32
4196
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
4197
{
4198
    abi_long ret = 0;
4199
    abi_ulong val;
4200
    int idx;
4201

    
4202
    switch(code) {
4203
    case TARGET_ARCH_SET_GS:
4204
    case TARGET_ARCH_SET_FS:
4205
        if (code == TARGET_ARCH_SET_GS)
4206
            idx = R_GS;
4207
        else
4208
            idx = R_FS;
4209
        cpu_x86_load_seg(env, idx, 0);
4210
        env->segs[idx].base = addr;
4211
        break;
4212
    case TARGET_ARCH_GET_GS:
4213
    case TARGET_ARCH_GET_FS:
4214
        if (code == TARGET_ARCH_GET_GS)
4215
            idx = R_GS;
4216
        else
4217
            idx = R_FS;
4218
        val = env->segs[idx].base;
4219
        if (put_user(val, addr, abi_ulong))
4220
            ret = -TARGET_EFAULT;
4221
        break;
4222
    default:
4223
        ret = -TARGET_EINVAL;
4224
        break;
4225
    }
4226
    return ret;
4227
}
4228
#endif
4229

    
4230
#endif /* defined(TARGET_I386) */
4231

    
4232
#define NEW_STACK_SIZE 0x40000
4233

    
4234
#if defined(CONFIG_USE_NPTL)
4235

    
4236
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
4237
typedef struct {
4238
    CPUArchState *env;
4239
    pthread_mutex_t mutex;
4240
    pthread_cond_t cond;
4241
    pthread_t thread;
4242
    uint32_t tid;
4243
    abi_ulong child_tidptr;
4244
    abi_ulong parent_tidptr;
4245
    sigset_t sigmask;
4246
} new_thread_info;
4247

    
4248
static void *clone_func(void *arg)
4249
{
4250
    new_thread_info *info = arg;
4251
    CPUArchState *env;
4252
    TaskState *ts;
4253

    
4254
    env = info->env;
4255
    thread_env = env;
4256
    ts = (TaskState *)thread_env->opaque;
4257
    info->tid = gettid();
4258
    env->host_tid = info->tid;
4259
    task_settid(ts);
4260
    if (info->child_tidptr)
4261
        put_user_u32(info->tid, info->child_tidptr);
4262
    if (info->parent_tidptr)
4263
        put_user_u32(info->tid, info->parent_tidptr);
4264
    /* Enable signals.  */
4265
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
4266
    /* Signal to the parent that we're ready.  */
4267
    pthread_mutex_lock(&info->mutex);
4268
    pthread_cond_broadcast(&info->cond);
4269
    pthread_mutex_unlock(&info->mutex);
4270
    /* Wait until the parent has finshed initializing the tls state.  */
4271
    pthread_mutex_lock(&clone_lock);
4272
    pthread_mutex_unlock(&clone_lock);
4273
    cpu_loop(env);
4274
    /* never exits */
4275
    return NULL;
4276
}
4277
#else
4278

    
4279
static int clone_func(void *arg)
4280
{
4281
    CPUArchState *env = arg;
4282
    cpu_loop(env);
4283
    /* never exits */
4284
    return 0;
4285
}
4286
#endif
4287

    
4288
/* do_fork() Must return host values and target errnos (unlike most
4289
   do_*() functions). */
4290
static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
4291
                   abi_ulong parent_tidptr, target_ulong newtls,
4292
                   abi_ulong child_tidptr)
4293
{
4294
    int ret;
4295
    TaskState *ts;
4296
    CPUArchState *new_env;
4297
#if defined(CONFIG_USE_NPTL)
4298
    unsigned int nptl_flags;
4299
    sigset_t sigmask;
4300
#else
4301
    uint8_t *new_stack;
4302
#endif
4303

    
4304
    /* Emulate vfork() with fork() */
4305
    if (flags & CLONE_VFORK)
4306
        flags &= ~(CLONE_VFORK | CLONE_VM);
4307

    
4308
    if (flags & CLONE_VM) {
4309
        TaskState *parent_ts = (TaskState *)env->opaque;
4310
#if defined(CONFIG_USE_NPTL)
4311
        new_thread_info info;
4312
        pthread_attr_t attr;
4313
#endif
4314
        ts = g_malloc0(sizeof(TaskState));
4315
        init_task_state(ts);
4316
        /* we create a new CPU instance. */
4317
        new_env = cpu_copy(env);
4318
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
4319
        cpu_reset(ENV_GET_CPU(new_env));
4320
#endif
4321
        /* Init regs that differ from the parent.  */
4322
        cpu_clone_regs(new_env, newsp);
4323
        new_env->opaque = ts;
4324
        ts->bprm = parent_ts->bprm;
4325
        ts->info = parent_ts->info;
4326
#if defined(CONFIG_USE_NPTL)
4327
        nptl_flags = flags;
4328
        flags &= ~CLONE_NPTL_FLAGS2;
4329

    
4330
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
4331
            ts->child_tidptr = child_tidptr;
4332
        }
4333

    
4334
        if (nptl_flags & CLONE_SETTLS)
4335
            cpu_set_tls (new_env, newtls);
4336

    
4337
        /* Grab a mutex so that thread setup appears atomic.  */
4338
        pthread_mutex_lock(&clone_lock);
4339

    
4340
        memset(&info, 0, sizeof(info));
4341
        pthread_mutex_init(&info.mutex, NULL);
4342
        pthread_mutex_lock(&info.mutex);
4343
        pthread_cond_init(&info.cond, NULL);
4344
        info.env = new_env;
4345
        if (nptl_flags & CLONE_CHILD_SETTID)
4346
            info.child_tidptr = child_tidptr;
4347
        if (nptl_flags & CLONE_PARENT_SETTID)
4348
            info.parent_tidptr = parent_tidptr;
4349

    
4350
        ret = pthread_attr_init(&attr);
4351
        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
4352
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4353
        /* It is not safe to deliver signals until the child has finished
4354
           initializing, so temporarily block all signals.  */
4355
        sigfillset(&sigmask);
4356
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
4357

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

    
4361
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
4362
        pthread_attr_destroy(&attr);
4363
        if (ret == 0) {
4364
            /* Wait for the child to initialize.  */
4365
            pthread_cond_wait(&info.cond, &info.mutex);
4366
            ret = info.tid;
4367
            if (flags & CLONE_PARENT_SETTID)
4368
                put_user_u32(ret, parent_tidptr);
4369
        } else {
4370
            ret = -1;
4371
        }
4372
        pthread_mutex_unlock(&info.mutex);
4373
        pthread_cond_destroy(&info.cond);
4374
        pthread_mutex_destroy(&info.mutex);
4375
        pthread_mutex_unlock(&clone_lock);
4376
#else
4377
        if (flags & CLONE_NPTL_FLAGS2)
4378
            return -EINVAL;
4379
        /* This is probably going to die very quickly, but do it anyway.  */
4380
        new_stack = g_malloc0 (NEW_STACK_SIZE);
4381
#ifdef __ia64__
4382
        ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
4383
#else
4384
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
4385
#endif
4386
#endif
4387
    } else {
4388
        /* if no CLONE_VM, we consider it is a fork */
4389
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
4390
            return -EINVAL;
4391
        fork_start();
4392
        ret = fork();
4393
        if (ret == 0) {
4394
            /* Child Process.  */
4395
            cpu_clone_regs(env, newsp);
4396
            fork_end(1);
4397
#if defined(CONFIG_USE_NPTL)
4398
            /* There is a race condition here.  The parent process could
4399
               theoretically read the TID in the child process before the child
4400
               tid is set.  This would require using either ptrace
4401
               (not implemented) or having *_tidptr to point at a shared memory
4402
               mapping.  We can't repeat the spinlock hack used above because
4403
               the child process gets its own copy of the lock.  */
4404
            if (flags & CLONE_CHILD_SETTID)
4405
                put_user_u32(gettid(), child_tidptr);
4406
            if (flags & CLONE_PARENT_SETTID)
4407
                put_user_u32(gettid(), parent_tidptr);
4408
            ts = (TaskState *)env->opaque;
4409
            if (flags & CLONE_SETTLS)
4410
                cpu_set_tls (env, newtls);
4411
            if (flags & CLONE_CHILD_CLEARTID)
4412
                ts->child_tidptr = child_tidptr;
4413
#endif
4414
        } else {
4415
            fork_end(0);
4416
        }
4417
    }
4418
    return ret;
4419
}
4420

    
4421
/* warning : doesn't handle linux specific flags... */
4422
static int target_to_host_fcntl_cmd(int cmd)
4423
{
4424
    switch(cmd) {
4425
        case TARGET_F_DUPFD:
4426
        case TARGET_F_GETFD:
4427
        case TARGET_F_SETFD:
4428
        case TARGET_F_GETFL:
4429
        case TARGET_F_SETFL:
4430
            return cmd;
4431
        case TARGET_F_GETLK:
4432
            return F_GETLK;
4433
        case TARGET_F_SETLK:
4434
            return F_SETLK;
4435
        case TARGET_F_SETLKW:
4436
            return F_SETLKW;
4437
        case TARGET_F_GETOWN:
4438
            return F_GETOWN;
4439
        case TARGET_F_SETOWN:
4440
            return F_SETOWN;
4441
        case TARGET_F_GETSIG:
4442
            return F_GETSIG;
4443
        case TARGET_F_SETSIG:
4444
            return F_SETSIG;
4445
#if TARGET_ABI_BITS == 32
4446
        case TARGET_F_GETLK64:
4447
            return F_GETLK64;
4448
        case TARGET_F_SETLK64:
4449
            return F_SETLK64;
4450
        case TARGET_F_SETLKW64:
4451
            return F_SETLKW64;
4452
#endif
4453
        case TARGET_F_SETLEASE:
4454
            return F_SETLEASE;
4455
        case TARGET_F_GETLEASE:
4456
            return F_GETLEASE;
4457
#ifdef F_DUPFD_CLOEXEC
4458
        case TARGET_F_DUPFD_CLOEXEC:
4459
            return F_DUPFD_CLOEXEC;
4460
#endif
4461
        case TARGET_F_NOTIFY:
4462
            return F_NOTIFY;
4463
        default:
4464
            return -TARGET_EINVAL;
4465
    }
4466
    return -TARGET_EINVAL;
4467
}
4468

    
4469
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4470
{
4471
    struct flock fl;
4472
    struct target_flock *target_fl;
4473
    struct flock64 fl64;
4474
    struct target_flock64 *target_fl64;
4475
    abi_long ret;
4476
    int host_cmd = target_to_host_fcntl_cmd(cmd);
4477

    
4478
    if (host_cmd == -TARGET_EINVAL)
4479
            return host_cmd;
4480

    
4481
    switch(cmd) {
4482
    case TARGET_F_GETLK:
4483
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4484
            return -TARGET_EFAULT;
4485
        fl.l_type = tswap16(target_fl->l_type);
4486
        fl.l_whence = tswap16(target_fl->l_whence);
4487
        fl.l_start = tswapal(target_fl->l_start);
4488
        fl.l_len = tswapal(target_fl->l_len);
4489
        fl.l_pid = tswap32(target_fl->l_pid);
4490
        unlock_user_struct(target_fl, arg, 0);
4491
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4492
        if (ret == 0) {
4493
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4494
                return -TARGET_EFAULT;
4495
            target_fl->l_type = tswap16(fl.l_type);
4496
            target_fl->l_whence = tswap16(fl.l_whence);
4497
            target_fl->l_start = tswapal(fl.l_start);
4498
            target_fl->l_len = tswapal(fl.l_len);
4499
            target_fl->l_pid = tswap32(fl.l_pid);
4500
            unlock_user_struct(target_fl, arg, 1);
4501
        }
4502
        break;
4503

    
4504
    case TARGET_F_SETLK:
4505
    case TARGET_F_SETLKW:
4506
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4507
            return -TARGET_EFAULT;
4508
        fl.l_type = tswap16(target_fl->l_type);
4509
        fl.l_whence = tswap16(target_fl->l_whence);
4510
        fl.l_start = tswapal(target_fl->l_start);
4511
        fl.l_len = tswapal(target_fl->l_len);
4512
        fl.l_pid = tswap32(target_fl->l_pid);
4513
        unlock_user_struct(target_fl, arg, 0);
4514
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4515
        break;
4516

    
4517
    case TARGET_F_GETLK64:
4518
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4519
            return -TARGET_EFAULT;
4520
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4521
        fl64.l_whence = tswap16(target_fl64->l_whence);
4522
        fl64.l_start = tswap64(target_fl64->l_start);
4523
        fl64.l_len = tswap64(target_fl64->l_len);
4524
        fl64.l_pid = tswap32(target_fl64->l_pid);
4525
        unlock_user_struct(target_fl64, arg, 0);
4526
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4527
        if (ret == 0) {
4528
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4529
                return -TARGET_EFAULT;
4530
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
4531
            target_fl64->l_whence = tswap16(fl64.l_whence);
4532
            target_fl64->l_start = tswap64(fl64.l_start);
4533
            target_fl64->l_len = tswap64(fl64.l_len);
4534
            target_fl64->l_pid = tswap32(fl64.l_pid);
4535
            unlock_user_struct(target_fl64, arg, 1);
4536
        }
4537
        break;
4538
    case TARGET_F_SETLK64:
4539
    case TARGET_F_SETLKW64:
4540
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4541
            return -TARGET_EFAULT;
4542
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4543
        fl64.l_whence = tswap16(target_fl64->l_whence);
4544
        fl64.l_start = tswap64(target_fl64->l_start);
4545
        fl64.l_len = tswap64(target_fl64->l_len);
4546
        fl64.l_pid = tswap32(target_fl64->l_pid);
4547
        unlock_user_struct(target_fl64, arg, 0);
4548
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4549
        break;
4550

    
4551
    case TARGET_F_GETFL:
4552
        ret = get_errno(fcntl(fd, host_cmd, arg));
4553
        if (ret >= 0) {
4554
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4555
        }
4556
        break;
4557

    
4558
    case TARGET_F_SETFL:
4559
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4560
        break;
4561

    
4562
    case TARGET_F_SETOWN:
4563
    case TARGET_F_GETOWN:
4564
    case TARGET_F_SETSIG:
4565
    case TARGET_F_GETSIG:
4566
    case TARGET_F_SETLEASE:
4567
    case TARGET_F_GETLEASE:
4568
        ret = get_errno(fcntl(fd, host_cmd, arg));
4569
        break;
4570

    
4571
    default:
4572
        ret = get_errno(fcntl(fd, cmd, arg));
4573
        break;
4574
    }
4575
    return ret;
4576
}
4577

    
4578
#ifdef USE_UID16
4579

    
4580
static inline int high2lowuid(int uid)
4581
{
4582
    if (uid > 65535)
4583
        return 65534;
4584
    else
4585
        return uid;
4586
}
4587

    
4588
static inline int high2lowgid(int gid)
4589
{
4590
    if (gid > 65535)
4591
        return 65534;
4592
    else
4593
        return gid;
4594
}
4595

    
4596
static inline int low2highuid(int uid)
4597
{
4598
    if ((int16_t)uid == -1)
4599
        return -1;
4600
    else
4601
        return uid;
4602
}
4603

    
4604
static inline int low2highgid(int gid)
4605
{
4606
    if ((int16_t)gid == -1)
4607
        return -1;
4608
    else
4609
        return gid;
4610
}
4611
static inline int tswapid(int id)
4612
{
4613
    return tswap16(id);
4614
}
4615
#else /* !USE_UID16 */
4616
static inline int high2lowuid(int uid)
4617
{
4618
    return uid;
4619
}
4620
static inline int high2lowgid(int gid)
4621
{
4622
    return gid;
4623
}
4624
static inline int low2highuid(int uid)
4625
{
4626
    return uid;
4627
}
4628
static inline int low2highgid(int gid)
4629
{
4630
    return gid;
4631
}
4632
static inline int tswapid(int id)
4633
{
4634
    return tswap32(id);
4635
}
4636
#endif /* USE_UID16 */
4637

    
4638
void syscall_init(void)
4639
{
4640
    IOCTLEntry *ie;
4641
    const argtype *arg_type;
4642
    int size;
4643
    int i;
4644

    
4645
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4646
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4647
#include "syscall_types.h"
4648
#undef STRUCT
4649
#undef STRUCT_SPECIAL
4650

    
4651
    /* Build target_to_host_errno_table[] table from
4652
     * host_to_target_errno_table[]. */
4653
    for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
4654
        target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4655
    }
4656

    
4657
    /* we patch the ioctl size if necessary. We rely on the fact that
4658
       no ioctl has all the bits at '1' in the size field */
4659
    ie = ioctl_entries;
4660
    while (ie->target_cmd != 0) {
4661
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4662
            TARGET_IOC_SIZEMASK) {
4663
            arg_type = ie->arg_type;
4664
            if (arg_type[0] != TYPE_PTR) {
4665
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4666
                        ie->target_cmd);
4667
                exit(1);
4668
            }
4669
            arg_type++;
4670
            size = thunk_type_size(arg_type, 0);
4671
            ie->target_cmd = (ie->target_cmd &
4672
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4673
                (size << TARGET_IOC_SIZESHIFT);
4674
        }
4675

    
4676
        /* automatic consistency check if same arch */
4677
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4678
    (defined(__x86_64__) && defined(TARGET_X86_64))
4679
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
4680
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4681
                    ie->name, ie->target_cmd, ie->host_cmd);
4682
        }
4683
#endif
4684
        ie++;
4685
    }
4686
}
4687

    
4688
#if TARGET_ABI_BITS == 32
4689
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4690
{
4691
#ifdef TARGET_WORDS_BIGENDIAN
4692
    return ((uint64_t)word0 << 32) | word1;
4693
#else
4694
    return ((uint64_t)word1 << 32) | word0;
4695
#endif
4696
}
4697
#else /* TARGET_ABI_BITS == 32 */
4698
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4699
{
4700
    return word0;
4701
}
4702
#endif /* TARGET_ABI_BITS != 32 */
4703

    
4704
#ifdef TARGET_NR_truncate64
4705
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4706
                                         abi_long arg2,
4707
                                         abi_long arg3,
4708
                                         abi_long arg4)
4709
{
4710
    if (regpairs_aligned(cpu_env)) {
4711
        arg2 = arg3;
4712
        arg3 = arg4;
4713
    }
4714
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4715
}
4716
#endif
4717

    
4718
#ifdef TARGET_NR_ftruncate64
4719
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4720
                                          abi_long arg2,
4721
                                          abi_long arg3,
4722
                                          abi_long arg4)
4723
{
4724
    if (regpairs_aligned(cpu_env)) {
4725
        arg2 = arg3;
4726
        arg3 = arg4;
4727
    }
4728
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4729
}
4730
#endif
4731

    
4732
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4733
                                               abi_ulong target_addr)
4734
{
4735
    struct target_timespec *target_ts;
4736

    
4737
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4738
        return -TARGET_EFAULT;
4739
    host_ts->tv_sec = tswapal(target_ts->tv_sec);
4740
    host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
4741
    unlock_user_struct(target_ts, target_addr, 0);
4742
    return 0;
4743
}
4744

    
4745
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4746
                                               struct timespec *host_ts)
4747
{
4748
    struct target_timespec *target_ts;
4749

    
4750
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4751
        return -TARGET_EFAULT;
4752
    target_ts->tv_sec = tswapal(host_ts->tv_sec);
4753
    target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
4754
    unlock_user_struct(target_ts, target_addr, 1);
4755
    return 0;
4756
}
4757

    
4758
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4759
static inline abi_long host_to_target_stat64(void *cpu_env,
4760
                                             abi_ulong target_addr,
4761
                                             struct stat *host_st)
4762
{
4763
#ifdef TARGET_ARM
4764
    if (((CPUARMState *)cpu_env)->eabi) {
4765
        struct target_eabi_stat64 *target_st;
4766

    
4767
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4768
            return -TARGET_EFAULT;
4769
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4770
        __put_user(host_st->st_dev, &target_st->st_dev);
4771
        __put_user(host_st->st_ino, &target_st->st_ino);
4772
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4773
        __put_user(host_st->st_ino, &target_st->__st_ino);
4774
#endif
4775
        __put_user(host_st->st_mode, &target_st->st_mode);
4776
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4777
        __put_user(host_st->st_uid, &target_st->st_uid);
4778
        __put_user(host_st->st_gid, &target_st->st_gid);
4779
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4780
        __put_user(host_st->st_size, &target_st->st_size);
4781
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4782
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4783
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4784
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4785
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4786
        unlock_user_struct(target_st, target_addr, 1);
4787
    } else
4788
#endif
4789
    {
4790
#if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4791
        struct target_stat *target_st;
4792
#else
4793
        struct target_stat64 *target_st;
4794
#endif
4795

    
4796
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4797
            return -TARGET_EFAULT;
4798
        memset(target_st, 0, sizeof(*target_st));
4799
        __put_user(host_st->st_dev, &target_st->st_dev);
4800
        __put_user(host_st->st_ino, &target_st->st_ino);
4801
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4802
        __put_user(host_st->st_ino, &target_st->__st_ino);
4803
#endif
4804
        __put_user(host_st->st_mode, &target_st->st_mode);
4805
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4806
        __put_user(host_st->st_uid, &target_st->st_uid);
4807
        __put_user(host_st->st_gid, &target_st->st_gid);
4808
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4809
        /* XXX: better use of kernel struct */
4810
        __put_user(host_st->st_size, &target_st->st_size);
4811
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4812
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4813
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4814
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4815
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4816
        unlock_user_struct(target_st, target_addr, 1);
4817
    }
4818

    
4819
    return 0;
4820
}
4821
#endif
4822

    
4823
#if defined(CONFIG_USE_NPTL)
4824
/* ??? Using host futex calls even when target atomic operations
4825
   are not really atomic probably breaks things.  However implementing
4826
   futexes locally would make futexes shared between multiple processes
4827
   tricky.  However they're probably useless because guest atomic
4828
   operations won't work either.  */
4829
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4830
                    target_ulong uaddr2, int val3)
4831
{
4832
    struct timespec ts, *pts;
4833
    int base_op;
4834

    
4835
    /* ??? We assume FUTEX_* constants are the same on both host
4836
       and target.  */
4837
#ifdef FUTEX_CMD_MASK
4838
    base_op = op & FUTEX_CMD_MASK;
4839
#else
4840
    base_op = op;
4841
#endif
4842
    switch (base_op) {
4843
    case FUTEX_WAIT:
4844
        if (timeout) {
4845
            pts = &ts;
4846
            target_to_host_timespec(pts, timeout);
4847
        } else {
4848
            pts = NULL;
4849
        }
4850
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4851
                         pts, NULL, 0));
4852
    case FUTEX_WAKE:
4853
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4854
    case FUTEX_FD:
4855
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4856
    case FUTEX_REQUEUE:
4857
    case FUTEX_CMP_REQUEUE:
4858
    case FUTEX_WAKE_OP:
4859
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4860
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4861
           But the prototype takes a `struct timespec *'; insert casts
4862
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4863
           since it's not compared to guest memory.  */
4864
        pts = (struct timespec *)(uintptr_t) timeout;
4865
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4866
                                   g2h(uaddr2),
4867
                                   (base_op == FUTEX_CMP_REQUEUE
4868
                                    ? tswap32(val3)
4869
                                    : val3)));
4870
    default:
4871
        return -TARGET_ENOSYS;
4872
    }
4873
}
4874
#endif
4875

    
4876
/* Map host to target signal numbers for the wait family of syscalls.
4877
   Assume all other status bits are the same.  */
4878
static int host_to_target_waitstatus(int status)
4879
{
4880
    if (WIFSIGNALED(status)) {
4881
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4882
    }
4883
    if (WIFSTOPPED(status)) {
4884
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4885
               | (status & 0xff);
4886
    }
4887
    return status;
4888
}
4889

    
4890
int get_osversion(void)
4891
{
4892
    static int osversion;
4893
    struct new_utsname buf;
4894
    const char *s;
4895
    int i, n, tmp;
4896
    if (osversion)
4897
        return osversion;
4898
    if (qemu_uname_release && *qemu_uname_release) {
4899
        s = qemu_uname_release;
4900
    } else {
4901
        if (sys_uname(&buf))
4902
            return 0;
4903
        s = buf.release;
4904
    }
4905
    tmp = 0;
4906
    for (i = 0; i < 3; i++) {
4907
        n = 0;
4908
        while (*s >= '0' && *s <= '9') {
4909
            n *= 10;
4910
            n += *s - '0';
4911
            s++;
4912
        }
4913
        tmp = (tmp << 8) + n;
4914
        if (*s == '.')
4915
            s++;
4916
    }
4917
    osversion = tmp;
4918
    return osversion;
4919
}
4920

    
4921

    
4922
static int open_self_maps(void *cpu_env, int fd)
4923
{
4924
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4925
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
4926
#endif
4927
    FILE *fp;
4928
    char *line = NULL;
4929
    size_t len = 0;
4930
    ssize_t read;
4931

    
4932
    fp = fopen("/proc/self/maps", "r");
4933
    if (fp == NULL) {
4934
        return -EACCES;
4935
    }
4936

    
4937
    while ((read = getline(&line, &len, fp)) != -1) {
4938
        int fields, dev_maj, dev_min, inode;
4939
        uint64_t min, max, offset;
4940
        char flag_r, flag_w, flag_x, flag_p;
4941
        char path[512] = "";
4942
        fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
4943
                        " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
4944
                        &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
4945

    
4946
        if ((fields < 10) || (fields > 11)) {
4947
            continue;
4948
        }
4949
        if (!strncmp(path, "[stack]", 7)) {
4950
            continue;
4951
        }
4952
        if (h2g_valid(min) && h2g_valid(max)) {
4953
            dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
4954
                    " %c%c%c%c %08" PRIx64 " %02x:%02x %d%s%s\n",
4955
                    h2g(min), h2g(max), flag_r, flag_w,
4956
                    flag_x, flag_p, offset, dev_maj, dev_min, inode,
4957
                    path[0] ? "          " : "", path);
4958
        }
4959
    }
4960

    
4961
    free(line);
4962
    fclose(fp);
4963

    
4964
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4965
    dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0          [stack]\n",
4966
                (unsigned long long)ts->info->stack_limit,
4967
                (unsigned long long)(ts->stack_base + (TARGET_PAGE_SIZE - 1))
4968
                                     & TARGET_PAGE_MASK,
4969
                (unsigned long long)0);
4970
#endif
4971

    
4972
    return 0;
4973
}
4974

    
4975
static int open_self_stat(void *cpu_env, int fd)
4976
{
4977
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
4978
    abi_ulong start_stack = ts->info->start_stack;
4979
    int i;
4980

    
4981
    for (i = 0; i < 44; i++) {
4982
      char buf[128];
4983
      int len;
4984
      uint64_t val = 0;
4985

    
4986
      if (i == 0) {
4987
        /* pid */
4988
        val = getpid();
4989
        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
4990
      } else if (i == 1) {
4991
        /* app name */
4992
        snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
4993
      } else if (i == 27) {
4994
        /* stack bottom */
4995
        val = start_stack;
4996
        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
4997
      } else {
4998
        /* for the rest, there is MasterCard */
4999
        snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
5000
      }
5001

    
5002
      len = strlen(buf);
5003
      if (write(fd, buf, len) != len) {
5004
          return -1;
5005
      }
5006
    }
5007

    
5008
    return 0;
5009
}
5010

    
5011
static int open_self_auxv(void *cpu_env, int fd)
5012
{
5013
    TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
5014
    abi_ulong auxv = ts->info->saved_auxv;
5015
    abi_ulong len = ts->info->auxv_len;
5016
    char *ptr;
5017

    
5018
    /*
5019
     * Auxiliary vector is stored in target process stack.
5020
     * read in whole auxv vector and copy it to file
5021
     */
5022
    ptr = lock_user(VERIFY_READ, auxv, len, 0);
5023
    if (ptr != NULL) {
5024
        while (len > 0) {
5025
            ssize_t r;
5026
            r = write(fd, ptr, len);
5027
            if (r <= 0) {
5028
                break;
5029
            }
5030
            len -= r;
5031
            ptr += r;
5032
        }
5033
        lseek(fd, 0, SEEK_SET);
5034
        unlock_user(ptr, auxv, len);
5035
    }
5036

    
5037
    return 0;
5038
}
5039

    
5040
static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
5041
{
5042
    struct fake_open {
5043
        const char *filename;
5044
        int (*fill)(void *cpu_env, int fd);
5045
    };
5046
    const struct fake_open *fake_open;
5047
    static const struct fake_open fakes[] = {
5048
        { "/proc/self/maps", open_self_maps },
5049
        { "/proc/self/stat", open_self_stat },
5050
        { "/proc/self/auxv", open_self_auxv },
5051
        { NULL, NULL }
5052
    };
5053

    
5054
    for (fake_open = fakes; fake_open->filename; fake_open++) {
5055
        if (!strncmp(pathname, fake_open->filename,
5056
                     strlen(fake_open->filename))) {
5057
            break;
5058
        }
5059
    }
5060

    
5061
    if (fake_open->filename) {
5062
        const char *tmpdir;
5063
        char filename[PATH_MAX];
5064
        int fd, r;
5065

    
5066
        /* create temporary file to map stat to */
5067
        tmpdir = getenv("TMPDIR");
5068
        if (!tmpdir)
5069
            tmpdir = "/tmp";
5070
        snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
5071
        fd = mkstemp(filename);
5072
        if (fd < 0) {
5073
            return fd;
5074
        }
5075
        unlink(filename);
5076

    
5077
        if ((r = fake_open->fill(cpu_env, fd))) {
5078
            close(fd);
5079
            return r;
5080
        }
5081
        lseek(fd, 0, SEEK_SET);
5082

    
5083
        return fd;
5084
    }
5085

    
5086
    return get_errno(open(path(pathname), flags, mode));
5087
}
5088

    
5089
/* do_syscall() should always have a single exit point at the end so
5090
   that actions, such as logging of syscall results, can be performed.
5091
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
5092
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5093
                    abi_long arg2, abi_long arg3, abi_long arg4,
5094
                    abi_long arg5, abi_long arg6, abi_long arg7,
5095
                    abi_long arg8)
5096
{
5097
    abi_long ret;
5098
    struct stat st;
5099
    struct statfs stfs;
5100
    void *p;
5101

    
5102
#ifdef DEBUG
5103
    gemu_log("syscall %d", num);
5104
#endif
5105
    if(do_strace)
5106
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
5107

    
5108
    switch(num) {
5109
    case TARGET_NR_exit:
5110
#ifdef CONFIG_USE_NPTL
5111
      /* In old applications this may be used to implement _exit(2).
5112
         However in threaded applictions it is used for thread termination,
5113
         and _exit_group is used for application termination.
5114
         Do thread termination if we have more then one thread.  */
5115
      /* FIXME: This probably breaks if a signal arrives.  We should probably
5116
         be disabling signals.  */
5117
      if (first_cpu->next_cpu) {
5118
          TaskState *ts;
5119
          CPUArchState **lastp;
5120
          CPUArchState *p;
5121

    
5122
          cpu_list_lock();
5123
          lastp = &first_cpu;
5124
          p = first_cpu;
5125
          while (p && p != (CPUArchState *)cpu_env) {
5126
              lastp = &p->next_cpu;
5127
              p = p->next_cpu;
5128
          }
5129
          /* If we didn't find the CPU for this thread then something is
5130
             horribly wrong.  */
5131
          if (!p)
5132
              abort();
5133
          /* Remove the CPU from the list.  */
5134
          *lastp = p->next_cpu;
5135
          cpu_list_unlock();
5136
          ts = ((CPUArchState *)cpu_env)->opaque;
5137
          if (ts->child_tidptr) {
5138
              put_user_u32(0, ts->child_tidptr);
5139
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
5140
                        NULL, NULL, 0);
5141
          }
5142
          thread_env = NULL;
5143
          object_delete(OBJECT(ENV_GET_CPU(cpu_env)));
5144
          g_free(ts);
5145
          pthread_exit(NULL);
5146
      }
5147
#endif
5148
#ifdef TARGET_GPROF
5149
        _mcleanup();
5150
#endif
5151
        gdb_exit(cpu_env, arg1);
5152
        _exit(arg1);
5153
        ret = 0; /* avoid warning */
5154
        break;
5155
    case TARGET_NR_read:
5156
        if (arg3 == 0)
5157
            ret = 0;
5158
        else {
5159
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5160
                goto efault;
5161
            ret = get_errno(read(arg1, p, arg3));
5162
            unlock_user(p, arg2, ret);
5163
        }
5164
        break;
5165
    case TARGET_NR_write:
5166
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5167
            goto efault;
5168
        ret = get_errno(write(arg1, p, arg3));
5169
        unlock_user(p, arg2, 0);
5170
        break;
5171
    case TARGET_NR_open:
5172
        if (!(p = lock_user_string(arg1)))
5173
            goto efault;
5174
        ret = get_errno(do_open(cpu_env, p,
5175
                                target_to_host_bitmask(arg2, fcntl_flags_tbl),
5176
                                arg3));
5177
        unlock_user(p, arg1, 0);
5178
        break;
5179
#if defined(TARGET_NR_openat) && defined(__NR_openat)
5180
    case TARGET_NR_openat:
5181
        if (!(p = lock_user_string(arg2)))
5182
            goto efault;
5183
        ret = get_errno(sys_openat(arg1,
5184
                                   path(p),
5185
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
5186
                                   arg4));
5187
        unlock_user(p, arg2, 0);
5188
        break;
5189
#endif
5190
    case TARGET_NR_close:
5191
        ret = get_errno(close(arg1));
5192
        break;
5193
    case TARGET_NR_brk:
5194
        ret = do_brk(arg1);
5195
        break;
5196
    case TARGET_NR_fork:
5197
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
5198
        break;
5199
#ifdef TARGET_NR_waitpid
5200
    case TARGET_NR_waitpid:
5201
        {
5202
            int status;
5203
            ret = get_errno(waitpid(arg1, &status, arg3));
5204
            if (!is_error(ret) && arg2 && ret
5205
                && put_user_s32(host_to_target_waitstatus(status), arg2))
5206
                goto efault;
5207
        }
5208
        break;
5209
#endif
5210
#ifdef TARGET_NR_waitid
5211
    case TARGET_NR_waitid:
5212
        {
5213
            siginfo_t info;
5214
            info.si_pid = 0;
5215
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
5216
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
5217
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
5218
                    goto efault;
5219
                host_to_target_siginfo(p, &info);
5220
                unlock_user(p, arg3, sizeof(target_siginfo_t));
5221
            }
5222
        }
5223
        break;
5224
#endif
5225
#ifdef TARGET_NR_creat /* not on alpha */
5226
    case TARGET_NR_creat:
5227
        if (!(p = lock_user_string(arg1)))
5228
            goto efault;
5229
        ret = get_errno(creat(p, arg2));
5230
        unlock_user(p, arg1, 0);
5231
        break;
5232
#endif
5233
    case TARGET_NR_link:
5234
        {
5235
            void * p2;
5236
            p = lock_user_string(arg1);
5237
            p2 = lock_user_string(arg2);
5238
            if (!p || !p2)
5239
                ret = -TARGET_EFAULT;
5240
            else
5241
                ret = get_errno(link(p, p2));
5242
            unlock_user(p2, arg2, 0);
5243
            unlock_user(p, arg1, 0);
5244
        }
5245
        break;
5246
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
5247
    case TARGET_NR_linkat:
5248
        {
5249
            void * p2 = NULL;
5250
            if (!arg2 || !arg4)
5251
                goto efault;
5252
            p  = lock_user_string(arg2);
5253
            p2 = lock_user_string(arg4);
5254
            if (!p || !p2)
5255
                ret = -TARGET_EFAULT;
5256
            else
5257
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
5258
            unlock_user(p, arg2, 0);
5259
            unlock_user(p2, arg4, 0);
5260
        }
5261
        break;
5262
#endif
5263
    case TARGET_NR_unlink:
5264
        if (!(p = lock_user_string(arg1)))
5265
            goto efault;
5266
        ret = get_errno(unlink(p));
5267
        unlock_user(p, arg1, 0);
5268
        break;
5269
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
5270
    case TARGET_NR_unlinkat:
5271
        if (!(p = lock_user_string(arg2)))
5272
            goto efault;
5273
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
5274
        unlock_user(p, arg2, 0);
5275
        break;
5276
#endif
5277
    case TARGET_NR_execve:
5278
        {
5279
            char **argp, **envp;
5280
            int argc, envc;
5281
            abi_ulong gp;
5282
            abi_ulong guest_argp;
5283
            abi_ulong guest_envp;
5284
            abi_ulong addr;
5285
            char **q;
5286
            int total_size = 0;
5287

    
5288
            argc = 0;
5289
            guest_argp = arg2;
5290
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
5291
                if (get_user_ual(addr, gp))
5292
                    goto efault;
5293
                if (!addr)
5294
                    break;
5295
                argc++;
5296
            }
5297
            envc = 0;
5298
            guest_envp = arg3;
5299
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
5300
                if (get_user_ual(addr, gp))
5301
                    goto efault;
5302
                if (!addr)
5303
                    break;
5304
                envc++;
5305
            }
5306

    
5307
            argp = alloca((argc + 1) * sizeof(void *));
5308
            envp = alloca((envc + 1) * sizeof(void *));
5309

    
5310
            for (gp = guest_argp, q = argp; gp;
5311
                  gp += sizeof(abi_ulong), q++) {
5312
                if (get_user_ual(addr, gp))
5313
                    goto execve_efault;
5314
                if (!addr)
5315
                    break;
5316
                if (!(*q = lock_user_string(addr)))
5317
                    goto execve_efault;
5318
                total_size += strlen(*q) + 1;
5319
            }
5320
            *q = NULL;
5321

    
5322
            for (gp = guest_envp, q = envp; gp;
5323
                  gp += sizeof(abi_ulong), q++) {
5324
                if (get_user_ual(addr, gp))
5325
                    goto execve_efault;
5326
                if (!addr)
5327
                    break;
5328
                if (!(*q = lock_user_string(addr)))
5329
                    goto execve_efault;
5330
                total_size += strlen(*q) + 1;
5331
            }
5332
            *q = NULL;
5333

    
5334
            /* This case will not be caught by the host's execve() if its
5335
               page size is bigger than the target's. */
5336
            if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
5337
                ret = -TARGET_E2BIG;
5338
                goto execve_end;
5339
            }
5340
            if (!(p = lock_user_string(arg1)))
5341
                goto execve_efault;
5342
            ret = get_errno(execve(p, argp, envp));
5343
            unlock_user(p, arg1, 0);
5344

    
5345
            goto execve_end;
5346

    
5347
        execve_efault:
5348
            ret = -TARGET_EFAULT;
5349

    
5350
        execve_end:
5351
            for (gp = guest_argp, q = argp; *q;
5352
                  gp += sizeof(abi_ulong), q++) {
5353
                if (get_user_ual(addr, gp)
5354
                    || !addr)
5355
                    break;
5356
                unlock_user(*q, addr, 0);
5357
            }
5358
            for (gp = guest_envp, q = envp; *q;
5359
                  gp += sizeof(abi_ulong), q++) {
5360
                if (get_user_ual(addr, gp)
5361
                    || !addr)
5362
                    break;
5363
                unlock_user(*q, addr, 0);
5364
            }
5365
        }
5366
        break;
5367
    case TARGET_NR_chdir:
5368
        if (!(p = lock_user_string(arg1)))
5369
            goto efault;
5370
        ret = get_errno(chdir(p));
5371
        unlock_user(p, arg1, 0);
5372
        break;
5373
#ifdef TARGET_NR_time
5374
    case TARGET_NR_time:
5375
        {
5376
            time_t host_time;
5377
            ret = get_errno(time(&host_time));
5378
            if (!is_error(ret)
5379
                && arg1
5380
                && put_user_sal(host_time, arg1))
5381
                goto efault;
5382
        }
5383
        break;
5384
#endif
5385
    case TARGET_NR_mknod:
5386
        if (!(p = lock_user_string(arg1)))
5387
            goto efault;
5388
        ret = get_errno(mknod(p, arg2, arg3));
5389
        unlock_user(p, arg1, 0);
5390
        break;
5391
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
5392
    case TARGET_NR_mknodat:
5393
        if (!(p = lock_user_string(arg2)))
5394
            goto efault;
5395
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
5396
        unlock_user(p, arg2, 0);
5397
        break;
5398
#endif
5399
    case TARGET_NR_chmod:
5400
        if (!(p = lock_user_string(arg1)))
5401
            goto efault;
5402
        ret = get_errno(chmod(p, arg2));
5403
        unlock_user(p, arg1, 0);
5404
        break;
5405
#ifdef TARGET_NR_break
5406
    case TARGET_NR_break:
5407
        goto unimplemented;
5408
#endif
5409
#ifdef TARGET_NR_oldstat
5410
    case TARGET_NR_oldstat:
5411
        goto unimplemented;
5412
#endif
5413
    case TARGET_NR_lseek:
5414
        ret = get_errno(lseek(arg1, arg2, arg3));
5415
        break;
5416
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
5417
    /* Alpha specific */
5418
    case TARGET_NR_getxpid:
5419
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
5420
        ret = get_errno(getpid());
5421
        break;
5422
#endif
5423
#ifdef TARGET_NR_getpid
5424
    case TARGET_NR_getpid:
5425
        ret = get_errno(getpid());
5426
        break;
5427
#endif
5428
    case TARGET_NR_mount:
5429
                {
5430
                        /* need to look at the data field */
5431
                        void *p2, *p3;
5432
                        p = lock_user_string(arg1);
5433
                        p2 = lock_user_string(arg2);
5434
                        p3 = lock_user_string(arg3);
5435
                        if (!p || !p2 || !p3)
5436
                            ret = -TARGET_EFAULT;
5437
                        else {
5438
                            /* FIXME - arg5 should be locked, but it isn't clear how to
5439
                             * do that since it's not guaranteed to be a NULL-terminated
5440
                             * string.
5441
                             */
5442
                            if ( ! arg5 )
5443
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
5444
                            else
5445
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
5446
                        }
5447
                        unlock_user(p, arg1, 0);
5448
                        unlock_user(p2, arg2, 0);
5449
                        unlock_user(p3, arg3, 0);
5450
                        break;
5451
                }
5452
#ifdef TARGET_NR_umount
5453
    case TARGET_NR_umount:
5454
        if (!(p = lock_user_string(arg1)))
5455
            goto efault;
5456
        ret = get_errno(umount(p));
5457
        unlock_user(p, arg1, 0);
5458
        break;
5459
#endif
5460
#ifdef TARGET_NR_stime /* not on alpha */
5461
    case TARGET_NR_stime:
5462
        {
5463
            time_t host_time;
5464
            if (get_user_sal(host_time, arg1))
5465
                goto efault;
5466
            ret = get_errno(stime(&host_time));
5467
        }
5468
        break;
5469
#endif
5470
    case TARGET_NR_ptrace:
5471
        goto unimplemented;
5472
#ifdef TARGET_NR_alarm /* not on alpha */
5473
    case TARGET_NR_alarm:
5474
        ret = alarm(arg1);
5475
        break;
5476
#endif
5477
#ifdef TARGET_NR_oldfstat
5478
    case TARGET_NR_oldfstat:
5479
        goto unimplemented;
5480
#endif
5481
#ifdef TARGET_NR_pause /* not on alpha */
5482
    case TARGET_NR_pause:
5483
        ret = get_errno(pause());
5484
        break;
5485
#endif
5486
#ifdef TARGET_NR_utime
5487
    case TARGET_NR_utime:
5488
        {
5489
            struct utimbuf tbuf, *host_tbuf;
5490
            struct target_utimbuf *target_tbuf;
5491
            if (arg2) {
5492
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
5493
                    goto efault;
5494
                tbuf.actime = tswapal(target_tbuf->actime);
5495
                tbuf.modtime = tswapal(target_tbuf->modtime);
5496
                unlock_user_struct(target_tbuf, arg2, 0);
5497
                host_tbuf = &tbuf;
5498
            } else {
5499
                host_tbuf = NULL;
5500
            }
5501
            if (!(p = lock_user_string(arg1)))
5502
                goto efault;
5503
            ret = get_errno(utime(p, host_tbuf));
5504
            unlock_user(p, arg1, 0);
5505
        }
5506
        break;
5507
#endif
5508
    case TARGET_NR_utimes:
5509
        {
5510
            struct timeval *tvp, tv[2];
5511
            if (arg2) {
5512
                if (copy_from_user_timeval(&tv[0], arg2)
5513
                    || copy_from_user_timeval(&tv[1],
5514
                                              arg2 + sizeof(struct target_timeval)))
5515
                    goto efault;
5516
                tvp = tv;
5517
            } else {
5518
                tvp = NULL;
5519
            }
5520
            if (!(p = lock_user_string(arg1)))
5521
                goto efault;
5522
            ret = get_errno(utimes(p, tvp));
5523
            unlock_user(p, arg1, 0);
5524
        }
5525
        break;
5526
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
5527
    case TARGET_NR_futimesat:
5528
        {
5529
            struct timeval *tvp, tv[2];
5530
            if (arg3) {
5531
                if (copy_from_user_timeval(&tv[0], arg3)
5532
                    || copy_from_user_timeval(&tv[1],
5533
                                              arg3 + sizeof(struct target_timeval)))
5534
                    goto efault;
5535
                tvp = tv;
5536
            } else {
5537
                tvp = NULL;
5538
            }
5539
            if (!(p = lock_user_string(arg2)))
5540
                goto efault;
5541
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
5542
            unlock_user(p, arg2, 0);
5543
        }
5544
        break;
5545
#endif
5546
#ifdef TARGET_NR_stty
5547
    case TARGET_NR_stty:
5548
        goto unimplemented;
5549
#endif
5550
#ifdef TARGET_NR_gtty
5551
    case TARGET_NR_gtty:
5552
        goto unimplemented;
5553
#endif
5554
    case TARGET_NR_access:
5555
        if (!(p = lock_user_string(arg1)))
5556
            goto efault;
5557
        ret = get_errno(access(path(p), arg2));
5558
        unlock_user(p, arg1, 0);
5559
        break;
5560
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
5561
    case TARGET_NR_faccessat:
5562
        if (!(p = lock_user_string(arg2)))
5563
            goto efault;
5564
        ret = get_errno(sys_faccessat(arg1, p, arg3));
5565
        unlock_user(p, arg2, 0);
5566
        break;
5567
#endif
5568
#ifdef TARGET_NR_nice /* not on alpha */
5569
    case TARGET_NR_nice:
5570
        ret = get_errno(nice(arg1));
5571
        break;
5572
#endif
5573
#ifdef TARGET_NR_ftime
5574
    case TARGET_NR_ftime:
5575
        goto unimplemented;
5576
#endif
5577
    case TARGET_NR_sync:
5578
        sync();
5579
        ret = 0;
5580
        break;
5581
    case TARGET_NR_kill:
5582
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
5583
        break;
5584
    case TARGET_NR_rename:
5585
        {
5586
            void *p2;
5587
            p = lock_user_string(arg1);
5588
            p2 = lock_user_string(arg2);
5589
            if (!p || !p2)
5590
                ret = -TARGET_EFAULT;
5591
            else
5592
                ret = get_errno(rename(p, p2));
5593
            unlock_user(p2, arg2, 0);
5594
            unlock_user(p, arg1, 0);
5595
        }
5596
        break;
5597
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
5598
    case TARGET_NR_renameat:
5599
        {
5600
            void *p2;
5601
            p  = lock_user_string(arg2);
5602
            p2 = lock_user_string(arg4);
5603
            if (!p || !p2)
5604
                ret = -TARGET_EFAULT;
5605
            else
5606
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
5607
            unlock_user(p2, arg4, 0);
5608
            unlock_user(p, arg2, 0);
5609
        }
5610
        break;
5611
#endif
5612
    case TARGET_NR_mkdir:
5613
        if (!(p = lock_user_string(arg1)))
5614
            goto efault;
5615
        ret = get_errno(mkdir(p, arg2));
5616
        unlock_user(p, arg1, 0);
5617
        break;
5618
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
5619
    case TARGET_NR_mkdirat:
5620
        if (!(p = lock_user_string(arg2)))
5621
            goto efault;
5622
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
5623
        unlock_user(p, arg2, 0);
5624
        break;
5625
#endif
5626
    case TARGET_NR_rmdir:
5627
        if (!(p = lock_user_string(arg1)))
5628
            goto efault;
5629
        ret = get_errno(rmdir(p));
5630
        unlock_user(p, arg1, 0);
5631
        break;
5632
    case TARGET_NR_dup:
5633
        ret = get_errno(dup(arg1));
5634
        break;
5635
    case TARGET_NR_pipe:
5636
        ret = do_pipe(cpu_env, arg1, 0, 0);
5637
        break;
5638
#ifdef TARGET_NR_pipe2
5639
    case TARGET_NR_pipe2:
5640
        ret = do_pipe(cpu_env, arg1,
5641
                      target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
5642
        break;
5643
#endif
5644
    case TARGET_NR_times:
5645
        {
5646
            struct target_tms *tmsp;
5647
            struct tms tms;
5648
            ret = get_errno(times(&tms));
5649
            if (arg1) {
5650
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
5651
                if (!tmsp)
5652
                    goto efault;
5653
                tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
5654
                tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
5655
                tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
5656
                tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
5657
            }
5658
            if (!is_error(ret))
5659
                ret = host_to_target_clock_t(ret);
5660
        }
5661
        break;
5662
#ifdef TARGET_NR_prof
5663
    case TARGET_NR_prof:
5664
        goto unimplemented;
5665
#endif
5666
#ifdef TARGET_NR_signal
5667
    case TARGET_NR_signal:
5668
        goto unimplemented;
5669
#endif
5670
    case TARGET_NR_acct:
5671
        if (arg1 == 0) {
5672
            ret = get_errno(acct(NULL));
5673
        } else {
5674
            if (!(p = lock_user_string(arg1)))
5675
                goto efault;
5676
            ret = get_errno(acct(path(p)));
5677
            unlock_user(p, arg1, 0);
5678
        }
5679
        break;
5680
#ifdef TARGET_NR_umount2 /* not on alpha */
5681
    case TARGET_NR_umount2:
5682
        if (!(p = lock_user_string(arg1)))
5683
            goto efault;
5684
        ret = get_errno(umount2(p, arg2));
5685
        unlock_user(p, arg1, 0);
5686
        break;
5687
#endif
5688
#ifdef TARGET_NR_lock
5689
    case TARGET_NR_lock:
5690
        goto unimplemented;
5691
#endif
5692
    case TARGET_NR_ioctl:
5693
        ret = do_ioctl(arg1, arg2, arg3);
5694
        break;
5695
    case TARGET_NR_fcntl:
5696
        ret = do_fcntl(arg1, arg2, arg3);
5697
        break;
5698
#ifdef TARGET_NR_mpx
5699
    case TARGET_NR_mpx:
5700
        goto unimplemented;
5701
#endif
5702
    case TARGET_NR_setpgid:
5703
        ret = get_errno(setpgid(arg1, arg2));
5704
        break;
5705
#ifdef TARGET_NR_ulimit
5706
    case TARGET_NR_ulimit:
5707
        goto unimplemented;
5708
#endif
5709
#ifdef TARGET_NR_oldolduname
5710
    case TARGET_NR_oldolduname:
5711
        goto unimplemented;
5712
#endif
5713
    case TARGET_NR_umask:
5714
        ret = get_errno(umask(arg1));
5715
        break;
5716
    case TARGET_NR_chroot:
5717
        if (!(p = lock_user_string(arg1)))
5718
            goto efault;
5719
        ret = get_errno(chroot(p));
5720
        unlock_user(p, arg1, 0);
5721
        break;
5722
    case TARGET_NR_ustat:
5723
        goto unimplemented;
5724
    case TARGET_NR_dup2:
5725
        ret = get_errno(dup2(arg1, arg2));
5726
        break;
5727
#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
5728
    case TARGET_NR_dup3:
5729
        ret = get_errno(dup3(arg1, arg2, arg3));
5730
        break;
5731
#endif
5732
#ifdef TARGET_NR_getppid /* not on alpha */
5733
    case TARGET_NR_getppid:
5734
        ret = get_errno(getppid());
5735
        break;
5736
#endif
5737
    case TARGET_NR_getpgrp:
5738
        ret = get_errno(getpgrp());
5739
        break;
5740
    case TARGET_NR_setsid:
5741
        ret = get_errno(setsid());
5742
        break;
5743
#ifdef TARGET_NR_sigaction
5744
    case TARGET_NR_sigaction:
5745
        {
5746
#if defined(TARGET_ALPHA)
5747
            struct target_sigaction act, oact, *pact = 0;
5748
            struct target_old_sigaction *old_act;
5749
            if (arg2) {
5750
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5751
                    goto efault;
5752
                act._sa_handler = old_act->_sa_handler;
5753
                target_siginitset(&act.sa_mask, old_act->sa_mask);
5754
                act.sa_flags = old_act->sa_flags;
5755
                act.sa_restorer = 0;
5756
                unlock_user_struct(old_act, arg2, 0);
5757
                pact = &act;
5758
            }
5759
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5760
            if (!is_error(ret) && arg3) {
5761
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5762
                    goto efault;
5763
                old_act->_sa_handler = oact._sa_handler;
5764
                old_act->sa_mask = oact.sa_mask.sig[0];
5765
                old_act->sa_flags = oact.sa_flags;
5766
                unlock_user_struct(old_act, arg3, 1);
5767
            }
5768
#elif defined(TARGET_MIPS)
5769
            struct target_sigaction act, oact, *pact, *old_act;
5770

    
5771
            if (arg2) {
5772
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5773
                    goto efault;
5774
                act._sa_handler = old_act->_sa_handler;
5775
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
5776
                act.sa_flags = old_act->sa_flags;
5777
                unlock_user_struct(old_act, arg2, 0);
5778
                pact = &act;
5779
            } else {
5780
                pact = NULL;
5781
            }
5782

    
5783
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5784

    
5785
            if (!is_error(ret) && arg3) {
5786
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5787
                    goto efault;
5788
                old_act->_sa_handler = oact._sa_handler;
5789
                old_act->sa_flags = oact.sa_flags;
5790
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
5791
                old_act->sa_mask.sig[1] = 0;
5792
                old_act->sa_mask.sig[2] = 0;
5793
                old_act->sa_mask.sig[3] = 0;
5794
                unlock_user_struct(old_act, arg3, 1);
5795
            }
5796
#else
5797
            struct target_old_sigaction *old_act;
5798
            struct target_sigaction act, oact, *pact;
5799
            if (arg2) {
5800
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5801
                    goto efault;
5802
                act._sa_handler = old_act->_sa_handler;
5803
                target_siginitset(&act.sa_mask, old_act->sa_mask);
5804
                act.sa_flags = old_act->sa_flags;
5805
                act.sa_restorer = old_act->sa_restorer;
5806
                unlock_user_struct(old_act, arg2, 0);
5807
                pact = &act;
5808
            } else {
5809
                pact = NULL;
5810
            }
5811
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5812
            if (!is_error(ret) && arg3) {
5813
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5814
                    goto efault;
5815
                old_act->_sa_handler = oact._sa_handler;
5816
                old_act->sa_mask = oact.sa_mask.sig[0];
5817
                old_act->sa_flags = oact.sa_flags;
5818
                old_act->sa_restorer = oact.sa_restorer;
5819
                unlock_user_struct(old_act, arg3, 1);
5820
            }
5821
#endif
5822
        }
5823
        break;
5824
#endif
5825
    case TARGET_NR_rt_sigaction:
5826
        {
5827
#if defined(TARGET_ALPHA)
5828
            struct target_sigaction act, oact, *pact = 0;
5829
            struct target_rt_sigaction *rt_act;
5830
            /* ??? arg4 == sizeof(sigset_t).  */
5831
            if (arg2) {
5832
                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
5833
                    goto efault;
5834
                act._sa_handler = rt_act->_sa_handler;
5835
                act.sa_mask = rt_act->sa_mask;
5836
                act.sa_flags = rt_act->sa_flags;
5837
                act.sa_restorer = arg5;
5838
                unlock_user_struct(rt_act, arg2, 0);
5839
                pact = &act;
5840
            }
5841
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5842
            if (!is_error(ret) && arg3) {
5843
                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
5844
                    goto efault;
5845
                rt_act->_sa_handler = oact._sa_handler;
5846
                rt_act->sa_mask = oact.sa_mask;
5847
                rt_act->sa_flags = oact.sa_flags;
5848
                unlock_user_struct(rt_act, arg3, 1);
5849
            }
5850
#else
5851
            struct target_sigaction *act;
5852
            struct target_sigaction *oact;
5853

    
5854
            if (arg2) {
5855
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
5856
                    goto efault;
5857
            } else
5858
                act = NULL;
5859
            if (arg3) {
5860
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
5861
                    ret = -TARGET_EFAULT;
5862
                    goto rt_sigaction_fail;
5863
                }
5864
            } else
5865
                oact = NULL;
5866
            ret = get_errno(do_sigaction(arg1, act, oact));
5867
        rt_sigaction_fail:
5868
            if (act)
5869
                unlock_user_struct(act, arg2, 0);
5870
            if (oact)
5871
                unlock_user_struct(oact, arg3, 1);
5872
#endif
5873
        }
5874
        break;
5875
#ifdef TARGET_NR_sgetmask /* not on alpha */
5876
    case TARGET_NR_sgetmask:
5877
        {
5878
            sigset_t cur_set;
5879
            abi_ulong target_set;
5880
            sigprocmask(0, NULL, &cur_set);
5881
            host_to_target_old_sigset(&target_set, &cur_set);
5882
            ret = target_set;
5883
        }
5884
        break;
5885
#endif
5886
#ifdef TARGET_NR_ssetmask /* not on alpha */
5887
    case TARGET_NR_ssetmask:
5888
        {
5889
            sigset_t set, oset, cur_set;
5890
            abi_ulong target_set = arg1;
5891
            sigprocmask(0, NULL, &cur_set);
5892
            target_to_host_old_sigset(&set, &target_set);
5893
            sigorset(&set, &set, &cur_set);
5894
            sigprocmask(SIG_SETMASK, &set, &oset);
5895
            host_to_target_old_sigset(&target_set, &oset);
5896
            ret = target_set;
5897
        }
5898
        break;
5899
#endif
5900
#ifdef TARGET_NR_sigprocmask
5901
    case TARGET_NR_sigprocmask:
5902
        {
5903
#if defined(TARGET_ALPHA)
5904
            sigset_t set, oldset;
5905
            abi_ulong mask;
5906
            int how;
5907

    
5908
            switch (arg1) {
5909
            case TARGET_SIG_BLOCK:
5910
                how = SIG_BLOCK;
5911
                break;
5912
            case TARGET_SIG_UNBLOCK:
5913
                how = SIG_UNBLOCK;
5914
                break;
5915
            case TARGET_SIG_SETMASK:
5916
                how = SIG_SETMASK;
5917
                break;
5918
            default:
5919
                ret = -TARGET_EINVAL;
5920
                goto fail;
5921
            }
5922
            mask = arg2;
5923
            target_to_host_old_sigset(&set, &mask);
5924

    
5925
            ret = get_errno(sigprocmask(how, &set, &oldset));
5926
            if (!is_error(ret)) {
5927
                host_to_target_old_sigset(&mask, &oldset);
5928
                ret = mask;
5929
                ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
5930
            }
5931
#else
5932
            sigset_t set, oldset, *set_ptr;
5933
            int how;
5934

    
5935
            if (arg2) {
5936
                switch (arg1) {
5937
                case TARGET_SIG_BLOCK:
5938
                    how = SIG_BLOCK;
5939
                    break;
5940
                case TARGET_SIG_UNBLOCK:
5941
                    how = SIG_UNBLOCK;
5942
                    break;
5943
                case TARGET_SIG_SETMASK:
5944
                    how = SIG_SETMASK;
5945
                    break;
5946
                default:
5947
                    ret = -TARGET_EINVAL;
5948
                    goto fail;
5949
                }
5950
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5951
                    goto efault;
5952
                target_to_host_old_sigset(&set, p);
5953
                unlock_user(p, arg2, 0);
5954
                set_ptr = &set;
5955
            } else {
5956
                how = 0;
5957
                set_ptr = NULL;
5958
            }
5959
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5960
            if (!is_error(ret) && arg3) {
5961
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5962
                    goto efault;
5963
                host_to_target_old_sigset(p, &oldset);
5964
                unlock_user(p, arg3, sizeof(target_sigset_t));
5965
            }
5966
#endif
5967
        }
5968
        break;
5969
#endif
5970
    case TARGET_NR_rt_sigprocmask:
5971
        {
5972
            int how = arg1;
5973
            sigset_t set, oldset, *set_ptr;
5974

    
5975
            if (arg2) {
5976
                switch(how) {
5977
                case TARGET_SIG_BLOCK:
5978
                    how = SIG_BLOCK;
5979
                    break;
5980
                case TARGET_SIG_UNBLOCK:
5981
                    how = SIG_UNBLOCK;
5982
                    break;
5983
                case TARGET_SIG_SETMASK:
5984
                    how = SIG_SETMASK;
5985
                    break;
5986
                default:
5987
                    ret = -TARGET_EINVAL;
5988
                    goto fail;
5989
                }
5990
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5991
                    goto efault;
5992
                target_to_host_sigset(&set, p);
5993
                unlock_user(p, arg2, 0);
5994
                set_ptr = &set;
5995
            } else {
5996
                how = 0;
5997
                set_ptr = NULL;
5998
            }
5999
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
6000
            if (!is_error(ret) && arg3) {
6001
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6002
                    goto efault;
6003
                host_to_target_sigset(p, &oldset);
6004
                unlock_user(p, arg3, sizeof(target_sigset_t));
6005
            }
6006
        }
6007
        break;
6008
#ifdef TARGET_NR_sigpending
6009
    case TARGET_NR_sigpending:
6010
        {
6011
            sigset_t set;
6012
            ret = get_errno(sigpending(&set));
6013
            if (!is_error(ret)) {
6014
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6015
                    goto efault;
6016
                host_to_target_old_sigset(p, &set);
6017
                unlock_user(p, arg1, sizeof(target_sigset_t));
6018
            }
6019
        }
6020
        break;
6021
#endif
6022
    case TARGET_NR_rt_sigpending:
6023
        {
6024
            sigset_t set;
6025
            ret = get_errno(sigpending(&set));
6026
            if (!is_error(ret)) {
6027
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6028
                    goto efault;
6029
                host_to_target_sigset(p, &set);
6030
                unlock_user(p, arg1, sizeof(target_sigset_t));
6031
            }
6032
        }
6033
        break;
6034
#ifdef TARGET_NR_sigsuspend
6035
    case TARGET_NR_sigsuspend:
6036
        {
6037
            sigset_t set;
6038
#if defined(TARGET_ALPHA)
6039
            abi_ulong mask = arg1;
6040
            target_to_host_old_sigset(&set, &mask);
6041
#else
6042
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6043
                goto efault;
6044
            target_to_host_old_sigset(&set, p);
6045
            unlock_user(p, arg1, 0);
6046
#endif
6047
            ret = get_errno(sigsuspend(&set));
6048
        }
6049
        break;
6050
#endif
6051
    case TARGET_NR_rt_sigsuspend:
6052
        {
6053
            sigset_t set;
6054
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6055
                goto efault;
6056
            target_to_host_sigset(&set, p);
6057
            unlock_user(p, arg1, 0);
6058
            ret = get_errno(sigsuspend(&set));
6059
        }
6060
        break;
6061
    case TARGET_NR_rt_sigtimedwait:
6062
        {
6063
            sigset_t set;
6064
            struct timespec uts, *puts;
6065
            siginfo_t uinfo;
6066

    
6067
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6068
                goto efault;
6069
            target_to_host_sigset(&set, p);
6070
            unlock_user(p, arg1, 0);
6071
            if (arg3) {
6072
                puts = &uts;
6073
                target_to_host_timespec(puts, arg3);
6074
            } else {
6075
                puts = NULL;
6076
            }
6077
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
6078
            if (!is_error(ret) && arg2) {
6079
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
6080
                    goto efault;
6081
                host_to_target_siginfo(p, &uinfo);
6082
                unlock_user(p, arg2, sizeof(target_siginfo_t));
6083
            }
6084
        }
6085
        break;
6086
    case TARGET_NR_rt_sigqueueinfo:
6087
        {
6088
            siginfo_t uinfo;
6089
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
6090
                goto efault;
6091
            target_to_host_siginfo(&uinfo, p);
6092
            unlock_user(p, arg1, 0);
6093
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
6094
        }
6095
        break;
6096
#ifdef TARGET_NR_sigreturn
6097
    case TARGET_NR_sigreturn:
6098
        /* NOTE: ret is eax, so not transcoding must be done */
6099
        ret = do_sigreturn(cpu_env);
6100
        break;
6101
#endif
6102
    case TARGET_NR_rt_sigreturn:
6103
        /* NOTE: ret is eax, so not transcoding must be done */
6104
        ret = do_rt_sigreturn(cpu_env);
6105
        break;
6106
    case TARGET_NR_sethostname:
6107
        if (!(p = lock_user_string(arg1)))
6108
            goto efault;
6109
        ret = get_errno(sethostname(p, arg2));
6110
        unlock_user(p, arg1, 0);
6111
        break;
6112
    case TARGET_NR_setrlimit:
6113
        {
6114
            int resource = target_to_host_resource(arg1);
6115
            struct target_rlimit *target_rlim;
6116
            struct rlimit rlim;
6117
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
6118
                goto efault;
6119
            rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
6120
            rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
6121
            unlock_user_struct(target_rlim, arg2, 0);
6122
            ret = get_errno(setrlimit(resource, &rlim));
6123
        }
6124
        break;
6125
    case TARGET_NR_getrlimit:
6126
        {
6127
            int resource = target_to_host_resource(arg1);
6128
            struct target_rlimit *target_rlim;
6129
            struct rlimit rlim;
6130

    
6131
            ret = get_errno(getrlimit(resource, &rlim));
6132
            if (!is_error(ret)) {
6133
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6134
                    goto efault;
6135
                target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6136
                target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6137
                unlock_user_struct(target_rlim, arg2, 1);
6138
            }
6139
        }
6140
        break;
6141
    case TARGET_NR_getrusage:
6142
        {
6143
            struct rusage rusage;
6144
            ret = get_errno(getrusage(arg1, &rusage));
6145
            if (!is_error(ret)) {
6146
                host_to_target_rusage(arg2, &rusage);
6147
            }
6148
        }
6149
        break;
6150
    case TARGET_NR_gettimeofday:
6151
        {
6152
            struct timeval tv;
6153
            ret = get_errno(gettimeofday(&tv, NULL));
6154
            if (!is_error(ret)) {
6155
                if (copy_to_user_timeval(arg1, &tv))
6156
                    goto efault;
6157
            }
6158
        }
6159
        break;
6160
    case TARGET_NR_settimeofday:
6161
        {
6162
            struct timeval tv;
6163
            if (copy_from_user_timeval(&tv, arg1))
6164
                goto efault;
6165
            ret = get_errno(settimeofday(&tv, NULL));
6166
        }
6167
        break;
6168
#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390)
6169
    case TARGET_NR_select:
6170
        {
6171
            struct target_sel_arg_struct *sel;
6172
            abi_ulong inp, outp, exp, tvp;
6173
            long nsel;
6174

    
6175
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
6176
                goto efault;
6177
            nsel = tswapal(sel->n);
6178
            inp = tswapal(sel->inp);
6179
            outp = tswapal(sel->outp);
6180
            exp = tswapal(sel->exp);
6181
            tvp = tswapal(sel->tvp);
6182
            unlock_user_struct(sel, arg1, 0);
6183
            ret = do_select(nsel, inp, outp, exp, tvp);
6184
        }
6185
        break;
6186
#endif
6187
#ifdef TARGET_NR_pselect6
6188
    case TARGET_NR_pselect6:
6189
        {
6190
            abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
6191
            fd_set rfds, wfds, efds;
6192
            fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
6193
            struct timespec ts, *ts_ptr;
6194

    
6195
            /*
6196
             * The 6th arg is actually two args smashed together,
6197
             * so we cannot use the C library.
6198
             */
6199
            sigset_t set;
6200
            struct {
6201
                sigset_t *set;
6202
                size_t size;
6203
            } sig, *sig_ptr;
6204

    
6205
            abi_ulong arg_sigset, arg_sigsize, *arg7;
6206
            target_sigset_t *target_sigset;
6207

    
6208
            n = arg1;
6209
            rfd_addr = arg2;
6210
            wfd_addr = arg3;
6211
            efd_addr = arg4;
6212
            ts_addr = arg5;
6213

    
6214
            ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
6215
            if (ret) {
6216
                goto fail;
6217
            }
6218
            ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
6219
            if (ret) {
6220
                goto fail;
6221
            }
6222
            ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
6223
            if (ret) {
6224
                goto fail;
6225
            }
6226

    
6227
            /*
6228
             * This takes a timespec, and not a timeval, so we cannot
6229
             * use the do_select() helper ...
6230
             */
6231
            if (ts_addr) {
6232
                if (target_to_host_timespec(&ts, ts_addr)) {
6233
                    goto efault;
6234
                }
6235
                ts_ptr = &ts;
6236
            } else {
6237
                ts_ptr = NULL;
6238
            }
6239

    
6240
            /* Extract the two packed args for the sigset */
6241
            if (arg6) {
6242
                sig_ptr = &sig;
6243
                sig.size = _NSIG / 8;
6244

    
6245
                arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
6246
                if (!arg7) {
6247
                    goto efault;
6248
                }
6249
                arg_sigset = tswapal(arg7[0]);
6250
                arg_sigsize = tswapal(arg7[1]);
6251
                unlock_user(arg7, arg6, 0);
6252

    
6253
                if (arg_sigset) {
6254
                    sig.set = &set;
6255
                    if (arg_sigsize != sizeof(*target_sigset)) {
6256
                        /* Like the kernel, we enforce correct size sigsets */
6257
                        ret = -TARGET_EINVAL;
6258
                        goto fail;
6259
                    }
6260
                    target_sigset = lock_user(VERIFY_READ, arg_sigset,
6261
                                              sizeof(*target_sigset), 1);
6262
                    if (!target_sigset) {
6263
                        goto efault;
6264
                    }
6265
                    target_to_host_sigset(&set, target_sigset);
6266
                    unlock_user(target_sigset, arg_sigset, 0);
6267
                } else {
6268
                    sig.set = NULL;
6269
                }
6270
            } else {
6271
                sig_ptr = NULL;
6272
            }
6273

    
6274
            ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
6275
                                         ts_ptr, sig_ptr));
6276

    
6277
            if (!is_error(ret)) {
6278
                if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
6279
                    goto efault;
6280
                if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
6281
                    goto efault;
6282
                if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
6283
                    goto efault;
6284

    
6285
                if (ts_addr && host_to_target_timespec(ts_addr, &ts))
6286
                    goto efault;
6287
            }
6288
        }
6289
        break;
6290
#endif
6291
    case TARGET_NR_symlink:
6292
        {
6293
            void *p2;
6294
            p = lock_user_string(arg1);
6295
            p2 = lock_user_string(arg2);
6296
            if (!p || !p2)
6297
                ret = -TARGET_EFAULT;
6298
            else
6299
                ret = get_errno(symlink(p, p2));
6300
            unlock_user(p2, arg2, 0);
6301
            unlock_user(p, arg1, 0);
6302
        }
6303
        break;
6304
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
6305
    case TARGET_NR_symlinkat:
6306
        {
6307
            void *p2;
6308
            p  = lock_user_string(arg1);
6309
            p2 = lock_user_string(arg3);
6310
            if (!p || !p2)
6311
                ret = -TARGET_EFAULT;
6312
            else
6313
                ret = get_errno(sys_symlinkat(p, arg2, p2));
6314
            unlock_user(p2, arg3, 0);
6315
            unlock_user(p, arg1, 0);
6316
        }
6317
        break;
6318
#endif
6319
#ifdef TARGET_NR_oldlstat
6320
    case TARGET_NR_oldlstat:
6321
        goto unimplemented;
6322
#endif
6323
    case TARGET_NR_readlink:
6324
        {
6325
            void *p2, *temp;
6326
            p = lock_user_string(arg1);
6327
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
6328
            if (!p || !p2)
6329
                ret = -TARGET_EFAULT;
6330
            else {
6331
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
6332
                    char real[PATH_MAX];
6333
                    temp = realpath(exec_path,real);
6334
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
6335
                    snprintf((char *)p2, arg3, "%s", real);
6336
                    }
6337
                else
6338
                    ret = get_errno(readlink(path(p), p2, arg3));
6339
            }
6340
            unlock_user(p2, arg2, ret);
6341
            unlock_user(p, arg1, 0);
6342
        }
6343
        break;
6344
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
6345
    case TARGET_NR_readlinkat:
6346
        {
6347
            void *p2;
6348
            p  = lock_user_string(arg2);
6349
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
6350
            if (!p || !p2)
6351
                ret = -TARGET_EFAULT;
6352
            else
6353
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
6354
            unlock_user(p2, arg3, ret);
6355
            unlock_user(p, arg2, 0);
6356
        }
6357
        break;
6358
#endif
6359
#ifdef TARGET_NR_uselib
6360
    case TARGET_NR_uselib:
6361
        goto unimplemented;
6362
#endif
6363
#ifdef TARGET_NR_swapon
6364
    case TARGET_NR_swapon:
6365
        if (!(p = lock_user_string(arg1)))
6366
            goto efault;
6367
        ret = get_errno(swapon(p, arg2));
6368
        unlock_user(p, arg1, 0);
6369
        break;
6370
#endif
6371
    case TARGET_NR_reboot:
6372
        if (!(p = lock_user_string(arg4)))
6373
            goto efault;
6374
        ret = reboot(arg1, arg2, arg3, p);
6375
        unlock_user(p, arg4, 0);
6376
        break;
6377
#ifdef TARGET_NR_readdir
6378
    case TARGET_NR_readdir:
6379
        goto unimplemented;
6380
#endif
6381
#ifdef TARGET_NR_mmap
6382
    case TARGET_NR_mmap:
6383
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \
6384
    defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
6385
    || defined(TARGET_S390X)
6386
        {
6387
            abi_ulong *v;
6388
            abi_ulong v1, v2, v3, v4, v5, v6;
6389
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
6390
                goto efault;
6391
            v1 = tswapal(v[0]);
6392
            v2 = tswapal(v[1]);
6393
            v3 = tswapal(v[2]);
6394
            v4 = tswapal(v[3]);
6395
            v5 = tswapal(v[4]);
6396
            v6 = tswapal(v[5]);
6397
            unlock_user(v, arg1, 0);
6398
            ret = get_errno(target_mmap(v1, v2, v3,
6399
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
6400
                                        v5, v6));
6401
        }
6402
#else
6403
        ret = get_errno(target_mmap(arg1, arg2, arg3,
6404
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
6405
                                    arg5,
6406
                                    arg6));
6407
#endif
6408
        break;
6409
#endif
6410
#ifdef TARGET_NR_mmap2
6411
    case TARGET_NR_mmap2:
6412
#ifndef MMAP_SHIFT
6413
#define MMAP_SHIFT 12
6414
#endif
6415
        ret = get_errno(target_mmap(arg1, arg2, arg3,
6416
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
6417
                                    arg5,
6418
                                    arg6 << MMAP_SHIFT));
6419
        break;
6420
#endif
6421
    case TARGET_NR_munmap:
6422
        ret = get_errno(target_munmap(arg1, arg2));
6423
        break;
6424
    case TARGET_NR_mprotect:
6425
        {
6426
            TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
6427
            /* Special hack to detect libc making the stack executable.  */
6428
            if ((arg3 & PROT_GROWSDOWN)
6429
                && arg1 >= ts->info->stack_limit
6430
                && arg1 <= ts->info->start_stack) {
6431
                arg3 &= ~PROT_GROWSDOWN;
6432
                arg2 = arg2 + arg1 - ts->info->stack_limit;
6433
                arg1 = ts->info->stack_limit;
6434
            }
6435
        }
6436
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
6437
        break;
6438
#ifdef TARGET_NR_mremap
6439
    case TARGET_NR_mremap:
6440
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
6441
        break;
6442
#endif
6443
        /* ??? msync/mlock/munlock are broken for softmmu.  */
6444
#ifdef TARGET_NR_msync
6445
    case TARGET_NR_msync:
6446
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
6447
        break;
6448
#endif
6449
#ifdef TARGET_NR_mlock
6450
    case TARGET_NR_mlock:
6451
        ret = get_errno(mlock(g2h(arg1), arg2));
6452
        break;
6453
#endif
6454
#ifdef TARGET_NR_munlock
6455
    case TARGET_NR_munlock:
6456
        ret = get_errno(munlock(g2h(arg1), arg2));
6457
        break;
6458
#endif
6459
#ifdef TARGET_NR_mlockall
6460
    case TARGET_NR_mlockall:
6461
        ret = get_errno(mlockall(arg1));
6462
        break;
6463
#endif
6464
#ifdef TARGET_NR_munlockall
6465
    case TARGET_NR_munlockall:
6466
        ret = get_errno(munlockall());
6467
        break;
6468
#endif
6469
    case TARGET_NR_truncate:
6470
        if (!(p = lock_user_string(arg1)))
6471
            goto efault;
6472
        ret = get_errno(truncate(p, arg2));
6473
        unlock_user(p, arg1, 0);
6474
        break;
6475
    case TARGET_NR_ftruncate:
6476
        ret = get_errno(ftruncate(arg1, arg2));
6477
        break;
6478
    case TARGET_NR_fchmod:
6479
        ret = get_errno(fchmod(arg1, arg2));
6480
        break;
6481
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
6482
    case TARGET_NR_fchmodat:
6483
        if (!(p = lock_user_string(arg2)))
6484
            goto efault;
6485
        ret = get_errno(sys_fchmodat(arg1, p, arg3));
6486
        unlock_user(p, arg2, 0);
6487
        break;
6488
#endif
6489
    case TARGET_NR_getpriority:
6490
        /* Note that negative values are valid for getpriority, so we must
6491
           differentiate based on errno settings.  */
6492
        errno = 0;
6493
        ret = getpriority(arg1, arg2);
6494
        if (ret == -1 && errno != 0) {
6495
            ret = -host_to_target_errno(errno);
6496
            break;
6497
        }
6498
#ifdef TARGET_ALPHA
6499
        /* Return value is the unbiased priority.  Signal no error.  */
6500
        ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
6501
#else
6502
        /* Return value is a biased priority to avoid negative numbers.  */
6503
        ret = 20 - ret;
6504
#endif
6505
        break;
6506
    case TARGET_NR_setpriority:
6507
        ret = get_errno(setpriority(arg1, arg2, arg3));
6508
        break;
6509
#ifdef TARGET_NR_profil
6510
    case TARGET_NR_profil:
6511
        goto unimplemented;
6512
#endif
6513
    case TARGET_NR_statfs:
6514
        if (!(p = lock_user_string(arg1)))
6515
            goto efault;
6516
        ret = get_errno(statfs(path(p), &stfs));
6517
        unlock_user(p, arg1, 0);
6518
    convert_statfs:
6519
        if (!is_error(ret)) {
6520
            struct target_statfs *target_stfs;
6521

    
6522
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
6523
                goto efault;
6524
            __put_user(stfs.f_type, &target_stfs->f_type);
6525
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6526
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6527
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6528
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6529
            __put_user(stfs.f_files, &target_stfs->f_files);
6530
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6531
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6532
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6533
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6534
            unlock_user_struct(target_stfs, arg2, 1);
6535
        }
6536
        break;
6537
    case TARGET_NR_fstatfs:
6538
        ret = get_errno(fstatfs(arg1, &stfs));
6539
        goto convert_statfs;
6540
#ifdef TARGET_NR_statfs64
6541
    case TARGET_NR_statfs64:
6542
        if (!(p = lock_user_string(arg1)))
6543
            goto efault;
6544
        ret = get_errno(statfs(path(p), &stfs));
6545
        unlock_user(p, arg1, 0);
6546
    convert_statfs64:
6547
        if (!is_error(ret)) {
6548
            struct target_statfs64 *target_stfs;
6549

    
6550
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
6551
                goto efault;
6552
            __put_user(stfs.f_type, &target_stfs->f_type);
6553
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
6554
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
6555
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6556
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6557
            __put_user(stfs.f_files, &target_stfs->f_files);
6558
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6559
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6560
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6561
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6562
            unlock_user_struct(target_stfs, arg3, 1);
6563
        }
6564
        break;
6565
    case TARGET_NR_fstatfs64:
6566
        ret = get_errno(fstatfs(arg1, &stfs));
6567
        goto convert_statfs64;
6568
#endif
6569
#ifdef TARGET_NR_ioperm
6570
    case TARGET_NR_ioperm:
6571
        goto unimplemented;
6572
#endif
6573
#ifdef TARGET_NR_socketcall
6574
    case TARGET_NR_socketcall:
6575
        ret = do_socketcall(arg1, arg2);
6576
        break;
6577
#endif
6578
#ifdef TARGET_NR_accept
6579
    case TARGET_NR_accept:
6580
        ret = do_accept(arg1, arg2, arg3);
6581
        break;
6582
#endif
6583
#ifdef TARGET_NR_bind
6584
    case TARGET_NR_bind:
6585
        ret = do_bind(arg1, arg2, arg3);
6586
        break;
6587
#endif
6588
#ifdef TARGET_NR_connect
6589
    case TARGET_NR_connect:
6590
        ret = do_connect(arg1, arg2, arg3);
6591
        break;
6592
#endif
6593
#ifdef TARGET_NR_getpeername
6594
    case TARGET_NR_getpeername:
6595
        ret = do_getpeername(arg1, arg2, arg3);
6596
        break;
6597
#endif
6598
#ifdef TARGET_NR_getsockname
6599
    case TARGET_NR_getsockname:
6600
        ret = do_getsockname(arg1, arg2, arg3);
6601
        break;
6602
#endif
6603
#ifdef TARGET_NR_getsockopt
6604
    case TARGET_NR_getsockopt:
6605
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
6606
        break;
6607
#endif
6608
#ifdef TARGET_NR_listen
6609
    case TARGET_NR_listen:
6610
        ret = get_errno(listen(arg1, arg2));
6611
        break;
6612
#endif
6613
#ifdef TARGET_NR_recv
6614
    case TARGET_NR_recv:
6615
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
6616
        break;
6617
#endif
6618
#ifdef TARGET_NR_recvfrom
6619
    case TARGET_NR_recvfrom:
6620
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
6621
        break;
6622
#endif
6623
#ifdef TARGET_NR_recvmsg
6624
    case TARGET_NR_recvmsg:
6625
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
6626
        break;
6627
#endif
6628
#ifdef TARGET_NR_send
6629
    case TARGET_NR_send:
6630
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
6631
        break;
6632
#endif
6633
#ifdef TARGET_NR_sendmsg
6634
    case TARGET_NR_sendmsg:
6635
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
6636
        break;
6637
#endif
6638
#ifdef TARGET_NR_sendto
6639
    case TARGET_NR_sendto:
6640
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
6641
        break;
6642
#endif
6643
#ifdef TARGET_NR_shutdown
6644
    case TARGET_NR_shutdown:
6645
        ret = get_errno(shutdown(arg1, arg2));
6646
        break;
6647
#endif
6648
#ifdef TARGET_NR_socket
6649
    case TARGET_NR_socket:
6650
        ret = do_socket(arg1, arg2, arg3);
6651
        break;
6652
#endif
6653
#ifdef TARGET_NR_socketpair
6654
    case TARGET_NR_socketpair:
6655
        ret = do_socketpair(arg1, arg2, arg3, arg4);
6656
        break;
6657
#endif
6658
#ifdef TARGET_NR_setsockopt
6659
    case TARGET_NR_setsockopt:
6660
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
6661
        break;
6662
#endif
6663

    
6664
    case TARGET_NR_syslog:
6665
        if (!(p = lock_user_string(arg2)))
6666
            goto efault;
6667
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
6668
        unlock_user(p, arg2, 0);
6669
        break;
6670

    
6671
    case TARGET_NR_setitimer:
6672
        {
6673
            struct itimerval value, ovalue, *pvalue;
6674

    
6675
            if (arg2) {
6676
                pvalue = &value;
6677
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
6678
                    || copy_from_user_timeval(&pvalue->it_value,
6679
                                              arg2 + sizeof(struct target_timeval)))
6680
                    goto efault;
6681
            } else {
6682
                pvalue = NULL;
6683
            }
6684
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
6685
            if (!is_error(ret) && arg3) {
6686
                if (copy_to_user_timeval(arg3,
6687
                                         &ovalue.it_interval)
6688
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
6689
                                            &ovalue.it_value))
6690
                    goto efault;
6691
            }
6692
        }
6693
        break;
6694
    case TARGET_NR_getitimer:
6695
        {
6696
            struct itimerval value;
6697

    
6698
            ret = get_errno(getitimer(arg1, &value));
6699
            if (!is_error(ret) && arg2) {
6700
                if (copy_to_user_timeval(arg2,
6701
                                         &value.it_interval)
6702
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
6703
                                            &value.it_value))
6704
                    goto efault;
6705
            }
6706
        }
6707
        break;
6708
    case TARGET_NR_stat:
6709
        if (!(p = lock_user_string(arg1)))
6710
            goto efault;
6711
        ret = get_errno(stat(path(p), &st));
6712
        unlock_user(p, arg1, 0);
6713
        goto do_stat;
6714
    case TARGET_NR_lstat:
6715
        if (!(p = lock_user_string(arg1)))
6716
            goto efault;
6717
        ret = get_errno(lstat(path(p), &st));
6718
        unlock_user(p, arg1, 0);
6719
        goto do_stat;
6720
    case TARGET_NR_fstat:
6721
        {
6722
            ret = get_errno(fstat(arg1, &st));
6723
        do_stat:
6724
            if (!is_error(ret)) {
6725
                struct target_stat *target_st;
6726

    
6727
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
6728
                    goto efault;
6729
                memset(target_st, 0, sizeof(*target_st));
6730
                __put_user(st.st_dev, &target_st->st_dev);
6731
                __put_user(st.st_ino, &target_st->st_ino);
6732
                __put_user(st.st_mode, &target_st->st_mode);
6733
                __put_user(st.st_uid, &target_st->st_uid);
6734
                __put_user(st.st_gid, &target_st->st_gid);
6735
                __put_user(st.st_nlink, &target_st->st_nlink);
6736
                __put_user(st.st_rdev, &target_st->st_rdev);
6737
                __put_user(st.st_size, &target_st->st_size);
6738
                __put_user(st.st_blksize, &target_st->st_blksize);
6739
                __put_user(st.st_blocks, &target_st->st_blocks);
6740
                __put_user(st.st_atime, &target_st->target_st_atime);
6741
                __put_user(st.st_mtime, &target_st->target_st_mtime);
6742
                __put_user(st.st_ctime, &target_st->target_st_ctime);
6743
                unlock_user_struct(target_st, arg2, 1);
6744
            }
6745
        }
6746
        break;
6747
#ifdef TARGET_NR_olduname
6748
    case TARGET_NR_olduname:
6749
        goto unimplemented;
6750
#endif
6751
#ifdef TARGET_NR_iopl
6752
    case TARGET_NR_iopl:
6753
        goto unimplemented;
6754
#endif
6755
    case TARGET_NR_vhangup:
6756
        ret = get_errno(vhangup());
6757
        break;
6758
#ifdef TARGET_NR_idle
6759
    case TARGET_NR_idle:
6760
        goto unimplemented;
6761
#endif
6762
#ifdef TARGET_NR_syscall
6763
    case TARGET_NR_syscall:
6764
        ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
6765
                         arg6, arg7, arg8, 0);
6766
        break;
6767
#endif
6768
    case TARGET_NR_wait4:
6769
        {
6770
            int status;
6771
            abi_long status_ptr = arg2;
6772
            struct rusage rusage, *rusage_ptr;
6773
            abi_ulong target_rusage = arg4;
6774
            if (target_rusage)
6775
                rusage_ptr = &rusage;
6776
            else
6777
                rusage_ptr = NULL;
6778
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
6779
            if (!is_error(ret)) {
6780
                if (status_ptr && ret) {
6781
                    status = host_to_target_waitstatus(status);
6782
                    if (put_user_s32(status, status_ptr))
6783
                        goto efault;
6784
                }
6785
                if (target_rusage)
6786
                    host_to_target_rusage(target_rusage, &rusage);
6787
            }
6788
        }
6789
        break;
6790
#ifdef TARGET_NR_swapoff
6791
    case TARGET_NR_swapoff:
6792
        if (!(p = lock_user_string(arg1)))
6793
            goto efault;
6794
        ret = get_errno(swapoff(p));
6795
        unlock_user(p, arg1, 0);
6796
        break;
6797
#endif
6798
    case TARGET_NR_sysinfo:
6799
        {
6800
            struct target_sysinfo *target_value;
6801
            struct sysinfo value;
6802
            ret = get_errno(sysinfo(&value));
6803
            if (!is_error(ret) && arg1)
6804
            {
6805
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
6806
                    goto efault;
6807
                __put_user(value.uptime, &target_value->uptime);
6808
                __put_user(value.loads[0], &target_value->loads[0]);
6809
                __put_user(value.loads[1], &target_value->loads[1]);
6810
                __put_user(value.loads[2], &target_value->loads[2]);
6811
                __put_user(value.totalram, &target_value->totalram);
6812
                __put_user(value.freeram, &target_value->freeram);
6813
                __put_user(value.sharedram, &target_value->sharedram);
6814
                __put_user(value.bufferram, &target_value->bufferram);
6815
                __put_user(value.totalswap, &target_value->totalswap);
6816
                __put_user(value.freeswap, &target_value->freeswap);
6817
                __put_user(value.procs, &target_value->procs);
6818
                __put_user(value.totalhigh, &target_value->totalhigh);
6819
                __put_user(value.freehigh, &target_value->freehigh);
6820
                __put_user(value.mem_unit, &target_value->mem_unit);
6821
                unlock_user_struct(target_value, arg1, 1);
6822
            }
6823
        }
6824
        break;
6825
#ifdef TARGET_NR_ipc
6826
    case TARGET_NR_ipc:
6827
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
6828
        break;
6829
#endif
6830
#ifdef TARGET_NR_semget
6831
    case TARGET_NR_semget:
6832
        ret = get_errno(semget(arg1, arg2, arg3));
6833
        break;
6834
#endif
6835
#ifdef TARGET_NR_semop
6836
    case TARGET_NR_semop:
6837
        ret = get_errno(do_semop(arg1, arg2, arg3));
6838
        break;
6839
#endif
6840
#ifdef TARGET_NR_semctl
6841
    case TARGET_NR_semctl:
6842
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
6843
        break;
6844
#endif
6845
#ifdef TARGET_NR_msgctl
6846
    case TARGET_NR_msgctl:
6847
        ret = do_msgctl(arg1, arg2, arg3);
6848
        break;
6849
#endif
6850
#ifdef TARGET_NR_msgget
6851
    case TARGET_NR_msgget:
6852
        ret = get_errno(msgget(arg1, arg2));
6853
        break;
6854
#endif
6855
#ifdef TARGET_NR_msgrcv
6856
    case TARGET_NR_msgrcv:
6857
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
6858
        break;
6859
#endif
6860
#ifdef TARGET_NR_msgsnd
6861
    case TARGET_NR_msgsnd:
6862
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
6863
        break;
6864
#endif
6865
#ifdef TARGET_NR_shmget
6866
    case TARGET_NR_shmget:
6867
        ret = get_errno(shmget(arg1, arg2, arg3));
6868
        break;
6869
#endif
6870
#ifdef TARGET_NR_shmctl
6871
    case TARGET_NR_shmctl:
6872
        ret = do_shmctl(arg1, arg2, arg3);
6873
        break;
6874
#endif
6875
#ifdef TARGET_NR_shmat
6876
    case TARGET_NR_shmat:
6877
        ret = do_shmat(arg1, arg2, arg3);
6878
        break;
6879
#endif
6880
#ifdef TARGET_NR_shmdt
6881
    case TARGET_NR_shmdt:
6882
        ret = do_shmdt(arg1);
6883
        break;
6884
#endif
6885
    case TARGET_NR_fsync:
6886
        ret = get_errno(fsync(arg1));
6887
        break;
6888
    case TARGET_NR_clone:
6889
#if defined(TARGET_SH4) || defined(TARGET_ALPHA)
6890
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
6891
#elif defined(TARGET_CRIS)
6892
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
6893
#elif defined(TARGET_S390X)
6894
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
6895
#else
6896
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
6897
#endif
6898
        break;
6899
#ifdef __NR_exit_group
6900
        /* new thread calls */
6901
    case TARGET_NR_exit_group:
6902
#ifdef TARGET_GPROF
6903
        _mcleanup();
6904
#endif
6905
        gdb_exit(cpu_env, arg1);
6906
        ret = get_errno(exit_group(arg1));
6907
        break;
6908
#endif
6909
    case TARGET_NR_setdomainname:
6910
        if (!(p = lock_user_string(arg1)))
6911
            goto efault;
6912
        ret = get_errno(setdomainname(p, arg2));
6913
        unlock_user(p, arg1, 0);
6914
        break;
6915
    case TARGET_NR_uname:
6916
        /* no need to transcode because we use the linux syscall */
6917
        {
6918
            struct new_utsname * buf;
6919

    
6920
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
6921
                goto efault;
6922
            ret = get_errno(sys_uname(buf));
6923
            if (!is_error(ret)) {
6924
                /* Overrite the native machine name with whatever is being
6925
                   emulated. */
6926
                strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
6927
                /* Allow the user to override the reported release.  */
6928
                if (qemu_uname_release && *qemu_uname_release)
6929
                  strcpy (buf->release, qemu_uname_release);
6930
            }
6931
            unlock_user_struct(buf, arg1, 1);
6932
        }
6933
        break;
6934
#ifdef TARGET_I386
6935
    case TARGET_NR_modify_ldt:
6936
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
6937
        break;
6938
#if !defined(TARGET_X86_64)
6939
    case TARGET_NR_vm86old:
6940
        goto unimplemented;
6941
    case TARGET_NR_vm86:
6942
        ret = do_vm86(cpu_env, arg1, arg2);
6943
        break;
6944
#endif
6945
#endif
6946
    case TARGET_NR_adjtimex:
6947
        goto unimplemented;
6948
#ifdef TARGET_NR_create_module
6949
    case TARGET_NR_create_module:
6950
#endif
6951
    case TARGET_NR_init_module:
6952
    case TARGET_NR_delete_module:
6953
#ifdef TARGET_NR_get_kernel_syms
6954
    case TARGET_NR_get_kernel_syms:
6955
#endif
6956
        goto unimplemented;
6957
    case TARGET_NR_quotactl:
6958
        goto unimplemented;
6959
    case TARGET_NR_getpgid:
6960
        ret = get_errno(getpgid(arg1));
6961
        break;
6962
    case TARGET_NR_fchdir:
6963
        ret = get_errno(fchdir(arg1));
6964
        break;
6965
#ifdef TARGET_NR_bdflush /* not on x86_64 */
6966
    case TARGET_NR_bdflush:
6967
        goto unimplemented;
6968
#endif
6969
#ifdef TARGET_NR_sysfs
6970
    case TARGET_NR_sysfs:
6971
        goto unimplemented;
6972
#endif
6973
    case TARGET_NR_personality:
6974
        ret = get_errno(personality(arg1));
6975
        break;
6976
#ifdef TARGET_NR_afs_syscall
6977
    case TARGET_NR_afs_syscall:
6978
        goto unimplemented;
6979
#endif
6980
#ifdef TARGET_NR__llseek /* Not on alpha */
6981
    case TARGET_NR__llseek:
6982
        {
6983
            int64_t res;
6984
#if !defined(__NR_llseek)
6985
            res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
6986
            if (res == -1) {
6987
                ret = get_errno(res);
6988
            } else {
6989
                ret = 0;
6990
            }
6991
#else
6992
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
6993
#endif
6994
            if ((ret == 0) && put_user_s64(res, arg4)) {
6995
                goto efault;
6996
            }
6997
        }
6998
        break;
6999
#endif
7000
    case TARGET_NR_getdents:
7001
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
7002
        {
7003
            struct target_dirent *target_dirp;
7004
            struct linux_dirent *dirp;
7005
            abi_long count = arg3;
7006

    
7007
            dirp = malloc(count);
7008
            if (!dirp) {
7009
                ret = -TARGET_ENOMEM;
7010
                goto fail;
7011
            }
7012

    
7013
            ret = get_errno(sys_getdents(arg1, dirp, count));
7014
            if (!is_error(ret)) {
7015
                struct linux_dirent *de;
7016
                struct target_dirent *tde;
7017
                int len = ret;
7018
                int reclen, treclen;
7019
                int count1, tnamelen;
7020

    
7021
                count1 = 0;
7022
                de = dirp;
7023
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7024
                    goto efault;
7025
                tde = target_dirp;
7026
                while (len > 0) {
7027
                    reclen = de->d_reclen;
7028
                    tnamelen = reclen - offsetof(struct linux_dirent, d_name);
7029
                    assert(tnamelen >= 0);
7030
                    treclen = tnamelen + offsetof(struct target_dirent, d_name);
7031
                    assert(count1 + treclen <= count);
7032
                    tde->d_reclen = tswap16(treclen);
7033
                    tde->d_ino = tswapal(de->d_ino);
7034
                    tde->d_off = tswapal(de->d_off);
7035
                    memcpy(tde->d_name, de->d_name, tnamelen);
7036
                    de = (struct linux_dirent *)((char *)de + reclen);
7037
                    len -= reclen;
7038
                    tde = (struct target_dirent *)((char *)tde + treclen);
7039
                    count1 += treclen;
7040
                }
7041
                ret = count1;
7042
                unlock_user(target_dirp, arg2, ret);
7043
            }
7044
            free(dirp);
7045
        }
7046
#else
7047
        {
7048
            struct linux_dirent *dirp;
7049
            abi_long count = arg3;
7050

    
7051
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7052
                goto efault;
7053
            ret = get_errno(sys_getdents(arg1, dirp, count));
7054
            if (!is_error(ret)) {
7055
                struct linux_dirent *de;
7056
                int len = ret;
7057
                int reclen;
7058
                de = dirp;
7059
                while (len > 0) {
7060
                    reclen = de->d_reclen;
7061
                    if (reclen > len)
7062
                        break;
7063
                    de->d_reclen = tswap16(reclen);
7064
                    tswapls(&de->d_ino);
7065
                    tswapls(&de->d_off);
7066
                    de = (struct linux_dirent *)((char *)de + reclen);
7067
                    len -= reclen;
7068
                }
7069
            }
7070
            unlock_user(dirp, arg2, ret);
7071
        }
7072
#endif
7073
        break;
7074
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7075
    case TARGET_NR_getdents64:
7076
        {
7077
            struct linux_dirent64 *dirp;
7078
            abi_long count = arg3;
7079
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7080
                goto efault;
7081
            ret = get_errno(sys_getdents64(arg1, dirp, count));
7082
            if (!is_error(ret)) {
7083
                struct linux_dirent64 *de;
7084
                int len = ret;
7085
                int reclen;
7086
                de = dirp;
7087
                while (len > 0) {
7088
                    reclen = de->d_reclen;
7089
                    if (reclen > len)
7090
                        break;
7091
                    de->d_reclen = tswap16(reclen);
7092
                    tswap64s((uint64_t *)&de->d_ino);
7093
                    tswap64s((uint64_t *)&de->d_off);
7094
                    de = (struct linux_dirent64 *)((char *)de + reclen);
7095
                    len -= reclen;
7096
                }
7097
            }
7098
            unlock_user(dirp, arg2, ret);
7099
        }
7100
        break;
7101
#endif /* TARGET_NR_getdents64 */
7102
#if defined(TARGET_NR__newselect) || defined(TARGET_S390X)
7103
#ifdef TARGET_S390X
7104
    case TARGET_NR_select:
7105
#else
7106
    case TARGET_NR__newselect:
7107
#endif
7108
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
7109
        break;
7110
#endif
7111
#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7112
# ifdef TARGET_NR_poll
7113
    case TARGET_NR_poll:
7114
# endif
7115
# ifdef TARGET_NR_ppoll
7116
    case TARGET_NR_ppoll:
7117
# endif
7118
        {
7119
            struct target_pollfd *target_pfd;
7120
            unsigned int nfds = arg2;
7121
            int timeout = arg3;
7122
            struct pollfd *pfd;
7123
            unsigned int i;
7124

    
7125
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
7126
            if (!target_pfd)
7127
                goto efault;
7128

    
7129
            pfd = alloca(sizeof(struct pollfd) * nfds);
7130
            for(i = 0; i < nfds; i++) {
7131
                pfd[i].fd = tswap32(target_pfd[i].fd);
7132
                pfd[i].events = tswap16(target_pfd[i].events);
7133
            }
7134

    
7135
# ifdef TARGET_NR_ppoll
7136
            if (num == TARGET_NR_ppoll) {
7137
                struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
7138
                target_sigset_t *target_set;
7139
                sigset_t _set, *set = &_set;
7140

    
7141
                if (arg3) {
7142
                    if (target_to_host_timespec(timeout_ts, arg3)) {
7143
                        unlock_user(target_pfd, arg1, 0);
7144
                        goto efault;
7145
                    }
7146
                } else {
7147
                    timeout_ts = NULL;
7148
                }
7149

    
7150
                if (arg4) {
7151
                    target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
7152
                    if (!target_set) {
7153
                        unlock_user(target_pfd, arg1, 0);
7154
                        goto efault;
7155
                    }
7156
                    target_to_host_sigset(set, target_set);
7157
                } else {
7158
                    set = NULL;
7159
                }
7160

    
7161
                ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
7162

    
7163
                if (!is_error(ret) && arg3) {
7164
                    host_to_target_timespec(arg3, timeout_ts);
7165
                }
7166
                if (arg4) {
7167
                    unlock_user(target_set, arg4, 0);
7168
                }
7169
            } else
7170
# endif
7171
                ret = get_errno(poll(pfd, nfds, timeout));
7172

    
7173
            if (!is_error(ret)) {
7174
                for(i = 0; i < nfds; i++) {
7175
                    target_pfd[i].revents = tswap16(pfd[i].revents);
7176
                }
7177
            }
7178
            unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
7179
        }
7180
        break;
7181
#endif
7182
    case TARGET_NR_flock:
7183
        /* NOTE: the flock constant seems to be the same for every
7184
           Linux platform */
7185
        ret = get_errno(flock(arg1, arg2));
7186
        break;
7187
    case TARGET_NR_readv:
7188
        {
7189
            int count = arg3;
7190
            struct iovec *vec;
7191

    
7192
            vec = alloca(count * sizeof(struct iovec));
7193
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
7194
                goto efault;
7195
            ret = get_errno(readv(arg1, vec, count));
7196
            unlock_iovec(vec, arg2, count, 1);
7197
        }
7198
        break;
7199
    case TARGET_NR_writev:
7200
        {
7201
            int count = arg3;
7202
            struct iovec *vec;
7203

    
7204
            vec = alloca(count * sizeof(struct iovec));
7205
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
7206
                goto efault;
7207
            ret = get_errno(writev(arg1, vec, count));
7208
            unlock_iovec(vec, arg2, count, 0);
7209
        }
7210
        break;
7211
    case TARGET_NR_getsid:
7212
        ret = get_errno(getsid(arg1));
7213
        break;
7214
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
7215
    case TARGET_NR_fdatasync:
7216
        ret = get_errno(fdatasync(arg1));
7217
        break;
7218
#endif
7219
    case TARGET_NR__sysctl:
7220
        /* We don't implement this, but ENOTDIR is always a safe
7221
           return value. */
7222
        ret = -TARGET_ENOTDIR;
7223
        break;
7224
    case TARGET_NR_sched_getaffinity:
7225
        {
7226
            unsigned int mask_size;
7227
            unsigned long *mask;
7228

    
7229
            /*
7230
             * sched_getaffinity needs multiples of ulong, so need to take
7231
             * care of mismatches between target ulong and host ulong sizes.
7232
             */
7233
            if (arg2 & (sizeof(abi_ulong) - 1)) {
7234
                ret = -TARGET_EINVAL;
7235
                break;
7236
            }
7237
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7238

    
7239
            mask = alloca(mask_size);
7240
            ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
7241

    
7242
            if (!is_error(ret)) {
7243
                if (copy_to_user(arg3, mask, ret)) {
7244
                    goto efault;
7245
                }
7246
            }
7247
        }
7248
        break;
7249
    case TARGET_NR_sched_setaffinity:
7250
        {
7251
            unsigned int mask_size;
7252
            unsigned long *mask;
7253

    
7254
            /*
7255
             * sched_setaffinity needs multiples of ulong, so need to take
7256
             * care of mismatches between target ulong and host ulong sizes.
7257
             */
7258
            if (arg2 & (sizeof(abi_ulong) - 1)) {
7259
                ret = -TARGET_EINVAL;
7260
                break;
7261
            }
7262
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7263

    
7264
            mask = alloca(mask_size);
7265
            if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
7266
                goto efault;
7267
            }
7268
            memcpy(mask, p, arg2);
7269
            unlock_user_struct(p, arg2, 0);
7270

    
7271
            ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
7272
        }
7273
        break;
7274
    case TARGET_NR_sched_setparam:
7275
        {
7276
            struct sched_param *target_schp;
7277
            struct sched_param schp;
7278

    
7279
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
7280
                goto efault;
7281
            schp.sched_priority = tswap32(target_schp->sched_priority);
7282
            unlock_user_struct(target_schp, arg2, 0);
7283
            ret = get_errno(sched_setparam(arg1, &schp));
7284
        }
7285
        break;
7286
    case TARGET_NR_sched_getparam:
7287
        {
7288
            struct sched_param *target_schp;
7289
            struct sched_param schp;
7290
            ret = get_errno(sched_getparam(arg1, &schp));
7291
            if (!is_error(ret)) {
7292
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
7293
                    goto efault;
7294
                target_schp->sched_priority = tswap32(schp.sched_priority);
7295
                unlock_user_struct(target_schp, arg2, 1);
7296
            }
7297
        }
7298
        break;
7299
    case TARGET_NR_sched_setscheduler:
7300
        {
7301
            struct sched_param *target_schp;
7302
            struct sched_param schp;
7303
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
7304
                goto efault;
7305
            schp.sched_priority = tswap32(target_schp->sched_priority);
7306
            unlock_user_struct(target_schp, arg3, 0);
7307
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
7308
        }
7309
        break;
7310
    case TARGET_NR_sched_getscheduler:
7311
        ret = get_errno(sched_getscheduler(arg1));
7312
        break;
7313
    case TARGET_NR_sched_yield:
7314
        ret = get_errno(sched_yield());
7315
        break;
7316
    case TARGET_NR_sched_get_priority_max:
7317
        ret = get_errno(sched_get_priority_max(arg1));
7318
        break;
7319
    case TARGET_NR_sched_get_priority_min:
7320
        ret = get_errno(sched_get_priority_min(arg1));
7321
        break;
7322
    case TARGET_NR_sched_rr_get_interval:
7323
        {
7324
            struct timespec ts;
7325
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
7326
            if (!is_error(ret)) {
7327
                host_to_target_timespec(arg2, &ts);
7328
            }
7329
        }
7330
        break;
7331
    case TARGET_NR_nanosleep:
7332
        {
7333
            struct timespec req, rem;
7334
            target_to_host_timespec(&req, arg1);
7335
            ret = get_errno(nanosleep(&req, &rem));
7336
            if (is_error(ret) && arg2) {
7337
                host_to_target_timespec(arg2, &rem);
7338
            }
7339
        }
7340
        break;
7341
#ifdef TARGET_NR_query_module
7342
    case TARGET_NR_query_module:
7343
        goto unimplemented;
7344
#endif
7345
#ifdef TARGET_NR_nfsservctl
7346
    case TARGET_NR_nfsservctl:
7347
        goto unimplemented;
7348
#endif
7349
    case TARGET_NR_prctl:
7350
        switch (arg1) {
7351
        case PR_GET_PDEATHSIG:
7352
        {
7353
            int deathsig;
7354
            ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
7355
            if (!is_error(ret) && arg2
7356
                && put_user_ual(deathsig, arg2)) {
7357
                goto efault;
7358
            }
7359
            break;
7360
        }
7361
#ifdef PR_GET_NAME
7362
        case PR_GET_NAME:
7363
        {
7364
            void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
7365
            if (!name) {
7366
                goto efault;
7367
            }
7368
            ret = get_errno(prctl(arg1, (unsigned long)name,
7369
                                  arg3, arg4, arg5));
7370
            unlock_user(name, arg2, 16);
7371
            break;
7372
        }
7373
        case PR_SET_NAME:
7374
        {
7375
            void *name = lock_user(VERIFY_READ, arg2, 16, 1);
7376
            if (!name) {
7377
                goto efault;
7378
            }
7379
            ret = get_errno(prctl(arg1, (unsigned long)name,
7380
                                  arg3, arg4, arg5));
7381
            unlock_user(name, arg2, 0);
7382
            break;
7383
        }
7384
#endif
7385
        default:
7386
            /* Most prctl options have no pointer arguments */
7387
            ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
7388
            break;
7389
        }
7390
        break;
7391
#ifdef TARGET_NR_arch_prctl
7392
    case TARGET_NR_arch_prctl:
7393
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
7394
        ret = do_arch_prctl(cpu_env, arg1, arg2);
7395
        break;
7396
#else
7397
        goto unimplemented;
7398
#endif
7399
#endif
7400
#ifdef TARGET_NR_pread
7401
    case TARGET_NR_pread:
7402
        if (regpairs_aligned(cpu_env))
7403
            arg4 = arg5;
7404
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
7405
            goto efault;
7406
        ret = get_errno(pread(arg1, p, arg3, arg4));
7407
        unlock_user(p, arg2, ret);
7408
        break;
7409
    case TARGET_NR_pwrite:
7410
        if (regpairs_aligned(cpu_env))
7411
            arg4 = arg5;
7412
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
7413
            goto efault;
7414
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
7415
        unlock_user(p, arg2, 0);
7416
        break;
7417
#endif
7418
#ifdef TARGET_NR_pread64
7419
    case TARGET_NR_pread64:
7420
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
7421
            goto efault;
7422
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
7423
        unlock_user(p, arg2, ret);
7424
        break;
7425
    case TARGET_NR_pwrite64:
7426
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
7427
            goto efault;
7428
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
7429
        unlock_user(p, arg2, 0);
7430
        break;
7431
#endif
7432
    case TARGET_NR_getcwd:
7433
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
7434
            goto efault;
7435
        ret = get_errno(sys_getcwd1(p, arg2));
7436
        unlock_user(p, arg1, ret);
7437
        break;
7438
    case TARGET_NR_capget:
7439
        goto unimplemented;
7440
    case TARGET_NR_capset:
7441
        goto unimplemented;
7442
    case TARGET_NR_sigaltstack:
7443
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
7444
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
7445
    defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
7446
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
7447
        break;
7448
#else
7449
        goto unimplemented;
7450
#endif
7451
    case TARGET_NR_sendfile:
7452
        goto unimplemented;
7453
#ifdef TARGET_NR_getpmsg
7454
    case TARGET_NR_getpmsg:
7455
        goto unimplemented;
7456
#endif
7457
#ifdef TARGET_NR_putpmsg
7458
    case TARGET_NR_putpmsg:
7459
        goto unimplemented;
7460
#endif
7461
#ifdef TARGET_NR_vfork
7462
    case TARGET_NR_vfork:
7463
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
7464
                        0, 0, 0, 0));
7465
        break;
7466
#endif
7467
#ifdef TARGET_NR_ugetrlimit
7468
    case TARGET_NR_ugetrlimit:
7469
    {
7470
        struct rlimit rlim;
7471
        int resource = target_to_host_resource(arg1);
7472
        ret = get_errno(getrlimit(resource, &rlim));
7473
        if (!is_error(ret)) {
7474
            struct target_rlimit *target_rlim;
7475
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
7476
                goto efault;
7477
            target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
7478
            target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
7479
            unlock_user_struct(target_rlim, arg2, 1);
7480
        }
7481
        break;
7482
    }
7483
#endif
7484
#ifdef TARGET_NR_truncate64
7485
    case TARGET_NR_truncate64:
7486
        if (!(p = lock_user_string(arg1)))
7487
            goto efault;
7488
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
7489
        unlock_user(p, arg1, 0);
7490
        break;
7491
#endif
7492
#ifdef TARGET_NR_ftruncate64
7493
    case TARGET_NR_ftruncate64:
7494
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
7495
        break;
7496
#endif
7497
#ifdef TARGET_NR_stat64
7498
    case TARGET_NR_stat64:
7499
        if (!(p = lock_user_string(arg1)))
7500
            goto efault;
7501
        ret = get_errno(stat(path(p), &st));
7502
        unlock_user(p, arg1, 0);
7503
        if (!is_error(ret))
7504
            ret = host_to_target_stat64(cpu_env, arg2, &st);
7505
        break;
7506
#endif
7507
#ifdef TARGET_NR_lstat64
7508
    case TARGET_NR_lstat64:
7509
        if (!(p = lock_user_string(arg1)))
7510
            goto efault;
7511
        ret = get_errno(lstat(path(p), &st));
7512
        unlock_user(p, arg1, 0);
7513
        if (!is_error(ret))
7514
            ret = host_to_target_stat64(cpu_env, arg2, &st);
7515
        break;
7516
#endif
7517
#ifdef TARGET_NR_fstat64
7518
    case TARGET_NR_fstat64:
7519
        ret = get_errno(fstat(arg1, &st));
7520
        if (!is_error(ret))
7521
            ret = host_to_target_stat64(cpu_env, arg2, &st);
7522
        break;
7523
#endif
7524
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
7525
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
7526
#ifdef TARGET_NR_fstatat64
7527
    case TARGET_NR_fstatat64:
7528
#endif
7529
#ifdef TARGET_NR_newfstatat
7530
    case TARGET_NR_newfstatat:
7531
#endif
7532
        if (!(p = lock_user_string(arg2)))
7533
            goto efault;
7534
#ifdef __NR_fstatat64
7535
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
7536
#else
7537
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
7538
#endif
7539
        if (!is_error(ret))
7540
            ret = host_to_target_stat64(cpu_env, arg3, &st);
7541
        break;
7542
#endif
7543
    case TARGET_NR_lchown:
7544
        if (!(p = lock_user_string(arg1)))
7545
            goto efault;
7546
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
7547
        unlock_user(p, arg1, 0);
7548
        break;
7549
#ifdef TARGET_NR_getuid
7550
    case TARGET_NR_getuid:
7551
        ret = get_errno(high2lowuid(getuid()));
7552
        break;
7553
#endif
7554
#ifdef TARGET_NR_getgid
7555
    case TARGET_NR_getgid:
7556
        ret = get_errno(high2lowgid(getgid()));
7557
        break;
7558
#endif
7559
#ifdef TARGET_NR_geteuid
7560
    case TARGET_NR_geteuid:
7561
        ret = get_errno(high2lowuid(geteuid()));
7562
        break;
7563
#endif
7564
#ifdef TARGET_NR_getegid
7565
    case TARGET_NR_getegid:
7566
        ret = get_errno(high2lowgid(getegid()));
7567
        break;
7568
#endif
7569
    case TARGET_NR_setreuid:
7570
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
7571
        break;
7572
    case TARGET_NR_setregid:
7573
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
7574
        break;
7575
    case TARGET_NR_getgroups:
7576
        {
7577
            int gidsetsize = arg1;
7578
            target_id *target_grouplist;
7579
            gid_t *grouplist;
7580
            int i;
7581

    
7582
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7583
            ret = get_errno(getgroups(gidsetsize, grouplist));
7584
            if (gidsetsize == 0)
7585
                break;
7586
            if (!is_error(ret)) {
7587
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
7588
                if (!target_grouplist)
7589
                    goto efault;
7590
                for(i = 0;i < ret; i++)
7591
                    target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
7592
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
7593
            }
7594
        }
7595
        break;
7596
    case TARGET_NR_setgroups:
7597
        {
7598
            int gidsetsize = arg1;
7599
            target_id *target_grouplist;
7600
            gid_t *grouplist;
7601
            int i;
7602

    
7603
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7604
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
7605
            if (!target_grouplist) {
7606
                ret = -TARGET_EFAULT;
7607
                goto fail;
7608
            }
7609
            for(i = 0;i < gidsetsize; i++)
7610
                grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
7611
            unlock_user(target_grouplist, arg2, 0);
7612
            ret = get_errno(setgroups(gidsetsize, grouplist));
7613
        }
7614
        break;
7615
    case TARGET_NR_fchown:
7616
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
7617
        break;
7618
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
7619
    case TARGET_NR_fchownat:
7620
        if (!(p = lock_user_string(arg2))) 
7621
            goto efault;
7622
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
7623
        unlock_user(p, arg2, 0);
7624
        break;
7625
#endif
7626
#ifdef TARGET_NR_setresuid
7627
    case TARGET_NR_setresuid:
7628
        ret = get_errno(setresuid(low2highuid(arg1),
7629
                                  low2highuid(arg2),
7630
                                  low2highuid(arg3)));
7631
        break;
7632
#endif
7633
#ifdef TARGET_NR_getresuid
7634
    case TARGET_NR_getresuid:
7635
        {
7636
            uid_t ruid, euid, suid;
7637
            ret = get_errno(getresuid(&ruid, &euid, &suid));
7638
            if (!is_error(ret)) {
7639
                if (put_user_u16(high2lowuid(ruid), arg1)
7640
                    || put_user_u16(high2lowuid(euid), arg2)
7641
                    || put_user_u16(high2lowuid(suid), arg3))
7642
                    goto efault;
7643
            }
7644
        }
7645
        break;
7646
#endif
7647
#ifdef TARGET_NR_getresgid
7648
    case TARGET_NR_setresgid:
7649
        ret = get_errno(setresgid(low2highgid(arg1),
7650
                                  low2highgid(arg2),
7651
                                  low2highgid(arg3)));
7652
        break;
7653
#endif
7654
#ifdef TARGET_NR_getresgid
7655
    case TARGET_NR_getresgid:
7656
        {
7657
            gid_t rgid, egid, sgid;
7658
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
7659
            if (!is_error(ret)) {
7660
                if (put_user_u16(high2lowgid(rgid), arg1)
7661
                    || put_user_u16(high2lowgid(egid), arg2)
7662
                    || put_user_u16(high2lowgid(sgid), arg3))
7663
                    goto efault;
7664
            }
7665
        }
7666
        break;
7667
#endif
7668
    case TARGET_NR_chown:
7669
        if (!(p = lock_user_string(arg1)))
7670
            goto efault;
7671
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
7672
        unlock_user(p, arg1, 0);
7673
        break;
7674
    case TARGET_NR_setuid:
7675
        ret = get_errno(setuid(low2highuid(arg1)));
7676
        break;
7677
    case TARGET_NR_setgid:
7678
        ret = get_errno(setgid(low2highgid(arg1)));
7679
        break;
7680
    case TARGET_NR_setfsuid:
7681
        ret = get_errno(setfsuid(arg1));
7682
        break;
7683
    case TARGET_NR_setfsgid:
7684
        ret = get_errno(setfsgid(arg1));
7685
        break;
7686

    
7687
#ifdef TARGET_NR_lchown32
7688
    case TARGET_NR_lchown32:
7689
        if (!(p = lock_user_string(arg1)))
7690
            goto efault;
7691
        ret = get_errno(lchown(p, arg2, arg3));
7692
        unlock_user(p, arg1, 0);
7693
        break;
7694
#endif
7695
#ifdef TARGET_NR_getuid32
7696
    case TARGET_NR_getuid32:
7697
        ret = get_errno(getuid());
7698
        break;
7699
#endif
7700

    
7701
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7702
   /* Alpha specific */
7703
    case TARGET_NR_getxuid:
7704
         {
7705
            uid_t euid;
7706
            euid=geteuid();
7707
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
7708
         }
7709
        ret = get_errno(getuid());
7710
        break;
7711
#endif
7712
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
7713
   /* Alpha specific */
7714
    case TARGET_NR_getxgid:
7715
         {
7716
            uid_t egid;
7717
            egid=getegid();
7718
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
7719
         }
7720
        ret = get_errno(getgid());
7721
        break;
7722
#endif
7723
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
7724
    /* Alpha specific */
7725
    case TARGET_NR_osf_getsysinfo:
7726
        ret = -TARGET_EOPNOTSUPP;
7727
        switch (arg1) {
7728
          case TARGET_GSI_IEEE_FP_CONTROL:
7729
            {
7730
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
7731

    
7732
                /* Copied from linux ieee_fpcr_to_swcr.  */
7733
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
7734
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
7735
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
7736
                                        | SWCR_TRAP_ENABLE_DZE
7737
                                        | SWCR_TRAP_ENABLE_OVF);
7738
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
7739
                                        | SWCR_TRAP_ENABLE_INE);
7740
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
7741
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
7742

    
7743
                if (put_user_u64 (swcr, arg2))
7744
                        goto efault;
7745
                ret = 0;
7746
            }
7747
            break;
7748

    
7749
          /* case GSI_IEEE_STATE_AT_SIGNAL:
7750
             -- Not implemented in linux kernel.
7751
             case GSI_UACPROC:
7752
             -- Retrieves current unaligned access state; not much used.
7753
             case GSI_PROC_TYPE:
7754
             -- Retrieves implver information; surely not used.
7755
             case GSI_GET_HWRPB:
7756
             -- Grabs a copy of the HWRPB; surely not used.
7757
          */
7758
        }
7759
        break;
7760
#endif
7761
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
7762
    /* Alpha specific */
7763
    case TARGET_NR_osf_setsysinfo:
7764
        ret = -TARGET_EOPNOTSUPP;
7765
        switch (arg1) {
7766
          case TARGET_SSI_IEEE_FP_CONTROL:
7767
            {
7768
                uint64_t swcr, fpcr, orig_fpcr;
7769

    
7770
                if (get_user_u64 (swcr, arg2)) {
7771
                    goto efault;
7772
                }
7773
                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
7774
                fpcr = orig_fpcr & FPCR_DYN_MASK;
7775

    
7776
                /* Copied from linux ieee_swcr_to_fpcr.  */
7777
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
7778
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
7779
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
7780
                                  | SWCR_TRAP_ENABLE_DZE
7781
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
7782
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
7783
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
7784
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
7785
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
7786

    
7787
                cpu_alpha_store_fpcr(cpu_env, fpcr);
7788
                ret = 0;
7789
            }
7790
            break;
7791

    
7792
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
7793
            {
7794
                uint64_t exc, fpcr, orig_fpcr;
7795
                int si_code;
7796

    
7797
                if (get_user_u64(exc, arg2)) {
7798
                    goto efault;
7799
                }
7800

    
7801
                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
7802

    
7803
                /* We only add to the exception status here.  */
7804
                fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35);
7805

    
7806
                cpu_alpha_store_fpcr(cpu_env, fpcr);
7807
                ret = 0;
7808

    
7809
                /* Old exceptions are not signaled.  */
7810
                fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
7811

    
7812
                /* If any exceptions set by this call,
7813
                   and are unmasked, send a signal.  */
7814
                si_code = 0;
7815
                if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) {
7816
                    si_code = TARGET_FPE_FLTRES;
7817
                }
7818
                if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) {
7819
                    si_code = TARGET_FPE_FLTUND;
7820
                }
7821
                if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) {
7822
                    si_code = TARGET_FPE_FLTOVF;
7823
                }
7824
                if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) {
7825
                    si_code = TARGET_FPE_FLTDIV;
7826
                }
7827
                if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) {
7828
                    si_code = TARGET_FPE_FLTINV;
7829
                }
7830
                if (si_code != 0) {
7831
                    target_siginfo_t info;
7832
                    info.si_signo = SIGFPE;
7833
                    info.si_errno = 0;
7834
                    info.si_code = si_code;
7835
                    info._sifields._sigfault._addr
7836
                        = ((CPUArchState *)cpu_env)->pc;
7837
                    queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
7838
                }
7839
            }
7840
            break;
7841

    
7842
          /* case SSI_NVPAIRS:
7843
             -- Used with SSIN_UACPROC to enable unaligned accesses.
7844
             case SSI_IEEE_STATE_AT_SIGNAL:
7845
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
7846
             -- Not implemented in linux kernel
7847
          */
7848
        }
7849
        break;
7850
#endif
7851
#ifdef TARGET_NR_osf_sigprocmask
7852
    /* Alpha specific.  */
7853
    case TARGET_NR_osf_sigprocmask:
7854
        {
7855
            abi_ulong mask;
7856
            int how;
7857
            sigset_t set, oldset;
7858

    
7859
            switch(arg1) {
7860
            case TARGET_SIG_BLOCK:
7861
                how = SIG_BLOCK;
7862
                break;
7863
            case TARGET_SIG_UNBLOCK:
7864
                how = SIG_UNBLOCK;
7865
                break;
7866
            case TARGET_SIG_SETMASK:
7867
                how = SIG_SETMASK;
7868
                break;
7869
            default:
7870
                ret = -TARGET_EINVAL;
7871
                goto fail;
7872
            }
7873
            mask = arg2;
7874
            target_to_host_old_sigset(&set, &mask);
7875
            sigprocmask(how, &set, &oldset);
7876
            host_to_target_old_sigset(&mask, &oldset);
7877
            ret = mask;
7878
        }
7879
        break;
7880
#endif
7881

    
7882
#ifdef TARGET_NR_getgid32
7883
    case TARGET_NR_getgid32:
7884
        ret = get_errno(getgid());
7885
        break;
7886
#endif
7887
#ifdef TARGET_NR_geteuid32
7888
    case TARGET_NR_geteuid32:
7889
        ret = get_errno(geteuid());
7890
        break;
7891
#endif
7892
#ifdef TARGET_NR_getegid32
7893
    case TARGET_NR_getegid32:
7894
        ret = get_errno(getegid());
7895
        break;
7896
#endif
7897
#ifdef TARGET_NR_setreuid32
7898
    case TARGET_NR_setreuid32:
7899
        ret = get_errno(setreuid(arg1, arg2));
7900
        break;
7901
#endif
7902
#ifdef TARGET_NR_setregid32
7903
    case TARGET_NR_setregid32:
7904
        ret = get_errno(setregid(arg1, arg2));
7905
        break;
7906
#endif
7907
#ifdef TARGET_NR_getgroups32
7908
    case TARGET_NR_getgroups32:
7909
        {
7910
            int gidsetsize = arg1;
7911
            uint32_t *target_grouplist;
7912
            gid_t *grouplist;
7913
            int i;
7914

    
7915
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7916
            ret = get_errno(getgroups(gidsetsize, grouplist));
7917
            if (gidsetsize == 0)
7918
                break;
7919
            if (!is_error(ret)) {
7920
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
7921
                if (!target_grouplist) {
7922
                    ret = -TARGET_EFAULT;
7923
                    goto fail;
7924
                }
7925
                for(i = 0;i < ret; i++)
7926
                    target_grouplist[i] = tswap32(grouplist[i]);
7927
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
7928
            }
7929
        }
7930
        break;
7931
#endif
7932
#ifdef TARGET_NR_setgroups32
7933
    case TARGET_NR_setgroups32:
7934
        {
7935
            int gidsetsize = arg1;
7936
            uint32_t *target_grouplist;
7937
            gid_t *grouplist;
7938
            int i;
7939

    
7940
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7941
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
7942
            if (!target_grouplist) {
7943
                ret = -TARGET_EFAULT;
7944
                goto fail;
7945
            }
7946
            for(i = 0;i < gidsetsize; i++)
7947
                grouplist[i] = tswap32(target_grouplist[i]);
7948
            unlock_user(target_grouplist, arg2, 0);
7949
            ret = get_errno(setgroups(gidsetsize, grouplist));
7950
        }
7951
        break;
7952
#endif
7953
#ifdef TARGET_NR_fchown32
7954
    case TARGET_NR_fchown32:
7955
        ret = get_errno(fchown(arg1, arg2, arg3));
7956
        break;
7957
#endif
7958
#ifdef TARGET_NR_setresuid32
7959
    case TARGET_NR_setresuid32:
7960
        ret = get_errno(setresuid(arg1, arg2, arg3));
7961
        break;
7962
#endif
7963
#ifdef TARGET_NR_getresuid32
7964
    case TARGET_NR_getresuid32:
7965
        {
7966
            uid_t ruid, euid, suid;
7967
            ret = get_errno(getresuid(&ruid, &euid, &suid));
7968
            if (!is_error(ret)) {
7969
                if (put_user_u32(ruid, arg1)
7970
                    || put_user_u32(euid, arg2)
7971
                    || put_user_u32(suid, arg3))
7972
                    goto efault;
7973
            }
7974
        }
7975
        break;
7976
#endif
7977
#ifdef TARGET_NR_setresgid32
7978
    case TARGET_NR_setresgid32:
7979
        ret = get_errno(setresgid(arg1, arg2, arg3));
7980
        break;
7981
#endif
7982
#ifdef TARGET_NR_getresgid32
7983
    case TARGET_NR_getresgid32:
7984
        {
7985
            gid_t rgid, egid, sgid;
7986
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
7987
            if (!is_error(ret)) {
7988
                if (put_user_u32(rgid, arg1)
7989
                    || put_user_u32(egid, arg2)
7990
                    || put_user_u32(sgid, arg3))
7991
                    goto efault;
7992
            }
7993
        }
7994
        break;
7995
#endif
7996
#ifdef TARGET_NR_chown32
7997
    case TARGET_NR_chown32:
7998
        if (!(p = lock_user_string(arg1)))
7999
            goto efault;
8000
        ret = get_errno(chown(p, arg2, arg3));
8001
        unlock_user(p, arg1, 0);
8002
        break;
8003
#endif
8004
#ifdef TARGET_NR_setuid32
8005
    case TARGET_NR_setuid32:
8006
        ret = get_errno(setuid(arg1));
8007
        break;
8008
#endif
8009
#ifdef TARGET_NR_setgid32
8010
    case TARGET_NR_setgid32:
8011
        ret = get_errno(setgid(arg1));
8012
        break;
8013
#endif
8014
#ifdef TARGET_NR_setfsuid32
8015
    case TARGET_NR_setfsuid32:
8016
        ret = get_errno(setfsuid(arg1));
8017
        break;
8018
#endif
8019
#ifdef TARGET_NR_setfsgid32
8020
    case TARGET_NR_setfsgid32:
8021
        ret = get_errno(setfsgid(arg1));
8022
        break;
8023
#endif
8024

    
8025
    case TARGET_NR_pivot_root:
8026
        goto unimplemented;
8027
#ifdef TARGET_NR_mincore
8028
    case TARGET_NR_mincore:
8029
        {
8030
            void *a;
8031
            ret = -TARGET_EFAULT;
8032
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
8033
                goto efault;
8034
            if (!(p = lock_user_string(arg3)))
8035
                goto mincore_fail;
8036
            ret = get_errno(mincore(a, arg2, p));
8037
            unlock_user(p, arg3, ret);
8038
            mincore_fail:
8039
            unlock_user(a, arg1, 0);
8040
        }
8041
        break;
8042
#endif
8043
#ifdef TARGET_NR_arm_fadvise64_64
8044
    case TARGET_NR_arm_fadvise64_64:
8045
        {
8046
                /*
8047
                 * arm_fadvise64_64 looks like fadvise64_64 but
8048
                 * with different argument order
8049
                 */
8050
                abi_long temp;
8051
                temp = arg3;
8052
                arg3 = arg4;
8053
                arg4 = temp;
8054
        }
8055
#endif
8056
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
8057
#ifdef TARGET_NR_fadvise64_64
8058
    case TARGET_NR_fadvise64_64:
8059
#endif
8060
#ifdef TARGET_NR_fadvise64
8061
    case TARGET_NR_fadvise64:
8062
#endif
8063
#ifdef TARGET_S390X
8064
        switch (arg4) {
8065
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
8066
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
8067
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
8068
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
8069
        default: break;
8070
        }
8071
#endif
8072
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
8073
        break;
8074
#endif
8075
#ifdef TARGET_NR_madvise
8076
    case TARGET_NR_madvise:
8077
        /* A straight passthrough may not be safe because qemu sometimes
8078
           turns private flie-backed mappings into anonymous mappings.
8079
           This will break MADV_DONTNEED.
8080
           This is a hint, so ignoring and returning success is ok.  */
8081
        ret = get_errno(0);
8082
        break;
8083
#endif
8084
#if TARGET_ABI_BITS == 32
8085
    case TARGET_NR_fcntl64:
8086
    {
8087
        int cmd;
8088
        struct flock64 fl;
8089
        struct target_flock64 *target_fl;
8090
#ifdef TARGET_ARM
8091
        struct target_eabi_flock64 *target_efl;
8092
#endif
8093

    
8094
        cmd = target_to_host_fcntl_cmd(arg2);
8095
        if (cmd == -TARGET_EINVAL) {
8096
            ret = cmd;
8097
            break;
8098
        }
8099

    
8100
        switch(arg2) {
8101
        case TARGET_F_GETLK64:
8102
#ifdef TARGET_ARM
8103
            if (((CPUARMState *)cpu_env)->eabi) {
8104
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
8105
                    goto efault;
8106
                fl.l_type = tswap16(target_efl->l_type);
8107
                fl.l_whence = tswap16(target_efl->l_whence);
8108
                fl.l_start = tswap64(target_efl->l_start);
8109
                fl.l_len = tswap64(target_efl->l_len);
8110
                fl.l_pid = tswap32(target_efl->l_pid);
8111
                unlock_user_struct(target_efl, arg3, 0);
8112
            } else
8113
#endif
8114
            {
8115
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
8116
                    goto efault;
8117
                fl.l_type = tswap16(target_fl->l_type);
8118
                fl.l_whence = tswap16(target_fl->l_whence);
8119
                fl.l_start = tswap64(target_fl->l_start);
8120
                fl.l_len = tswap64(target_fl->l_len);
8121
                fl.l_pid = tswap32(target_fl->l_pid);
8122
                unlock_user_struct(target_fl, arg3, 0);
8123
            }
8124
            ret = get_errno(fcntl(arg1, cmd, &fl));
8125
            if (ret == 0) {
8126
#ifdef TARGET_ARM
8127
                if (((CPUARMState *)cpu_env)->eabi) {
8128
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
8129
                        goto efault;
8130
                    target_efl->l_type = tswap16(fl.l_type);
8131
                    target_efl->l_whence = tswap16(fl.l_whence);
8132
                    target_efl->l_start = tswap64(fl.l_start);
8133
                    target_efl->l_len = tswap64(fl.l_len);
8134
                    target_efl->l_pid = tswap32(fl.l_pid);
8135
                    unlock_user_struct(target_efl, arg3, 1);
8136
                } else
8137
#endif
8138
                {
8139
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
8140
                        goto efault;
8141
                    target_fl->l_type = tswap16(fl.l_type);
8142
                    target_fl->l_whence = tswap16(fl.l_whence);
8143
                    target_fl->l_start = tswap64(fl.l_start);
8144
                    target_fl->l_len = tswap64(fl.l_len);
8145
                    target_fl->l_pid = tswap32(fl.l_pid);
8146
                    unlock_user_struct(target_fl, arg3, 1);
8147
                }
8148
            }
8149
            break;
8150

    
8151
        case TARGET_F_SETLK64:
8152
        case TARGET_F_SETLKW64:
8153
#ifdef TARGET_ARM
8154
            if (((CPUARMState *)cpu_env)->eabi) {
8155
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
8156
                    goto efault;
8157
                fl.l_type = tswap16(target_efl->l_type);
8158
                fl.l_whence = tswap16(target_efl->l_whence);
8159
                fl.l_start = tswap64(target_efl->l_start);
8160
                fl.l_len = tswap64(target_efl->l_len);
8161
                fl.l_pid = tswap32(target_efl->l_pid);
8162
                unlock_user_struct(target_efl, arg3, 0);
8163
            } else
8164
#endif
8165
            {
8166
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
8167
                    goto efault;
8168
                fl.l_type = tswap16(target_fl->l_type);
8169
                fl.l_whence = tswap16(target_fl->l_whence);
8170
                fl.l_start = tswap64(target_fl->l_start);
8171
                fl.l_len = tswap64(target_fl->l_len);
8172
                fl.l_pid = tswap32(target_fl->l_pid);
8173
                unlock_user_struct(target_fl, arg3, 0);
8174
            }
8175
            ret = get_errno(fcntl(arg1, cmd, &fl));
8176
            break;
8177
        default:
8178
            ret = do_fcntl(arg1, arg2, arg3);
8179
            break;
8180
        }
8181
        break;
8182
    }
8183
#endif
8184
#ifdef TARGET_NR_cacheflush
8185
    case TARGET_NR_cacheflush:
8186
        /* self-modifying code is handled automatically, so nothing needed */
8187
        ret = 0;
8188
        break;
8189
#endif
8190
#ifdef TARGET_NR_security
8191
    case TARGET_NR_security:
8192
        goto unimplemented;
8193
#endif
8194
#ifdef TARGET_NR_getpagesize
8195
    case TARGET_NR_getpagesize:
8196
        ret = TARGET_PAGE_SIZE;
8197
        break;
8198
#endif
8199
    case TARGET_NR_gettid:
8200
        ret = get_errno(gettid());
8201
        break;
8202
#ifdef TARGET_NR_readahead
8203
    case TARGET_NR_readahead:
8204
#if TARGET_ABI_BITS == 32
8205
        if (regpairs_aligned(cpu_env)) {
8206
            arg2 = arg3;
8207
            arg3 = arg4;
8208
            arg4 = arg5;
8209
        }
8210
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
8211
#else
8212
        ret = get_errno(readahead(arg1, arg2, arg3));
8213
#endif
8214
        break;
8215
#endif
8216
#ifdef CONFIG_ATTR
8217
#ifdef TARGET_NR_setxattr
8218
    case TARGET_NR_listxattr:
8219
    case TARGET_NR_llistxattr:
8220
    {
8221
        void *p, *b = 0;
8222
        if (arg2) {
8223
            b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8224
            if (!b) {
8225
                ret = -TARGET_EFAULT;
8226
                break;
8227
            }
8228
        }
8229
        p = lock_user_string(arg1);
8230
        if (p) {
8231
            if (num == TARGET_NR_listxattr) {
8232
                ret = get_errno(listxattr(p, b, arg3));
8233
            } else {
8234
                ret = get_errno(llistxattr(p, b, arg3));
8235
            }
8236
        } else {
8237
            ret = -TARGET_EFAULT;
8238
        }
8239
        unlock_user(p, arg1, 0);
8240
        unlock_user(b, arg2, arg3);
8241
        break;
8242
    }
8243
    case TARGET_NR_flistxattr:
8244
    {
8245
        void *b = 0;
8246
        if (arg2) {
8247
            b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8248
            if (!b) {
8249
                ret = -TARGET_EFAULT;
8250
                break;
8251
            }
8252
        }
8253
        ret = get_errno(flistxattr(arg1, b, arg3));
8254
        unlock_user(b, arg2, arg3);
8255
        break;
8256
    }
8257
    case TARGET_NR_setxattr:
8258
    case TARGET_NR_lsetxattr:
8259
        {
8260
            void *p, *n, *v = 0;
8261
            if (arg3) {
8262
                v = lock_user(VERIFY_READ, arg3, arg4, 1);
8263
                if (!v) {
8264
                    ret = -TARGET_EFAULT;
8265
                    break;
8266
                }
8267
            }
8268
            p = lock_user_string(arg1);
8269
            n = lock_user_string(arg2);
8270
            if (p && n) {
8271
                if (num == TARGET_NR_setxattr) {
8272
                    ret = get_errno(setxattr(p, n, v, arg4, arg5));
8273
                } else {
8274
                    ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
8275
                }
8276
            } else {
8277
                ret = -TARGET_EFAULT;
8278
            }
8279
            unlock_user(p, arg1, 0);
8280
            unlock_user(n, arg2, 0);
8281
            unlock_user(v, arg3, 0);
8282
        }
8283
        break;
8284
    case TARGET_NR_fsetxattr:
8285
        {
8286
            void *n, *v = 0;
8287
            if (arg3) {
8288
                v = lock_user(VERIFY_READ, arg3, arg4, 1);
8289
                if (!v) {
8290
                    ret = -TARGET_EFAULT;
8291
                    break;
8292
                }
8293
            }
8294
            n = lock_user_string(arg2);
8295
            if (n) {
8296
                ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
8297
            } else {
8298
                ret = -TARGET_EFAULT;
8299
            }
8300
            unlock_user(n, arg2, 0);
8301
            unlock_user(v, arg3, 0);
8302
        }
8303
        break;
8304
    case TARGET_NR_getxattr:
8305
    case TARGET_NR_lgetxattr:
8306
        {
8307
            void *p, *n, *v = 0;
8308
            if (arg3) {
8309
                v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8310
                if (!v) {
8311
                    ret = -TARGET_EFAULT;
8312
                    break;
8313
                }
8314
            }
8315
            p = lock_user_string(arg1);
8316
            n = lock_user_string(arg2);
8317
            if (p && n) {
8318
                if (num == TARGET_NR_getxattr) {
8319
                    ret = get_errno(getxattr(p, n, v, arg4));
8320
                } else {
8321
                    ret = get_errno(lgetxattr(p, n, v, arg4));
8322
                }
8323
            } else {
8324
                ret = -TARGET_EFAULT;
8325
            }
8326
            unlock_user(p, arg1, 0);
8327
            unlock_user(n, arg2, 0);
8328
            unlock_user(v, arg3, arg4);
8329
        }
8330
        break;
8331
    case TARGET_NR_fgetxattr:
8332
        {
8333
            void *n, *v = 0;
8334
            if (arg3) {
8335
                v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8336
                if (!v) {
8337
                    ret = -TARGET_EFAULT;
8338
                    break;
8339
                }
8340
            }
8341
            n = lock_user_string(arg2);
8342
            if (n) {
8343
                ret = get_errno(fgetxattr(arg1, n, v, arg4));
8344
            } else {
8345
                ret = -TARGET_EFAULT;
8346
            }
8347
            unlock_user(n, arg2, 0);
8348
            unlock_user(v, arg3, arg4);
8349
        }
8350
        break;
8351
    case TARGET_NR_removexattr:
8352
    case TARGET_NR_lremovexattr:
8353
        {
8354
            void *p, *n;
8355
            p = lock_user_string(arg1);
8356
            n = lock_user_string(arg2);
8357
            if (p && n) {
8358
                if (num == TARGET_NR_removexattr) {
8359
                    ret = get_errno(removexattr(p, n));
8360
                } else {
8361
                    ret = get_errno(lremovexattr(p, n));
8362
                }
8363
            } else {
8364
                ret = -TARGET_EFAULT;
8365
            }
8366
            unlock_user(p, arg1, 0);
8367
            unlock_user(n, arg2, 0);
8368
        }
8369
        break;
8370
    case TARGET_NR_fremovexattr:
8371
        {
8372
            void *n;
8373
            n = lock_user_string(arg2);
8374
            if (n) {
8375
                ret = get_errno(fremovexattr(arg1, n));
8376
            } else {
8377
                ret = -TARGET_EFAULT;
8378
            }
8379
            unlock_user(n, arg2, 0);
8380
        }
8381
        break;
8382
#endif
8383
#endif /* CONFIG_ATTR */
8384
#ifdef TARGET_NR_set_thread_area
8385
    case TARGET_NR_set_thread_area:
8386
#if defined(TARGET_MIPS)
8387
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
8388
      ret = 0;
8389
      break;
8390
#elif defined(TARGET_CRIS)
8391
      if (arg1 & 0xff)
8392
          ret = -TARGET_EINVAL;
8393
      else {
8394
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
8395
          ret = 0;
8396
      }
8397
      break;
8398
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
8399
      ret = do_set_thread_area(cpu_env, arg1);
8400
      break;
8401
#else
8402
      goto unimplemented_nowarn;
8403
#endif
8404
#endif
8405
#ifdef TARGET_NR_get_thread_area
8406
    case TARGET_NR_get_thread_area:
8407
#if defined(TARGET_I386) && defined(TARGET_ABI32)
8408
        ret = do_get_thread_area(cpu_env, arg1);
8409
#else
8410
        goto unimplemented_nowarn;
8411
#endif
8412
#endif
8413
#ifdef TARGET_NR_getdomainname
8414
    case TARGET_NR_getdomainname:
8415
        goto unimplemented_nowarn;
8416
#endif
8417

    
8418
#ifdef TARGET_NR_clock_gettime
8419
    case TARGET_NR_clock_gettime:
8420
    {
8421
        struct timespec ts;
8422
        ret = get_errno(clock_gettime(arg1, &ts));
8423
        if (!is_error(ret)) {
8424
            host_to_target_timespec(arg2, &ts);
8425
        }
8426
        break;
8427
    }
8428
#endif
8429
#ifdef TARGET_NR_clock_getres
8430
    case TARGET_NR_clock_getres:
8431
    {
8432
        struct timespec ts;
8433
        ret = get_errno(clock_getres(arg1, &ts));
8434
        if (!is_error(ret)) {
8435
            host_to_target_timespec(arg2, &ts);
8436
        }
8437
        break;
8438
    }
8439
#endif
8440
#ifdef TARGET_NR_clock_nanosleep
8441
    case TARGET_NR_clock_nanosleep:
8442
    {
8443
        struct timespec ts;
8444
        target_to_host_timespec(&ts, arg3);
8445
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
8446
        if (arg4)
8447
            host_to_target_timespec(arg4, &ts);
8448
        break;
8449
    }
8450
#endif
8451

    
8452
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
8453
    case TARGET_NR_set_tid_address:
8454
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
8455
        break;
8456
#endif
8457

    
8458
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
8459
    case TARGET_NR_tkill:
8460
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
8461
        break;
8462
#endif
8463

    
8464
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
8465
    case TARGET_NR_tgkill:
8466
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
8467
                        target_to_host_signal(arg3)));
8468
        break;
8469
#endif
8470

    
8471
#ifdef TARGET_NR_set_robust_list
8472
    case TARGET_NR_set_robust_list:
8473
        goto unimplemented_nowarn;
8474
#endif
8475

    
8476
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
8477
    case TARGET_NR_utimensat:
8478
        {
8479
            struct timespec *tsp, ts[2];
8480
            if (!arg3) {
8481
                tsp = NULL;
8482
            } else {
8483
                target_to_host_timespec(ts, arg3);
8484
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
8485
                tsp = ts;
8486
            }
8487
            if (!arg2)
8488
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
8489
            else {
8490
                if (!(p = lock_user_string(arg2))) {
8491
                    ret = -TARGET_EFAULT;
8492
                    goto fail;
8493
                }
8494
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
8495
                unlock_user(p, arg2, 0);
8496
            }
8497
        }
8498
        break;
8499
#endif
8500
#if defined(CONFIG_USE_NPTL)
8501
    case TARGET_NR_futex:
8502
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
8503
        break;
8504
#endif
8505
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
8506
    case TARGET_NR_inotify_init:
8507
        ret = get_errno(sys_inotify_init());
8508
        break;
8509
#endif
8510
#ifdef CONFIG_INOTIFY1
8511
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
8512
    case TARGET_NR_inotify_init1:
8513
        ret = get_errno(sys_inotify_init1(arg1));
8514
        break;
8515
#endif
8516
#endif
8517
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
8518
    case TARGET_NR_inotify_add_watch:
8519
        p = lock_user_string(arg2);
8520
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
8521
        unlock_user(p, arg2, 0);
8522
        break;
8523
#endif
8524
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
8525
    case TARGET_NR_inotify_rm_watch:
8526
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
8527
        break;
8528
#endif
8529

    
8530
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
8531
    case TARGET_NR_mq_open:
8532
        {
8533
            struct mq_attr posix_mq_attr;
8534

    
8535
            p = lock_user_string(arg1 - 1);
8536
            if (arg4 != 0)
8537
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
8538
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
8539
            unlock_user (p, arg1, 0);
8540
        }
8541
        break;
8542

    
8543
    case TARGET_NR_mq_unlink:
8544
        p = lock_user_string(arg1 - 1);
8545
        ret = get_errno(mq_unlink(p));
8546
        unlock_user (p, arg1, 0);
8547
        break;
8548

    
8549
    case TARGET_NR_mq_timedsend:
8550
        {
8551
            struct timespec ts;
8552

    
8553
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
8554
            if (arg5 != 0) {
8555
                target_to_host_timespec(&ts, arg5);
8556
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
8557
                host_to_target_timespec(arg5, &ts);
8558
            }
8559
            else
8560
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
8561
            unlock_user (p, arg2, arg3);
8562
        }
8563
        break;
8564

    
8565
    case TARGET_NR_mq_timedreceive:
8566
        {
8567
            struct timespec ts;
8568
            unsigned int prio;
8569

    
8570
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
8571
            if (arg5 != 0) {
8572
                target_to_host_timespec(&ts, arg5);
8573
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
8574
                host_to_target_timespec(arg5, &ts);
8575
            }
8576
            else
8577
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
8578
            unlock_user (p, arg2, arg3);
8579
            if (arg4 != 0)
8580
                put_user_u32(prio, arg4);
8581
        }
8582
        break;
8583

    
8584
    /* Not implemented for now... */
8585
/*     case TARGET_NR_mq_notify: */
8586
/*         break; */
8587

    
8588
    case TARGET_NR_mq_getsetattr:
8589
        {
8590
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
8591
            ret = 0;
8592
            if (arg3 != 0) {
8593
                ret = mq_getattr(arg1, &posix_mq_attr_out);
8594
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
8595
            }
8596
            if (arg2 != 0) {
8597
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
8598
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
8599
            }
8600

    
8601
        }
8602
        break;
8603
#endif
8604

    
8605
#ifdef CONFIG_SPLICE
8606
#ifdef TARGET_NR_tee
8607
    case TARGET_NR_tee:
8608
        {
8609
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
8610
        }
8611
        break;
8612
#endif
8613
#ifdef TARGET_NR_splice
8614
    case TARGET_NR_splice:
8615
        {
8616
            loff_t loff_in, loff_out;
8617
            loff_t *ploff_in = NULL, *ploff_out = NULL;
8618
            if(arg2) {
8619
                get_user_u64(loff_in, arg2);
8620
                ploff_in = &loff_in;
8621
            }
8622
            if(arg4) {
8623
                get_user_u64(loff_out, arg2);
8624
                ploff_out = &loff_out;
8625
            }
8626
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
8627
        }
8628
        break;
8629
#endif
8630
#ifdef TARGET_NR_vmsplice
8631
        case TARGET_NR_vmsplice:
8632
        {
8633
            int count = arg3;
8634
            struct iovec *vec;
8635

    
8636
            vec = alloca(count * sizeof(struct iovec));
8637
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
8638
                goto efault;
8639
            ret = get_errno(vmsplice(arg1, vec, count, arg4));
8640
            unlock_iovec(vec, arg2, count, 0);
8641
        }
8642
        break;
8643
#endif
8644
#endif /* CONFIG_SPLICE */
8645
#ifdef CONFIG_EVENTFD
8646
#if defined(TARGET_NR_eventfd)
8647
    case TARGET_NR_eventfd:
8648
        ret = get_errno(eventfd(arg1, 0));
8649
        break;
8650
#endif
8651
#if defined(TARGET_NR_eventfd2)
8652
    case TARGET_NR_eventfd2:
8653
        ret = get_errno(eventfd(arg1, arg2));
8654
        break;
8655
#endif
8656
#endif /* CONFIG_EVENTFD  */
8657
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
8658
    case TARGET_NR_fallocate:
8659
#if TARGET_ABI_BITS == 32
8660
        ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
8661
                                  target_offset64(arg5, arg6)));
8662
#else
8663
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
8664
#endif
8665
        break;
8666
#endif
8667
#if defined(CONFIG_SYNC_FILE_RANGE)
8668
#if defined(TARGET_NR_sync_file_range)
8669
    case TARGET_NR_sync_file_range:
8670
#if TARGET_ABI_BITS == 32
8671
#if defined(TARGET_MIPS)
8672
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8673
                                        target_offset64(arg5, arg6), arg7));
8674
#else
8675
        ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
8676
                                        target_offset64(arg4, arg5), arg6));
8677
#endif /* !TARGET_MIPS */
8678
#else
8679
        ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
8680
#endif
8681
        break;
8682
#endif
8683
#if defined(TARGET_NR_sync_file_range2)
8684
    case TARGET_NR_sync_file_range2:
8685
        /* This is like sync_file_range but the arguments are reordered */
8686
#if TARGET_ABI_BITS == 32
8687
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
8688
                                        target_offset64(arg5, arg6), arg2));
8689
#else
8690
        ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
8691
#endif
8692
        break;
8693
#endif
8694
#endif
8695
#if defined(CONFIG_EPOLL)
8696
#if defined(TARGET_NR_epoll_create)
8697
    case TARGET_NR_epoll_create:
8698
        ret = get_errno(epoll_create(arg1));
8699
        break;
8700
#endif
8701
#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
8702
    case TARGET_NR_epoll_create1:
8703
        ret = get_errno(epoll_create1(arg1));
8704
        break;
8705
#endif
8706
#if defined(TARGET_NR_epoll_ctl)
8707
    case TARGET_NR_epoll_ctl:
8708
    {
8709
        struct epoll_event ep;
8710
        struct epoll_event *epp = 0;
8711
        if (arg4) {
8712
            struct target_epoll_event *target_ep;
8713
            if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
8714
                goto efault;
8715
            }
8716
            ep.events = tswap32(target_ep->events);
8717
            /* The epoll_data_t union is just opaque data to the kernel,
8718
             * so we transfer all 64 bits across and need not worry what
8719
             * actual data type it is.
8720
             */
8721
            ep.data.u64 = tswap64(target_ep->data.u64);
8722
            unlock_user_struct(target_ep, arg4, 0);
8723
            epp = &ep;
8724
        }
8725
        ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
8726
        break;
8727
    }
8728
#endif
8729

    
8730
#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
8731
#define IMPLEMENT_EPOLL_PWAIT
8732
#endif
8733
#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
8734
#if defined(TARGET_NR_epoll_wait)
8735
    case TARGET_NR_epoll_wait:
8736
#endif
8737
#if defined(IMPLEMENT_EPOLL_PWAIT)
8738
    case TARGET_NR_epoll_pwait:
8739
#endif
8740
    {
8741
        struct target_epoll_event *target_ep;
8742
        struct epoll_event *ep;
8743
        int epfd = arg1;
8744
        int maxevents = arg3;
8745
        int timeout = arg4;
8746

    
8747
        target_ep = lock_user(VERIFY_WRITE, arg2,
8748
                              maxevents * sizeof(struct target_epoll_event), 1);
8749
        if (!target_ep) {
8750
            goto efault;
8751
        }
8752

    
8753
        ep = alloca(maxevents * sizeof(struct epoll_event));
8754

    
8755
        switch (num) {
8756
#if defined(IMPLEMENT_EPOLL_PWAIT)
8757
        case TARGET_NR_epoll_pwait:
8758
        {
8759
            target_sigset_t *target_set;
8760
            sigset_t _set, *set = &_set;
8761

    
8762
            if (arg5) {
8763
                target_set = lock_user(VERIFY_READ, arg5,
8764
                                       sizeof(target_sigset_t), 1);
8765
                if (!target_set) {
8766
                    unlock_user(target_ep, arg2, 0);
8767
                    goto efault;
8768
                }
8769
                target_to_host_sigset(set, target_set);
8770
                unlock_user(target_set, arg5, 0);
8771
            } else {
8772
                set = NULL;
8773
            }
8774

    
8775
            ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
8776
            break;
8777
        }
8778
#endif
8779
#if defined(TARGET_NR_epoll_wait)
8780
        case TARGET_NR_epoll_wait:
8781
            ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
8782
            break;
8783
#endif
8784
        default:
8785
            ret = -TARGET_ENOSYS;
8786
        }
8787
        if (!is_error(ret)) {
8788
            int i;
8789
            for (i = 0; i < ret; i++) {
8790
                target_ep[i].events = tswap32(ep[i].events);
8791
                target_ep[i].data.u64 = tswap64(ep[i].data.u64);
8792
            }
8793
        }
8794
        unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
8795
        break;
8796
    }
8797
#endif
8798
#endif
8799
#ifdef TARGET_NR_prlimit64
8800
    case TARGET_NR_prlimit64:
8801
    {
8802
        /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
8803
        struct target_rlimit64 *target_rnew, *target_rold;
8804
        struct host_rlimit64 rnew, rold, *rnewp = 0;
8805
        if (arg3) {
8806
            if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
8807
                goto efault;
8808
            }
8809
            rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
8810
            rnew.rlim_max = tswap64(target_rnew->rlim_max);
8811
            unlock_user_struct(target_rnew, arg3, 0);
8812
            rnewp = &rnew;
8813
        }
8814

    
8815
        ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
8816
        if (!is_error(ret) && arg4) {
8817
            if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
8818
                goto efault;
8819
            }
8820
            target_rold->rlim_cur = tswap64(rold.rlim_cur);
8821
            target_rold->rlim_max = tswap64(rold.rlim_max);
8822
            unlock_user_struct(target_rold, arg4, 1);
8823
        }
8824
        break;
8825
    }
8826
#endif
8827
    default:
8828
    unimplemented:
8829
        gemu_log("qemu: Unsupported syscall: %d\n", num);
8830
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
8831
    unimplemented_nowarn:
8832
#endif
8833
        ret = -TARGET_ENOSYS;
8834
        break;
8835
    }
8836
fail:
8837
#ifdef DEBUG
8838
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
8839
#endif
8840
    if(do_strace)
8841
        print_syscall_ret(num, ret);
8842
    return ret;
8843
efault:
8844
    ret = -TARGET_EFAULT;
8845
    goto fail;
8846
}